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.
BLEDevice.h
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 #ifndef __BLE_DEVICE__ 00018 #define __BLE_DEVICE__ 00019 00020 #include "blecommon.h" 00021 #include "Gap.h" 00022 #include "GattServer.h" 00023 #include "BLEDeviceInstanceBase.h" 00024 00025 /** 00026 * The base class used to abstract away BLE capable radio transceivers or SOCs, 00027 * to enable this BLE API to work with any radio transparently. 00028 */ 00029 class BLEDevice 00030 { 00031 public: 00032 /** 00033 * Initialize the BLE controller. This should be called before using 00034 * anything else in the BLE_API. 00035 */ 00036 ble_error_t init(); 00037 ble_error_t reset(void); 00038 00039 /* GAP specific APIs */ 00040 public: 00041 /** 00042 * Set the BTLE MAC address and type. 00043 * @return BLE_ERROR_NONE on success. 00044 */ 00045 ble_error_t setAddress(Gap::addr_type_t type, const Gap::address_t address); 00046 00047 /** 00048 * Fetch the BTLE MAC address and type. 00049 * @return BLE_ERROR_NONE on success. 00050 */ 00051 ble_error_t getAddress(Gap::addr_type_t *typeP, Gap::address_t address); 00052 00053 /** 00054 * @param[in] advType 00055 * The GAP advertising mode to use for this device. Valid 00056 * values are defined in AdvertisingType: 00057 * 00058 * \par ADV_NON_CONNECTABLE_UNDIRECTED 00059 * All connections to the peripheral device will be refused. 00060 * 00061 * \par ADV_CONNECTABLE_DIRECTED 00062 * Only connections from a pre-defined central device will be 00063 * accepted. 00064 * 00065 * \par ADV_CONNECTABLE_UNDIRECTED 00066 * Any central device can connect to this peripheral. 00067 * 00068 * \par ADV_SCANNABLE_UNDIRECTED 00069 * Any central device can connect to this peripheral, and 00070 * the secondary Scan Response payload will be included or 00071 * available to central devices. 00072 * 00073 * \par 00074 * See Bluetooth Core Specification 4.0 (Vol. 3), Part C, 00075 * Section 9.3 and Core Specification 4.0 (Vol. 6), Part B, 00076 * Section 2.3.1 for further information on GAP connection 00077 * modes 00078 */ 00079 void setAdvertisingType (GapAdvertisingParams::AdvertisingType); 00080 00081 /** 00082 * @param[in] interval 00083 * Advertising interval between 0x0020 and 0x4000 in 0.625ms 00084 * units (20ms to 10.24s). If using non-connectable mode 00085 * (ADV_NON_CONNECTABLE_UNDIRECTED) this min value is 00086 * 0x00A0 (100ms). To reduce the likelihood of collisions, the 00087 * link layer perturbs this interval by a pseudo-random delay 00088 * with a range of 0 ms to 10 ms for each advertising event. 00089 * 00090 * \par 00091 * Decreasing this value will allow central devices to detect 00092 * your peripheral faster at the expense of more power being 00093 * used by the radio due to the higher data transmit rate. 00094 * 00095 * \par 00096 * This field must be set to 0 if connectionMode is equal 00097 * to ADV_CONNECTABLE_DIRECTED 00098 * 00099 * \par 00100 * See Bluetooth Core Specification, Vol 3., Part C, 00101 * Appendix A for suggested advertising intervals. 00102 */ 00103 void setAdvertisingInterval (uint16_t interval); 00104 00105 /** 00106 * @param[in] timeout 00107 * Advertising timeout between 0x1 and 0x3FFF (1 and 16383) 00108 * in seconds. Enter 0 to disable the advertising timeout. 00109 */ 00110 void setAdvertisingTimeout (uint16_t timeout); 00111 00112 /** 00113 * Please refer to the APIs above. 00114 */ 00115 void setAdvertisingParams(const GapAdvertisingParams &advParams); 00116 00117 /** 00118 * This API is typically used as an internal helper to udpate the transport 00119 * backend with advertising data before starting to advertise. It may also 00120 * be explicity used to dynamically reset the accumulated advertising 00121 * payload and scanResponse; to do this, the application can clear and re- 00122 * accumulate a new advertising payload (and scanResponse) before using this 00123 * API. 00124 */ 00125 ble_error_t setAdvertisingPayload(void); 00126 00127 /** 00128 * Reset any advertising payload prepared from prior calls to 00129 * accumulateAdvertisingPayload(). 00130 */ 00131 void clearAdvertisingPayload(void); 00132 00133 /** 00134 * Accumulate an AD structure in the advertising payload. Please note that 00135 * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used 00136 * as an additional 31 bytes if the advertising payload proves to be too 00137 * small. 00138 * 00139 * @param flags 00140 * The flags to be added. Multiple flags may be specified in 00141 * combination. 00142 */ 00143 ble_error_t accumulateAdvertisingPayload(uint8_t flags); 00144 00145 /** 00146 * Accumulate an AD structure in the advertising payload. Please note that 00147 * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used 00148 * as an additional 31 bytes if the advertising payload proves to be too 00149 * small. 00150 * 00151 * @param app 00152 * The appearance of the peripheral. 00153 */ 00154 ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::Appearance app); 00155 00156 /** 00157 * Accumulate an AD structure in the advertising payload. Please note that 00158 * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used 00159 * as an additional 31 bytes if the advertising payload proves to be too 00160 * small. 00161 * 00162 * @param app 00163 * The max transmit power to be used by the controller. This is 00164 * only a hint. 00165 */ 00166 ble_error_t accumulateAdvertisingPayloadTxPower(int8_t power); 00167 00168 /** 00169 * Accumulate a variable length byte-stream as an AD structure in the 00170 * advertising payload. Please note that the payload is limited to 31 bytes. 00171 * The SCAN_RESPONSE message may be used as an additional 31 bytes if the 00172 * advertising payload proves to be too small. 00173 * 00174 * @param type The type which describes the variable length data. 00175 * @param data data bytes. 00176 * @param len length of data. 00177 */ 00178 ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len); 00179 00180 /** 00181 * Accumulate a variable length byte-stream as an AD structure in the 00182 * scanResponse payload. 00183 * 00184 * @param type The type which describes the variable length data. 00185 * @param data data bytes. 00186 * @param len length of data. 00187 */ 00188 ble_error_t accumulateScanResponse(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len); 00189 00190 /** 00191 * Start advertising (GAP Discoverable, Connectable modes, Broadcast 00192 * Procedure). 00193 */ 00194 ble_error_t startAdvertising(void); 00195 00196 /** 00197 * Stop advertising (GAP Discoverable, Connectable modes, Broadcast 00198 * Procedure). 00199 */ 00200 ble_error_t stopAdvertising(void); 00201 00202 ble_error_t disconnect(Gap::DisconnectionReason_t reason); 00203 00204 /* APIs to set GAP callbacks. */ 00205 void onTimeout(Gap::EventCallback_t timeoutCallback); 00206 00207 void onConnection(Gap::ConnectionEventCallback_t connectionCallback); 00208 /** 00209 * Used to setup a callback for GAP disconnection. 00210 */ 00211 void onDisconnection(Gap::DisconnectionEventCallback_t disconnectionCallback); 00212 00213 /** 00214 * Setup a callback for the GATT event DATA_SENT. 00215 */ 00216 void onDataSent(GattServer::ServerEventCallbackWithCount_t callback); 00217 00218 /** 00219 * Setup a callback for when a characteristic has its value updated by a 00220 * client. 00221 * 00222 * @Note: it is possible to chain together multiple onDataWritten callbacks 00223 * (potentially from different modules of an application) to receive updates 00224 * to characteristics. Many services, such as DFU and UART add their own 00225 * onDataWritten callbacks behind the scenes to trap interesting events. 00226 * 00227 * @Note: it is also possible to setup a callback into a member function of 00228 * some object. 00229 */ 00230 void onDataWritten(void (*callback)(const GattCharacteristicWriteCBParams *eventDataP)); 00231 template <typename T> void onDataWritten(T * objPtr, void (T::*memberPtr)(const GattCharacteristicWriteCBParams *context)); 00232 00233 void onUpdatesEnabled(GattServer::EventCallback_t callback); 00234 void onUpdatesDisabled(GattServer::EventCallback_t callback); 00235 void onConfirmationReceived(GattServer::EventCallback_t callback); 00236 00237 /** 00238 * Add a service declaration to the local server ATT table. Also add the 00239 * characteristics contained within. 00240 */ 00241 ble_error_t addService(GattService &service); 00242 00243 Gap::GapState_t getGapState(void) const; 00244 00245 /** 00246 * @param[in/out] lengthP 00247 * input: Length in bytes to be read, 00248 * output: Total length of attribute value upon successful return. 00249 */ 00250 ble_error_t readCharacteristicValue (uint16_t handle, uint8_t *const buffer, uint16_t *const lengthP); 00251 00252 /** 00253 * @param localOnly 00254 * Only update the characteristic locally regardless of notify/indicate flags in the CCCD. 00255 */ 00256 ble_error_t updateCharacteristicValue (uint16_t handle, const uint8_t *value, uint16_t size, bool localOnly = false); 00257 00258 /** 00259 * Yield control to the BLE stack or to other tasks waiting for events. This 00260 * is a sleep function which will return when there is an application 00261 * specific interrupt, but the MCU might wake up several times before 00262 * returning (to service the stack). This is not always interchangeable with 00263 * WFE(). 00264 */ 00265 void waitForEvent(void); 00266 00267 ble_error_t getPreferredConnectionParams(Gap::ConnectionParams_t *params); 00268 ble_error_t setPreferredConnectionParams(const Gap::ConnectionParams_t *params); 00269 ble_error_t updateConnectionParams(Gap::Handle_t handle, const Gap::ConnectionParams_t *params); 00270 00271 /** 00272 * This call allows the application to get the BLE stack version information. 00273 * 00274 * @return A pointer to a const string representing the version. 00275 * Note: The string is owned by the BLE_API. 00276 */ 00277 const char *getVersion(void); 00278 00279 /** 00280 * Set the device name characteristic in the GAP service. 00281 * @param deviceName The new value for the device-name. This is a UTF-8 encoded, <b>NULL-terminated</b> string. 00282 */ 00283 ble_error_t setDeviceName(const uint8_t *deviceName); 00284 00285 /** 00286 * Get the value of the device name characteristic in the GAP service. 00287 * @param[out] deviceName Pointer to an empty buffer where the UTF-8 *non NULL- 00288 * terminated* string will be placed. Set this 00289 * value to NULL in order to obtain the deviceName-length 00290 * from the 'length' parameter. 00291 * 00292 * @param[in/out] lengthP (on input) Length of the buffer pointed to by deviceName; 00293 * (on output) the complete device name length (without the 00294 * null terminator). 00295 * 00296 * @note If the device name is longer than the size of the supplied buffer, 00297 * length will return the complete device name length, 00298 * and not the number of bytes actually returned in deviceName. 00299 * The application may use this information to retry with a suitable buffer size. 00300 * 00301 * Sample use: 00302 * uint8_t deviceName[20]; 00303 * unsigned length = sizeof(deviceName); 00304 * ble.getDeviceName(deviceName, &length); 00305 * if (length < sizeof(deviceName)) { 00306 * deviceName[length] = 0; 00307 * } 00308 * DEBUG("length: %u, deviceName: %s\r\n", length, deviceName); 00309 */ 00310 ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP); 00311 00312 /** 00313 * Set the appearance characteristic in the GAP service. 00314 * @param[in] appearance The new value for the device-appearance. 00315 */ 00316 ble_error_t setAppearance(uint16_t appearance); 00317 00318 /** 00319 * Set the appearance characteristic in the GAP service. 00320 * @param[out] appearance The new value for the device-appearance. 00321 */ 00322 ble_error_t getAppearance(uint16_t *appearanceP); 00323 00324 /** 00325 * Set the radio's transmit power. 00326 * @param[in] txPower Radio transmit power in dBm. 00327 */ 00328 ble_error_t setTxPower(int8_t txPower); 00329 00330 public: 00331 BLEDevice() : transport(createBLEDeviceInstance()), advParams(), advPayload(), scanResponse(), needToSetAdvPayload(true) { 00332 advPayload.clear(); 00333 scanResponse.clear(); 00334 } 00335 00336 private: 00337 BLEDeviceInstanceBase *const transport; /* the device specific backend */ 00338 00339 GapAdvertisingParams advParams; 00340 GapAdvertisingData advPayload; 00341 GapAdvertisingData scanResponse; 00342 00343 /* Accumulation of AD structures in the advertisement payload should 00344 * eventually result in a call to the target's setAdvertisingData() before 00345 * the server begins advertising. This flag marks the status of the pending update.*/ 00346 bool needToSetAdvPayload; 00347 00348 /** 00349 * DEPRECATED 00350 */ 00351 public: 00352 ble_error_t setAdvertisingData(const GapAdvertisingData &ADStructures, const GapAdvertisingData &scanResponse); 00353 ble_error_t setAdvertisingData(const GapAdvertisingData &ADStructures); 00354 00355 ble_error_t startAdvertising(const GapAdvertisingParams &advParams); 00356 }; 00357 00358 /* BLEDevice methods. Most of these simply forward the calls to the underlying 00359 * transport.*/ 00360 00361 inline ble_error_t 00362 BLEDevice::reset(void) 00363 { 00364 return transport->reset(); 00365 } 00366 00367 inline ble_error_t 00368 BLEDevice::setAddress(Gap::addr_type_t type, const Gap::address_t address) 00369 { 00370 return transport->getGap().setAddress(type, address); 00371 } 00372 00373 inline ble_error_t 00374 BLEDevice::getAddress(Gap::addr_type_t *typeP, Gap::address_t address) 00375 { 00376 return transport->getGap().getAddress(typeP, address); 00377 } 00378 00379 inline void 00380 BLEDevice::setAdvertisingType (GapAdvertisingParams::AdvertisingType advType) 00381 { 00382 advParams.setAdvertisingType(advType); 00383 } 00384 00385 inline void 00386 BLEDevice::setAdvertisingInterval (uint16_t interval) 00387 { 00388 advParams.setInterval(interval); 00389 } 00390 00391 inline void 00392 BLEDevice::setAdvertisingTimeout (uint16_t timeout) 00393 { 00394 advParams.setTimeout(timeout); 00395 } 00396 00397 inline void 00398 BLEDevice::setAdvertisingParams(const GapAdvertisingParams &newAdvParams) 00399 { 00400 advParams = newAdvParams; 00401 } 00402 00403 inline void 00404 BLEDevice::clearAdvertisingPayload(void) 00405 { 00406 needToSetAdvPayload = true; 00407 advPayload.clear(); 00408 } 00409 00410 inline ble_error_t 00411 BLEDevice::accumulateAdvertisingPayload(uint8_t flags) 00412 { 00413 needToSetAdvPayload = true; 00414 return advPayload.addFlags(flags); 00415 } 00416 00417 inline ble_error_t 00418 BLEDevice::accumulateAdvertisingPayload(GapAdvertisingData::Appearance app) 00419 { 00420 needToSetAdvPayload = true; 00421 transport->getGap().setAppearance(app); 00422 return advPayload.addAppearance(app); 00423 } 00424 00425 inline ble_error_t 00426 BLEDevice::accumulateAdvertisingPayloadTxPower(int8_t txPower) 00427 { 00428 needToSetAdvPayload = true; 00429 return advPayload.addTxPower(txPower); 00430 } 00431 00432 inline ble_error_t 00433 BLEDevice::accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) 00434 { 00435 needToSetAdvPayload = true; 00436 if (type == GapAdvertisingData::COMPLETE_LOCAL_NAME) { 00437 transport->getGap().setDeviceName(data); 00438 } 00439 return advPayload.addData(type, data, len); 00440 } 00441 00442 inline ble_error_t 00443 BLEDevice::accumulateScanResponse(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) 00444 { 00445 needToSetAdvPayload = true; 00446 return scanResponse.addData(type, data, len); 00447 } 00448 00449 inline ble_error_t 00450 BLEDevice::setAdvertisingPayload(void) { 00451 needToSetAdvPayload = false; 00452 return transport->getGap().setAdvertisingData(advPayload, scanResponse); 00453 } 00454 00455 inline ble_error_t 00456 BLEDevice::startAdvertising(void) 00457 { 00458 ble_error_t rc; 00459 if ((rc = transport->getGattServer().initializeGATTDatabase()) != BLE_ERROR_NONE) { 00460 return rc; 00461 } 00462 if (needToSetAdvPayload) { 00463 if ((rc = setAdvertisingPayload()) != BLE_ERROR_NONE) { 00464 return rc; 00465 } 00466 } 00467 00468 return transport->getGap().startAdvertising(advParams); 00469 } 00470 00471 inline ble_error_t 00472 BLEDevice::stopAdvertising(void) 00473 { 00474 return transport->getGap().stopAdvertising(); 00475 } 00476 00477 inline ble_error_t 00478 BLEDevice::disconnect(Gap::DisconnectionReason_t reason) 00479 { 00480 return transport->getGap().disconnect(reason); 00481 } 00482 00483 inline void 00484 BLEDevice::onTimeout(Gap::EventCallback_t timeoutCallback) 00485 { 00486 transport->getGap().setOnTimeout(timeoutCallback); 00487 } 00488 00489 inline void 00490 BLEDevice::onConnection(Gap::ConnectionEventCallback_t connectionCallback) 00491 { 00492 transport->getGap().setOnConnection(connectionCallback); 00493 } 00494 00495 inline void 00496 BLEDevice::onDisconnection(Gap::DisconnectionEventCallback_t disconnectionCallback) 00497 { 00498 transport->getGap().setOnDisconnection(disconnectionCallback); 00499 } 00500 00501 inline void 00502 BLEDevice::onDataSent(GattServer::ServerEventCallbackWithCount_t callback) 00503 { 00504 transport->getGattServer().setOnDataSent(callback); 00505 } 00506 00507 inline void 00508 BLEDevice::onDataWritten(void (*callback)(const GattCharacteristicWriteCBParams *eventDataP)) { 00509 transport->getGattServer().setOnDataWritten(callback); 00510 } 00511 00512 template <typename T> inline void 00513 BLEDevice::onDataWritten(T *objPtr, void (T::*memberPtr)(const GattCharacteristicWriteCBParams *context)) { 00514 transport->getGattServer().setOnDataWritten(objPtr, memberPtr); 00515 } 00516 00517 inline void 00518 BLEDevice::onUpdatesEnabled(GattServer::EventCallback_t callback) 00519 { 00520 transport->getGattServer().setOnUpdatesEnabled(callback); 00521 } 00522 00523 inline void 00524 BLEDevice::onUpdatesDisabled(GattServer::EventCallback_t callback) 00525 { 00526 transport->getGattServer().setOnUpdatesDisabled(callback); 00527 } 00528 00529 inline void 00530 BLEDevice::onConfirmationReceived(GattServer::EventCallback_t callback) 00531 { 00532 transport->getGattServer().setOnConfirmationReceived(callback); 00533 } 00534 00535 inline ble_error_t 00536 BLEDevice::addService(GattService &service) 00537 { 00538 return transport->getGattServer().addService(service); 00539 } 00540 00541 inline Gap::GapState_t 00542 BLEDevice::getGapState(void) const 00543 { 00544 return transport->getGap().getState(); 00545 } 00546 00547 inline ble_error_t BLEDevice::readCharacteristicValue (uint16_t handle, uint8_t *const buffer, uint16_t *const lengthP) 00548 { 00549 return transport->getGattServer().readValue(handle, buffer, lengthP); 00550 } 00551 00552 inline ble_error_t 00553 BLEDevice::updateCharacteristicValue (uint16_t handle, const uint8_t *value, uint16_t size, bool localOnly) 00554 { 00555 return transport->getGattServer().updateValue(handle, const_cast<uint8_t *>(value), size, localOnly); 00556 } 00557 00558 inline void 00559 BLEDevice::waitForEvent(void) 00560 { 00561 transport->waitForEvent(); 00562 } 00563 00564 inline ble_error_t 00565 BLEDevice::getPreferredConnectionParams(Gap::ConnectionParams_t *params) 00566 { 00567 return transport->getGap().getPreferredConnectionParams(params); 00568 } 00569 00570 inline ble_error_t 00571 BLEDevice::setPreferredConnectionParams(const Gap::ConnectionParams_t *params) 00572 { 00573 return transport->getGap().setPreferredConnectionParams(params); 00574 } 00575 00576 inline ble_error_t 00577 BLEDevice::updateConnectionParams(Gap::Handle_t handle, const Gap::ConnectionParams_t *params) { 00578 return transport->getGap().updateConnectionParams(handle, params); 00579 } 00580 00581 inline const char * 00582 BLEDevice::getVersion(void) 00583 { 00584 return transport->getVersion(); 00585 } 00586 00587 inline ble_error_t 00588 BLEDevice::setDeviceName(const uint8_t *deviceName) 00589 { 00590 return transport->getGap().setDeviceName(deviceName); 00591 } 00592 00593 inline ble_error_t 00594 BLEDevice::getDeviceName(uint8_t *deviceName, unsigned *lengthP) 00595 { 00596 return transport->getGap().getDeviceName(deviceName, lengthP); 00597 } 00598 00599 inline ble_error_t 00600 BLEDevice::setAppearance(uint16_t appearance) 00601 { 00602 return transport->getGap().setAppearance(appearance); 00603 } 00604 00605 inline ble_error_t 00606 BLEDevice::getAppearance(uint16_t *appearanceP) 00607 { 00608 return transport->getGap().getAppearance(appearanceP); 00609 } 00610 00611 inline ble_error_t 00612 BLEDevice::setTxPower(int8_t txPower) 00613 { 00614 return transport->setTxPower(txPower); 00615 } 00616 00617 /* 00618 * ALL OF THE FOLLOWING METHODS ARE DEPRECATED 00619 */ 00620 00621 inline ble_error_t 00622 BLEDevice::setAdvertisingData(const GapAdvertisingData &ADStructures, const GapAdvertisingData &scanResponse) 00623 { 00624 needToSetAdvPayload = false; 00625 return transport->getGap().setAdvertisingData(ADStructures, scanResponse); 00626 } 00627 00628 inline ble_error_t 00629 BLEDevice::setAdvertisingData(const GapAdvertisingData &ADStructures) 00630 { 00631 GapAdvertisingData scanResponse; 00632 00633 needToSetAdvPayload = false; 00634 return transport->getGap().setAdvertisingData(ADStructures, scanResponse); 00635 } 00636 00637 inline ble_error_t 00638 BLEDevice::startAdvertising(const GapAdvertisingParams &_advParams) 00639 { 00640 return transport->getGap().startAdvertising(_advParams); 00641 } 00642 00643 #endif // ifndef __BLE_DEVICE__
Generated on Tue Jul 12 2022 20:04:42 by
