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