High level Bluetooth Low Energy API and radio abstraction layer
Fork of BLE_API by
Revision 140:407d134c179d, committed 2014-11-21
- Comitter:
- rgrover1
- Date:
- Fri Nov 21 09:23:24 2014 +0000
- Parent:
- 139:baaf1c5f0db2
- Child:
- 141:bbc85b4fbdb7
- Commit message:
- Synchronized with git rev 5b8a2fb5
Author: Rohit Grover
making APIs within GattServer private; but adding friend BLEDevice.
Changed in this revision
--- a/README.md Fri Nov 21 09:23:24 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ -# mbed Bluetooth Low Energy Stack -This is the github repo for the BLE_API used by developer.mbed.org . The BLE stack is under development and constantly evolving. For up to date documentation please see [the mbed BLE Documentation page](http://developer.mbed.org/teams/Bluetooth-Low-Energy/code/BLE_API/docs/tip/). - -# Supported Services -Supported GATT services and constantly being added and can be found in the /services folder. -Currently supported services include: -* Battery -* Device Firmware Update (DFU) -* Device Information -* Health Thermometer -* Heart Rate -* UART - -# Getting Started -The mbed BLE API is meant to be used in projects on developer.mbed.org. Please see examples and sample project files there. -A good starting point are these pages: -* [mbed BLE API](developer.mbed.org/teams/Bluetooth-Low-Energy/) -* [mbed BLE Getting Started Guide](http://developer.mbed.org/forum/team-63-Bluetooth-Low-Energy-community/topic/5262/) \ No newline at end of file
--- a/common/blecommon.h Fri Nov 21 09:23:24 2014 +0000 +++ b/common/blecommon.h Fri Nov 21 09:23:24 2014 +0000 @@ -27,7 +27,6 @@ #endif #include <stdint.h> -#include <stddef.h> /** @defgroup BLE_UUID_VALUES Assigned Values for BLE UUIDs * @{ */
--- a/public/BLEDevice.h Fri Nov 21 09:23:24 2014 +0000 +++ b/public/BLEDevice.h Fri Nov 21 09:23:24 2014 +0000 @@ -17,6 +17,7 @@ #ifndef __BLE_DEVICE__ #define __BLE_DEVICE__ +#include "mbed.h" #include "blecommon.h" #include "Gap.h" #include "GattServer.h" @@ -42,13 +43,13 @@ * Set the BTLE MAC address and type. * @return BLE_ERROR_NONE on success. */ - ble_error_t setAddress(Gap::addr_type_t type, const uint8_t address[Gap::ADDR_LEN]); + ble_error_t setAddress(Gap::addr_type_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::addr_type_t *typeP, uint8_t address[Gap::ADDR_LEN]); + ble_error_t getAddress(Gap::addr_type_t *typeP, Gap::address_t address); /** * @param[in] advType @@ -228,7 +229,7 @@ * some object. */ void onDataWritten(void (*callback)(const GattCharacteristicWriteCBParams *eventDataP)); - template <typename T> void onDataWritten(T *objPtr, void (T::*memberPtr)(const GattCharacteristicWriteCBParams *context)); + template <typename T> void onDataWritten(T * objPtr, void (T::*memberPtr)(const GattCharacteristicWriteCBParams *context)); void onUpdatesEnabled(GattServer::EventCallback_t callback); void onUpdatesDisabled(GattServer::EventCallback_t callback); @@ -253,7 +254,7 @@ * @param localOnly * Only update the characteristic locally regardless of notify/indicate flags in the CCCD. */ - ble_error_t updateCharacteristicValue(uint16_t handle, const uint8_t* value, uint16_t size, bool localOnly = false); + ble_error_t updateCharacteristicValue(uint16_t handle, const uint8_t *value, uint16_t size, bool localOnly = false); /** * Yield control to the BLE stack or to other tasks waiting for events. This @@ -276,56 +277,56 @@ */ 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); + /** + * 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); + /** + * 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[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 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); + /** + * Set the radio's transmit power. + * @param[in] txPower Radio transmit power in dBm. + */ + ble_error_t setTxPower(int8_t txPower); public: BLEDevice() : transport(createBLEDeviceInstance()), advParams(), advPayload(), scanResponse(), needToSetAdvPayload(true) { @@ -365,13 +366,13 @@ } inline ble_error_t -BLEDevice::setAddress(Gap::addr_type_t type, const uint8_t address[Gap::ADDR_LEN]) +BLEDevice::setAddress(Gap::addr_type_t type, const Gap::address_t address) { return transport->getGap().setAddress(type, address); } inline ble_error_t -BLEDevice::getAddress(Gap::addr_type_t *typeP, uint8_t address[Gap::ADDR_LEN]) +BLEDevice::getAddress(Gap::addr_type_t *typeP, Gap::address_t address) { return transport->getGap().getAddress(typeP, address); } @@ -418,6 +419,7 @@ BLEDevice::accumulateAdvertisingPayload(GapAdvertisingData::Appearance app) { needToSetAdvPayload = true; + transport->getGap().setAppearance(app); return advPayload.addAppearance(app); } @@ -432,6 +434,9 @@ 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); } @@ -451,8 +456,11 @@ inline ble_error_t BLEDevice::startAdvertising(void) { + ble_error_t rc; + if ((rc = transport->getGattServer().initializeGATTDatabase()) != BLE_ERROR_NONE) { + return rc; + } if (needToSetAdvPayload) { - ble_error_t rc; if ((rc = setAdvertisingPayload()) != BLE_ERROR_NONE) { return rc; } @@ -507,7 +515,6 @@ transport->getGattServer().setOnDataWritten(objPtr, memberPtr); } - inline void BLEDevice::onUpdatesEnabled(GattServer::EventCallback_t callback) { @@ -544,7 +551,7 @@ } inline ble_error_t -BLEDevice::updateCharacteristicValue(uint16_t handle, const uint8_t* value, uint16_t size, bool localOnly) +BLEDevice::updateCharacteristicValue(uint16_t handle, const uint8_t *value, uint16_t size, bool localOnly) { return transport->getGattServer().updateValue(handle, const_cast<uint8_t *>(value), size, localOnly); }
--- a/public/CallChainOfFunctionPointersWithContext.h Fri Nov 21 09:23:24 2014 +0000 +++ b/public/CallChainOfFunctionPointersWithContext.h Fri Nov 21 09:23:24 2014 +0000 @@ -19,6 +19,7 @@ #include <string.h> #include "FunctionPointerWithContext.h" +namespace mbed { /** 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, @@ -26,6 +27,7 @@ * * Example: * @code + * #include "mbed.h" * * CallChainOfFunctionPointersWithContext<void *> chain; * @@ -145,4 +147,6 @@ CallChainOfFunctionPointersWithContext & operator = (const CallChainOfFunctionPointersWithContext &); }; -#endif \ No newline at end of file +} // namespace mbed + +#endif
--- a/public/FunctionPointerWithContext.h Fri Nov 21 09:23:24 2014 +0000 +++ b/public/FunctionPointerWithContext.h Fri Nov 21 09:23:24 2014 +0000 @@ -19,6 +19,7 @@ #include <string.h> +namespace mbed { /** A class for storing and calling a pointer to a static or member void function * which takes a context. @@ -125,5 +126,6 @@ * external memory to manage the chain. Also refer to * 'CallChain' as an alternative. */ }; +} // namespace mbed #endif // ifndef MBED_FUNCTIONPOINTER_WITH_CONTEXT_H \ No newline at end of file
--- a/public/Gap.h Fri Nov 21 09:23:24 2014 +0000 +++ b/public/Gap.h Fri Nov 21 09:23:24 2014 +0000 @@ -17,6 +17,7 @@ #ifndef __GAP_H__ #define __GAP_H__ +#include "mbed.h" #include "blecommon.h" #include "GapAdvertisingData.h" #include "GapAdvertisingParams.h" @@ -40,6 +41,7 @@ } addr_type_t; static const unsigned ADDR_LEN = 6; + typedef uint8_t address_t[ADDR_LEN]; /** * enumeration for disconnection reasons. The values for these reasons are @@ -63,48 +65,55 @@ typedef uint16_t Handle_t; 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.*/ + 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; + static const uint16_t UNIT_1_25_MS = 1250; /**< Number of microseconds in 1.25 milliseconds. */ + static uint16_t MSEC_TO_GAP_DURATION_UNITS(uint32_t durationInMillis) { + return (durationInMillis * 1000) / UNIT_1_25_MS; + } + public: /* These functions must be defined in the sub-class */ - virtual ble_error_t setAddress(addr_type_t type, const uint8_t address[ADDR_LEN]) = 0; - virtual ble_error_t getAddress(addr_type_t *typeP, uint8_t address[ADDR_LEN]) = 0; + virtual ble_error_t setAddress(addr_type_t type, const address_t address) = 0; + virtual ble_error_t getAddress(addr_type_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 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; + virtual ble_error_t startAdvertising(const GapAdvertisingParams &) = 0; + virtual ble_error_t stopAdvertising(void) = 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; - virtual ble_error_t setDeviceName(const uint8_t *deviceName) = 0; + 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; + virtual ble_error_t setAppearance(uint16_t appearance) = 0; + virtual ble_error_t getAppearance(uint16_t *appearanceP) = 0; typedef void (*EventCallback_t)(void); - typedef void (*ConnectionEventCallback_t)(Handle_t, const ConnectionParams_t *); + typedef void (*ConnectionEventCallback_t)(Handle_t, addr_type_t peerAddrType, const address_t peerAddr, const ConnectionParams_t *); typedef void (*DisconnectionEventCallback_t)(Handle_t, DisconnectionReason_t); /* Event callback handlers */ void setOnTimeout(EventCallback_t callback) { onTimeout = callback; } + void setOnConnection(ConnectionEventCallback_t callback) { onConnection = callback; } + void setOnDisconnection(DisconnectionEventCallback_t callback) { onDisconnection = callback; } - void processConnectionEvent(Handle_t handle, const ConnectionParams_t *params) { + void processConnectionEvent(Handle_t handle, addr_type_t type, const address_t addr, const ConnectionParams_t *params) { state.connected = 1; if (onConnection) { - onConnection(handle, params); + onConnection(handle, type, addr, params); } } @@ -136,7 +145,7 @@ } protected: - GapState_t state; + GapState_t state; private: EventCallback_t onTimeout;
--- a/public/GapAdvertisingParams.h Fri Nov 21 09:23:24 2014 +0000 +++ b/public/GapAdvertisingParams.h Fri Nov 21 09:23:24 2014 +0000 @@ -19,11 +19,6 @@ #include "blecommon.h" -#define GAP_ADV_PARAMS_INTERVAL_MIN (0x0020) -#define GAP_ADV_PARAMS_INTERVAL_MIN_NONCON (0x00A0) -#define GAP_ADV_PARAMS_INTERVAL_MAX (0x1000) -#define GAP_ADV_PARAMS_TIMEOUT_MAX (0x3FFF) - /**************************************************************************/ /*! \brief @@ -50,6 +45,11 @@ 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; + /**************************************************************************/ /*! \brief @@ -70,6 +70,7 @@ ADV_NON_CONNECTABLE_UNDIRECTED /**< Vol 3, Part C, Section 9.3.2 and Vol 6, Part B, Section 2.3.1.3 */ }; +public: GapAdvertisingParams(AdvertisingType advType = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED, uint16_t interval = GAP_ADV_PARAMS_INTERVAL_MIN_NONCON, uint16_t timeout = 0);
--- a/public/GapEvents.h Fri Nov 21 09:23:24 2014 +0000 +++ b/public/GapEvents.h Fri Nov 21 09:23:24 2014 +0000 @@ -18,6 +18,7 @@ #define __GAP_EVENTS_H__ #include "blecommon.h" +#include "mbed.h" /**************************************************************************/ /*!
--- a/public/GattAttribute.h Fri Nov 21 09:23:24 2014 +0000 +++ b/public/GattAttribute.h Fri Nov 21 09:23:24 2014 +0000 @@ -18,6 +18,8 @@ #ifndef __GATT_ATTRIBUTE_H__ #define __GATT_ATTRIBUTE_H__ +#include <stddef.h> + #include "blecommon.h" #include "UUID.h"
--- a/public/GattServer.h Fri Nov 21 09:23:24 2014 +0000 +++ b/public/GattServer.h Fri Nov 21 09:23:24 2014 +0000 @@ -17,7 +17,6 @@ #ifndef __GATT_SERVER_H__ #define __GATT_SERVER_H__ -#include "blecommon.h" #include "GattService.h" #include "GattServerEvents.h" #include "GattCharacteristicWriteCBParams.h" @@ -33,20 +32,29 @@ class GattServer { public: + /* Event callback handlers. */ + typedef void (*EventCallback_t)(uint16_t attributeHandle); + typedef void (*ServerEventCallback_t)(void); /**< independent of any particular attribute */ + typedef void (*ServerEventCallbackWithCount_t)(unsigned count); /**< independent of any particular attribute */ + +protected: + GattServer() : serviceCount(0), characteristicCount(0), onDataSent(NULL), onDataWritten(), onUpdatesEnabled(NULL), onUpdatesDisabled(NULL), onConfirmationReceived(NULL) { + /* empty */ + } + + 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(uint16_t handle, uint8_t buffer[], uint16_t *const lengthP) = 0; virtual ble_error_t updateValue(uint16_t, uint8_t[], uint16_t, bool localOnly = false) = 0; + virtual ble_error_t initializeGATTDatabase(void) = 0; // 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! - /* Event callback handlers. */ - typedef void (*EventCallback_t)(uint16_t attributeHandle); - typedef void (*ServerEventCallback_t)(void); /**< independent of any particular attribute */ - typedef void (*ServerEventCallbackWithCount_t)(unsigned count); /**< independent of any particular attribute */ void setOnDataSent(ServerEventCallbackWithCount_t callback) { onDataSent = callback; } @@ -67,6 +75,7 @@ onConfirmationReceived = callback; } +protected: void handleDataWrittenEvent(const GattCharacteristicWriteCBParams *params) { if (onDataWritten.hasCallbacksAttached()) { onDataWritten.call(params); @@ -100,14 +109,8 @@ } protected: - GattServer() : serviceCount(0), characteristicCount(0), onDataSent(NULL), onDataWritten(), onUpdatesEnabled(NULL), onUpdatesDisabled(NULL), onConfirmationReceived(NULL) { - /* empty */ - } - -protected: uint8_t serviceCount; uint8_t characteristicCount; - uint8_t descriptorCount; private: ServerEventCallbackWithCount_t onDataSent; @@ -115,6 +118,11 @@ EventCallback_t onUpdatesEnabled; EventCallback_t onUpdatesDisabled; EventCallback_t onConfirmationReceived; + +private: + /* disallow copy and assginment */ + GattServer(const GattServer &); + GattServer& operator=(const GattServer &); }; #endif // ifndef __GATT_SERVER_H__ \ No newline at end of file
--- a/public/GattServerEvents.h Fri Nov 21 09:23:24 2014 +0000 +++ b/public/GattServerEvents.h Fri Nov 21 09:23:24 2014 +0000 @@ -18,6 +18,7 @@ #define __GATT_SERVER_EVENTS_H__ #include "blecommon.h" +#include "mbed.h" /**************************************************************************/ /*!
--- a/services/UARTService.h Fri Nov 21 09:23:24 2014 +0000 +++ b/services/UARTService.h Fri Nov 21 09:23:24 2014 +0000 @@ -17,7 +17,6 @@ #ifndef __BLE_UART_SERVICE_H__ #define __BLE_UART_SERVICE_H__ -#include "mbed.h" #include "Stream.h" #include "UUID.h"