My fork of X_NUCLEO_IDB0XA1
Fork of X_NUCLEO_IDB0XA1 by
Embed:
(wiki syntax)
Show/hide line numbers
BlueNRGGap.cpp
Go to the documentation of this file.
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 Wed Jul 13 2022 03:04:51 by 1.7.2