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.
Dependencies: HC_SR04_Ultrasonic_Library Servo mbed
Fork of FIP_REV1 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 #include "BlueNRGDevice.h" 00018 #include "mbed.h" 00019 #include "Payload.h" 00020 #include "Utils.h" 00021 00022 //Local Variables 00023 const char *local_name = NULL; 00024 uint8_t local_name_length = 0; 00025 const uint8_t *scan_response_payload = NULL; 00026 uint8_t scan_rsp_length = 0; 00027 uint8_t servUuidlength = 0; 00028 uint8_t* servUuidData = NULL; 00029 00030 uint32_t advtInterval = 0; 00031 00032 /**************************************************************************/ 00033 /*! 00034 @brief Sets the advertising parameters and payload for the device. 00035 Note: Some data types give error when their adv data is updated using aci_gap_update_adv_data() API 00036 00037 @param[in] params 00038 Basic advertising details, including the advertising 00039 delay, timeout and how the device should be advertised 00040 @params[in] advData 00041 The primary advertising data payload 00042 @params[in] scanResponse 00043 The optional Scan Response payload if the advertising 00044 type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED 00045 in \ref GapAdveritinngParams 00046 00047 @returns \ref ble_error_t 00048 00049 @retval BLE_ERROR_NONE 00050 Everything executed properly 00051 00052 @retval BLE_ERROR_BUFFER_OVERFLOW 00053 The proposed action would cause a buffer overflow. All 00054 advertising payloads must be <= 31 bytes, for example. 00055 00056 @retval BLE_ERROR_NOT_IMPLEMENTED 00057 A feature was requested that is not yet supported in the 00058 nRF51 firmware or hardware. 00059 00060 @retval BLE_ERROR_PARAM_OUT_OF_RANGE 00061 One of the proposed values is outside the valid range. 00062 00063 @section EXAMPLE 00064 00065 @code 00066 00067 @endcode 00068 */ 00069 /**************************************************************************/ 00070 ble_error_t BlueNRGGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse) 00071 { 00072 DEBUG("BlueNRGGap::setAdvertisingData\n\r"); 00073 /* Make sure we don't exceed the advertising payload length */ 00074 if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) { 00075 return BLE_ERROR_BUFFER_OVERFLOW; 00076 } 00077 00078 /* Make sure we have a payload! */ 00079 if (advData.getPayloadLen() <= 0) { 00080 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00081 } else { 00082 PayloadPtr loadPtr(advData.getPayload(), advData.getPayloadLen()); 00083 for(uint8_t index=0; index<loadPtr.getPayloadUnitCount(); index++) { 00084 PayloadUnit unit = loadPtr.getUnitAtIndex(index); 00085 00086 DEBUG("adData[%d].length=%d\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getLenPtr())); 00087 DEBUG("adData[%d].AdType=0x%x\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr())); 00088 00089 #if 0 00090 00091 int err = aci_gap_update_adv_data(*loadPtr.getUnitAtIndex(index).getLenPtr(), loadPtr.getUnitAtIndex(index).getAdTypePtr()); 00092 if(BLE_STATUS_SUCCESS!=err) { 00093 DEBUG("error occurred while adding adv data\n\r"); 00094 return BLE_ERROR_PARAM_OUT_OF_RANGE; // no other suitable error code is available 00095 DEBUG("error occurred while adding adv data for Adv type 0x%x, errCode = 0x%x\n", *loadPtr.getUnitAtIndex(index).getAdTypePtr(), err); 00096 //return BLE_ERROR_PARAM_OUT_OF_RANGE; // no other suitable error code is available 00097 } 00098 #endif 00099 //UnitPayload unitLoad = load.getPayLoadAtIndex(index); 00100 switch(*loadPtr.getUnitAtIndex(index).getAdTypePtr()) { 00101 case GapAdvertisingData::FLAGS: /* ref *Flags */ 00102 //Check if Flags are OK. BlueNRG only supports LE Mode. 00103 uint8_t *flags = loadPtr.getUnitAtIndex(index).getDataPtr(); 00104 if((*flags & GapAdvertisingData::BREDR_NOT_SUPPORTED) != GapAdvertisingData::BREDR_NOT_SUPPORTED) { 00105 DEBUG("BlueNRG does not support BR/EDR Mode"); 00106 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00107 } 00108 00109 break; 00110 case GapAdvertisingData::INCOMPLETE_LIST_16BIT_SERVICE_IDS: /**< Incomplete list of 16-bit Service IDs */ 00111 break; 00112 case GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS: /**< Complete list of 16-bit Service IDs */ 00113 DEBUG("Advertising type: COMPLETE_LIST_16BIT_SERVICE_IDS\n\r"); 00114 DEBUG("Advertising type: COMPLETE_LIST_16BIT_SERVICE_IDS\n"); 00115 #if 0 00116 int err = aci_gap_update_adv_data(*loadPtr.getUnitAtIndex(index).getLenPtr(), loadPtr.getUnitAtIndex(index).getAdTypePtr()); 00117 if(BLE_STATUS_SUCCESS!=err) { 00118 DEBUG("error occurred while adding adv data\n"); 00119 return BLE_ERROR_PARAM_OUT_OF_RANGE; // no other suitable error code is available 00120 } 00121 #endif 00122 break; 00123 case GapAdvertisingData::INCOMPLETE_LIST_32BIT_SERVICE_IDS: /**< Incomplete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */ 00124 break; 00125 case GapAdvertisingData::COMPLETE_LIST_32BIT_SERVICE_IDS: /**< Complete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */ 00126 break; 00127 case GapAdvertisingData::INCOMPLETE_LIST_128BIT_SERVICE_IDS: /**< Incomplete list of 128-bit Service IDs */ 00128 break; 00129 case GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS: /**< Complete list of 128-bit Service IDs */ 00130 break; 00131 case GapAdvertisingData::SHORTENED_LOCAL_NAME: /**< Shortened Local Name */ 00132 break; 00133 case GapAdvertisingData::COMPLETE_LOCAL_NAME: /**< Complete Local Name */ 00134 DEBUG("Advertising type: COMPLETE_LOCAL_NAME\n\r"); 00135 loadPtr.getUnitAtIndex(index).printDataAsString(); 00136 local_name_length = *loadPtr.getUnitAtIndex(index).getLenPtr()-1; 00137 local_name = (const char*)loadPtr.getUnitAtIndex(index).getAdTypePtr(); 00138 //for(int i=0; i<local_name_length; i++) DEBUG("\n%c", local_name[i]); 00139 /*aci_gatt_update_char_value(g_gap_service_handle, 00140 g_device_name_char_handle, 00141 0, 00142 local_name_length, 00143 (tHalUint8 *)local_name);*/ 00144 //COMPLETE_LOCAL_NAME is only advertising device name. Gatt Device Name is not the same.(Must be set right after GAP/GATT init?) 00145 00146 00147 DEBUG("device_name length=%d\n\r", local_name_length); 00148 break; 00149 00150 case GapAdvertisingData::TX_POWER_LEVEL: /**< TX Power Level (in dBm) */ 00151 DEBUG("Advertising type: TX_POWER_LEVEL\n\r"); 00152 int8_t dbm = *loadPtr.getUnitAtIndex(index).getDataPtr(); 00153 int8_t enHighPower = 0; 00154 int8_t paLevel = 0; 00155 int8_t dbmActuallySet = getHighPowerAndPALevelValue(dbm, enHighPower, paLevel); 00156 DEBUG("dbm=%d, dbmActuallySet=%d\n\r", dbm, dbmActuallySet); 00157 DEBUG("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); 00158 aci_hal_set_tx_power_level(enHighPower, paLevel); 00159 break; 00160 case GapAdvertisingData::DEVICE_ID: /**< Device ID */ 00161 break; 00162 case GapAdvertisingData::SLAVE_CONNECTION_INTERVAL_RANGE: /**< Slave :Connection Interval Range */ 00163 break; 00164 case GapAdvertisingData::SERVICE_DATA: /**< Service Data */ 00165 break; 00166 case GapAdvertisingData::APPEARANCE: 00167 /* 00168 Tested with GapAdvertisingData::GENERIC_PHONE. 00169 for other appearances BLE Scanner android app is not behaving properly 00170 */ 00171 DEBUG("Advertising type: APPEARANCE\n\r"); 00172 const char *deviceAppearance = NULL; 00173 deviceAppearance = (const char*)loadPtr.getUnitAtIndex(index).getDataPtr(); // to be set later when startAdvertising() is called 00174 00175 uint8_t Appearance[2]; 00176 uint16_t devP = (uint16_t)*deviceAppearance; 00177 STORE_LE_16(Appearance, (uint16_t)devP); 00178 00179 DEBUG("input: deviceAppearance= 0x%x 0x%x..., strlen(deviceAppearance)=%d\n\r", Appearance[1], Appearance[0], (uint8_t)*loadPtr.getUnitAtIndex(index).getLenPtr()-1); /**< \ref Appearance */ 00180 00181 aci_gatt_update_char_value(g_gap_service_handle, g_appearance_char_handle, 0, 2, (tHalUint8 *)deviceAppearance);//not using array Appearance[2] 00182 break; 00183 case GapAdvertisingData::ADVERTISING_INTERVAL: /**< Advertising Interval */ 00184 advtInterval = (uint16_t)(*loadPtr.getUnitAtIndex(index).getDataPtr()); 00185 DEBUG("advtInterval=%d\n\r", advtInterval); 00186 break; 00187 case GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA: /**< Manufacturer Specific Data */ 00188 break; 00189 00190 } 00191 } 00192 //Set the SCAN_RSP Payload 00193 scan_response_payload = scanResponse.getPayload(); 00194 scan_rsp_length = scanResponse.getPayloadLen(); 00195 } 00196 return BLE_ERROR_NONE; 00197 } 00198 00199 /**************************************************************************/ 00200 /*! 00201 @brief Starts the BLE HW, initialising any services that were 00202 added before this function was called. 00203 00204 @note All services must be added before calling this function! 00205 00206 @returns ble_error_t 00207 00208 @retval BLE_ERROR_NONE 00209 Everything executed properly 00210 00211 @section EXAMPLE 00212 00213 @code 00214 00215 @endcode 00216 */ 00217 /**************************************************************************/ 00218 ble_error_t BlueNRGGap::startAdvertising(const GapAdvertisingParams ¶ms) 00219 { 00220 /* Make sure we support the advertising type */ 00221 if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) { 00222 /* ToDo: This requires a propery security implementation, etc. */ 00223 return BLE_ERROR_NOT_IMPLEMENTED; 00224 } 00225 00226 /* Check interval range */ 00227 if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) { 00228 /* Min delay is slightly longer for unconnectable devices */ 00229 if ((params.getInterval() < GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) || 00230 (params.getInterval() > GAP_ADV_PARAMS_INTERVAL_MAX)) { 00231 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00232 } 00233 } else { 00234 if ((params.getInterval() < GAP_ADV_PARAMS_INTERVAL_MIN) || 00235 (params.getInterval() > GAP_ADV_PARAMS_INTERVAL_MAX)) { 00236 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00237 } 00238 } 00239 00240 /* Check timeout is zero for Connectable Directed */ 00241 if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) { 00242 /* Timeout must be 0 with this type, although we'll never get here */ 00243 /* since this isn't implemented yet anyway */ 00244 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00245 } 00246 00247 /* Check timeout for other advertising types */ 00248 if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && 00249 (params.getTimeout() > GAP_ADV_PARAMS_TIMEOUT_MAX)) { 00250 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00251 } 00252 00253 tBleStatus ret; 00254 00255 //const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; 00256 //const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,device_name[27],device_name[28],device_name[29],device_name[30], device_name[31], 00257 // device_name[32], device_name[33], device_name[34], device_name[35], device_name[36]}; 00258 00259 00260 00261 //const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,device_name[27],device_name[28]}; 00262 const LongUUID_t HRM_SERVICE_UUID_128 = {0x18, 0x0D}; 00263 /* set scan response data */ 00264 hci_le_set_scan_resp_data(scan_rsp_length, scan_response_payload); /*int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]);*/ 00265 00266 /*aci_gap_set_discoverable(Advertising_Event_Type, Adv_min_intvl, Adv_Max_Intvl, Addr_Type, Adv_Filter_Policy, 00267 Local_Name_Length, local_name, service_uuid_length, service_uuid_list, Slave_conn_intvl_min, Slave_conn_intvl_max);*/ 00268 /*LINK_LAYER.H DESCRIBES THE ADVERTISING TYPES*/ 00269 00270 char* name = NULL; 00271 uint8_t nameLen = 0; 00272 if(local_name!=NULL) { 00273 name = (char*)local_name; 00274 DEBUG("name=%s\n\r", name); 00275 nameLen = local_name_length; 00276 } else { 00277 char str[] = "ST_BLE_DEV"; 00278 name = new char[strlen(str)+1]; 00279 name[0] = AD_TYPE_COMPLETE_LOCAL_NAME; 00280 strcpy(name+1, str); 00281 nameLen = strlen(name); 00282 DEBUG("nameLen=%d\n\r", nameLen); 00283 DEBUG("name=%s\n\r", name); 00284 } 00285 00286 00287 advtInterval = params.getInterval(); // set advtInterval in case it is not already set by user application 00288 ret = aci_gap_set_discoverable(params.getAdvertisingType(), // Advertising_Event_Type 00289 0, // Adv_Interval_Min 00290 advtInterval, // Adv_Interval_Max 00291 PUBLIC_ADDR, // Address_Type <hdd> It seems there is some problem with RANDOM_ADDRESS. <problem_desc> When RANDOM_ADDRESS is selected device name is not being handled properly, i.e. wrong device name is seen by android app </problem_desc> 00292 NO_WHITE_LIST_USE, // Adv_Filter_Policy 00293 nameLen, //local_name_length, // Local_Name_Length 00294 (const char*)name, //local_name, // Local_Name 00295 servUuidlength, //Service_Uuid_Length 00296 servUuidData, //Service_Uuid_List 00297 0, // Slave_Conn_Interval_Min 00298 0); // Slave_Conn_Interval_Max 00299 00300 state.advertising = 1; 00301 00302 return BLE_ERROR_NONE; 00303 } 00304 00305 /**************************************************************************/ 00306 /*! 00307 @brief Stops the BLE HW and disconnects from any devices 00308 00309 @returns ble_error_t 00310 00311 @retval BLE_ERROR_NONE 00312 Everything executed properly 00313 00314 @section EXAMPLE 00315 00316 @code 00317 00318 @endcode 00319 */ 00320 /**************************************************************************/ 00321 ble_error_t BlueNRGGap::stopAdvertising(void) 00322 { 00323 tBleStatus ret; 00324 00325 if(state.advertising == 1) { 00326 //Set non-discoverable to stop advertising 00327 ret = aci_gap_set_non_discoverable(); 00328 00329 if (ret != BLE_STATUS_SUCCESS){ 00330 DEBUG("Error in stopping advertisement!!\n\r") ; 00331 return BLE_ERROR_PARAM_OUT_OF_RANGE ; //Not correct Error Value 00332 //FIXME: Define Error values equivalent to BlueNRG Error Codes. 00333 } 00334 DEBUG("Advertisement stopped!!\n\r") ; 00335 //Set GapState_t::advertising state 00336 state.advertising = 0; 00337 } 00338 00339 return BLE_ERROR_NONE; 00340 } 00341 00342 /**************************************************************************/ 00343 /*! 00344 @brief Disconnects if we are connected to a central device 00345 00346 @returns ble_error_t 00347 00348 @retval BLE_ERROR_NONE 00349 Everything executed properly 00350 00351 @section EXAMPLE 00352 00353 @code 00354 00355 @endcode 00356 */ 00357 /**************************************************************************/ 00358 ble_error_t BlueNRGGap::disconnect(void) 00359 { 00360 tBleStatus ret; 00361 //For Reason codes check BlueTooth HCI Spec 00362 00363 if(m_connectionHandle != BLE_CONN_HANDLE_INVALID) { 00364 ret = aci_gap_terminate(m_connectionHandle, 0x16);//0x16 Connection Terminated by Local Host. 00365 00366 if (ret != BLE_STATUS_SUCCESS){ 00367 DEBUG("Error in GAP termination!!\n\r") ; 00368 return BLE_ERROR_PARAM_OUT_OF_RANGE ; //Not correct Error Value 00369 //FIXME: Define Error values equivalent to BlueNRG Error Codes. 00370 } 00371 00372 //DEBUG("Disconnected from localhost!!\n\r") ; 00373 m_connectionHandle = BLE_CONN_HANDLE_INVALID; 00374 } 00375 00376 return BLE_ERROR_NONE; 00377 } 00378 00379 /**************************************************************************/ 00380 /*! 00381 @brief Sets the 16-bit connection handle 00382 */ 00383 /**************************************************************************/ 00384 void BlueNRGGap::setConnectionHandle(uint16_t con_handle) 00385 { 00386 m_connectionHandle = con_handle; 00387 } 00388 00389 /**************************************************************************/ 00390 /*! 00391 @brief Gets the 16-bit connection handle 00392 */ 00393 /**************************************************************************/ 00394 uint16_t BlueNRGGap::getConnectionHandle(void) 00395 { 00396 return m_connectionHandle; 00397 } 00398 00399 /**************************************************************************/ 00400 /*! 00401 @brief Sets the BLE device address. SetAddress will reset the BLE 00402 device and re-initialize BTLE. Will not start advertising. 00403 00404 @returns ble_error_t 00405 00406 @section EXAMPLE 00407 00408 @code 00409 00410 @endcode 00411 */ 00412 /**************************************************************************/ 00413 ble_error_t BlueNRGGap::setAddress(addr_type_t type, const uint8_t address[6]) 00414 { 00415 tBleStatus ret; 00416 00417 if (type > ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE) { 00418 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00419 } 00420 00421 //copy address to bdAddr[6] 00422 for(int i=0; i<BDADDR_SIZE; i++) { 00423 bdaddr[i] = address[i]; 00424 //DEBUG("i[%d]:0x%x\n\r",i,bdaddr[i]); 00425 } 00426 00427 if(!isSetAddress) isSetAddress = true; 00428 00429 //Re-Init the BTLE Device with SetAddress as true 00430 //if(BlueNRGDevice::getIsInitialized())//Re-init only initialization is already done 00431 btle_init(isSetAddress); 00432 00433 //if (ret==BLE_STATUS_SUCCESS) 00434 return BLE_ERROR_NONE; 00435 } 00436 00437 /**************************************************************************/ 00438 /*! 00439 @brief Returns boolean if the address of the device has been set 00440 or not 00441 00442 @returns bool 00443 00444 @section EXAMPLE 00445 00446 @code 00447 00448 @endcode 00449 */ 00450 /**************************************************************************/ 00451 bool BlueNRGGap::getIsSetAddress() 00452 { 00453 return isSetAddress; 00454 } 00455 00456 /**************************************************************************/ 00457 /*! 00458 @brief Returns the address of the device if set 00459 00460 @returns ble_error_t 00461 00462 @section EXAMPLE 00463 00464 @code 00465 00466 @endcode 00467 */ 00468 /**************************************************************************/ 00469 tHalUint8* BlueNRGGap::getAddress() 00470 { 00471 if(isSetAddress) 00472 return bdaddr; 00473 else return NULL; 00474 } 00475 00476 /**************************************************************************/ 00477 /*! 00478 @brief obtains preferred connection params 00479 00480 @returns ble_error_t 00481 00482 @section EXAMPLE 00483 00484 @code 00485 00486 @endcode 00487 */ 00488 /**************************************************************************/ 00489 ble_error_t BlueNRGGap::getPreferredConnectionParams(ConnectionParams_t *params) 00490 { 00491 return BLE_ERROR_NONE; 00492 } 00493 00494 00495 /**************************************************************************/ 00496 /*! 00497 @brief sets preferred connection params 00498 00499 @returns ble_error_t 00500 00501 @section EXAMPLE 00502 00503 @code 00504 00505 @endcode 00506 */ 00507 /**************************************************************************/ 00508 ble_error_t BlueNRGGap::setPreferredConnectionParams(const ConnectionParams_t *params) 00509 { 00510 return BLE_ERROR_NONE; 00511 } 00512 00513 /**************************************************************************/ 00514 /*! 00515 @brief updates preferred connection params 00516 00517 @returns ble_error_t 00518 00519 @section EXAMPLE 00520 00521 @code 00522 00523 @endcode 00524 */ 00525 /**************************************************************************/ 00526 ble_error_t BlueNRGGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *params) 00527 { 00528 return BLE_ERROR_NONE; 00529 } 00530
Generated on Tue Jul 12 2022 21:41:59 by
