From c8eccb0222eef43ed0732dad7c6d16bdc45ab5ce Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Tue, 2 Sep 2014 15:09:46 +0100 Subject: [PATCH] Release 0.1.0 ============= Mostly API changes. Features ~~~~~~~~ - onConnection() callback now receives connection-parameters applicable to the new connection. - onDataSent() callback now receives a count parameter containing the number of times notifications were sent out since the last callback. - A 'reason' parameter has been added to Gap::disconnect() to indicate the reason for disconnection; and also to the onDisconnection callback to receive a reason from the remote host. Bugfixes ~~~~~~~~ - onDataWritten() callback now receives an additional parameter (GattServer::WriteEventCallback_t) encapsulating the update. This avoids having to re-fetch the updated characteristic's value attribute. It also fixes a bug where multiple updates to the characteristic's value-attribute could get clobbered if they occurred in quick succession before the callbacks could be processed. --- common/UUID.cpp | 4 +- public/BLEDevice.h | 30 +++++++------- public/Gap.h | 51 ++++++++++++++---------- public/GapAdvertisingParams.h | 23 ++++------- public/GapEvents.h | 39 ++---------------- public/GattCharacteristicWriteCBParams.h | 35 ++++++++++++++++ public/GattServer.h | 46 ++++++++++----------- public/GattServerEvents.h | 47 ---------------------- public/UUID.h | 16 ++++---- 9 files changed, 120 insertions(+), 171 deletions(-) create mode 100644 public/GattCharacteristicWriteCBParams.h diff --git a/common/UUID.cpp b/common/UUID.cpp index afb872d..c2f9dc4 100644 --- a/common/UUID.cpp +++ b/common/UUID.cpp @@ -64,7 +64,7 @@ @endcode */ /**************************************************************************/ -UUID::UUID(const LongUUID_t longUUID) : type(UUID_TYPE_SHORT), baseUUID(), shortUUID(0) +UUID::UUID(const LongUUIDBytes_t longUUID) : type(UUID_TYPE_SHORT), baseUUID(), shortUUID(0) { memcpy(baseUUID, longUUID, LENGTH_OF_LONG_UUID); shortUUID = (uint16_t)((longUUID[2] << 8) | (longUUID[3])); @@ -98,7 +98,7 @@ UUID::UUID(const LongUUID_t longUUID) : type(UUID_TYPE_SHORT), baseUUID(), short The 16-bit BLE UUID value. */ /**************************************************************************/ -UUID::UUID(ShortUUID_t shortUUID) : type(UUID_TYPE_SHORT), baseUUID(), shortUUID(shortUUID) +UUID::UUID(ShortUUIDBytes_t shortUUID) : type(UUID_TYPE_SHORT), baseUUID(), shortUUID(shortUUID) { /* empty */ } diff --git a/public/BLEDevice.h b/public/BLEDevice.h index 9f2e93f..8f6940e 100644 --- a/public/BLEDevice.h +++ b/public/BLEDevice.h @@ -194,27 +194,27 @@ public: */ ble_error_t stopAdvertising(void); - ble_error_t disconnect(void); + ble_error_t disconnect(Gap::DisconnectionReason_t reason); /* APIs to set GAP callbacks. */ void onTimeout(Gap::EventCallback_t timeoutCallback); - void onConnection(Gap::HandleSpecificEventCallback_t connectionCallback); + void onConnection(Gap::ConnectionEventCallback_t connectionCallback); /** * Used to setup a callback for GAP disconnection. */ - void onDisconnection(Gap::HandleSpecificEventCallback_t disconnectionCallback); + void onDisconnection(Gap::DisconnectionEventCallback_t disconnectionCallback); /** * Setup a callback for the GATT event DATA_SENT. */ - void onDataSent(GattServer::ServerEventCallback_t callback); + void onDataSent(GattServer::ServerEventCallbackWithCount_t callback); /** * Setup a callback for when a characteristic has its value updated by a * client. */ - void onDataWritten(GattServer::EventCallback_t callback); + void onDataWritten(GattServer::WriteEventCallback_t callback); void onUpdatesEnabled(GattServer::EventCallback_t callback); void onUpdatesDisabled(GattServer::EventCallback_t callback); void onConfirmationReceived(GattServer::EventCallback_t callback); @@ -443,9 +443,9 @@ BLEDevice::stopAdvertising(void) } inline ble_error_t -BLEDevice::disconnect(void) +BLEDevice::disconnect(Gap::DisconnectionReason_t reason) { - return transport->getGap().disconnect(); + return transport->getGap().disconnect(reason); } inline void @@ -455,25 +455,25 @@ BLEDevice::onTimeout(Gap::EventCallback_t timeoutCallback) } inline void -BLEDevice::onConnection(Gap::HandleSpecificEventCallback_t connectionCallback) +BLEDevice::onConnection(Gap::ConnectionEventCallback_t connectionCallback) { transport->getGap().setOnConnection(connectionCallback); } inline void -BLEDevice::onDisconnection(Gap::HandleSpecificEventCallback_t disconnectionCallback) +BLEDevice::onDisconnection(Gap::DisconnectionEventCallback_t disconnectionCallback) { transport->getGap().setOnDisconnection(disconnectionCallback); } inline void -BLEDevice::onDataSent(GattServer::ServerEventCallback_t callback) +BLEDevice::onDataSent(GattServer::ServerEventCallbackWithCount_t callback) { transport->getGattServer().setOnDataSent(callback); } inline void -BLEDevice::onDataWritten(GattServer::EventCallback_t callback) +BLEDevice::onDataWritten(GattServer::WriteEventCallback_t callback) { transport->getGattServer().setOnDataWritten(callback); } @@ -551,25 +551,25 @@ BLEDevice::getVersion(void) inline ble_error_t BLEDevice::setDeviceName(const uint8_t *deviceName) { - return transport->getGattServer().setDeviceName(deviceName); + return transport->getGap().setDeviceName(deviceName); } inline ble_error_t BLEDevice::getDeviceName(uint8_t *deviceName, unsigned *lengthP) { - return transport->getGattServer().getDeviceName(deviceName, lengthP); + return transport->getGap().getDeviceName(deviceName, lengthP); } inline ble_error_t BLEDevice::setAppearance(uint16_t appearance) { - return transport->getGattServer().setAppearance(appearance); + return transport->getGap().setAppearance(appearance); } inline ble_error_t BLEDevice::getAppearance(uint16_t *appearanceP) { - return transport->getGattServer().getAppearance(appearanceP); + return transport->getGap().getAppearance(appearanceP); } inline ble_error_t diff --git a/public/Gap.h b/public/Gap.h index 6f2b78c..1ce8ef5 100644 --- a/public/Gap.h +++ b/public/Gap.h @@ -40,6 +40,12 @@ public: ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE } addr_type_t; + enum DisconnectionReason_t { + REMOTE_USER_TERMINATED_CONNECTION, + CONN_INTERVAL_UNACCEPTABLE, + LOCAL_HOST_TERMINATED_CONNECTION, + }; + /* Describes the current state of the device (more than one bit can be set) */ typedef struct GapState_s { unsigned advertising : 1; /**< peripheral is currently advertising */ @@ -61,39 +67,42 @@ public: 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(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 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; + typedef void (*EventCallback_t)(void); - typedef void (*HandleSpecificEventCallback_t)(Handle_t); + typedef void (*ConnectionEventCallback_t)(Handle_t, const ConnectionParams_t *); + typedef void (*DisconnectionEventCallback_t)(Handle_t, DisconnectionReason_t); /* Event callback handlers */ void setOnTimeout(EventCallback_t callback) { onTimeout = callback; } - void setOnConnection(HandleSpecificEventCallback_t callback) { + void setOnConnection(ConnectionEventCallback_t callback) { onConnection = callback; } - void setOnDisconnection(HandleSpecificEventCallback_t callback) { + void setOnDisconnection(DisconnectionEventCallback_t callback) { onDisconnection = callback; } - void processHandleSpecificEvent(GapEvents::gapEvent_e type, Handle_t handle) { - switch (type) { - case GapEvents::GAP_EVENT_CONNECTED: - state.connected = 1; - if (onConnection) { - onConnection(handle); - } - break; - case GapEvents::GAP_EVENT_DISCONNECTED: - state.connected = 0; - if (onDisconnection) { - onDisconnection(handle); - } - break; + void processConnectionEvent(Handle_t handle, const ConnectionParams_t *params) { + state.connected = 1; + if (onConnection) { + onConnection(handle, params); + } + } + + void processDisconnectionEvent(Handle_t handle, DisconnectionReason_t reason) { + state.connected = 0; + if (onDisconnection) { + onDisconnection(handle, reason); } } @@ -121,9 +130,9 @@ protected: GapState_t state; private: - EventCallback_t onTimeout; - HandleSpecificEventCallback_t onConnection; - HandleSpecificEventCallback_t onDisconnection; + EventCallback_t onTimeout; + ConnectionEventCallback_t onConnection; + DisconnectionEventCallback_t onDisconnection; }; #endif // ifndef __GAP_H__ diff --git a/public/GapAdvertisingParams.h b/public/GapAdvertisingParams.h index cd6080e..d757ef7 100644 --- a/public/GapAdvertisingParams.h +++ b/public/GapAdvertisingParams.h @@ -63,23 +63,15 @@ public: \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 */ + 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 */ }; - GapAdvertisingParams(AdvertisingType advType = - GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED, - uint16_t interval = - GAP_ADV_PARAMS_INTERVAL_MIN_NONCON, + GapAdvertisingParams(AdvertisingType advType = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED, + uint16_t interval = GAP_ADV_PARAMS_INTERVAL_MIN_NONCON, uint16_t timeout = 0); virtual ~GapAdvertisingParams(void); @@ -146,5 +138,4 @@ GapAdvertisingParams::getTimeout(void) const return _timeout; } - #endif // ifndef __GAP_ADVERTISING_PARAMS_H__ diff --git a/public/GapEvents.h b/public/GapEvents.h index 002d0be..31b8a60 100644 --- a/public/GapEvents.h +++ b/public/GapEvents.h @@ -38,43 +38,10 @@ public: */ /******************************************************************/ 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 */ + 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; - - /******************************************************************/ - /*! - \brief - Advertising timed out before a connection was established - */ - /******************************************************************/ - virtual void onTimeout(void) { - } - - /******************************************************************/ - /*! - \brief - A connection was established with a central device - */ - /******************************************************************/ - virtual void onConnected(void) { - } - - /******************************************************************/ - /*! - \brief - A connection was closed or lost with a central device - */ - /******************************************************************/ - virtual void onDisconnected(void) { - } }; #endif // ifndef __GAP_EVENTS_H__ diff --git a/public/GattCharacteristicWriteCBParams.h b/public/GattCharacteristicWriteCBParams.h new file mode 100644 index 0000000..813d3f1 --- /dev/null +++ b/public/GattCharacteristicWriteCBParams.h @@ -0,0 +1,35 @@ +/* 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_WRITE_CB_PARAMS_H__ +#define __GATT_CHARACTERISTIC_WRITE_CB_PARAMS_H__ + +struct GattCharacteristicWriteCBParams { + 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. */ +}; + +#endif /*__GATT_CHARACTERISTIC_WRITE_CB_PARAMS_H__*/ diff --git a/public/GattServer.h b/public/GattServer.h index 62242d3..68805d9 100644 --- a/public/GattServer.h +++ b/public/GattServer.h @@ -21,6 +21,7 @@ #include "blecommon.h" #include "GattService.h" #include "GattServerEvents.h" +#include "GattCharacteristicWriteCBParams.h" /**************************************************************************/ /*! @@ -36,10 +37,6 @@ public: 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 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; // 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 @@ -48,11 +45,13 @@ public: /* Event callback handlers. */ typedef void (*EventCallback_t)(uint16_t attributeHandle); - typedef void (*ServerEventCallback_t)(void); /* independent of any particular attribute */ - void setOnDataSent(ServerEventCallback_t callback) { + typedef void (*WriteEventCallback_t)(uint16_t attributeHandle, const GattCharacteristicWriteCBParams *eventDataP); + 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; } - void setOnDataWritten(EventCallback_t callback) { + void setOnDataWritten(WriteEventCallback_t callback) { onDataWritten = callback; } void setOnUpdatesEnabled(EventCallback_t callback) { @@ -65,13 +64,14 @@ public: onConfirmationReceived = callback; } + void handleDataWrittenEvent(uint16_t charHandle, const GattCharacteristicWriteCBParams *params) { + if (onDataWritten) { + onDataWritten(charHandle, params); + } + } + void handleEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle) { switch (type) { - case GattServerEvents::GATT_EVENT_DATA_WRITTEN: - if (onDataWritten) { - onDataWritten(charHandle); - } - break; case GattServerEvents::GATT_EVENT_UPDATES_ENABLED: if (onUpdatesEnabled) { onUpdatesEnabled(charHandle); @@ -90,15 +90,9 @@ public: } } - void handleEvent(GattServerEvents::gattEvent_e type) { - switch (type) { - case GattServerEvents::GATT_EVENT_DATA_SENT: - if (onDataSent) { - onDataSent(); - } - break; - default: - break; + void handleDataSentEvent(unsigned count) { + if (onDataSent) { + onDataSent(count); } } @@ -113,11 +107,11 @@ protected: uint8_t descriptorCount; private: - ServerEventCallback_t onDataSent; - EventCallback_t onDataWritten; - EventCallback_t onUpdatesEnabled; - EventCallback_t onUpdatesDisabled; - EventCallback_t onConfirmationReceived; + ServerEventCallbackWithCount_t onDataSent; + WriteEventCallback_t onDataWritten; + EventCallback_t onUpdatesEnabled; + EventCallback_t onUpdatesDisabled; + EventCallback_t onConfirmationReceived; }; #endif // ifndef __GATT_SERVER_H__ diff --git a/public/GattServerEvents.h b/public/GattServerEvents.h index 25d28ff..21e871c 100644 --- a/public/GattServerEvents.h +++ b/public/GattServerEvents.h @@ -44,53 +44,6 @@ public: GATT_EVENT_UPDATES_DISABLED = 4, /**< Notify/Indicate Disabled in CCCD */ GATT_EVENT_CONFIRMATION_RECEIVED = 5 /**< Response received from Indicate message */ } gattEvent_t; - - /******************************************************************/ - /*! - \brief - A message was successfully transmitted - */ - /******************************************************************/ - virtual void onDataSent(uint16_t charHandle) { - } - - /******************************************************************/ - /*! - \brief - The GATT client (the phone, tablet, etc.) wrote data to a - characteristic or descriptor on the GATT Server (the peripheral - device). - */ - /******************************************************************/ - virtual void onDataWritten(uint16_t charHandle) { - } - - /******************************************************************/ - /*! - \brief - A Notify or Indicate flag was enabled in the CCCD - */ - /******************************************************************/ - virtual void onUpdatesEnabled(uint16_t charHandle) { - } - - /******************************************************************/ - /*! - \brief - A Notify or Indicate flag was disabled in the CCCD - */ - /******************************************************************/ - virtual void onUpdatesDisabled(uint16_t charHandle) { - } - - /******************************************************************/ - /*! - \brief - A confirmation response was received from an Indicate message - */ - /******************************************************************/ - virtual void onConfirmationReceived(uint16_t charHandle) { - } }; #endif // ifndef __GATT_SERVER_EVENTS_H__ diff --git a/public/UUID.h b/public/UUID.h index 370d5e8..363bee1 100644 --- a/public/UUID.h +++ b/public/UUID.h @@ -21,8 +21,8 @@ #include "blecommon.h" const unsigned LENGTH_OF_LONG_UUID = 16; -typedef uint16_t ShortUUID_t; -typedef uint8_t LongUUID_t[LENGTH_OF_LONG_UUID]; +typedef uint16_t ShortUUIDBytes_t; +typedef uint8_t LongUUIDBytes_t[LENGTH_OF_LONG_UUID]; class UUID { @@ -33,8 +33,8 @@ public: }; public: - UUID(const LongUUID_t); - UUID(ShortUUID_t); + UUID(const LongUUIDBytes_t); + UUID(ShortUUIDBytes_t); virtual ~UUID(void); public: @@ -44,18 +44,18 @@ public: const uint8_t* getBaseUUID(void) const { return baseUUID; } - ShortUUID_t getShortUUID(void) const { + ShortUUIDBytes_t getShortUUID(void) const { return shortUUID; } private: - uint8_t type; // UUID_TYPE_SHORT or UUID_TYPE_LONG - LongUUID_t baseUUID; /* the base of the long UUID (if + uint8_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.*/ - ShortUUID_t shortUUID; // 16 bit uuid (byte 2-3 using with base) + ShortUUIDBytes_t shortUUID; // 16 bit uuid (byte 2-3 using with base) }; #endif // ifndef __UUID_H__