Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: BLE_HeartRate_IDB0XA1
Fork of X_NUCLEO_IDB0XA1 by
BlueNRGGap.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 00018 /** 00019 ****************************************************************************** 00020 * @file BlueNRGGap.cpp 00021 * @author STMicroelectronics 00022 * @brief Implementation of BLE_API Gap Class 00023 ****************************************************************************** 00024 * @copy 00025 * 00026 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 00027 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 00028 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 00029 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 00030 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 00031 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 00032 * 00033 * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> 00034 */ 00035 00036 /** @defgroup BlueNRGGap 00037 * @brief BlueNRG BLE_API GAP Adaptation 00038 * @{ 00039 */ 00040 00041 #include "BlueNRGDevice.h" 00042 #include "mbed.h" 00043 #include "Payload.h" 00044 #include "Utils.h" 00045 #include "debug.h" 00046 00047 //Local Variables 00048 //const char *local_name = NULL; 00049 //uint8_t local_name_length = 0; 00050 00051 /* 00052 * Utility to process GAP specific events (e.g., Advertising timeout) 00053 */ 00054 void BlueNRGGap::Process(void) 00055 { 00056 if(AdvToFlag) { 00057 stopAdvertising(); 00058 } 00059 00060 } 00061 00062 /**************************************************************************/ 00063 /*! 00064 @brief Sets the advertising parameters and payload for the device. 00065 Note: Some data types give error when their adv data is updated using aci_gap_update_adv_data() API 00066 00067 @params[in] advData 00068 The primary advertising data payload 00069 @params[in] scanResponse 00070 The optional Scan Response payload if the advertising 00071 type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED 00072 in \ref GapAdveritinngParams 00073 00074 @returns \ref ble_error_t 00075 00076 @retval BLE_ERROR_NONE 00077 Everything executed properly 00078 00079 @retval BLE_ERROR_BUFFER_OVERFLOW 00080 The proposed action would cause a buffer overflow. All 00081 advertising payloads must be <= 31 bytes, for example. 00082 00083 @retval BLE_ERROR_NOT_IMPLEMENTED 00084 A feature was requested that is not yet supported in the 00085 nRF51 firmware or hardware. 00086 00087 @retval BLE_ERROR_PARAM_OUT_OF_RANGE 00088 One of the proposed values is outside the valid range. 00089 00090 @section EXAMPLE 00091 00092 @code 00093 00094 @endcode 00095 */ 00096 /**************************************************************************/ 00097 ble_error_t BlueNRGGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse) 00098 { 00099 PRINTF("BlueNRGGap::setAdvertisingData\n\r"); 00100 /* Make sure we don't exceed the advertising payload length */ 00101 if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) { 00102 PRINTF("Exceeded the advertising payload length\n\r"); 00103 return BLE_ERROR_BUFFER_OVERFLOW; 00104 } 00105 00106 /* Make sure we have a payload! */ 00107 if (advData.getPayloadLen() == 0) { 00108 PRINTF("advData.getPayloadLen() == 0\n\r"); 00109 //return BLE_ERROR_PARAM_OUT_OF_RANGE; 00110 local_name_length = 0; 00111 txPowLevSet = 0; 00112 servUuidlength = 0; 00113 AdvLen = 0; 00114 } else { 00115 PayloadPtr loadPtr(advData.getPayload(), advData.getPayloadLen()); 00116 00117 for(uint8_t index=0; index<loadPtr.getPayloadUnitCount(); index++) { 00118 loadPtr.getUnitAtIndex(index); 00119 00120 PRINTF("adData[%d].length=%d\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getLenPtr())); 00121 PRINTF("adData[%d].AdType=0x%x\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr())); 00122 00123 switch(*loadPtr.getUnitAtIndex(index).getAdTypePtr()) { 00124 case GapAdvertisingData::FLAGS: /* ref *Flags */ 00125 { 00126 PRINTF("Advertising type: FLAGS\n\r"); 00127 //Check if Flags are OK. BlueNRG only supports LE Mode. 00128 uint8_t *flags = loadPtr.getUnitAtIndex(index).getDataPtr(); 00129 if((*flags & GapAdvertisingData::BREDR_NOT_SUPPORTED) != GapAdvertisingData::BREDR_NOT_SUPPORTED) { 00130 PRINTF("BlueNRG does not support BR/EDR Mode"); 00131 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00132 } 00133 00134 break; 00135 } 00136 case GapAdvertisingData::INCOMPLETE_LIST_16BIT_SERVICE_IDS: /**< Incomplete list of 16-bit Service IDs */ 00137 case GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS: /**< Complete list of 16-bit Service IDs */ 00138 case GapAdvertisingData::INCOMPLETE_LIST_128BIT_SERVICE_IDS: /**< Incomplete list of 128-bit Service IDs */ 00139 case GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS: /**< Complete list of 128-bit Service IDs */ 00140 { 00141 PRINTF("Advertising type: INCOMPLETE_LIST SERVICE_IDS/COMPLETE_LIST SERVICE_IDS\n\r"); 00142 00143 uint8_t buffSize = *loadPtr.getUnitAtIndex(index).getLenPtr()-1; 00144 // The total lenght should include the Data Type Value 00145 if(buffSize>UUID_BUFFER_SIZE-1) { 00146 return BLE_ERROR_INVALID_PARAM; 00147 } 00148 00149 servUuidlength = buffSize+1; // +1 to include the Data Type Value 00150 servUuidData[0] = (uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr()); //Data Type Value 00151 00152 PRINTF("servUuidlength=%d servUuidData[0]=%d buffSize=%d\n\r", servUuidlength, servUuidData[0], buffSize); 00153 // Save the Service UUID list just after the Data Type Value field 00154 memcpy(servUuidData+1, loadPtr.getUnitAtIndex(index).getDataPtr(), buffSize); 00155 #ifdef DEBUG 00156 for(unsigned i=0; i<servUuidlength; i++) { 00157 PRINTF("servUuidData[%d] = 0x%x\n\r", i, servUuidData[i]); 00158 } 00159 00160 for(unsigned i=0; i<buffSize; i++) { 00161 PRINTF("loadPtr.getUnitAtIndex(index).getDataPtr()[%d] = 0x%x\n\r", 00162 i, loadPtr.getUnitAtIndex(index).getDataPtr()[i]); 00163 } 00164 #endif /* DEBUG */ 00165 break; 00166 } 00167 case GapAdvertisingData::INCOMPLETE_LIST_32BIT_SERVICE_IDS: /**< Incomplete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */ 00168 { 00169 PRINTF("Advertising type: INCOMPLETE_LIST_32BIT_SERVICE_IDS\n\r"); 00170 return BLE_ERROR_NOT_IMPLEMENTED; 00171 } 00172 case GapAdvertisingData::COMPLETE_LIST_32BIT_SERVICE_IDS: /**< Complete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */ 00173 { 00174 PRINTF("Advertising type: COMPLETE_LIST_32BIT_SERVICE_IDS\n\r"); 00175 return BLE_ERROR_NOT_IMPLEMENTED; 00176 } 00177 case GapAdvertisingData::SHORTENED_LOCAL_NAME: /**< Shortened Local Name */ 00178 { 00179 break; 00180 } 00181 case GapAdvertisingData::COMPLETE_LOCAL_NAME: /**< Complete Local Name */ 00182 { 00183 PRINTF("Advertising type: COMPLETE_LOCAL_NAME\n\r"); 00184 loadPtr.getUnitAtIndex(index).printDataAsString(); 00185 loadPtr.getUnitAtIndex(index).printDataAsHex(); 00186 local_name_length = *loadPtr.getUnitAtIndex(index).getLenPtr()-1; 00187 // The total length should include the Data Type Value 00188 if(local_name_length>ADV_DATA_MAX_SIZE-1) { 00189 return BLE_ERROR_INVALID_PARAM; 00190 } 00191 local_name[0] = (uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr()); //Data Type Value 00192 memcpy(local_name+1, (uint8_t*)loadPtr.getUnitAtIndex(index).getDataPtr(), local_name_length-1); 00193 PRINTF("Advertising type: COMPLETE_LOCAL_NAME local_name=%s local_name_length=%d\n\r", local_name+1, local_name_length); 00194 00195 break; 00196 } 00197 case GapAdvertisingData::TX_POWER_LEVEL: /**< TX Power Level (in dBm) */ 00198 { 00199 PRINTF("Advertising type: TX_POWER_LEVEL\n\r"); 00200 int8_t enHighPower = 0; 00201 int8_t paLevel = 0; 00202 00203 int8_t dbm = *loadPtr.getUnitAtIndex(index).getDataPtr(); 00204 tBleStatus ret = getHighPowerAndPALevelValue(dbm, enHighPower, paLevel); 00205 #ifdef DEBUG 00206 PRINTF("dbm=%d, ret=%d\n\r", dbm, ret); 00207 PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); 00208 #endif 00209 if(ret == BLE_STATUS_SUCCESS) { 00210 aci_hal_set_tx_power_level(enHighPower, paLevel); 00211 txPowLevSet = 1; 00212 } 00213 break; 00214 } 00215 case GapAdvertisingData::DEVICE_ID: /**< Device ID */ 00216 { 00217 break; 00218 } 00219 case GapAdvertisingData::SLAVE_CONNECTION_INTERVAL_RANGE: /**< Slave :Connection Interval Range */ 00220 { 00221 PRINTF("Advertising type: SLAVE_CONNECTION_INTERVAL_RANGE\n\r"); 00222 uint8_t *ptr = loadPtr.getUnitAtIndex(index).getDataPtr(); 00223 slaveConnIntervMin = ptr[0]|ptr[1]<<8; 00224 slaveConnIntervMax = ptr[2]|ptr[3]<<8; 00225 00226 break; 00227 } 00228 case GapAdvertisingData::SERVICE_DATA: /**< Service Data */ 00229 { 00230 PRINTF("Advertising type: SERVICE_DATA\n\r"); 00231 uint8_t buffSize = *loadPtr.getUnitAtIndex(index).getLenPtr()-1; 00232 PRINTF("Advertising type: SERVICE_DATA (buffSize=%d)\n\r", buffSize); 00233 // the total ADV DATA LEN should include two more bytes: the buffer size byte; and the Service Data Type Value byte 00234 if(buffSize>ADV_DATA_MAX_SIZE-2) { 00235 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00236 } 00237 #ifdef DEBUG 00238 for(int i=0; i<buffSize+1; i++) { 00239 PRINTF("Advertising type: SERVICE_DATA loadPtr.getUnitAtIndex(index).getDataPtr()[%d] = 0x%x\n\r", 00240 i, loadPtr.getUnitAtIndex(index).getDataPtr()[i]); 00241 } 00242 #endif 00243 // the total ADV DATA LEN should include two more bytes: the buffer size byte; and the Service Data Type Value byte 00244 AdvData[AdvLen++] = buffSize+1; // the fisrt byte is the data buffer size (type+data) 00245 AdvData[AdvLen++] = AD_TYPE_SERVICE_DATA; 00246 memcpy(&AdvData[AdvLen], loadPtr.getUnitAtIndex(index).getDataPtr(), buffSize); 00247 AdvLen += buffSize; 00248 break; 00249 } 00250 00251 case GapAdvertisingData::ADVERTISING_INTERVAL: /**< Advertising Interval */ 00252 { 00253 printf("Advertising type: ADVERTISING_INTERVAL\n\r"); 00254 uint8_t buffSize = *loadPtr.getUnitAtIndex(index).getLenPtr()-1; 00255 AdvData[AdvLen++] = buffSize+1; // the fisrt byte is the data buffer size (type+data) 00256 AdvData[AdvLen++] = AD_TYPE_ADVERTISING_INTERVAL; 00257 memcpy(&AdvData[AdvLen], loadPtr.getUnitAtIndex(index).getDataPtr(), buffSize); 00258 AdvLen += buffSize; 00259 break; 00260 } 00261 case GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA: /**< Manufacturer Specific Data */ 00262 { 00263 PRINTF("Advertising type: MANUFACTURER_SPECIFIC_DATA\n\r"); 00264 uint8_t buffSize = *loadPtr.getUnitAtIndex(index).getLenPtr()-1; 00265 PRINTF("Advertising type: MANUFACTURER_SPECIFIC_DATA (buffSize=%d)\n\r", buffSize); 00266 // the total ADV DATA LEN should include two more bytes: 00267 // the buffer size byte; 00268 // and the Manufacturer Specific Data Type Value byte 00269 if(buffSize>ADV_DATA_MAX_SIZE-2) { 00270 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00271 } 00272 #ifdef DBEUG 00273 for(int i=0; i<buffSize+1; i++) { 00274 PRINTF("Advertising type: MANUFACTURER_SPECIFIC_DATA loadPtr.getUnitAtIndex(index).getDataPtr()[%d] = 0x%x\n\r", 00275 i, loadPtr.getUnitAtIndex(index).getDataPtr()[i]); 00276 } 00277 #endif 00278 // the total ADV DATA LEN should include two more bytes: the buffer size byte; and the Manufacturer Specific Data Type Value byte 00279 AdvData[AdvLen++] = buffSize+1; // the fisrt byte is the data buffer size (type+data) 00280 AdvData[AdvLen++] = AD_TYPE_MANUFACTURER_SPECIFIC_DATA; 00281 memcpy(&AdvData[AdvLen], loadPtr.getUnitAtIndex(index).getDataPtr(), buffSize); 00282 AdvLen += buffSize; 00283 break; 00284 } 00285 } // end switch 00286 00287 } //end for 00288 00289 //Set the SCAN_RSP Payload 00290 if(scanResponse.getPayloadLen() > 0) { 00291 scan_response_payload = scanResponse.getPayload(); 00292 scan_rsp_length = scanResponse.getPayloadLen(); 00293 } 00294 00295 /* Align the GAP Service Appearance Char value coherently */ 00296 STORE_LE_16(deviceAppearance, advData.getAppearance()); 00297 setAppearance((GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0])); 00298 00299 // Update the ADV data if we are already in ADV mode 00300 if(AdvLen > 0 && state.advertising == 1) { 00301 00302 tBleStatus ret = aci_gap_update_adv_data(AdvLen, AdvData); 00303 if(BLE_STATUS_SUCCESS!=ret) { 00304 PRINTF("error occurred while adding adv data (ret=0x%x)\n", ret); 00305 switch (ret) { 00306 case BLE_STATUS_TIMEOUT: 00307 return BLE_STACK_BUSY; 00308 case ERR_INVALID_HCI_CMD_PARAMS: 00309 case BLE_STATUS_INVALID_PARAMS: 00310 return BLE_ERROR_INVALID_PARAM; 00311 case BLE_STATUS_FAILED: 00312 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00313 default: 00314 return BLE_ERROR_UNSPECIFIED; 00315 } 00316 } 00317 } 00318 } 00319 return BLE_ERROR_NONE; 00320 } 00321 00322 /* 00323 * Utility to set ADV timeout flag 00324 */ 00325 void BlueNRGGap::setAdvToFlag(void) { 00326 AdvToFlag = true; 00327 } 00328 00329 /* 00330 * ADV timeout callback 00331 */ 00332 #ifdef AST_FOR_MBED_OS 00333 static void advTimeoutCB(void) 00334 { 00335 Gap::GapState_t state; 00336 00337 state = BlueNRGGap::getInstance().getState(); 00338 if (state.advertising == 1) { 00339 00340 BlueNRGGap::getInstance().stopAdvertising(); 00341 00342 } 00343 } 00344 #else 00345 static void advTimeoutCB(void) 00346 { 00347 Gap::GapState_t state; 00348 00349 state = BlueNRGGap::getInstance().getState(); 00350 if (state.advertising == 1) { 00351 00352 BlueNRGGap::getInstance().setAdvToFlag(); 00353 00354 Timeout t = BlueNRGGap::getInstance().getAdvTimeout(); 00355 t.detach(); /* disable the callback from the timeout */ 00356 00357 } 00358 } 00359 #endif /* AST_FOR_MBED_OS */ 00360 00361 /**************************************************************************/ 00362 /*! 00363 @brief Starts the BLE HW, initialising any services that were 00364 added before this function was called. 00365 00366 @param[in] params 00367 Basic advertising details, including the advertising 00368 delay, timeout and how the device should be advertised 00369 00370 @note All services must be added before calling this function! 00371 00372 @returns ble_error_t 00373 00374 @retval BLE_ERROR_NONE 00375 Everything executed properly 00376 00377 @section EXAMPLE 00378 00379 @code 00380 00381 @endcode 00382 */ 00383 /**************************************************************************/ 00384 00385 ble_error_t BlueNRGGap::startAdvertising(const GapAdvertisingParams ¶ms) 00386 { 00387 tBleStatus ret; 00388 ble_error_t rc; 00389 00390 /* Make sure we support the advertising type */ 00391 if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) { 00392 /* ToDo: This requires a proper security implementation, etc. */ 00393 return BLE_ERROR_NOT_IMPLEMENTED; 00394 } 00395 00396 /* Check interval range */ 00397 if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) { 00398 /* Min delay is slightly longer for unconnectable devices */ 00399 if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) || 00400 (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) { 00401 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00402 } 00403 } else { 00404 if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN) || 00405 (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) { 00406 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00407 } 00408 } 00409 00410 /* Check timeout is zero for Connectable Directed */ 00411 if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) { 00412 /* Timeout must be 0 with this type, although we'll never get here */ 00413 /* since this isn't implemented yet anyway */ 00414 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00415 } 00416 00417 /* Check timeout for other advertising types */ 00418 if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && 00419 (params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) { 00420 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00421 } 00422 00423 /* 00424 * Advertising filter policy setting 00425 * FIXME: the Security Manager should be implemented 00426 */ 00427 AdvertisingPolicyMode_t mode = getAdvertisingPolicyMode(); 00428 if(mode != ADV_POLICY_IGNORE_WHITELIST) { 00429 ret = aci_gap_configure_whitelist(); 00430 if(ret != BLE_STATUS_SUCCESS) { 00431 PRINTF("aci_gap_configure_whitelist ret=0x%x\n\r", ret); 00432 return BLE_ERROR_OPERATION_NOT_PERMITTED; 00433 } 00434 } 00435 00436 uint8_t advFilterPolicy = NO_WHITE_LIST_USE; 00437 switch(mode) { 00438 case ADV_POLICY_FILTER_SCAN_REQS: 00439 advFilterPolicy = WHITE_LIST_FOR_ONLY_SCAN; 00440 break; 00441 case ADV_POLICY_FILTER_CONN_REQS: 00442 advFilterPolicy = WHITE_LIST_FOR_ONLY_CONN; 00443 break; 00444 case ADV_POLICY_FILTER_ALL_REQS: 00445 advFilterPolicy = WHITE_LIST_FOR_ALL; 00446 break; 00447 default: 00448 advFilterPolicy = NO_WHITE_LIST_USE; 00449 break; 00450 } 00451 00452 /* Check the ADV type before setting scan response data */ 00453 if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED || 00454 params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED) { 00455 00456 /* set scan response data */ 00457 PRINTF(" setting scan response data (scan_rsp_length=%u)\n", scan_rsp_length); 00458 ret = hci_le_set_scan_resp_data(scan_rsp_length, scan_response_payload); 00459 00460 if(BLE_STATUS_SUCCESS!=ret) { 00461 PRINTF(" error while setting scan response data (ret=0x%x)\n", ret); 00462 switch (ret) { 00463 case BLE_STATUS_TIMEOUT: 00464 return BLE_STACK_BUSY; 00465 default: 00466 return BLE_ERROR_UNSPECIFIED; 00467 } 00468 } 00469 } else { 00470 hci_le_set_scan_resp_data(0, NULL); 00471 } 00472 00473 //advInterval = params.getIntervalInADVUnits(); 00474 setAdvParameters(); 00475 PRINTF("advInterval=%d advType=%d\n\r", advInterval, params.getAdvertisingType()); 00476 00477 /* Setting discoverable mode */ 00478 ret = aci_gap_set_discoverable(params.getAdvertisingType(), // AdvType 00479 advInterval, // AdvIntervMin 00480 advInterval, // AdvIntervMax 00481 addr_type, // OwnAddrType 00482 advFilterPolicy, // AdvFilterPolicy 00483 local_name_length, // LocalNameLen 00484 (const char*)local_name, // LocalName 00485 servUuidlength, // ServiceUUIDLen 00486 servUuidData, // ServiceUUIDList 00487 slaveConnIntervMin, // SlaveConnIntervMin 00488 slaveConnIntervMax); // SlaveConnIntervMax 00489 00490 00491 PRINTF("!!!setting discoverable (servUuidlength=0x%x)\n\r", servUuidlength); 00492 if(BLE_STATUS_SUCCESS!=ret) { 00493 PRINTF("error occurred while setting discoverable (ret=0x%x)\n\r", ret); 00494 switch (ret) { 00495 case BLE_STATUS_INVALID_PARAMS: 00496 case ERR_INVALID_HCI_CMD_PARAMS: 00497 return BLE_ERROR_INVALID_PARAM; 00498 case ERR_COMMAND_DISALLOWED: 00499 return BLE_ERROR_OPERATION_NOT_PERMITTED; 00500 case ERR_UNSUPPORTED_FEATURE: 00501 return BLE_ERROR_NOT_IMPLEMENTED; 00502 case BLE_STATUS_TIMEOUT: 00503 return BLE_STACK_BUSY; 00504 default: 00505 return BLE_ERROR_UNSPECIFIED; 00506 } 00507 } 00508 00509 // Since AD_TYPE_TX_POWER_LEVEL has not been set by application, we delete it 00510 if(!txPowLevSet) { 00511 PRINTF("Deleting TX POW LEV\n"); 00512 aci_gap_delete_ad_type(AD_TYPE_TX_POWER_LEVEL); 00513 txPowLevSet = 0; 00514 } 00515 00516 // Stop Advertising if an error occurs while updating ADV data 00517 rc = updateAdvertisingData(); 00518 if(rc != BLE_ERROR_NONE) { 00519 aci_gap_set_non_discoverable(); 00520 return rc; 00521 } 00522 00523 state.advertising = 1; 00524 00525 AdvToFlag = false; 00526 if(params.getTimeout() != 0) { 00527 PRINTF("!!! attaching to!!!\n"); 00528 #ifdef AST_FOR_MBED_OS 00529 minar::Scheduler::postCallback(advTimeoutCB).delay(minar::milliseconds(params.getTimeout() * 1000)); 00530 #else 00531 advTimeout.attach(advTimeoutCB, params.getTimeout() * 1000); 00532 #endif 00533 } 00534 00535 return BLE_ERROR_NONE; 00536 } 00537 00538 ble_error_t BlueNRGGap::updateAdvertisingData(void) 00539 { 00540 tBleStatus ret; 00541 00542 // Before updating the ADV data, delete COMPLETE_LOCAL_NAME field 00543 if(AdvLen > 0) { 00544 if(local_name_length > 0) { 00545 ret = aci_gap_delete_ad_type(AD_TYPE_COMPLETE_LOCAL_NAME); 00546 if (BLE_STATUS_SUCCESS!=ret){ 00547 PRINTF("aci_gap_delete_ad_type failed return=%d\n", ret); 00548 switch (ret) { 00549 case BLE_STATUS_TIMEOUT: 00550 return BLE_STACK_BUSY; 00551 case ERR_COMMAND_DISALLOWED: 00552 return BLE_ERROR_OPERATION_NOT_PERMITTED; 00553 case ERR_INVALID_HCI_CMD_PARAMS: 00554 return BLE_ERROR_INVALID_PARAM; 00555 default: 00556 return BLE_ERROR_UNSPECIFIED; 00557 } 00558 } 00559 } 00560 00561 // ...and TX_POWER_LEVEL field to make the needed room in ADV payload 00562 if(txPowLevSet) { 00563 ret = aci_gap_delete_ad_type(AD_TYPE_TX_POWER_LEVEL); 00564 if (BLE_STATUS_SUCCESS!=ret){ 00565 PRINTF("aci_gap_delete_ad_type failed return=%d\n", ret); 00566 switch (ret) { 00567 case BLE_STATUS_TIMEOUT: 00568 return BLE_STACK_BUSY; 00569 case ERR_COMMAND_DISALLOWED: 00570 return BLE_ERROR_OPERATION_NOT_PERMITTED; 00571 case ERR_INVALID_HCI_CMD_PARAMS: 00572 return BLE_ERROR_INVALID_PARAM; 00573 default: 00574 return BLE_ERROR_UNSPECIFIED; 00575 } 00576 } 00577 } 00578 00579 ret = aci_gap_update_adv_data(AdvLen, AdvData); 00580 if(BLE_STATUS_SUCCESS!=ret) { 00581 PRINTF("error occurred while adding adv data (ret=0x%x)\n\r", ret); 00582 switch (ret) { 00583 case BLE_STATUS_TIMEOUT: 00584 return BLE_STACK_BUSY; 00585 case ERR_INVALID_HCI_CMD_PARAMS: 00586 case BLE_STATUS_INVALID_PARAMS: 00587 return BLE_ERROR_INVALID_PARAM; 00588 case BLE_STATUS_FAILED: 00589 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00590 default: 00591 return BLE_ERROR_UNSPECIFIED; 00592 } 00593 } 00594 00595 } // AdvLen>0 00596 00597 if(deviceAppearance != 0) { 00598 uint8_t appearance[] = {3, AD_TYPE_APPEARANCE, deviceAppearance[0], deviceAppearance[1]}; 00599 // just ignore error code while setting appearance 00600 aci_gap_update_adv_data(4, appearance); 00601 } 00602 00603 return BLE_ERROR_NONE; 00604 00605 } 00606 00607 /**************************************************************************/ 00608 /*! 00609 @brief Stops the BLE HW and disconnects from any devices 00610 00611 @returns ble_error_t 00612 00613 @retval BLE_ERROR_NONE 00614 Everything executed properly 00615 00616 @section EXAMPLE 00617 00618 @code 00619 00620 @endcode 00621 */ 00622 /**************************************************************************/ 00623 ble_error_t BlueNRGGap::stopAdvertising(void) 00624 { 00625 tBleStatus ret; 00626 00627 if(state.advertising == 1) { 00628 //Set non-discoverable to stop advertising 00629 ret = aci_gap_set_non_discoverable(); 00630 00631 if (BLE_STATUS_SUCCESS!=ret){ 00632 PRINTF("Error in stopping advertisement (ret=0x%x)!!\n\r", ret) ; 00633 switch (ret) { 00634 case ERR_COMMAND_DISALLOWED: 00635 return BLE_ERROR_OPERATION_NOT_PERMITTED; 00636 case BLE_STATUS_TIMEOUT: 00637 return BLE_STACK_BUSY; 00638 default: 00639 return BLE_ERROR_UNSPECIFIED; 00640 } 00641 } 00642 PRINTF("Advertisement stopped!!\n\r") ; 00643 //Set GapState_t::advertising state 00644 state.advertising = 0; 00645 } 00646 00647 return BLE_ERROR_NONE; 00648 } 00649 00650 /**************************************************************************/ 00651 /*! 00652 @brief Disconnects if we are connected to a central device 00653 00654 @param[in] reason 00655 Disconnection Reason 00656 00657 @returns ble_error_t 00658 00659 @retval BLE_ERROR_NONE 00660 Everything executed properly 00661 00662 @section EXAMPLE 00663 00664 @code 00665 00666 @endcode 00667 */ 00668 /**************************************************************************/ 00669 ble_error_t BlueNRGGap::disconnect(Handle_t connectionHandle, Gap::DisconnectionReason_t reason) 00670 { 00671 tBleStatus ret; 00672 00673 ret = aci_gap_terminate(connectionHandle, reason); 00674 00675 if (BLE_STATUS_SUCCESS != ret){ 00676 PRINTF("Error in GAP termination (ret=0x%x)!!\n\r", ret) ; 00677 switch (ret) { 00678 case ERR_COMMAND_DISALLOWED: 00679 return BLE_ERROR_OPERATION_NOT_PERMITTED; 00680 case BLE_STATUS_TIMEOUT: 00681 return BLE_STACK_BUSY; 00682 default: 00683 return BLE_ERROR_UNSPECIFIED; 00684 } 00685 } 00686 00687 return BLE_ERROR_NONE; 00688 } 00689 00690 /**************************************************************************/ 00691 /*! 00692 @brief Disconnects if we are connected to a central device 00693 00694 @param[in] reason 00695 Disconnection Reason 00696 00697 @returns ble_error_t 00698 00699 @retval BLE_ERROR_NONE 00700 Everything executed properly 00701 00702 @section EXAMPLE 00703 00704 @code 00705 00706 @endcode 00707 */ 00708 /**************************************************************************/ 00709 ble_error_t BlueNRGGap::disconnect(Gap::DisconnectionReason_t reason) 00710 { 00711 return disconnect(m_connectionHandle, reason); 00712 } 00713 00714 /**************************************************************************/ 00715 /*! 00716 @brief Sets the 16-bit connection handle 00717 00718 @param[in] conn_handle 00719 Connection Handle which is set in the Gap Instance 00720 00721 @returns void 00722 */ 00723 /**************************************************************************/ 00724 void BlueNRGGap::setConnectionHandle(uint16_t conn_handle) 00725 { 00726 m_connectionHandle = conn_handle; 00727 } 00728 00729 /**************************************************************************/ 00730 /*! 00731 @brief Gets the 16-bit connection handle 00732 00733 @param[in] void 00734 00735 @returns uint16_t 00736 Connection Handle of the Gap Instance 00737 */ 00738 /**************************************************************************/ 00739 uint16_t BlueNRGGap::getConnectionHandle(void) 00740 { 00741 return m_connectionHandle; 00742 } 00743 00744 /**************************************************************************/ 00745 /*! 00746 @brief Sets the BLE device address. SetAddress will reset the BLE 00747 device and re-initialize BTLE. Will not start advertising. 00748 00749 @param[in] type 00750 Type of Address 00751 00752 @param[in] address[6] 00753 Value of the Address to be set 00754 00755 @returns ble_error_t 00756 00757 @section EXAMPLE 00758 00759 @code 00760 00761 @endcode 00762 */ 00763 /**************************************************************************/ 00764 ble_error_t BlueNRGGap::setAddress(AddressType_t type, const BLEProtocol::AddressBytes_t address) 00765 { 00766 tBleStatus ret; 00767 00768 if (type > BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) { 00769 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00770 } 00771 00772 addr_type = type; 00773 00774 // If Address Type is other than PUBLIC, the given Address is ignored 00775 if(addr_type == BLEProtocol::AddressType::PUBLIC){ 00776 ret = aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET, 00777 CONFIG_DATA_PUBADDR_LEN, 00778 address); 00779 if(ret != BLE_STATUS_SUCCESS) { 00780 return BLE_ERROR_OPERATION_NOT_PERMITTED; 00781 } 00782 } else { 00783 return BLE_ERROR_OPERATION_NOT_PERMITTED; 00784 } 00785 00786 return BLE_ERROR_NONE; 00787 } 00788 00789 /**************************************************************************/ 00790 /*! 00791 @brief Returns boolean if the address of the device has been set 00792 or not 00793 00794 @returns bool 00795 00796 @section EXAMPLE 00797 00798 @code 00799 00800 @endcode 00801 */ 00802 /**************************************************************************/ 00803 bool BlueNRGGap::getIsSetAddress() 00804 { 00805 return isSetAddress; 00806 } 00807 00808 /**************************************************************************/ 00809 /*! 00810 @brief Returns the address of the device if set 00811 00812 @returns Pointer to the address if Address is set else NULL 00813 00814 @section EXAMPLE 00815 00816 @code 00817 00818 @endcode 00819 */ 00820 /**************************************************************************/ 00821 ble_error_t BlueNRGGap::getAddress(AddressType_t *typeP, Address_t address) 00822 { 00823 uint8_t bdaddr[BDADDR_SIZE]; 00824 uint8_t data_len_out; 00825 00826 if(typeP != NULL) { 00827 *typeP = addr_type; 00828 } 00829 00830 tBleStatus ret = aci_hal_read_config_data(CONFIG_DATA_RANDOM_ADDRESS_IDB05A1, BDADDR_SIZE, &data_len_out, bdaddr); 00831 if(ret != BLE_STATUS_SUCCESS) { 00832 return BLE_ERROR_UNSPECIFIED; 00833 } 00834 00835 if(address != NULL) { 00836 memcpy(address, bdaddr, BDADDR_SIZE); 00837 } 00838 00839 return BLE_ERROR_NONE; 00840 } 00841 00842 /**************************************************************************/ 00843 /*! 00844 @brief obtains preferred connection params 00845 00846 @returns ble_error_t 00847 00848 @section EXAMPLE 00849 00850 @code 00851 00852 @endcode 00853 */ 00854 /**************************************************************************/ 00855 ble_error_t BlueNRGGap::getPreferredConnectionParams(ConnectionParams_t *params) 00856 { 00857 /* avoid compiler warnings about unused variables */ 00858 (void)params; 00859 00860 return BLE_ERROR_NOT_IMPLEMENTED; 00861 } 00862 00863 00864 /**************************************************************************/ 00865 /*! 00866 @brief sets preferred connection params 00867 00868 @returns ble_error_t 00869 00870 @section EXAMPLE 00871 00872 @code 00873 00874 @endcode 00875 */ 00876 /**************************************************************************/ 00877 ble_error_t BlueNRGGap::setPreferredConnectionParams(const ConnectionParams_t *params) 00878 { 00879 /* avoid compiler warnings about unused variables */ 00880 (void)params; 00881 00882 return BLE_ERROR_NOT_IMPLEMENTED; 00883 } 00884 00885 /**************************************************************************/ 00886 /*! 00887 @brief updates preferred connection params 00888 00889 @returns ble_error_t 00890 00891 @section EXAMPLE 00892 00893 @code 00894 00895 @endcode 00896 */ 00897 /**************************************************************************/ 00898 ble_error_t BlueNRGGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *params) 00899 { 00900 /* avoid compiler warnings about unused variables */ 00901 (void) handle; 00902 (void)params; 00903 00904 return BLE_ERROR_NONE; 00905 } 00906 00907 /**************************************************************************/ 00908 /*! 00909 @brief Sets the Device Name Characteristic 00910 00911 @param[in] deviceName 00912 pointer to device name to be set 00913 00914 @returns ble_error_t 00915 00916 @retval BLE_ERROR_NONE 00917 Everything executed properly 00918 00919 @section EXAMPLE 00920 00921 @code 00922 00923 @endcode 00924 */ 00925 /**************************************************************************/ 00926 ble_error_t BlueNRGGap::setDeviceName(const uint8_t *deviceName) 00927 { 00928 tBleStatus ret; 00929 uint8_t nameLen = 0; 00930 00931 nameLen = strlen((const char*)deviceName); 00932 PRINTF("DeviceName Size=%d\n\r", nameLen); 00933 00934 ret = aci_gatt_update_char_value(g_gap_service_handle, 00935 g_device_name_char_handle, 00936 0, 00937 nameLen, 00938 deviceName); 00939 00940 if (BLE_STATUS_SUCCESS != ret){ 00941 PRINTF("device set name failed (ret=0x%x)!!\n\r", ret) ; 00942 switch (ret) { 00943 case BLE_STATUS_INVALID_HANDLE: 00944 case BLE_STATUS_INVALID_PARAMETER: 00945 return BLE_ERROR_INVALID_PARAM; 00946 case BLE_STATUS_INSUFFICIENT_RESOURCES: 00947 return BLE_ERROR_NO_MEM; 00948 case BLE_STATUS_TIMEOUT: 00949 return BLE_STACK_BUSY; 00950 default: 00951 return BLE_ERROR_UNSPECIFIED; 00952 } 00953 } 00954 00955 return BLE_ERROR_NONE; 00956 } 00957 00958 /**************************************************************************/ 00959 /*! 00960 @brief Gets the Device Name Characteristic 00961 00962 @param[in] deviceName 00963 pointer to device name 00964 00965 @param[in] lengthP 00966 pointer to device name length 00967 00968 @returns ble_error_t 00969 00970 @retval BLE_ERROR_NONE 00971 Everything executed properly 00972 00973 @section EXAMPLE 00974 00975 @code 00976 00977 @endcode 00978 */ 00979 /**************************************************************************/ 00980 ble_error_t BlueNRGGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP) 00981 { 00982 tBleStatus ret; 00983 00984 ret = aci_gatt_read_handle_value(g_device_name_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE, 00985 *lengthP, 00986 (uint16_t *)lengthP, 00987 deviceName); 00988 PRINTF("getDeviceName ret=0x%02x (lengthP=%d)\n\r", ret, *lengthP); 00989 if (ret == BLE_STATUS_SUCCESS) { 00990 return BLE_ERROR_NONE; 00991 } else { 00992 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00993 } 00994 } 00995 00996 /**************************************************************************/ 00997 /*! 00998 @brief Sets the Device Appearance Characteristic 00999 01000 @param[in] appearance 01001 device appearance 01002 01003 @returns ble_error_t 01004 01005 @retval BLE_ERROR_NONE 01006 Everything executed properly 01007 01008 @section EXAMPLE 01009 01010 @code 01011 01012 @endcode 01013 */ 01014 /**************************************************************************/ 01015 ble_error_t BlueNRGGap::setAppearance(GapAdvertisingData::Appearance appearance) 01016 { 01017 tBleStatus ret; 01018 uint8_t deviceAppearance[2]; 01019 01020 STORE_LE_16(deviceAppearance, appearance); 01021 PRINTF("input: incoming = %d deviceAppearance= 0x%x 0x%x\n\r", appearance, deviceAppearance[1], deviceAppearance[0]); 01022 01023 ret = aci_gatt_update_char_value(g_gap_service_handle, 01024 g_appearance_char_handle, 01025 0, 2, (uint8_t *)deviceAppearance); 01026 if (BLE_STATUS_SUCCESS == ret){ 01027 return BLE_ERROR_NONE; 01028 } 01029 01030 PRINTF("setAppearance failed (ret=0x%x)!!\n\r", ret); 01031 switch (ret) { 01032 case BLE_STATUS_INVALID_HANDLE: 01033 case BLE_STATUS_INVALID_PARAMETER: 01034 return BLE_ERROR_INVALID_PARAM; 01035 case BLE_STATUS_INSUFFICIENT_RESOURCES: 01036 return BLE_ERROR_NO_MEM; 01037 case BLE_STATUS_TIMEOUT: 01038 return BLE_STACK_BUSY; 01039 default: 01040 return BLE_ERROR_UNSPECIFIED; 01041 } 01042 } 01043 01044 /**************************************************************************/ 01045 /*! 01046 @brief Gets the Device Appearance Characteristic 01047 01048 @param[in] appearance 01049 pointer to device appearance value 01050 01051 @returns ble_error_t 01052 01053 @retval BLE_ERROR_NONE 01054 Everything executed properly 01055 01056 @section EXAMPLE 01057 01058 @code 01059 01060 @endcode 01061 */ 01062 /**************************************************************************/ 01063 ble_error_t BlueNRGGap::getAppearance(GapAdvertisingData::Appearance *appearanceP) 01064 { 01065 tBleStatus ret; 01066 uint16_t lengthP = 2; 01067 01068 ret = aci_gatt_read_handle_value(g_appearance_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE, 01069 lengthP, 01070 &lengthP, 01071 (uint8_t*)appearanceP); 01072 PRINTF("getAppearance ret=0x%02x (lengthP=%d)\n\r", ret, lengthP); 01073 if (ret == BLE_STATUS_SUCCESS) { 01074 return BLE_ERROR_NONE; 01075 } else { 01076 return BLE_ERROR_PARAM_OUT_OF_RANGE; 01077 } 01078 01079 } 01080 01081 GapScanningParams* BlueNRGGap::getScanningParams(void) 01082 { 01083 return &_scanningParams; 01084 } 01085 01086 static void makeConnection(void) 01087 { 01088 BlueNRGGap::getInstance().createConnection(); 01089 } 01090 01091 void BlueNRGGap::Discovery_CB(Reason_t reason, 01092 uint8_t adv_type, 01093 uint8_t addr_type, 01094 uint8_t *addr, 01095 uint8_t *data_length, 01096 uint8_t *data, 01097 uint8_t *RSSI) 01098 { 01099 switch (reason) { 01100 case DEVICE_FOUND: 01101 { 01102 GapAdvertisingParams::AdvertisingType_t type; 01103 bool isScanResponse = false; 01104 01105 /* 01106 * Whitelisting (scan policy): 01107 * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) && 01108 * Private Random Address 01109 * => scan_results = FALSE 01110 * FIXME: the Security Manager should be implemented 01111 */ 01112 ScanningPolicyMode_t mode = getScanningPolicyMode(); 01113 PRINTF("mode=%u addr_type=%u\n\r", mode, addr_type); 01114 if(mode == Gap::SCAN_POLICY_FILTER_ALL_ADV || 01115 (addr_type == RESOLVABLE_PRIVATE_ADDR || 01116 addr_type == NON_RESOLVABLE_PRIVATE_ADDR)) { 01117 return; 01118 } 01119 01120 switch(adv_type) { 01121 case ADV_IND: 01122 type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED; 01123 break; 01124 case ADV_DIRECT_IND: 01125 type = GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED; 01126 break; 01127 case ADV_SCAN_IND: 01128 case SCAN_RSP: 01129 type = GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED; 01130 isScanResponse = true; 01131 break; 01132 case ADV_NONCONN_IND: 01133 type = GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED; 01134 break; 01135 default: 01136 type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED; 01137 } 01138 01139 PRINTF("data_length=%d adv peerAddr[%02x %02x %02x %02x %02x %02x] \r\n", 01140 *data_length, addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]); 01141 if(!_connecting) { 01142 processAdvertisementReport(addr, *RSSI, isScanResponse, type, *data_length, data); 01143 } 01144 PRINTF("!!!After processAdvertisementReport\n\r"); 01145 } 01146 break; 01147 01148 case DISCOVERY_COMPLETE: 01149 // The discovery is complete. If this is due to a stop scanning (i.e., the device 01150 // we are interested in has been found) and a connection has been requested 01151 // then we start the device connection. 01152 PRINTF("DISCOVERY_COMPLETE\n\r"); 01153 _scanning = false; 01154 01155 // Since the DISCOVERY_COMPLETE event can be received during the scanning interval, 01156 // we need to delay the starting of connection 01157 uint16_t delay = 2*(_scanningParams.getInterval()); 01158 01159 #ifdef AST_FOR_MBED_OS 01160 if(_connecting) { 01161 minar::Scheduler::postCallback(makeConnection).delay(minar::milliseconds(delay)); 01162 } 01163 #else 01164 Clock_Wait(delay); 01165 if(_connecting) { 01166 makeConnection(); 01167 } 01168 #endif /* AST_FOR_MBED_OS */ 01169 01170 break; 01171 } 01172 } 01173 01174 ble_error_t BlueNRGGap::startRadioScan(const GapScanningParams &scanningParams) 01175 { 01176 01177 tBleStatus ret = BLE_STATUS_SUCCESS; 01178 01179 // Stop ADV before scanning 01180 /* 01181 if (state.advertising == 1) { 01182 stopAdvertising(); 01183 } 01184 */ 01185 01186 /* 01187 * Whitelisting (scan policy): 01188 * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) && 01189 * White List is empty 01190 * => scan operation = FAILURE 01191 * FIXME: the Security Manager should be implemented 01192 */ 01193 ScanningPolicyMode_t mode = getScanningPolicyMode(); 01194 uint8_t whiteListSize = whitelistAddresses.size; 01195 if(whiteListSize == 0 && mode == Gap::SCAN_POLICY_FILTER_ALL_ADV) { 01196 return BLE_ERROR_OPERATION_NOT_PERMITTED; 01197 } 01198 01199 ret = btleStartRadioScan(scanningParams.getActiveScanning(), 01200 scanningParams.getInterval(), 01201 scanningParams.getWindow(), 01202 addr_type); 01203 01204 PRINTF("Scanning...\n\r"); 01205 PRINTF("scanningParams.getInterval()=%u[msec]\r\n",(scanningParams.getInterval()*625)/1000); 01206 PRINTF("scanningParams.getWindow()=%u[msec]\r\n",(scanningParams.getWindow()*625)/1000); 01207 //PRINTF("_advParams.getInterval()=%u\r\n",_advParams.getInterval()); 01208 //PRINTF("CONN_P1=%u\r\n",(unsigned)CONN_P1); 01209 //PRINTF("CONN_P2=%u\r\n",(unsigned)CONN_P2); 01210 if (BLE_STATUS_SUCCESS == ret){ 01211 PRINTF("Observation Procedure Started\n"); 01212 _scanning = true; 01213 return BLE_ERROR_NONE; 01214 } 01215 01216 // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED 01217 switch (ret) { 01218 case BLE_STATUS_INVALID_CID: 01219 PRINTF("Observation Procedure not implemented!!!\n\r"); 01220 return BLE_ERROR_NOT_IMPLEMENTED; 01221 default: 01222 PRINTF("Observation Procedure failed (0x%02X)\n\r", ret); 01223 return BLE_ERROR_UNSPECIFIED; 01224 } 01225 01226 } 01227 01228 ble_error_t BlueNRGGap::stopScan() { 01229 tBleStatus ret = BLE_STATUS_SUCCESS; 01230 01231 PRINTF("stopScan\n\r"); 01232 ret = aci_gap_terminate_gap_procedure(GAP_OBSERVATION_PROC); 01233 01234 if (ret != BLE_STATUS_SUCCESS) { 01235 PRINTF("GAP Terminate Gap Procedure failed(ret=0x%x)\n", ret); 01236 return BLE_ERROR_UNSPECIFIED; 01237 } else { 01238 PRINTF("Discovery Procedure Terminated\n"); 01239 return BLE_ERROR_NONE; 01240 } 01241 } 01242 01243 /**************************************************************************/ 01244 /*! 01245 @brief set Tx power level 01246 @param[in] txPower Transmission Power level 01247 @returns ble_error_t 01248 */ 01249 /**************************************************************************/ 01250 ble_error_t BlueNRGGap::setTxPower(int8_t txPower) 01251 { 01252 tBleStatus ret; 01253 01254 int8_t enHighPower = 0; 01255 int8_t paLevel = 0; 01256 01257 ret = getHighPowerAndPALevelValue(txPower, enHighPower, paLevel); 01258 if(ret!=BLE_STATUS_SUCCESS) { 01259 return BLE_ERROR_PARAM_OUT_OF_RANGE; 01260 } 01261 01262 PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); 01263 ret = aci_hal_set_tx_power_level(enHighPower, paLevel); 01264 if(ret!=BLE_STATUS_SUCCESS) { 01265 return BLE_ERROR_PARAM_OUT_OF_RANGE; 01266 } 01267 01268 return BLE_ERROR_NONE; 01269 } 01270 01271 /**************************************************************************/ 01272 /*! 01273 @brief get permitted Tx power values 01274 @param[in] values pointer to pointer to permitted power values 01275 @param[in] num number of values 01276 */ 01277 /**************************************************************************/ 01278 void BlueNRGGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) { 01279 static const int8_t permittedTxValues[] = { 01280 -18, -15, -14, -12, -11, -9, -8, -6, -5, -2, 0, 2, 4, 5, 8 01281 }; 01282 01283 *valueArrayPP = permittedTxValues; 01284 *countP = sizeof(permittedTxValues) / sizeof(int8_t); 01285 } 01286 01287 /**************************************************************************/ 01288 /*! 01289 @brief Set advertising parameters according to the current state 01290 Parameters value is set taking into account guidelines of the BlueNRG 01291 time slots allocation 01292 */ 01293 /**************************************************************************/ 01294 void BlueNRGGap::setAdvParameters(void) 01295 { 01296 uint32_t advIntMS; 01297 01298 if(state.connected == 1) { 01299 advIntMS = (conn_min_interval*1.25)-GUARD_INT; 01300 advInterval = _advParams.MSEC_TO_ADVERTISEMENT_DURATION_UNITS(advIntMS); 01301 } else { 01302 advInterval = _advParams.getIntervalInADVUnits(); 01303 } 01304 } 01305 01306 /**************************************************************************/ 01307 /*! 01308 @brief Set connection parameters according to the current state (ADV and/or SCAN) 01309 Parameters value is set taking into account guidelines of the BlueNRG 01310 time slots allocation 01311 */ 01312 /**************************************************************************/ 01313 void BlueNRGGap::setConnectionParameters(void) 01314 { 01315 if (state.advertising == 1) { 01316 01317 if (_scanningParams.getInterval() < advInterval) { 01318 PRINTF("state.adv=1 scanInterval<advInterval\r\n"); 01319 scanInterval = advInterval; 01320 scanWindow = advInterval; 01321 } else { 01322 PRINTF("state.adv=1 scanInterval>=advInterval\r\n"); 01323 scanInterval = _scanningParams.getInterval(); 01324 scanWindow = _scanningParams.getWindow(); 01325 } 01326 01327 if(advInterval>(MAX_INT_CONN-(GUARD_INT/1.25))) { //(4000-GUARD_INT)ms 01328 conn_min_interval = MAX_INT_CONN; 01329 conn_max_interval = MAX_INT_CONN; 01330 } else { 01331 conn_min_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25; 01332 conn_max_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25; 01333 } 01334 01335 } else { 01336 01337 PRINTF("state.adv = 0\r\n"); 01338 01339 scanInterval = _scanningParams.getInterval(); 01340 scanWindow = _scanningParams.getWindow(); 01341 if(SCAN_DURATION_UNITS_TO_MSEC(scanInterval)>(MAX_INT_CONN*1.25) || 01342 SCAN_DURATION_UNITS_TO_MSEC(scanInterval)<(MIN_INT_CONN*1.25)) { //(4000)ms || (7.5)ms 01343 conn_min_interval = DEF_INT_CONN; 01344 conn_max_interval = DEF_INT_CONN; 01345 } else { 01346 conn_min_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25; 01347 conn_max_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25; 01348 } 01349 } 01350 PRINTF("scanInterval=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanInterval)); 01351 PRINTF("scanWindow()=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanWindow)); 01352 PRINTF("conn_min_interval=%u[msec]\r\n",(unsigned)(conn_min_interval*1.25)); 01353 PRINTF("conn_max_interval=%u[msec]\r\n",(unsigned)(conn_max_interval*1.25)); 01354 01355 } 01356 01357 ble_error_t BlueNRGGap::createConnection () 01358 { 01359 tBleStatus ret; 01360 01361 /* 01362 Before creating connection, set parameters according 01363 to previous or current procedure (ADV and/or SCAN) 01364 */ 01365 setConnectionParameters(); 01366 01367 /* 01368 Scan_Interval, Scan_Window, Peer_Address_Type, Peer_Address, Own_Address_Type, Conn_Interval_Min, 01369 Conn_Interval_Max, Conn_Latency, Supervision_Timeout, Conn_Len_Min, Conn_Len_Max 01370 */ 01371 ret = aci_gap_create_connection(scanInterval, 01372 scanWindow, 01373 _peerAddrType, 01374 (unsigned char*)_peerAddr, 01375 addr_type, 01376 conn_min_interval, conn_max_interval, 0, 01377 SUPERV_TIMEOUT, CONN_L1, CONN_L1); 01378 01379 //_connecting = false; 01380 01381 if (ret != BLE_STATUS_SUCCESS) { 01382 PRINTF("Error while starting connection (ret=0x%02X).\n\r", ret); 01383 return BLE_ERROR_UNSPECIFIED; 01384 } else { 01385 PRINTF("Connection started.\n"); 01386 _connecting = false; 01387 return BLE_ERROR_NONE; 01388 } 01389 } 01390 01391 ble_error_t BlueNRGGap::connect (const Gap::Address_t peerAddr, 01392 Gap::AddressType_t peerAddrType, 01393 const ConnectionParams_t *connectionParams, 01394 const GapScanningParams *scanParams) 01395 { 01396 /* avoid compiler warnings about unused variables */ 01397 (void)connectionParams; 01398 (void)scanParams; 01399 01400 // Save the peer address 01401 for(int i=0; i<BDADDR_SIZE; i++) { 01402 _peerAddr[i] = peerAddr[i]; 01403 } 01404 _peerAddrType = peerAddrType; 01405 01406 _connecting = true; 01407 01408 if(_scanning) { 01409 stopScan(); 01410 } else { 01411 PRINTF("Calling createConnection from connect()\n\r"); 01412 return createConnection(); 01413 } 01414 01415 return BLE_ERROR_NONE; 01416 } 01417 01418 /**************************************************************************/ 01419 /*! 01420 @brief Set the advertising policy filter mode that will be used in 01421 the next call to startAdvertising(). 01422 01423 @returns \ref ble_errror_t 01424 01425 @retval BLE_ERROR_NONE 01426 Everything executed properly. 01427 01428 BLE_ERROR_NOT_IMPLEMENTED 01429 This feature is currently note implemented. 01430 */ 01431 /**************************************************************************/ 01432 ble_error_t BlueNRGGap::setAdvertisingPolicyMode(Gap::AdvertisingPolicyMode_t mode) 01433 { 01434 advertisingPolicyMode = mode; 01435 01436 return BLE_ERROR_NONE; 01437 } 01438 01439 /**************************************************************************/ 01440 /*! 01441 @brief Set the scanning policy filter mode that will be used in 01442 the next call to startAdvertising(). 01443 01444 @returns \ref ble_errror_t 01445 01446 @retval BLE_ERROR_NONE 01447 Everything executed properly. 01448 01449 BLE_ERROR_NOT_IMPLEMENTED 01450 This feature is currently note implemented. 01451 */ 01452 /**************************************************************************/ 01453 ble_error_t BlueNRGGap::setScanningPolicyMode(Gap::ScanningPolicyMode_t mode) 01454 { 01455 scanningPolicyMode = mode; 01456 01457 return BLE_ERROR_NONE; 01458 } 01459 01460 /**************************************************************************/ 01461 /*! 01462 @brief Get the current advertising policy filter mode. 01463 01464 @returns The advertising policy filter mode. 01465 */ 01466 /**************************************************************************/ 01467 Gap::AdvertisingPolicyMode_t BlueNRGGap::getAdvertisingPolicyMode(void) const 01468 { 01469 return advertisingPolicyMode; 01470 } 01471 01472 /**************************************************************************/ 01473 /*! 01474 @brief Get the current scanning policy filter mode. 01475 01476 @returns The scanning policy filter mode. 01477 01478 */ 01479 /**************************************************************************/ 01480 Gap::ScanningPolicyMode_t BlueNRGGap::getScanningPolicyMode(void) const 01481 { 01482 return scanningPolicyMode; 01483 } 01484 01485 /**************************************************************************/ 01486 /*! 01487 @brief Clear BlueNRGGap's state. 01488 01489 @returns ble_error_t 01490 01491 @retval BLE_ERROR_NONE 01492 Everything executed properly 01493 */ 01494 /**************************************************************************/ 01495 ble_error_t BlueNRGGap::reset(void) 01496 { 01497 /* Clear all state that is from the parent, including private members */ 01498 if (Gap::reset() != BLE_ERROR_NONE) { 01499 return BLE_ERROR_INVALID_STATE; 01500 } 01501 01502 /* Clear derived class members */ 01503 m_connectionHandle = BLE_CONN_HANDLE_INVALID; 01504 01505 memset(deviceAppearance, 0, sizeof(deviceAppearance)); 01506 memset(local_name, 0, LOCAL_NAME_MAX_SIZE); 01507 memset(local_name, 0, UUID_BUFFER_SIZE); 01508 memset(AdvData, 0, ADV_DATA_MAX_SIZE); 01509 01510 /* Set the whitelist policy filter modes to IGNORE_WHITELIST */ 01511 advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST; 01512 scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST; 01513 01514 return BLE_ERROR_NONE; 01515 } 01516
Generated on Thu Jul 14 2022 01:08:08 by
1.7.2
