High level Bluetooth Low Energy API and radio abstraction layer
Fork of BLE_API by
Revision 710:b2e1a2660ec2, committed 2015-06-19
- Comitter:
- rgrover1
- Date:
- Fri Jun 19 15:53:28 2015 +0100
- Parent:
- 709:77f6fc6999cd
- Child:
- 711:ea0c4bf9ec99
- Commit message:
- Synchronized with git rev 7e8977d8
Author: Rohit Grover
Release 0.3.8
=============
This is a minor set of enhancements before we yotta-ize BLE_API.
Enhancements
~~~~~~~~~~~~
* Minor rework for class UUID; added a default and copy constructor; and a != operator.
* Added copy constructor and accessors for GapAdvertisingParams.
* GapScanningParams:: remove unnecessary checks for SCAN_TIMEOUT_MAX.
* Add a comment header block to explain why BLEDevice::init() may not be safe
to call from global static context.
* Introduce GattAttribute::INVALID_HANDLE.
* Replace some deprecated uses of Gap::address_t with Gap::Address_t.
Bugfixes
~~~~~~~~
* None.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/BLE.h Fri Jun 19 15:53:28 2015 +0100 @@ -0,0 +1,1342 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BLE_H__ +#define __BLE_H__ + +#include "blecommon.h" +#include "Gap.h" +#include "GattServer.h" +#include "GattClient.h" +#include "BLEInstanceBase.h" + +/** + * The base class used to abstract away BLE capable radio transceivers or SOCs, + * to enable this BLE API to work with any radio transparently. + */ +class BLE +{ +public: + /** + * Initialize the BLE controller. This should be called before using + * anything else in the BLE_API. + * + * init() hands control to the underlying BLE module to accomplish + * initialization. This initialization may tacitly depend on other hardware + * setup (such as clocks or power-modes) which happens early on during + * system startup. It may not be safe to call init() from global static + * context where ordering is compiler specific and can't be guaranteed--it + * is safe to call BLE::init() from within main(). + */ + ble_error_t init(); + + /** + * Purge the BLE stack of GATT and GAP state. init() must be called + * afterwards to re-instate services and GAP state. This API offers a way to + * repopulate the GATT database with new services and characteristics. + */ + ble_error_t shutdown(void) { + clearAdvertisingPayload(); + return transport->shutdown(); + } + + /** + * This call allows the application to get the BLE stack version information. + * + * @return A pointer to a const string representing the version. + * Note: The string is owned by the BLE_API. + */ + const char *getVersion(void) { + return transport->getVersion(); + } + + /* + * Accessors to GAP. Please refer to Gap.h. All GAP related functionality requires + * going through this accessor. + */ + const Gap &gap() const { + return transport->getGap(); + } + Gap &gap() { + return transport->getGap(); + } + + /* + * Accessors to GATT Server. Please refer to GattServer.h. All GATTServer related + * functionality requires going through this accessor. + */ + const GattServer& gattServer() const { + return transport->getGattServer(); + } + GattServer& gattServer() { + return transport->getGattServer(); + } + + /* + * Accessors to GATT Client. Please refer to GattClient.h. All GATTClient related + * functionality requires going through this accessor. + */ + const GattClient& gattClient() const { + return transport->getGattClient(); + } + GattClient& gattClient() { + return transport->getGattClient(); + } + + /* + * Accessors to Security Manager. Please refer to SecurityManager.h. All + * SecurityManager related functionality requires going through this + * accessor. + */ + const SecurityManager& securityManager() const { + return transport->getSecurityManager(); + } + SecurityManager& securityManager() { + return transport->getSecurityManager(); + } + + /** + * Yield control to the BLE stack or to other tasks waiting for events. This + * is a sleep function which will return when there is an application + * specific interrupt, but the MCU might wake up several times before + * returning (to service the stack). This is not always interchangeable with + * WFE(). + */ + void waitForEvent(void) { + transport->waitForEvent(); + } + + /* + * Deprecation alert! + * All of the following are deprecated and may be dropped in a future + * release. Documentation should refer to alternative APIs. + */ + + /* GAP specific APIs. */ +public: + /** + * Set the BTLE MAC address and type. + * @return BLE_ERROR_NONE on success. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.setAddress(...) should be replaced with + * ble.gap().setAddress(...). + */ + ble_error_t setAddress(Gap::AddressType_t type, const Gap::Address_t address) { + return gap().setAddress(type, address); + } + + /** + * Fetch the BTLE MAC address and type. + * @return BLE_ERROR_NONE on success. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.getAddress(...) should be replaced with + * ble.gap().getAddress(...). + */ + ble_error_t getAddress(Gap::AddressType_t *typeP, Gap::Address_t address) { + return gap().getAddress(typeP, address); + } + + /** + * Set the GAP advertising mode to use for this device. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.setAdvertisingType(...) should be replaced with + * ble.gap().setAdvertisingType(...). + */ + void setAdvertisingType(GapAdvertisingParams::AdvertisingType advType) { + gap().setAdvertisingType(advType); + } + + /** + * @param[in] interval + * Advertising interval in units of milliseconds. Advertising + * is disabled if interval is 0. If interval is smaller than + * the minimum supported value, then the minimum supported + * value is used instead. This minimum value can be discovered + * using getMinAdvertisingInterval(). + * + * This field must be set to 0 if connectionMode is equal + * to ADV_CONNECTABLE_DIRECTED. + * + * @note: Decreasing this value will allow central devices to detect a + * peripheral faster at the expense of more power being used by the radio + * due to the higher data transmit rate. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.setAdvertisingInterval(...) should be replaced with + * ble.gap().setAdvertisingInterval(...). + * + * @note: [WARNING] This API previously used 0.625ms as the unit for its + * 'interval' argument. That required an explicit conversion from + * milliseconds using Gap::MSEC_TO_GAP_DURATION_UNITS(). This conversion is + * no longer required as the new units are milliseconds. Any application + * code depending on the old semantics would need to be updated accordingly. + */ + void setAdvertisingInterval(uint16_t interval) { + gap().setAdvertisingInterval(interval); + } + + /** + * @return Minimum Advertising interval in milliseconds. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.getMinAdvertisingInterval(...) should be replaced with + * ble.gap().getMinAdvertisingInterval(...). + */ + uint16_t getMinAdvertisingInterval(void) const { + return gap().getMinAdvertisingInterval(); + } + + /** + * @return Minimum Advertising interval in milliseconds for non-connectible mode. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.getMinNonConnectableAdvertisingInterval(...) should be replaced with + * ble.gap().getMinNonConnectableAdvertisingInterval(...). + */ + uint16_t getMinNonConnectableAdvertisingInterval(void) const { + return gap().getMinNonConnectableAdvertisingInterval(); + } + + /** + * @return Maximum Advertising interval in milliseconds. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.getMaxAdvertisingInterval(...) should be replaced with + * ble.gap().getMaxAdvertisingInterval(...). + */ + uint16_t getMaxAdvertisingInterval(void) const { + return gap().getMaxAdvertisingInterval(); + } + + /** + * @param[in] timeout + * Advertising timeout (in seconds) between 0x1 and 0x3FFF (1 + * and 16383). Use 0 to disable the advertising timeout. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.setAdvertisingTimeout(...) should be replaced with + * ble.gap().setAdvertisingTimeout(...). + */ + void setAdvertisingTimeout(uint16_t timeout) { + gap().setAdvertisingTimeout(timeout); + } + + /** + * Setup a particular, user-constructed set of advertisement parameters for + * the underlying stack. It would be uncommon for this API to be used + * directly; there are other APIs to tweak advertisement parameters + * individually (see above). + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.setAdvertisingParams(...) should be replaced with + * ble.gap().setAdvertisingParams(...). + */ + void setAdvertisingParams(const GapAdvertisingParams &advParams) { + gap().setAdvertisingParams(advParams); + } + + /** + * @return Read back advertising parameters. Useful for storing and + * restoring parameters rapidly. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.getAdvertisingParams(...) should be replaced with + * ble.gap().getAdvertisingParams(...). + */ + const GapAdvertisingParams &getAdvertisingParams(void) const { + return gap().getAdvertisingParams(); + } + + /** + * Accumulate an AD structure in the advertising payload. Please note that + * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used + * as an additional 31 bytes if the advertising payload proves to be too + * small. + * + * @param[in] flags + * The flags to be added. Please refer to + * GapAdvertisingData::Flags for valid flags. Multiple + * flags may be specified in combination. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.accumulateAdvertisingPayload(flags) should be replaced with + * ble.gap().accumulateAdvertisingPayload(flags). + */ + ble_error_t accumulateAdvertisingPayload(uint8_t flags) { + return gap().accumulateAdvertisingPayload(flags); + } + + /** + * Accumulate an AD structure in the advertising payload. Please note that + * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used + * as an additional 31 bytes if the advertising payload proves to be too + * small. + * + * @param[in] app + * The appearance of the peripheral. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.accumulateAdvertisingPayload(appearance) should be replaced with + * ble.gap().accumulateAdvertisingPayload(appearance). + */ + ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::Appearance app) { + return gap().accumulateAdvertisingPayload(app); + } + + /** + * Accumulate an AD structure in the advertising payload. Please note that + * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used + * as an additional 31 bytes if the advertising payload proves to be too + * small. + * + * @param[in] app + * The max transmit power to be used by the controller. This + * is only a hint. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.accumulateAdvertisingPayloadTxPower(txPower) should be replaced with + * ble.gap().accumulateAdvertisingPayloadTxPower(txPower). + */ + ble_error_t accumulateAdvertisingPayloadTxPower(int8_t power) { + return gap().accumulateAdvertisingPayloadTxPower(power); + } + + /** + * Accumulate a variable length byte-stream as an AD structure in the + * advertising payload. Please note that the payload is limited to 31 bytes. + * The SCAN_RESPONSE message may be used as an additional 31 bytes if the + * advertising payload proves to be too small. + * + * @param type The type which describes the variable length data. + * @param data data bytes. + * @param len length of data. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.accumulateAdvertisingPayload(...) should be replaced with + * ble.gap().accumulateAdvertisingPayload(...). + */ + ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) { + return gap().accumulateAdvertisingPayload(type, data, len); + } + + /** + * Setup a particular, user-constructed advertisement payload for the + * underlying stack. It would be uncommon for this API to be used directly; + * there are other APIs to build an advertisement payload (see above). + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.setAdvertisingData(...) should be replaced with + * ble.gap().setAdvertisingPayload(...). + */ + ble_error_t setAdvertisingData(const GapAdvertisingData &advData) { + return gap().setAdvertisingPayload(advData); + } + + /** + * @return Read back advertising data. Useful for storing and + * restoring payload. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.getAdvertisingData(...) should be replaced with + * ble.gap().getAdvertisingPayload()(...). + */ + const GapAdvertisingData &getAdvertisingData(void) const { + return gap().getAdvertisingPayload(); + } + + /** + * Reset any advertising payload prepared from prior calls to + * accumulateAdvertisingPayload(). This automatically propagates the re- + * initialized adv payload to the underlying stack. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.clearAdvertisingPayload(...) should be replaced with + * ble.gap().clearAdvertisingPayload(...). + */ + void clearAdvertisingPayload(void) { + gap().clearAdvertisingPayload(); + } + + /** + * This API is *deprecated* and resolves to a no-operation. It is left here + * to allow older code to compile. Please avoid using this API in new code. + * This API will be dropped in a future release. + * + * Formerly, it would be used to dynamically reset the accumulated advertising + * payload and scanResponse; to do this, the application would clear and re- + * accumulate a new advertising payload (and scanResponse) before using this + * API. Updates to the underlying advertisement payload now happen + * implicitly. + */ + ble_error_t setAdvertisingPayload(void) { + return BLE_ERROR_NONE; + } + + /** + * Accumulate a variable length byte-stream as an AD structure in the + * scanResponse payload. + * + * @param[in] type The type which describes the variable length data. + * @param[in] data data bytes. + * @param[in] len length of data. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.accumulateScanResponse(...) should be replaced with + * ble.gap().accumulateScanResponse(...). + */ + ble_error_t accumulateScanResponse(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) { + return gap().accumulateScanResponse(type, data, len); + } + + /** + * Reset any scan response prepared from prior calls to + * accumulateScanResponse(). + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.clearScanResponse(...) should be replaced with + * ble.gap().clearScanResponse(...). + */ + void clearScanResponse(void) { + gap().clearScanResponse(); + } + + /** + * Start advertising. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.startAdvertising(...) should be replaced with + * ble.gap().startAdvertising(...). + */ + ble_error_t startAdvertising(void) { + return gap().startAdvertising(); + } + + /** + * Stop advertising. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.stopAdvertising(...) should be replaced with + * ble.gap().stopAdvertising(...). + */ + ble_error_t stopAdvertising(void) { + return gap().stopAdvertising(); + } + + /** + * Setup parameters for GAP scanning--i.e. observer mode. + * @param[in] interval + * Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s]. + * @param[in] window + * Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s]. + * @param[in] timeout + * Scan timeout (in seconds) between 0x0001 and 0xFFFF, 0x0000 disables timeout. + * @param[in] activeScanning + * Set to True if active-scanning is required. This is used to fetch the + * scan response from a peer if possible. + * + * The scanning window divided by the interval determines the duty cycle for + * scanning. For example, if the interval is 100ms and the window is 10ms, + * then the controller will scan for 10 percent of the time. It is possible + * to have the interval and window set to the same value. In this case, + * scanning is continuous, with a change of scanning frequency once every + * interval. + * + * Once the scanning parameters have been configured, scanning can be + * enabled by using startScan(). + * + * @Note: The scan interval and window are recommendations to the BLE stack. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.setScanParams(...) should be replaced with + * ble.gap().setScanParams(...). + */ + ble_error_t setScanParams(uint16_t interval = GapScanningParams::SCAN_INTERVAL_MAX, + uint16_t window = GapScanningParams::SCAN_WINDOW_MAX, + uint16_t timeout = 0, + bool activeScanning = false) { + return gap().setScanParams(interval, window, timeout, activeScanning); + } + + /** + * Setup the scanInterval parameter for GAP scanning--i.e. observer mode. + * @param[in] interval + * Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s]. + * + * The scanning window divided by the interval determines the duty cycle for + * scanning. For example, if the interval is 100ms and the window is 10ms, + * then the controller will scan for 10 percent of the time. It is possible + * to have the interval and window set to the same value. In this case, + * scanning is continuous, with a change of scanning frequency once every + * interval. + * + * Once the scanning parameters have been configured, scanning can be + * enabled by using startScan(). + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.setScanInterval(interval) should be replaced with + * ble.gap().setScanInterval(interval). + */ + ble_error_t setScanInterval(uint16_t interval) { + return gap().setScanInterval(interval); + } + + /** + * Setup the scanWindow parameter for GAP scanning--i.e. observer mode. + * @param[in] window + * Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s]. + * + * The scanning window divided by the interval determines the duty cycle for + * scanning. For example, if the interval is 100ms and the window is 10ms, + * then the controller will scan for 10 percent of the time. It is possible + * to have the interval and window set to the same value. In this case, + * scanning is continuous, with a change of scanning frequency once every + * interval. + * + * Once the scanning parameters have been configured, scanning can be + * enabled by using startScan(). + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.setScanWindow(window) should be replaced with + * ble.gap().setScanWindow(window). + */ + ble_error_t setScanWindow(uint16_t window) { + return gap().setScanWindow(window); + } + + /** + * Setup parameters for GAP scanning--i.e. observer mode. + * @param[in] timeout + * Scan timeout (in seconds) between 0x0001 and 0xFFFF, 0x0000 disables timeout. + * + * The scanning window divided by the interval determines the duty cycle for + * scanning. For example, if the interval is 100ms and the window is 10ms, + * then the controller will scan for 10 percent of the time. It is possible + * to have the interval and window set to the same value. In this case, + * scanning is continuous, with a change of scanning frequency once every + * interval. + * + * Once the scanning parameters have been configured, scanning can be + * enabled by using startScan(). + * + * @Note: The scan interval and window are recommendations to the BLE stack. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.setScanTimeout(...) should be replaced with + * ble.gap().setScanTimeout(...). + */ + ble_error_t setScanTimeout(uint16_t timeout) { + return gap().setScanTimeout(timeout); + } + + /** + * Setup parameters for GAP scanning--i.e. observer mode. + * @param[in] activeScanning + * Set to True if active-scanning is required. This is used to fetch the + * scan response from a peer if possible. + * + * Once the scanning parameters have been configured, scanning can be + * enabled by using startScan(). + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.setActiveScan(...) should be replaced with + * ble.gap().setActiveScanning(...). + */ + void setActiveScan(bool activeScanning) { + gap().setActiveScanning(activeScanning); + } + + /** + * Start scanning (Observer Procedure) based on the parameters currently in + * effect. + * + * @param[in] callback + * The application specific callback to be invoked upon + * receiving every advertisement report. This can be passed in + * as NULL, in which case scanning may not be enabled at all. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.startScan(callback) should be replaced with + * ble.gap().startScan(callback). + */ + ble_error_t startScan(void (*callback)(const Gap::AdvertisementCallbackParams_t *params)) { + return gap().startScan(callback); + } + + /** + * Same as above, but this takes an (object, method) pair for a callback. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.startScan(callback) should be replaced with + * ble.gap().startScan(object, callback). + */ + template<typename T> + ble_error_t startScan(T *object, void (T::*memberCallback)(const Gap::AdvertisementCallbackParams_t *params)); + + /** + * Stop scanning. The current scanning parameters remain in effect. + * + * @retval BLE_ERROR_NONE if successfully stopped scanning procedure. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.stopScan() should be replaced with + * ble.gap().stopScan(). + */ + ble_error_t stopScan(void) { + return gap().stopScan(); + } + + /** + * Create a connection (GAP Link Establishment). + * @param peerAddr + * 48-bit address, LSB format. + * @param peerAddrType + * Address type of the peer. + * @param connectionParams + * Connection parameters. + * @param scanParams + * Paramters to be used while scanning for the peer. + * @return BLE_ERROR_NONE if connection establishment procedure is started + * successfully. The onConnection callback (if set) will be invoked upon + * a connection event. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.connect(...) should be replaced with + * ble.gap().connect(...). + */ + ble_error_t connect(const Gap::Address_t peerAddr, + Gap::AddressType_t peerAddrType = Gap::ADDR_TYPE_RANDOM_STATIC, + const Gap::ConnectionParams_t *connectionParams = NULL, + const GapScanningParams *scanParams = NULL) { + return gap().connect(peerAddr, peerAddrType, connectionParams, scanParams); + } + + /** + * This call initiates the disconnection procedure, and its completion will + * be communicated to the application with an invocation of the + * onDisconnection callback. + * + * @param[in] connectionHandle + * @param[in] reason + * The reason for disconnection to be sent back to the peer. + */ + ble_error_t disconnect(Gap::Handle_t connectionHandle, Gap::DisconnectionReason_t reason) { + return gap().disconnect(connectionHandle, reason); + } + + /** + * This call initiates the disconnection procedure, and its completion will + * be communicated to the application with an invocation of the + * onDisconnection callback. + * + * @param reason + * The reason for disconnection to be sent back to the peer. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.disconnect(reason) should be replaced with + * ble.gap().disconnect(reason). + * + * @note: this version of disconnect() doesn't take a connection handle. It + * will work reliably only for stacks which are limited to a single + * connection. This API should be considered *deprecated* in favour of the + * alternative which takes a connection handle. It will be dropped in the future. + */ + ble_error_t disconnect(Gap::DisconnectionReason_t reason) { + return gap().disconnect(reason); + } + + /** + * Returns the current GAP state of the device using a bitmask which + * describes whether the device is advertising and/or connected. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.getGapState() should be replaced with + * ble.gap().getState(). + */ + Gap::GapState_t getGapState(void) const { + return gap().getState(); + } + + /** + * Get the GAP peripheral preferred connection parameters. These are the + * defaults that the peripheral would like to have in a connection. The + * choice of the connection parameters is eventually up to the central. + * + * @param[out] params + * The structure where the parameters will be stored. Memory + * for this is owned by the caller. + * + * @return BLE_ERROR_NONE if the parameters were successfully filled into + * the given structure pointed to by params. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.getPreferredConnectionParams() should be replaced with + * ble.gap().getPreferredConnectionParams(). + */ + ble_error_t getPreferredConnectionParams(Gap::ConnectionParams_t *params) { + return gap().getPreferredConnectionParams(params); + } + + /** + * Set the GAP peripheral preferred connection parameters. These are the + * defaults that the peripheral would like to have in a connection. The + * choice of the connection parameters is eventually up to the central. + * + * @param[in] params + * The structure containing the desired parameters. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.setPreferredConnectionParams() should be replaced with + * ble.gap().setPreferredConnectionParams(). + */ + ble_error_t setPreferredConnectionParams(const Gap::ConnectionParams_t *params) { + return gap().setPreferredConnectionParams(params); + } + + /** + * Update connection parameters while in the peripheral role. + * @details In the peripheral role, this will send the corresponding L2CAP request to the connected peer and wait for + * the central to perform the procedure. + * @param[in] handle + * Connection Handle + * @param[in] params + * Pointer to desired connection parameters. If NULL is provided on a peripheral role, + * the parameters in the PPCP characteristic of the GAP service will be used instead. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.updateConnectionParams() should be replaced with + * ble.gap().updateConnectionParams(). + */ + ble_error_t updateConnectionParams(Gap::Handle_t handle, const Gap::ConnectionParams_t *params) { + return gap().updateConnectionParams(handle, params); + } + + /** + * Set the device name characteristic in the GAP service. + * @param[in] deviceName + * The new value for the device-name. This is a UTF-8 encoded, <b>NULL-terminated</b> string. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.setDeviceName() should be replaced with + * ble.gap().setDeviceName(). + */ + ble_error_t setDeviceName(const uint8_t *deviceName) { + return gap().setDeviceName(deviceName); + } + + /** + * Get the value of the device name characteristic in the GAP service. + * @param[out] deviceName + * Pointer to an empty buffer where the UTF-8 *non NULL- + * terminated* string will be placed. Set this + * value to NULL in order to obtain the deviceName-length + * from the 'length' parameter. + * + * @param[in/out] lengthP + * (on input) Length of the buffer pointed to by deviceName; + * (on output) the complete device name length (without the + * null terminator). + * + * @note If the device name is longer than the size of the supplied buffer, + * length will return the complete device name length, and not the + * number of bytes actually returned in deviceName. The application may + * use this information to retry with a suitable buffer size. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.getDeviceName() should be replaced with + * ble.gap().getDeviceName(). + */ + ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP) { + return gap().getDeviceName(deviceName, lengthP); + } + + /** + * Set the appearance characteristic in the GAP service. + * @param[in] appearance + * The new value for the device-appearance. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.setAppearance() should be replaced with + * ble.gap().setAppearance(). + */ + ble_error_t setAppearance(GapAdvertisingData::Appearance appearance) { + return gap().setAppearance(appearance); + } + + /** + * Get the appearance characteristic in the GAP service. + * @param[out] appearance + * The new value for the device-appearance. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.getAppearance() should be replaced with + * ble.gap().getAppearance(). + */ + ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP) { + return gap().getAppearance(appearanceP); + } + + /** + * Set the radio's transmit power. + * @param[in] txPower Radio transmit power in dBm. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.setTxPower() should be replaced with + * ble.gap().setTxPower(). + */ + ble_error_t setTxPower(int8_t txPower) { + return gap().setTxPower(txPower); + } + + /** + * Query the underlying stack for permitted arguments for setTxPower(). + * + * @param[out] valueArrayPP + * Out parameter to receive the immutable array of Tx values. + * @param[out] countP + * Out parameter to receive the array's size. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.getPermittedTxPowerValues() should be replaced with + * ble.gap().getPermittedTxPowerValues(). + */ + void getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) { + gap().getPermittedTxPowerValues(valueArrayPP, countP); + } + + /** + * Add a service declaration to the local server ATT table. Also add the + * characteristics contained within. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from GattServer directly. A former call + * to ble.addService() should be replaced with + * ble.gattServer().addService(). + */ + ble_error_t addService(GattService &service) { + return gattServer().addService(service); + } + + /** + * Read the value of a characteristic from the local GattServer + * @param[in] attributeHandle + * Attribute handle for the value attribute of the characteristic. + * @param[out] buffer + * A buffer to hold the value being read. + * @param[in/out] lengthP + * Length of the buffer being supplied. If the attribute + * value is longer than the size of the supplied buffer, + * this variable will hold upon return the total attribute value length + * (excluding offset). The application may use this + * information to allocate a suitable buffer size. + * + * @return BLE_ERROR_NONE if a value was read successfully into the buffer. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from GattServer directly. A former call + * to ble.readCharacteristicValue() should be replaced with + * ble.gattServer().read(). + */ + ble_error_t readCharacteristicValue(GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP) { + return gattServer().read(attributeHandle, buffer, lengthP); + } + + /** + * Read the value of a characteristic from the local GattServer + * @param[in] connectionHandle + * Connection Handle. + * @param[in] attributeHandle + * Attribute handle for the value attribute of the characteristic. + * @param[out] buffer + * A buffer to hold the value being read. + * @param[in/out] lengthP + * Length of the buffer being supplied. If the attribute + * value is longer than the size of the supplied buffer, + * this variable will hold upon return the total attribute value length + * (excluding offset). The application may use this + * information to allocate a suitable buffer size. + * + * @return BLE_ERROR_NONE if a value was read successfully into the buffer. + * + * @note This API is a version of above with an additional connection handle + * parameter to allow fetches for connection-specific multivalued + * attribtues (such as the CCCDs). + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from GattServer directly. A former call + * to ble.readCharacteristicValue() should be replaced with + * ble.gattServer().read(). + */ + ble_error_t readCharacteristicValue(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP) { + return gattServer().read(connectionHandle, attributeHandle, buffer, lengthP); + } + + /** + * Update the value of a characteristic on the local GattServer. + * + * @param[in] attributeHandle + * Handle for the value attribute of the Characteristic. + * @param[in] value + * A pointer to a buffer holding the new value + * @param[in] size + * Size of the new value (in bytes). + * @param[in] localOnly + * Should this update be kept on the local + * GattServer regardless of the state of the + * notify/indicate flag in the CCCD for this + * Characteristic? If set to true, no notification + * or indication is generated. + * + * @return BLE_ERROR_NONE if we have successfully set the value of the attribute. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from GattServer directly. A former call + * to ble.updateCharacteristicValue() should be replaced with + * ble.gattServer().write(). + */ + ble_error_t updateCharacteristicValue(GattAttribute::Handle_t attributeHandle, + const uint8_t *value, + uint16_t size, + bool localOnly = false) { + return gattServer().write(attributeHandle, value, size, localOnly); + } + + /** + * Update the value of a characteristic on the local GattServer. A version + * of the same as above with connection handle parameter to allow updates + * for connection-specific multivalued attribtues (such as the CCCDs). + * + * @param[in] connectionHandle + * Connection Handle. + * @param[in] attributeHandle + * Handle for the value attribute of the Characteristic. + * @param[in] value + * A pointer to a buffer holding the new value + * @param[in] size + * Size of the new value (in bytes). + * @param[in] localOnly + * Should this update be kept on the local + * GattServer regardless of the state of the + * notify/indicate flag in the CCCD for this + * Characteristic? If set to true, no notification + * or indication is generated. + * + * @return BLE_ERROR_NONE if we have successfully set the value of the attribute. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from GattServer directly. A former call + * to ble.updateCharacteristicValue() should be replaced with + * ble.gattServer().write(). + */ + ble_error_t updateCharacteristicValue(Gap::Handle_t connectionHandle, + GattAttribute::Handle_t attributeHandle, + const uint8_t *value, + uint16_t size, + bool localOnly = false) { + return gattServer().write(connectionHandle, attributeHandle, value, size, localOnly); + } + + /** + * Enable the BLE stack's Security Manager. The Security Manager implements + * the actual cryptographic algorithms and protocol exchanges that allow two + * devices to securely exchange data and privately detect each other. + * Calling this API is a prerequisite for encryption and pairing (bonding). + * + * @param[in] enableBonding Allow for bonding. + * @param[in] requireMITM Require protection for man-in-the-middle attacks. + * @param[in] iocaps To specify IO capabilities of this peripheral, + * such as availability of a display or keyboard to + * support out-of-band exchanges of security data. + * @param[in] passkey To specify a static passkey. + * + * @return BLE_ERROR_NONE on success. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from SecurityManager directly. A former + * call to ble.initializeSecurity(...) should be replaced with + * ble.securityManager().init(...). + */ + ble_error_t initializeSecurity(bool enableBonding = true, + bool requireMITM = true, + SecurityManager::SecurityIOCapabilities_t iocaps = SecurityManager::IO_CAPS_NONE, + const SecurityManager::Passkey_t passkey = NULL) { + return securityManager().init(enableBonding, requireMITM, iocaps, passkey); + } + + /** + * Get the security status of a connection. + * + * @param[in] connectionHandle Handle to identify the connection. + * @param[out] securityStatusP security status. + * + * @return BLE_SUCCESS Or appropriate error code indicating reason for failure. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from SecurityManager directly. A former + * call to ble.getLinkSecurity(...) should be replaced with + * ble.securityManager().getLinkSecurity(...). + */ + ble_error_t getLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::LinkSecurityStatus_t *securityStatusP) { + return securityManager().getLinkSecurity(connectionHandle, securityStatusP); + } + + /** + * Delete all peer device context and all related bonding information from + * the database within the security manager. + * + * @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure. + * @retval BLE_ERROR_INVALID_STATE If the API is called without module initialization and/or + * application registration. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from SecurityManager directly. A former + * call to ble.purgeAllBondingState() should be replaced with + * ble.securityManager().purgeAllBondingState(). + */ + ble_error_t purgeAllBondingState(void) { + return securityManager().purgeAllBondingState(); + } + + /** + * Setup a callback for timeout events. Refer to Gap::TimeoutSource_t for + * possible event types. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from GattServer directly. A former call + * to ble.onTimeout(callback) should be replaced with + * ble.gap().onTimeout(callback). + */ + void onTimeout(Gap::TimeoutEventCallback_t timeoutCallback) { + gap().onTimeout(timeoutCallback); + } + + /** + * Setup a callback for connection events. Refer to Gap::ConnectionEventCallback_t. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from GattServer directly. A former call + * to ble.onConnection(callback) should be replaced with + * ble.gap().onConnection(callback). + */ + void onConnection(Gap::ConnectionEventCallback_t connectionCallback) { + gap().onConnection(connectionCallback); + } + + /** + * Used to setup a callback for GAP disconnection. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from GattServer directly. A former call + * to ble.onDisconnection(callback) should be replaced with + * ble.gap().onDisconnection(callback). + */ + void onDisconnection(Gap::DisconnectionEventCallback_t disconnectionCallback) { + gap().onDisconnection(disconnectionCallback); + } + + /** + * Append to a chain of callbacks to be invoked upon disconnection; these + * callbacks receive no context and are therefore different from the + * onDisconnection callback. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from GattServer directly. A former call + * to ble.addToDisconnectionCallchain(...) should be replaced with + * ble.gap().addToDisconnectionCallchain(...). + */ + template<typename T> + void addToDisconnectionCallChain(T *tptr, void (T::*mptr)(void)) { + gap().addToDisconnectionCallChain(tptr, mptr); + } + + /** + * Radio Notification is a feature that enables ACTIVE and INACTIVE + * (nACTIVE) signals from the stack that notify the application when the + * radio is in use. The signal is sent using software interrupt. + * + * The ACTIVE signal is sent before the Radio Event starts. The nACTIVE + * signal is sent at the end of the Radio Event. These signals can be used + * by the application programmer to synchronize application logic with radio + * activity. For example, the ACTIVE signal can be used to shut off external + * devices to manage peak current drawn during periods when the radio is on, + * or to trigger sensor data collection for transmission in the Radio Event. + * + * @param callback + * The application handler to be invoked in response to a radio + * ACTIVE/INACTIVE event. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from GattServer directly. A former call + * to ble.onRadioNotification(...) should be replaced with + * ble.gap().onRadioNotification(...). + */ + void onRadioNotification(Gap::RadioNotificationEventCallback_t callback) { + gap().onRadioNotification(callback); + } + + /** + * Add a callback for the GATT event DATA_SENT (which is triggered when + * updates are sent out by GATT in the form of notifications). + * + * @Note: it is possible to chain together multiple onDataSent callbacks + * (potentially from different modules of an application) to receive updates + * to characteristics. + * + * @Note: it is also possible to setup a callback into a member function of + * some object. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from GattServer directly. A former call + * to ble.onDataSent(...) should be replaced with + * ble.gattServer().onDataSent(...). + */ + void onDataSent(void (*callback)(unsigned count)) { + gattServer().onDataSent(callback); + } + template <typename T> void onDataSent(T * objPtr, void (T::*memberPtr)(unsigned count)) { + gattServer().onDataSent(objPtr, memberPtr); + } + + /** + * Setup a callback for when an attribute has its value updated by or at the + * connected peer. For a peripheral, this callback triggered when the local + * GATT server has an attribute updated by a write command from the peer. + * For a Central, this callback is triggered when a response is received for + * a write request. + * + * @Note: it is possible to chain together multiple onDataWritten callbacks + * (potentially from different modules of an application) to receive updates + * to characteristics. Many services, such as DFU and UART add their own + * onDataWritten callbacks behind the scenes to trap interesting events. + * + * @Note: it is also possible to setup a callback into a member function of + * some object. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from GattServer directly. A former call + * to ble.onDataWritten(...) should be replaced with + * ble.gattServer().onDataWritten(...). + */ + void onDataWritten(void (*callback)(const GattWriteCallbackParams *eventDataP)) { + gattServer().onDataWritten(callback); + } + template <typename T> void onDataWritten(T * objPtr, void (T::*memberPtr)(const GattWriteCallbackParams *context)) { + gattServer().onDataWritten(objPtr, memberPtr); + } + + /** + * Setup a callback to be invoked on the peripheral when an attribute is + * being read by a remote client. + * + * @Note: this functionality may not be available on all underlying stacks. + * You could use GattCharacteristic::setReadAuthorizationCallback() as an + * alternative. + * + * @Note: it is possible to chain together multiple onDataRead callbacks + * (potentially from different modules of an application) to receive updates + * to characteristics. Services may add their own onDataRead callbacks + * behind the scenes to trap interesting events. + * + * @Note: it is also possible to setup a callback into a member function of + * some object. + * + * @return BLE_ERROR_NOT_IMPLEMENTED if this functionality isn't available; + * else BLE_ERROR_NONE. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from GattServer directly. A former call + * to ble.onDataRead(...) should be replaced with + * ble.gattServer().onDataRead(...). + */ + ble_error_t onDataRead(void (*callback)(const GattReadCallbackParams *eventDataP)) { + return gattServer().onDataRead(callback); + } + template <typename T> ble_error_t onDataRead(T * objPtr, void (T::*memberPtr)(const GattReadCallbackParams *context)) { + return gattServer().onDataRead(objPtr, memberPtr); + } + + /** + * Setup a callback for when notifications/indications are enabled for a + * characteristic on the local GattServer. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from GattServer directly. A former call + * to ble.onUpdatesEnabled(callback) should be replaced with + * ble.gattServer().onUpdatesEnabled(callback). + */ + void onUpdatesEnabled(GattServer::EventCallback_t callback) { + gattServer().onUpdatesEnabled(callback); + } + + /** + * Setup a callback for when notifications/indications are disabled for a + * characteristic on the local GattServer. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from GattServer directly. A former call + * to ble.onUpdatesEnabled(callback) should be replaced with + * ble.gattServer().onUpdatesEnabled(callback). + */ + void onUpdatesDisabled(GattServer::EventCallback_t callback) { + gattServer().onUpdatesDisabled(callback); + } + + /** + * Setup a callback for when the GATT server receives a response for an + * indication event sent previously. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from GattServer directly. A former call + * to ble.onConfirmationReceived(callback) should be replaced with + * ble.gattServer().onConfirmationReceived(callback). + */ + void onConfirmationReceived(GattServer::EventCallback_t callback) { + gattServer().onConfirmationReceived(callback); + } + + /** + * Setup a callback for when the security setup procedure (key generation + * and exchange) for a link has started. This will be skipped for bonded + * devices. The callback is passed in parameters received from the peer's + * security request: bool allowBonding, bool requireMITM, and + * SecurityIOCapabilities_t. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from SecurityManager directly. A former + * call to ble.onSecuritySetupInitiated(callback) should be replaced with + * ble.securityManager().onSecuritySetupInitiated(callback). + */ + void onSecuritySetupInitiated(SecurityManager::SecuritySetupInitiatedCallback_t callback) { + securityManager().onSecuritySetupInitiated(callback); + } + + /** + * Setup a callback for when the security setup procedure (key generation + * and exchange) for a link has completed. This will be skipped for bonded + * devices. The callback is passed in the success/failure status of the + * security setup procedure. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from SecurityManager directly. A former + * call to ble.onSecuritySetupCompleted(callback) should be replaced with + * ble.securityManager().onSecuritySetupCompleted(callback). + */ + void onSecuritySetupCompleted(SecurityManager::SecuritySetupCompletedCallback_t callback) { + securityManager().onSecuritySetupCompleted(callback); + } + + /** + * Setup a callback for when a link with the peer is secured. For bonded + * devices, subsequent reconnections with bonded peer will result only in + * this callback when the link is secured and setup procedures will not + * occur unless the bonding information is either lost or deleted on either + * or both sides. The callback is passed in a SecurityManager::SecurityMode_t according + * to the level of security in effect for the secured link. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from SecurityManager directly. A former + * call to ble.onLinkSecured(callback) should be replaced with + * ble.securityManager().onLinkSecured(callback). + */ + void onLinkSecured(SecurityManager::LinkSecuredCallback_t callback) { + securityManager().onLinkSecured(callback); + } + + /** + * Setup a callback for successful bonding; i.e. that link-specific security + * context is stored persistently for a peer device. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from SecurityManager directly. A former + * call to ble.onSecurityContextStored(callback) should be replaced with + * ble.securityManager().onSecurityContextStored(callback). + */ + void onSecurityContextStored(SecurityManager::HandleSpecificEvent_t callback) { + securityManager().onSecurityContextStored(callback); + } + + /** + * Setup a callback for when the passkey needs to be displayed on a + * peripheral with DISPLAY capability. This happens when security is + * configured to prevent Man-In-The-Middle attacks, and a PIN (or passkey) + * needs to be exchanged between the peers to authenticate the connection + * attempt. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from SecurityManager directly. A former + * call to ble.onPasskeyDisplay(callback) should be replaced with + * ble.securityManager().onPasskeyDisplay(callback). + */ + void onPasskeyDisplay(SecurityManager::PasskeyDisplayCallback_t callback) { + return securityManager().onPasskeyDisplay(callback); + } + +public: + BLE() : transport(createBLEInstance()) { + /* empty */ + } + +private: + BLEInstanceBase *const transport; /* the device specific backend */ +}; + +typedef BLE BLEDevice; /* DEPRECATED. This type alias is retained for the sake of compatibility with older + * code. Will be dropped at some point soon.*/ + +#endif // ifndef __BLE_H__ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/BLEInstanceBase.h Fri Jun 19 15:53:28 2015 +0100 @@ -0,0 +1,56 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BLE_DEVICE_INSTANCE_BASE__ +#define __BLE_DEVICE_INSTANCE_BASE__ + +#include "Gap.h" + +/* forward declarations */ +class GattServer; +class GattClient; + +/** + * The interface for the transport object to be created by the target library's + * createBLEInstance(). + */ +class BLEInstanceBase +{ +public: + virtual ble_error_t init(void) = 0; + virtual ble_error_t shutdown(void) = 0; + virtual const char *getVersion(void) = 0; + virtual Gap& getGap() = 0; + virtual const Gap& getGap() const = 0; + virtual GattServer& getGattServer() = 0; + virtual const GattServer& getGattServer() const = 0; + virtual GattClient& getGattClient() = 0; + virtual SecurityManager& getSecurityManager() = 0; + virtual const SecurityManager& getSecurityManager() const = 0; + virtual void waitForEvent(void) = 0; +}; + +/** + * BLE uses composition to hide an interface object encapsulating the + * backend transport. + * + * The following API is used to create the singleton interface object. An + * implementation for this function must be provided by the device-specific + * library, otherwise there will be a linker error. + */ +extern BLEInstanceBase *createBLEInstance(void); + +#endif // ifndef __BLE_DEVICE_INSTANCE_BASE__ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/CallChainOfFunctionPointersWithContext.h Fri Jun 19 15:53:28 2015 +0100 @@ -0,0 +1,149 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_CALLCHAIN_OF_FUNCTION_POINTERS_WITH_CONTEXT_H +#define MBED_CALLCHAIN_OF_FUNCTION_POINTERS_WITH_CONTEXT_H + +#include <string.h> +#include "FunctionPointerWithContext.h" + + +/** Group one or more functions in an instance of a CallChainOfFunctionPointersWithContext, then call them in + * sequence using CallChainOfFunctionPointersWithContext::call(). Used mostly by the interrupt chaining code, + * but can be used for other purposes. + * + * Example: + * @code + * + * CallChainOfFunctionPointersWithContext<void *> chain; + * + * void first(void *context) { + * printf("'first' function.\n"); + * } + * + * void second(void *context) { + * printf("'second' function.\n"); + * } + * + * class Test { + * public: + * void f(void *context) { + * printf("A::f (class member).\n"); + * } + * }; + * + * int main() { + * Test test; + * + * chain.add(second); + * chain.add_front(first); + * chain.add(&test, &Test::f); + * chain.call(); + * } + * @endcode + */ + +template <typename ContextType> +class CallChainOfFunctionPointersWithContext { +public: + typedef FunctionPointerWithContext<ContextType> *pFunctionPointerWithContext_t; + +public: + /** Create an empty chain + * + * @param size (optional) Initial size of the chain + */ + CallChainOfFunctionPointersWithContext() : chainHead(NULL) { + /* empty */ + } + + virtual ~CallChainOfFunctionPointersWithContext() { + clear(); + } + + /** Add a function at the front of the chain + * + * @param function A pointer to a void function + * + * @returns + * The function object created for 'function' + */ + pFunctionPointerWithContext_t add(void (*function)(ContextType context)) { + return common_add(new FunctionPointerWithContext<ContextType>(function)); + } + + /** Add a function at the front of the chain + * + * @param tptr pointer to the object to call the member function on + * @param mptr pointer to the member function to be called + * + * @returns + * The function object created for 'tptr' and 'mptr' + */ + template<typename T> + pFunctionPointerWithContext_t add(T *tptr, void (T::*mptr)(ContextType context)) { + return common_add(new FunctionPointerWithContext<ContextType>(tptr, mptr)); + } + + /** Clear the call chain (remove all functions in the chain). + */ + void clear(void) { + pFunctionPointerWithContext_t fptr = chainHead; + while (fptr) { + pFunctionPointerWithContext_t deadPtr = fptr; + fptr = deadPtr->getNext(); + delete deadPtr; + } + + chainHead = NULL; + } + + bool hasCallbacksAttached(void) const { + return (chainHead != NULL); + } + + /** Call all the functions in the chain in sequence + * @Note: the stack frames of all the callbacks within the chained + * FunctionPointers will stack up. Hopefully there won't be too many + * chained FunctionPointers. + */ + void call(ContextType context) { + if (chainHead) { + chainHead->call(context); + } + } + +private: + pFunctionPointerWithContext_t common_add(pFunctionPointerWithContext_t pf) { + if (chainHead == NULL) { + chainHead = pf; + } else { + pf->chainAsNext(chainHead); + chainHead = pf; + } + + return chainHead; + } + +private: + pFunctionPointerWithContext_t chainHead; + + /* disallow copy constructor and assignment operators */ +private: + CallChainOfFunctionPointersWithContext(const CallChainOfFunctionPointersWithContext &); + CallChainOfFunctionPointersWithContext & operator = (const CallChainOfFunctionPointersWithContext &); +}; + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/DiscoveredCharacteristic.h Fri Jun 19 15:53:28 2015 +0100 @@ -0,0 +1,191 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DISCOVERED_CHARACTERISTIC_H__ +#define __DISCOVERED_CHARACTERISTIC_H__ + +#include "UUID.h" +#include "Gap.h" +#include "GattAttribute.h" +#include "GattClient.h" + +/** + * Structure for holding information about the service and the characteristics + * found during the discovery process. + */ +class DiscoveredCharacteristic { +public: + struct Properties_t { + uint8_t _broadcast :1; /**< Broadcasting of the value permitted. */ + uint8_t _read :1; /**< Reading the value permitted. */ + uint8_t _writeWoResp :1; /**< Writing the value with Write Command permitted. */ + uint8_t _write :1; /**< Writing the value with Write Request permitted. */ + uint8_t _notify :1; /**< Notications of the value permitted. */ + uint8_t _indicate :1; /**< Indications of the value permitted. */ + uint8_t _authSignedWrite :1; /**< Writing the value with Signed Write Command permitted. */ + + public: + bool broadcast(void) const {return _broadcast; } + bool read(void) const {return _read; } + bool writeWoResp(void) const {return _writeWoResp; } + bool write(void) const {return _write; } + bool notify(void) const {return _notify; } + bool indicate(void) const {return _indicate; } + bool authSignedWrite(void) const {return _authSignedWrite;} + + private: + operator uint8_t() const; /* disallow implicit conversion into an integer */ + operator unsigned() const; /* disallow implicit conversion into an integer */ + }; + + /** + * Structure for holding information about the service and the characteristics + * found during the discovery process. + */ + struct DiscoveredDescriptor { + GattAttribute::Handle_t handle; /**< Descriptor Handle. */ + UUID uuid; /**< Descriptor UUID. */ + }; + + /** + * Callback type for when a characteristic descriptor is found during descriptor- + * discovery. The receiving function is passed in a pointer to a + * DiscoveredDescriptor object which will remain valid for the lifetime + * of the callback. Memory for this object is owned by the BLE_API eventing + * framework. The application can safely make a persistent shallow-copy of + * this object in order to work with the characteristic beyond the callback. + */ + typedef void (*DescriptorCallback_t)(const DiscoveredDescriptor *); + + /** + * Initiate (or continue) a read for the value attribute, optionally at a + * given offset. If the Characteristic or Descriptor to be read is longer + * than ATT_MTU - 1, this function must be called multiple times with + * appropriate offset to read the complete value. + * + * @return BLE_ERROR_NONE if a read has been initiated, else + * BLE_ERROR_INVALID_STATE if some internal state about the connection is invalid, or + * BLE_STACK_BUSY if some client procedure already in progress, or + * BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's properties. + */ + ble_error_t read(uint16_t offset = 0) const; + + /** + * Perform a write without response procedure. + * + * @param length + * The amount of data being written. + * @param value + * The bytes being written. + * + * @note It is important to note that a write without response will generate + * an onDataSent() callback when the packet has been transmitted. There + * will be a BLE-stack specific limit to the number of pending + * writeWoResponse operations; the user may want to use the onDataSent() + * callback for flow-control. + * + * @retval BLE_ERROR_NONE Successfully started the Write procedure, else + * BLE_ERROR_INVALID_STATE if some internal state about the connection is invalid, or + * BLE_STACK_BUSY if some client procedure already in progress, or + * BLE_ERROR_NO_MEM if there are no available buffers left to process the request, or + * BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's properties. + */ + ble_error_t writeWoResponse(uint16_t length, const uint8_t *value) const; + + /** + * Initiate a GATT Characteristic Descriptor Discovery procedure for descriptors within this characteristic. + * + * @param callback + * @param matchingUUID + * filter for descriptors. Defaults to wildcard which will discover all descriptors. + * + * @return BLE_ERROR_NONE if descriptor discovery is launched successfully; else an appropriate error. + */ + ble_error_t discoverDescriptors(DescriptorCallback_t callback, const UUID &matchingUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) const; + + /** + * Perform a write procedure. + * + * @param length + * The amount of data being written. + * @param value + * The bytes being written. + * + * @note It is important to note that a write will generate + * an onDataWritten() callback when the peer acknowledges the request. + * + * @retval BLE_ERROR_NONE Successfully started the Write procedure, else + * BLE_ERROR_INVALID_STATE if some internal state about the connection is invalid, or + * BLE_STACK_BUSY if some client procedure already in progress, or + * BLE_ERROR_NO_MEM if there are no available buffers left to process the request, or + * BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's properties. + */ + ble_error_t write(uint16_t length, const uint8_t *value) const; + + static void setupOnDataRead(GattClient::ReadCallback_t callback) { + onDataReadCallback = callback; + } + + static void setupOnDataWrite(GattClient::WriteCallback_t callback) { + onDataWriteCallback = callback; + } + + void setupLongUUID(UUID::LongUUIDBytes_t longUUID) { + uuid.setupLong(longUUID); + } + +public: + UUID::ShortUUIDBytes_t getShortUUID(void) const { + return uuid.getShortUUID(); + } + + const Properties_t& getProperties(void) const { + return props; + } + + const GattAttribute::Handle_t& getDeclHandle(void) const { + return declHandle; + } + const GattAttribute::Handle_t& getValueHandle(void) const { + return valueHandle; + } + +public: + DiscoveredCharacteristic() : gattc(NULL), + uuid(UUID::ShortUUIDBytes_t(0)), + props(), + declHandle(GattAttribute::INVALID_HANDLE), + valueHandle(GattAttribute::INVALID_HANDLE) { + /* empty */ + } + +protected: + GattClient *gattc; + +protected: + UUID uuid; + Properties_t props; + GattAttribute::Handle_t declHandle; + GattAttribute::Handle_t valueHandle; + + Gap::Handle_t connHandle; + +public: + static GattClient::ReadCallback_t onDataReadCallback; + static GattClient::WriteCallback_t onDataWriteCallback; +}; + +#endif /*__DISCOVERED_CHARACTERISTIC_H__*/ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/DiscoveredService.h Fri Jun 19 15:53:28 2015 +0100 @@ -0,0 +1,71 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DISCOVERED_SERVICE_H__ +#define __DISCOVERED_SERVICE_H__ + +#include "UUID.h" +#include "GattAttribute.h" + +/**@brief Type for holding information about the service and the characteristics found during + * the discovery process. + */ +class DiscoveredService { +public: + void setup(UUID uuidIn, GattAttribute::Handle_t startHandleIn, GattAttribute::Handle_t endHandleIn) { + uuid = uuidIn; + startHandle = startHandleIn; + endHandle = endHandleIn; + } + + void setup(GattAttribute::Handle_t startHandleIn, GattAttribute::Handle_t endHandleIn) { + startHandle = startHandleIn; + endHandle = endHandleIn; + } + + void setupLongUUID(UUID::LongUUIDBytes_t longUUID) { + uuid.setupLong(longUUID); + } + +public: + const UUID &getUUID(void) const { + return uuid; + } + + const GattAttribute::Handle_t& getStartHandle(void) const { + return startHandle; + } + const GattAttribute::Handle_t& getEndHandle(void) const { + return endHandle; + } + +public: + DiscoveredService() : uuid(UUID::ShortUUIDBytes_t(0)), + startHandle(GattAttribute::INVALID_HANDLE), + endHandle(GattAttribute::INVALID_HANDLE) { + /* empty */ + } + +private: + DiscoveredService(const DiscoveredService &); + +private: + UUID uuid; /**< UUID of the service. */ + GattAttribute::Handle_t startHandle; /**< Service Handle Range. */ + GattAttribute::Handle_t endHandle; /**< Service Handle Range. */ +}; + +#endif /*__DISCOVERED_SERVICE_H__*/ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/FunctionPointerWithContext.h Fri Jun 19 15:53:28 2015 +0100 @@ -0,0 +1,129 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBED_FUNCTIONPOINTER_WITH_CONTEXT_H +#define MBED_FUNCTIONPOINTER_WITH_CONTEXT_H + +#include <string.h> + + +/** A class for storing and calling a pointer to a static or member void function + * which takes a context. + */ +template <typename ContextType> +class FunctionPointerWithContext { +public: + typedef FunctionPointerWithContext<ContextType> *pFunctionPointerWithContext_t; + typedef void (*pvoidfcontext_t)(ContextType context); + + /** Create a FunctionPointerWithContext, attaching a static function + * + * @param function The void static function to attach (default is none) + */ + FunctionPointerWithContext(void (*function)(ContextType context) = NULL) : + _function(NULL), _object(NULL), _member(), _membercaller(NULL), _next(NULL) { + attach(function); + } + + /** Create a FunctionPointerWithContext, attaching a member function + * + * @param object The object pointer to invoke the member function on (i.e. the this pointer) + * @param function The address of the void member function to attach + */ + template<typename T> + FunctionPointerWithContext(T *object, void (T::*member)(ContextType context)) : + _function(NULL), _object(NULL), _member(), _membercaller(NULL), _next(NULL) { + attach(object, member); + } + + /** Attach a static function + * + * @param function The void static function to attach (default is none) + */ + void attach(void (*function)(ContextType context) = NULL) { + _function = function; + } + + /** Attach a member function + * + * @param object The object pointer to invoke the member function on (i.e. the this pointer) + * @param function The address of the void member function to attach + */ + template<typename T> + void attach(T *object, void (T::*member)(ContextType context)) { + _object = static_cast<void *>(object); + memcpy(_member, (char *)&member, sizeof(member)); + _membercaller = &FunctionPointerWithContext::membercaller<T>; + } + + /** Call the attached static or member function; and if there are chained + * FunctionPointers their callbacks are invoked as well. + * @Note: all chained callbacks stack up; so hopefully there won't be too + * many FunctionPointers in a chain. */ + void call(ContextType context) { + if (_function) { + _function(context); + } else if (_object && _membercaller) { + _membercaller(_object, _member, context); + } + + /* Propagate the call to next in the chain. */ + if (_next) { + _next->call(context); + } + } + + /** + * Setup an external FunctionPointer as a next in the chain of related + * callbacks. Invoking call() on the head FunctionPointer will invoke all + * chained callbacks. + * + * Refer to 'CallChain' as an alternative. + */ + void chainAsNext(pFunctionPointerWithContext_t next) { + _next = next; + } + + pFunctionPointerWithContext_t getNext(void) const { + return _next; + } + + pvoidfcontext_t get_function() const { + return (pvoidfcontext_t)_function; + } + +private: + template<typename T> + static void membercaller(void *object, char *member, ContextType context) { + T *o = static_cast<T *>(object); + void (T::*m)(ContextType); + memcpy((char *)&m, member, sizeof(m)); + (o->*m)(context); + } + + void (*_function)(ContextType context); /**< static function pointer - NULL if none attached */ + void *_object; /**< object this pointer - NULL if none attached */ + char _member[16]; /**< raw member function pointer storage - converted back by + * registered _membercaller */ + void (*_membercaller)(void *, char *, ContextType); /**< registered membercaller function to convert back and call + * _member on _object passing the context. */ + pFunctionPointerWithContext_t _next; /**< Optional link to make a chain out of functionPointers; this + * allows chaining function pointers without requiring + * external memory to manage the chain. Also refer to + * 'CallChain' as an alternative. */ +}; + +#endif // ifndef MBED_FUNCTIONPOINTER_WITH_CONTEXT_H \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/Gap.h Fri Jun 19 15:53:28 2015 +0100 @@ -0,0 +1,886 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GAP_H__ +#define __GAP_H__ + +#include "GapAdvertisingData.h" +#include "GapAdvertisingParams.h" +#include "GapScanningParams.h" +#include "GapEvents.h" +#include "CallChain.h" +#include "FunctionPointerWithContext.h" + +using namespace mbed; + +/* Forward declarations for classes which will only be used for pointers or references in the following. */ +class GapAdvertisingParams; +class GapScanningParams; +class GapAdvertisingData; + +class Gap { +public: + enum AddressType_t { + ADDR_TYPE_PUBLIC = 0, + ADDR_TYPE_RANDOM_STATIC, + ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE, + ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE + }; + typedef enum AddressType_t addr_type_t; /* @Note: deprecated. Use AddressType_t instead. */ + + static const unsigned ADDR_LEN = 6; + typedef uint8_t Address_t[ADDR_LEN]; /* 48-bit address, LSB format. */ + typedef Address_t address_t; /* @Note: deprecated. Use Address_t instead. */ + + enum TimeoutSource_t { + TIMEOUT_SRC_ADVERTISING = 0x00, /**< Advertising timeout. */ + TIMEOUT_SRC_SECURITY_REQUEST = 0x01, /**< Security request timeout. */ + TIMEOUT_SRC_SCAN = 0x02, /**< Scanning timeout. */ + TIMEOUT_SRC_CONN = 0x03, /**< Connection timeout. */ + }; + + /** + * Enumeration for disconnection reasons. The values for these reasons are + * derived from Nordic's implementation; but the reasons are meant to be + * independent of the transport. If you are returned a reason which is not + * covered by this enumeration, then please refer to the underlying + * transport library. + */ + enum DisconnectionReason_t { + CONNECTION_TIMEOUT = 0x08, + REMOTE_USER_TERMINATED_CONNECTION = 0x13, + REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES = 0x14, /**< Remote Device Terminated Connection due to low resources.*/ + REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF = 0x15, /**< Remote Device Terminated Connection due to power off. */ + LOCAL_HOST_TERMINATED_CONNECTION = 0x16, + CONN_INTERVAL_UNACCEPTABLE = 0x3B, + }; + + /* Describes the current state of the device (more than one bit can be set) */ + struct GapState_t { + unsigned advertising : 1; /**< peripheral is currently advertising */ + unsigned connected : 1; /**< peripheral is connected to a central */ + }; + + typedef uint16_t Handle_t; /* Type for connection handle. */ + + typedef struct { + uint16_t minConnectionInterval; /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ + uint16_t maxConnectionInterval; /**< Maximum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ + uint16_t slaveLatency; /**< Slave Latency in number of connection events, see @ref BLE_GAP_CP_LIMITS.*/ + uint16_t connectionSupervisionTimeout; /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/ + } ConnectionParams_t; + + enum Role_t { + PERIPHERAL = 0x1, /**< Peripheral Role. */ + CENTRAL = 0x2, /**< Central Role. */ + }; + + struct AdvertisementCallbackParams_t { + Address_t peerAddr; + int8_t rssi; + bool isScanResponse; + GapAdvertisingParams::AdvertisingType_t type; + uint8_t advertisingDataLen; + const uint8_t *advertisingData; + }; + typedef FunctionPointerWithContext<const AdvertisementCallbackParams_t *> AdvertisementReportCallback_t; + + struct ConnectionCallbackParams_t { + Handle_t handle; + Role_t role; + AddressType_t peerAddrType; + Address_t peerAddr; + AddressType_t ownAddrType; + Address_t ownAddr; + const ConnectionParams_t *connectionParams; + + ConnectionCallbackParams_t(Handle_t handleIn, + Role_t roleIn, + AddressType_t peerAddrTypeIn, + const uint8_t *peerAddrIn, + AddressType_t ownAddrTypeIn, + const uint8_t *ownAddrIn, + const ConnectionParams_t *connectionParamsIn) : + handle(handleIn), + role(roleIn), + peerAddrType(peerAddrTypeIn), + peerAddr(), + ownAddrType(ownAddrTypeIn), + ownAddr(), + connectionParams(connectionParamsIn) { + memcpy(peerAddr, peerAddrIn, ADDR_LEN); + memcpy(ownAddr, ownAddrIn, ADDR_LEN); + } + }; + + static const uint16_t UNIT_1_25_MS = 1250; /**< Number of microseconds in 1.25 milliseconds. */ + static const uint16_t UNIT_0_625_MS = 625; /**< Number of microseconds in 0.625 milliseconds. */ + static uint16_t MSEC_TO_GAP_DURATION_UNITS(uint32_t durationInMillis) { + return (durationInMillis * 1000) / UNIT_1_25_MS; + } + static uint16_t MSEC_TO_ADVERTISEMENT_DURATION_UNITS(uint32_t durationInMillis) { + return (durationInMillis * 1000) / UNIT_0_625_MS; + } + static uint16_t ADVERTISEMENT_DURATION_UNITS_TO_MS(uint16_t gapUnits) { + return (gapUnits * UNIT_0_625_MS) / 1000; + } + + typedef void (*TimeoutEventCallback_t)(TimeoutSource_t source); + typedef void (*ConnectionEventCallback_t)(const ConnectionCallbackParams_t *params); + typedef void (*DisconnectionEventCallback_t)(Handle_t, DisconnectionReason_t); + typedef void (*RadioNotificationEventCallback_t)(bool radio_active); /* gets passed true for ACTIVE; false for INACTIVE. */ + + /* + * The following functions are meant to be overridden in the platform-specific sub-class. + */ +public: + /** + * Set the BTLE MAC address and type. Please note that the address format is + * LSB (least significant byte first). Please refer to Address_t. + * + * @return BLE_ERROR_NONE on success. + */ + virtual ble_error_t setAddress(AddressType_t type, const Address_t address) { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + } + + /** + * Fetch the BTLE MAC address and type. + * + * @return BLE_ERROR_NONE on success. + */ + virtual ble_error_t getAddress(AddressType_t *typeP, Address_t address) { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + } + + /** + * @return Minimum Advertising interval in milliseconds. + */ + virtual uint16_t getMinAdvertisingInterval(void) const { + return 0; /* default implementation; override this API if this capability is supported. */ + } + + /** + * @return Minimum Advertising interval in milliseconds for non-connectible mode. + */ + virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const { + return 0; /* default implementation; override this API if this capability is supported. */ + } + + /** + * @return Maximum Advertising interval in milliseconds. + */ + virtual uint16_t getMaxAdvertisingInterval(void) const { + return 0xFFFF; /* default implementation; override this API if this capability is supported. */ + } + + virtual ble_error_t stopAdvertising(void) { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + } + + /** + * Stop scanning. The current scanning parameters remain in effect. + * + * @retval BLE_ERROR_NONE if successfully stopped scanning procedure. + */ + virtual ble_error_t stopScan() { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + } + + /** + * Create a connection (GAP Link Establishment). + * + * @param peerAddr + * 48-bit address, LSB format. + * @param peerAddrType + * Address type of the peer. + * @param connectionParams + * Connection parameters. + * @param scanParams + * Paramters to be used while scanning for the peer. + * @return BLE_ERROR_NONE if connection establishment procedure is started + * successfully. The connectionCallback (if set) will be invoked upon + * a connection event. + */ + virtual ble_error_t connect(const Address_t peerAddr, + Gap::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams) { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + } + + /** + * This call initiates the disconnection procedure, and its completion will + * be communicated to the application with an invocation of the + * disconnectionCallback. + * + * @param reason + * The reason for disconnection to be sent back to the peer. + */ + virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason) { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + } + + /** + * This call initiates the disconnection procedure, and its completion will + * be communicated to the application with an invocation of the + * disconnectionCallback. + * + * @param reason + * The reason for disconnection to be sent back to the peer. + * + * @note: this version of disconnect() doesn't take a connection handle. It + * will work reliably only for stacks which are limited to a single + * connection. This API should be considered *deprecated* in favour of the + * altertive which takes a connection handle. It will be dropped in the future. + */ + virtual ble_error_t disconnect(DisconnectionReason_t reason) { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + } + + /** + * Get the GAP peripheral preferred connection parameters. These are the + * defaults that the peripheral would like to have in a connection. The + * choice of the connection parameters is eventually up to the central. + * + * @param[out] params + * The structure where the parameters will be stored. Memory + * for this is owned by the caller. + * + * @return BLE_ERROR_NONE if the parameters were successfully filled into + * the given structure pointed to by params. + */ + virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params) { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + } + + /** + * Set the GAP peripheral preferred connection parameters. These are the + * defaults that the peripheral would like to have in a connection. The + * choice of the connection parameters is eventually up to the central. + * + * @param[in] params + * The structure containing the desired parameters. + */ + virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params) { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + } + + /** + * Update connection parameters while in the peripheral role. + * @details In the peripheral role, this will send the corresponding L2CAP request to the connected peer and wait for + * the central to perform the procedure. + * @param[in] handle + * Connection Handle + * @param[in] params + * Pointer to desired connection parameters. If NULL is provided on a peripheral role, + * the parameters in the PPCP characteristic of the GAP service will be used instead. + */ + virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params) { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + } + + /** + * Set the device name characteristic in the GAP service. + * @param[in] deviceName + * The new value for the device-name. This is a UTF-8 encoded, <b>NULL-terminated</b> string. + */ + virtual ble_error_t setDeviceName(const uint8_t *deviceName) { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + } + + /** + * Get the value of the device name characteristic in the GAP service. + * @param[out] deviceName + * Pointer to an empty buffer where the UTF-8 *non NULL- + * terminated* string will be placed. Set this + * value to NULL in order to obtain the deviceName-length + * from the 'length' parameter. + * + * @param[in/out] lengthP + * (on input) Length of the buffer pointed to by deviceName; + * (on output) the complete device name length (without the + * null terminator). + * + * @note If the device name is longer than the size of the supplied buffer, + * length will return the complete device name length, and not the + * number of bytes actually returned in deviceName. The application may + * use this information to retry with a suitable buffer size. + */ + virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP) { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + } + + /** + * Set the appearance characteristic in the GAP service. + * @param[in] appearance + * The new value for the device-appearance. + */ + virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance) { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + } + + /** + * Get the appearance characteristic in the GAP service. + * @param[out] appearance + * The new value for the device-appearance. + */ + virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP) { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + } + + /** + * Set the radio's transmit power. + * @param[in] txPower Radio transmit power in dBm. + */ + virtual ble_error_t setTxPower(int8_t txPower) { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + } + + /** + * Query the underlying stack for permitted arguments for setTxPower(). + * + * @param[out] valueArrayPP + * Out parameter to receive the immutable array of Tx values. + * @param[out] countP + * Out parameter to receive the array's size. + */ + virtual void getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) { + *countP = 0; /* default implementation; override this API if this capability is supported. */ + } + +protected: + /* Override the following in the underlying adaptation layer to provide the functionality of scanning. */ + virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams) { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + } + + /* + * APIs with non-virtual implementations. + */ +public: + /** + * Returns the current GAP state of the device using a bitmask which + * describes whether the device is advertising and/or connected. + */ + GapState_t getState(void) const { + return state; + } + + /** + * Set the GAP advertising mode to use for this device. + */ + void setAdvertisingType(GapAdvertisingParams::AdvertisingType_t advType) { + _advParams.setAdvertisingType(advType); + } + + /** + * @param[in] interval + * Advertising interval in units of milliseconds. Advertising + * is disabled if interval is 0. If interval is smaller than + * the minimum supported value, then the minimum supported + * value is used instead. This minimum value can be discovered + * using getMinAdvertisingInterval(). + * + * This field must be set to 0 if connectionMode is equal + * to ADV_CONNECTABLE_DIRECTED. + * + * @note: Decreasing this value will allow central devices to detect a + * peripheral faster at the expense of more power being used by the radio + * due to the higher data transmit rate. + * + * @note: This API is now *deprecated* and will be dropped in the future. + * You should use the parallel API from Gap directly. A former call to + * ble.setAdvertisingInterval(...) should now be achieved using + * ble.gap().setAdvertisingInterval(...). + * + * @Note: [WARNING] This API previously used 0.625ms as the unit for its + * 'interval' argument. That required an explicit conversion from + * milliseconds using Gap::MSEC_TO_GAP_DURATION_UNITS(). This conversion is + * no longer required as the new units are milliseconds. Any application + * code depending on the old semantics would need to be updated accordingly. + */ + void setAdvertisingInterval(uint16_t interval) { + if (interval == 0) { + stopAdvertising(); + } else if (interval < getMinAdvertisingInterval()) { + interval = getMinAdvertisingInterval(); + } + _advParams.setInterval(MSEC_TO_ADVERTISEMENT_DURATION_UNITS(interval)); + } + + /** + * @param[in] timeout + * Advertising timeout (in seconds) between 0x1 and 0x3FFF (1 + * and 16383). Use 0 to disable the advertising timeout. + */ + void setAdvertisingTimeout(uint16_t timeout) { + _advParams.setTimeout(timeout); + } + + /** + * Start advertising. + */ + ble_error_t startAdvertising(void) { + setAdvertisingData(); /* update the underlying stack */ + return startAdvertising(_advParams); + } + + /** + * Reset any advertising payload prepared from prior calls to + * accumulateAdvertisingPayload(). This automatically propagates the re- + * initialized adv payload to the underlying stack. + * + * Note: This should be followed by a call to setAdvertisingPayload() or + * startAdvertising() before the update takes effect. + */ + void clearAdvertisingPayload(void) { + _advPayload.clear(); + setAdvertisingData(); + } + + /** + * Accumulate an AD structure in the advertising payload. Please note that + * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used + * as an additional 31 bytes if the advertising payload proves to be too + * small. + * + * @param[in] flags + * The flags to be added. Please refer to + * GapAdvertisingData::Flags for valid flags. Multiple + * flags may be specified in combination. + */ + ble_error_t accumulateAdvertisingPayload(uint8_t flags) { + ble_error_t rc; + if ((rc = _advPayload.addFlags(flags)) != BLE_ERROR_NONE) { + return rc; + } + + return setAdvertisingData(); + } + + /** + * Accumulate an AD structure in the advertising payload. Please note that + * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used + * as an additional 31 bytes if the advertising payload proves to be too + * small. + * + * @param app + * The appearance of the peripheral. + */ + ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::Appearance app) { + setAppearance(app); + + ble_error_t rc; + if ((rc = _advPayload.addAppearance(app)) != BLE_ERROR_NONE) { + return rc; + } + + return setAdvertisingData(); + } + + /** + * Accumulate an AD structure in the advertising payload. Please note that + * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used + * as an additional 31 bytes if the advertising payload proves to be too + * small. + * + * @param app + * The max transmit power to be used by the controller. This is + * only a hint. + */ + ble_error_t accumulateAdvertisingPayloadTxPower(int8_t power) { + ble_error_t rc; + if ((rc = _advPayload.addTxPower(power)) != BLE_ERROR_NONE) { + return rc; + } + + return setAdvertisingData(); + } + + /** + * Accumulate a variable length byte-stream as an AD structure in the + * advertising payload. Please note that the payload is limited to 31 bytes. + * The SCAN_RESPONSE message may be used as an additional 31 bytes if the + * advertising payload proves to be too small. + * + * @param type The type which describes the variable length data. + * @param data data bytes. + * @param len length of data. + */ + ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) { + if (type == GapAdvertisingData::COMPLETE_LOCAL_NAME) { + setDeviceName(data); + } + + ble_error_t rc; + if ((rc = _advPayload.addData(type, data, len)) != BLE_ERROR_NONE) { + return rc; + } + + return setAdvertisingData(); + } + + /** + * Setup a particular, user-constructed advertisement payload for the + * underlying stack. It would be uncommon for this API to be used directly; + * there are other APIs to build an advertisement payload (see above). + */ + ble_error_t setAdvertisingPayload(const GapAdvertisingData &payload) { + _advPayload = payload; + return setAdvertisingData(); + } + + /** + * @return Read back advertising data. Useful for storing and + * restoring payload. + */ + const GapAdvertisingData &getAdvertisingPayload(void) const { + return _advPayload; + } + + /** + * Accumulate a variable length byte-stream as an AD structure in the + * scanResponse payload. + * + * @param[in] type The type which describes the variable length data. + * @param[in] data data bytes. + * @param[in] len length of data. + */ + ble_error_t accumulateScanResponse(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) { + ble_error_t rc; + if ((rc = _scanResponse.addData(type, data, len)) != BLE_ERROR_NONE) { + return rc; + } + + return setAdvertisingData(); + } + + /** + * Reset any scan response prepared from prior calls to + * accumulateScanResponse(). + * + * Note: This should be followed by a call to setAdvertisingPayload() or + * startAdvertising() before the update takes effect. + */ + void clearScanResponse(void) { + _scanResponse.clear(); + setAdvertisingData(); + } + + /** + * Setup parameters for GAP scanning--i.e. observer mode. + * @param[in] interval + * Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s]. + * @param[in] window + * Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s]. + * @param[in] timeout + * Scan timeout (in seconds) between 0x0001 and 0xFFFF, 0x0000 disables timeout. + * @param[in] activeScanning + * Set to True if active-scanning is required. This is used to fetch the + * scan response from a peer if possible. + * + * The scanning window divided by the interval determines the duty cycle for + * scanning. For example, if the interval is 100ms and the window is 10ms, + * then the controller will scan for 10 percent of the time. It is possible + * to have the interval and window set to the same value. In this case, + * scanning is continuous, with a change of scanning frequency once every + * interval. + * + * Once the scanning parameters have been configured, scanning can be + * enabled by using startScan(). + * + * @Note: The scan interval and window are recommendations to the BLE stack. + */ + ble_error_t setScanParams(uint16_t interval = GapScanningParams::SCAN_INTERVAL_MAX, + uint16_t window = GapScanningParams::SCAN_WINDOW_MAX, + uint16_t timeout = 0, + bool activeScanning = false) { + ble_error_t rc; + if (((rc = _scanningParams.setInterval(interval)) == BLE_ERROR_NONE) && + ((rc = _scanningParams.setWindow(window)) == BLE_ERROR_NONE) && + ((rc = _scanningParams.setTimeout(timeout)) == BLE_ERROR_NONE)) { + _scanningParams.setActiveScanning(activeScanning); + return BLE_ERROR_NONE; + } + + return rc; + } + + /** + * Setup the scanInterval parameter for GAP scanning--i.e. observer mode. + * @param[in] interval + * Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s]. + * + * The scanning window divided by the interval determines the duty cycle for + * scanning. For example, if the interval is 100ms and the window is 10ms, + * then the controller will scan for 10 percent of the time. It is possible + * to have the interval and window set to the same value. In this case, + * scanning is continuous, with a change of scanning frequency once every + * interval. + * + * Once the scanning parameters have been configured, scanning can be + * enabled by using startScan(). + */ + ble_error_t setScanInterval(uint16_t interval) { + return _scanningParams.setInterval(interval); + } + + /** + * Setup the scanWindow parameter for GAP scanning--i.e. observer mode. + * @param[in] window + * Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s]. + * + * The scanning window divided by the interval determines the duty cycle for + * scanning. For example, if the interval is 100ms and the window is 10ms, + * then the controller will scan for 10 percent of the time. It is possible + * to have the interval and window set to the same value. In this case, + * scanning is continuous, with a change of scanning frequency once every + * interval. + * + * Once the scanning parameters have been configured, scanning can be + * enabled by using startScan(). + */ + ble_error_t setScanWindow(uint16_t window) { + return _scanningParams.setWindow(window); + } + + /** + * Setup parameters for GAP scanning--i.e. observer mode. + * @param[in] timeout + * Scan timeout (in seconds) between 0x0001 and 0xFFFF, 0x0000 disables timeout. + * + * Once the scanning parameters have been configured, scanning can be + * enabled by using startScan(). + */ + ble_error_t setScanTimeout(uint16_t timeout) { + return _scanningParams.setTimeout(timeout); + } + + /** + * Setup parameters for GAP scanning--i.e. observer mode. + * @param[in] activeScanning + * Set to True if active-scanning is required. This is used to fetch the + * scan response from a peer if possible. + * + * Once the scanning parameters have been configured, scanning can be + * enabled by using startScan(). + */ + void setActiveScanning(bool activeScanning) { + _scanningParams.setActiveScanning(activeScanning); + } + + /** + * Start scanning (Observer Procedure) based on the parameters currently in + * effect. + * + * @param[in] callback + * The application specific callback to be invoked upon + * receiving every advertisement report. This can be passed in + * as NULL, in which case scanning may not be enabled at all. + */ + ble_error_t startScan(void (*callback)(const AdvertisementCallbackParams_t *params)) { + ble_error_t err = BLE_ERROR_NONE; + if (callback) { + if ((err = startRadioScan(_scanningParams)) == BLE_ERROR_NONE) { + onAdvertisementReport.attach(callback); + } + } + + return err; + } + + /** + * Same as above, but this takes an (object, method) pair for a callback. + */ + template<typename T> + ble_error_t startScan(T *object, void (T::*callbackMember)(const AdvertisementCallbackParams_t *params)) { + ble_error_t err = BLE_ERROR_NONE; + if (object && callbackMember) { + if ((err = startRadioScan(_scanningParams)) == BLE_ERROR_NONE) { + onAdvertisementReport.attach(object, callbackMember); + } + } + + return err; + } + +private: + ble_error_t setAdvertisingData(void) { + return setAdvertisingData(_advPayload, _scanResponse); + } + +private: + virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &) = 0; + virtual ble_error_t startAdvertising(const GapAdvertisingParams &) = 0; + +public: + /** + * Accessors to read back currently active advertising params. + */ + GapAdvertisingParams &getAdvertisingParams(void) { + return _advParams; + } + const GapAdvertisingParams &getAdvertisingParams(void) const { + return _advParams; + } + + /** + * Setup a particular, user-constructed set of advertisement parameters for + * the underlying stack. It would be uncommon for this API to be used + * directly; there are other APIs to tweak advertisement parameters + * individually. + */ + void setAdvertisingParams(const GapAdvertisingParams &newParams) { + _advParams = newParams; + } + + /* Event callback handlers. */ +public: + /** + * Setup a callback for timeout events. Refer to TimeoutSource_t for + * possible event types. + */ + void onTimeout(TimeoutEventCallback_t callback) {timeoutCallback = callback;} + + /** + * Setup a callback for connection events. Refer to ConnectionEventCallback_t. + */ + void onConnection(ConnectionEventCallback_t callback) {connectionCallback = callback;} + + /** + * Set the application callback for disconnection events. + * @param callback + * Pointer to the unique callback. + */ + void onDisconnection(DisconnectionEventCallback_t callback) {disconnectionCallback = callback;} + + /** + * Append to a chain of callbacks to be invoked upon disconnection; these + * callbacks receive no context and are therefore different from the + * disconnectionCallback callback. + * @param callback + * function pointer to be invoked upon disconnection; receives no context. + */ + template<typename T> + void addToDisconnectionCallChain(T *tptr, void (T::*mptr)(void)) {disconnectionCallChain.add(tptr, mptr);} + + /** + * Set the application callback for radio-notification events. + * + * Radio Notification is a feature that enables ACTIVE and INACTIVE + * (nACTIVE) signals from the stack that notify the application when the + * radio is in use. The signal is sent using software interrupt. + * + * The ACTIVE signal is sent before the Radio Event starts. The nACTIVE + * signal is sent at the end of the Radio Event. These signals can be used + * by the application programmer to synchronize application logic with radio + * activity. For example, the ACTIVE signal can be used to shut off external + * devices to manage peak current drawn during periods when the radio is on, + * or to trigger sensor data collection for transmission in the Radio Event. + * + * @param callback + * The application handler to be invoked in response to a radio + * ACTIVE/INACTIVE event. + */ + virtual void onRadioNotification(RadioNotificationEventCallback_t callback) {radioNotificationCallback = callback;} + +protected: + Gap() : + _advParams(), + _advPayload(), + _scanningParams(), + _scanResponse(), + state(), + timeoutCallback(NULL), + connectionCallback(NULL), + disconnectionCallback(NULL), + radioNotificationCallback(), + onAdvertisementReport(), + disconnectionCallChain() { + _advPayload.clear(); + _scanResponse.clear(); + } + + /* Entry points for the underlying stack to report events back to the user. */ +public: + void processConnectionEvent(Handle_t handle, + Role_t role, + AddressType_t peerAddrType, + const Address_t peerAddr, + AddressType_t ownAddrType, + const Address_t ownAddr, + const ConnectionParams_t *connectionParams) { + state.connected = 1; + if (connectionCallback) { + ConnectionCallbackParams_t callbackParams(handle, role, peerAddrType, peerAddr, ownAddrType, ownAddr, connectionParams); + connectionCallback(&callbackParams); + } + } + + void processDisconnectionEvent(Handle_t handle, DisconnectionReason_t reason) { + state.connected = 0; + if (disconnectionCallback) { + disconnectionCallback(handle, reason); + } + disconnectionCallChain.call(); + } + + void processAdvertisementReport(const Address_t peerAddr, + int8_t rssi, + bool isScanResponse, + GapAdvertisingParams::AdvertisingType_t type, + uint8_t advertisingDataLen, + const uint8_t *advertisingData) { + AdvertisementCallbackParams_t params; + memcpy(params.peerAddr, peerAddr, ADDR_LEN); + params.rssi = rssi; + params.isScanResponse = isScanResponse; + params.type = type; + params.advertisingDataLen = advertisingDataLen; + params.advertisingData = advertisingData; + onAdvertisementReport.call(¶ms); + } + + void processTimeoutEvent(TimeoutSource_t source) { + if (timeoutCallback) { + timeoutCallback(source); + } + } + +protected: + GapAdvertisingParams _advParams; + GapAdvertisingData _advPayload; + GapScanningParams _scanningParams; + GapAdvertisingData _scanResponse; + + GapState_t state; + +protected: + TimeoutEventCallback_t timeoutCallback; + ConnectionEventCallback_t connectionCallback; + DisconnectionEventCallback_t disconnectionCallback; + RadioNotificationEventCallback_t radioNotificationCallback; + AdvertisementReportCallback_t onAdvertisementReport; + CallChain disconnectionCallChain; + +private: + /* disallow copy and assignment */ + Gap(const Gap &); + Gap& operator=(const Gap &); +}; + +#endif // ifndef __GAP_H__ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/GapAdvertisingData.h Fri Jun 19 15:53:28 2015 +0100 @@ -0,0 +1,310 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GAP_ADVERTISING_DATA_H__ +#define __GAP_ADVERTISING_DATA_H__ + +#include <stdint.h> +#include <string.h> + +#include "blecommon.h" + +#define GAP_ADVERTISING_DATA_MAX_PAYLOAD (31) + +/**************************************************************************/ +/*! + \brief + This class provides several helper functions to generate properly + formatted GAP Advertising and Scan Response data payloads + + \note + See Bluetooth Specification 4.0 (Vol. 3), Part C, Section 11 and 18 + for further information on Advertising and Scan Response data. + + \par Advertising and Scan Response Payloads + Advertising data and Scan Response data are organized around a set of + data types called 'AD types' in Bluetooth 4.0 (see the Bluetooth Core + Specification v4.0, Vol. 3, Part C, Sections 11 and 18). + + \par + Each AD type has it's own standardized 'assigned number', as defined + by the Bluetooth SIG: + https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile + + \par + For convenience sake, all appropriate AD types have been encapsulated + into GapAdvertisingData::DataType. + + \par + Before the AD Types and their payload (if any) can be inserted into + the Advertising or Scan Response frames, they need to be formatted as + follows: + + \li \c Record length (1 byte) + \li \c AD Type (1 byte) + \li \c AD payload (optional, only present if record length > 1) + + \par + This class takes care of properly formatting the payload, performs + some basic checks on the payload length, and tries to avoid common + errors like adding an exclusive AD field twice in the Advertising + or Scan Response payload. + + \par EXAMPLE + + \code + + // ToDo + + \endcode +*/ +/**************************************************************************/ +class GapAdvertisingData +{ +public: + /**********************************************************************/ + /*! + \brief + A list of Advertising Data types commonly used by peripherals. + These AD types are used to describe the capabilities of the + peripheral, and get inserted inside the advertising or scan + response payloads. + + \par Source + \li \c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 11, 18 + \li \c https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile + */ + /**********************************************************************/ + enum DataType { + FLAGS = 0x01, /**< \ref *Flags */ + INCOMPLETE_LIST_16BIT_SERVICE_IDS = 0x02, /**< Incomplete list of 16-bit Service IDs */ + COMPLETE_LIST_16BIT_SERVICE_IDS = 0x03, /**< Complete list of 16-bit Service IDs */ + INCOMPLETE_LIST_32BIT_SERVICE_IDS = 0x04, /**< Incomplete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */ + COMPLETE_LIST_32BIT_SERVICE_IDS = 0x05, /**< Complete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */ + INCOMPLETE_LIST_128BIT_SERVICE_IDS = 0x06, /**< Incomplete list of 128-bit Service IDs */ + COMPLETE_LIST_128BIT_SERVICE_IDS = 0x07, /**< Complete list of 128-bit Service IDs */ + SHORTENED_LOCAL_NAME = 0x08, /**< Shortened Local Name */ + COMPLETE_LOCAL_NAME = 0x09, /**< Complete Local Name */ + TX_POWER_LEVEL = 0x0A, /**< TX Power Level (in dBm) */ + DEVICE_ID = 0x10, /**< Device ID */ + SLAVE_CONNECTION_INTERVAL_RANGE = 0x12, /**< Slave Connection Interval Range */ + SERVICE_DATA = 0x16, /**< Service Data */ + APPEARANCE = 0x19, /**< \ref Appearance */ + ADVERTISING_INTERVAL = 0x1A, /**< Advertising Interval */ + MANUFACTURER_SPECIFIC_DATA = 0xFF /**< Manufacturer Specific Data */ + }; + + /**********************************************************************/ + /*! + \brief + A list of values for the FLAGS AD Type + + \note + You can use more than one value in the FLAGS AD Type (ex. + LE_GENERAL_DISCOVERABLE and BREDR_NOT_SUPPORTED). + + \par Source + \li \c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 18.1 + */ + /**********************************************************************/ + enum Flags { + LE_LIMITED_DISCOVERABLE = 0x01, /**< *Peripheral device is discoverable for a limited period of time */ + LE_GENERAL_DISCOVERABLE = 0x02, /**< Peripheral device is discoverable at any moment */ + BREDR_NOT_SUPPORTED = 0x04, /**< Peripheral device is LE only */ + SIMULTANEOUS_LE_BREDR_C = 0x08, /**< Not relevant - central mode only */ + SIMULTANEOUS_LE_BREDR_H = 0x10 /**< Not relevant - central mode only */ + }; + + /**********************************************************************/ + /*! + \brief + A list of values for the APPEARANCE AD Type, which describes the + physical shape or appearance of the device + + \par Source + \li \c Bluetooth Core Specification Supplement, Part A, Section 1.12 + \li \c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 12.2 + \li \c https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml + */ + /**********************************************************************/ + enum Appearance { + UNKNOWN = 0, /**< Unknown of unspecified appearance type */ + GENERIC_PHONE = 64, /**< Generic Phone */ + GENERIC_COMPUTER = 128, /**< Generic Computer */ + GENERIC_WATCH = 192, /**< Generic Watch */ + WATCH_SPORTS_WATCH = 193, /**< Sports Watch */ + GENERIC_CLOCK = 256, /**< Generic Clock */ + GENERIC_DISPLAY = 320, /**< Generic Display */ + GENERIC_REMOTE_CONTROL = 384, /**< Generic Remote Control */ + GENERIC_EYE_GLASSES = 448, /**< Generic Eye Glasses */ + GENERIC_TAG = 512, /**< Generic Tag */ + GENERIC_KEYRING = 576, /**< Generic Keyring */ + GENERIC_MEDIA_PLAYER = 640, /**< Generic Media Player */ + GENERIC_BARCODE_SCANNER = 704, /**< Generic Barcode Scanner */ + GENERIC_THERMOMETER = 768, /**< Generic Thermometer */ + THERMOMETER_EAR = 769, /**< Ear Thermometer */ + GENERIC_HEART_RATE_SENSOR = 832, /**< Generic Heart Rate Sensor */ + HEART_RATE_SENSOR_HEART_RATE_BELT = 833, /**< Belt Heart Rate Sensor */ + GENERIC_BLOOD_PRESSURE = 896, /**< Generic Blood Pressure */ + BLOOD_PRESSURE_ARM = 897, /**< Arm Blood Pressure */ + BLOOD_PRESSURE_WRIST = 898, /**< Wrist Blood Pressure */ + HUMAN_INTERFACE_DEVICE_HID = 960, /**< Human Interface Device (HID) */ + KEYBOARD = 961, /**< Keyboard */ + MOUSE = 962, /**< Mouse */ + JOYSTICK = 963, /**< Joystick */ + GAMEPAD = 964, /**< Gamepad */ + DIGITIZER_TABLET = 965, /**< Digitizer Tablet */ + CARD_READER = 966, /**< Card Read */ + DIGITAL_PEN = 967, /**< Digital Pen */ + BARCODE_SCANNER = 968, /**< Barcode Scanner */ + GENERIC_GLUCOSE_METER = 1024, /**< Generic Glucose Meter */ + GENERIC_RUNNING_WALKING_SENSOR = 1088, /**< Generic Running/Walking Sensor */ + RUNNING_WALKING_SENSOR_IN_SHOE = 1089, /**< In Shoe Running/Walking Sensor */ + RUNNING_WALKING_SENSOR_ON_SHOE = 1090, /**< On Shoe Running/Walking Sensor */ + RUNNING_WALKING_SENSOR_ON_HIP = 1091, /**< On Hip Running/Walking Sensor */ + GENERIC_CYCLING = 1152, /**< Generic Cycling */ + CYCLING_CYCLING_COMPUTER = 1153, /**< Cycling Computer */ + CYCLING_SPEED_SENSOR = 1154, /**< Cycling Speed Senspr */ + CYCLING_CADENCE_SENSOR = 1155, /**< Cycling Cadence Sensor */ + CYCLING_POWER_SENSOR = 1156, /**< Cycling Power Sensor */ + CYCLING_SPEED_AND_CADENCE_SENSOR = 1157, /**< Cycling Speed and Cadence Sensor */ + PULSE_OXIMETER_GENERIC = 3136, /**< Generic Pulse Oximeter */ + PULSE_OXIMETER_FINGERTIP = 3137, /**< Fingertip Pulse Oximeter */ + PULSE_OXIMETER_WRIST_WORN = 3138, /**< Wrist Worn Pulse Oximeter */ + OUTDOOR_GENERIC = 5184, /**< Generic Outdoor */ + OUTDOOR_LOCATION_DISPLAY_DEVICE = 5185, /**< Outdoor Location Display Device */ + OUTDOOR_LOCATION_AND_NAVIGATION_DISPLAY_DEVICE = 5186, /**< Outdoor Location and Navigation Display Device */ + OUTDOOR_LOCATION_POD = 5187, /**< Outdoor Location Pod */ + OUTDOOR_LOCATION_AND_NAVIGATION_POD = 5188 /**< Outdoor Location and Navigation Pod */ + }; + + GapAdvertisingData(void) : _payload(), _payloadLen(0), _appearance(GENERIC_TAG) { + /* empty */ + } + + /** + * Adds advertising data based on the specified AD type (see DataType) + * + * @param advDataType The Advertising 'DataType' to add + * @param payload Pointer to the payload contents + * @param len Size of the payload in bytes + * + * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the + * advertising buffer to overflow, else BLE_ERROR_NONE. + */ + ble_error_t addData(DataType advDataType, const uint8_t *payload, uint8_t len) + { + /* ToDo: Check if an AD type already exists and if the existing */ + /* value is exclusive or not (flags, etc.) */ + + /* Make sure we don't exceed the 31 byte payload limit */ + if (_payloadLen + len + 2 > GAP_ADVERTISING_DATA_MAX_PAYLOAD) { + return BLE_ERROR_BUFFER_OVERFLOW; + } + + /* Field length */ + memset(&_payload[_payloadLen], len + 1, 1); + _payloadLen++; + + /* Field ID */ + memset(&_payload[_payloadLen], (uint8_t)advDataType, 1); + _payloadLen++; + + /* Payload */ + memcpy(&_payload[_payloadLen], payload, len); + _payloadLen += len; + + return BLE_ERROR_NONE; + } + + /** + * Helper function to add APPEARANCE data to the advertising payload + * + * @param appearance + * The APPEARANCE value to add + * + * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the + * advertising buffer to overflow, else BLE_ERROR_NONE. + */ + ble_error_t addAppearance(Appearance appearance = GENERIC_TAG) { + _appearance = appearance; + return addData(GapAdvertisingData::APPEARANCE, (uint8_t *)&appearance, 2); + } + + /** + * Helper function to add FLAGS data to the advertising payload. + * @param flags + * LE_LIMITED_DISCOVERABLE + * The peripheral is discoverable for a limited period of time. + * LE_GENERAL_DISCOVERABLE + * The peripheral is permanently discoverable. + * BREDR_NOT_SUPPORTED + * This peripheral is a Bluetooth Low Energy only device (no EDR support). + * + * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the + * advertising buffer to overflow, else BLE_ERROR_NONE. + */ + ble_error_t addFlags(uint8_t flags = LE_GENERAL_DISCOVERABLE) { + return addData(GapAdvertisingData::FLAGS, &flags, 1); + } + + /** + * Helper function to add TX_POWER_LEVEL data to the advertising payload + * + * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the + * advertising buffer to overflow, else BLE_ERROR_NONE. + */ + ble_error_t addTxPower(int8_t txPower) { + /* ToDo: Basic error checking to make sure txPower is in range */ + return addData(GapAdvertisingData::TX_POWER_LEVEL, (uint8_t *)&txPower, 1); + } + + /** + * Clears the payload and resets the payload length counter + */ + void clear(void) { + memset(&_payload, 0, GAP_ADVERTISING_DATA_MAX_PAYLOAD); + _payloadLen = 0; + } + + /** + * Returns a pointer to the the current payload + */ + const uint8_t *getPayload(void) const { + return (_payloadLen > 0) ? _payload : NULL; + } + + /** + * Returns the current payload length (0..31 bytes) + */ + uint8_t getPayloadLen(void) const { + return _payloadLen; + } + + /** + * Returns the 16-bit appearance value for this device + */ + uint16_t getAppearance(void) const { + return (uint16_t)_appearance; + } + +private: + uint8_t _payload[GAP_ADVERTISING_DATA_MAX_PAYLOAD]; + uint8_t _payloadLen; + uint16_t _appearance; +}; + +#endif // ifndef __GAP_ADVERTISING_DATA_H__ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/GapAdvertisingParams.h Fri Jun 19 15:53:28 2015 +0100 @@ -0,0 +1,103 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#ifndef __GAP_ADVERTISING_PARAMS_H__ +#define __GAP_ADVERTISING_PARAMS_H__ + +/**************************************************************************/ +/*! + \brief + This class provides a wrapper for the core advertising parameters, + including the advertising type (Connectable Undirected, + Non Connectable Undirected, etc.), as well as the advertising and + timeout intervals. + + \par + See the following for more information on advertising types: + + \li \c Bluetooth Core Specification 4.0 (Vol. 6), Part B, Section 2.3.1 + \li \c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 9.3 +*/ +/**************************************************************************/ +class GapAdvertisingParams { +public: + static const unsigned GAP_ADV_PARAMS_INTERVAL_MIN = 0x0020; + static const unsigned GAP_ADV_PARAMS_INTERVAL_MIN_NONCON = 0x00A0; + static const unsigned GAP_ADV_PARAMS_INTERVAL_MAX = 0x4000; + static const unsigned GAP_ADV_PARAMS_TIMEOUT_MAX = 0x3FFF; + + /*! + * Encapsulates the peripheral advertising modes, which determine how + * the device appears to other central devices in hearing range + */ + enum AdvertisingType_t { + ADV_CONNECTABLE_UNDIRECTED, /**< Vol 3, Part C, Section 9.3.4 and Vol 6, Part B, Section 2.3.1.1 */ + ADV_CONNECTABLE_DIRECTED, /**< Vol 3, Part C, Section 9.3.3 and Vol 6, Part B, Section 2.3.1.2 */ + ADV_SCANNABLE_UNDIRECTED, /**< Include support for Scan Response payloads, see Vol 6, Part B, Section 2.3.1.4 */ + ADV_NON_CONNECTABLE_UNDIRECTED /**< Vol 3, Part C, Section 9.3.2 and Vol 6, Part B, Section 2.3.1.3 */ + }; + typedef enum AdvertisingType_t AdvertisingType; /* deprecated type alias. */ + +public: + GapAdvertisingParams(AdvertisingType_t advType = ADV_CONNECTABLE_UNDIRECTED, + uint16_t interval = GAP_ADV_PARAMS_INTERVAL_MIN_NONCON, + uint16_t timeout = 0) : _advType(advType), _interval(interval), _timeout(timeout) { + /* Interval checks */ + if (_advType == ADV_CONNECTABLE_DIRECTED) { + /* Interval must be 0 in directed connectable mode */ + _interval = 0; + } else if (_advType == ADV_NON_CONNECTABLE_UNDIRECTED) { + /* Min interval is slightly larger than in other modes */ + if (_interval < GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) { + _interval = GAP_ADV_PARAMS_INTERVAL_MIN_NONCON; + } + if (_interval > GAP_ADV_PARAMS_INTERVAL_MAX) { + _interval = GAP_ADV_PARAMS_INTERVAL_MAX; + } + } else { + /* Stay within interval limits */ + if (_interval < GAP_ADV_PARAMS_INTERVAL_MIN) { + _interval = GAP_ADV_PARAMS_INTERVAL_MIN; + } + if (_interval > GAP_ADV_PARAMS_INTERVAL_MAX) { + _interval = GAP_ADV_PARAMS_INTERVAL_MAX; + } + } + + /* Timeout checks */ + if (timeout) { + /* Stay within timeout limits */ + if (_timeout > GAP_ADV_PARAMS_TIMEOUT_MAX) { + _timeout = GAP_ADV_PARAMS_TIMEOUT_MAX; + } + } + } + + AdvertisingType_t getAdvertisingType(void) const {return _advType; } + uint16_t getInterval(void) const {return _interval;} + uint16_t getTimeout(void) const {return _timeout; } + + void setAdvertisingType(AdvertisingType_t newAdvType) {_advType = newAdvType; } + void setInterval(uint16_t newInterval) {_interval = newInterval;} + void setTimeout(uint16_t newTimeout) {_timeout = newTimeout; } + +private: + AdvertisingType_t _advType; + uint16_t _interval; + uint16_t _timeout; +}; + +#endif // ifndef __GAP_ADVERTISING_PARAMS_H__ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/GapEvents.h Fri Jun 19 15:53:28 2015 +0100 @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GAP_EVENTS_H__ +#define __GAP_EVENTS_H__ + +#include "blecommon.h" + +/**************************************************************************/ +/*! + \brief + The base class used to abstract away the callback events that can be + triggered with the GAP. +*/ +/**************************************************************************/ +class GapEvents +{ +public: + /******************************************************************/ + /*! + \brief + Identifies GAP events generated by the radio HW when an event + callback occurs + */ + /******************************************************************/ + typedef enum gapEvent_e { + GAP_EVENT_TIMEOUT = 1, /**< Advertising timed out before a connection was established */ + GAP_EVENT_CONNECTED = 2, /**< A connection was established with a central device */ + GAP_EVENT_DISCONNECTED = 3 /**< A connection was closed or lost with a central device */ + } gapEvent_t; +}; + +#endif // ifndef __GAP_EVENTS_H__ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/GapScanningParams.h Fri Jun 19 15:53:28 2015 +0100 @@ -0,0 +1,63 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#ifndef __GAP_SCANNING_PARAMS_H__ +#define __GAP_SCANNING_PARAMS_H__ + +class GapScanningParams { +public: + static const unsigned SCAN_INTERVAL_MIN = 0x0004; /**< Minimum Scan interval in 625 us units, i.e. 2.5 ms. */ + static const unsigned SCAN_INTERVAL_MAX = 0x4000; /**< Maximum Scan interval in 625 us units, i.e. 10.24 s. */ + static const unsigned SCAN_WINDOW_MIN = 0x0004; /**< Minimum Scan window in 625 us units, i.e. 2.5 ms. */ + static const unsigned SCAN_WINDOW_MAX = 0x4000; /**< Maximum Scan window in 625 us units, i.e. 10.24 s. */ + static const unsigned SCAN_TIMEOUT_MIN = 0x0001; /**< Minimum Scan timeout in seconds. */ + static const unsigned SCAN_TIMEOUT_MAX = 0xFFFF; /**< Maximum Scan timeout in seconds. */ + +public: + GapScanningParams(uint16_t interval = SCAN_INTERVAL_MAX, + uint16_t window = SCAN_WINDOW_MAX, + uint16_t timeout = 0, + bool activeScanning = false); + + ble_error_t setInterval(uint16_t newIntervalInMS); + + ble_error_t setWindow(uint16_t newWindowInMS); + + ble_error_t setTimeout(uint16_t newTimeout); + + void setActiveScanning(bool activeScanning); + +public: + /* @Note: The following return durations in units of 0.625 ms */ + uint16_t getInterval(void) const {return _interval;} + uint16_t getWindow(void) const {return _window; } + + uint16_t getTimeout(void) const {return _timeout; } + bool getActiveScanning(void) const {return _activeScanning;} + +private: + uint16_t _interval; /**< Scan interval in units of 625us (between 2.5ms to 10.24s). */ + uint16_t _window; /**< Scan window in units of 625us (between 2.5ms to 10.24s). */ + uint16_t _timeout; /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */ + bool _activeScanning; /**< obtain not only the advertising data from the peer device, but also their scanResponse if possible. */ + +private: + /* disallow copy constructor */ + GapScanningParams(const GapScanningParams &); + GapScanningParams& operator =(const GapScanningParams &in); +}; + +#endif // ifndef __GAP_SCANNING_PARAMS_H__ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/GattAttribute.h Fri Jun 19 15:53:28 2015 +0100 @@ -0,0 +1,79 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GATT_ATTRIBUTE_H__ +#define __GATT_ATTRIBUTE_H__ + +#include "UUID.h" + +class GattAttribute { +public: + typedef uint16_t Handle_t; + static const Handle_t INVALID_HANDLE = 0x0000; + +public: + /** + * @brief Creates a new GattAttribute using the specified + * UUID, value length, and inital value + * + * @param[in] uuid + * The UUID to use for this attribute + * @param[in] valuePtr + * The memory holding the initial value. + * @param[in] initialLen + * The min length in bytes of this attribute's value + * @param[in] maxLen + * The max length in bytes of this attribute's value + * + * @section EXAMPLE + * + * @code + * + * // UUID = 0x2A19, Min length 2, Max len = 2 + * GattAttribute attr = GattAttribute(0x2A19, &someValue, 2, 2); + * + * @endcode + */ + GattAttribute(const UUID &uuid, uint8_t *valuePtr = NULL, uint16_t initialLen = 0, uint16_t maxLen = 0) : + _uuid(uuid), _valuePtr(valuePtr), _initialLen(initialLen), _lenMax(maxLen), _len(initialLen), _handle() { + /* empty */ + } + +public: + Handle_t getHandle(void) const {return _handle; } + const UUID &getUUID(void) const {return _uuid; } + uint16_t getLength(void) const {return _len; } + uint16_t getInitialLength(void) const {return _initialLen;} + uint16_t getMaxLength(void) const {return _lenMax; } + uint16_t *getLengthPtr(void) {return &_len; } + void setHandle(Handle_t id) {_handle = id; } + uint8_t *getValuePtr(void) {return _valuePtr; } + +private: + UUID _uuid; /* Characteristic UUID */ + uint8_t *_valuePtr; + uint16_t _initialLen; /* Initial length of the value */ + uint16_t _lenMax; /* Maximum length of the value */ + uint16_t _len; /* Current length of the value */ + Handle_t _handle; + +private: + /* disallow copy and assignment */ + GattAttribute(const GattAttribute &); + GattAttribute& operator=(const GattAttribute &); +}; + +#endif // ifndef __GATT_ATTRIBUTE_H__ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/GattCallbackParamTypes.h Fri Jun 19 15:53:28 2015 +0100 @@ -0,0 +1,78 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GATT_CALLBACK_PARAM_TYPES_H__ +#define __GATT_CALLBACK_PARAM_TYPES_H__ + +struct GattWriteCallbackParams { + enum WriteOp_t { + OP_INVALID = 0x00, /**< Invalid Operation. */ + OP_WRITE_REQ = 0x01, /**< Write Request. */ + OP_WRITE_CMD = 0x02, /**< Write Command. */ + OP_SIGN_WRITE_CMD = 0x03, /**< Signed Write Command. */ + OP_PREP_WRITE_REQ = 0x04, /**< Prepare Write Request. */ + OP_EXEC_WRITE_REQ_CANCEL = 0x05, /**< Execute Write Request: Cancel all prepared writes. */ + OP_EXEC_WRITE_REQ_NOW = 0x06, /**< Execute Write Request: Immediately execute all prepared writes. */ + }; + + GattAttribute::Handle_t handle; + WriteOp_t writeOp; /**< Type of write operation, */ + uint16_t offset; /**< Offset for the write operation. */ + uint16_t len; + const uint8_t *data; /* @note: data might not persist beyond the callback; make a local copy if needed. */ +}; + +struct GattReadCallbackParams { + GattAttribute::Handle_t handle; + uint16_t offset; /**< Offset for the read operation. */ + uint16_t len; + const uint8_t *data; /* @note: data might not persist beyond the callback; make a local copy if needed. */ +}; + +enum GattAuthCallbackReply_t { + AUTH_CALLBACK_REPLY_SUCCESS = 0x00, /**< Success. */ + AUTH_CALLBACK_REPLY_ATTERR_INVALID_HANDLE = 0x0101, /**< ATT Error: Invalid Attribute Handle. */ + AUTH_CALLBACK_REPLY_ATTERR_READ_NOT_PERMITTED = 0x0102, /**< ATT Error: Read not permitted. */ + AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED = 0x0103, /**< ATT Error: Write not permitted. */ + AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHENTICATION = 0x0105, /**< ATT Error: Authenticated link required. */ + AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET = 0x0107, /**< ATT Error: Offset specified was past the end of the attribute. */ + AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION = 0x0108, /**< ATT Error: Used in ATT as Insufficient Authorisation. */ + AUTH_CALLBACK_REPLY_ATTERR_PREPARE_QUEUE_FULL = 0x0109, /**< ATT Error: Used in ATT as Prepare Queue Full. */ + AUTH_CALLBACK_REPLY_ATTERR_ATTRIBUTE_NOT_FOUND = 0x010A, /**< ATT Error: Used in ATT as Attribute not found. */ + AUTH_CALLBACK_REPLY_ATTERR_ATTRIBUTE_NOT_LONG = 0x010B, /**< ATT Error: Attribute cannot be read or written using read/write blob requests. */ + AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH = 0x010D, /**< ATT Error: Invalid value size. */ + AUTH_CALLBACK_REPLY_ATTERR_INSUF_RESOURCES = 0x0111, /**< ATT Error: Encrypted link required. */ +}; + +struct GattWriteAuthCallbackParams { + GattAttribute::Handle_t handle; + uint16_t offset; /**< Offset for the write operation. */ + uint16_t len; /**< Length of the incoming data. */ + const uint8_t *data; /**< Incoming data, variable length. */ + GattAuthCallbackReply_t authorizationReply; /* This is the out parameter which needs to be set to true by the callback if the + * request is to proceed; false otherwise. */ +}; + +struct GattReadAuthCallbackParams { + GattAttribute::Handle_t handle; + uint16_t offset; /**< Offset for the read operation. */ + uint16_t len; /**< Optional: new length of the outgoing data. */ + uint8_t *data; /**< Optional: new outgoing data. Leave at NULL if data is unchanged. */ + GattAuthCallbackReply_t authorizationReply; /* This is the out parameter which needs to be set to true by the callback if the + * request is to proceed; false otherwise. */ +}; + +#endif /*__GATT_CALLBACK_PARAM_TYPES_H__*/ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/GattCharacteristic.h Fri Jun 19 15:53:28 2015 +0100 @@ -0,0 +1,515 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GATT_CHARACTERISTIC_H__ +#define __GATT_CHARACTERISTIC_H__ + +#include "Gap.h" +#include "SecurityManager.h" +#include "GattAttribute.h" +#include "GattCallbackParamTypes.h" +#include "FunctionPointerWithContext.h" + +class GattCharacteristic { +public: + enum { + UUID_BATTERY_LEVEL_STATE_CHAR = 0x2A1B, + UUID_BATTERY_POWER_STATE_CHAR = 0x2A1A, + UUID_REMOVABLE_CHAR = 0x2A3A, + UUID_SERVICE_REQUIRED_CHAR = 0x2A3B, + UUID_ALERT_CATEGORY_ID_CHAR = 0x2A43, + UUID_ALERT_CATEGORY_ID_BIT_MASK_CHAR = 0x2A42, + UUID_ALERT_LEVEL_CHAR = 0x2A06, + UUID_ALERT_NOTIFICATION_CONTROL_POINT_CHAR = 0x2A44, + UUID_ALERT_STATUS_CHAR = 0x2A3F, + UUID_BATTERY_LEVEL_CHAR = 0x2A19, + UUID_BLOOD_PRESSURE_FEATURE_CHAR = 0x2A49, + UUID_BLOOD_PRESSURE_MEASUREMENT_CHAR = 0x2A35, + UUID_BODY_SENSOR_LOCATION_CHAR = 0x2A38, + UUID_BOOT_KEYBOARD_INPUT_REPORT_CHAR = 0x2A22, + UUID_BOOT_KEYBOARD_OUTPUT_REPORT_CHAR = 0x2A32, + UUID_BOOT_MOUSE_INPUT_REPORT_CHAR = 0x2A33, + UUID_CURRENT_TIME_CHAR = 0x2A2B, + UUID_DATE_TIME_CHAR = 0x2A08, + UUID_DAY_DATE_TIME_CHAR = 0x2A0A, + UUID_DAY_OF_WEEK_CHAR = 0x2A09, + UUID_DST_OFFSET_CHAR = 0x2A0D, + UUID_EXACT_TIME_256_CHAR = 0x2A0C, + UUID_FIRMWARE_REVISION_STRING_CHAR = 0x2A26, + UUID_GLUCOSE_FEATURE_CHAR = 0x2A51, + UUID_GLUCOSE_MEASUREMENT_CHAR = 0x2A18, + UUID_GLUCOSE_MEASUREMENT_CONTEXT_CHAR = 0x2A34, + UUID_HARDWARE_REVISION_STRING_CHAR = 0x2A27, + UUID_HEART_RATE_CONTROL_POINT_CHAR = 0x2A39, + UUID_HEART_RATE_MEASUREMENT_CHAR = 0x2A37, + UUID_HID_CONTROL_POINT_CHAR = 0x2A4C, + UUID_HID_INFORMATION_CHAR = 0x2A4A, + UUID_IEEE_REGULATORY_CERTIFICATION_DATA_LIST_CHAR = 0x2A2A, + UUID_INTERMEDIATE_CUFF_PRESSURE_CHAR = 0x2A36, + UUID_INTERMEDIATE_TEMPERATURE_CHAR = 0x2A1E, + UUID_LOCAL_TIME_INFORMATION_CHAR = 0x2A0F, + UUID_MANUFACTURER_NAME_STRING_CHAR = 0x2A29, + UUID_MEASUREMENT_INTERVAL_CHAR = 0x2A21, + UUID_MODEL_NUMBER_STRING_CHAR = 0x2A24, + UUID_UNREAD_ALERT_CHAR = 0x2A45, + UUID_NEW_ALERT_CHAR = 0x2A46, + UUID_PNP_ID_CHAR = 0x2A50, + UUID_PROTOCOL_MODE_CHAR = 0x2A4E, + UUID_RECORD_ACCESS_CONTROL_POINT_CHAR = 0x2A52, + UUID_REFERENCE_TIME_INFORMATION_CHAR = 0x2A14, + UUID_REPORT_CHAR = 0x2A4D, + UUID_REPORT_MAP_CHAR = 0x2A4B, + UUID_RINGER_CONTROL_POINT_CHAR = 0x2A40, + UUID_RINGER_SETTING_CHAR = 0x2A41, + UUID_SCAN_INTERVAL_WINDOW_CHAR = 0x2A4F, + UUID_SCAN_REFRESH_CHAR = 0x2A31, + UUID_SERIAL_NUMBER_STRING_CHAR = 0x2A25, + UUID_SOFTWARE_REVISION_STRING_CHAR = 0x2A28, + UUID_SUPPORTED_NEW_ALERT_CATEGORY_CHAR = 0x2A47, + UUID_SUPPORTED_UNREAD_ALERT_CATEGORY_CHAR = 0x2A48, + UUID_SYSTEM_ID_CHAR = 0x2A23, + UUID_TEMPERATURE_MEASUREMENT_CHAR = 0x2A1C, + UUID_TEMPERATURE_TYPE_CHAR = 0x2A1D, + UUID_TIME_ACCURACY_CHAR = 0x2A12, + UUID_TIME_SOURCE_CHAR = 0x2A13, + UUID_TIME_UPDATE_CONTROL_POINT_CHAR = 0x2A16, + UUID_TIME_UPDATE_STATE_CHAR = 0x2A17, + UUID_TIME_WITH_DST_CHAR = 0x2A11, + UUID_TIME_ZONE_CHAR = 0x2A0E, + UUID_TX_POWER_LEVEL_CHAR = 0x2A07, + UUID_CSC_FEATURE_CHAR = 0x2A5C, + UUID_CSC_MEASUREMENT_CHAR = 0x2A5B, + UUID_RSC_FEATURE_CHAR = 0x2A54, + UUID_RSC_MEASUREMENT_CHAR = 0x2A53, + }; + + /**************************************************************************/ + /*! + \brief Standard GATT characteristic presentation format unit types. + These unit types are used to describe what the raw numeric + data in a characteristic actually represents. + + \note See https://developer.bluetooth.org/gatt/units/Pages/default.aspx + */ + /**************************************************************************/ + enum { + BLE_GATT_UNIT_NONE = 0x2700, /**< No specified unit type */ + BLE_GATT_UNIT_LENGTH_METRE = 0x2701, /**< Length, Metre */ + BLE_GATT_UNIT_MASS_KILOGRAM = 0x2702, /**< Mass, Kilogram */ + BLE_GATT_UNIT_TIME_SECOND = 0x2703, /**< Time, Second */ + BLE_GATT_UNIT_ELECTRIC_CURRENT_AMPERE = 0x2704, /**< Electric Current, Ampere */ + BLE_GATT_UNIT_THERMODYNAMIC_TEMPERATURE_KELVIN = 0x2705, /**< Thermodynamic Temperature, Kelvin */ + BLE_GATT_UNIT_AMOUNT_OF_SUBSTANCE_MOLE = 0x2706, /**< Amount of Substance, Mole */ + BLE_GATT_UNIT_LUMINOUS_INTENSITY_CANDELA = 0x2707, /**< Luminous Intensity, Candela */ + BLE_GATT_UNIT_AREA_SQUARE_METRES = 0x2710, /**< Area, Square Metres */ + BLE_GATT_UNIT_VOLUME_CUBIC_METRES = 0x2711, /**< Volume, Cubic Metres*/ + BLE_GATT_UNIT_VELOCITY_METRES_PER_SECOND = 0x2712, /**< Velocity, Metres per Second*/ + BLE_GATT_UNIT_ACCELERATION_METRES_PER_SECOND_SQUARED = 0x2713, /**< Acceleration, Metres per Second Squared */ + BLE_GATT_UNIT_WAVENUMBER_RECIPROCAL_METRE = 0x2714, /**< Wave Number Reciprocal, Metre */ + BLE_GATT_UNIT_DENSITY_KILOGRAM_PER_CUBIC_METRE = 0x2715, /**< Density, Kilogram per Cubic Metre */ + BLE_GATT_UNIT_SURFACE_DENSITY_KILOGRAM_PER_SQUARE_METRE = 0x2716, /**< */ + BLE_GATT_UNIT_SPECIFIC_VOLUME_CUBIC_METRE_PER_KILOGRAM = 0x2717, /**< */ + BLE_GATT_UNIT_CURRENT_DENSITY_AMPERE_PER_SQUARE_METRE = 0x2718, /**< */ + BLE_GATT_UNIT_MAGNETIC_FIELD_STRENGTH_AMPERE_PER_METRE = 0x2719, /**< Magnetic Field Strength, Ampere per Metre */ + BLE_GATT_UNIT_AMOUNT_CONCENTRATION_MOLE_PER_CUBIC_METRE = 0x271A, /**< */ + BLE_GATT_UNIT_MASS_CONCENTRATION_KILOGRAM_PER_CUBIC_METRE = 0x271B, /**< */ + BLE_GATT_UNIT_LUMINANCE_CANDELA_PER_SQUARE_METRE = 0x271C, /**< */ + BLE_GATT_UNIT_REFRACTIVE_INDEX = 0x271D, /**< */ + BLE_GATT_UNIT_RELATIVE_PERMEABILITY = 0x271E, /**< */ + BLE_GATT_UNIT_PLANE_ANGLE_RADIAN = 0x2720, /**< */ + BLE_GATT_UNIT_SOLID_ANGLE_STERADIAN = 0x2721, /**< */ + BLE_GATT_UNIT_FREQUENCY_HERTZ = 0x2722, /**< Frequency, Hertz */ + BLE_GATT_UNIT_FORCE_NEWTON = 0x2723, /**< Force, Newton */ + BLE_GATT_UNIT_PRESSURE_PASCAL = 0x2724, /**< Pressure, Pascal */ + BLE_GATT_UNIT_ENERGY_JOULE = 0x2725, /**< Energy, Joule */ + BLE_GATT_UNIT_POWER_WATT = 0x2726, /**< Power, Watt */ + BLE_GATT_UNIT_ELECTRIC_CHARGE_COULOMB = 0x2727, /**< Electrical Charge, Coulomb */ + BLE_GATT_UNIT_ELECTRIC_POTENTIAL_DIFFERENCE_VOLT = 0x2728, /**< Electrical Potential Difference, Voltage */ + BLE_GATT_UNIT_CAPACITANCE_FARAD = 0x2729, /**< */ + BLE_GATT_UNIT_ELECTRIC_RESISTANCE_OHM = 0x272A, /**< */ + BLE_GATT_UNIT_ELECTRIC_CONDUCTANCE_SIEMENS = 0x272B, /**< */ + BLE_GATT_UNIT_MAGNETIC_FLEX_WEBER = 0x272C, /**< */ + BLE_GATT_UNIT_MAGNETIC_FLEX_DENSITY_TESLA = 0x272D, /**< */ + BLE_GATT_UNIT_INDUCTANCE_HENRY = 0x272E, /**< */ + BLE_GATT_UNIT_THERMODYNAMIC_TEMPERATURE_DEGREE_CELSIUS = 0x272F, /**< */ + BLE_GATT_UNIT_LUMINOUS_FLUX_LUMEN = 0x2730, /**< */ + BLE_GATT_UNIT_ILLUMINANCE_LUX = 0x2731, /**< */ + BLE_GATT_UNIT_ACTIVITY_REFERRED_TO_A_RADIONUCLIDE_BECQUEREL = 0x2732, /**< */ + BLE_GATT_UNIT_ABSORBED_DOSE_GRAY = 0x2733, /**< */ + BLE_GATT_UNIT_DOSE_EQUIVALENT_SIEVERT = 0x2734, /**< */ + BLE_GATT_UNIT_CATALYTIC_ACTIVITY_KATAL = 0x2735, /**< */ + BLE_GATT_UNIT_DYNAMIC_VISCOSITY_PASCAL_SECOND = 0x2740, /**< */ + BLE_GATT_UNIT_MOMENT_OF_FORCE_NEWTON_METRE = 0x2741, /**< */ + BLE_GATT_UNIT_SURFACE_TENSION_NEWTON_PER_METRE = 0x2742, /**< */ + BLE_GATT_UNIT_ANGULAR_VELOCITY_RADIAN_PER_SECOND = 0x2743, /**< */ + BLE_GATT_UNIT_ANGULAR_ACCELERATION_RADIAN_PER_SECOND_SQUARED = 0x2744, /**< */ + BLE_GATT_UNIT_HEAT_FLUX_DENSITY_WATT_PER_SQUARE_METRE = 0x2745, /**< */ + BLE_GATT_UNIT_HEAT_CAPACITY_JOULE_PER_KELVIN = 0x2746, /**< */ + BLE_GATT_UNIT_SPECIFIC_HEAT_CAPACITY_JOULE_PER_KILOGRAM_KELVIN = 0x2747, /**< */ + BLE_GATT_UNIT_SPECIFIC_ENERGY_JOULE_PER_KILOGRAM = 0x2748, /**< */ + BLE_GATT_UNIT_THERMAL_CONDUCTIVITY_WATT_PER_METRE_KELVIN = 0x2749, /**< */ + BLE_GATT_UNIT_ENERGY_DENSITY_JOULE_PER_CUBIC_METRE = 0x274A, /**< */ + BLE_GATT_UNIT_ELECTRIC_FIELD_STRENGTH_VOLT_PER_METRE = 0x274B, /**< */ + BLE_GATT_UNIT_ELECTRIC_CHARGE_DENSITY_COULOMB_PER_CUBIC_METRE = 0x274C, /**< */ + BLE_GATT_UNIT_SURFACE_CHARGE_DENSITY_COULOMB_PER_SQUARE_METRE = 0x274D, /**< */ + BLE_GATT_UNIT_ELECTRIC_FLUX_DENSITY_COULOMB_PER_SQUARE_METRE = 0x274E, /**< */ + BLE_GATT_UNIT_PERMITTIVITY_FARAD_PER_METRE = 0x274F, /**< */ + BLE_GATT_UNIT_PERMEABILITY_HENRY_PER_METRE = 0x2750, /**< */ + BLE_GATT_UNIT_MOLAR_ENERGY_JOULE_PER_MOLE = 0x2751, /**< */ + BLE_GATT_UNIT_MOLAR_ENTROPY_JOULE_PER_MOLE_KELVIN = 0x2752, /**< */ + BLE_GATT_UNIT_EXPOSURE_COULOMB_PER_KILOGRAM = 0x2753, /**< */ + BLE_GATT_UNIT_ABSORBED_DOSE_RATE_GRAY_PER_SECOND = 0x2754, /**< */ + BLE_GATT_UNIT_RADIANT_INTENSITY_WATT_PER_STERADIAN = 0x2755, /**< */ + BLE_GATT_UNIT_RADIANCE_WATT_PER_SQUARE_METRE_STERADIAN = 0x2756, /**< */ + BLE_GATT_UNIT_CATALYTIC_ACTIVITY_CONCENTRATION_KATAL_PER_CUBIC_METRE = 0x2757, /**< */ + BLE_GATT_UNIT_TIME_MINUTE = 0x2760, /**< Time, Minute */ + BLE_GATT_UNIT_TIME_HOUR = 0x2761, /**< Time, Hour */ + BLE_GATT_UNIT_TIME_DAY = 0x2762, /**< Time, Day */ + BLE_GATT_UNIT_PLANE_ANGLE_DEGREE = 0x2763, /**< */ + BLE_GATT_UNIT_PLANE_ANGLE_MINUTE = 0x2764, /**< */ + BLE_GATT_UNIT_PLANE_ANGLE_SECOND = 0x2765, /**< */ + BLE_GATT_UNIT_AREA_HECTARE = 0x2766, /**< */ + BLE_GATT_UNIT_VOLUME_LITRE = 0x2767, /**< */ + BLE_GATT_UNIT_MASS_TONNE = 0x2768, /**< */ + BLE_GATT_UNIT_PRESSURE_BAR = 0x2780, /**< Pressure, Bar */ + BLE_GATT_UNIT_PRESSURE_MILLIMETRE_OF_MERCURY = 0x2781, /**< Pressure, Millimetre of Mercury */ + BLE_GATT_UNIT_LENGTH_ANGSTROM = 0x2782, /**< */ + BLE_GATT_UNIT_LENGTH_NAUTICAL_MILE = 0x2783, /**< */ + BLE_GATT_UNIT_AREA_BARN = 0x2784, /**< */ + BLE_GATT_UNIT_VELOCITY_KNOT = 0x2785, /**< */ + BLE_GATT_UNIT_LOGARITHMIC_RADIO_QUANTITY_NEPER = 0x2786, /**< */ + BLE_GATT_UNIT_LOGARITHMIC_RADIO_QUANTITY_BEL = 0x2787, /**< */ + BLE_GATT_UNIT_LENGTH_YARD = 0x27A0, /**< Length, Yard */ + BLE_GATT_UNIT_LENGTH_PARSEC = 0x27A1, /**< Length, Parsec */ + BLE_GATT_UNIT_LENGTH_INCH = 0x27A2, /**< Length, Inch */ + BLE_GATT_UNIT_LENGTH_FOOT = 0x27A3, /**< Length, Foot */ + BLE_GATT_UNIT_LENGTH_MILE = 0x27A4, /**< Length, Mile */ + BLE_GATT_UNIT_PRESSURE_POUND_FORCE_PER_SQUARE_INCH = 0x27A5, /**< */ + BLE_GATT_UNIT_VELOCITY_KILOMETRE_PER_HOUR = 0x27A6, /**< Velocity, Kilometre per Hour */ + BLE_GATT_UNIT_VELOCITY_MILE_PER_HOUR = 0x27A7, /**< Velocity, Mile per Hour */ + BLE_GATT_UNIT_ANGULAR_VELOCITY_REVOLUTION_PER_MINUTE = 0x27A8, /**< Angular Velocity, Revolution per Minute */ + BLE_GATT_UNIT_ENERGY_GRAM_CALORIE = 0x27A9, /**< Energy, Gram Calorie */ + BLE_GATT_UNIT_ENERGY_KILOGRAM_CALORIE = 0x27AA, /**< Energy, Kilogram Calorie */ + BLE_GATT_UNIT_ENERGY_KILOWATT_HOUR = 0x27AB, /**< Energy, Killowatt Hour */ + BLE_GATT_UNIT_THERMODYNAMIC_TEMPERATURE_DEGREE_FAHRENHEIT = 0x27AC, /**< */ + BLE_GATT_UNIT_PERCENTAGE = 0x27AD, /**< Percentage */ + BLE_GATT_UNIT_PER_MILLE = 0x27AE, /**< */ + BLE_GATT_UNIT_PERIOD_BEATS_PER_MINUTE = 0x27AF, /**< */ + BLE_GATT_UNIT_ELECTRIC_CHARGE_AMPERE_HOURS = 0x27B0, /**< */ + BLE_GATT_UNIT_MASS_DENSITY_MILLIGRAM_PER_DECILITRE = 0x27B1, /**< */ + BLE_GATT_UNIT_MASS_DENSITY_MILLIMOLE_PER_LITRE = 0x27B2, /**< */ + BLE_GATT_UNIT_TIME_YEAR = 0x27B3, /**< Time, Year */ + BLE_GATT_UNIT_TIME_MONTH = 0x27B4, /**< Time, Month */ + BLE_GATT_UNIT_CONCENTRATION_COUNT_PER_CUBIC_METRE = 0x27B5, /**< */ + BLE_GATT_UNIT_IRRADIANCE_WATT_PER_SQUARE_METRE = 0x27B6 /**< */ + }; + + /**************************************************************************/ + /*! + \brief Standard GATT number types + + \note See Bluetooth Specification 4.0 (Vol. 3), Part G, Section 3.3.3.5.2 + \note See http://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml + */ + /**************************************************************************/ + enum { + BLE_GATT_FORMAT_RFU = 0x00, /**< Reserved For Future Use. */ + BLE_GATT_FORMAT_BOOLEAN = 0x01, /**< Boolean. */ + BLE_GATT_FORMAT_2BIT = 0x02, /**< Unsigned 2-bit integer. */ + BLE_GATT_FORMAT_NIBBLE = 0x03, /**< Unsigned 4-bit integer. */ + BLE_GATT_FORMAT_UINT8 = 0x04, /**< Unsigned 8-bit integer. */ + BLE_GATT_FORMAT_UINT12 = 0x05, /**< Unsigned 12-bit integer. */ + BLE_GATT_FORMAT_UINT16 = 0x06, /**< Unsigned 16-bit integer. */ + BLE_GATT_FORMAT_UINT24 = 0x07, /**< Unsigned 24-bit integer. */ + BLE_GATT_FORMAT_UINT32 = 0x08, /**< Unsigned 32-bit integer. */ + BLE_GATT_FORMAT_UINT48 = 0x09, /**< Unsigned 48-bit integer. */ + BLE_GATT_FORMAT_UINT64 = 0x0A, /**< Unsigned 64-bit integer. */ + BLE_GATT_FORMAT_UINT128 = 0x0B, /**< Unsigned 128-bit integer. */ + BLE_GATT_FORMAT_SINT8 = 0x0C, /**< Signed 2-bit integer. */ + BLE_GATT_FORMAT_SINT12 = 0x0D, /**< Signed 12-bit integer. */ + BLE_GATT_FORMAT_SINT16 = 0x0E, /**< Signed 16-bit integer. */ + BLE_GATT_FORMAT_SINT24 = 0x0F, /**< Signed 24-bit integer. */ + BLE_GATT_FORMAT_SINT32 = 0x10, /**< Signed 32-bit integer. */ + BLE_GATT_FORMAT_SINT48 = 0x11, /**< Signed 48-bit integer. */ + BLE_GATT_FORMAT_SINT64 = 0x12, /**< Signed 64-bit integer. */ + BLE_GATT_FORMAT_SINT128 = 0x13, /**< Signed 128-bit integer. */ + BLE_GATT_FORMAT_FLOAT32 = 0x14, /**< IEEE-754 32-bit floating point. */ + BLE_GATT_FORMAT_FLOAT64 = 0x15, /**< IEEE-754 64-bit floating point. */ + BLE_GATT_FORMAT_SFLOAT = 0x16, /**< IEEE-11073 16-bit SFLOAT. */ + BLE_GATT_FORMAT_FLOAT = 0x17, /**< IEEE-11073 32-bit FLOAT. */ + BLE_GATT_FORMAT_DUINT16 = 0x18, /**< IEEE-20601 format. */ + BLE_GATT_FORMAT_UTF8S = 0x19, /**< UTF-8 string. */ + BLE_GATT_FORMAT_UTF16S = 0x1A, /**< UTF-16 string. */ + BLE_GATT_FORMAT_STRUCT = 0x1B /**< Opaque Structure. */ + }; + + /**************************************************************************/ + /*! + \brief Standard GATT characteristic properties + + \note See Bluetooth Specification 4.0 (Vol. 3), Part G, Section 3.3.1.1 + and Section 3.3.3.1 for Extended Properties + */ + /**************************************************************************/ + typedef enum ble_gatt_char_properties_e { + BLE_GATT_CHAR_PROPERTIES_NONE = 0x00, + BLE_GATT_CHAR_PROPERTIES_BROADCAST = 0x01, /**< Permits broadcasts of the Characteristic Value using Server Characteristic Configuration Descriptor. */ + BLE_GATT_CHAR_PROPERTIES_READ = 0x02, /**< Permits reads of the Characteristic Value. */ + BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE = 0x04, /**< Permits writes of the Characteristic Value without response. */ + BLE_GATT_CHAR_PROPERTIES_WRITE = 0x08, /**< Permits writes of the Characteristic Value with response. */ + BLE_GATT_CHAR_PROPERTIES_NOTIFY = 0x10, /**< Permits notifications of a Characteristic Value without acknowledgment. */ + BLE_GATT_CHAR_PROPERTIES_INDICATE = 0x20, /**< Permits indications of a Characteristic Value with acknowledgment. */ + BLE_GATT_CHAR_PROPERTIES_AUTHENTICATED_SIGNED_WRITES = 0x40, /**< Permits signed writes to the Characteristic Value. */ + BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES = 0x80 /**< Additional characteristic properties are defined in the Characteristic Extended Properties Descriptor */ + } ble_gatt_char_properties_t; + + /**************************************************************************/ + /*! + \brief GATT presentation format wrapper + + \note See Bluetooth Specification 4.0 (Vol. 3), Part G, Section 3.3.3.5 + \note See https://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml + */ + /**************************************************************************/ + typedef struct PresentationFormat { + uint8_t gatt_format; /**< Format of the value, see @ref ble_gatt_format_t. */ + int8_t exponent; /**< Exponent for integer data types. Ex. if Exponent = -3 and the char value is 3892, the actual value is 3.892 */ + uint16_t gatt_unit; /**< UUID from Bluetooth Assigned Numbers, see @ref ble_gatt_unit_t. */ + uint8_t gatt_namespace; /**< Namespace from Bluetooth Assigned Numbers, normally '1', see @ref BLE_GATT_CPF_NAMESPACES. */ + uint16_t gatt_nsdesc; /**< Namespace description from Bluetooth Assigned Numbers, normally '0', see @ref BLE_GATT_CPF_NAMESPACES. */ + } presentation_format_t; + + /** + * @brief Creates a new GattCharacteristic using the specified 16-bit + * UUID, value length, and properties + * + * @note The UUID value must be unique in the service and is normally >1 + * + * @param[in] uuid + * The UUID to use for this characteristic + * @param[in] valuePtr + * The memory holding the initial value. The value is copied + * into the stack when the enclosing service is added; and + * thereafter maintained internally by the stack. + * @param[in] initialLen + * The min length in bytes of this characteristic's value + * @param[in] maxLen + * The max length in bytes of this characteristic's value + * @param[in] props + * The 8-bit bit field containing the characteristic's properties + * @param[in] descriptors + * A pointer to an array of descriptors to be included within + * this characteristic. The memory for the descriptor array is + * owned by the caller, and should remain valid at least until + * the enclosing service is added to the GATT table. + * @param[in] numDescriptors + * The number of descriptors in the previous array. + * + * @NOTE: If valuePtr == NULL, initialLength == 0, and properties == READ + * for the value attribute of a characteristic, then that particular + * characteristic may be considered optional and dropped while + * instantiating the service with the underlying BLE stack. + */ + GattCharacteristic(const UUID &uuid, + uint8_t *valuePtr = NULL, + uint16_t initialLen = 0, + uint16_t maxLen = 0, + uint8_t props = BLE_GATT_CHAR_PROPERTIES_NONE, + GattAttribute *descriptors[] = NULL, + unsigned numDescriptors = 0) : + _valueAttribute(uuid, valuePtr, initialLen, maxLen), + _properties(props), + _requiredSecurity(SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK), + _descriptors(descriptors), + _descriptorCount(numDescriptors), + enabledReadAuthorization(false), + enabledWriteAuthorization(false), + readAuthorizationCallback(), + writeAuthorizationCallback() { + /* empty */ + } + +public: + /** + * Setup the minimum security (mode and level) requirements for access to the characteristic's value attribute. + * + * @param securityMode Can be one of encryption or signing, with or without protection for MITM (man in the middle attacks). + */ + void requireSecurity(SecurityManager::SecurityMode_t securityMode) { + _requiredSecurity = securityMode; + } + +public: + /** + * Authorization. + */ + void setWriteAuthorizationCallback(void (*callback)(GattWriteAuthCallbackParams *)) { + writeAuthorizationCallback.attach(callback); + enabledWriteAuthorization = true; + } + template <typename T> + void setWriteAuthorizationCallback(T *object, void (T::*member)(GattWriteAuthCallbackParams *)) { + writeAuthorizationCallback.attach(object, member); + enabledWriteAuthorization = true; + } + void setReadAuthorizationCallback(void (*callback)(GattReadAuthCallbackParams *)) { + readAuthorizationCallback.attach(callback); + enabledReadAuthorization = true; + } + template <typename T> + void setReadAuthorizationCallback(T *object, void (T::*member)(GattReadAuthCallbackParams *)) { + readAuthorizationCallback.attach(object, member); + enabledReadAuthorization = true; + } + + /** + * Helper function meant to be called from the guts of the BLE stack to + * determine the authorization reply for a write request. + * @param params to capture the context of the write-auth request; and also contains an out-parameter for reply. + * @return true if the write is authorized to proceed. + */ + GattAuthCallbackReply_t authorizeWrite(GattWriteAuthCallbackParams *params) { + if (!isWriteAuthorizationEnabled()) { + return AUTH_CALLBACK_REPLY_SUCCESS; + } + + params->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; /* initialized to no-error by default */ + writeAuthorizationCallback.call(params); + return params->authorizationReply; + } + + /** + * Helper function meant to be called from the guts of the BLE stack to + * determine the authorization reply for a read request. + * @param params to capture the context of the read-auth request. + * + * @NOTE: To authorize/deny the read the params->authorizationReply field + * should be set to true/false. + * + * If the read is approved and params->data is unchanged (NULL), + * the current characteristic value will be used. + * + * If the read is approved, a new value can be provided by setting + * the params->data pointer and params->len fields. + * + * @return true if the read is authorized to proceed. + */ + GattAuthCallbackReply_t authorizeRead(GattReadAuthCallbackParams *params) { + if (!isReadAuthorizationEnabled()) { + return AUTH_CALLBACK_REPLY_SUCCESS; + } + + params->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; /* initialized to no-error by default */ + readAuthorizationCallback.call(params); + return params->authorizationReply; + } + + /* accessors */ +public: + GattAttribute& getValueAttribute() {return _valueAttribute; } + const GattAttribute& getValueAttribute() const {return _valueAttribute; } + GattAttribute::Handle_t getValueHandle(void) const {return getValueAttribute().getHandle();} + uint8_t getProperties(void) const {return _properties; } + SecurityManager::SecurityMode_t getRequiredSecurity() const {return _requiredSecurity; } + uint8_t getDescriptorCount(void) const {return _descriptorCount; } + bool isReadAuthorizationEnabled() const {return enabledReadAuthorization; } + bool isWriteAuthorizationEnabled() const {return enabledWriteAuthorization; } + + GattAttribute *getDescriptor(uint8_t index) { + if (index >= _descriptorCount) { + return NULL; + } + + return _descriptors[index]; + } + +private: + GattAttribute _valueAttribute; + uint8_t _properties; + SecurityManager::SecurityMode_t _requiredSecurity; + GattAttribute **_descriptors; + uint8_t _descriptorCount; + + bool enabledReadAuthorization; + bool enabledWriteAuthorization; + FunctionPointerWithContext<GattReadAuthCallbackParams *> readAuthorizationCallback; + FunctionPointerWithContext<GattWriteAuthCallbackParams *> writeAuthorizationCallback; + +private: + /* disallow copy and assignment */ + GattCharacteristic(const GattCharacteristic &); + GattCharacteristic& operator=(const GattCharacteristic &); +}; + +template <typename T> +class ReadOnlyGattCharacteristic : public GattCharacteristic { +public: + ReadOnlyGattCharacteristic<T>(const UUID &uuid, T *valuePtr, uint8_t additionalProperties = BLE_GATT_CHAR_PROPERTIES_NONE) : + GattCharacteristic(uuid, reinterpret_cast<uint8_t *>(valuePtr), sizeof(T), sizeof(T), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | additionalProperties) { + /* empty */ + } +}; + +template <typename T> +class WriteOnlyGattCharacteristic : public GattCharacteristic { +public: + WriteOnlyGattCharacteristic<T>(const UUID &uuid, T *valuePtr, uint8_t additionalProperties = BLE_GATT_CHAR_PROPERTIES_NONE) : + GattCharacteristic(uuid, reinterpret_cast<uint8_t *>(valuePtr), sizeof(T), sizeof(T), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | additionalProperties) { + /* empty */ + } +}; + +template <typename T> +class ReadWriteGattCharacteristic : public GattCharacteristic { +public: + ReadWriteGattCharacteristic<T>(const UUID &uuid, T *valuePtr, uint8_t additionalProperties = BLE_GATT_CHAR_PROPERTIES_NONE) : + GattCharacteristic(uuid, reinterpret_cast<uint8_t *>(valuePtr), sizeof(T), sizeof(T), + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | additionalProperties) { + /* empty */ + } +}; + +template <typename T, unsigned NUM_ELEMENTS> +class WriteOnlyArrayGattCharacteristic : public GattCharacteristic { +public: + WriteOnlyArrayGattCharacteristic<T, NUM_ELEMENTS>(const UUID &uuid, T valuePtr[NUM_ELEMENTS], uint8_t additionalProperties = BLE_GATT_CHAR_PROPERTIES_NONE) : + GattCharacteristic(uuid, reinterpret_cast<uint8_t *>(valuePtr), sizeof(T) * NUM_ELEMENTS, sizeof(T) * NUM_ELEMENTS, + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | additionalProperties) { + /* empty */ + } +}; + +template <typename T, unsigned NUM_ELEMENTS> +class ReadOnlyArrayGattCharacteristic : public GattCharacteristic { +public: + ReadOnlyArrayGattCharacteristic<T, NUM_ELEMENTS>(const UUID &uuid, T valuePtr[NUM_ELEMENTS], uint8_t additionalProperties = BLE_GATT_CHAR_PROPERTIES_NONE) : + GattCharacteristic(uuid, reinterpret_cast<uint8_t *>(valuePtr), sizeof(T) * NUM_ELEMENTS, sizeof(T) * NUM_ELEMENTS, + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | additionalProperties) { + /* empty */ + } +}; + +template <typename T, unsigned NUM_ELEMENTS> +class ReadWriteArrayGattCharacteristic : public GattCharacteristic { +public: + ReadWriteArrayGattCharacteristic<T, NUM_ELEMENTS>(const UUID &uuid, T valuePtr[NUM_ELEMENTS], uint8_t additionalProperties = BLE_GATT_CHAR_PROPERTIES_NONE) : + GattCharacteristic(uuid, reinterpret_cast<uint8_t *>(valuePtr), sizeof(T) * NUM_ELEMENTS, sizeof(T) * NUM_ELEMENTS, + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | additionalProperties) { + /* empty */ + } +}; + +#endif // ifndef __GATT_CHARACTERISTIC_H__ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/GattClient.h Fri Jun 19 15:53:28 2015 +0100 @@ -0,0 +1,229 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GATT_CLIENT_H__ +#define __GATT_CLIENT_H__ + +#include "Gap.h" +#include "GattAttribute.h" +#include "ServiceDiscovery.h" + +#include "GattCallbackParamTypes.h" + +class GattClient { +public: + typedef void (*ReadCallback_t)(const GattReadCallbackParams *params); + + enum WriteOp_t { + GATT_OP_WRITE_REQ = 0x01, /**< Write Request. */ + GATT_OP_WRITE_CMD = 0x02, /**< Write Command. */ + }; + + typedef void (*WriteCallback_t)(const GattWriteCallbackParams *params); + + /* + * The following functions are meant to be overridden in the platform-specific sub-class. + */ +public: + /** + * Launch service discovery. Once launched, service discovery will remain + * active with callbacks being issued back into the application for matching + * services/characteristics. isServiceDiscoveryActive() can be used to + * determine status; and a termination callback (if setup) will be invoked + * at the end. Service discovery can be terminated prematurely if needed + * using terminateServiceDiscovery(). + * + * @param connectionHandle + * Handle for the connection with the peer. + * @param sc + * This is the application callback for matching service. Taken as + * NULL by default. Note: service discovery may still be active + * when this callback is issued; calling asynchronous BLE-stack + * APIs from within this application callback might cause the + * stack to abort service discovery. If this becomes an issue, it + * may be better to make local copy of the discoveredService and + * wait for service discovery to terminate before operating on the + * service. + * @param cc + * This is the application callback for matching characteristic. + * Taken as NULL by default. Note: service discovery may still be + * active when this callback is issued; calling asynchronous + * BLE-stack APIs from within this application callback might cause + * the stack to abort service discovery. If this becomes an issue, + * it may be better to make local copy of the discoveredCharacteristic + * and wait for service discovery to terminate before operating on the + * characteristic. + * @param matchingServiceUUID + * UUID based filter for specifying a service in which the application is + * interested. By default it is set as the wildcard UUID_UNKNOWN, + * in which case it matches all services. If characteristic-UUID + * filter (below) is set to the wildcard value, then a service + * callback will be invoked for the matching service (or for every + * service if the service filter is a wildcard). + * @param matchingCharacteristicUUIDIn + * UUID based filter for specifying characteristic in which the application + * is interested. By default it is set as the wildcard UUID_UKNOWN + * to match against any characteristic. If both service-UUID + * filter and characteristic-UUID filter are used with non- wildcard + * values, then only a single characteristic callback is + * invoked for the matching characteristic. + * + * @note Using wildcard values for both service-UUID and characteristic- + * UUID will result in complete service discovery--callbacks being + * called for every service and characteristic. + * + * @note Providing NULL for the characteristic callback will result in + * characteristic discovery being skipped for each matching + * service. This allows for an inexpensive method to discover only + * services. + * + * @return + * BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error. + */ + virtual ble_error_t launchServiceDiscovery(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc = NULL, + ServiceDiscovery::CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + } + + /** + * Launch service discovery for services. Once launched, service discovery will remain + * active with service-callbacks being issued back into the application for matching + * services. isServiceDiscoveryActive() can be used to + * determine status; and a termination callback (if setup) will be invoked + * at the end. Service discovery can be terminated prematurely if needed + * using terminateServiceDiscovery(). + * + * @param connectionHandle + * Handle for the connection with the peer. + * @param sc + * This is the application callback for matching service. Note: service discovery may still be active + * when this callback is issued; calling asynchronous BLE-stack + * APIs from within this application callback might cause the + * stack to abort service discovery. If this becomes an issue, it + * may be better to make local copy of the discoveredService and + * wait for service discovery to terminate before operating on the + * service. + * @param matchingServiceUUID + * UUID based filter for specifying a service in which the application is + * interested. By default it is set as the wildcard UUID_UNKNOWN, + * in which case it matches all services. + * + * @return + * BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error. + */ + virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + } + + /** + * Launch service discovery for services. Once launched, service discovery will remain + * active with service-callbacks being issued back into the application for matching + * services. isServiceDiscoveryActive() can be used to + * determine status; and a termination callback (if setup) will be invoked + * at the end. Service discovery can be terminated prematurely if needed + * using terminateServiceDiscovery(). + * + * @param connectionHandle + * Handle for the connection with the peer. + * @param sc + * This is the application callback for matching service. Note: service discovery may still be active + * when this callback is issued; calling asynchronous BLE-stack + * APIs from within this application callback might cause the + * stack to abort service discovery. If this becomes an issue, it + * may be better to make local copy of the discoveredService and + * wait for service discovery to terminate before operating on the + * service. + * @param startHandle, endHandle + * Handle range within which to limit the search + * + * @return + * BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error. + */ + virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle) { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + } + + /** + * Is service-discovery currently active? + */ + virtual bool isServiceDiscoveryActive(void) const { + return false; /* default implementation; override this API if this capability is supported. */ + } + + /** + * Terminate an ongoing service-discovery. This should result in an + * invocation of the TerminationCallback if service-discovery is active. + */ + virtual void terminateServiceDiscovery(void) { + /* default implementation; override this API if this capability is supported. */ + } + + /* Initiate a Gatt Client read procedure by attribute-handle. */ + virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + } + + /** + * Initiate a GATT Client write procedure. + * + * @param[in] cmd + * Command can be either a write-request (which generates a + * matching response from the peripheral), or a write-command, + * which doesn't require the connected peer to respond. + * @param[in] connHandle + * Connection handle. + * @param[in] attributeHandle + * handle for the target attribtue on the remote GATT server. + * @param[in] length + * length of the new value. + * @param[in] value + * new value being written. + */ + virtual ble_error_t write(GattClient::WriteOp_t cmd, + Gap::Handle_t connHandle, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value) const { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + } + + /** + * Setup callback for when serviceDiscovery terminates. + */ + virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { + /* default implementation; override this API if this capability is supported. */ + } + +protected: + GattClient() { + /* empty */ + } + +private: + /* disallow copy and assignment */ + GattClient(const GattClient &); + GattClient& operator=(const GattClient &); +}; + +#endif // ifndef __GATT_CLIENT_H__ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/GattServer.h Fri Jun 19 15:53:28 2015 +0100 @@ -0,0 +1,316 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GATT_SERVER_H__ +#define __GATT_SERVER_H__ + +#include "Gap.h" +#include "GattService.h" +#include "GattAttribute.h" +#include "GattServerEvents.h" +#include "GattCallbackParamTypes.h" +#include "CallChainOfFunctionPointersWithContext.h" + +class GattServer { +public: + /* Event callback handlers. */ + typedef void (*EventCallback_t)(GattAttribute::Handle_t attributeHandle); + typedef void (*ServerEventCallback_t)(void); /**< independent of any particular attribute */ + +protected: + GattServer() : + serviceCount(0), + characteristicCount(0), + dataSentCallChain(), + dataWrittenCallChain(), + dataReadCallChain(), + updatesEnabledCallback(NULL), + updatesDisabledCallback(NULL), + confirmationReceivedCallback(NULL) { + /* empty */ + } + + /* + * The following functions are meant to be overridden in the platform-specific sub-class. + */ +public: + + /** + * Add a service declaration to the local server ATT table. Also add the + * characteristics contained within. + */ + virtual ble_error_t addService(GattService &) { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + } + + /** + * Read the value of a characteristic from the local GattServer + * @param[in] attributeHandle + * Attribute handle for the value attribute of the characteristic. + * @param[out] buffer + * A buffer to hold the value being read. + * @param[in/out] lengthP + * Length of the buffer being supplied. If the attribute + * value is longer than the size of the supplied buffer, + * this variable will hold upon return the total attribute value length + * (excluding offset). The application may use this + * information to allocate a suitable buffer size. + * + * @return BLE_ERROR_NONE if a value was read successfully into the buffer. + */ + virtual ble_error_t read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + } + + /** + * Read the value of a characteristic from the local GattServer + * @param[in] connectionHandle + * Connection Handle. + * @param[in] attributeHandle + * Attribute handle for the value attribute of the characteristic. + * @param[out] buffer + * A buffer to hold the value being read. + * @param[in/out] lengthP + * Length of the buffer being supplied. If the attribute + * value is longer than the size of the supplied buffer, + * this variable will hold upon return the total attribute value length + * (excluding offset). The application may use this + * information to allocate a suitable buffer size. + * + * @return BLE_ERROR_NONE if a value was read successfully into the buffer. + * + * @note This API is a version of above with an additional connection handle + * parameter to allow fetches for connection-specific multivalued + * attribtues (such as the CCCDs). + */ + virtual ble_error_t read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP) { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + } + + /** + * Update the value of a characteristic on the local GattServer. + * + * @param[in] attributeHandle + * Handle for the value attribute of the Characteristic. + * @param[in] value + * A pointer to a buffer holding the new value + * @param[in] size + * Size of the new value (in bytes). + * @param[in] localOnly + * Should this update be kept on the local + * GattServer regardless of the state of the + * notify/indicate flag in the CCCD for this + * Characteristic? If set to true, no notification + * or indication is generated. + * + * @return BLE_ERROR_NONE if we have successfully set the value of the attribute. + */ + virtual ble_error_t write(GattAttribute::Handle_t, const uint8_t *, uint16_t, bool localOnly = false) { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + } + + /** + * Update the value of a characteristic on the local GattServer. A version + * of the same as above with connection handle parameter to allow updates + * for connection-specific multivalued attribtues (such as the CCCDs). + * + * @param[in] connectionHandle + * Connection Handle. + * @param[in] attributeHandle + * Handle for the value attribute of the Characteristic. + * @param[in] value + * A pointer to a buffer holding the new value + * @param[in] size + * Size of the new value (in bytes). + * @param[in] localOnly + * Should this update be kept on the local + * GattServer regardless of the state of the + * notify/indicate flag in the CCCD for this + * Characteristic? If set to true, no notification + * or indication is generated. + * + * @return BLE_ERROR_NONE if we have successfully set the value of the attribute. + */ + virtual ble_error_t write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t, const uint8_t *, uint16_t, bool localOnly = false) { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + } + + /** + * A virtual function to allow underlying stacks to indicate if they support + * onDataRead(). It should be overridden to return true as applicable. + */ + virtual bool isOnDataReadAvailable() const { + return false; /* default implementation; override this API if this capability is supported. */ + } + + /* + * APIs with non-virtual implementations. + */ +public: + /** + * Add a callback for the GATT event DATA_SENT (which is triggered when + * updates are sent out by GATT in the form of notifications). + * + * @Note: it is possible to chain together multiple onDataSent callbacks + * (potentially from different modules of an application) to receive updates + * to characteristics. + * + * @Note: it is also possible to setup a callback into a member function of + * some object. + */ + void onDataSent(void (*callback)(unsigned count)) {dataSentCallChain.add(callback);} + template <typename T> + void onDataSent(T *objPtr, void (T::*memberPtr)(unsigned count)) { + dataSentCallChain.add(objPtr, memberPtr); + } + + /** + * Setup a callback for when an attribute has its value updated by or at the + * connected peer. For a peripheral, this callback triggered when the local + * GATT server has an attribute updated by a write command from the peer. + * For a Central, this callback is triggered when a response is received for + * a write request. + * + * @Note: it is possible to chain together multiple onDataWritten callbacks + * (potentially from different modules of an application) to receive updates + * to characteristics. Many services, such as DFU and UART add their own + * onDataWritten callbacks behind the scenes to trap interesting events. + * + * @Note: it is also possible to setup a callback into a member function of + * some object. + */ + void onDataWritten(void (*callback)(const GattWriteCallbackParams *eventDataP)) {dataWrittenCallChain.add(callback);} + template <typename T> + void onDataWritten(T *objPtr, void (T::*memberPtr)(const GattWriteCallbackParams *context)) { + dataWrittenCallChain.add(objPtr, memberPtr); + } + + /** + * Setup a callback to be invoked on the peripheral when an attribute is + * being read by a remote client. + * + * @Note: this functionality may not be available on all underlying stacks. + * You could use GattCharacteristic::setReadAuthorizationCallback() as an + * alternative. + * + * @Note: it is possible to chain together multiple onDataRead callbacks + * (potentially from different modules of an application) to receive updates + * to characteristics. Services may add their own onDataRead callbacks + * behind the scenes to trap interesting events. + * + * @Note: it is also possible to setup a callback into a member function of + * some object. + * + * @return BLE_ERROR_NOT_IMPLEMENTED if this functionality isn't available; + * else BLE_ERROR_NONE. + */ + ble_error_t onDataRead(void (*callback)(const GattReadCallbackParams *eventDataP)) { + if (!isOnDataReadAvailable()) { + return BLE_ERROR_NOT_IMPLEMENTED; + } + + dataReadCallChain.add(callback); + return BLE_ERROR_NONE; + } + template <typename T> + ble_error_t onDataRead(T *objPtr, void (T::*memberPtr)(const GattReadCallbackParams *context)) { + if (!isOnDataReadAvailable()) { + return BLE_ERROR_NOT_IMPLEMENTED; + } + + dataReadCallChain.add(objPtr, memberPtr); + return BLE_ERROR_NONE; + } + + /** + * Setup a callback for when notifications/indications are enabled for a + * characteristic on the local GattServer. + */ + void onUpdatesEnabled(EventCallback_t callback) {updatesEnabledCallback = callback;} + + /** + * Setup a callback for when notifications/indications are disabled for a + * characteristic on the local GattServer. + */ + void onUpdatesDisabled(EventCallback_t callback) {updatesDisabledCallback = callback;} + + /** + * Setup a callback for when the GATT server receives a response for an + * indication event sent previously. + */ + void onConfirmationReceived(EventCallback_t callback) {confirmationReceivedCallback = callback;} + + /* Entry points for the underlying stack to report events back to the user. */ +protected: + void handleDataWrittenEvent(const GattWriteCallbackParams *params) { + if (dataWrittenCallChain.hasCallbacksAttached()) { + dataWrittenCallChain.call(params); + } + } + + void handleDataReadEvent(const GattReadCallbackParams *params) { + if (dataReadCallChain.hasCallbacksAttached()) { + dataReadCallChain.call(params); + } + } + + void handleEvent(GattServerEvents::gattEvent_e type, GattAttribute::Handle_t charHandle) { + switch (type) { + case GattServerEvents::GATT_EVENT_UPDATES_ENABLED: + if (updatesEnabledCallback) { + updatesEnabledCallback(charHandle); + } + break; + case GattServerEvents::GATT_EVENT_UPDATES_DISABLED: + if (updatesDisabledCallback) { + updatesDisabledCallback(charHandle); + } + break; + case GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED: + if (confirmationReceivedCallback) { + confirmationReceivedCallback(charHandle); + } + break; + default: + break; + } + } + + void handleDataSentEvent(unsigned count) { + if (dataSentCallChain.hasCallbacksAttached()) { + dataSentCallChain.call(count); + } + } + +protected: + uint8_t serviceCount; + uint8_t characteristicCount; + +private: + CallChainOfFunctionPointersWithContext<unsigned> dataSentCallChain; + CallChainOfFunctionPointersWithContext<const GattWriteCallbackParams *> dataWrittenCallChain; + CallChainOfFunctionPointersWithContext<const GattReadCallbackParams *> dataReadCallChain; + EventCallback_t updatesEnabledCallback; + EventCallback_t updatesDisabledCallback; + EventCallback_t confirmationReceivedCallback; + +private: + /* disallow copy and assignment */ + GattServer(const GattServer &); + GattServer& operator=(const GattServer &); +}; + +#endif // ifndef __GATT_SERVER_H__ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/GattServerEvents.h Fri Jun 19 15:53:28 2015 +0100 @@ -0,0 +1,39 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GATT_SERVER_EVENTS_H__ +#define __GATT_SERVER_EVENTS_H__ + +/*! + \brief + The base class used to abstract away the callback events that can be + triggered with the GATT Server. +*/ +class GattServerEvents +{ +public: + typedef enum gattEvent_e { + GATT_EVENT_DATA_SENT = 1, /**< Fired when a msg was successfully sent out (notify only?) */ + GATT_EVENT_DATA_WRITTEN = 2, /**< Client wrote data to Server (separate into char and descriptor writes?) */ + GATT_EVENT_UPDATES_ENABLED = 3, /**< Notify/Indicate Enabled in CCCD */ + GATT_EVENT_UPDATES_DISABLED = 4, /**< Notify/Indicate Disabled in CCCD */ + GATT_EVENT_CONFIRMATION_RECEIVED = 5, /**< Response received from Indicate message */ + GATT_EVENT_READ_AUTHORIZATION_REQ = 6, /**< Request application to authorize read */ + GATT_EVENT_WRITE_AUTHORIZATION_REQ = 7, /**< Request application to authorize write */ + } gattEvent_t; +}; + +#endif // ifndef __GATT_SERVER_EVENTS_H__ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/GattService.h Fri Jun 19 15:53:28 2015 +0100 @@ -0,0 +1,85 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#ifndef __GATT_SERVICE_H__ +#define __GATT_SERVICE_H__ + +#include "UUID.h" +#include "GattCharacteristic.h" + +class GattService { +public: + enum { + UUID_ALERT_NOTIFICATION_SERVICE = 0x1811, + UUID_BATTERY_SERVICE = 0x180F, + UUID_BLOOD_PRESSURE_SERVICE = 0x1810, + UUID_CURRENT_TIME_SERVICE = 0x1805, + UUID_CYCLING_SPEED_AND_CADENCE = 0x1816, + UUID_DEVICE_INFORMATION_SERVICE = 0x180A, + UUID_GLUCOSE_SERVICE = 0x1808, + UUID_HEALTH_THERMOMETER_SERVICE = 0x1809, + UUID_HEART_RATE_SERVICE = 0x180D, + UUID_HUMAN_INTERFACE_DEVICE_SERVICE = 0x1812, + UUID_IMMEDIATE_ALERT_SERVICE = 0x1802, + UUID_LINK_LOSS_SERVICE = 0x1803, + UUID_NEXT_DST_CHANGE_SERVICE = 0x1807, + UUID_PHONE_ALERT_STATUS_SERVICE = 0x180E, + UUID_REFERENCE_TIME_UPDATE_SERVICE = 0x1806, + UUID_RUNNING_SPEED_AND_CADENCE = 0x1814, + UUID_SCAN_PARAMETERS_SERVICE = 0x1813, + UUID_TX_POWER_SERVICE = 0x1804 + }; + +public: + /** + * @brief Creates a new GattCharacteristic using the specified 16-bit + * UUID, value length, and properties + * + * @note The UUID value must be unique in the service and is normally >1 + * + * @param[in] uuid + * The UUID to use for this characteristic + * @param[in] characteristics + * A pointer to an array of characteristics to be included within this service + * @param[in] numCharacteristics + * The number of characteristics + */ + GattService(const UUID &uuid, GattCharacteristic *characteristics[], unsigned numCharacteristics) : + _primaryServiceID(uuid), _characteristicCount(numCharacteristics), _characteristics(characteristics), _handle(0) { + /* empty */ + } + + const UUID &getUUID(void) const {return _primaryServiceID; } + uint16_t getHandle(void) const {return _handle; } + uint8_t getCharacteristicCount(void) const {return _characteristicCount;} + void setHandle(uint16_t handle) {_handle = handle;} + + GattCharacteristic *getCharacteristic(uint8_t index) { + if (index >= _characteristicCount) { + return NULL; + } + + return _characteristics[index]; + } + +private: + UUID _primaryServiceID; + uint8_t _characteristicCount; + GattCharacteristic **_characteristics; + uint16_t _handle; +}; + +#endif // ifndef __GATT_SERVICE_H__ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/SecurityManager.h Fri Jun 19 15:53:28 2015 +0100 @@ -0,0 +1,215 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __SECURITY_MANAGER_H__ +#define __SECURITY_MANAGER_H__ + +#include <stdint.h> + +#include "Gap.h" + +class SecurityManager { +public: + enum SecurityMode_t { + SECURITY_MODE_NO_ACCESS, + SECURITY_MODE_ENCRYPTION_OPEN_LINK, /**< require no protection, open link. */ + SECURITY_MODE_ENCRYPTION_NO_MITM, /**< require encryption, but no MITM protection. */ + SECURITY_MODE_ENCRYPTION_WITH_MITM, /**< require encryption and MITM protection. */ + SECURITY_MODE_SIGNED_NO_MITM, /**< require signing or encryption, but no MITM protection. */ + SECURITY_MODE_SIGNED_WITH_MITM, /**< require signing or encryption, and MITM protection. */ + }; + + /** + * @brief Defines possible security status/states. + * + * @details Defines possible security status/states of a link when requested by getLinkSecurity(). + */ + enum LinkSecurityStatus_t { + NOT_ENCRYPTED, /**< The link is not secured. */ + ENCRYPTION_IN_PROGRESS, /**< Link security is being established.*/ + ENCRYPTED /**< The link is secure.*/ + }; + + enum SecurityIOCapabilities_t { + IO_CAPS_DISPLAY_ONLY = 0x00, /**< Display Only. */ + IO_CAPS_DISPLAY_YESNO = 0x01, /**< Display and Yes/No entry. */ + IO_CAPS_KEYBOARD_ONLY = 0x02, /**< Keyboard Only. */ + IO_CAPS_NONE = 0x03, /**< No I/O capabilities. */ + IO_CAPS_KEYBOARD_DISPLAY = 0x04, /**< Keyboard and Display. */ + }; + + enum SecurityCompletionStatus_t { + SEC_STATUS_SUCCESS = 0x00, /**< Procedure completed with success. */ + SEC_STATUS_TIMEOUT = 0x01, /**< Procedure timed out. */ + SEC_STATUS_PDU_INVALID = 0x02, /**< Invalid PDU received. */ + SEC_STATUS_PASSKEY_ENTRY_FAILED = 0x81, /**< Passkey entry failed (user canceled or other). */ + SEC_STATUS_OOB_NOT_AVAILABLE = 0x82, /**< Out of Band Key not available. */ + SEC_STATUS_AUTH_REQ = 0x83, /**< Authentication requirements not met. */ + SEC_STATUS_CONFIRM_VALUE = 0x84, /**< Confirm value failed. */ + SEC_STATUS_PAIRING_NOT_SUPP = 0x85, /**< Pairing not supported. */ + SEC_STATUS_ENC_KEY_SIZE = 0x86, /**< Encryption key size. */ + SEC_STATUS_SMP_CMD_UNSUPPORTED = 0x87, /**< Unsupported SMP command. */ + SEC_STATUS_UNSPECIFIED = 0x88, /**< Unspecified reason. */ + SEC_STATUS_REPEATED_ATTEMPTS = 0x89, /**< Too little time elapsed since last attempt. */ + SEC_STATUS_INVALID_PARAMS = 0x8A, /**< Invalid parameters. */ + }; + + /** + * Declaration of type containing a passkey to be used during pairing. This + * is passed into initializeSecurity() to specify a pre-programmed passkey + * for authentication instead of generating a random one. + */ + static const unsigned PASSKEY_LEN = 6; + typedef uint8_t Passkey_t[PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */ + +public: + typedef void (*HandleSpecificEvent_t)(Gap::Handle_t handle); + typedef void (*SecuritySetupInitiatedCallback_t)(Gap::Handle_t, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps); + typedef void (*SecuritySetupCompletedCallback_t)(Gap::Handle_t, SecurityCompletionStatus_t status); + typedef void (*LinkSecuredCallback_t)(Gap::Handle_t handle, SecurityMode_t securityMode); + typedef void (*PasskeyDisplayCallback_t)(Gap::Handle_t handle, const Passkey_t passkey); + + /* + * The following functions are meant to be overridden in the platform-specific sub-class. + */ +public: + /** + * Enable the BLE stack's Security Manager. The Security Manager implements + * the actual cryptographic algorithms and protocol exchanges that allow two + * devices to securely exchange data and privately detect each other. + * Calling this API is a prerequisite for encryption and pairing (bonding). + * + * @param[in] enableBonding Allow for bonding. + * @param[in] requireMITM Require protection for man-in-the-middle attacks. + * @param[in] iocaps To specify IO capabilities of this peripheral, + * such as availability of a display or keyboard to + * support out-of-band exchanges of security data. + * @param[in] passkey To specify a static passkey. + * + * @return BLE_ERROR_NONE on success. + */ + virtual ble_error_t init(bool enableBonding = true, + bool requireMITM = true, + SecurityIOCapabilities_t iocaps = IO_CAPS_NONE, + const Passkey_t passkey = NULL) { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this if security is supported. */ + } + + /** + * Get the security status of a connection. + * + * @param[in] connectionHandle Handle to identify the connection. + * @param[out] securityStatusP security status. + * + * @return BLE_SUCCESS Or appropriate error code indicating reason for failure. + */ + virtual ble_error_t getLinkSecurity(Gap::Handle_t connectionHandle, LinkSecurityStatus_t *securityStatusP) { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this if security is supported. */ + } + + /** + * Delete all peer device context and all related bonding information from + * the database within the security manager. + * + * @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure. + * @retval BLE_ERROR_INVALID_STATE If the API is called without module initialization and/or + * application registration. + */ + virtual ble_error_t purgeAllBondingState(void) { + return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this if security is supported. */ + } + + /* Event callback handlers. */ +public: + /** + * To indicate that security procedure for link has started. + */ + virtual void onSecuritySetupInitiated(SecuritySetupInitiatedCallback_t callback) {securitySetupInitiatedCallback = callback;} + + /** + * To indicate that security procedure for link has completed. + */ + virtual void onSecuritySetupCompleted(SecuritySetupCompletedCallback_t callback) {securitySetupCompletedCallback = callback;} + + /** + * To indicate that link with the peer is secured. For bonded devices, + * subsequent re-connections with bonded peer will result only in this callback + * when the link is secured and setup procedures will not occur unless the + * bonding information is either lost or deleted on either or both sides. + */ + virtual void onLinkSecured(LinkSecuredCallback_t callback) {linkSecuredCallback = callback;} + + /** + * To indicate that device context is stored persistently. + */ + virtual void onSecurityContextStored(HandleSpecificEvent_t callback) {securityContextStoredCallback = callback;} + + /** + * To set the callback for when the passkey needs to be displayed on a peripheral with DISPLAY capability. + */ + virtual void onPasskeyDisplay(PasskeyDisplayCallback_t callback) {passkeyDisplayCallback = callback;} + + /* Entry points for the underlying stack to report events back to the user. */ +public: + void processSecuritySetupInitiatedEvent(Gap::Handle_t handle, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps) { + if (securitySetupInitiatedCallback) { + securitySetupInitiatedCallback(handle, allowBonding, requireMITM, iocaps); + } + } + + void processSecuritySetupCompletedEvent(Gap::Handle_t handle, SecurityCompletionStatus_t status) { + if (securitySetupCompletedCallback) { + securitySetupCompletedCallback(handle, status); + } + } + + void processLinkSecuredEvent(Gap::Handle_t handle, SecurityMode_t securityMode) { + if (linkSecuredCallback) { + linkSecuredCallback(handle, securityMode); + } + } + + void processSecurityContextStoredEvent(Gap::Handle_t handle) { + if (securityContextStoredCallback) { + securityContextStoredCallback(handle); + } + } + + void processPasskeyDisplayEvent(Gap::Handle_t handle, const Passkey_t passkey) { + if (passkeyDisplayCallback) { + passkeyDisplayCallback(handle, passkey); + } + } + +protected: + SecurityManager() : + securitySetupInitiatedCallback(), + securitySetupCompletedCallback(), + linkSecuredCallback(), + securityContextStoredCallback(), + passkeyDisplayCallback() { + /* empty */ + } + +protected: + SecuritySetupInitiatedCallback_t securitySetupInitiatedCallback; + SecuritySetupCompletedCallback_t securitySetupCompletedCallback; + LinkSecuredCallback_t linkSecuredCallback; + HandleSpecificEvent_t securityContextStoredCallback; + PasskeyDisplayCallback_t passkeyDisplayCallback; +}; + +#endif /*__SECURITY_MANAGER_H__*/ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/ServiceDiscovery.h Fri Jun 19 15:53:28 2015 +0100 @@ -0,0 +1,143 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __SERVICE_DISOVERY_H__ +#define __SERVICE_DISOVERY_H__ + +#include "UUID.h" +#include "Gap.h" +#include "GattAttribute.h" + +class DiscoveredService; +class DiscoveredCharacteristic; + +class ServiceDiscovery { +public: + /* + * Exposed application callback types. + */ + + /** + * Callback type for when a matching Service is found during service- + * discovery. The receiving function is passed in a pointer to a + * DiscoveredService object which will remain valid for the lifetime of the + * callback. Memory for this object is owned by the BLE_API eventing + * framework. The application can safely make a persistent shallow-copy of + * this object in order to work with the service beyond the callback. + */ + typedef void (*ServiceCallback_t)(const DiscoveredService *); + + /** + * Callback type for when a matching Characteristic is found during service- + * discovery. The receiving function is passed in a pointer to a + * DiscoveredCharacteristic object which will remain valid for the lifetime + * of the callback. Memory for this object is owned by the BLE_API eventing + * framework. The application can safely make a persistent shallow-copy of + * this object in order to work with the characteristic beyond the callback. + */ + typedef void (*CharacteristicCallback_t)(const DiscoveredCharacteristic *); + + /** + * Callback type for when serviceDiscovery terminates. + */ + typedef void (*TerminationCallback_t)(Gap::Handle_t connectionHandle); + +public: + /** + * Launch service discovery. Once launched, service discovery will remain + * active with callbacks being issued back into the application for matching + * services/characteristics. isActive() can be used to determine status; and + * a termination callback (if setup) will be invoked at the end. Service + * discovery can be terminated prematurely if needed using terminate(). + * + * @param connectionHandle + * Handle for the connection with the peer. + * @param sc + * This is the application callback for matching service. Taken as + * NULL by default. Note: service discovery may still be active + * when this callback is issued; calling asynchronous BLE-stack + * APIs from within this application callback might cause the + * stack to abort service discovery. If this becomes an issue, it + * may be better to make local copy of the discoveredService and + * wait for service discovery to terminate before operating on the + * service. + * @param cc + * This is the application callback for matching characteristic. + * Taken as NULL by default. Note: service discovery may still be + * active when this callback is issued; calling asynchronous + * BLE-stack APIs from within this application callback might cause + * the stack to abort service discovery. If this becomes an issue, + * it may be better to make local copy of the discoveredCharacteristic + * and wait for service discovery to terminate before operating on the + * characteristic. + * @param matchingServiceUUID + * UUID based filter for specifying a service in which the application is + * interested. By default it is set as the wildcard UUID_UNKNOWN, + * in which case it matches all services. If characteristic-UUID + * filter (below) is set to the wildcard value, then a service + * callback will be invoked for the matching service (or for every + * service if the service filter is a wildcard). + * @param matchingCharacteristicUUIDIn + * UUID based filter for specifying characteristic in which the application + * is interested. By default it is set as the wildcard UUID_UKNOWN + * to match against any characteristic. If both service-UUID + * filter and characteristic-UUID filter are used with non- wildcard + * values, then only a single characteristic callback is + * invoked for the matching characteristic. + * + * @note Using wildcard values for both service-UUID and characteristic- + * UUID will result in complete service discovery--callbacks being + * called for every service and characteristic. + * + * @note Providing NULL for the characteristic callback will result in + * characteristic discovery being skipped for each matching + * service. This allows for an inexpensive method to discover only + * services. + * + * @return + * BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error. + */ + virtual ble_error_t launch(Gap::Handle_t connectionHandle, + ServiceCallback_t sc = NULL, + CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) = 0; + + /** + * Is service-discovery currently active? + */ + virtual bool isActive(void) const = 0; + + /** + * Terminate an ongoing service-discovery. This should result in an + * invocation of the TerminationCallback if service-discovery is active. + */ + virtual void terminate(void) = 0; + + /** + * Setup callback to be invoked when service discovery is terminated. + */ + virtual void onTermination(TerminationCallback_t callback) = 0; + +protected: + Gap::Handle_t connHandle; /**< Connection handle as provided by the SoftDevice. */ + UUID matchingServiceUUID; + ServiceCallback_t serviceCallback; + UUID matchingCharacteristicUUID; + CharacteristicCallback_t characteristicCallback; +}; + +#endif // ifndef __SERVICE_DISOVERY_H__ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/UUID.h Fri Jun 19 15:53:28 2015 +0100 @@ -0,0 +1,143 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UUID_H__ +#define __UUID_H__ + +#include <stdint.h> +#include <string.h> + +#include "blecommon.h" + +class UUID { +public: + enum UUID_Type_t { + UUID_TYPE_SHORT = 0, // Short BLE UUID + UUID_TYPE_LONG = 1 // Full 128-bit UUID + }; + + typedef uint16_t ShortUUIDBytes_t; + + static const unsigned LENGTH_OF_LONG_UUID = 16; + typedef uint8_t LongUUIDBytes_t[LENGTH_OF_LONG_UUID]; + +public: + /** + * Creates a new 128-bit UUID + * + * @note The UUID is a unique 128-bit (16 byte) ID used to identify + * different service or characteristics on the BLE device. + * + * @param longUUID + * The 128-bit (16-byte) UUID value, MSB first (big-endian). + */ + UUID(const LongUUIDBytes_t longUUID) : type(UUID_TYPE_LONG), baseUUID(), shortUUID(0) { + setupLong(longUUID); + } + + /** + * Creates a new 16-bit UUID + * + * @note The UUID is a unique 16-bit (2 byte) ID used to identify + * different service or characteristics on the BLE device. + * + * For efficiency, and because 16 bytes would take a large chunk of the + * 27-byte data payload length of the Link Layer, the BLE specification adds + * two additional UUID formats: 16-bit and 32-bit UUIDs. These shortened + * formats can be used only with UUIDs that are defined in the Bluetooth + * specification (i.e., that are listed by the Bluetooth SIG as standard + * Bluetooth UUIDs). + * + * To reconstruct the full 128-bit UUID from the shortened version, insert + * the 16-bit short value (indicated by xxxx, including leading zeros) into + * the Bluetooth Base UUID: + * + * 0000xxxx-0000-1000-8000-00805F9B34FB + * + * @note Shortening is not available for UUIDs that are not derived from the + * Bluetooth Base UUID. Such non-standard UUIDs are commonly called + * vendor-specific UUIDs. In these cases, you’ll need to use the full + * 128-bit UUID value at all times. + * + * @note we don't yet support 32-bit shortened UUIDs. + */ + UUID(ShortUUIDBytes_t shortUUID) : type(UUID_TYPE_SHORT), baseUUID(), shortUUID(shortUUID) { + /* empty */ + } + + UUID(const UUID &source) { + type = source.type; + shortUUID = source.shortUUID; + memcpy(baseUUID, source.baseUUID, LENGTH_OF_LONG_UUID); + } + + UUID(void) : type(UUID_TYPE_SHORT), shortUUID(BLE_UUID_UNKNOWN) { + /* empty */ + } + + /** + * Fill in a 128-bit UUID; this is useful when UUID isn't known at the time of object construction. + */ + void setupLong(const LongUUIDBytes_t longUUID) { + type = UUID_TYPE_LONG; + memcpy(baseUUID, longUUID, LENGTH_OF_LONG_UUID); + shortUUID = (uint16_t)((longUUID[2] << 8) | (longUUID[3])); + } + +public: + UUID_Type_t shortOrLong(void) const {return type; } + const uint8_t *getBaseUUID(void) const { + if (type == UUID_TYPE_SHORT) { + return (const uint8_t*)&shortUUID; + } else { + return baseUUID; + } + } + + ShortUUIDBytes_t getShortUUID(void) const {return shortUUID;} + uint8_t getLen(void) const { + return ((type == UUID_TYPE_SHORT) ? sizeof(ShortUUIDBytes_t) : LENGTH_OF_LONG_UUID); + } + + bool operator== (const UUID &other) const { + if ((this->type == UUID_TYPE_SHORT) && (other.type == UUID_TYPE_SHORT) && + (this->shortUUID == other.shortUUID)) { + return true; + } + + if ((this->type == UUID_TYPE_LONG) && (other.type == UUID_TYPE_LONG) && + (memcmp(this->baseUUID, other.baseUUID, LENGTH_OF_LONG_UUID) == 0)) { + return true; + } + + return false; + } + + bool operator!= (const UUID &other) const { + return !(*this == other); + } + +private: + UUID_Type_t type; // UUID_TYPE_SHORT or UUID_TYPE_LONG + LongUUIDBytes_t baseUUID; /* the base of the long UUID (if + * used). Note: bytes 12 and 13 (counting from LSB) + * are zeroed out to allow comparison with other long + * UUIDs which differ only in the 16-bit relative + * part.*/ + ShortUUIDBytes_t shortUUID; // 16 bit uuid (byte 2-3 using with base) +}; + +#endif // ifndef __UUID_H__ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/blecommon.h Fri Jun 19 15:53:28 2015 +0100 @@ -0,0 +1,133 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BLE_COMMON_H__ +#define __BLE_COMMON_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @defgroup BLE_UUID_VALUES Assigned Values for BLE UUIDs + * @{ */ +/* Generic UUIDs, applicable to all services */ +enum { + BLE_UUID_UNKNOWN = 0x0000, /**< Reserved UUID. */ + BLE_UUID_SERVICE_PRIMARY = 0x2800, /**< Primary Service. */ + BLE_UUID_SERVICE_SECONDARY = 0x2801, /**< Secondary Service. */ + BLE_UUID_SERVICE_INCLUDE = 0x2802, /**< Include. */ + BLE_UUID_CHARACTERISTIC = 0x2803, /**< Characteristic. */ + BLE_UUID_DESCRIPTOR_CHAR_EXT_PROP = 0x2900, /**< Characteristic Extended Properties Descriptor. */ + BLE_UUID_DESCRIPTOR_CHAR_USER_DESC = 0x2901, /**< Characteristic User Description Descriptor. */ + BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG = 0x2902, /**< Client Characteristic Configuration Descriptor. */ + BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG = 0x2903, /**< Server Characteristic Configuration Descriptor. */ + BLE_UUID_DESCRIPTOR_CHAR_PRESENTATION_FORMAT = 0x2904, /**< Characteristic Presentation Format Descriptor. */ + BLE_UUID_DESCRIPTOR_CHAR_AGGREGATE_FORMAT = 0x2905, /**< Characteristic Aggregate Format Descriptor. */ + +/* GATT specific UUIDs */ + BLE_UUID_GATT = 0x1801, /**< Generic Attribute Profile. */ + BLE_UUID_GATT_CHARACTERISTIC_SERVICE_CHANGED = 0x2A05, /**< Service Changed Characteristic. */ + +/* GAP specific UUIDs */ + BLE_UUID_GAP = 0x1800, /**< Generic Access Profile. */ + BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME = 0x2A00, /**< Device Name Characteristic. */ + BLE_UUID_GAP_CHARACTERISTIC_APPEARANCE = 0x2A01, /**< Appearance Characteristic. */ + BLE_UUID_GAP_CHARACTERISTIC_PPF = 0x2A02, /**< Peripheral Privacy Flag Characteristic. */ + BLE_UUID_GAP_CHARACTERISTIC_RECONN_ADDR = 0x2A03, /**< Reconnection Address Characteristic. */ + BLE_UUID_GAP_CHARACTERISTIC_PPCP = 0x2A04, /**< Peripheral Preferred Connection Parameters Characteristic. */ +}; +/** @} */ + +/** @defgroup BLE_APPEARANCES Bluetooth Appearance values + * @note Retrieved from http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml + * @{ */ +enum { + BLE_APPEARANCE_UNKNOWN = 0, /**< Unknown. */ + BLE_APPEARANCE_GENERIC_PHONE = 64, /**< Generic Phone. */ + BLE_APPEARANCE_GENERIC_COMPUTER = 128, /**< Generic Computer. */ + BLE_APPEARANCE_GENERIC_WATCH = 192, /**< Generic Watch. */ + BLE_APPEARANCE_WATCH_SPORTS_WATCH = 193, /**< Watch: Sports Watch. */ + BLE_APPEARANCE_GENERIC_CLOCK = 256, /**< Generic Clock. */ + BLE_APPEARANCE_GENERIC_DISPLAY = 320, /**< Generic Display. */ + BLE_APPEARANCE_GENERIC_REMOTE_CONTROL = 384, /**< Generic Remote Control. */ + BLE_APPEARANCE_GENERIC_EYE_GLASSES = 448, /**< Generic Eye-glasses. */ + BLE_APPEARANCE_GENERIC_TAG = 512, /**< Generic Tag. */ + BLE_APPEARANCE_GENERIC_KEYRING = 576, /**< Generic Keyring. */ + BLE_APPEARANCE_GENERIC_MEDIA_PLAYER = 640, /**< Generic Media Player. */ + BLE_APPEARANCE_GENERIC_BARCODE_SCANNER = 704, /**< Generic Barcode Scanner. */ + BLE_APPEARANCE_GENERIC_THERMOMETER = 768, /**< Generic Thermometer. */ + BLE_APPEARANCE_THERMOMETER_EAR = 769, /**< Thermometer: Ear. */ + BLE_APPEARANCE_GENERIC_HEART_RATE_SENSOR = 832, /**< Generic Heart rate Sensor. */ + BLE_APPEARANCE_HEART_RATE_SENSOR_HEART_RATE_BELT = 833, /**< Heart Rate Sensor: Heart Rate Belt. */ + BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE = 896, /**< Generic Blood Pressure. */ + BLE_APPEARANCE_BLOOD_PRESSURE_ARM = 897, /**< Blood Pressure: Arm. */ + BLE_APPEARANCE_BLOOD_PRESSURE_WRIST = 898, /**< Blood Pressure: Wrist. */ + BLE_APPEARANCE_GENERIC_HID = 960, /**< Human Interface Device (HID). */ + BLE_APPEARANCE_HID_KEYBOARD = 961, /**< Keyboard (HID Subtype). */ + BLE_APPEARANCE_HID_MOUSE = 962, /**< Mouse (HID Subtype). */ + BLE_APPEARANCE_HID_JOYSTICK = 963, /**< Joystiq (HID Subtype). */ + BLE_APPEARANCE_HID_GAMEPAD = 964, /**< Gamepad (HID Subtype). */ + BLE_APPEARANCE_HID_DIGITIZERSUBTYPE = 965, /**< Digitizer Tablet (HID Subtype). */ + BLE_APPEARANCE_HID_CARD_READER = 966, /**< Card Reader (HID Subtype). */ + BLE_APPEARANCE_HID_DIGITAL_PEN = 967, /**< Digital Pen (HID Subtype). */ + BLE_APPEARANCE_HID_BARCODE = 968, /**< Barcode Scanner (HID Subtype). */ + BLE_APPEARANCE_GENERIC_GLUCOSE_METER = 1024, /**< Generic Glucose Meter. */ + BLE_APPEARANCE_GENERIC_RUNNING_WALKING_SENSOR = 1088, /**< Generic Running Walking Sensor. */ + BLE_APPEARANCE_RUNNING_WALKING_SENSOR_IN_SHOE = 1089, /**< Running Walking Sensor: In-Shoe. */ + BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_SHOE = 1090, /**< Running Walking Sensor: On-Shoe. */ + BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_HIP = 1091, /**< Running Walking Sensor: On-Hip. */ + BLE_APPEARANCE_GENERIC_CYCLING = 1152, /**< Generic Cycling. */ + BLE_APPEARANCE_CYCLING_CYCLING_COMPUTER = 1153, /**< Cycling: Cycling Computer. */ + BLE_APPEARANCE_CYCLING_SPEED_SENSOR = 1154, /**< Cycling: Speed Sensor. */ + BLE_APPEARANCE_CYCLING_CADENCE_SENSOR = 1155, /**< Cycling: Cadence Sensor. */ + BLE_APPEARANCE_CYCLING_POWER_SENSOR = 1156, /**< Cycling: Power Sensor. */ + BLE_APPEARANCE_CYCLING_SPEED_CADENCE_SENSOR = 1157, /**< Cycling: Speed and Cadence Sensor. */ + BLE_APPEARANCE_GENERIC_PULSE_OXIMETER = 3136, /**< Generic Pulse Oximeter. */ + BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP = 3137, /**< Fingertip (Pulse Oximeter subtype). */ + BLE_APPEARANCE_PULSE_OXIMETER_WRIST_WORN = 3138, /**< Wrist Worn(Pulse Oximeter subtype). */ + BLE_APPEARANCE_GENERIC_WEIGHT_SCALE = 3200, /**< Generic Weight Scale. */ + BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS_ACT = 5184, /**< Generic Outdoor Sports Activity. */ + BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_DISP = 5185, /**< Location Display Device (Outdoor Sports Activity subtype). */ + BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_DISP = 5186, /**< Location and Navigation Display Device (Outdoor Sports Activity subtype). */ + BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_POD = 5187, /**< Location Pod (Outdoor Sports Activity subtype). */ + BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_POD = 5188, /**< Location and Navigation Pod (Outdoor Sports Activity subtype). */ +}; +/** @} */ + +/**************************************************************************/ +/*! + \brief Error codes for the BLE API +*/ +/**************************************************************************/ +enum ble_error_t { + BLE_ERROR_NONE = 0, /**< No error */ + BLE_ERROR_BUFFER_OVERFLOW = 1, /**< The requested action would cause a buffer overflow and has been aborted */ + BLE_ERROR_NOT_IMPLEMENTED = 2, /**< Requested a feature that isn't yet implement or isn't supported by the target HW */ + BLE_ERROR_PARAM_OUT_OF_RANGE = 3, /**< One of the supplied parameters is outside the valid range */ + BLE_ERROR_INVALID_PARAM = 4, /**< One of the supplied parameters is invalid */ + BLE_STACK_BUSY = 5, /**< The stack is busy */ + BLE_ERROR_INVALID_STATE = 6, /**< Invalid state. */ + BLE_ERROR_NO_MEM = 7, /**< Out of Memory */ + BLE_ERROR_OPERATION_NOT_PERMITTED = 8, + BLE_ERROR_UNSPECIFIED = 9, /**< Unknown error. */ +}; + +#ifdef __cplusplus +} +#endif + +#endif // ifndef __BLE_COMMON_H__ \ No newline at end of file
--- a/common/BLEDevice.cpp Fri Jun 19 15:53:06 2015 +0100 +++ b/common/BLEDevice.cpp Fri Jun 19 15:53:28 2015 +0100 @@ -14,14 +14,14 @@ * limitations under the License. */ -#include "BLE.h" +#include "BLEDevice.h" #if defined(TARGET_OTA_ENABLED) #include "DFUService.h" #endif ble_error_t -BLE::init() +BLEDevice::init() { ble_error_t err = transport->init(); if (err != BLE_ERROR_NONE) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/BLEDeviceInstanceBase.h Fri Jun 19 15:53:28 2015 +0100 @@ -0,0 +1,52 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BLE_DEVICE_INSTANCE_BASE__ +#define __BLE_DEVICE_INSTANCE_BASE__ + +/** + * The interface for the transport object to be created by the target library's + * createBLEDeviceInstance(). + */ +class BLEDeviceInstanceBase +{ +public: + virtual const char *getVersion(void) = 0; + virtual Gap& getGap() = 0; + virtual GattServer& getGattServer() = 0; + virtual ble_error_t init(void) = 0; + virtual ble_error_t shutdown(void) = 0; + virtual ble_error_t reset(void) = 0; + virtual ble_error_t initializeSecurity(bool enableBonding = true, + bool requireMITM = true, + Gap::SecurityIOCapabilities_t iocaps = Gap::IO_CAPS_NONE, + const Gap::Passkey_t passkey = NULL) = 0; + virtual ble_error_t setTxPower(int8_t txPower) = 0; + virtual void getPermittedTxPowerValues(const int8_t **, size_t *) = 0; + virtual void waitForEvent(void) = 0; +}; + +/** + * BLEDevice uses composition to hide an interface object encapsulating the + * backend transport. + * + * The following API is used to create the singleton interface object. An + * implementation for this function must be provided by the device-specific + * library, otherwise there will be a linker error. + */ +extern BLEDeviceInstanceBase *createBLEDeviceInstance(void); + +#endif // ifndef __BLE_DEVICE_INSTANCE_BASE__ \ No newline at end of file
--- a/common/BLEInstanceBase.h Fri Jun 19 15:53:06 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __BLE_DEVICE_INSTANCE_BASE__ -#define __BLE_DEVICE_INSTANCE_BASE__ - -#include "Gap.h" - -/* forward declarations */ -class GattServer; -class GattClient; - -/** - * The interface for the transport object to be created by the target library's - * createBLEInstance(). - */ -class BLEInstanceBase -{ -public: - virtual ble_error_t init(void) = 0; - virtual ble_error_t shutdown(void) = 0; - virtual const char *getVersion(void) = 0; - virtual Gap& getGap() = 0; - virtual const Gap& getGap() const = 0; - virtual GattServer& getGattServer() = 0; - virtual const GattServer& getGattServer() const = 0; - virtual GattClient& getGattClient() = 0; - virtual SecurityManager& getSecurityManager() = 0; - virtual const SecurityManager& getSecurityManager() const = 0; - virtual void waitForEvent(void) = 0; -}; - -/** - * BLE uses composition to hide an interface object encapsulating the - * backend transport. - * - * The following API is used to create the singleton interface object. An - * implementation for this function must be provided by the device-specific - * library, otherwise there will be a linker error. - */ -extern BLEInstanceBase *createBLEInstance(void); - -#endif // ifndef __BLE_DEVICE_INSTANCE_BASE__ \ No newline at end of file
--- a/common/DiscoveredCharacteristic.cpp Fri Jun 19 15:53:06 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "DiscoveredCharacteristic.h" -#include "GattClient.h" - -GattClient::ReadCallback_t DiscoveredCharacteristic::onDataReadCallback; -GattClient::WriteCallback_t DiscoveredCharacteristic::onDataWriteCallback; - -ble_error_t -DiscoveredCharacteristic::read(uint16_t offset) const -{ - if (!props.read()) { - return BLE_ERROR_OPERATION_NOT_PERMITTED; - } - - if (!gattc) { - return BLE_ERROR_INVALID_STATE; - } - - return gattc->read(connHandle, valueHandle, offset); -} - -ble_error_t -DiscoveredCharacteristic::write(uint16_t length, const uint8_t *value) const -{ - if (!props.write()) { - return BLE_ERROR_OPERATION_NOT_PERMITTED; - } - - if (!gattc) { - return BLE_ERROR_INVALID_STATE; - } - - return gattc->write(GattClient::GATT_OP_WRITE_REQ, connHandle, valueHandle, length, value); -} - -ble_error_t -DiscoveredCharacteristic::writeWoResponse(uint16_t length, const uint8_t *value) const -{ - if (!props.writeWoResp()) { - return BLE_ERROR_OPERATION_NOT_PERMITTED; - } - - if (!gattc) { - return BLE_ERROR_INVALID_STATE; - } - - return gattc->write(GattClient::GATT_OP_WRITE_CMD, connHandle, valueHandle, length, value); -} - -ble_error_t -DiscoveredCharacteristic::discoverDescriptors(DescriptorCallback_t callback, const UUID &matchingUUID) const -{ - return BLE_ERROR_NOT_IMPLEMENTED; /* TODO: this needs to be filled in. */ -} \ No newline at end of file
--- a/common/GapScanningParams.cpp Fri Jun 19 15:53:06 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "Gap.h" -#include "GapScanningParams.h" - -GapScanningParams::GapScanningParams(uint16_t interval, uint16_t window, uint16_t timeout, bool activeScanning) : - _interval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(interval)), - _window(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(window)), - _timeout(timeout), - _activeScanning(activeScanning) { - /* stay within limits */ - if (_interval < SCAN_INTERVAL_MIN) { - _interval = SCAN_INTERVAL_MIN; - } - if (_interval > SCAN_INTERVAL_MAX) { - _interval = SCAN_INTERVAL_MAX; - } - if (_window < SCAN_WINDOW_MIN) { - _window = SCAN_WINDOW_MIN; - } - if (_window > SCAN_WINDOW_MAX) { - _window = SCAN_WINDOW_MAX; - } -} - -ble_error_t -GapScanningParams::setInterval(uint16_t newIntervalInMS) -{ - uint16_t newInterval = Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(newIntervalInMS); - if ((newInterval >= SCAN_INTERVAL_MIN) && (newInterval < SCAN_INTERVAL_MAX)) { - _interval = newInterval; - return BLE_ERROR_NONE; - } - - return BLE_ERROR_PARAM_OUT_OF_RANGE; -} - -ble_error_t -GapScanningParams::setWindow(uint16_t newWindowInMS) -{ - uint16_t newWindow = Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(newWindowInMS); - if ((newWindow >= SCAN_WINDOW_MIN) && (newWindow < SCAN_WINDOW_MAX)) { - _window = newWindow; - return BLE_ERROR_NONE; - } - - return BLE_ERROR_PARAM_OUT_OF_RANGE; -} - -ble_error_t -GapScanningParams::setTimeout(uint16_t newTimeout) -{ - _timeout = newTimeout; - return BLE_ERROR_NONE; -} - -void -GapScanningParams::setActiveScanning(bool activeScanning) -{ - _activeScanning = activeScanning; -} \ No newline at end of file
--- a/common/blecommon.h Fri Jun 19 15:53:06 2015 +0100 +++ b/common/blecommon.h Fri Jun 19 15:53:28 2015 +0100 @@ -21,6 +21,8 @@ extern "C" { #endif +#include <stdint.h> +#include <stddef.h> /** @defgroup BLE_UUID_VALUES Assigned Values for BLE UUIDs * @{ */ @@ -113,18 +115,18 @@ \brief Error codes for the BLE API */ /**************************************************************************/ -enum ble_error_t { - BLE_ERROR_NONE = 0, /**< No error */ - BLE_ERROR_BUFFER_OVERFLOW = 1, /**< The requested action would cause a buffer overflow and has been aborted */ - BLE_ERROR_NOT_IMPLEMENTED = 2, /**< Requested a feature that isn't yet implement or isn't supported by the target HW */ - BLE_ERROR_PARAM_OUT_OF_RANGE = 3, /**< One of the supplied parameters is outside the valid range */ - BLE_ERROR_INVALID_PARAM = 4, /**< One of the supplied parameters is invalid */ - BLE_STACK_BUSY = 5, /**< The stack is busy */ - BLE_ERROR_INVALID_STATE = 6, /**< Invalid state. */ - BLE_ERROR_NO_MEM = 7, /**< Out of Memory */ - BLE_ERROR_OPERATION_NOT_PERMITTED = 8, - BLE_ERROR_UNSPECIFIED = 9, /**< Unknown error. */ -}; +typedef enum ble_error_e +{ + BLE_ERROR_NONE = 0, /**< No error */ + BLE_ERROR_BUFFER_OVERFLOW = 1, /**< The requested action would cause a buffer overflow and has been aborted */ + BLE_ERROR_NOT_IMPLEMENTED = 2, /**< Requested a feature that isn't yet implement or isn't supported by the target HW */ + BLE_ERROR_PARAM_OUT_OF_RANGE = 3, /**< One of the supplied parameters is outside the valid range */ + BLE_ERROR_INVALID_PARAM = 4, /**< One of the supplied parameters is invalid */ + BLE_STACK_BUSY = 5, /**< The stack is busy */ + BLE_ERROR_INVALID_STATE = 6, /**< Invalid state. */ + BLE_ERROR_NO_MEM = 7, /**< Out of Memory */ + BLE_ERROR_UNSPECIFIED = 8, /**< Unknown error. */ +} ble_error_t; #ifdef __cplusplus }
--- a/public/BLE.h Fri Jun 19 15:53:06 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1342 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __BLE_H__ -#define __BLE_H__ - -#include "blecommon.h" -#include "Gap.h" -#include "GattServer.h" -#include "GattClient.h" -#include "BLEInstanceBase.h" - -/** - * The base class used to abstract away BLE capable radio transceivers or SOCs, - * to enable this BLE API to work with any radio transparently. - */ -class BLE -{ -public: - /** - * Initialize the BLE controller. This should be called before using - * anything else in the BLE_API. - * - * init() hands control to the underlying BLE module to accomplish - * initialization. This initialization may tacitly depend on other hardware - * setup (such as clocks or power-modes) which happens early on during - * system startup. It may not be safe to call init() from global static - * context where ordering is compiler specific and can't be guaranteed--it - * is safe to call BLE::init() from within main(). - */ - ble_error_t init(); - - /** - * Purge the BLE stack of GATT and GAP state. init() must be called - * afterwards to re-instate services and GAP state. This API offers a way to - * repopulate the GATT database with new services and characteristics. - */ - ble_error_t shutdown(void) { - clearAdvertisingPayload(); - return transport->shutdown(); - } - - /** - * This call allows the application to get the BLE stack version information. - * - * @return A pointer to a const string representing the version. - * Note: The string is owned by the BLE_API. - */ - const char *getVersion(void) { - return transport->getVersion(); - } - - /* - * Accessors to GAP. Please refer to Gap.h. All GAP related functionality requires - * going through this accessor. - */ - const Gap &gap() const { - return transport->getGap(); - } - Gap &gap() { - return transport->getGap(); - } - - /* - * Accessors to GATT Server. Please refer to GattServer.h. All GATTServer related - * functionality requires going through this accessor. - */ - const GattServer& gattServer() const { - return transport->getGattServer(); - } - GattServer& gattServer() { - return transport->getGattServer(); - } - - /* - * Accessors to GATT Client. Please refer to GattClient.h. All GATTClient related - * functionality requires going through this accessor. - */ - const GattClient& gattClient() const { - return transport->getGattClient(); - } - GattClient& gattClient() { - return transport->getGattClient(); - } - - /* - * Accessors to Security Manager. Please refer to SecurityManager.h. All - * SecurityManager related functionality requires going through this - * accessor. - */ - const SecurityManager& securityManager() const { - return transport->getSecurityManager(); - } - SecurityManager& securityManager() { - return transport->getSecurityManager(); - } - - /** - * Yield control to the BLE stack or to other tasks waiting for events. This - * is a sleep function which will return when there is an application - * specific interrupt, but the MCU might wake up several times before - * returning (to service the stack). This is not always interchangeable with - * WFE(). - */ - void waitForEvent(void) { - transport->waitForEvent(); - } - - /* - * Deprecation alert! - * All of the following are deprecated and may be dropped in a future - * release. Documentation should refer to alternative APIs. - */ - - /* GAP specific APIs. */ -public: - /** - * Set the BTLE MAC address and type. - * @return BLE_ERROR_NONE on success. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.setAddress(...) should be replaced with - * ble.gap().setAddress(...). - */ - ble_error_t setAddress(Gap::AddressType_t type, const Gap::Address_t address) { - return gap().setAddress(type, address); - } - - /** - * Fetch the BTLE MAC address and type. - * @return BLE_ERROR_NONE on success. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.getAddress(...) should be replaced with - * ble.gap().getAddress(...). - */ - ble_error_t getAddress(Gap::AddressType_t *typeP, Gap::Address_t address) { - return gap().getAddress(typeP, address); - } - - /** - * Set the GAP advertising mode to use for this device. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.setAdvertisingType(...) should be replaced with - * ble.gap().setAdvertisingType(...). - */ - void setAdvertisingType(GapAdvertisingParams::AdvertisingType advType) { - gap().setAdvertisingType(advType); - } - - /** - * @param[in] interval - * Advertising interval in units of milliseconds. Advertising - * is disabled if interval is 0. If interval is smaller than - * the minimum supported value, then the minimum supported - * value is used instead. This minimum value can be discovered - * using getMinAdvertisingInterval(). - * - * This field must be set to 0 if connectionMode is equal - * to ADV_CONNECTABLE_DIRECTED. - * - * @note: Decreasing this value will allow central devices to detect a - * peripheral faster at the expense of more power being used by the radio - * due to the higher data transmit rate. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.setAdvertisingInterval(...) should be replaced with - * ble.gap().setAdvertisingInterval(...). - * - * @note: [WARNING] This API previously used 0.625ms as the unit for its - * 'interval' argument. That required an explicit conversion from - * milliseconds using Gap::MSEC_TO_GAP_DURATION_UNITS(). This conversion is - * no longer required as the new units are milliseconds. Any application - * code depending on the old semantics would need to be updated accordingly. - */ - void setAdvertisingInterval(uint16_t interval) { - gap().setAdvertisingInterval(interval); - } - - /** - * @return Minimum Advertising interval in milliseconds. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.getMinAdvertisingInterval(...) should be replaced with - * ble.gap().getMinAdvertisingInterval(...). - */ - uint16_t getMinAdvertisingInterval(void) const { - return gap().getMinAdvertisingInterval(); - } - - /** - * @return Minimum Advertising interval in milliseconds for non-connectible mode. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.getMinNonConnectableAdvertisingInterval(...) should be replaced with - * ble.gap().getMinNonConnectableAdvertisingInterval(...). - */ - uint16_t getMinNonConnectableAdvertisingInterval(void) const { - return gap().getMinNonConnectableAdvertisingInterval(); - } - - /** - * @return Maximum Advertising interval in milliseconds. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.getMaxAdvertisingInterval(...) should be replaced with - * ble.gap().getMaxAdvertisingInterval(...). - */ - uint16_t getMaxAdvertisingInterval(void) const { - return gap().getMaxAdvertisingInterval(); - } - - /** - * @param[in] timeout - * Advertising timeout (in seconds) between 0x1 and 0x3FFF (1 - * and 16383). Use 0 to disable the advertising timeout. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.setAdvertisingTimeout(...) should be replaced with - * ble.gap().setAdvertisingTimeout(...). - */ - void setAdvertisingTimeout(uint16_t timeout) { - gap().setAdvertisingTimeout(timeout); - } - - /** - * Setup a particular, user-constructed set of advertisement parameters for - * the underlying stack. It would be uncommon for this API to be used - * directly; there are other APIs to tweak advertisement parameters - * individually (see above). - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.setAdvertisingParams(...) should be replaced with - * ble.gap().setAdvertisingParams(...). - */ - void setAdvertisingParams(const GapAdvertisingParams &advParams) { - gap().setAdvertisingParams(advParams); - } - - /** - * @return Read back advertising parameters. Useful for storing and - * restoring parameters rapidly. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.getAdvertisingParams(...) should be replaced with - * ble.gap().getAdvertisingParams(...). - */ - const GapAdvertisingParams &getAdvertisingParams(void) const { - return gap().getAdvertisingParams(); - } - - /** - * Accumulate an AD structure in the advertising payload. Please note that - * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used - * as an additional 31 bytes if the advertising payload proves to be too - * small. - * - * @param[in] flags - * The flags to be added. Please refer to - * GapAdvertisingData::Flags for valid flags. Multiple - * flags may be specified in combination. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.accumulateAdvertisingPayload(flags) should be replaced with - * ble.gap().accumulateAdvertisingPayload(flags). - */ - ble_error_t accumulateAdvertisingPayload(uint8_t flags) { - return gap().accumulateAdvertisingPayload(flags); - } - - /** - * Accumulate an AD structure in the advertising payload. Please note that - * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used - * as an additional 31 bytes if the advertising payload proves to be too - * small. - * - * @param[in] app - * The appearance of the peripheral. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.accumulateAdvertisingPayload(appearance) should be replaced with - * ble.gap().accumulateAdvertisingPayload(appearance). - */ - ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::Appearance app) { - return gap().accumulateAdvertisingPayload(app); - } - - /** - * Accumulate an AD structure in the advertising payload. Please note that - * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used - * as an additional 31 bytes if the advertising payload proves to be too - * small. - * - * @param[in] app - * The max transmit power to be used by the controller. This - * is only a hint. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.accumulateAdvertisingPayloadTxPower(txPower) should be replaced with - * ble.gap().accumulateAdvertisingPayloadTxPower(txPower). - */ - ble_error_t accumulateAdvertisingPayloadTxPower(int8_t power) { - return gap().accumulateAdvertisingPayloadTxPower(power); - } - - /** - * Accumulate a variable length byte-stream as an AD structure in the - * advertising payload. Please note that the payload is limited to 31 bytes. - * The SCAN_RESPONSE message may be used as an additional 31 bytes if the - * advertising payload proves to be too small. - * - * @param type The type which describes the variable length data. - * @param data data bytes. - * @param len length of data. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.accumulateAdvertisingPayload(...) should be replaced with - * ble.gap().accumulateAdvertisingPayload(...). - */ - ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) { - return gap().accumulateAdvertisingPayload(type, data, len); - } - - /** - * Setup a particular, user-constructed advertisement payload for the - * underlying stack. It would be uncommon for this API to be used directly; - * there are other APIs to build an advertisement payload (see above). - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.setAdvertisingData(...) should be replaced with - * ble.gap().setAdvertisingPayload(...). - */ - ble_error_t setAdvertisingData(const GapAdvertisingData &advData) { - return gap().setAdvertisingPayload(advData); - } - - /** - * @return Read back advertising data. Useful for storing and - * restoring payload. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.getAdvertisingData(...) should be replaced with - * ble.gap().getAdvertisingPayload()(...). - */ - const GapAdvertisingData &getAdvertisingData(void) const { - return gap().getAdvertisingPayload(); - } - - /** - * Reset any advertising payload prepared from prior calls to - * accumulateAdvertisingPayload(). This automatically propagates the re- - * initialized adv payload to the underlying stack. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.clearAdvertisingPayload(...) should be replaced with - * ble.gap().clearAdvertisingPayload(...). - */ - void clearAdvertisingPayload(void) { - gap().clearAdvertisingPayload(); - } - - /** - * This API is *deprecated* and resolves to a no-operation. It is left here - * to allow older code to compile. Please avoid using this API in new code. - * This API will be dropped in a future release. - * - * Formerly, it would be used to dynamically reset the accumulated advertising - * payload and scanResponse; to do this, the application would clear and re- - * accumulate a new advertising payload (and scanResponse) before using this - * API. Updates to the underlying advertisement payload now happen - * implicitly. - */ - ble_error_t setAdvertisingPayload(void) { - return BLE_ERROR_NONE; - } - - /** - * Accumulate a variable length byte-stream as an AD structure in the - * scanResponse payload. - * - * @param[in] type The type which describes the variable length data. - * @param[in] data data bytes. - * @param[in] len length of data. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.accumulateScanResponse(...) should be replaced with - * ble.gap().accumulateScanResponse(...). - */ - ble_error_t accumulateScanResponse(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) { - return gap().accumulateScanResponse(type, data, len); - } - - /** - * Reset any scan response prepared from prior calls to - * accumulateScanResponse(). - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.clearScanResponse(...) should be replaced with - * ble.gap().clearScanResponse(...). - */ - void clearScanResponse(void) { - gap().clearScanResponse(); - } - - /** - * Start advertising. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.startAdvertising(...) should be replaced with - * ble.gap().startAdvertising(...). - */ - ble_error_t startAdvertising(void) { - return gap().startAdvertising(); - } - - /** - * Stop advertising. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.stopAdvertising(...) should be replaced with - * ble.gap().stopAdvertising(...). - */ - ble_error_t stopAdvertising(void) { - return gap().stopAdvertising(); - } - - /** - * Setup parameters for GAP scanning--i.e. observer mode. - * @param[in] interval - * Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s]. - * @param[in] window - * Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s]. - * @param[in] timeout - * Scan timeout (in seconds) between 0x0001 and 0xFFFF, 0x0000 disables timeout. - * @param[in] activeScanning - * Set to True if active-scanning is required. This is used to fetch the - * scan response from a peer if possible. - * - * The scanning window divided by the interval determines the duty cycle for - * scanning. For example, if the interval is 100ms and the window is 10ms, - * then the controller will scan for 10 percent of the time. It is possible - * to have the interval and window set to the same value. In this case, - * scanning is continuous, with a change of scanning frequency once every - * interval. - * - * Once the scanning parameters have been configured, scanning can be - * enabled by using startScan(). - * - * @Note: The scan interval and window are recommendations to the BLE stack. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.setScanParams(...) should be replaced with - * ble.gap().setScanParams(...). - */ - ble_error_t setScanParams(uint16_t interval = GapScanningParams::SCAN_INTERVAL_MAX, - uint16_t window = GapScanningParams::SCAN_WINDOW_MAX, - uint16_t timeout = 0, - bool activeScanning = false) { - return gap().setScanParams(interval, window, timeout, activeScanning); - } - - /** - * Setup the scanInterval parameter for GAP scanning--i.e. observer mode. - * @param[in] interval - * Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s]. - * - * The scanning window divided by the interval determines the duty cycle for - * scanning. For example, if the interval is 100ms and the window is 10ms, - * then the controller will scan for 10 percent of the time. It is possible - * to have the interval and window set to the same value. In this case, - * scanning is continuous, with a change of scanning frequency once every - * interval. - * - * Once the scanning parameters have been configured, scanning can be - * enabled by using startScan(). - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.setScanInterval(interval) should be replaced with - * ble.gap().setScanInterval(interval). - */ - ble_error_t setScanInterval(uint16_t interval) { - return gap().setScanInterval(interval); - } - - /** - * Setup the scanWindow parameter for GAP scanning--i.e. observer mode. - * @param[in] window - * Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s]. - * - * The scanning window divided by the interval determines the duty cycle for - * scanning. For example, if the interval is 100ms and the window is 10ms, - * then the controller will scan for 10 percent of the time. It is possible - * to have the interval and window set to the same value. In this case, - * scanning is continuous, with a change of scanning frequency once every - * interval. - * - * Once the scanning parameters have been configured, scanning can be - * enabled by using startScan(). - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.setScanWindow(window) should be replaced with - * ble.gap().setScanWindow(window). - */ - ble_error_t setScanWindow(uint16_t window) { - return gap().setScanWindow(window); - } - - /** - * Setup parameters for GAP scanning--i.e. observer mode. - * @param[in] timeout - * Scan timeout (in seconds) between 0x0001 and 0xFFFF, 0x0000 disables timeout. - * - * The scanning window divided by the interval determines the duty cycle for - * scanning. For example, if the interval is 100ms and the window is 10ms, - * then the controller will scan for 10 percent of the time. It is possible - * to have the interval and window set to the same value. In this case, - * scanning is continuous, with a change of scanning frequency once every - * interval. - * - * Once the scanning parameters have been configured, scanning can be - * enabled by using startScan(). - * - * @Note: The scan interval and window are recommendations to the BLE stack. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.setScanTimeout(...) should be replaced with - * ble.gap().setScanTimeout(...). - */ - ble_error_t setScanTimeout(uint16_t timeout) { - return gap().setScanTimeout(timeout); - } - - /** - * Setup parameters for GAP scanning--i.e. observer mode. - * @param[in] activeScanning - * Set to True if active-scanning is required. This is used to fetch the - * scan response from a peer if possible. - * - * Once the scanning parameters have been configured, scanning can be - * enabled by using startScan(). - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.setActiveScan(...) should be replaced with - * ble.gap().setActiveScanning(...). - */ - void setActiveScan(bool activeScanning) { - gap().setActiveScanning(activeScanning); - } - - /** - * Start scanning (Observer Procedure) based on the parameters currently in - * effect. - * - * @param[in] callback - * The application specific callback to be invoked upon - * receiving every advertisement report. This can be passed in - * as NULL, in which case scanning may not be enabled at all. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.startScan(callback) should be replaced with - * ble.gap().startScan(callback). - */ - ble_error_t startScan(void (*callback)(const Gap::AdvertisementCallbackParams_t *params)) { - return gap().startScan(callback); - } - - /** - * Same as above, but this takes an (object, method) pair for a callback. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.startScan(callback) should be replaced with - * ble.gap().startScan(object, callback). - */ - template<typename T> - ble_error_t startScan(T *object, void (T::*memberCallback)(const Gap::AdvertisementCallbackParams_t *params)); - - /** - * Stop scanning. The current scanning parameters remain in effect. - * - * @retval BLE_ERROR_NONE if successfully stopped scanning procedure. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.stopScan() should be replaced with - * ble.gap().stopScan(). - */ - ble_error_t stopScan(void) { - return gap().stopScan(); - } - - /** - * Create a connection (GAP Link Establishment). - * @param peerAddr - * 48-bit address, LSB format. - * @param peerAddrType - * Address type of the peer. - * @param connectionParams - * Connection parameters. - * @param scanParams - * Paramters to be used while scanning for the peer. - * @return BLE_ERROR_NONE if connection establishment procedure is started - * successfully. The onConnection callback (if set) will be invoked upon - * a connection event. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.connect(...) should be replaced with - * ble.gap().connect(...). - */ - ble_error_t connect(const Gap::Address_t peerAddr, - Gap::AddressType_t peerAddrType = Gap::ADDR_TYPE_RANDOM_STATIC, - const Gap::ConnectionParams_t *connectionParams = NULL, - const GapScanningParams *scanParams = NULL) { - return gap().connect(peerAddr, peerAddrType, connectionParams, scanParams); - } - - /** - * This call initiates the disconnection procedure, and its completion will - * be communicated to the application with an invocation of the - * onDisconnection callback. - * - * @param[in] connectionHandle - * @param[in] reason - * The reason for disconnection to be sent back to the peer. - */ - ble_error_t disconnect(Gap::Handle_t connectionHandle, Gap::DisconnectionReason_t reason) { - return gap().disconnect(connectionHandle, reason); - } - - /** - * This call initiates the disconnection procedure, and its completion will - * be communicated to the application with an invocation of the - * onDisconnection callback. - * - * @param reason - * The reason for disconnection to be sent back to the peer. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.disconnect(reason) should be replaced with - * ble.gap().disconnect(reason). - * - * @note: this version of disconnect() doesn't take a connection handle. It - * will work reliably only for stacks which are limited to a single - * connection. This API should be considered *deprecated* in favour of the - * alternative which takes a connection handle. It will be dropped in the future. - */ - ble_error_t disconnect(Gap::DisconnectionReason_t reason) { - return gap().disconnect(reason); - } - - /** - * Returns the current GAP state of the device using a bitmask which - * describes whether the device is advertising and/or connected. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.getGapState() should be replaced with - * ble.gap().getState(). - */ - Gap::GapState_t getGapState(void) const { - return gap().getState(); - } - - /** - * Get the GAP peripheral preferred connection parameters. These are the - * defaults that the peripheral would like to have in a connection. The - * choice of the connection parameters is eventually up to the central. - * - * @param[out] params - * The structure where the parameters will be stored. Memory - * for this is owned by the caller. - * - * @return BLE_ERROR_NONE if the parameters were successfully filled into - * the given structure pointed to by params. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.getPreferredConnectionParams() should be replaced with - * ble.gap().getPreferredConnectionParams(). - */ - ble_error_t getPreferredConnectionParams(Gap::ConnectionParams_t *params) { - return gap().getPreferredConnectionParams(params); - } - - /** - * Set the GAP peripheral preferred connection parameters. These are the - * defaults that the peripheral would like to have in a connection. The - * choice of the connection parameters is eventually up to the central. - * - * @param[in] params - * The structure containing the desired parameters. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.setPreferredConnectionParams() should be replaced with - * ble.gap().setPreferredConnectionParams(). - */ - ble_error_t setPreferredConnectionParams(const Gap::ConnectionParams_t *params) { - return gap().setPreferredConnectionParams(params); - } - - /** - * Update connection parameters while in the peripheral role. - * @details In the peripheral role, this will send the corresponding L2CAP request to the connected peer and wait for - * the central to perform the procedure. - * @param[in] handle - * Connection Handle - * @param[in] params - * Pointer to desired connection parameters. If NULL is provided on a peripheral role, - * the parameters in the PPCP characteristic of the GAP service will be used instead. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.updateConnectionParams() should be replaced with - * ble.gap().updateConnectionParams(). - */ - ble_error_t updateConnectionParams(Gap::Handle_t handle, const Gap::ConnectionParams_t *params) { - return gap().updateConnectionParams(handle, params); - } - - /** - * Set the device name characteristic in the GAP service. - * @param[in] deviceName - * The new value for the device-name. This is a UTF-8 encoded, <b>NULL-terminated</b> string. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.setDeviceName() should be replaced with - * ble.gap().setDeviceName(). - */ - ble_error_t setDeviceName(const uint8_t *deviceName) { - return gap().setDeviceName(deviceName); - } - - /** - * Get the value of the device name characteristic in the GAP service. - * @param[out] deviceName - * Pointer to an empty buffer where the UTF-8 *non NULL- - * terminated* string will be placed. Set this - * value to NULL in order to obtain the deviceName-length - * from the 'length' parameter. - * - * @param[in/out] lengthP - * (on input) Length of the buffer pointed to by deviceName; - * (on output) the complete device name length (without the - * null terminator). - * - * @note If the device name is longer than the size of the supplied buffer, - * length will return the complete device name length, and not the - * number of bytes actually returned in deviceName. The application may - * use this information to retry with a suitable buffer size. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.getDeviceName() should be replaced with - * ble.gap().getDeviceName(). - */ - ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP) { - return gap().getDeviceName(deviceName, lengthP); - } - - /** - * Set the appearance characteristic in the GAP service. - * @param[in] appearance - * The new value for the device-appearance. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.setAppearance() should be replaced with - * ble.gap().setAppearance(). - */ - ble_error_t setAppearance(GapAdvertisingData::Appearance appearance) { - return gap().setAppearance(appearance); - } - - /** - * Get the appearance characteristic in the GAP service. - * @param[out] appearance - * The new value for the device-appearance. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.getAppearance() should be replaced with - * ble.gap().getAppearance(). - */ - ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP) { - return gap().getAppearance(appearanceP); - } - - /** - * Set the radio's transmit power. - * @param[in] txPower Radio transmit power in dBm. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.setTxPower() should be replaced with - * ble.gap().setTxPower(). - */ - ble_error_t setTxPower(int8_t txPower) { - return gap().setTxPower(txPower); - } - - /** - * Query the underlying stack for permitted arguments for setTxPower(). - * - * @param[out] valueArrayPP - * Out parameter to receive the immutable array of Tx values. - * @param[out] countP - * Out parameter to receive the array's size. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.getPermittedTxPowerValues() should be replaced with - * ble.gap().getPermittedTxPowerValues(). - */ - void getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) { - gap().getPermittedTxPowerValues(valueArrayPP, countP); - } - - /** - * Add a service declaration to the local server ATT table. Also add the - * characteristics contained within. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from GattServer directly. A former call - * to ble.addService() should be replaced with - * ble.gattServer().addService(). - */ - ble_error_t addService(GattService &service) { - return gattServer().addService(service); - } - - /** - * Read the value of a characteristic from the local GattServer - * @param[in] attributeHandle - * Attribute handle for the value attribute of the characteristic. - * @param[out] buffer - * A buffer to hold the value being read. - * @param[in/out] lengthP - * Length of the buffer being supplied. If the attribute - * value is longer than the size of the supplied buffer, - * this variable will hold upon return the total attribute value length - * (excluding offset). The application may use this - * information to allocate a suitable buffer size. - * - * @return BLE_ERROR_NONE if a value was read successfully into the buffer. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from GattServer directly. A former call - * to ble.readCharacteristicValue() should be replaced with - * ble.gattServer().read(). - */ - ble_error_t readCharacteristicValue(GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP) { - return gattServer().read(attributeHandle, buffer, lengthP); - } - - /** - * Read the value of a characteristic from the local GattServer - * @param[in] connectionHandle - * Connection Handle. - * @param[in] attributeHandle - * Attribute handle for the value attribute of the characteristic. - * @param[out] buffer - * A buffer to hold the value being read. - * @param[in/out] lengthP - * Length of the buffer being supplied. If the attribute - * value is longer than the size of the supplied buffer, - * this variable will hold upon return the total attribute value length - * (excluding offset). The application may use this - * information to allocate a suitable buffer size. - * - * @return BLE_ERROR_NONE if a value was read successfully into the buffer. - * - * @note This API is a version of above with an additional connection handle - * parameter to allow fetches for connection-specific multivalued - * attribtues (such as the CCCDs). - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from GattServer directly. A former call - * to ble.readCharacteristicValue() should be replaced with - * ble.gattServer().read(). - */ - ble_error_t readCharacteristicValue(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP) { - return gattServer().read(connectionHandle, attributeHandle, buffer, lengthP); - } - - /** - * Update the value of a characteristic on the local GattServer. - * - * @param[in] attributeHandle - * Handle for the value attribute of the Characteristic. - * @param[in] value - * A pointer to a buffer holding the new value - * @param[in] size - * Size of the new value (in bytes). - * @param[in] localOnly - * Should this update be kept on the local - * GattServer regardless of the state of the - * notify/indicate flag in the CCCD for this - * Characteristic? If set to true, no notification - * or indication is generated. - * - * @return BLE_ERROR_NONE if we have successfully set the value of the attribute. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from GattServer directly. A former call - * to ble.updateCharacteristicValue() should be replaced with - * ble.gattServer().write(). - */ - ble_error_t updateCharacteristicValue(GattAttribute::Handle_t attributeHandle, - const uint8_t *value, - uint16_t size, - bool localOnly = false) { - return gattServer().write(attributeHandle, value, size, localOnly); - } - - /** - * Update the value of a characteristic on the local GattServer. A version - * of the same as above with connection handle parameter to allow updates - * for connection-specific multivalued attribtues (such as the CCCDs). - * - * @param[in] connectionHandle - * Connection Handle. - * @param[in] attributeHandle - * Handle for the value attribute of the Characteristic. - * @param[in] value - * A pointer to a buffer holding the new value - * @param[in] size - * Size of the new value (in bytes). - * @param[in] localOnly - * Should this update be kept on the local - * GattServer regardless of the state of the - * notify/indicate flag in the CCCD for this - * Characteristic? If set to true, no notification - * or indication is generated. - * - * @return BLE_ERROR_NONE if we have successfully set the value of the attribute. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from GattServer directly. A former call - * to ble.updateCharacteristicValue() should be replaced with - * ble.gattServer().write(). - */ - ble_error_t updateCharacteristicValue(Gap::Handle_t connectionHandle, - GattAttribute::Handle_t attributeHandle, - const uint8_t *value, - uint16_t size, - bool localOnly = false) { - return gattServer().write(connectionHandle, attributeHandle, value, size, localOnly); - } - - /** - * Enable the BLE stack's Security Manager. The Security Manager implements - * the actual cryptographic algorithms and protocol exchanges that allow two - * devices to securely exchange data and privately detect each other. - * Calling this API is a prerequisite for encryption and pairing (bonding). - * - * @param[in] enableBonding Allow for bonding. - * @param[in] requireMITM Require protection for man-in-the-middle attacks. - * @param[in] iocaps To specify IO capabilities of this peripheral, - * such as availability of a display or keyboard to - * support out-of-band exchanges of security data. - * @param[in] passkey To specify a static passkey. - * - * @return BLE_ERROR_NONE on success. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from SecurityManager directly. A former - * call to ble.initializeSecurity(...) should be replaced with - * ble.securityManager().init(...). - */ - ble_error_t initializeSecurity(bool enableBonding = true, - bool requireMITM = true, - SecurityManager::SecurityIOCapabilities_t iocaps = SecurityManager::IO_CAPS_NONE, - const SecurityManager::Passkey_t passkey = NULL) { - return securityManager().init(enableBonding, requireMITM, iocaps, passkey); - } - - /** - * Get the security status of a connection. - * - * @param[in] connectionHandle Handle to identify the connection. - * @param[out] securityStatusP security status. - * - * @return BLE_SUCCESS Or appropriate error code indicating reason for failure. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from SecurityManager directly. A former - * call to ble.getLinkSecurity(...) should be replaced with - * ble.securityManager().getLinkSecurity(...). - */ - ble_error_t getLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::LinkSecurityStatus_t *securityStatusP) { - return securityManager().getLinkSecurity(connectionHandle, securityStatusP); - } - - /** - * Delete all peer device context and all related bonding information from - * the database within the security manager. - * - * @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure. - * @retval BLE_ERROR_INVALID_STATE If the API is called without module initialization and/or - * application registration. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from SecurityManager directly. A former - * call to ble.purgeAllBondingState() should be replaced with - * ble.securityManager().purgeAllBondingState(). - */ - ble_error_t purgeAllBondingState(void) { - return securityManager().purgeAllBondingState(); - } - - /** - * Setup a callback for timeout events. Refer to Gap::TimeoutSource_t for - * possible event types. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from GattServer directly. A former call - * to ble.onTimeout(callback) should be replaced with - * ble.gap().onTimeout(callback). - */ - void onTimeout(Gap::TimeoutEventCallback_t timeoutCallback) { - gap().onTimeout(timeoutCallback); - } - - /** - * Setup a callback for connection events. Refer to Gap::ConnectionEventCallback_t. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from GattServer directly. A former call - * to ble.onConnection(callback) should be replaced with - * ble.gap().onConnection(callback). - */ - void onConnection(Gap::ConnectionEventCallback_t connectionCallback) { - gap().onConnection(connectionCallback); - } - - /** - * Used to setup a callback for GAP disconnection. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from GattServer directly. A former call - * to ble.onDisconnection(callback) should be replaced with - * ble.gap().onDisconnection(callback). - */ - void onDisconnection(Gap::DisconnectionEventCallback_t disconnectionCallback) { - gap().onDisconnection(disconnectionCallback); - } - - /** - * Append to a chain of callbacks to be invoked upon disconnection; these - * callbacks receive no context and are therefore different from the - * onDisconnection callback. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from GattServer directly. A former call - * to ble.addToDisconnectionCallchain(...) should be replaced with - * ble.gap().addToDisconnectionCallchain(...). - */ - template<typename T> - void addToDisconnectionCallChain(T *tptr, void (T::*mptr)(void)) { - gap().addToDisconnectionCallChain(tptr, mptr); - } - - /** - * Radio Notification is a feature that enables ACTIVE and INACTIVE - * (nACTIVE) signals from the stack that notify the application when the - * radio is in use. The signal is sent using software interrupt. - * - * The ACTIVE signal is sent before the Radio Event starts. The nACTIVE - * signal is sent at the end of the Radio Event. These signals can be used - * by the application programmer to synchronize application logic with radio - * activity. For example, the ACTIVE signal can be used to shut off external - * devices to manage peak current drawn during periods when the radio is on, - * or to trigger sensor data collection for transmission in the Radio Event. - * - * @param callback - * The application handler to be invoked in response to a radio - * ACTIVE/INACTIVE event. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from GattServer directly. A former call - * to ble.onRadioNotification(...) should be replaced with - * ble.gap().onRadioNotification(...). - */ - void onRadioNotification(Gap::RadioNotificationEventCallback_t callback) { - gap().onRadioNotification(callback); - } - - /** - * Add a callback for the GATT event DATA_SENT (which is triggered when - * updates are sent out by GATT in the form of notifications). - * - * @Note: it is possible to chain together multiple onDataSent callbacks - * (potentially from different modules of an application) to receive updates - * to characteristics. - * - * @Note: it is also possible to setup a callback into a member function of - * some object. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from GattServer directly. A former call - * to ble.onDataSent(...) should be replaced with - * ble.gattServer().onDataSent(...). - */ - void onDataSent(void (*callback)(unsigned count)) { - gattServer().onDataSent(callback); - } - template <typename T> void onDataSent(T * objPtr, void (T::*memberPtr)(unsigned count)) { - gattServer().onDataSent(objPtr, memberPtr); - } - - /** - * Setup a callback for when an attribute has its value updated by or at the - * connected peer. For a peripheral, this callback triggered when the local - * GATT server has an attribute updated by a write command from the peer. - * For a Central, this callback is triggered when a response is received for - * a write request. - * - * @Note: it is possible to chain together multiple onDataWritten callbacks - * (potentially from different modules of an application) to receive updates - * to characteristics. Many services, such as DFU and UART add their own - * onDataWritten callbacks behind the scenes to trap interesting events. - * - * @Note: it is also possible to setup a callback into a member function of - * some object. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from GattServer directly. A former call - * to ble.onDataWritten(...) should be replaced with - * ble.gattServer().onDataWritten(...). - */ - void onDataWritten(void (*callback)(const GattWriteCallbackParams *eventDataP)) { - gattServer().onDataWritten(callback); - } - template <typename T> void onDataWritten(T * objPtr, void (T::*memberPtr)(const GattWriteCallbackParams *context)) { - gattServer().onDataWritten(objPtr, memberPtr); - } - - /** - * Setup a callback to be invoked on the peripheral when an attribute is - * being read by a remote client. - * - * @Note: this functionality may not be available on all underlying stacks. - * You could use GattCharacteristic::setReadAuthorizationCallback() as an - * alternative. - * - * @Note: it is possible to chain together multiple onDataRead callbacks - * (potentially from different modules of an application) to receive updates - * to characteristics. Services may add their own onDataRead callbacks - * behind the scenes to trap interesting events. - * - * @Note: it is also possible to setup a callback into a member function of - * some object. - * - * @return BLE_ERROR_NOT_IMPLEMENTED if this functionality isn't available; - * else BLE_ERROR_NONE. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from GattServer directly. A former call - * to ble.onDataRead(...) should be replaced with - * ble.gattServer().onDataRead(...). - */ - ble_error_t onDataRead(void (*callback)(const GattReadCallbackParams *eventDataP)) { - return gattServer().onDataRead(callback); - } - template <typename T> ble_error_t onDataRead(T * objPtr, void (T::*memberPtr)(const GattReadCallbackParams *context)) { - return gattServer().onDataRead(objPtr, memberPtr); - } - - /** - * Setup a callback for when notifications/indications are enabled for a - * characteristic on the local GattServer. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from GattServer directly. A former call - * to ble.onUpdatesEnabled(callback) should be replaced with - * ble.gattServer().onUpdatesEnabled(callback). - */ - void onUpdatesEnabled(GattServer::EventCallback_t callback) { - gattServer().onUpdatesEnabled(callback); - } - - /** - * Setup a callback for when notifications/indications are disabled for a - * characteristic on the local GattServer. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from GattServer directly. A former call - * to ble.onUpdatesEnabled(callback) should be replaced with - * ble.gattServer().onUpdatesEnabled(callback). - */ - void onUpdatesDisabled(GattServer::EventCallback_t callback) { - gattServer().onUpdatesDisabled(callback); - } - - /** - * Setup a callback for when the GATT server receives a response for an - * indication event sent previously. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from GattServer directly. A former call - * to ble.onConfirmationReceived(callback) should be replaced with - * ble.gattServer().onConfirmationReceived(callback). - */ - void onConfirmationReceived(GattServer::EventCallback_t callback) { - gattServer().onConfirmationReceived(callback); - } - - /** - * Setup a callback for when the security setup procedure (key generation - * and exchange) for a link has started. This will be skipped for bonded - * devices. The callback is passed in parameters received from the peer's - * security request: bool allowBonding, bool requireMITM, and - * SecurityIOCapabilities_t. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from SecurityManager directly. A former - * call to ble.onSecuritySetupInitiated(callback) should be replaced with - * ble.securityManager().onSecuritySetupInitiated(callback). - */ - void onSecuritySetupInitiated(SecurityManager::SecuritySetupInitiatedCallback_t callback) { - securityManager().onSecuritySetupInitiated(callback); - } - - /** - * Setup a callback for when the security setup procedure (key generation - * and exchange) for a link has completed. This will be skipped for bonded - * devices. The callback is passed in the success/failure status of the - * security setup procedure. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from SecurityManager directly. A former - * call to ble.onSecuritySetupCompleted(callback) should be replaced with - * ble.securityManager().onSecuritySetupCompleted(callback). - */ - void onSecuritySetupCompleted(SecurityManager::SecuritySetupCompletedCallback_t callback) { - securityManager().onSecuritySetupCompleted(callback); - } - - /** - * Setup a callback for when a link with the peer is secured. For bonded - * devices, subsequent reconnections with bonded peer will result only in - * this callback when the link is secured and setup procedures will not - * occur unless the bonding information is either lost or deleted on either - * or both sides. The callback is passed in a SecurityManager::SecurityMode_t according - * to the level of security in effect for the secured link. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from SecurityManager directly. A former - * call to ble.onLinkSecured(callback) should be replaced with - * ble.securityManager().onLinkSecured(callback). - */ - void onLinkSecured(SecurityManager::LinkSecuredCallback_t callback) { - securityManager().onLinkSecured(callback); - } - - /** - * Setup a callback for successful bonding; i.e. that link-specific security - * context is stored persistently for a peer device. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from SecurityManager directly. A former - * call to ble.onSecurityContextStored(callback) should be replaced with - * ble.securityManager().onSecurityContextStored(callback). - */ - void onSecurityContextStored(SecurityManager::HandleSpecificEvent_t callback) { - securityManager().onSecurityContextStored(callback); - } - - /** - * Setup a callback for when the passkey needs to be displayed on a - * peripheral with DISPLAY capability. This happens when security is - * configured to prevent Man-In-The-Middle attacks, and a PIN (or passkey) - * needs to be exchanged between the peers to authenticate the connection - * attempt. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from SecurityManager directly. A former - * call to ble.onPasskeyDisplay(callback) should be replaced with - * ble.securityManager().onPasskeyDisplay(callback). - */ - void onPasskeyDisplay(SecurityManager::PasskeyDisplayCallback_t callback) { - return securityManager().onPasskeyDisplay(callback); - } - -public: - BLE() : transport(createBLEInstance()) { - /* empty */ - } - -private: - BLEInstanceBase *const transport; /* the device specific backend */ -}; - -typedef BLE BLEDevice; /* DEPRECATED. This type alias is retained for the sake of compatibility with older - * code. Will be dropped at some point soon.*/ - -#endif // ifndef __BLE_H__ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/public/BLEDevice.h Fri Jun 19 15:53:28 2015 +0100 @@ -0,0 +1,1090 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BLE_DEVICE__ +#define __BLE_DEVICE__ + +#include "blecommon.h" +#include "Gap.h" +#include "GattServer.h" +#include "GapScanningParams.h" +#include "BLEDeviceInstanceBase.h" + +/** + * The base class used to abstract away BLE capable radio transceivers or SOCs, + * to enable this BLE API to work with any radio transparently. + */ +class BLEDevice +{ +public: + /** + * Initialize the BLE controller. This should be called before using + * anything else in the BLE_API. + * + * init() hands control to the underlying BLE module to accomplish + * initialization. This initialization may tacitly depend on other hardware + * setup (such as clocks or power-modes) which happens early on during + * system startup. It may not be safe to call init() from global static + * context where ordering is compiler specific and can't be guaranteed--it + * is safe to call BLEDevice::init() from within main(). + */ + ble_error_t init(); + + ble_error_t reset(void); + + /** + * Purge the BLE stack of GATT and GAP state. init() must be called afterwards to re-instate services and GAP state. + */ + ble_error_t shutdown(void); + + /* GAP specific APIs */ +public: + /** + * Set the BTLE MAC address and type. + * @return BLE_ERROR_NONE on success. + */ + ble_error_t setAddress(Gap::AddressType_t type, const Gap::Address_t address); + + /** + * Fetch the BTLE MAC address and type. + * @return BLE_ERROR_NONE on success. + */ + ble_error_t getAddress(Gap::AddressType_t *typeP, Gap::Address_t address); + + /** + * @param[in] advType + * The GAP advertising mode to use for this device. Valid + * values are defined in AdvertisingType: + * + * \par ADV_NON_CONNECTABLE_UNDIRECTED + * All connections to the peripheral device will be refused. + * + * \par ADV_CONNECTABLE_DIRECTED + * Only connections from a pre-defined central device will be + * accepted. + * + * \par ADV_CONNECTABLE_UNDIRECTED + * Any central device can connect to this peripheral. + * + * \par ADV_SCANNABLE_UNDIRECTED + * Include support for Scan Response payloads. + * + * \par + * See Bluetooth Core Specification 4.0 (Vol. 3), Part C, + * Section 9.3 and Core Specification 4.0 (Vol. 6), Part B, + * Section 2.3.1 for further information on GAP connection + * modes + */ + void setAdvertisingType(GapAdvertisingParams::AdvertisingType); + + /** + * @param[in] interval + * Advertising interval in units of milliseconds. Advertising + * is disabled if interval is 0. If interval is smaller than + * the minimum supported value, then the minimum supported + * value is used instead. + * + * \par + * Decreasing this value will allow central devices to detect + * your peripheral faster at the expense of more power being + * used by the radio due to the higher data transmit rate. + * + * \par + * This field must be set to 0 if connectionMode is equal + * to ADV_CONNECTABLE_DIRECTED + * + * \par + * See Bluetooth Core Specification, Vol 3., Part C, + * Appendix A for suggested advertising intervals. + * + * @Note: [WARNING] This API previously used 0.625ms as the unit for its + * 'interval' argument. That required an explicit conversion from + * milliseconds using Gap::MSEC_TO_GAP_DURATION_UNITS(). This conversion is + * no longer required as the new units are milliseconds. Any application + * code depending on the old semantics would need to be updated accordingly. + */ + void setAdvertisingInterval(uint16_t interval); + + /** + * @return Minimum Advertising interval in milliseconds. + */ + uint16_t getMinAdvertisingInterval(void) const; + /** + * @return Minimum Advertising interval in milliseconds for non connectible mode. + */ + uint16_t getMinNonConnectableAdvertisingInterval(void) const; + /** + * @return Maximum Advertising interval in milliseconds. + */ + uint16_t getMaxAdvertisingInterval(void) const; + + /** + * @param[in] timeout + * Advertising timeout between 0x1 and 0x3FFF (1 and 16383) + * in seconds. Enter 0 to disable the advertising timeout. + */ + void setAdvertisingTimeout(uint16_t timeout); + + /** + * Please refer to the APIs above. + */ + void setAdvertisingParams(const GapAdvertisingParams &advParams); + + /** + * @return Read back advertising parameters. Useful for storing and + * restoring parameters rapidly. + */ + const GapAdvertisingParams &getAdvertisingParams(void) const; + + /** + * This API is typically used as an internal helper to udpate the transport + * backend with advertising data before starting to advertise. It may also + * be explicity used to dynamically reset the accumulated advertising + * payload and scanResponse; to do this, the application can clear and re- + * accumulate a new advertising payload (and scanResponse) before using this + * API. + */ + ble_error_t setAdvertisingPayload(void); + + /** + * Set advertising data using object. + */ + ble_error_t setAdvertisingData(const GapAdvertisingData &advData); + + /** + * @return Read back advertising data. Useful for storing and + * restoring payload. + */ + const GapAdvertisingData &getAdvertisingData(void) const; + + /** + * Reset any advertising payload prepared from prior calls to + * accumulateAdvertisingPayload(). + * + * Note: This should be followed by a call to setAdvertisingPayload() or + * startAdvertising() before the update takes effect. + */ + void clearAdvertisingPayload(void); + + /** + * Accumulate an AD structure in the advertising payload. Please note that + * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used + * as an additional 31 bytes if the advertising payload proves to be too + * small. + * + * @param flags + * The flags to be added. Multiple flags may be specified in + * combination. + */ + ble_error_t accumulateAdvertisingPayload(uint8_t flags); + + /** + * Accumulate an AD structure in the advertising payload. Please note that + * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used + * as an additional 31 bytes if the advertising payload proves to be too + * small. + * + * @param app + * The appearance of the peripheral. + */ + ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::Appearance app); + + /** + * Accumulate an AD structure in the advertising payload. Please note that + * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used + * as an additional 31 bytes if the advertising payload proves to be too + * small. + * + * @param app + * The max transmit power to be used by the controller. This is + * only a hint. + */ + ble_error_t accumulateAdvertisingPayloadTxPower(int8_t power); + + /** + * Accumulate a variable length byte-stream as an AD structure in the + * advertising payload. Please note that the payload is limited to 31 bytes. + * The SCAN_RESPONSE message may be used as an additional 31 bytes if the + * advertising payload proves to be too small. + * + * @param type The type which describes the variable length data. + * @param data data bytes. + * @param len length of data. + */ + ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len); + + /** + * Accumulate a variable length byte-stream as an AD structure in the + * scanResponse payload. + * + * @param type The type which describes the variable length data. + * @param data data bytes. + * @param len length of data. + */ + ble_error_t accumulateScanResponse(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len); + + /** + * Reset any scan response prepared from prior calls to + * accumulateScanResponse(). + * + * Note: This should be followed by a call to setAdvertisingPayload() or + * startAdvertising() before the update takes effect. + */ + void clearScanResponse(void); + + /** + * Start advertising (GAP Discoverable, Connectable modes, Broadcast + * Procedure). + */ + ble_error_t startAdvertising(void); + + /** + * Stop advertising (GAP Discoverable, Connectable modes, Broadcast + * Procedure). + */ + ble_error_t stopAdvertising(void); + + /** + * Setup parameters for GAP scanning--i.e. observer mode. + * @param interval Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s]. + * @param window Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s]. + * @param timeout Scan timeout (in seconds) between 0x0001 and 0xFFFF, 0x0000 disables timeout. + * @param activeScanning Set to True if active-scanning is required. This is used to fetch the + * scan response from a peer if possible. + * + * The scanning window divided by the interval determines the duty cycle for + * scanning. For example, if the interval is 100ms and the window is 10ms, + * then the controller will scan for 10 percent of the time. It is possible + * to have the interval and window set to the same value. In this case, + * scanning is continuous, with a change of scanning frequency once every + * interval. + * + * Once the scanning parameters have been configured, scanning can be + * enabled by using startScan(). + * + * @Note: The scan interval and window are recommendations to the BLE stack. + */ + ble_error_t setScanParams(uint16_t interval = GapScanningParams::SCAN_INTERVAL_MAX, + uint16_t window = GapScanningParams::SCAN_WINDOW_MAX, + uint16_t timeout = 0, + bool activeScanning = false); + ble_error_t setScanInterval(uint16_t interval); + ble_error_t setScanWindow (uint16_t window); + ble_error_t setScanTimeout (uint16_t timeout); + void setActiveScan (bool activeScanning); + + /** + * Start scanning (Observer Procedure) based on the scan-params currently + * in effect. + * + * @param callback The application callback to be invoked upon receiving + * every advertisement report. Can be passed in as NULL, in which case + * scanning may not be enabled at all. + */ + ble_error_t startScan(void (*callback)(const Gap::AdvertisementCallbackParams_t *params)); + + /** + * Start scanning (Observer Procedure) based on the scan-params currently + * in effect. + * + * @param[in] object + * @param[in] callbackMember + * The above pair of parameters define the callback object + * and member function to receive the advertisement params. + */ + template<typename T> + ble_error_t startScan(T *object, void (T::*memberCallback)(const Gap::AdvertisementCallbackParams_t *params)); + + /** + * Stop scanning. The current scanning parameters remain in effect. + * + * @retval BLE_ERROR_NONE if successfully stopped scanning procedure. + */ + ble_error_t stopScan(void); + + /** + * This call initiates the disconnection procedure, and its completion will + * be communicated to the application with an invocation of the + * onDisconnection callback. + * + * @param reason + * The reason for disconnection to be sent back to the peer. + */ + ble_error_t disconnect(Gap::DisconnectionReason_t reason); + + /* APIs to set GAP callbacks. */ + void onTimeout(Gap::EventCallback_t timeoutCallback); + + void onConnection(Gap::ConnectionEventCallback_t connectionCallback); + /** + * Used to setup a callback for GAP disconnection. + */ + void onDisconnection(Gap::DisconnectionEventCallback_t disconnectionCallback); + + /** + * Append to a chain of callbacks to be invoked upon disconnection; these + * callbacks receive no context and are therefore different from the + * onDisconnection callback. + */ + template<typename T> + void addToDisconnectionCallChain(T *tptr, void (T::*mptr)(void)); + + /** + * Add a callback for the GATT event DATA_SENT (which is triggered when + * updates are sent out by GATT in the form of notifications). + * + * @Note: it is possible to chain together multiple onDataSent callbacks + * (potentially from different modules of an application) to receive updates + * to characteristics. + * + * @Note: it is also possible to setup a callback into a member function of + * some object. + */ + void onDataSent(void (*callback)(unsigned count)); + template <typename T> void onDataSent(T * objPtr, void (T::*memberPtr)(unsigned count)); + + /** + * Setup a callback for when a characteristic has its value updated by a + * client. + * + * @Note: it is possible to chain together multiple onDataWritten callbacks + * (potentially from different modules of an application) to receive updates + * to characteristics. Many services, such as DFU and UART add their own + * onDataWritten callbacks behind the scenes to trap interesting events. + * + * @Note: it is also possible to setup a callback into a member function of + * some object. + */ + void onDataWritten(void (*callback)(const GattCharacteristicWriteCBParams *eventDataP)); + template <typename T> void onDataWritten(T * objPtr, void (T::*memberPtr)(const GattCharacteristicWriteCBParams *context)); + + /** + * Setup a callback for when a characteristic is being read by a client. + * + * @Note: this functionality may not be available on all underlying stacks. + * You could use GattCharacteristic::setReadAuthorizationCallback() as an + * alternative. + * + * @Note: it is possible to chain together multiple onDataRead callbacks + * (potentially from different modules of an application) to receive updates + * to characteristics. Services may add their own onDataRead callbacks + * behind the scenes to trap interesting events. + * + * @Note: it is also possible to setup a callback into a member function of + * some object. + * + * @return BLE_ERROR_NOT_IMPLEMENTED if this functionality isn't available; + * else BLE_ERROR_NONE. + */ + ble_error_t onDataRead(void (*callback)(const GattCharacteristicReadCBParams *eventDataP)); + template <typename T> ble_error_t onDataRead(T * objPtr, void (T::*memberPtr)(const GattCharacteristicReadCBParams *context)); + + void onUpdatesEnabled(GattServer::EventCallback_t callback); + void onUpdatesDisabled(GattServer::EventCallback_t callback); + void onConfirmationReceived(GattServer::EventCallback_t callback); + + /** + * Radio Notification is a feature that enables ACTIVE and INACTIVE + * (nACTIVE) signals from the stack that notify the application when the + * radio is in use. The signal is sent using software interrupt. + * + * The ACTIVE signal is sent before the Radio Event starts. The nACTIVE + * signal is sent at the end of the Radio Event. These signals can be used + * by the application programmer to synchronize application logic with radio + * activity. For example, the ACTIVE signal can be used to shut off external + * devices to manage peak current drawn during periods when the radio is on, + * or to trigger sensor data collection for transmission in the Radio Event. + * + * @param callback + * The application handler to be invoked in response to a radio + * ACTIVE/INACTIVE event. + */ + void onRadioNotification(Gap::RadioNotificationEventCallback_t callback); + + /** + * Add a service declaration to the local server ATT table. Also add the + * characteristics contained within. + */ + ble_error_t addService(GattService &service); + + /** + * Returns the current GAP state of the device using a bitmask which + * describes whether the device is advertising and/or connected. + */ + Gap::GapState_t getGapState(void) const; + + /** + * @param[in/out] lengthP + * input: Length in bytes to be read, + * output: Total length of attribute value upon successful return. + */ + ble_error_t readCharacteristicValue(GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP); + /** + * A version of the same as above with connection handle parameter to allow fetches for connection-specific multivalued attribtues (such as the CCCDs). + */ + ble_error_t readCharacteristicValue(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP); + + /** + * @param localOnly + * Only update the characteristic locally regardless of notify/indicate flags in the CCCD. + */ + ble_error_t updateCharacteristicValue(GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size, bool localOnly = false); + /** + * A version of the same as above with connection handle parameter to allow updates for connection-specific multivalued attribtues (such as the CCCDs). + */ + ble_error_t updateCharacteristicValue(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size, bool localOnly = false); + + /** + * Yield control to the BLE stack or to other tasks waiting for events. This + * is a sleep function which will return when there is an application + * specific interrupt, but the MCU might wake up several times before + * returning (to service the stack). This is not always interchangeable with + * WFE(). + */ + void waitForEvent(void); + + ble_error_t getPreferredConnectionParams(Gap::ConnectionParams_t *params); + ble_error_t setPreferredConnectionParams(const Gap::ConnectionParams_t *params); + ble_error_t updateConnectionParams(Gap::Handle_t handle, const Gap::ConnectionParams_t *params); + + /** + * This call allows the application to get the BLE stack version information. + * + * @return A pointer to a const string representing the version. + * Note: The string is owned by the BLE_API. + */ + const char *getVersion(void); + + /** + * Set the device name characteristic in the GAP service. + * @param deviceName The new value for the device-name. This is a UTF-8 encoded, <b>NULL-terminated</b> string. + */ + ble_error_t setDeviceName(const uint8_t *deviceName); + + /** + * Get the value of the device name characteristic in the GAP service. + * @param[out] deviceName Pointer to an empty buffer where the UTF-8 *non NULL- + * terminated* string will be placed. Set this + * value to NULL in order to obtain the deviceName-length + * from the 'length' parameter. + * + * @param[in/out] lengthP (on input) Length of the buffer pointed to by deviceName; + * (on output) the complete device name length (without the + * null terminator). + * + * @note If the device name is longer than the size of the supplied buffer, + * length will return the complete device name length, + * and not the number of bytes actually returned in deviceName. + * The application may use this information to retry with a suitable buffer size. + * + * Sample use: + * uint8_t deviceName[20]; + * unsigned length = sizeof(deviceName); + * ble.getDeviceName(deviceName, &length); + * if (length < sizeof(deviceName)) { + * deviceName[length] = 0; + * } + * DEBUG("length: %u, deviceName: %s\r\n", length, deviceName); + */ + ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP); + + /** + * Set the appearance characteristic in the GAP service. + * @param[in] appearance The new value for the device-appearance. + */ + ble_error_t setAppearance(uint16_t appearance); + + /** + * Set the appearance characteristic in the GAP service. + * @param[out] appearance The new value for the device-appearance. + */ + ble_error_t getAppearance(uint16_t *appearanceP); + + /** + * Set the radio's transmit power. + * @param[in] txPower Radio transmit power in dBm. + */ + ble_error_t setTxPower(int8_t txPower); + + /** + * Query the underlying stack for permitted arguments for setTxPower(). + * + * @param[out] valueArrayPP + * Out parameter to receive the immutable array of Tx values. + * @param[out] countP + * Out parameter to receive the array's size. + */ + void getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP); + + /** + * Enable the BLE stack's Security Manager. The Security Manager implements + * the actual cryptographic algorithms and protocol exchanges that allow two + * devices to securely exchange data and privately detect each other. + * Calling this API is a prerequisite for encryption and pairing (bonding). + * + * @param[in] enableBonding Allow for bonding. + * @param[in] requireMITM Require protection for man-in-the-middle attacks. + * @param[in] iocaps To specify IO capabilities of this peripheral, + * such as availability of a display or keyboard to + * support out-of-band exchanges of security data. + * @param[in] passkey To specify a static passkey. + * + * @return BLE_ERROR_NONE on success. + */ + ble_error_t initializeSecurity(bool enableBonding = true, + bool requireMITM = true, + Gap::SecurityIOCapabilities_t iocaps = Gap::IO_CAPS_NONE, + const Gap::Passkey_t passkey = NULL); + + /** + * Setup a callback for when the security setup procedure (key generation + * and exchange) for a link has started. This will be skipped for bonded + * devices. The callback is passed in parameters received from the peer's + * security request: bool allowBonding, bool requireMITM, and + * SecurityIOCapabilities_t. + */ + void onSecuritySetupInitiated(Gap::SecuritySetupInitiatedCallback_t callback); + + /** + * Setup a callback for when the security setup procedure (key generation + * and exchange) for a link has completed. This will be skipped for bonded + * devices. The callback is passed in the success/failure status of the + * security setup procedure. + */ + void onSecuritySetupCompleted(Gap::SecuritySetupCompletedCallback_t callback); + + /** + * Setup a callback for when a link with the peer is secured. For bonded + * devices, subsequent reconnections with bonded peer will result only in + * this callback when the link is secured and setup procedures will not + * occur unless the bonding information is either lost or deleted on either + * or both sides. The callback is passed in a Gap::SecurityMode_t according + * to the level of security in effect for the secured link. + */ + void onLinkSecured(Gap::LinkSecuredCallback_t callback); + + /** + * Setup a callback for successful bonding; i.e. that link-specific security + * context is stored persistently for a peer device. + */ + void onSecurityContextStored(Gap::HandleSpecificEvent_t callback); + + /** + * Setup a callback for when the passkey needs to be displayed on a + * peripheral with DISPLAY capability. This happens when security is + * configured to prevent Man-In-The-Middle attacks, and a PIN (or passkey) + * needs to be exchanged between the peers to authenticate the connection + * attempt. + */ + void onPasskeyDisplay(Gap::PasskeyDisplayCallback_t callback); + + /** + * Get the security status of a connection. + * + * @param[in] connectionHandle Handle to identify the connection. + * @param[out] securityStatusP security status. + * + * @return BLE_SUCCESS Or appropriate error code indicating reason for failure. + */ + ble_error_t getLinkSecurity(Gap::Handle_t connectionHandle, Gap::LinkSecurityStatus_t *securityStatusP); + + /** + * Delete all peer device context and all related bonding information from + * the database within the security manager. + * + * @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure. + * @retval BLE_ERROR_INVALID_STATE If the API is called without module initialization and/or + * application registration. + */ + ble_error_t purgeAllBondingState(void); + +public: + BLEDevice() : transport(createBLEDeviceInstance()), advParams(), advPayload(), scanResponse(), needToSetAdvPayload(true), scanningParams() { + advPayload.clear(); + scanResponse.clear(); + } + +private: + BLEDeviceInstanceBase *const transport; /* the device specific backend */ + + GapAdvertisingParams advParams; + GapAdvertisingData advPayload; + GapAdvertisingData scanResponse; + + /* Accumulation of AD structures in the advertisement payload should + * eventually result in a call to the target's setAdvertisingData() before + * the server begins advertising. This flag marks the status of the pending update.*/ + bool needToSetAdvPayload; + + GapScanningParams scanningParams; +}; + +/* BLEDevice methods. Most of these simply forward the calls to the underlying + * transport.*/ + +inline ble_error_t +BLEDevice::reset(void) +{ + return transport->reset(); +} + +inline ble_error_t +BLEDevice::shutdown(void) +{ + clearAdvertisingPayload(); + return transport->shutdown(); +} + +inline ble_error_t +BLEDevice::setAddress(Gap::AddressType_t type, const Gap::Address_t address) +{ + return transport->getGap().setAddress(type, address); +} + +inline ble_error_t +BLEDevice::getAddress(Gap::AddressType_t *typeP, Gap::Address_t address) +{ + return transport->getGap().getAddress(typeP, address); +} + +inline void +BLEDevice::setAdvertisingType(GapAdvertisingParams::AdvertisingType advType) +{ + advParams.setAdvertisingType(advType); +} + +inline void +BLEDevice::setAdvertisingInterval(uint16_t interval) +{ + if (interval == 0) { + stopAdvertising(); + } else if (interval < getMinAdvertisingInterval()) { + interval = getMinAdvertisingInterval(); + } + advParams.setInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(interval)); +} + +inline uint16_t +BLEDevice::getMinAdvertisingInterval(void) const { + return transport->getGap().getMinAdvertisingInterval(); +} + +inline uint16_t +BLEDevice::getMinNonConnectableAdvertisingInterval(void) const { + return transport->getGap().getMinNonConnectableAdvertisingInterval(); +} + +inline uint16_t +BLEDevice::getMaxAdvertisingInterval(void) const { + return transport->getGap().getMaxAdvertisingInterval(); +} + +inline void +BLEDevice::setAdvertisingTimeout(uint16_t timeout) +{ + advParams.setTimeout(timeout); +} + +inline void +BLEDevice::setAdvertisingParams(const GapAdvertisingParams &newAdvParams) +{ + advParams = newAdvParams; +} + +inline const GapAdvertisingParams & +BLEDevice::getAdvertisingParams(void) const +{ + return advParams; +} + +inline void +BLEDevice::clearAdvertisingPayload(void) +{ + needToSetAdvPayload = true; + advPayload.clear(); +} + +inline ble_error_t +BLEDevice::accumulateAdvertisingPayload(uint8_t flags) +{ + needToSetAdvPayload = true; + return advPayload.addFlags(flags); +} + +inline ble_error_t +BLEDevice::accumulateAdvertisingPayload(GapAdvertisingData::Appearance app) +{ + needToSetAdvPayload = true; + transport->getGap().setAppearance(app); + return advPayload.addAppearance(app); +} + +inline ble_error_t +BLEDevice::accumulateAdvertisingPayloadTxPower(int8_t txPower) +{ + needToSetAdvPayload = true; + return advPayload.addTxPower(txPower); +} + +inline ble_error_t +BLEDevice::accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) +{ + needToSetAdvPayload = true; + if (type == GapAdvertisingData::COMPLETE_LOCAL_NAME) { + transport->getGap().setDeviceName(data); + } + return advPayload.addData(type, data, len); +} + +inline ble_error_t +BLEDevice::accumulateScanResponse(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) +{ + needToSetAdvPayload = true; + return scanResponse.addData(type, data, len); +} + +inline void +BLEDevice::clearScanResponse(void) +{ + needToSetAdvPayload = true; + scanResponse.clear(); +} + +inline ble_error_t +BLEDevice::setAdvertisingPayload(void) { + needToSetAdvPayload = false; + return transport->getGap().setAdvertisingData(advPayload, scanResponse); +} + +inline ble_error_t +BLEDevice::setAdvertisingData(const GapAdvertisingData& newPayload) +{ + advPayload = newPayload; + + return setAdvertisingPayload(); +} + +inline const GapAdvertisingData & +BLEDevice::getAdvertisingData(void) const { + return advPayload; +} + +inline ble_error_t +BLEDevice::startAdvertising(void) +{ + ble_error_t rc; + if ((rc = transport->getGattServer().initializeGATTDatabase()) != BLE_ERROR_NONE) { + return rc; + } + if (needToSetAdvPayload) { + if ((rc = setAdvertisingPayload()) != BLE_ERROR_NONE) { + return rc; + } + } + + return transport->getGap().startAdvertising(advParams); +} + +inline ble_error_t +BLEDevice::stopAdvertising(void) +{ + return transport->getGap().stopAdvertising(); +} + +inline ble_error_t +BLEDevice::setScanParams(uint16_t interval, uint16_t window, uint16_t timeout, bool activeScanning) { + ble_error_t rc; + if (((rc = scanningParams.setInterval(interval)) == BLE_ERROR_NONE) && + ((rc = scanningParams.setWindow(window)) == BLE_ERROR_NONE) && + ((rc = scanningParams.setTimeout(timeout)) == BLE_ERROR_NONE)) { + scanningParams.setActiveScanning(activeScanning); + return BLE_ERROR_NONE; + } + + return rc; +} + +inline ble_error_t +BLEDevice::setScanInterval(uint16_t interval) { + return scanningParams.setInterval(interval); +} + +inline ble_error_t +BLEDevice::setScanWindow(uint16_t window) { + return scanningParams.setWindow(window); +} + +inline ble_error_t +BLEDevice::setScanTimeout(uint16_t timeout) { + return scanningParams.setTimeout(timeout); +} + +inline void +BLEDevice::setActiveScan(bool activeScanning) { + return scanningParams.setActiveScanning(activeScanning); +} + +inline ble_error_t +BLEDevice::startScan(void (*callback)(const Gap::AdvertisementCallbackParams_t *params)) { + return transport->getGap().startScan(scanningParams, callback); +} + +template<typename T> +inline ble_error_t +BLEDevice::startScan(T *object, void (T::*memberCallback)(const Gap::AdvertisementCallbackParams_t *params)) { + return transport->getGap().startScan(scanningParams, object, memberCallback); +} + +inline ble_error_t +BLEDevice::stopScan(void) { + return transport->getGap().stopScan(); +} + +inline ble_error_t +BLEDevice::disconnect(Gap::DisconnectionReason_t reason) +{ + return transport->getGap().disconnect(reason); +} + +inline void +BLEDevice::onTimeout(Gap::EventCallback_t timeoutCallback) +{ + transport->getGap().setOnTimeout(timeoutCallback); +} + +inline void +BLEDevice::onConnection(Gap::ConnectionEventCallback_t connectionCallback) +{ + transport->getGap().setOnConnection(connectionCallback); +} + +inline void +BLEDevice::onDisconnection(Gap::DisconnectionEventCallback_t disconnectionCallback) +{ + transport->getGap().setOnDisconnection(disconnectionCallback); +} + +template<typename T> +inline void +BLEDevice::addToDisconnectionCallChain(T *tptr, void (T::*mptr)(void)) { + transport->getGap().addToDisconnectionCallChain(tptr, mptr); +} + +inline void +BLEDevice::onDataSent(void (*callback)(unsigned count)) { + transport->getGattServer().setOnDataSent(callback); +} + +template <typename T> inline void +BLEDevice::onDataSent(T *objPtr, void (T::*memberPtr)(unsigned count)) { + transport->getGattServer().setOnDataSent(objPtr, memberPtr); +} + +inline void +BLEDevice::onDataWritten(void (*callback)(const GattCharacteristicWriteCBParams *eventDataP)) { + transport->getGattServer().setOnDataWritten(callback); +} + +template <typename T> inline void +BLEDevice::onDataWritten(T *objPtr, void (T::*memberPtr)(const GattCharacteristicWriteCBParams *context)) { + transport->getGattServer().setOnDataWritten(objPtr, memberPtr); +} + +inline ble_error_t +BLEDevice::onDataRead(void (*callback)(const GattCharacteristicReadCBParams *eventDataP)) { + return transport->getGattServer().setOnDataRead(callback); +} + +template <typename T> inline ble_error_t +BLEDevice::onDataRead(T *objPtr, void (T::*memberPtr)(const GattCharacteristicReadCBParams *context)) { + return transport->getGattServer().setOnDataRead(objPtr, memberPtr); +} + +inline void +BLEDevice::onUpdatesEnabled(GattServer::EventCallback_t callback) +{ + transport->getGattServer().setOnUpdatesEnabled(callback); +} + +inline void +BLEDevice::onUpdatesDisabled(GattServer::EventCallback_t callback) +{ + transport->getGattServer().setOnUpdatesDisabled(callback); +} + +inline void +BLEDevice::onConfirmationReceived(GattServer::EventCallback_t callback) +{ + transport->getGattServer().setOnConfirmationReceived(callback); +} + +inline void +BLEDevice::onRadioNotification(Gap::RadioNotificationEventCallback_t callback) +{ + transport->getGap().setOnRadioNotification(callback); +} + +inline ble_error_t +BLEDevice::addService(GattService &service) +{ + return transport->getGattServer().addService(service); +} + +inline Gap::GapState_t +BLEDevice::getGapState(void) const +{ + return transport->getGap().getState(); +} + +inline ble_error_t BLEDevice::readCharacteristicValue(GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP) +{ + return transport->getGattServer().readValue(attributeHandle, buffer, lengthP); +} + +inline ble_error_t BLEDevice::readCharacteristicValue(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP) +{ + return transport->getGattServer().readValue(connectionHandle, attributeHandle, buffer, lengthP); +} + +inline ble_error_t +BLEDevice::updateCharacteristicValue(GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size, bool localOnly) +{ + return transport->getGattServer().updateValue(attributeHandle, const_cast<uint8_t *>(value), size, localOnly); +} + +inline ble_error_t +BLEDevice::updateCharacteristicValue(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size, bool localOnly) +{ + return transport->getGattServer().updateValue(connectionHandle, attributeHandle, const_cast<uint8_t *>(value), size, localOnly); +} + +inline void +BLEDevice::waitForEvent(void) +{ + transport->waitForEvent(); +} + +inline ble_error_t +BLEDevice::getPreferredConnectionParams(Gap::ConnectionParams_t *params) +{ + return transport->getGap().getPreferredConnectionParams(params); +} + +inline ble_error_t +BLEDevice::setPreferredConnectionParams(const Gap::ConnectionParams_t *params) +{ + return transport->getGap().setPreferredConnectionParams(params); +} + +inline ble_error_t +BLEDevice::updateConnectionParams(Gap::Handle_t handle, const Gap::ConnectionParams_t *params) { + return transport->getGap().updateConnectionParams(handle, params); +} + +inline const char * +BLEDevice::getVersion(void) +{ + return transport->getVersion(); +} + +inline ble_error_t +BLEDevice::setDeviceName(const uint8_t *deviceName) +{ + return transport->getGap().setDeviceName(deviceName); +} + +inline ble_error_t +BLEDevice::getDeviceName(uint8_t *deviceName, unsigned *lengthP) +{ + return transport->getGap().getDeviceName(deviceName, lengthP); +} + +inline ble_error_t +BLEDevice::setAppearance(uint16_t appearance) +{ + return transport->getGap().setAppearance(appearance); +} + +inline ble_error_t +BLEDevice::getAppearance(uint16_t *appearanceP) +{ + return transport->getGap().getAppearance(appearanceP); +} + +inline ble_error_t +BLEDevice::setTxPower(int8_t txPower) +{ + return transport->setTxPower(txPower); +} + +inline void +BLEDevice::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) +{ + transport->getPermittedTxPowerValues(valueArrayPP, countP); +} + +inline ble_error_t +BLEDevice::initializeSecurity(bool enableBonding, + bool requireMITM, + Gap::SecurityIOCapabilities_t iocaps, + const Gap::Passkey_t passkey) +{ + return transport->initializeSecurity(enableBonding, requireMITM, iocaps, passkey); +} + +inline void +BLEDevice::onSecuritySetupInitiated(Gap::SecuritySetupInitiatedCallback_t callback) +{ + transport->getGap().setOnSecuritySetupInitiated(callback); +} + +inline void +BLEDevice::onSecuritySetupCompleted(Gap::SecuritySetupCompletedCallback_t callback) +{ + transport->getGap().setOnSecuritySetupCompleted(callback); +} + +inline void +BLEDevice::onLinkSecured(Gap::LinkSecuredCallback_t callback) +{ + transport->getGap().setOnLinkSecured(callback); +} + +inline void +BLEDevice::onSecurityContextStored(Gap::HandleSpecificEvent_t callback) +{ + transport->getGap().setOnSecurityContextStored(callback); +} + +inline void +BLEDevice::onPasskeyDisplay(Gap::PasskeyDisplayCallback_t callback) +{ + return transport->getGap().setOnPasskeyDisplay(callback); +} + +inline ble_error_t +BLEDevice::getLinkSecurity(Gap::Handle_t connectionHandle, Gap::LinkSecurityStatus_t *securityStatusP) +{ + return transport->getGap().getLinkSecurity(connectionHandle, securityStatusP); +} + +inline ble_error_t +BLEDevice::purgeAllBondingState(void) +{ + return transport->getGap().purgeAllBondingState(); +} + +#endif // ifndef __BLE_DEVICE__ \ No newline at end of file
--- a/public/DiscoveredCharacteristic.h Fri Jun 19 15:53:06 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,191 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __DISCOVERED_CHARACTERISTIC_H__ -#define __DISCOVERED_CHARACTERISTIC_H__ - -#include "UUID.h" -#include "Gap.h" -#include "GattAttribute.h" -#include "GattClient.h" - -/** - * Structure for holding information about the service and the characteristics - * found during the discovery process. - */ -class DiscoveredCharacteristic { -public: - struct Properties_t { - uint8_t _broadcast :1; /**< Broadcasting of the value permitted. */ - uint8_t _read :1; /**< Reading the value permitted. */ - uint8_t _writeWoResp :1; /**< Writing the value with Write Command permitted. */ - uint8_t _write :1; /**< Writing the value with Write Request permitted. */ - uint8_t _notify :1; /**< Notications of the value permitted. */ - uint8_t _indicate :1; /**< Indications of the value permitted. */ - uint8_t _authSignedWrite :1; /**< Writing the value with Signed Write Command permitted. */ - - public: - bool broadcast(void) const {return _broadcast; } - bool read(void) const {return _read; } - bool writeWoResp(void) const {return _writeWoResp; } - bool write(void) const {return _write; } - bool notify(void) const {return _notify; } - bool indicate(void) const {return _indicate; } - bool authSignedWrite(void) const {return _authSignedWrite;} - - private: - operator uint8_t() const; /* disallow implicit conversion into an integer */ - operator unsigned() const; /* disallow implicit conversion into an integer */ - }; - - /** - * Structure for holding information about the service and the characteristics - * found during the discovery process. - */ - struct DiscoveredDescriptor { - GattAttribute::Handle_t handle; /**< Descriptor Handle. */ - UUID uuid; /**< Descriptor UUID. */ - }; - - /** - * Callback type for when a characteristic descriptor is found during descriptor- - * discovery. The receiving function is passed in a pointer to a - * DiscoveredDescriptor object which will remain valid for the lifetime - * of the callback. Memory for this object is owned by the BLE_API eventing - * framework. The application can safely make a persistent shallow-copy of - * this object in order to work with the characteristic beyond the callback. - */ - typedef void (*DescriptorCallback_t)(const DiscoveredDescriptor *); - - /** - * Initiate (or continue) a read for the value attribute, optionally at a - * given offset. If the Characteristic or Descriptor to be read is longer - * than ATT_MTU - 1, this function must be called multiple times with - * appropriate offset to read the complete value. - * - * @return BLE_ERROR_NONE if a read has been initiated, else - * BLE_ERROR_INVALID_STATE if some internal state about the connection is invalid, or - * BLE_STACK_BUSY if some client procedure already in progress, or - * BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's properties. - */ - ble_error_t read(uint16_t offset = 0) const; - - /** - * Perform a write without response procedure. - * - * @param length - * The amount of data being written. - * @param value - * The bytes being written. - * - * @note It is important to note that a write without response will generate - * an onDataSent() callback when the packet has been transmitted. There - * will be a BLE-stack specific limit to the number of pending - * writeWoResponse operations; the user may want to use the onDataSent() - * callback for flow-control. - * - * @retval BLE_ERROR_NONE Successfully started the Write procedure, else - * BLE_ERROR_INVALID_STATE if some internal state about the connection is invalid, or - * BLE_STACK_BUSY if some client procedure already in progress, or - * BLE_ERROR_NO_MEM if there are no available buffers left to process the request, or - * BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's properties. - */ - ble_error_t writeWoResponse(uint16_t length, const uint8_t *value) const; - - /** - * Initiate a GATT Characteristic Descriptor Discovery procedure for descriptors within this characteristic. - * - * @param callback - * @param matchingUUID - * filter for descriptors. Defaults to wildcard which will discover all descriptors. - * - * @return BLE_ERROR_NONE if descriptor discovery is launched successfully; else an appropriate error. - */ - ble_error_t discoverDescriptors(DescriptorCallback_t callback, const UUID &matchingUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) const; - - /** - * Perform a write procedure. - * - * @param length - * The amount of data being written. - * @param value - * The bytes being written. - * - * @note It is important to note that a write will generate - * an onDataWritten() callback when the peer acknowledges the request. - * - * @retval BLE_ERROR_NONE Successfully started the Write procedure, else - * BLE_ERROR_INVALID_STATE if some internal state about the connection is invalid, or - * BLE_STACK_BUSY if some client procedure already in progress, or - * BLE_ERROR_NO_MEM if there are no available buffers left to process the request, or - * BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's properties. - */ - ble_error_t write(uint16_t length, const uint8_t *value) const; - - static void setupOnDataRead(GattClient::ReadCallback_t callback) { - onDataReadCallback = callback; - } - - static void setupOnDataWrite(GattClient::WriteCallback_t callback) { - onDataWriteCallback = callback; - } - - void setupLongUUID(UUID::LongUUIDBytes_t longUUID) { - uuid.setupLong(longUUID); - } - -public: - UUID::ShortUUIDBytes_t getShortUUID(void) const { - return uuid.getShortUUID(); - } - - const Properties_t& getProperties(void) const { - return props; - } - - const GattAttribute::Handle_t& getDeclHandle(void) const { - return declHandle; - } - const GattAttribute::Handle_t& getValueHandle(void) const { - return valueHandle; - } - -public: - DiscoveredCharacteristic() : gattc(NULL), - uuid(UUID::ShortUUIDBytes_t(0)), - props(), - declHandle(GattAttribute::INVALID_HANDLE), - valueHandle(GattAttribute::INVALID_HANDLE) { - /* empty */ - } - -protected: - GattClient *gattc; - -protected: - UUID uuid; - Properties_t props; - GattAttribute::Handle_t declHandle; - GattAttribute::Handle_t valueHandle; - - Gap::Handle_t connHandle; - -public: - static GattClient::ReadCallback_t onDataReadCallback; - static GattClient::WriteCallback_t onDataWriteCallback; -}; - -#endif /*__DISCOVERED_CHARACTERISTIC_H__*/ \ No newline at end of file
--- a/public/DiscoveredService.h Fri Jun 19 15:53:06 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __DISCOVERED_SERVICE_H__ -#define __DISCOVERED_SERVICE_H__ - -#include "UUID.h" -#include "GattAttribute.h" - -/**@brief Type for holding information about the service and the characteristics found during - * the discovery process. - */ -class DiscoveredService { -public: - void setup(UUID uuidIn, GattAttribute::Handle_t startHandleIn, GattAttribute::Handle_t endHandleIn) { - uuid = uuidIn; - startHandle = startHandleIn; - endHandle = endHandleIn; - } - - void setup(GattAttribute::Handle_t startHandleIn, GattAttribute::Handle_t endHandleIn) { - startHandle = startHandleIn; - endHandle = endHandleIn; - } - - void setupLongUUID(UUID::LongUUIDBytes_t longUUID) { - uuid.setupLong(longUUID); - } - -public: - const UUID &getUUID(void) const { - return uuid; - } - - const GattAttribute::Handle_t& getStartHandle(void) const { - return startHandle; - } - const GattAttribute::Handle_t& getEndHandle(void) const { - return endHandle; - } - -public: - DiscoveredService() : uuid(UUID::ShortUUIDBytes_t(0)), - startHandle(GattAttribute::INVALID_HANDLE), - endHandle(GattAttribute::INVALID_HANDLE) { - /* empty */ - } - -private: - DiscoveredService(const DiscoveredService &); - -private: - UUID uuid; /**< UUID of the service. */ - GattAttribute::Handle_t startHandle; /**< Service Handle Range. */ - GattAttribute::Handle_t endHandle; /**< Service Handle Range. */ -}; - -#endif /*__DISCOVERED_SERVICE_H__*/ \ No newline at end of file
--- a/public/Gap.h Fri Jun 19 15:53:06 2015 +0100 +++ b/public/Gap.h Fri Jun 19 15:53:28 2015 +0100 @@ -19,17 +19,13 @@ #include "GapAdvertisingData.h" #include "GapAdvertisingParams.h" -#include "GapScanningParams.h" #include "GapEvents.h" #include "CallChain.h" #include "FunctionPointerWithContext.h" using namespace mbed; -/* Forward declarations for classes which will only be used for pointers or references in the following. */ -class GapAdvertisingParams; -class GapScanningParams; -class GapAdvertisingData; +class GapScanningParams; /* forward declaration */ class Gap { public: @@ -45,11 +41,11 @@ typedef uint8_t Address_t[ADDR_LEN]; /* 48-bit address, LSB format. */ typedef Address_t address_t; /* @Note: deprecated. Use Address_t instead. */ - enum TimeoutSource_t { - TIMEOUT_SRC_ADVERTISING = 0x00, /**< Advertising timeout. */ - TIMEOUT_SRC_SECURITY_REQUEST = 0x01, /**< Security request timeout. */ - TIMEOUT_SRC_SCAN = 0x02, /**< Scanning timeout. */ - TIMEOUT_SRC_CONN = 0x03, /**< Connection timeout. */ + enum AdvertisementType_t { + ADV_IND = 0x00, /**< Connectable undirected. */ + ADV_DIRECT_IND = 0x01, /**< Connectable directed. */ + ADV_SCAN_IND = 0x02, /**< Scannable undirected. */ + ADV_NONCONN_IND = 0x03, /**< Non connectable undirected. */ }; /** @@ -60,12 +56,9 @@ * transport library. */ enum DisconnectionReason_t { - CONNECTION_TIMEOUT = 0x08, - REMOTE_USER_TERMINATED_CONNECTION = 0x13, - REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES = 0x14, /**< Remote Device Terminated Connection due to low resources.*/ - REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF = 0x15, /**< Remote Device Terminated Connection due to power off. */ - LOCAL_HOST_TERMINATED_CONNECTION = 0x16, - CONN_INTERVAL_UNACCEPTABLE = 0x3B, + REMOTE_USER_TERMINATED_CONNECTION = 0x13, + LOCAL_HOST_TERMINATED_CONNECTION = 0x16, + CONN_INTERVAL_UNACCEPTABLE = 0x3B, }; /* Describes the current state of the device (more than one bit can be set) */ @@ -74,7 +67,7 @@ unsigned connected : 1; /**< peripheral is connected to a central */ }; - typedef uint16_t Handle_t; /* Type for connection handle. */ + typedef uint16_t Handle_t; typedef struct { uint16_t minConnectionInterval; /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ @@ -83,49 +76,58 @@ uint16_t connectionSupervisionTimeout; /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/ } ConnectionParams_t; - enum Role_t { - PERIPHERAL = 0x1, /**< Peripheral Role. */ - CENTRAL = 0x2, /**< Central Role. */ + enum SecurityMode_t { + SECURITY_MODE_NO_ACCESS, + SECURITY_MODE_ENCRYPTION_OPEN_LINK, /**< require no protection, open link. */ + SECURITY_MODE_ENCRYPTION_NO_MITM, /**< require encryption, but no MITM protection. */ + SECURITY_MODE_ENCRYPTION_WITH_MITM, /**< require encryption and MITM protection. */ + SECURITY_MODE_SIGNED_NO_MITM, /**< require signing or encryption, but no MITM protection. */ + SECURITY_MODE_SIGNED_WITH_MITM, /**< require signing or encryption, and MITM protection. */ + }; + + /** + * @brief Defines possible security status/states. + * + * @details Defines possible security status/states of a link when requested by getLinkSecurity(). + */ + enum LinkSecurityStatus_t { + NOT_ENCRYPTED, /**< The link is not secured. */ + ENCRYPTION_IN_PROGRESS, /**< Link security is being established.*/ + ENCRYPTED /**< The link is secure.*/ }; - struct AdvertisementCallbackParams_t { - Address_t peerAddr; - int8_t rssi; - bool isScanResponse; - GapAdvertisingParams::AdvertisingType_t type; - uint8_t advertisingDataLen; - const uint8_t *advertisingData; + enum SecurityIOCapabilities_t { + IO_CAPS_DISPLAY_ONLY = 0x00, /**< Display Only. */ + IO_CAPS_DISPLAY_YESNO = 0x01, /**< Display and Yes/No entry. */ + IO_CAPS_KEYBOARD_ONLY = 0x02, /**< Keyboard Only. */ + IO_CAPS_NONE = 0x03, /**< No I/O capabilities. */ + IO_CAPS_KEYBOARD_DISPLAY = 0x04, /**< Keyboard and Display. */ }; - typedef FunctionPointerWithContext<const AdvertisementCallbackParams_t *> AdvertisementReportCallback_t; - - struct ConnectionCallbackParams_t { - Handle_t handle; - Role_t role; - AddressType_t peerAddrType; - Address_t peerAddr; - AddressType_t ownAddrType; - Address_t ownAddr; - const ConnectionParams_t *connectionParams; - ConnectionCallbackParams_t(Handle_t handleIn, - Role_t roleIn, - AddressType_t peerAddrTypeIn, - const uint8_t *peerAddrIn, - AddressType_t ownAddrTypeIn, - const uint8_t *ownAddrIn, - const ConnectionParams_t *connectionParamsIn) : - handle(handleIn), - role(roleIn), - peerAddrType(peerAddrTypeIn), - peerAddr(), - ownAddrType(ownAddrTypeIn), - ownAddr(), - connectionParams(connectionParamsIn) { - memcpy(peerAddr, peerAddrIn, ADDR_LEN); - memcpy(ownAddr, ownAddrIn, ADDR_LEN); - } + enum SecurityCompletionStatus_t { + SEC_STATUS_SUCCESS = 0x00, /**< Procedure completed with success. */ + SEC_STATUS_TIMEOUT = 0x01, /**< Procedure timed out. */ + SEC_STATUS_PDU_INVALID = 0x02, /**< Invalid PDU received. */ + SEC_STATUS_PASSKEY_ENTRY_FAILED = 0x81, /**< Passkey entry failed (user canceled or other). */ + SEC_STATUS_OOB_NOT_AVAILABLE = 0x82, /**< Out of Band Key not available. */ + SEC_STATUS_AUTH_REQ = 0x83, /**< Authentication requirements not met. */ + SEC_STATUS_CONFIRM_VALUE = 0x84, /**< Confirm value failed. */ + SEC_STATUS_PAIRING_NOT_SUPP = 0x85, /**< Pairing not supported. */ + SEC_STATUS_ENC_KEY_SIZE = 0x86, /**< Encryption key size. */ + SEC_STATUS_SMP_CMD_UNSUPPORTED = 0x87, /**< Unsupported SMP command. */ + SEC_STATUS_UNSPECIFIED = 0x88, /**< Unspecified reason. */ + SEC_STATUS_REPEATED_ATTEMPTS = 0x89, /**< Too little time elapsed since last attempt. */ + SEC_STATUS_INVALID_PARAMS = 0x8A, /**< Invalid parameters. */ }; + /** + * Declaration of type containing a passkey to be used during pairing. This + * is passed into initializeSecurity() to specify a pre-programmed passkey + * for authentication instead of generating a random one. + */ + static const unsigned PASSKEY_LEN = 6; + typedef uint8_t Passkey_t[PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */ + static const uint16_t UNIT_1_25_MS = 1250; /**< Number of microseconds in 1.25 milliseconds. */ static const uint16_t UNIT_0_625_MS = 625; /**< Number of microseconds in 0.625 milliseconds. */ static uint16_t MSEC_TO_GAP_DURATION_UNITS(uint32_t durationInMillis) { @@ -138,564 +140,59 @@ return (gapUnits * UNIT_0_625_MS) / 1000; } - typedef void (*TimeoutEventCallback_t)(TimeoutSource_t source); - typedef void (*ConnectionEventCallback_t)(const ConnectionCallbackParams_t *params); + typedef void (*EventCallback_t)(void); + typedef void (*ConnectionEventCallback_t)(Handle_t, + AddressType_t peerAddrType, const Address_t peerAddr, + AddressType_t ownAddrType, const Address_t ownAddr, + const ConnectionParams_t *); + typedef void (*HandleSpecificEvent_t)(Handle_t handle); typedef void (*DisconnectionEventCallback_t)(Handle_t, DisconnectionReason_t); - typedef void (*RadioNotificationEventCallback_t)(bool radio_active); /* gets passed true for ACTIVE; false for INACTIVE. */ - - /* - * The following functions are meant to be overridden in the platform-specific sub-class. - */ -public: - /** - * Set the BTLE MAC address and type. Please note that the address format is - * LSB (least significant byte first). Please refer to Address_t. - * - * @return BLE_ERROR_NONE on success. - */ - virtual ble_error_t setAddress(AddressType_t type, const Address_t address) { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ - } - - /** - * Fetch the BTLE MAC address and type. - * - * @return BLE_ERROR_NONE on success. - */ - virtual ble_error_t getAddress(AddressType_t *typeP, Address_t address) { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ - } - - /** - * @return Minimum Advertising interval in milliseconds. - */ - virtual uint16_t getMinAdvertisingInterval(void) const { - return 0; /* default implementation; override this API if this capability is supported. */ - } - - /** - * @return Minimum Advertising interval in milliseconds for non-connectible mode. - */ - virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const { - return 0; /* default implementation; override this API if this capability is supported. */ - } - - /** - * @return Maximum Advertising interval in milliseconds. - */ - virtual uint16_t getMaxAdvertisingInterval(void) const { - return 0xFFFF; /* default implementation; override this API if this capability is supported. */ - } - - virtual ble_error_t stopAdvertising(void) { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ - } - - /** - * Stop scanning. The current scanning parameters remain in effect. - * - * @retval BLE_ERROR_NONE if successfully stopped scanning procedure. - */ - virtual ble_error_t stopScan() { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ - } - - /** - * Create a connection (GAP Link Establishment). - * - * @param peerAddr - * 48-bit address, LSB format. - * @param peerAddrType - * Address type of the peer. - * @param connectionParams - * Connection parameters. - * @param scanParams - * Paramters to be used while scanning for the peer. - * @return BLE_ERROR_NONE if connection establishment procedure is started - * successfully. The connectionCallback (if set) will be invoked upon - * a connection event. - */ - virtual ble_error_t connect(const Address_t peerAddr, - Gap::AddressType_t peerAddrType, - const ConnectionParams_t *connectionParams, - const GapScanningParams *scanParams) { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ - } - - /** - * This call initiates the disconnection procedure, and its completion will - * be communicated to the application with an invocation of the - * disconnectionCallback. - * - * @param reason - * The reason for disconnection to be sent back to the peer. - */ - virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason) { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ - } - - /** - * This call initiates the disconnection procedure, and its completion will - * be communicated to the application with an invocation of the - * disconnectionCallback. - * - * @param reason - * The reason for disconnection to be sent back to the peer. - * - * @note: this version of disconnect() doesn't take a connection handle. It - * will work reliably only for stacks which are limited to a single - * connection. This API should be considered *deprecated* in favour of the - * altertive which takes a connection handle. It will be dropped in the future. - */ - virtual ble_error_t disconnect(DisconnectionReason_t reason) { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ - } + typedef void (*RadioNotificationEventCallback_t) (bool radio_active); /* gets passed true for ACTIVE; false for INACTIVE. */ + typedef void (*SecuritySetupInitiatedCallback_t)(Handle_t, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps); + typedef void (*SecuritySetupCompletedCallback_t)(Handle_t, SecurityCompletionStatus_t status); + typedef void (*LinkSecuredCallback_t)(Handle_t handle, SecurityMode_t securityMode); + typedef void (*PasskeyDisplayCallback_t)(Handle_t handle, const Passkey_t passkey); - /** - * Get the GAP peripheral preferred connection parameters. These are the - * defaults that the peripheral would like to have in a connection. The - * choice of the connection parameters is eventually up to the central. - * - * @param[out] params - * The structure where the parameters will be stored. Memory - * for this is owned by the caller. - * - * @return BLE_ERROR_NONE if the parameters were successfully filled into - * the given structure pointed to by params. - */ - virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params) { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ - } - - /** - * Set the GAP peripheral preferred connection parameters. These are the - * defaults that the peripheral would like to have in a connection. The - * choice of the connection parameters is eventually up to the central. - * - * @param[in] params - * The structure containing the desired parameters. - */ - virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params) { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ - } - - /** - * Update connection parameters while in the peripheral role. - * @details In the peripheral role, this will send the corresponding L2CAP request to the connected peer and wait for - * the central to perform the procedure. - * @param[in] handle - * Connection Handle - * @param[in] params - * Pointer to desired connection parameters. If NULL is provided on a peripheral role, - * the parameters in the PPCP characteristic of the GAP service will be used instead. - */ - virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params) { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ - } - - /** - * Set the device name characteristic in the GAP service. - * @param[in] deviceName - * The new value for the device-name. This is a UTF-8 encoded, <b>NULL-terminated</b> string. - */ - virtual ble_error_t setDeviceName(const uint8_t *deviceName) { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ - } + struct AdvertisementCallbackParams_t { + Address_t peerAddr; + int8_t rssi; + bool isScanResponse; + AdvertisementType_t type; + uint8_t advertisingDataLen; + const uint8_t *advertisingData; + }; + typedef FunctionPointerWithContext<const AdvertisementCallbackParams_t *> AdvertisementReportCallback_t; - /** - * Get the value of the device name characteristic in the GAP service. - * @param[out] deviceName - * Pointer to an empty buffer where the UTF-8 *non NULL- - * terminated* string will be placed. Set this - * value to NULL in order to obtain the deviceName-length - * from the 'length' parameter. - * - * @param[in/out] lengthP - * (on input) Length of the buffer pointed to by deviceName; - * (on output) the complete device name length (without the - * null terminator). - * - * @note If the device name is longer than the size of the supplied buffer, - * length will return the complete device name length, and not the - * number of bytes actually returned in deviceName. The application may - * use this information to retry with a suitable buffer size. - */ - virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP) { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ - } - - /** - * Set the appearance characteristic in the GAP service. - * @param[in] appearance - * The new value for the device-appearance. - */ - virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance) { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ - } - - /** - * Get the appearance characteristic in the GAP service. - * @param[out] appearance - * The new value for the device-appearance. - */ - virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP) { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ - } - - /** - * Set the radio's transmit power. - * @param[in] txPower Radio transmit power in dBm. - */ - virtual ble_error_t setTxPower(int8_t txPower) { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ - } - - /** - * Query the underlying stack for permitted arguments for setTxPower(). - * - * @param[out] valueArrayPP - * Out parameter to receive the immutable array of Tx values. - * @param[out] countP - * Out parameter to receive the array's size. - */ - virtual void getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) { - *countP = 0; /* default implementation; override this API if this capability is supported. */ - } - -protected: - /* Override the following in the underlying adaptation layer to provide the functionality of scanning. */ - virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams) { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ - } - - /* - * APIs with non-virtual implementations. - */ -public: - /** - * Returns the current GAP state of the device using a bitmask which - * describes whether the device is advertising and/or connected. - */ - GapState_t getState(void) const { - return state; - } - - /** - * Set the GAP advertising mode to use for this device. - */ - void setAdvertisingType(GapAdvertisingParams::AdvertisingType_t advType) { - _advParams.setAdvertisingType(advType); - } + friend class BLEDevice; - /** - * @param[in] interval - * Advertising interval in units of milliseconds. Advertising - * is disabled if interval is 0. If interval is smaller than - * the minimum supported value, then the minimum supported - * value is used instead. This minimum value can be discovered - * using getMinAdvertisingInterval(). - * - * This field must be set to 0 if connectionMode is equal - * to ADV_CONNECTABLE_DIRECTED. - * - * @note: Decreasing this value will allow central devices to detect a - * peripheral faster at the expense of more power being used by the radio - * due to the higher data transmit rate. - * - * @note: This API is now *deprecated* and will be dropped in the future. - * You should use the parallel API from Gap directly. A former call to - * ble.setAdvertisingInterval(...) should now be achieved using - * ble.gap().setAdvertisingInterval(...). - * - * @Note: [WARNING] This API previously used 0.625ms as the unit for its - * 'interval' argument. That required an explicit conversion from - * milliseconds using Gap::MSEC_TO_GAP_DURATION_UNITS(). This conversion is - * no longer required as the new units are milliseconds. Any application - * code depending on the old semantics would need to be updated accordingly. - */ - void setAdvertisingInterval(uint16_t interval) { - if (interval == 0) { - stopAdvertising(); - } else if (interval < getMinAdvertisingInterval()) { - interval = getMinAdvertisingInterval(); - } - _advParams.setInterval(MSEC_TO_ADVERTISEMENT_DURATION_UNITS(interval)); - } - - /** - * @param[in] timeout - * Advertising timeout (in seconds) between 0x1 and 0x3FFF (1 - * and 16383). Use 0 to disable the advertising timeout. - */ - void setAdvertisingTimeout(uint16_t timeout) { - _advParams.setTimeout(timeout); - } - - /** - * Start advertising. - */ - ble_error_t startAdvertising(void) { - setAdvertisingData(); /* update the underlying stack */ - return startAdvertising(_advParams); - } - - /** - * Reset any advertising payload prepared from prior calls to - * accumulateAdvertisingPayload(). This automatically propagates the re- - * initialized adv payload to the underlying stack. - * - * Note: This should be followed by a call to setAdvertisingPayload() or - * startAdvertising() before the update takes effect. - */ - void clearAdvertisingPayload(void) { - _advPayload.clear(); - setAdvertisingData(); - } - - /** - * Accumulate an AD structure in the advertising payload. Please note that - * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used - * as an additional 31 bytes if the advertising payload proves to be too - * small. - * - * @param[in] flags - * The flags to be added. Please refer to - * GapAdvertisingData::Flags for valid flags. Multiple - * flags may be specified in combination. - */ - ble_error_t accumulateAdvertisingPayload(uint8_t flags) { - ble_error_t rc; - if ((rc = _advPayload.addFlags(flags)) != BLE_ERROR_NONE) { - return rc; - } - - return setAdvertisingData(); - } - - /** - * Accumulate an AD structure in the advertising payload. Please note that - * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used - * as an additional 31 bytes if the advertising payload proves to be too - * small. - * - * @param app - * The appearance of the peripheral. - */ - ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::Appearance app) { - setAppearance(app); - - ble_error_t rc; - if ((rc = _advPayload.addAppearance(app)) != BLE_ERROR_NONE) { - return rc; - } - - return setAdvertisingData(); - } - - /** - * Accumulate an AD structure in the advertising payload. Please note that - * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used - * as an additional 31 bytes if the advertising payload proves to be too - * small. - * - * @param app - * The max transmit power to be used by the controller. This is - * only a hint. - */ - ble_error_t accumulateAdvertisingPayloadTxPower(int8_t power) { - ble_error_t rc; - if ((rc = _advPayload.addTxPower(power)) != BLE_ERROR_NONE) { - return rc; - } - - return setAdvertisingData(); - } - - /** - * Accumulate a variable length byte-stream as an AD structure in the - * advertising payload. Please note that the payload is limited to 31 bytes. - * The SCAN_RESPONSE message may be used as an additional 31 bytes if the - * advertising payload proves to be too small. - * - * @param type The type which describes the variable length data. - * @param data data bytes. - * @param len length of data. - */ - ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) { - if (type == GapAdvertisingData::COMPLETE_LOCAL_NAME) { - setDeviceName(data); - } - - ble_error_t rc; - if ((rc = _advPayload.addData(type, data, len)) != BLE_ERROR_NONE) { - return rc; - } - - return setAdvertisingData(); - } +private: + /* These functions must be defined in the sub-class */ + virtual ble_error_t setAddress(AddressType_t type, const Address_t address) = 0; + virtual ble_error_t getAddress(AddressType_t *typeP, Address_t address) = 0; + virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &) = 0; + virtual ble_error_t startAdvertising(const GapAdvertisingParams &) = 0; + virtual ble_error_t stopAdvertising(void) = 0; + virtual ble_error_t stopScan() = 0; + virtual uint16_t getMinAdvertisingInterval(void) const = 0; + virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const = 0; + virtual uint16_t getMaxAdvertisingInterval(void) const = 0; + virtual ble_error_t disconnect(DisconnectionReason_t reason) = 0; + virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params) = 0; + virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params) = 0; + virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params) = 0; - /** - * Setup a particular, user-constructed advertisement payload for the - * underlying stack. It would be uncommon for this API to be used directly; - * there are other APIs to build an advertisement payload (see above). - */ - ble_error_t setAdvertisingPayload(const GapAdvertisingData &payload) { - _advPayload = payload; - return setAdvertisingData(); - } - - /** - * @return Read back advertising data. Useful for storing and - * restoring payload. - */ - const GapAdvertisingData &getAdvertisingPayload(void) const { - return _advPayload; - } - - /** - * Accumulate a variable length byte-stream as an AD structure in the - * scanResponse payload. - * - * @param[in] type The type which describes the variable length data. - * @param[in] data data bytes. - * @param[in] len length of data. - */ - ble_error_t accumulateScanResponse(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) { - ble_error_t rc; - if ((rc = _scanResponse.addData(type, data, len)) != BLE_ERROR_NONE) { - return rc; - } - - return setAdvertisingData(); - } - - /** - * Reset any scan response prepared from prior calls to - * accumulateScanResponse(). - * - * Note: This should be followed by a call to setAdvertisingPayload() or - * startAdvertising() before the update takes effect. - */ - void clearScanResponse(void) { - _scanResponse.clear(); - setAdvertisingData(); - } + virtual ble_error_t purgeAllBondingState(void) = 0; + virtual ble_error_t getLinkSecurity(Handle_t connectionHandle, LinkSecurityStatus_t *securityStatusP) = 0; - /** - * Setup parameters for GAP scanning--i.e. observer mode. - * @param[in] interval - * Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s]. - * @param[in] window - * Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s]. - * @param[in] timeout - * Scan timeout (in seconds) between 0x0001 and 0xFFFF, 0x0000 disables timeout. - * @param[in] activeScanning - * Set to True if active-scanning is required. This is used to fetch the - * scan response from a peer if possible. - * - * The scanning window divided by the interval determines the duty cycle for - * scanning. For example, if the interval is 100ms and the window is 10ms, - * then the controller will scan for 10 percent of the time. It is possible - * to have the interval and window set to the same value. In this case, - * scanning is continuous, with a change of scanning frequency once every - * interval. - * - * Once the scanning parameters have been configured, scanning can be - * enabled by using startScan(). - * - * @Note: The scan interval and window are recommendations to the BLE stack. - */ - ble_error_t setScanParams(uint16_t interval = GapScanningParams::SCAN_INTERVAL_MAX, - uint16_t window = GapScanningParams::SCAN_WINDOW_MAX, - uint16_t timeout = 0, - bool activeScanning = false) { - ble_error_t rc; - if (((rc = _scanningParams.setInterval(interval)) == BLE_ERROR_NONE) && - ((rc = _scanningParams.setWindow(window)) == BLE_ERROR_NONE) && - ((rc = _scanningParams.setTimeout(timeout)) == BLE_ERROR_NONE)) { - _scanningParams.setActiveScanning(activeScanning); - return BLE_ERROR_NONE; - } - - return rc; - } + virtual ble_error_t setDeviceName(const uint8_t *deviceName) = 0; + virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP) = 0; + virtual ble_error_t setAppearance(uint16_t appearance) = 0; + virtual ble_error_t getAppearance(uint16_t *appearanceP) = 0; - /** - * Setup the scanInterval parameter for GAP scanning--i.e. observer mode. - * @param[in] interval - * Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s]. - * - * The scanning window divided by the interval determines the duty cycle for - * scanning. For example, if the interval is 100ms and the window is 10ms, - * then the controller will scan for 10 percent of the time. It is possible - * to have the interval and window set to the same value. In this case, - * scanning is continuous, with a change of scanning frequency once every - * interval. - * - * Once the scanning parameters have been configured, scanning can be - * enabled by using startScan(). - */ - ble_error_t setScanInterval(uint16_t interval) { - return _scanningParams.setInterval(interval); - } - - /** - * Setup the scanWindow parameter for GAP scanning--i.e. observer mode. - * @param[in] window - * Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s]. - * - * The scanning window divided by the interval determines the duty cycle for - * scanning. For example, if the interval is 100ms and the window is 10ms, - * then the controller will scan for 10 percent of the time. It is possible - * to have the interval and window set to the same value. In this case, - * scanning is continuous, with a change of scanning frequency once every - * interval. - * - * Once the scanning parameters have been configured, scanning can be - * enabled by using startScan(). - */ - ble_error_t setScanWindow(uint16_t window) { - return _scanningParams.setWindow(window); - } - - /** - * Setup parameters for GAP scanning--i.e. observer mode. - * @param[in] timeout - * Scan timeout (in seconds) between 0x0001 and 0xFFFF, 0x0000 disables timeout. - * - * Once the scanning parameters have been configured, scanning can be - * enabled by using startScan(). - */ - ble_error_t setScanTimeout(uint16_t timeout) { - return _scanningParams.setTimeout(timeout); - } - - /** - * Setup parameters for GAP scanning--i.e. observer mode. - * @param[in] activeScanning - * Set to True if active-scanning is required. This is used to fetch the - * scan response from a peer if possible. - * - * Once the scanning parameters have been configured, scanning can be - * enabled by using startScan(). - */ - void setActiveScanning(bool activeScanning) { - _scanningParams.setActiveScanning(activeScanning); - } - - /** - * Start scanning (Observer Procedure) based on the parameters currently in - * effect. - * - * @param[in] callback - * The application specific callback to be invoked upon - * receiving every advertisement report. This can be passed in - * as NULL, in which case scanning may not be enabled at all. - */ - ble_error_t startScan(void (*callback)(const AdvertisementCallbackParams_t *params)) { + ble_error_t startScan(const GapScanningParams &scanningParams, void (*callback)(const AdvertisementCallbackParams_t *params)) { ble_error_t err = BLE_ERROR_NONE; if (callback) { - if ((err = startRadioScan(_scanningParams)) == BLE_ERROR_NONE) { + if ((err = startRadioScan(scanningParams)) == BLE_ERROR_NONE) { onAdvertisementReport.attach(callback); } } @@ -703,14 +200,11 @@ return err; } - /** - * Same as above, but this takes an (object, method) pair for a callback. - */ template<typename T> - ble_error_t startScan(T *object, void (T::*callbackMember)(const AdvertisementCallbackParams_t *params)) { + ble_error_t startScan(const GapScanningParams &scanningParams, T *object, void (T::*callbackMember)(const AdvertisementCallbackParams_t *params)) { ble_error_t err = BLE_ERROR_NONE; if (object && callbackMember) { - if ((err = startRadioScan(_scanningParams)) == BLE_ERROR_NONE) { + if ((err = startRadioScan(scanningParams)) == BLE_ERROR_NONE) { onAdvertisementReport.attach(object, callbackMember); } } @@ -718,133 +212,144 @@ return err; } -private: - ble_error_t setAdvertisingData(void) { - return setAdvertisingData(_advPayload, _scanResponse); - } - -private: - virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &) = 0; - virtual ble_error_t startAdvertising(const GapAdvertisingParams &) = 0; - -public: - /** - * Accessors to read back currently active advertising params. - */ - GapAdvertisingParams &getAdvertisingParams(void) { - return _advParams; - } - const GapAdvertisingParams &getAdvertisingParams(void) const { - return _advParams; - } +protected: + virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams) = 0; - /** - * Setup a particular, user-constructed set of advertisement parameters for - * the underlying stack. It would be uncommon for this API to be used - * directly; there are other APIs to tweak advertisement parameters - * individually. - */ - void setAdvertisingParams(const GapAdvertisingParams &newParams) { - _advParams = newParams; - } - - /* Event callback handlers. */ -public: - /** - * Setup a callback for timeout events. Refer to TimeoutSource_t for - * possible event types. - */ - void onTimeout(TimeoutEventCallback_t callback) {timeoutCallback = callback;} - - /** - * Setup a callback for connection events. Refer to ConnectionEventCallback_t. - */ - void onConnection(ConnectionEventCallback_t callback) {connectionCallback = callback;} + /* Event callback handlers */ + void setOnTimeout(EventCallback_t callback) {onTimeout = callback;} + void setOnConnection(ConnectionEventCallback_t callback) {onConnection = callback;} /** * Set the application callback for disconnection events. * @param callback * Pointer to the unique callback. */ - void onDisconnection(DisconnectionEventCallback_t callback) {disconnectionCallback = callback;} + void setOnDisconnection(DisconnectionEventCallback_t callback) {onDisconnection = callback;} + + /** + * Set the application callback for radio-notification events. + * @param callback + * Handler to be executed in response to a radio notification event. + */ + virtual void setOnRadioNotification(RadioNotificationEventCallback_t callback) {onRadioNotification = callback;} + + /** + * To indicate that security procedure for link has started. + */ + virtual void setOnSecuritySetupInitiated(SecuritySetupInitiatedCallback_t callback) {onSecuritySetupInitiated = callback;} + + /** + * To indicate that security procedure for link has completed. + */ + virtual void setOnSecuritySetupCompleted(SecuritySetupCompletedCallback_t callback) {onSecuritySetupCompleted = callback;} + + /** + * To indicate that link with the peer is secured. For bonded devices, + * subsequent re-connections with bonded peer will result only in this callback + * when the link is secured and setup procedures will not occur unless the + * bonding information is either lost or deleted on either or both sides. + */ + virtual void setOnLinkSecured(LinkSecuredCallback_t callback) {onLinkSecured = callback;} + + /** + * To indicate that device context is stored persistently. + */ + virtual void setOnSecurityContextStored(HandleSpecificEvent_t callback) {onSecurityContextStored = callback;} + + /** + * To set the callback for when the passkey needs to be displayed on a peripheral with DISPLAY capability. + */ + virtual void setOnPasskeyDisplay(PasskeyDisplayCallback_t callback) {onPasskeyDisplay = callback;} /** * Append to a chain of callbacks to be invoked upon disconnection; these * callbacks receive no context and are therefore different from the - * disconnectionCallback callback. + * onDisconnection callback. * @param callback * function pointer to be invoked upon disconnection; receives no context. + * + * @note the disconnection CallChain should have been merged with + * onDisconnctionCallback; but this was not possible because + * FunctionPointer (which is a building block for CallChain) doesn't + * accept variadic templates. */ template<typename T> void addToDisconnectionCallChain(T *tptr, void (T::*mptr)(void)) {disconnectionCallChain.add(tptr, mptr);} - /** - * Set the application callback for radio-notification events. - * - * Radio Notification is a feature that enables ACTIVE and INACTIVE - * (nACTIVE) signals from the stack that notify the application when the - * radio is in use. The signal is sent using software interrupt. - * - * The ACTIVE signal is sent before the Radio Event starts. The nACTIVE - * signal is sent at the end of the Radio Event. These signals can be used - * by the application programmer to synchronize application logic with radio - * activity. For example, the ACTIVE signal can be used to shut off external - * devices to manage peak current drawn during periods when the radio is on, - * or to trigger sensor data collection for transmission in the Radio Event. - * - * @param callback - * The application handler to be invoked in response to a radio - * ACTIVE/INACTIVE event. - */ - virtual void onRadioNotification(RadioNotificationEventCallback_t callback) {radioNotificationCallback = callback;} +private: + GapState_t getState(void) const { + return state; + } protected: Gap() : - _advParams(), - _advPayload(), - _scanningParams(), - _scanResponse(), state(), - timeoutCallback(NULL), - connectionCallback(NULL), - disconnectionCallback(NULL), - radioNotificationCallback(), + onTimeout(NULL), + onConnection(NULL), + onDisconnection(NULL), + onRadioNotification(), + onSecuritySetupInitiated(), + onSecuritySetupCompleted(), + onLinkSecured(), + onSecurityContextStored(), + onPasskeyDisplay(), onAdvertisementReport(), disconnectionCallChain() { - _advPayload.clear(); - _scanResponse.clear(); + /* empty */ } - /* Entry points for the underlying stack to report events back to the user. */ public: - void processConnectionEvent(Handle_t handle, - Role_t role, - AddressType_t peerAddrType, - const Address_t peerAddr, - AddressType_t ownAddrType, - const Address_t ownAddr, - const ConnectionParams_t *connectionParams) { + void processConnectionEvent(Handle_t handle, AddressType_t peerAddrType, const Address_t peerAddr, AddressType_t ownAddrType, const Address_t ownAddr, const ConnectionParams_t *params) { state.connected = 1; - if (connectionCallback) { - ConnectionCallbackParams_t callbackParams(handle, role, peerAddrType, peerAddr, ownAddrType, ownAddr, connectionParams); - connectionCallback(&callbackParams); + if (onConnection) { + onConnection(handle, peerAddrType, peerAddr, ownAddrType, ownAddr, params); } } void processDisconnectionEvent(Handle_t handle, DisconnectionReason_t reason) { state.connected = 0; - if (disconnectionCallback) { - disconnectionCallback(handle, reason); + if (onDisconnection) { + onDisconnection(handle, reason); } disconnectionCallChain.call(); } - void processAdvertisementReport(const Address_t peerAddr, - int8_t rssi, - bool isScanResponse, - GapAdvertisingParams::AdvertisingType_t type, - uint8_t advertisingDataLen, - const uint8_t *advertisingData) { + void processSecuritySetupInitiatedEvent(Handle_t handle, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps) { + if (onSecuritySetupInitiated) { + onSecuritySetupInitiated(handle, allowBonding, requireMITM, iocaps); + } + } + + void processSecuritySetupCompletedEvent(Handle_t handle, SecurityCompletionStatus_t status) { + if (onSecuritySetupCompleted) { + onSecuritySetupCompleted(handle, status); + } + } + + void processLinkSecuredEvent(Handle_t handle, SecurityMode_t securityMode) { + if (onLinkSecured) { + onLinkSecured(handle, securityMode); + } + } + + void processSecurityContextStoredEvent(Handle_t handle) { + if (onSecurityContextStored) { + onSecurityContextStored(handle); + } + } + + void processPasskeyDisplayEvent(Handle_t handle, const Passkey_t passkey) { + if (onPasskeyDisplay) { + onPasskeyDisplay(handle, passkey); + } + } + + void processAdvertisementReport(const Address_t peerAddr, + int8_t rssi, + bool isScanResponse, + AdvertisementType_t type, + uint8_t advertisingDataLen, + const uint8_t *advertisingData) { AdvertisementCallbackParams_t params; memcpy(params.peerAddr, peerAddr, ADDR_LEN); params.rssi = rssi; @@ -855,25 +360,32 @@ onAdvertisementReport.call(¶ms); } - void processTimeoutEvent(TimeoutSource_t source) { - if (timeoutCallback) { - timeoutCallback(source); + void processEvent(GapEvents::gapEvent_e type) { + switch (type) { + case GapEvents::GAP_EVENT_TIMEOUT: + state.advertising = 0; + if (onTimeout) { + onTimeout(); + } + break; + default: + break; } } protected: - GapAdvertisingParams _advParams; - GapAdvertisingData _advPayload; - GapScanningParams _scanningParams; - GapAdvertisingData _scanResponse; - GapState_t state; protected: - TimeoutEventCallback_t timeoutCallback; - ConnectionEventCallback_t connectionCallback; - DisconnectionEventCallback_t disconnectionCallback; - RadioNotificationEventCallback_t radioNotificationCallback; + EventCallback_t onTimeout; + ConnectionEventCallback_t onConnection; + DisconnectionEventCallback_t onDisconnection; + RadioNotificationEventCallback_t onRadioNotification; + SecuritySetupInitiatedCallback_t onSecuritySetupInitiated; + SecuritySetupCompletedCallback_t onSecuritySetupCompleted; + LinkSecuredCallback_t onLinkSecured; + HandleSpecificEvent_t onSecurityContextStored; + PasskeyDisplayCallback_t onPasskeyDisplay; AdvertisementReportCallback_t onAdvertisementReport; CallChain disconnectionCallChain;
--- a/public/GapAdvertisingData.h Fri Jun 19 15:53:06 2015 +0100 +++ b/public/GapAdvertisingData.h Fri Jun 19 15:53:28 2015 +0100 @@ -17,7 +17,6 @@ #ifndef __GAP_ADVERTISING_DATA_H__ #define __GAP_ADVERTISING_DATA_H__ -#include <stdint.h> #include <string.h> #include "blecommon.h"
--- a/public/GapAdvertisingParams.h Fri Jun 19 15:53:06 2015 +0100 +++ b/public/GapAdvertisingParams.h Fri Jun 19 15:53:28 2015 +0100 @@ -39,22 +39,30 @@ static const unsigned GAP_ADV_PARAMS_INTERVAL_MAX = 0x4000; static const unsigned GAP_ADV_PARAMS_TIMEOUT_MAX = 0x3FFF; + /**************************************************************************/ /*! - * Encapsulates the peripheral advertising modes, which determine how - * the device appears to other central devices in hearing range - */ - enum AdvertisingType_t { + \brief + Encapsulates the peripheral advertising modes, which determine how + the device appears to other central devices in hearing range + + \par + See the following for more information on advertising types: + + \li \c Bluetooth Core Specification 4.0 (Vol. 6), Part B, Section 2.3.1 + \li \c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 9.3 + */ + /**************************************************************************/ + enum AdvertisingType { ADV_CONNECTABLE_UNDIRECTED, /**< Vol 3, Part C, Section 9.3.4 and Vol 6, Part B, Section 2.3.1.1 */ ADV_CONNECTABLE_DIRECTED, /**< Vol 3, Part C, Section 9.3.3 and Vol 6, Part B, Section 2.3.1.2 */ ADV_SCANNABLE_UNDIRECTED, /**< Include support for Scan Response payloads, see Vol 6, Part B, Section 2.3.1.4 */ ADV_NON_CONNECTABLE_UNDIRECTED /**< Vol 3, Part C, Section 9.3.2 and Vol 6, Part B, Section 2.3.1.3 */ }; - typedef enum AdvertisingType_t AdvertisingType; /* deprecated type alias. */ public: - GapAdvertisingParams(AdvertisingType_t advType = ADV_CONNECTABLE_UNDIRECTED, - uint16_t interval = GAP_ADV_PARAMS_INTERVAL_MIN_NONCON, - uint16_t timeout = 0) : _advType(advType), _interval(interval), _timeout(timeout) { + GapAdvertisingParams(AdvertisingType advType = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED, + uint16_t interval = GAP_ADV_PARAMS_INTERVAL_MIN_NONCON, + uint16_t timeout = 0) : _advType(advType), _interval(interval), _timeout(timeout) { /* Interval checks */ if (_advType == ADV_CONNECTABLE_DIRECTED) { /* Interval must be 0 in directed connectable mode */ @@ -86,18 +94,18 @@ } } - AdvertisingType_t getAdvertisingType(void) const {return _advType; } - uint16_t getInterval(void) const {return _interval;} - uint16_t getTimeout(void) const {return _timeout; } + AdvertisingType getAdvertisingType(void) const {return _advType; } + uint16_t getInterval(void) const {return _interval;} + uint16_t getTimeout(void) const {return _timeout; } - void setAdvertisingType(AdvertisingType_t newAdvType) {_advType = newAdvType; } - void setInterval(uint16_t newInterval) {_interval = newInterval;} - void setTimeout(uint16_t newTimeout) {_timeout = newTimeout; } + void setAdvertisingType(AdvertisingType newAdvType) {_advType = newAdvType; } + void setInterval(uint16_t newInterval) {_interval = newInterval;} + void setTimeout(uint16_t newTimeout) {_timeout = newTimeout; } private: - AdvertisingType_t _advType; - uint16_t _interval; - uint16_t _timeout; + AdvertisingType _advType; + uint16_t _interval; + uint16_t _timeout; }; #endif // ifndef __GAP_ADVERTISING_PARAMS_H__ \ No newline at end of file
--- a/public/GapScanningParams.h Fri Jun 19 15:53:06 2015 +0100 +++ b/public/GapScanningParams.h Fri Jun 19 15:53:28 2015 +0100 @@ -17,6 +17,8 @@ #ifndef __GAP_SCANNING_PARAMS_H__ #define __GAP_SCANNING_PARAMS_H__ +#include "Gap.h" + class GapScanningParams { public: static const unsigned SCAN_INTERVAL_MIN = 0x0004; /**< Minimum Scan interval in 625 us units, i.e. 2.5 ms. */ @@ -27,20 +29,58 @@ static const unsigned SCAN_TIMEOUT_MAX = 0xFFFF; /**< Maximum Scan timeout in seconds. */ public: - GapScanningParams(uint16_t interval = SCAN_INTERVAL_MAX, - uint16_t window = SCAN_WINDOW_MAX, - uint16_t timeout = 0, - bool activeScanning = false); - - ble_error_t setInterval(uint16_t newIntervalInMS); + GapScanningParams(uint16_t interval = SCAN_INTERVAL_MAX, + uint16_t window = SCAN_WINDOW_MAX, + uint16_t timeout = 0, + bool activeScanning = false) : _interval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(interval)), + _window(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(window)), + _timeout(timeout), + _activeScanning(activeScanning) { + /* stay within limits */ + if (_interval < SCAN_INTERVAL_MIN) { + _interval = SCAN_INTERVAL_MIN; + } + if (_interval > SCAN_INTERVAL_MAX) { + _interval = SCAN_INTERVAL_MAX; + } + if (_window < SCAN_WINDOW_MIN) { + _window = SCAN_WINDOW_MIN; + } + if (_window > SCAN_WINDOW_MAX) { + _window = SCAN_WINDOW_MAX; + } + } - ble_error_t setWindow(uint16_t newWindowInMS); + ble_error_t setInterval(uint16_t newIntervalInMS) { + uint16_t newInterval = Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(newIntervalInMS); + if ((newInterval >= SCAN_INTERVAL_MIN) && (newInterval < SCAN_INTERVAL_MAX)) { + _interval = newInterval; + return BLE_ERROR_NONE; + } - ble_error_t setTimeout(uint16_t newTimeout); + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } - void setActiveScanning(bool activeScanning); + ble_error_t setWindow(uint16_t newWindowInMS) { + uint16_t newWindow = Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(newWindowInMS); + if ((newWindow >= SCAN_WINDOW_MIN) && (newWindow < SCAN_WINDOW_MAX)) { + _window = newWindow; + return BLE_ERROR_NONE; + } + + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } -public: + ble_error_t setTimeout(uint16_t newTimeout) { + _timeout = newTimeout; + return BLE_ERROR_NONE; + } + + void setActiveScanning(bool activeScanning) { + _activeScanning = activeScanning; + } + + /* @Note: The following return durations in units of 0.625 ms */ uint16_t getInterval(void) const {return _interval;} uint16_t getWindow(void) const {return _window; }
--- a/public/GattAttribute.h Fri Jun 19 15:53:06 2015 +0100 +++ b/public/GattAttribute.h Fri Jun 19 15:53:28 2015 +0100 @@ -17,8 +17,6 @@ #ifndef __GATT_ATTRIBUTE_H__ #define __GATT_ATTRIBUTE_H__ -#include "UUID.h" - class GattAttribute { public: typedef uint16_t Handle_t;
--- a/public/GattCallbackParamTypes.h Fri Jun 19 15:53:06 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __GATT_CALLBACK_PARAM_TYPES_H__ -#define __GATT_CALLBACK_PARAM_TYPES_H__ - -struct GattWriteCallbackParams { - enum WriteOp_t { - OP_INVALID = 0x00, /**< Invalid Operation. */ - OP_WRITE_REQ = 0x01, /**< Write Request. */ - OP_WRITE_CMD = 0x02, /**< Write Command. */ - OP_SIGN_WRITE_CMD = 0x03, /**< Signed Write Command. */ - OP_PREP_WRITE_REQ = 0x04, /**< Prepare Write Request. */ - OP_EXEC_WRITE_REQ_CANCEL = 0x05, /**< Execute Write Request: Cancel all prepared writes. */ - OP_EXEC_WRITE_REQ_NOW = 0x06, /**< Execute Write Request: Immediately execute all prepared writes. */ - }; - - GattAttribute::Handle_t handle; - WriteOp_t writeOp; /**< Type of write operation, */ - uint16_t offset; /**< Offset for the write operation. */ - uint16_t len; - const uint8_t *data; /* @note: data might not persist beyond the callback; make a local copy if needed. */ -}; - -struct GattReadCallbackParams { - GattAttribute::Handle_t handle; - uint16_t offset; /**< Offset for the read operation. */ - uint16_t len; - const uint8_t *data; /* @note: data might not persist beyond the callback; make a local copy if needed. */ -}; - -enum GattAuthCallbackReply_t { - AUTH_CALLBACK_REPLY_SUCCESS = 0x00, /**< Success. */ - AUTH_CALLBACK_REPLY_ATTERR_INVALID_HANDLE = 0x0101, /**< ATT Error: Invalid Attribute Handle. */ - AUTH_CALLBACK_REPLY_ATTERR_READ_NOT_PERMITTED = 0x0102, /**< ATT Error: Read not permitted. */ - AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED = 0x0103, /**< ATT Error: Write not permitted. */ - AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHENTICATION = 0x0105, /**< ATT Error: Authenticated link required. */ - AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET = 0x0107, /**< ATT Error: Offset specified was past the end of the attribute. */ - AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION = 0x0108, /**< ATT Error: Used in ATT as Insufficient Authorisation. */ - AUTH_CALLBACK_REPLY_ATTERR_PREPARE_QUEUE_FULL = 0x0109, /**< ATT Error: Used in ATT as Prepare Queue Full. */ - AUTH_CALLBACK_REPLY_ATTERR_ATTRIBUTE_NOT_FOUND = 0x010A, /**< ATT Error: Used in ATT as Attribute not found. */ - AUTH_CALLBACK_REPLY_ATTERR_ATTRIBUTE_NOT_LONG = 0x010B, /**< ATT Error: Attribute cannot be read or written using read/write blob requests. */ - AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH = 0x010D, /**< ATT Error: Invalid value size. */ - AUTH_CALLBACK_REPLY_ATTERR_INSUF_RESOURCES = 0x0111, /**< ATT Error: Encrypted link required. */ -}; - -struct GattWriteAuthCallbackParams { - GattAttribute::Handle_t handle; - uint16_t offset; /**< Offset for the write operation. */ - uint16_t len; /**< Length of the incoming data. */ - const uint8_t *data; /**< Incoming data, variable length. */ - GattAuthCallbackReply_t authorizationReply; /* This is the out parameter which needs to be set to true by the callback if the - * request is to proceed; false otherwise. */ -}; - -struct GattReadAuthCallbackParams { - GattAttribute::Handle_t handle; - uint16_t offset; /**< Offset for the read operation. */ - uint16_t len; /**< Optional: new length of the outgoing data. */ - uint8_t *data; /**< Optional: new outgoing data. Leave at NULL if data is unchanged. */ - GattAuthCallbackReply_t authorizationReply; /* This is the out parameter which needs to be set to true by the callback if the - * request is to proceed; false otherwise. */ -}; - -#endif /*__GATT_CALLBACK_PARAM_TYPES_H__*/ \ No newline at end of file
--- a/public/GattCharacteristic.h Fri Jun 19 15:53:06 2015 +0100 +++ b/public/GattCharacteristic.h Fri Jun 19 15:53:28 2015 +0100 @@ -18,9 +18,8 @@ #define __GATT_CHARACTERISTIC_H__ #include "Gap.h" -#include "SecurityManager.h" #include "GattAttribute.h" -#include "GattCallbackParamTypes.h" +#include "GattCharacteristicCallbackParams.h" #include "FunctionPointerWithContext.h" class GattCharacteristic { @@ -332,7 +331,7 @@ unsigned numDescriptors = 0) : _valueAttribute(uuid, valuePtr, initialLen, maxLen), _properties(props), - _requiredSecurity(SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK), + _requiredSecurity(Gap::SECURITY_MODE_ENCRYPTION_OPEN_LINK), _descriptors(descriptors), _descriptorCount(numDescriptors), enabledReadAuthorization(false), @@ -348,7 +347,7 @@ * * @param securityMode Can be one of encryption or signing, with or without protection for MITM (man in the middle attacks). */ - void requireSecurity(SecurityManager::SecurityMode_t securityMode) { + void requireSecurity(Gap::SecurityMode_t securityMode) { _requiredSecurity = securityMode; } @@ -356,21 +355,21 @@ /** * Authorization. */ - void setWriteAuthorizationCallback(void (*callback)(GattWriteAuthCallbackParams *)) { + void setWriteAuthorizationCallback(void (*callback)(GattCharacteristicWriteAuthCBParams *)) { writeAuthorizationCallback.attach(callback); enabledWriteAuthorization = true; } template <typename T> - void setWriteAuthorizationCallback(T *object, void (T::*member)(GattWriteAuthCallbackParams *)) { + void setWriteAuthorizationCallback(T *object, void (T::*member)(GattCharacteristicWriteAuthCBParams *)) { writeAuthorizationCallback.attach(object, member); enabledWriteAuthorization = true; } - void setReadAuthorizationCallback(void (*callback)(GattReadAuthCallbackParams *)) { + void setReadAuthorizationCallback(void (*callback)(GattCharacteristicReadAuthCBParams *)) { readAuthorizationCallback.attach(callback); enabledReadAuthorization = true; } template <typename T> - void setReadAuthorizationCallback(T *object, void (T::*member)(GattReadAuthCallbackParams *)) { + void setReadAuthorizationCallback(T *object, void (T::*member)(GattCharacteristicReadAuthCBParams *)) { readAuthorizationCallback.attach(object, member); enabledReadAuthorization = true; } @@ -381,7 +380,7 @@ * @param params to capture the context of the write-auth request; and also contains an out-parameter for reply. * @return true if the write is authorized to proceed. */ - GattAuthCallbackReply_t authorizeWrite(GattWriteAuthCallbackParams *params) { + GattCharacteristicAuthCBReply_t authorizeWrite(GattCharacteristicWriteAuthCBParams *params) { if (!isWriteAuthorizationEnabled()) { return AUTH_CALLBACK_REPLY_SUCCESS; } @@ -407,7 +406,7 @@ * * @return true if the read is authorized to proceed. */ - GattAuthCallbackReply_t authorizeRead(GattReadAuthCallbackParams *params) { + GattCharacteristicAuthCBReply_t authorizeRead(GattCharacteristicReadAuthCBParams *params) { if (!isReadAuthorizationEnabled()) { return AUTH_CALLBACK_REPLY_SUCCESS; } @@ -423,7 +422,7 @@ const GattAttribute& getValueAttribute() const {return _valueAttribute; } GattAttribute::Handle_t getValueHandle(void) const {return getValueAttribute().getHandle();} uint8_t getProperties(void) const {return _properties; } - SecurityManager::SecurityMode_t getRequiredSecurity() const {return _requiredSecurity; } + Gap::SecurityMode_t getRequiredSecurity() const {return _requiredSecurity; } uint8_t getDescriptorCount(void) const {return _descriptorCount; } bool isReadAuthorizationEnabled() const {return enabledReadAuthorization; } bool isWriteAuthorizationEnabled() const {return enabledWriteAuthorization; } @@ -437,16 +436,16 @@ } private: - GattAttribute _valueAttribute; - uint8_t _properties; - SecurityManager::SecurityMode_t _requiredSecurity; - GattAttribute **_descriptors; - uint8_t _descriptorCount; + GattAttribute _valueAttribute; + uint8_t _properties; + Gap::SecurityMode_t _requiredSecurity; + GattAttribute **_descriptors; + uint8_t _descriptorCount; bool enabledReadAuthorization; bool enabledWriteAuthorization; - FunctionPointerWithContext<GattReadAuthCallbackParams *> readAuthorizationCallback; - FunctionPointerWithContext<GattWriteAuthCallbackParams *> writeAuthorizationCallback; + FunctionPointerWithContext<GattCharacteristicReadAuthCBParams *> readAuthorizationCallback; + FunctionPointerWithContext<GattCharacteristicWriteAuthCBParams *> writeAuthorizationCallback; private: /* disallow copy and assignment */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/public/GattCharacteristicCallbackParams.h Fri Jun 19 15:53:28 2015 +0100 @@ -0,0 +1,80 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GATT_CHARACTERISTIC_CALLBACK_PARAMS_H__ +#define __GATT_CHARACTERISTIC_CALLBACK_PARAMS_H__ + +struct GattCharacteristicWriteCBParams { + GattAttribute::Handle_t charHandle; + enum Type { + GATTS_CHAR_OP_INVALID = 0x00, /**< Invalid Operation. */ + GATTS_CHAR_OP_WRITE_REQ = 0x01, /**< Write Request. */ + GATTS_CHAR_OP_WRITE_CMD = 0x02, /**< Write Command. */ + GATTS_CHAR_OP_SIGN_WRITE_CMD = 0x03, /**< Signed Write Command. */ + GATTS_CHAR_OP_PREP_WRITE_REQ = 0x04, /**< Prepare Write Request. */ + GATTS_CHAR_OP_EXEC_WRITE_REQ_CANCEL = 0x05, /**< Execute Write Request: Cancel all prepared writes. */ + GATTS_CHAR_OP_EXEC_WRITE_REQ_NOW = 0x06, /**< Execute Write Request: Immediately execute all prepared writes. */ + } op; /**< Type of write operation, */ + uint16_t offset; /**< Offset for the write operation. */ + uint16_t len; /**< Length of the incoming data. */ + const uint8_t *data; /**< Incoming data, variable length. */ +}; + +struct GattCharacteristicReadCBParams { + GattAttribute::Handle_t charHandle; + enum Type { + GATTS_CHAR_OP_INVALID = 0x00, /**< Invalid Operation. */ + GATTS_CHAR_OP_READ_REQ = 0x0A, /**< Read Request. */ + } op; /**< Type of write operation, */ + uint16_t offset; /**< Offset for the read operation. */ + uint16_t *len; /**< Length of the outgoing data. */ + uint8_t *data; /**< Outgoing data, variable length. */ +}; + +enum GattCharacteristicAuthCBReply_t { + AUTH_CALLBACK_REPLY_SUCCESS = 0x00, /**< Success. */ + AUTH_CALLBACK_REPLY_ATTERR_INVALID_HANDLE = 0x0101, /**< ATT Error: Invalid Attribute Handle. */ + AUTH_CALLBACK_REPLY_ATTERR_READ_NOT_PERMITTED = 0x0102, /**< ATT Error: Read not permitted. */ + AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED = 0x0103, /**< ATT Error: Write not permitted. */ + AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHENTICATION = 0x0105, /**< ATT Error: Authenticated link required. */ + AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET = 0x0107, /**< ATT Error: Offset specified was past the end of the attribute. */ + AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION = 0x0108, /**< ATT Error: Used in ATT as Insufficient Authorisation. */ + AUTH_CALLBACK_REPLY_ATTERR_PREPARE_QUEUE_FULL = 0x0109, /**< ATT Error: Used in ATT as Prepare Queue Full. */ + AUTH_CALLBACK_REPLY_ATTERR_ATTRIBUTE_NOT_FOUND = 0x010A, /**< ATT Error: Used in ATT as Attribute not found. */ + AUTH_CALLBACK_REPLY_ATTERR_ATTRIBUTE_NOT_LONG = 0x010B, /**< ATT Error: Attribute cannot be read or written using read/write blob requests. */ + AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH = 0x010D, /**< ATT Error: Invalid value size. */ + AUTH_CALLBACK_REPLY_ATTERR_INSUF_RESOURCES = 0x0111, /**< ATT Error: Encrypted link required. */ +}; + +struct GattCharacteristicWriteAuthCBParams { + GattAttribute::Handle_t charHandle; + uint16_t offset; /**< Offset for the write operation. */ + uint16_t len; /**< Length of the incoming data. */ + const uint8_t *data; /**< Incoming data, variable length. */ + GattCharacteristicAuthCBReply_t authorizationReply; /* This is the out parameter which needs to be set to true by the callback if the + * request is to proceed; false otherwise. */ +}; + +struct GattCharacteristicReadAuthCBParams { + GattAttribute::Handle_t charHandle; + uint16_t offset; /**< Offset for the read operation. */ + uint16_t len; /**< Optional: new length of the outgoing data. */ + uint8_t *data; /**< Optional: new outgoing data. Leave at NULL if data is unchanged. */ + GattCharacteristicAuthCBReply_t authorizationReply; /* This is the out parameter which needs to be set to true by the callback if the + * request is to proceed; false otherwise. */ +}; + +#endif /*__GATT_CHARACTERISTIC_CALLBACK_PARAMS_H__*/ \ No newline at end of file
--- a/public/GattClient.h Fri Jun 19 15:53:06 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,229 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __GATT_CLIENT_H__ -#define __GATT_CLIENT_H__ - -#include "Gap.h" -#include "GattAttribute.h" -#include "ServiceDiscovery.h" - -#include "GattCallbackParamTypes.h" - -class GattClient { -public: - typedef void (*ReadCallback_t)(const GattReadCallbackParams *params); - - enum WriteOp_t { - GATT_OP_WRITE_REQ = 0x01, /**< Write Request. */ - GATT_OP_WRITE_CMD = 0x02, /**< Write Command. */ - }; - - typedef void (*WriteCallback_t)(const GattWriteCallbackParams *params); - - /* - * The following functions are meant to be overridden in the platform-specific sub-class. - */ -public: - /** - * Launch service discovery. Once launched, service discovery will remain - * active with callbacks being issued back into the application for matching - * services/characteristics. isServiceDiscoveryActive() can be used to - * determine status; and a termination callback (if setup) will be invoked - * at the end. Service discovery can be terminated prematurely if needed - * using terminateServiceDiscovery(). - * - * @param connectionHandle - * Handle for the connection with the peer. - * @param sc - * This is the application callback for matching service. Taken as - * NULL by default. Note: service discovery may still be active - * when this callback is issued; calling asynchronous BLE-stack - * APIs from within this application callback might cause the - * stack to abort service discovery. If this becomes an issue, it - * may be better to make local copy of the discoveredService and - * wait for service discovery to terminate before operating on the - * service. - * @param cc - * This is the application callback for matching characteristic. - * Taken as NULL by default. Note: service discovery may still be - * active when this callback is issued; calling asynchronous - * BLE-stack APIs from within this application callback might cause - * the stack to abort service discovery. If this becomes an issue, - * it may be better to make local copy of the discoveredCharacteristic - * and wait for service discovery to terminate before operating on the - * characteristic. - * @param matchingServiceUUID - * UUID based filter for specifying a service in which the application is - * interested. By default it is set as the wildcard UUID_UNKNOWN, - * in which case it matches all services. If characteristic-UUID - * filter (below) is set to the wildcard value, then a service - * callback will be invoked for the matching service (or for every - * service if the service filter is a wildcard). - * @param matchingCharacteristicUUIDIn - * UUID based filter for specifying characteristic in which the application - * is interested. By default it is set as the wildcard UUID_UKNOWN - * to match against any characteristic. If both service-UUID - * filter and characteristic-UUID filter are used with non- wildcard - * values, then only a single characteristic callback is - * invoked for the matching characteristic. - * - * @note Using wildcard values for both service-UUID and characteristic- - * UUID will result in complete service discovery--callbacks being - * called for every service and characteristic. - * - * @note Providing NULL for the characteristic callback will result in - * characteristic discovery being skipped for each matching - * service. This allows for an inexpensive method to discover only - * services. - * - * @return - * BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error. - */ - virtual ble_error_t launchServiceDiscovery(Gap::Handle_t connectionHandle, - ServiceDiscovery::ServiceCallback_t sc = NULL, - ServiceDiscovery::CharacteristicCallback_t cc = NULL, - const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), - const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ - } - - /** - * Launch service discovery for services. Once launched, service discovery will remain - * active with service-callbacks being issued back into the application for matching - * services. isServiceDiscoveryActive() can be used to - * determine status; and a termination callback (if setup) will be invoked - * at the end. Service discovery can be terminated prematurely if needed - * using terminateServiceDiscovery(). - * - * @param connectionHandle - * Handle for the connection with the peer. - * @param sc - * This is the application callback for matching service. Note: service discovery may still be active - * when this callback is issued; calling asynchronous BLE-stack - * APIs from within this application callback might cause the - * stack to abort service discovery. If this becomes an issue, it - * may be better to make local copy of the discoveredService and - * wait for service discovery to terminate before operating on the - * service. - * @param matchingServiceUUID - * UUID based filter for specifying a service in which the application is - * interested. By default it is set as the wildcard UUID_UNKNOWN, - * in which case it matches all services. - * - * @return - * BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error. - */ - virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, - ServiceDiscovery::ServiceCallback_t callback, - const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ - } - - /** - * Launch service discovery for services. Once launched, service discovery will remain - * active with service-callbacks being issued back into the application for matching - * services. isServiceDiscoveryActive() can be used to - * determine status; and a termination callback (if setup) will be invoked - * at the end. Service discovery can be terminated prematurely if needed - * using terminateServiceDiscovery(). - * - * @param connectionHandle - * Handle for the connection with the peer. - * @param sc - * This is the application callback for matching service. Note: service discovery may still be active - * when this callback is issued; calling asynchronous BLE-stack - * APIs from within this application callback might cause the - * stack to abort service discovery. If this becomes an issue, it - * may be better to make local copy of the discoveredService and - * wait for service discovery to terminate before operating on the - * service. - * @param startHandle, endHandle - * Handle range within which to limit the search - * - * @return - * BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error. - */ - virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, - ServiceDiscovery::ServiceCallback_t callback, - GattAttribute::Handle_t startHandle, - GattAttribute::Handle_t endHandle) { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ - } - - /** - * Is service-discovery currently active? - */ - virtual bool isServiceDiscoveryActive(void) const { - return false; /* default implementation; override this API if this capability is supported. */ - } - - /** - * Terminate an ongoing service-discovery. This should result in an - * invocation of the TerminationCallback if service-discovery is active. - */ - virtual void terminateServiceDiscovery(void) { - /* default implementation; override this API if this capability is supported. */ - } - - /* Initiate a Gatt Client read procedure by attribute-handle. */ - virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ - } - - /** - * Initiate a GATT Client write procedure. - * - * @param[in] cmd - * Command can be either a write-request (which generates a - * matching response from the peripheral), or a write-command, - * which doesn't require the connected peer to respond. - * @param[in] connHandle - * Connection handle. - * @param[in] attributeHandle - * handle for the target attribtue on the remote GATT server. - * @param[in] length - * length of the new value. - * @param[in] value - * new value being written. - */ - virtual ble_error_t write(GattClient::WriteOp_t cmd, - Gap::Handle_t connHandle, - GattAttribute::Handle_t attributeHandle, - size_t length, - const uint8_t *value) const { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ - } - - /** - * Setup callback for when serviceDiscovery terminates. - */ - virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { - /* default implementation; override this API if this capability is supported. */ - } - -protected: - GattClient() { - /* empty */ - } - -private: - /* disallow copy and assignment */ - GattClient(const GattClient &); - GattClient& operator=(const GattClient &); -}; - -#endif // ifndef __GATT_CLIENT_H__ \ No newline at end of file
--- a/public/GattServer.h Fri Jun 19 15:53:06 2015 +0100 +++ b/public/GattServer.h Fri Jun 19 15:53:28 2015 +0100 @@ -21,7 +21,7 @@ #include "GattService.h" #include "GattAttribute.h" #include "GattServerEvents.h" -#include "GattCallbackParamTypes.h" +#include "GattCharacteristicCallbackParams.h" #include "CallChainOfFunctionPointersWithContext.h" class GattServer { @@ -34,118 +34,39 @@ GattServer() : serviceCount(0), characteristicCount(0), - dataSentCallChain(), - dataWrittenCallChain(), - dataReadCallChain(), - updatesEnabledCallback(NULL), - updatesDisabledCallback(NULL), - confirmationReceivedCallback(NULL) { + onDataSent(), + onDataWritten(), + onDataRead(), + onUpdatesEnabled(NULL), + onUpdatesDisabled(NULL), + onConfirmationReceived(NULL) { /* empty */ } - /* - * The following functions are meant to be overridden in the platform-specific sub-class. - */ -public: - - /** - * Add a service declaration to the local server ATT table. Also add the - * characteristics contained within. - */ - virtual ble_error_t addService(GattService &) { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ - } - - /** - * Read the value of a characteristic from the local GattServer - * @param[in] attributeHandle - * Attribute handle for the value attribute of the characteristic. - * @param[out] buffer - * A buffer to hold the value being read. - * @param[in/out] lengthP - * Length of the buffer being supplied. If the attribute - * value is longer than the size of the supplied buffer, - * this variable will hold upon return the total attribute value length - * (excluding offset). The application may use this - * information to allocate a suitable buffer size. - * - * @return BLE_ERROR_NONE if a value was read successfully into the buffer. - */ - virtual ble_error_t read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ - } + friend class BLEDevice; +private: + /* These functions must be defined in the sub-class */ + virtual ble_error_t addService(GattService &) = 0; + virtual ble_error_t readValue(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) = 0; + virtual ble_error_t readValue(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) = 0; + virtual ble_error_t updateValue(GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false) = 0; + virtual ble_error_t updateValue(Gap::Handle_t connectionHandle, GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false) = 0; + virtual ble_error_t initializeGATTDatabase(void) = 0; - /** - * Read the value of a characteristic from the local GattServer - * @param[in] connectionHandle - * Connection Handle. - * @param[in] attributeHandle - * Attribute handle for the value attribute of the characteristic. - * @param[out] buffer - * A buffer to hold the value being read. - * @param[in/out] lengthP - * Length of the buffer being supplied. If the attribute - * value is longer than the size of the supplied buffer, - * this variable will hold upon return the total attribute value length - * (excluding offset). The application may use this - * information to allocate a suitable buffer size. - * - * @return BLE_ERROR_NONE if a value was read successfully into the buffer. - * - * @note This API is a version of above with an additional connection handle - * parameter to allow fetches for connection-specific multivalued - * attribtues (such as the CCCDs). - */ - virtual ble_error_t read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP) { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ - } + // ToDo: For updateValue, check the CCCD to see if the value we are + // updating has the notify or indicate bits sent, and if BOTH are set + // be sure to call sd_ble_gatts_hvx() twice with notify then indicate! + // Strange use case, but valid and must be covered! - /** - * Update the value of a characteristic on the local GattServer. - * - * @param[in] attributeHandle - * Handle for the value attribute of the Characteristic. - * @param[in] value - * A pointer to a buffer holding the new value - * @param[in] size - * Size of the new value (in bytes). - * @param[in] localOnly - * Should this update be kept on the local - * GattServer regardless of the state of the - * notify/indicate flag in the CCCD for this - * Characteristic? If set to true, no notification - * or indication is generated. - * - * @return BLE_ERROR_NONE if we have successfully set the value of the attribute. - */ - virtual ble_error_t write(GattAttribute::Handle_t, const uint8_t *, uint16_t, bool localOnly = false) { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + void setOnDataSent(void (*callback)(unsigned count)) {onDataSent.add(callback);} + template <typename T> + void setOnDataSent(T *objPtr, void (T::*memberPtr)(unsigned count)) { + onDataSent.add(objPtr, memberPtr); } - - /** - * Update the value of a characteristic on the local GattServer. A version - * of the same as above with connection handle parameter to allow updates - * for connection-specific multivalued attribtues (such as the CCCDs). - * - * @param[in] connectionHandle - * Connection Handle. - * @param[in] attributeHandle - * Handle for the value attribute of the Characteristic. - * @param[in] value - * A pointer to a buffer holding the new value - * @param[in] size - * Size of the new value (in bytes). - * @param[in] localOnly - * Should this update be kept on the local - * GattServer regardless of the state of the - * notify/indicate flag in the CCCD for this - * Characteristic? If set to true, no notification - * or indication is generated. - * - * @return BLE_ERROR_NONE if we have successfully set the value of the attribute. - */ - virtual ble_error_t write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t, const uint8_t *, uint16_t, bool localOnly = false) { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this API if this capability is supported. */ + void setOnDataWritten(void (*callback)(const GattCharacteristicWriteCBParams *eventDataP)) {onDataWritten.add(callback);} + template <typename T> + void setOnDataWritten(T *objPtr, void (T::*memberPtr)(const GattCharacteristicWriteCBParams *context)) { + onDataWritten.add(objPtr, memberPtr); } /** @@ -153,135 +74,57 @@ * onDataRead(). It should be overridden to return true as applicable. */ virtual bool isOnDataReadAvailable() const { - return false; /* default implementation; override this API if this capability is supported. */ + return false; } - - /* - * APIs with non-virtual implementations. - */ -public: - /** - * Add a callback for the GATT event DATA_SENT (which is triggered when - * updates are sent out by GATT in the form of notifications). - * - * @Note: it is possible to chain together multiple onDataSent callbacks - * (potentially from different modules of an application) to receive updates - * to characteristics. - * - * @Note: it is also possible to setup a callback into a member function of - * some object. - */ - void onDataSent(void (*callback)(unsigned count)) {dataSentCallChain.add(callback);} - template <typename T> - void onDataSent(T *objPtr, void (T::*memberPtr)(unsigned count)) { - dataSentCallChain.add(objPtr, memberPtr); - } + ble_error_t setOnDataRead(void (*callback)(const GattCharacteristicReadCBParams *eventDataP)) { + if (!isOnDataReadAvailable()) { + return BLE_ERROR_NOT_IMPLEMENTED; + } - /** - * Setup a callback for when an attribute has its value updated by or at the - * connected peer. For a peripheral, this callback triggered when the local - * GATT server has an attribute updated by a write command from the peer. - * For a Central, this callback is triggered when a response is received for - * a write request. - * - * @Note: it is possible to chain together multiple onDataWritten callbacks - * (potentially from different modules of an application) to receive updates - * to characteristics. Many services, such as DFU and UART add their own - * onDataWritten callbacks behind the scenes to trap interesting events. - * - * @Note: it is also possible to setup a callback into a member function of - * some object. - */ - void onDataWritten(void (*callback)(const GattWriteCallbackParams *eventDataP)) {dataWrittenCallChain.add(callback);} - template <typename T> - void onDataWritten(T *objPtr, void (T::*memberPtr)(const GattWriteCallbackParams *context)) { - dataWrittenCallChain.add(objPtr, memberPtr); + onDataRead.add(callback); + return BLE_ERROR_NONE; } - - /** - * Setup a callback to be invoked on the peripheral when an attribute is - * being read by a remote client. - * - * @Note: this functionality may not be available on all underlying stacks. - * You could use GattCharacteristic::setReadAuthorizationCallback() as an - * alternative. - * - * @Note: it is possible to chain together multiple onDataRead callbacks - * (potentially from different modules of an application) to receive updates - * to characteristics. Services may add their own onDataRead callbacks - * behind the scenes to trap interesting events. - * - * @Note: it is also possible to setup a callback into a member function of - * some object. - * - * @return BLE_ERROR_NOT_IMPLEMENTED if this functionality isn't available; - * else BLE_ERROR_NONE. - */ - ble_error_t onDataRead(void (*callback)(const GattReadCallbackParams *eventDataP)) { + template <typename T> + ble_error_t setOnDataRead(T *objPtr, void (T::*memberPtr)(const GattCharacteristicReadCBParams *context)) { if (!isOnDataReadAvailable()) { return BLE_ERROR_NOT_IMPLEMENTED; } - dataReadCallChain.add(callback); - return BLE_ERROR_NONE; - } - template <typename T> - ble_error_t onDataRead(T *objPtr, void (T::*memberPtr)(const GattReadCallbackParams *context)) { - if (!isOnDataReadAvailable()) { - return BLE_ERROR_NOT_IMPLEMENTED; - } - - dataReadCallChain.add(objPtr, memberPtr); + onDataRead.add(objPtr, memberPtr); return BLE_ERROR_NONE; } - - /** - * Setup a callback for when notifications/indications are enabled for a - * characteristic on the local GattServer. - */ - void onUpdatesEnabled(EventCallback_t callback) {updatesEnabledCallback = callback;} + void setOnUpdatesEnabled(EventCallback_t callback) {onUpdatesEnabled = callback;} + void setOnUpdatesDisabled(EventCallback_t callback) {onUpdatesDisabled = callback;} + void setOnConfirmationReceived(EventCallback_t callback) {onConfirmationReceived = callback;} - /** - * Setup a callback for when notifications/indications are disabled for a - * characteristic on the local GattServer. - */ - void onUpdatesDisabled(EventCallback_t callback) {updatesDisabledCallback = callback;} - - /** - * Setup a callback for when the GATT server receives a response for an - * indication event sent previously. - */ - void onConfirmationReceived(EventCallback_t callback) {confirmationReceivedCallback = callback;} - - /* Entry points for the underlying stack to report events back to the user. */ protected: - void handleDataWrittenEvent(const GattWriteCallbackParams *params) { - if (dataWrittenCallChain.hasCallbacksAttached()) { - dataWrittenCallChain.call(params); + void handleDataWrittenEvent(const GattCharacteristicWriteCBParams *params) { + if (onDataWritten.hasCallbacksAttached()) { + onDataWritten.call(params); } } - void handleDataReadEvent(const GattReadCallbackParams *params) { - if (dataReadCallChain.hasCallbacksAttached()) { - dataReadCallChain.call(params); + void handleDataReadEvent(const GattCharacteristicReadCBParams *params) { + if (onDataRead.hasCallbacksAttached()) { + onDataRead.call(params); } } void handleEvent(GattServerEvents::gattEvent_e type, GattAttribute::Handle_t charHandle) { switch (type) { case GattServerEvents::GATT_EVENT_UPDATES_ENABLED: - if (updatesEnabledCallback) { - updatesEnabledCallback(charHandle); + if (onUpdatesEnabled) { + onUpdatesEnabled(charHandle); } break; case GattServerEvents::GATT_EVENT_UPDATES_DISABLED: - if (updatesDisabledCallback) { - updatesDisabledCallback(charHandle); + if (onUpdatesDisabled) { + onUpdatesDisabled(charHandle); } break; case GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED: - if (confirmationReceivedCallback) { - confirmationReceivedCallback(charHandle); + if (onConfirmationReceived) { + onConfirmationReceived(charHandle); } break; default: @@ -290,8 +133,8 @@ } void handleDataSentEvent(unsigned count) { - if (dataSentCallChain.hasCallbacksAttached()) { - dataSentCallChain.call(count); + if (onDataSent.hasCallbacksAttached()) { + onDataSent.call(count); } } @@ -300,12 +143,12 @@ uint8_t characteristicCount; private: - CallChainOfFunctionPointersWithContext<unsigned> dataSentCallChain; - CallChainOfFunctionPointersWithContext<const GattWriteCallbackParams *> dataWrittenCallChain; - CallChainOfFunctionPointersWithContext<const GattReadCallbackParams *> dataReadCallChain; - EventCallback_t updatesEnabledCallback; - EventCallback_t updatesDisabledCallback; - EventCallback_t confirmationReceivedCallback; + CallChainOfFunctionPointersWithContext<unsigned> onDataSent; + CallChainOfFunctionPointersWithContext<const GattCharacteristicWriteCBParams *> onDataWritten; + CallChainOfFunctionPointersWithContext<const GattCharacteristicReadCBParams *> onDataRead; + EventCallback_t onUpdatesEnabled; + EventCallback_t onUpdatesDisabled; + EventCallback_t onConfirmationReceived; private: /* disallow copy and assignment */
--- a/public/SecurityManager.h Fri Jun 19 15:53:06 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,215 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2015 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __SECURITY_MANAGER_H__ -#define __SECURITY_MANAGER_H__ - -#include <stdint.h> - -#include "Gap.h" - -class SecurityManager { -public: - enum SecurityMode_t { - SECURITY_MODE_NO_ACCESS, - SECURITY_MODE_ENCRYPTION_OPEN_LINK, /**< require no protection, open link. */ - SECURITY_MODE_ENCRYPTION_NO_MITM, /**< require encryption, but no MITM protection. */ - SECURITY_MODE_ENCRYPTION_WITH_MITM, /**< require encryption and MITM protection. */ - SECURITY_MODE_SIGNED_NO_MITM, /**< require signing or encryption, but no MITM protection. */ - SECURITY_MODE_SIGNED_WITH_MITM, /**< require signing or encryption, and MITM protection. */ - }; - - /** - * @brief Defines possible security status/states. - * - * @details Defines possible security status/states of a link when requested by getLinkSecurity(). - */ - enum LinkSecurityStatus_t { - NOT_ENCRYPTED, /**< The link is not secured. */ - ENCRYPTION_IN_PROGRESS, /**< Link security is being established.*/ - ENCRYPTED /**< The link is secure.*/ - }; - - enum SecurityIOCapabilities_t { - IO_CAPS_DISPLAY_ONLY = 0x00, /**< Display Only. */ - IO_CAPS_DISPLAY_YESNO = 0x01, /**< Display and Yes/No entry. */ - IO_CAPS_KEYBOARD_ONLY = 0x02, /**< Keyboard Only. */ - IO_CAPS_NONE = 0x03, /**< No I/O capabilities. */ - IO_CAPS_KEYBOARD_DISPLAY = 0x04, /**< Keyboard and Display. */ - }; - - enum SecurityCompletionStatus_t { - SEC_STATUS_SUCCESS = 0x00, /**< Procedure completed with success. */ - SEC_STATUS_TIMEOUT = 0x01, /**< Procedure timed out. */ - SEC_STATUS_PDU_INVALID = 0x02, /**< Invalid PDU received. */ - SEC_STATUS_PASSKEY_ENTRY_FAILED = 0x81, /**< Passkey entry failed (user canceled or other). */ - SEC_STATUS_OOB_NOT_AVAILABLE = 0x82, /**< Out of Band Key not available. */ - SEC_STATUS_AUTH_REQ = 0x83, /**< Authentication requirements not met. */ - SEC_STATUS_CONFIRM_VALUE = 0x84, /**< Confirm value failed. */ - SEC_STATUS_PAIRING_NOT_SUPP = 0x85, /**< Pairing not supported. */ - SEC_STATUS_ENC_KEY_SIZE = 0x86, /**< Encryption key size. */ - SEC_STATUS_SMP_CMD_UNSUPPORTED = 0x87, /**< Unsupported SMP command. */ - SEC_STATUS_UNSPECIFIED = 0x88, /**< Unspecified reason. */ - SEC_STATUS_REPEATED_ATTEMPTS = 0x89, /**< Too little time elapsed since last attempt. */ - SEC_STATUS_INVALID_PARAMS = 0x8A, /**< Invalid parameters. */ - }; - - /** - * Declaration of type containing a passkey to be used during pairing. This - * is passed into initializeSecurity() to specify a pre-programmed passkey - * for authentication instead of generating a random one. - */ - static const unsigned PASSKEY_LEN = 6; - typedef uint8_t Passkey_t[PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */ - -public: - typedef void (*HandleSpecificEvent_t)(Gap::Handle_t handle); - typedef void (*SecuritySetupInitiatedCallback_t)(Gap::Handle_t, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps); - typedef void (*SecuritySetupCompletedCallback_t)(Gap::Handle_t, SecurityCompletionStatus_t status); - typedef void (*LinkSecuredCallback_t)(Gap::Handle_t handle, SecurityMode_t securityMode); - typedef void (*PasskeyDisplayCallback_t)(Gap::Handle_t handle, const Passkey_t passkey); - - /* - * The following functions are meant to be overridden in the platform-specific sub-class. - */ -public: - /** - * Enable the BLE stack's Security Manager. The Security Manager implements - * the actual cryptographic algorithms and protocol exchanges that allow two - * devices to securely exchange data and privately detect each other. - * Calling this API is a prerequisite for encryption and pairing (bonding). - * - * @param[in] enableBonding Allow for bonding. - * @param[in] requireMITM Require protection for man-in-the-middle attacks. - * @param[in] iocaps To specify IO capabilities of this peripheral, - * such as availability of a display or keyboard to - * support out-of-band exchanges of security data. - * @param[in] passkey To specify a static passkey. - * - * @return BLE_ERROR_NONE on success. - */ - virtual ble_error_t init(bool enableBonding = true, - bool requireMITM = true, - SecurityIOCapabilities_t iocaps = IO_CAPS_NONE, - const Passkey_t passkey = NULL) { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this if security is supported. */ - } - - /** - * Get the security status of a connection. - * - * @param[in] connectionHandle Handle to identify the connection. - * @param[out] securityStatusP security status. - * - * @return BLE_SUCCESS Or appropriate error code indicating reason for failure. - */ - virtual ble_error_t getLinkSecurity(Gap::Handle_t connectionHandle, LinkSecurityStatus_t *securityStatusP) { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this if security is supported. */ - } - - /** - * Delete all peer device context and all related bonding information from - * the database within the security manager. - * - * @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure. - * @retval BLE_ERROR_INVALID_STATE If the API is called without module initialization and/or - * application registration. - */ - virtual ble_error_t purgeAllBondingState(void) { - return BLE_ERROR_NOT_IMPLEMENTED; /* default implementation; override this if security is supported. */ - } - - /* Event callback handlers. */ -public: - /** - * To indicate that security procedure for link has started. - */ - virtual void onSecuritySetupInitiated(SecuritySetupInitiatedCallback_t callback) {securitySetupInitiatedCallback = callback;} - - /** - * To indicate that security procedure for link has completed. - */ - virtual void onSecuritySetupCompleted(SecuritySetupCompletedCallback_t callback) {securitySetupCompletedCallback = callback;} - - /** - * To indicate that link with the peer is secured. For bonded devices, - * subsequent re-connections with bonded peer will result only in this callback - * when the link is secured and setup procedures will not occur unless the - * bonding information is either lost or deleted on either or both sides. - */ - virtual void onLinkSecured(LinkSecuredCallback_t callback) {linkSecuredCallback = callback;} - - /** - * To indicate that device context is stored persistently. - */ - virtual void onSecurityContextStored(HandleSpecificEvent_t callback) {securityContextStoredCallback = callback;} - - /** - * To set the callback for when the passkey needs to be displayed on a peripheral with DISPLAY capability. - */ - virtual void onPasskeyDisplay(PasskeyDisplayCallback_t callback) {passkeyDisplayCallback = callback;} - - /* Entry points for the underlying stack to report events back to the user. */ -public: - void processSecuritySetupInitiatedEvent(Gap::Handle_t handle, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps) { - if (securitySetupInitiatedCallback) { - securitySetupInitiatedCallback(handle, allowBonding, requireMITM, iocaps); - } - } - - void processSecuritySetupCompletedEvent(Gap::Handle_t handle, SecurityCompletionStatus_t status) { - if (securitySetupCompletedCallback) { - securitySetupCompletedCallback(handle, status); - } - } - - void processLinkSecuredEvent(Gap::Handle_t handle, SecurityMode_t securityMode) { - if (linkSecuredCallback) { - linkSecuredCallback(handle, securityMode); - } - } - - void processSecurityContextStoredEvent(Gap::Handle_t handle) { - if (securityContextStoredCallback) { - securityContextStoredCallback(handle); - } - } - - void processPasskeyDisplayEvent(Gap::Handle_t handle, const Passkey_t passkey) { - if (passkeyDisplayCallback) { - passkeyDisplayCallback(handle, passkey); - } - } - -protected: - SecurityManager() : - securitySetupInitiatedCallback(), - securitySetupCompletedCallback(), - linkSecuredCallback(), - securityContextStoredCallback(), - passkeyDisplayCallback() { - /* empty */ - } - -protected: - SecuritySetupInitiatedCallback_t securitySetupInitiatedCallback; - SecuritySetupCompletedCallback_t securitySetupCompletedCallback; - LinkSecuredCallback_t linkSecuredCallback; - HandleSpecificEvent_t securityContextStoredCallback; - PasskeyDisplayCallback_t passkeyDisplayCallback; -}; - -#endif /*__SECURITY_MANAGER_H__*/ \ No newline at end of file
--- a/public/ServiceDiscovery.h Fri Jun 19 15:53:06 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,143 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __SERVICE_DISOVERY_H__ -#define __SERVICE_DISOVERY_H__ - -#include "UUID.h" -#include "Gap.h" -#include "GattAttribute.h" - -class DiscoveredService; -class DiscoveredCharacteristic; - -class ServiceDiscovery { -public: - /* - * Exposed application callback types. - */ - - /** - * Callback type for when a matching Service is found during service- - * discovery. The receiving function is passed in a pointer to a - * DiscoveredService object which will remain valid for the lifetime of the - * callback. Memory for this object is owned by the BLE_API eventing - * framework. The application can safely make a persistent shallow-copy of - * this object in order to work with the service beyond the callback. - */ - typedef void (*ServiceCallback_t)(const DiscoveredService *); - - /** - * Callback type for when a matching Characteristic is found during service- - * discovery. The receiving function is passed in a pointer to a - * DiscoveredCharacteristic object which will remain valid for the lifetime - * of the callback. Memory for this object is owned by the BLE_API eventing - * framework. The application can safely make a persistent shallow-copy of - * this object in order to work with the characteristic beyond the callback. - */ - typedef void (*CharacteristicCallback_t)(const DiscoveredCharacteristic *); - - /** - * Callback type for when serviceDiscovery terminates. - */ - typedef void (*TerminationCallback_t)(Gap::Handle_t connectionHandle); - -public: - /** - * Launch service discovery. Once launched, service discovery will remain - * active with callbacks being issued back into the application for matching - * services/characteristics. isActive() can be used to determine status; and - * a termination callback (if setup) will be invoked at the end. Service - * discovery can be terminated prematurely if needed using terminate(). - * - * @param connectionHandle - * Handle for the connection with the peer. - * @param sc - * This is the application callback for matching service. Taken as - * NULL by default. Note: service discovery may still be active - * when this callback is issued; calling asynchronous BLE-stack - * APIs from within this application callback might cause the - * stack to abort service discovery. If this becomes an issue, it - * may be better to make local copy of the discoveredService and - * wait for service discovery to terminate before operating on the - * service. - * @param cc - * This is the application callback for matching characteristic. - * Taken as NULL by default. Note: service discovery may still be - * active when this callback is issued; calling asynchronous - * BLE-stack APIs from within this application callback might cause - * the stack to abort service discovery. If this becomes an issue, - * it may be better to make local copy of the discoveredCharacteristic - * and wait for service discovery to terminate before operating on the - * characteristic. - * @param matchingServiceUUID - * UUID based filter for specifying a service in which the application is - * interested. By default it is set as the wildcard UUID_UNKNOWN, - * in which case it matches all services. If characteristic-UUID - * filter (below) is set to the wildcard value, then a service - * callback will be invoked for the matching service (or for every - * service if the service filter is a wildcard). - * @param matchingCharacteristicUUIDIn - * UUID based filter for specifying characteristic in which the application - * is interested. By default it is set as the wildcard UUID_UKNOWN - * to match against any characteristic. If both service-UUID - * filter and characteristic-UUID filter are used with non- wildcard - * values, then only a single characteristic callback is - * invoked for the matching characteristic. - * - * @note Using wildcard values for both service-UUID and characteristic- - * UUID will result in complete service discovery--callbacks being - * called for every service and characteristic. - * - * @note Providing NULL for the characteristic callback will result in - * characteristic discovery being skipped for each matching - * service. This allows for an inexpensive method to discover only - * services. - * - * @return - * BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error. - */ - virtual ble_error_t launch(Gap::Handle_t connectionHandle, - ServiceCallback_t sc = NULL, - CharacteristicCallback_t cc = NULL, - const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), - const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) = 0; - - /** - * Is service-discovery currently active? - */ - virtual bool isActive(void) const = 0; - - /** - * Terminate an ongoing service-discovery. This should result in an - * invocation of the TerminationCallback if service-discovery is active. - */ - virtual void terminate(void) = 0; - - /** - * Setup callback to be invoked when service discovery is terminated. - */ - virtual void onTermination(TerminationCallback_t callback) = 0; - -protected: - Gap::Handle_t connHandle; /**< Connection handle as provided by the SoftDevice. */ - UUID matchingServiceUUID; - ServiceCallback_t serviceCallback; - UUID matchingCharacteristicUUID; - CharacteristicCallback_t characteristicCallback; -}; - -#endif // ifndef __SERVICE_DISOVERY_H__ \ No newline at end of file
--- a/public/UUID.h Fri Jun 19 15:53:06 2015 +0100 +++ b/public/UUID.h Fri Jun 19 15:53:28 2015 +0100 @@ -17,7 +17,6 @@ #ifndef __UUID_H__ #define __UUID_H__ -#include <stdint.h> #include <string.h> #include "blecommon.h" @@ -29,10 +28,9 @@ UUID_TYPE_LONG = 1 // Full 128-bit UUID }; - typedef uint16_t ShortUUIDBytes_t; - static const unsigned LENGTH_OF_LONG_UUID = 16; - typedef uint8_t LongUUIDBytes_t[LENGTH_OF_LONG_UUID]; + typedef uint16_t ShortUUIDBytes_t; + typedef uint8_t LongUUIDBytes_t[LENGTH_OF_LONG_UUID]; public: /**
--- a/services/BatteryService.h Fri Jun 19 15:53:06 2015 +0100 +++ b/services/BatteryService.h Fri Jun 19 15:53:28 2015 +0100 @@ -17,7 +17,7 @@ #ifndef __BLE_BATTERY_SERVICE_H__ #define __BLE_BATTERY_SERVICE_H__ -#include "BLE.h" +#include "BLEDevice.h" /** * @class BatteryService @@ -29,19 +29,25 @@ public: /** * @param[ref] _ble - * BLE object for the underlying controller. + * BLEDevice object for the underlying controller. * @param[in] level * 8bit batterly level. Usually used to represent percentage of batterly charge remaining. */ - BatteryService(BLE &_ble, uint8_t level = 100) : + BatteryService(BLEDevice &_ble, uint8_t level = 100) : ble(_ble), batteryLevel(level), batteryLevelCharacteristic(GattCharacteristic::UUID_BATTERY_LEVEL_CHAR, &batteryLevel, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) { + static bool serviceAdded = false; /* We should only ever need to add the heart rate service once. */ + if (serviceAdded) { + return; + } + GattCharacteristic *charTable[] = {&batteryLevelCharacteristic}; GattService batteryService(GattService::UUID_BATTERY_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); ble.addService(batteryService); + serviceAdded = true; } /** @@ -56,8 +62,8 @@ ble.updateCharacteristicValue(batteryLevelCharacteristic.getValueAttribute().getHandle(), &batteryLevel, 1); } -protected: - BLE &ble; +private: + BLEDevice &ble; uint8_t batteryLevel; ReadOnlyGattCharacteristic<uint8_t> batteryLevelCharacteristic;
--- a/services/DFUService.h Fri Jun 19 15:53:06 2015 +0100 +++ b/services/DFUService.h Fri Jun 19 15:53:28 2015 +0100 @@ -17,7 +17,7 @@ #ifndef __BLE_DFU_SERVICE_H__ #define __BLE_DFU_SERVICE_H__ -#include "BLE.h" +#include "BLEDevice.h" #include "UUID.h" extern "C" void bootloader_start(void); @@ -48,17 +48,17 @@ * @brief Adds Device Firmware Update service to an existing ble object. * * @param[ref] _ble - * BLE object for the underlying controller. + * BLEDevice object for the underlying controller. * @param[in] _handoverCallback * Application specific handover callback. */ - DFUService(BLE &_ble, ResetPrepare_t _handoverCallback = NULL) : + DFUService(BLEDevice &_ble, ResetPrepare_t _handoverCallback = NULL) : ble(_ble), + controlBytes(), + packetBytes(), controlPoint(DFUServiceControlCharacteristicUUID, controlBytes, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), packet(DFUServicePacketCharacteristicUUID, packetBytes, SIZEOF_PACKET_BYTES, SIZEOF_PACKET_BYTES, - GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE), - controlBytes(), - packetBytes() { + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE) { static bool serviceAdded = false; /* We should only ever need to add the DFU service once. */ if (serviceAdded) { return; @@ -94,8 +94,8 @@ * @param[in] params * Information about the characterisitc being updated. */ - virtual void onDataWritten(const GattWriteCallbackParams *params) { - if (params->handle == controlPoint.getValueHandle()) { + virtual void onDataWritten(const GattCharacteristicWriteCBParams *params) { + if (params->charHandle == controlPoint.getValueHandle()) { /* At present, writing anything will do the trick--this needs to be improved. */ if (handoverCallback) { handoverCallback(); @@ -105,12 +105,16 @@ } } -protected: +private: static const unsigned SIZEOF_CONTROL_BYTES = 2; static const unsigned SIZEOF_PACKET_BYTES = 20; -protected: - BLE &ble; + static ResetPrepare_t handoverCallback; /**< application specific handover callback. */ + +private: + BLEDevice &ble; + uint8_t controlBytes[SIZEOF_CONTROL_BYTES]; + uint8_t packetBytes[SIZEOF_PACKET_BYTES]; /**< Writing to the control characteristic triggers the handover to dfu- * bootloader. At present, writing anything will do the trick--this needs @@ -123,11 +127,6 @@ * FOTA clients might get confused as service definitions change after * handing control over to the bootloader. */ GattCharacteristic packet; - - uint8_t controlBytes[SIZEOF_CONTROL_BYTES]; - uint8_t packetBytes[SIZEOF_PACKET_BYTES]; - - static ResetPrepare_t handoverCallback; /**< application specific handover callback. */ }; #endif /* #ifndef __BLE_DFU_SERVICE_H__*/ \ No newline at end of file
--- a/services/DeviceInformationService.h Fri Jun 19 15:53:06 2015 +0100 +++ b/services/DeviceInformationService.h Fri Jun 19 15:53:28 2015 +0100 @@ -17,7 +17,7 @@ #ifndef __BLE_DEVICE_INFORMATION_SERVICE_H__ #define __BLE_DEVICE_INFORMATION_SERVICE_H__ -#include "BLE.h" +#include "BLEDevice.h" /** * @class DeviceInformationService @@ -31,7 +31,7 @@ * @brief Device Information Service Constructor. * * @param[ref] _ble - * BLE object for the underlying controller. + * BLEDevice object for the underlying controller. * @param[in] manufacturersName * This characteristic represents the name of the * manufacturer of the device. The name is copied into the @@ -57,7 +57,7 @@ * the software within the device. The value is copied * into the BLE stack during this constructor. */ - DeviceInformationService(BLE &_ble, + DeviceInformationService(BLEDevice &_ble, const char *manufacturersName = NULL, const char *modelNumber = NULL, const char *serialNumber = NULL, @@ -114,8 +114,8 @@ serviceAdded = true; } -protected: - BLE &ble; +private: + BLEDevice &ble; GattCharacteristic manufacturersNameStringCharacteristic; GattCharacteristic modelNumberStringCharacteristic; GattCharacteristic serialNumberStringCharacteristic;
--- a/services/HealthThermometerService.h Fri Jun 19 15:53:06 2015 +0100 +++ b/services/HealthThermometerService.h Fri Jun 19 15:53:28 2015 +0100 @@ -17,7 +17,7 @@ #ifndef __BLE_HEALTH_THERMOMETER_SERVICE_H__ #define __BLE_HEALTH_THERMOMETER_SERVICE_H__ -#include "BLE.h" +#include "BLEDevice.h" /** * @class HealthThermometerService @@ -51,7 +51,7 @@ * @param[in] initialTemp initial value in celsius * @param[in] _location */ - HealthThermometerService(BLE &_ble, float initialTemp, uint8_t _location) : + HealthThermometerService(BLEDevice &_ble, float initialTemp, uint8_t _location) : ble(_ble), valueBytes(initialTemp), tempMeasurement(GattCharacteristic::UUID_TEMPERATURE_MEASUREMENT_CHAR, (TemperatureValueBytes *)valueBytes.getPointer(), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), @@ -141,7 +141,7 @@ }; private: - BLE &ble; + BLEDevice &ble; TemperatureValueBytes valueBytes; ReadOnlyGattCharacteristic<TemperatureValueBytes> tempMeasurement; ReadOnlyGattCharacteristic<uint8_t> tempLocation;
--- a/services/HeartRateService.h Fri Jun 19 15:53:06 2015 +0100 +++ b/services/HeartRateService.h Fri Jun 19 15:53:28 2015 +0100 @@ -17,7 +17,7 @@ #ifndef __BLE_HEART_RATE_SERVICE_H__ #define __BLE_HEART_RATE_SERVICE_H__ -#include "BLE.h" +#include "BLEDevice.h" /** * @class HeartRateService @@ -47,13 +47,13 @@ * @brief Constructor with 8bit HRM Counter value. * * @param[ref] _ble - * Reference to the underlying BLE. + * Reference to the underlying BLEDevice. * @param[in] hrmCounter (8-bit) * initial value for the hrm counter. * @param[in] location * Sensor's location. */ - HeartRateService(BLE &_ble, uint8_t hrmCounter, uint8_t location) : + HeartRateService(BLEDevice &_ble, uint8_t hrmCounter, uint8_t location) : ble(_ble), valueBytes(hrmCounter), hrmRate(GattCharacteristic::UUID_HEART_RATE_MEASUREMENT_CHAR, valueBytes.getPointer(), @@ -68,13 +68,13 @@ * @brief Constructor with a 16-bit HRM Counter value. * * @param[in] _ble - * Reference to the underlying BLE. + * Reference to the underlying BLEDevice. * @param[in] hrmCounter (8-bit) * initial value for the hrm counter. * @param[in] location * Sensor's location. */ - HeartRateService(BLE &_ble, uint16_t hrmCounter, uint8_t location) : + HeartRateService(BLEDevice &_ble, uint16_t hrmCounter, uint8_t location) : ble(_ble), valueBytes(hrmCounter), hrmRate(GattCharacteristic::UUID_HEART_RATE_MEASUREMENT_CHAR, valueBytes.getPointer(), @@ -114,8 +114,8 @@ * @param[in] params * Information about the characterisitc being updated. */ - virtual void onDataWritten(const GattWriteCallbackParams *params) { - if (params->handle == controlPoint.getValueAttribute().getHandle()) { + virtual void onDataWritten(const GattCharacteristicWriteCBParams *params) { + if (params->charHandle == controlPoint.getValueAttribute().getHandle()) { /* Do something here if the new value is 1; else you can override this method by * extending this class. * @NOTE: if you are extending this class, be sure to also call @@ -125,16 +125,23 @@ } } -protected: +private: void setupService(void) { + static bool serviceAdded = false; /* We should only ever need to add the heart rate service once. */ + if (serviceAdded) { + return; + } + GattCharacteristic *charTable[] = {&hrmRate, &hrmLocation, &controlPoint}; GattService hrmService(GattService::UUID_HEART_RATE_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); ble.addService(hrmService); + serviceAdded = true; + ble.onDataWritten(this, &HeartRateService::onDataWritten); } -protected: +private: /* Private internal representation for the bytes used to work with the vaulue of the heart-rate characteristic. */ struct HeartRateValueBytes { static const unsigned MAX_VALUE_BYTES = 3; /* FLAGS + up to two bytes for heart-rate */ @@ -174,14 +181,14 @@ return 1 + ((valueBytes[FLAGS_BYTE_INDEX] & VALUE_FORMAT_FLAG) ? sizeof(uint16_t) : sizeof(uint8_t)); } - private: +private: /* First byte = 8-bit values, no extra info, Second byte = uint8_t HRM value */ /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml */ uint8_t valueBytes[MAX_VALUE_BYTES]; }; -protected: - BLE &ble; +private: + BLEDevice &ble; HeartRateValueBytes valueBytes; uint8_t controlPointValue;
--- a/services/LinkLossService.h Fri Jun 19 15:53:06 2015 +0100 +++ b/services/LinkLossService.h Fri Jun 19 15:53:28 2015 +0100 @@ -37,9 +37,9 @@ /** * @param[ref] ble - * BLE object for the underlying controller. + * BLEDevice object for the underlying controller. */ - LinkLossService(BLE &bleIn, callback_t callbackIn, AlertLevel_t levelIn = NO_ALERT) : + LinkLossService(BLEDevice &bleIn, callback_t callbackIn, AlertLevel_t levelIn = NO_ALERT) : ble(bleIn), alertLevel(levelIn), callback(callbackIn), @@ -80,7 +80,7 @@ * @param[in] params * Information about the characterisitc being updated. */ - virtual void onDataWritten(const GattWriteCallbackParams *params) { + virtual void onDataWritten(const GattCharacteristicWriteCBParams *params) { if (params->charHandle == alertLevelChar.getValueHandle()) { alertLevel = *reinterpret_cast<const AlertLevel_t *>(params->data); } @@ -92,8 +92,8 @@ } } -protected: - BLE &ble; +private: + BLEDevice &ble; AlertLevel_t alertLevel; callback_t callback;
--- a/services/UARTService.h Fri Jun 19 15:53:06 2015 +0100 +++ b/services/UARTService.h Fri Jun 19 15:53:28 2015 +0100 @@ -21,7 +21,7 @@ #include "Stream.h" #include "UUID.h" -#include "BLE.h" +#include "BLEDevice.h" extern const uint8_t UARTServiceBaseUUID[UUID::LENGTH_OF_LONG_UUID]; extern const uint16_t UARTServiceShortUUID; @@ -48,9 +48,9 @@ /** * @param[ref] ble - * BLE object for the underlying controller. + * BLEDevice object for the underlying controller. */ - UARTService(BLE &_ble) : + UARTService(BLEDevice &_ble) : ble(_ble), receiveBuffer(), sendBuffer(), @@ -167,8 +167,8 @@ * function from the global onDataWritten() callback handler; or if that's * not used, this method can be used as a callback directly. */ - void onDataWritten(const GattWriteCallbackParams *params) { - if (params->handle == getTXCharacteristicHandle()) { + void onDataWritten(const GattCharacteristicWriteCBParams *params) { + if (params->charHandle == getTXCharacteristicHandle()) { uint16_t bytesRead = params->len; if (bytesRead <= BLE_UART_SERVICE_MAX_DATA_LEN) { numBytesReceived = bytesRead; @@ -179,7 +179,7 @@ } private: - BLE &ble; + BLEDevice &ble; uint8_t receiveBuffer[BLE_UART_SERVICE_MAX_DATA_LEN]; /**< The local buffer into which we receive * inbound data before forwarding it to the
--- a/services/URIBeaconConfigService.cpp Fri Jun 19 15:53:06 2015 +0100 +++ b/services/URIBeaconConfigService.cpp Fri Jun 19 15:53:28 2015 +0100 @@ -21,15 +21,15 @@ 0xab, 0x96, 0x99, 0xb9, 0x1a, 0xc9, 0x81, 0xd8, \ } -const uint8_t UUID_URI_BEACON_SERVICE[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x80); -const uint8_t UUID_LOCK_STATE_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x81); -const uint8_t UUID_LOCK_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x82); -const uint8_t UUID_UNLOCK_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x83); -const uint8_t UUID_URI_DATA_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x84); -const uint8_t UUID_FLAGS_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x85); -const uint8_t UUID_ADV_POWER_LEVELS_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x86); -const uint8_t UUID_TX_POWER_MODE_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x87); -const uint8_t UUID_BEACON_PERIOD_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x88); -const uint8_t UUID_RESET_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x89); +const uint8_t UUID_URI_BEACON_SERVICE[LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x80); +const uint8_t UUID_LOCK_STATE_CHAR[LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x81); +const uint8_t UUID_LOCK_CHAR[LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x82); +const uint8_t UUID_UNLOCK_CHAR[LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x83); +const uint8_t UUID_URI_DATA_CHAR[LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x84); +const uint8_t UUID_FLAGS_CHAR[LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x85); +const uint8_t UUID_ADV_POWER_LEVELS_CHAR[LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x86); +const uint8_t UUID_TX_POWER_MODE_CHAR[LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x87); +const uint8_t UUID_BEACON_PERIOD_CHAR[LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x88); +const uint8_t UUID_RESET_CHAR[LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x89); -const uint8_t BEACON_UUID[sizeof(UUID::ShortUUIDBytes_t)] = {0xD8, 0xFE}; \ No newline at end of file +const uint8_t BEACON_UUID[sizeof(ShortUUIDBytes_t)] = {0xD8, 0xFE}; \ No newline at end of file
--- a/services/URIBeaconConfigService.h Fri Jun 19 15:53:06 2015 +0100 +++ b/services/URIBeaconConfigService.h Fri Jun 19 15:53:28 2015 +0100 @@ -17,21 +17,21 @@ #ifndef SERVICES_URIBEACONCONFIGSERVICE_H_ #define SERVICES_URIBEACONCONFIGSERVICE_H_ -#include "BLE.h" +#include "BLEDevice.h" #include "mbed.h" -extern const uint8_t UUID_URI_BEACON_SERVICE[UUID::LENGTH_OF_LONG_UUID]; -extern const uint8_t UUID_LOCK_STATE_CHAR[UUID::LENGTH_OF_LONG_UUID]; -extern const uint8_t UUID_LOCK_CHAR[UUID::LENGTH_OF_LONG_UUID]; -extern const uint8_t UUID_UNLOCK_CHAR[UUID::LENGTH_OF_LONG_UUID]; -extern const uint8_t UUID_URI_DATA_CHAR[UUID::LENGTH_OF_LONG_UUID]; -extern const uint8_t UUID_FLAGS_CHAR[UUID::LENGTH_OF_LONG_UUID]; -extern const uint8_t UUID_ADV_POWER_LEVELS_CHAR[UUID::LENGTH_OF_LONG_UUID]; -extern const uint8_t UUID_TX_POWER_MODE_CHAR[UUID::LENGTH_OF_LONG_UUID]; -extern const uint8_t UUID_BEACON_PERIOD_CHAR[UUID::LENGTH_OF_LONG_UUID]; -extern const uint8_t UUID_RESET_CHAR[UUID::LENGTH_OF_LONG_UUID]; +extern const uint8_t UUID_URI_BEACON_SERVICE[LENGTH_OF_LONG_UUID]; +extern const uint8_t UUID_LOCK_STATE_CHAR[LENGTH_OF_LONG_UUID]; +extern const uint8_t UUID_LOCK_CHAR[LENGTH_OF_LONG_UUID]; +extern const uint8_t UUID_UNLOCK_CHAR[LENGTH_OF_LONG_UUID]; +extern const uint8_t UUID_URI_DATA_CHAR[LENGTH_OF_LONG_UUID]; +extern const uint8_t UUID_FLAGS_CHAR[LENGTH_OF_LONG_UUID]; +extern const uint8_t UUID_ADV_POWER_LEVELS_CHAR[LENGTH_OF_LONG_UUID]; +extern const uint8_t UUID_TX_POWER_MODE_CHAR[LENGTH_OF_LONG_UUID]; +extern const uint8_t UUID_BEACON_PERIOD_CHAR[LENGTH_OF_LONG_UUID]; +extern const uint8_t UUID_RESET_CHAR[LENGTH_OF_LONG_UUID]; -extern const uint8_t BEACON_UUID[sizeof(UUID::ShortUUIDBytes_t)]; +extern const uint8_t BEACON_UUID[sizeof(ShortUUIDBytes_t)]; /** * @class URIBeaconConfigService @@ -71,7 +71,7 @@ /** * @param[ref] ble - * BLE object for the underlying controller. + * BLEDevice object for the underlying controller. * @param[in/out] paramsIn * Reference to application-visible beacon state, loaded * from persistent storage at startup. @@ -85,7 +85,7 @@ * @param[in] defaultAdvPowerLevelsIn * Default power-levels array; applies only if the resetToDefaultsFlag is true. */ - URIBeaconConfigService(BLE &bleIn, + URIBeaconConfigService(BLEDevice &bleIn, Params_t ¶msIn, bool resetToDefaultsFlag, const char *defaultURIDataIn, @@ -232,8 +232,8 @@ * characteristics of this service. Attempts to do so are also applied to * the internal state of this service object. */ - void onDataWrittenCallback(const GattWriteCallbackParams *writeParams) { - uint16_t handle = writeParams->handle; + void onDataWrittenCallback(const GattCharacteristicWriteCBParams *writeParams) { + uint16_t handle = writeParams->charHandle; if (handle == lockChar.getValueHandle()) { // Validated earlier @@ -305,8 +305,8 @@ reinterpret_cast<uint8_t *>(params.advPowerLevels), sizeof(PowerLevels_t)); } -private: - void lockAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { + private: + void lockAuthorizationCallback(GattCharacteristicWriteAuthCBParams *authParams) { if (lockedState) { authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; } else if (authParams->len != sizeof(Lock_t)) { @@ -319,7 +319,7 @@ } - void unlockAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { + void unlockAuthorizationCallback(GattCharacteristicWriteAuthCBParams *authParams) { if (!lockedState) { authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; } else if (authParams->len != sizeof(Lock_t)) { @@ -333,7 +333,7 @@ } } - void uriDataWriteAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { + void uriDataWriteAuthorizationCallback(GattCharacteristicWriteAuthCBParams *authParams) { if (lockedState) { authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; } else if (authParams->offset != 0) { @@ -343,7 +343,7 @@ } } - void powerModeAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { + void powerModeAuthorizationCallback(GattCharacteristicWriteAuthCBParams *authParams) { if (lockedState) { authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; } else if (authParams->len != sizeof(uint8_t)) { @@ -358,7 +358,7 @@ } template <typename T> - void basicAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { + void basicAuthorizationCallback(GattCharacteristicWriteAuthCBParams *authParams) { if (lockedState) { authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; } else if (authParams->len != sizeof(T)) { @@ -370,8 +370,7 @@ } } -protected: - BLE &ble; + BLEDevice &ble; Params_t ¶ms; size_t defaultUriDataLength; // Default value that is restored on reset @@ -392,7 +391,7 @@ ReadWriteGattCharacteristic<uint16_t> beaconPeriodChar; WriteOnlyGattCharacteristic<uint8_t> resetChar; -public: + public: /* * Encode a human-readable URI into the binary format defined by URIBeacon spec (https://github.com/google/uribeacon/tree/master/specification). */
--- a/services/iBeaconService.h Fri Jun 19 15:53:06 2015 +0100 +++ b/services/iBeaconService.h Fri Jun 19 15:53:28 2015 +0100 @@ -1,74 +1,74 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2015 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef __BLE_IBEACON_SERVICE_H__ -#define __BLE_IBEACON_SERVICE_H__ - -#include "core_cmInstr.h" -#include "BLE.h" - -/** -* @class iBeaconService -* @brief iBeacon Service. This service sets up a device to broadcast advertising packets to mimic an iBeacon<br> -*/ - -class iBeaconService -{ -public: - typedef const uint8_t LocationUUID_t[16]; - - union Payload { - uint8_t raw[25]; - struct { - uint16_t companyID; - uint8_t ID; - uint8_t len; - uint8_t proximityUUID[16]; - uint16_t majorNumber; - uint16_t minorNumber; - uint8_t txPower; - }; - - Payload(LocationUUID_t uuid, uint16_t majNum, uint16_t minNum, uint8_t transmitPower, uint16_t companyIDIn) : - companyID(companyIDIn), ID(0x02), len(0x15), majorNumber(__REV16(majNum)), minorNumber(__REV16(minNum)), txPower(transmitPower) - { - memcpy(proximityUUID, uuid, sizeof(LocationUUID_t)); - } - }; - -public: - iBeaconService(BLE &_ble, - LocationUUID_t uuid, - uint16_t majNum, - uint16_t minNum, - uint8_t txP = 0xC8, - uint16_t compID = 0x004C) : - ble(_ble), data(uuid, majNum, minNum, txP, compID) - { - // Generate the 0x020106 part of the iBeacon Prefix - ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE ); - // Generate the 0x1AFF part of the iBeacon Prefix - ble.accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, data.raw, sizeof(data.raw)); - - // Set advertising type - ble.setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED); - } - -private: - BLE &ble; - Payload data; -}; - -#endif //__BLE_IBEACON_SERVICE_H__ \ No newline at end of file +/* mbed Microcontroller Library + * Copyright (c) 2006-2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __BLE_IBEACON_SERVICE_H__ +#define __BLE_IBEACON_SERVICE_H__ + +#include "core_cmInstr.h" +#include "BLEDevice.h" + +/** +* @class iBeaconService +* @brief iBeacon Service. This service sets up a device to broadcast advertising packets to mimic an iBeacon<br> +*/ + +class iBeaconService +{ +public: + typedef const uint8_t LocationUUID_t[16]; + + union Payload { + uint8_t raw[25]; + struct { + uint16_t companyID; + uint8_t ID; + uint8_t len; + uint8_t proximityUUID[16]; + uint16_t majorNumber; + uint16_t minorNumber; + uint8_t txPower; + }; + + Payload(LocationUUID_t uuid, uint16_t majNum, uint16_t minNum, uint8_t transmitPower, uint16_t companyIDIn) : + companyID(companyIDIn), ID(0x02), len(0x15), majorNumber(__REV16(majNum)), minorNumber(__REV16(minNum)), txPower(transmitPower) + { + memcpy(proximityUUID, uuid, sizeof(LocationUUID_t)); + } + }; + +public: + iBeaconService(BLEDevice &_ble, + LocationUUID_t uuid, + uint16_t majNum, + uint16_t minNum, + uint8_t txP = 0xC8, + uint16_t compID = 0x004C) : + ble(_ble), data(uuid, majNum, minNum, txP, compID) + { + // Generate the 0x020106 part of the iBeacon Prefix + ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE ); + // Generate the 0x1AFF part of the iBeacon Prefix + ble.accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, data.raw, sizeof(data.raw)); + + // Set advertising type + ble.setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED); + } + +private: + BLEDevice &ble; + Payload data; +}; + +#endif //__BLE_IBEACON_SERVICE_H__ \ No newline at end of file