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