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