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