Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of Nucleo_BLE_API by
Revision 0:289fd2dae405, committed 2014-12-19
- Comitter:
- sjallouli
- Date:
- Fri Dec 19 18:54:46 2014 +0000
- Child:
- 1:79e5c08cbcc7
- Commit message:
- BLE_API for Nucleo Bluetoothe Low Energy Shield
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/common/BLEDevice.cpp Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,38 @@
+/* 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 "BLEDevice.h"
+
+#if defined(TARGET_OTA_ENABLED)
+#include "DFUService.h"
+#endif
+
+ble_error_t
+BLEDevice::init()
+{
+ ble_error_t err = transport->init();
+ if (err != BLE_ERROR_NONE) {
+ return err;
+ }
+
+ /* Platforms enabled for DFU should introduce the DFU Service into
+ * applications automatically. */
+#if defined(TARGET_OTA_ENABLED)
+ static DFUService dfu(*this); // defined static so that the object remains alive
+#endif // TARGET_OTA_ENABLED
+
+ return BLE_ERROR_NONE;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/common/BLEDeviceInstanceBase.h Fri Dec 19 18:54:46 2014 +0000
@@ -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 __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 reset(void) = 0;
+ virtual ble_error_t setTxPower(int8_t txPower) = 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__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/common/GapAdvertisingData.cpp Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,238 @@
+/* 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 <stdio.h>
+#include <string.h>
+
+#include "GapAdvertisingData.h"
+
+/**************************************************************************/
+/*!
+ \brief Creates a new GapAdvertisingData instance
+
+ \par EXAMPLE
+
+ \code
+
+ \endcode
+*/
+/**************************************************************************/
+GapAdvertisingData::GapAdvertisingData(void) : _payload(), _payloadLen(0), _appearance(GENERIC_TAG) {
+ /* empty */
+}
+
+/**************************************************************************/
+/*!
+ Destructor
+*/
+/**************************************************************************/
+GapAdvertisingData::~GapAdvertisingData(void)
+{
+}
+
+/**************************************************************************/
+/*!
+ \brief Adds advertising data based on the specified AD type (see
+ DataType)
+
+ \args[in] advDataType The Advertising 'DataType' to add
+ \args[in] payload Pointer to the payload contents
+ \args[in] len Size of the payload in bytes
+
+ \returns ble_error_t
+
+ \retval BLE_ERROR_NONE
+ Everything executed properly
+
+ \retval BLE_ERROR_BUFFER_OVERFLOW
+ The specified data would cause the advertising buffer
+ to overflow
+
+ \par EXAMPLE
+
+ \code
+
+ \endcode
+*/
+/**************************************************************************/
+ble_error_t GapAdvertisingData::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;
+}
+
+/**************************************************************************/
+/*!
+ \brief Helper function to add APPEARANCE data to the advertising
+ payload
+
+ \args[in] appearance The APPEARANCE value to add
+
+ \returns ble_error_t
+
+ \retval BLE_ERROR_NONE
+ Everything executed properly
+
+ \retval BLE_ERROR_BUFFER_OVERFLOW
+ The specified data would cause the advertising buffer
+ to overflow
+
+ \par EXAMPLE
+
+ \code
+
+ \endcode
+*/
+/**************************************************************************/
+ble_error_t GapAdvertisingData::addAppearance(Appearance appearance)
+{
+ _appearance = appearance;
+ return addData(GapAdvertisingData::APPEARANCE, (uint8_t *)&appearance, 2);
+}
+
+/**************************************************************************/
+/*!
+ \brief Helper function to add FLAGS data to the advertising
+ payload
+
+ \args[in] flag The FLAGS value to add
+
+ \par LE_LIMITED_DISCOVERABLE
+ The peripheral is discoverable for a limited period of
+ time
+
+ \par LE_GENERAL_DISCOVERABLE
+ The peripheral is permanently discoverable
+
+ \par BREDR_NOT_SUPPORTED
+ This peripheral is a Bluetooth Low Energy only device
+ (no EDR support)
+
+ \returns ble_error_t
+
+ \retval BLE_ERROR_NONE
+ Everything executed properly
+
+ \retval BLE_ERROR_BUFFER_OVERFLOW
+ The specified data would cause the advertising buffer
+ to overflow
+
+ \par EXAMPLE
+
+ \code
+
+ \endcode
+*/
+/**************************************************************************/
+ble_error_t GapAdvertisingData::addFlags(uint8_t flags)
+{
+ return addData(GapAdvertisingData::FLAGS, &flags, 1);
+}
+
+/**************************************************************************/
+/*!
+ \brief Helper function to add TX_POWER_LEVEL data to the
+ advertising payload
+
+ \args[in] flag The TX_POWER_LEVEL value to add
+
+ \returns ble_error_t
+
+ \retval BLE_ERROR_NONE
+ Everything executed properly
+
+ \retval BLE_ERROR_BUFFER_OVERFLOW
+ The specified data would cause the advertising buffer
+ to overflow
+
+ \par EXAMPLE
+
+ \code
+
+ \endcode
+*/
+/**************************************************************************/
+ble_error_t GapAdvertisingData::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);
+}
+
+/**************************************************************************/
+/*!
+ \brief Clears the payload and resets the payload length counter
+*/
+/**************************************************************************/
+void GapAdvertisingData::clear(void)
+{
+ memset(&_payload, 0, GAP_ADVERTISING_DATA_MAX_PAYLOAD);
+ _payloadLen = 0;
+}
+
+/**************************************************************************/
+/*!
+ \brief Returns a pointer to the the current payload
+
+ \returns A pointer to the payload
+*/
+/**************************************************************************/
+const uint8_t *GapAdvertisingData::getPayload(void) const
+{
+ return (_payloadLen > 0) ? _payload : NULL;
+}
+
+/**************************************************************************/
+/*!
+ \brief Returns the current payload length (0..31 bytes)
+
+ \returns The payload length in bytes
+*/
+/**************************************************************************/
+uint8_t GapAdvertisingData::getPayloadLen(void) const
+{
+ return _payloadLen;
+}
+
+/**************************************************************************/
+/*!
+ \brief Returns the 16-bit appearance value for this device
+
+ \returns The 16-bit appearance value
+*/
+/**************************************************************************/
+uint16_t GapAdvertisingData::getAppearance(void) const
+{
+ return (uint16_t)_appearance;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/common/GapAdvertisingParams.cpp Fri Dec 19 18:54:46 2014 +0000
@@ -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.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "blecommon.h"
+#include "GapAdvertisingParams.h"
+
+/**************************************************************************/
+/*!
+ \brief
+ Instantiates a new GapAdvertisingParams instance
+
+ \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
+ Any central device can connect to this peripheral, and
+ the secondary Scan Response payload will be included or
+ available to central devices.
+
+ \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
+
+ \param[in] interval
+ Advertising interval between 0x0020 and 0x4000 in 0.625ms units
+ (20ms to 10.24s). If using non-connectable mode
+ (ADV_NON_CONNECTABLE_UNDIRECTED) this min value is 0x00A0
+ (100ms). To reduce the likelihood of collisions, the link layer
+ perturbs this interval by a pseudo-random delay with a range of
+ 0 ms to 10 ms for each advertising event.
+
+ \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.
+
+ \param[in] timeout
+ Advertising timeout between 0x1 and 0x3FFF (1 and 16383)
+ in seconds. Enter 0 to disable the advertising timeout.
+
+ \par EXAMPLE
+
+ \code
+
+ \endcode
+*/
+/**************************************************************************/
+GapAdvertisingParams::GapAdvertisingParams(AdvertisingType advType, uint16_t interval, uint16_t timeout)
+{
+ _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;
+ }
+ }
+}
+
+/**************************************************************************/
+/*!
+ Destructor
+*/
+/**************************************************************************/
+GapAdvertisingParams::~GapAdvertisingParams(void)
+{
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/common/GattService.cpp Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,43 @@
+/* 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 <stdio.h>
+#include <string.h>
+
+#include "GattService.h"
+
+/**************************************************************************/
+/*!
+ @brief Creates a new GattService using the specified 128-bit UUID
+
+ @note The UUID value must be unique on the device
+
+ @param[in] uuid
+ The 16 byte (128-bit) UUID to use for this characteristic
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+GattService::GattService(const UUID &uuid, GattCharacteristic *characteristics[], unsigned numCharacteristics) :
+ _primaryServiceID(uuid), _characteristicCount(numCharacteristics), _characteristics(characteristics), _handle(0)
+{
+ /* empty */
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/common/UUID.cpp Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,113 @@
+/* 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 <stdio.h>
+#include <string.h>
+
+#include "UUID.h"
+
+/**************************************************************************/
+/*!
+ @brief 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.
+
+ @note When creating a UUID, the constructor will check if all bytes
+ except bytes 2/3 are equal to 0. If only bytes 2/3 have a
+ value, the UUID will be treated as a short/BLE UUID, and the
+ .type field will be set to UUID::UUID_TYPE_SHORT. If any
+ of the bytes outside byte 2/3 have a non-zero value, the UUID
+ will be considered a 128-bit ID, and .type will be assigned
+ as UUID::UUID_TYPE_LONG.
+
+ @param[in] uuid_base
+ The 128-bit (16-byte) UUID value. For 128-bit values,
+ assign all 16 bytes. For 16-bit values, assign the
+ 16-bits to byte 2 and 3, and leave the rest of the bytes
+ as 0.
+
+ @section EXAMPLE
+
+ @code
+
+ // Create a short UUID (0x180F)
+ uint8_t shortID[16] = { 0, 0, 0x0F, 0x18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ UUID ble_uuid = UUID(shortID);
+ // ble_uuid.type = UUID_TYPE_SHORT
+ // ble_uuid.value = 0x180F
+
+ // Creeate a long UUID
+ uint8_t longID[16] = { 0x00, 0x11, 0x22, 0x33,
+ 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xAA, 0xBB,
+ 0xCC, 0xDD, 0xEE, 0xFF };
+ UUID custom_uuid = UUID(longID);
+ // custom_uuid.type = UUID_TYPE_LONG
+ // custom_uuid.value = 0x3322
+ // custom_uuid.base = 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF
+
+ @endcode
+*/
+/**************************************************************************/
+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]));
+
+ /* Check if this is a short of a long UUID */
+ unsigned index;
+ for (index = 0; index < LENGTH_OF_LONG_UUID; index++) {
+ if ((index == 2) || (index == 3)) {
+ continue; /* we should not consider bytes 2 and 3 because that's
+ * where the 16-bit relative UUID is placed. */
+ }
+
+ if (baseUUID[index] != 0) {
+ type = UUID_TYPE_LONG;
+
+ /* zero out the 16-bit part in the base; this will help equate long
+ * UUIDs when they differ only in this 16-bit relative part.*/
+ baseUUID[2] = 0;
+ baseUUID[3] = 0;
+
+ return;
+ }
+ }
+}
+
+/**************************************************************************/
+/*!
+ @brief Creates a short (16-bit) UUID
+
+ @param[in] ble_uuid
+ The 16-bit BLE UUID value.
+*/
+/**************************************************************************/
+UUID::UUID(ShortUUIDBytes_t shortUUID) : type(UUID_TYPE_SHORT), baseUUID(), shortUUID(shortUUID)
+{
+ /* empty */
+}
+
+/**************************************************************************/
+/*!
+ @brief UUID destructor
+*/
+/**************************************************************************/
+UUID::~UUID(void)
+{
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/common/blecommon.h Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,135 @@
+/* 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__
+
+#define NRF51
+#define DEBUG_NRF_USER
+#define BLE_STACK_SUPPORT_REQD
+#define BOARD_PCA10001
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+/** @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
+*/
+/**************************************************************************/
+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_STACK_BUSY = 4, /**< The stack is busy */
+} ble_error_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ifndef __BLE_COMMON_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/readme.txt Fri Dec 19 18:54:46 2014 +0000 @@ -0,0 +1,1 @@ +These files are common to all implementations of the BLE_API. \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/public/BLEDevice.h Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,626 @@
+/* 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 "mbed.h"
+#include "blecommon.h"
+#include "Gap.h"
+#include "GattServer.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.
+ */
+ ble_error_t init();
+ ble_error_t reset(void);
+
+ /* GAP specific APIs */
+public:
+ /**
+ * Set the BTLE MAC address and type.
+ * @return
+ */
+ ble_error_t setAddress(Gap::addr_type_t type, const uint8_t address[6]);
+
+ /**
+ * @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
+ * Any central device can connect to this peripheral, and
+ * the secondary Scan Response payload will be included or
+ * available to central devices.
+ *
+ * \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 between 0x0020 and 0x4000 in 0.625ms
+ * units (20ms to 10.24s). If using non-connectable mode
+ * (ADV_NON_CONNECTABLE_UNDIRECTED) this min value is
+ * 0x00A0 (100ms). To reduce the likelihood of collisions, the
+ * link layer perturbs this interval by a pseudo-random delay
+ * with a range of 0 ms to 10 ms for each advertising event.
+ *
+ * \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.
+ */
+ void setAdvertisingInterval(uint16_t interval);
+
+ /**
+ * @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);
+
+ /**
+ * 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);
+
+ /**
+ * Reset any advertising payload prepared from prior calls to
+ * accumulateAdvertisingPayload().
+ */
+ 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);
+
+ /**
+ * 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);
+
+ 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);
+
+ /**
+ * Setup a callback for the GATT event DATA_SENT.
+ */
+ void onDataSent(GattServer::ServerEventCallbackWithCount_t callback);
+
+ /**
+ * 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));
+
+ void onUpdatesEnabled(GattServer::EventCallback_t callback);
+ void onUpdatesDisabled(GattServer::EventCallback_t callback);
+ void onConfirmationReceived(GattServer::EventCallback_t callback);
+
+ /**
+ * Add a service declaration to the local server ATT table. Also add the
+ * characteristics contained within.
+ */
+ ble_error_t addService(GattService &service);
+
+ 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(uint16_t handle, uint8_t *const buffer, uint16_t *const lengthP);
+
+ /**
+ * @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);
+
+ /**
+ * 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);
+
+public:
+ BLEDevice() : transport(createBLEDeviceInstance()), advParams(), advPayload(), scanResponse(), needToSetAdvPayload(true) {
+ 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;
+
+ /**
+ * DEPRECATED
+ */
+public:
+ ble_error_t setAdvertisingData(const GapAdvertisingData &ADStructures, const GapAdvertisingData &scanResponse);
+ ble_error_t setAdvertisingData(const GapAdvertisingData &ADStructures);
+
+ ble_error_t startAdvertising(const GapAdvertisingParams &advParams);
+};
+
+/* 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::setAddress(Gap::addr_type_t type, const uint8_t address[6])
+{
+ return transport->getGap().setAddress(type, address);
+}
+
+inline void
+BLEDevice::setAdvertisingType(GapAdvertisingParams::AdvertisingType advType)
+{
+ advParams.setAdvertisingType(advType);
+}
+
+inline void
+BLEDevice::setAdvertisingInterval(uint16_t interval)
+{
+ advParams.setInterval(interval);
+}
+
+inline void
+BLEDevice::setAdvertisingTimeout(uint16_t timeout)
+{
+ advParams.setTimeout(timeout);
+}
+
+inline void
+BLEDevice::setAdvertisingParams(const GapAdvertisingParams &newAdvParams)
+{
+ advParams = newAdvParams;
+}
+
+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;
+ 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;
+ 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 ble_error_t
+BLEDevice::setAdvertisingPayload(void) {
+ needToSetAdvPayload = false;
+ return transport->getGap().setAdvertisingData(advPayload, scanResponse);
+}
+
+inline ble_error_t
+BLEDevice::startAdvertising(void)
+{
+ if (needToSetAdvPayload) {
+ ble_error_t rc;
+ 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::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);
+}
+
+inline void
+BLEDevice::onDataSent(GattServer::ServerEventCallbackWithCount_t callback)
+{
+ transport->getGattServer().setOnDataSent(callback);
+}
+
+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 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 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(uint16_t handle, uint8_t *const buffer, uint16_t *const lengthP)
+{
+ return transport->getGattServer().readValue(handle, buffer, lengthP);
+}
+
+inline ble_error_t
+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);
+}
+
+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);
+}
+
+/*
+ * ALL OF THE FOLLOWING METHODS ARE DEPRECATED
+ */
+
+inline ble_error_t
+BLEDevice::setAdvertisingData(const GapAdvertisingData &ADStructures, const GapAdvertisingData &scanResponse)
+{
+ needToSetAdvPayload = false;
+ return transport->getGap().setAdvertisingData(ADStructures, scanResponse);
+}
+
+inline ble_error_t
+BLEDevice::setAdvertisingData(const GapAdvertisingData &ADStructures)
+{
+ GapAdvertisingData scanResponse;
+
+ needToSetAdvPayload = false;
+ return transport->getGap().setAdvertisingData(ADStructures, scanResponse);
+}
+
+inline ble_error_t
+BLEDevice::startAdvertising(const GapAdvertisingParams &_advParams)
+{
+ return transport->getGap().startAdvertising(_advParams);
+}
+
+#endif // ifndef __BLE_DEVICE__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/public/CallChainOfFunctionPointersWithContext.h Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,153 @@
+/* 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"
+
+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,
+ * but can be used for other purposes.
+ *
+ * Example:
+ * @code
+ * #include "mbed.h"
+ *
+ * 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 &);
+};
+
+} // namespace mbed
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/public/FunctionPointerWithContext.h Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,131 @@
+/* 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>
+
+namespace mbed {
+
+/** 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. */
+};
+} // namespace mbed
+
+#endif // ifndef MBED_FUNCTIONPOINTER_WITH_CONTEXT_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/public/Gap.h Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,145 @@
+/* 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 "mbed.h"
+#include "blecommon.h"
+#include "GapAdvertisingData.h"
+#include "GapAdvertisingParams.h"
+#include "GapEvents.h"
+
+/**************************************************************************/
+/*!
+ \brief
+ The base class used to abstract GAP functionality to a specific radio
+ transceiver, SOC or BLE Stack.
+*/
+/**************************************************************************/
+class Gap
+{
+public:
+ typedef enum addr_type_e {
+ ADDR_TYPE_PUBLIC = 0,
+ ADDR_TYPE_RANDOM_STATIC,
+ ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE,
+ ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE
+ } addr_type_t;
+
+ /**
+ * 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 {
+ 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) */
+ typedef struct GapState_s {
+ unsigned advertising : 1; /**< peripheral is currently advertising */
+ unsigned connected : 1; /**< peripheral is connected to a central */
+ } GapState_t;
+
+ 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.*/
+ } ConnectionParams_t;
+
+public:
+ /* These functions must be defined in the sub-class */
+ virtual ble_error_t setAddress(addr_type_t type, const uint8_t address[6]) = 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 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 (*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(ConnectionEventCallback_t callback) {
+ onConnection = callback;
+ }
+ void setOnDisconnection(DisconnectionEventCallback_t callback) {
+ onDisconnection = callback;
+ }
+
+ 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);
+ }
+ }
+
+ void processEvent(GapEvents::gapEvent_e type) {
+ switch (type) {
+ case GapEvents::GAP_EVENT_TIMEOUT:
+ state.advertising = 0;
+ if (onTimeout) {
+ onTimeout();
+ }
+ break;
+ }
+ }
+
+ GapState_t getState(void) const {
+ return state;
+ }
+
+protected:
+ Gap() : state(), onTimeout(NULL), onConnection(NULL), onDisconnection(NULL) {
+ /* empty */
+ }
+
+protected:
+ GapState_t state;
+
+private:
+ EventCallback_t onTimeout;
+ ConnectionEventCallback_t onConnection;
+ DisconnectionEventCallback_t onDisconnection;
+};
+
+#endif // ifndef __GAP_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/public/GapAdvertisingData.h Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,209 @@
+/* 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 "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);
+ virtual ~GapAdvertisingData(void);
+
+ ble_error_t addData(DataType, const uint8_t *, uint8_t);
+ ble_error_t addAppearance(Appearance appearance = GENERIC_TAG);
+ ble_error_t addFlags(uint8_t flags = LE_GENERAL_DISCOVERABLE);
+ ble_error_t addTxPower(int8_t txPower);
+ void clear(void);
+ const uint8_t *getPayload(void) const;
+ uint8_t getPayloadLen(void) const;
+ uint16_t getAppearance(void) const;
+
+private:
+ uint8_t _payload[GAP_ADVERTISING_DATA_MAX_PAYLOAD];
+ uint8_t _payloadLen;
+ uint16_t _appearance;
+};
+
+#endif // ifndef __GAP_ADVERTISING_DATA_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/public/GapAdvertisingParams.h Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,141 @@
+/* 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__
+
+#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
+ 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
+
+ \par EXAMPLE
+
+ \code
+
+ // ToDo
+
+ \endcode
+*/
+/**************************************************************************/
+class GapAdvertisingParams
+{
+public:
+ /**************************************************************************/
+ /*!
+ \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 */
+ };
+
+ GapAdvertisingParams(AdvertisingType advType = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED,
+ uint16_t interval = GAP_ADV_PARAMS_INTERVAL_MIN_NONCON,
+ uint16_t timeout = 0);
+ virtual ~GapAdvertisingParams(void);
+
+ void setAdvertisingType(AdvertisingType newAdvType);
+ void setInterval(uint16_t newInterval);
+ void setTimeout(uint16_t newTimeout);
+
+ virtual AdvertisingType getAdvertisingType(void) const;
+ virtual uint16_t getInterval(void) const;
+ virtual uint16_t getTimeout(void) const;
+
+private:
+ AdvertisingType _advType;
+ uint16_t _interval;
+ uint16_t _timeout;
+};
+
+inline void
+GapAdvertisingParams::setAdvertisingType(AdvertisingType newAdvType) {
+ _advType = newAdvType;
+}
+
+inline void
+GapAdvertisingParams::setInterval(uint16_t newInterval) {
+ _interval = newInterval;
+}
+
+inline void
+GapAdvertisingParams::setTimeout(uint16_t newTimeout) {
+ _timeout = newTimeout;
+}
+
+
+/**************************************************************************/
+/*!
+ \brief returns the current Advertising Type value
+*/
+/**************************************************************************/
+inline GapAdvertisingParams::AdvertisingType
+GapAdvertisingParams::getAdvertisingType(void) const
+{
+ return _advType;
+}
+
+/**************************************************************************/
+/*!
+ \brief returns the current Advertising Delay (in units of 0.625ms)
+*/
+/**************************************************************************/
+inline uint16_t
+GapAdvertisingParams::getInterval(void) const
+{
+ return _interval;
+}
+
+/**************************************************************************/
+/*!
+ \brief returns the current Advertising Timeout (in seconds)
+*/
+/**************************************************************************/
+inline uint16_t
+GapAdvertisingParams::getTimeout(void) const
+{
+ return _timeout;
+}
+
+#endif // ifndef __GAP_ADVERTISING_PARAMS_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/public/GapEvents.h Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,47 @@
+/* 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"
+#include "mbed.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__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/public/GattAttribute.h Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,96 @@
+/* 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 "blecommon.h"
+#include "UUID.h"
+
+/**************************************************************************/
+/*!
+ \brief GATT attribute
+*/
+/**************************************************************************/
+class GattAttribute
+{
+public:
+ typedef uint16_t Handle_t;
+
+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 characteristic's value
+ * @param[in] maxLen
+ * The max length in bytes of this characteristic's value
+ *
+ * @section EXAMPLE
+ *
+ * @code
+ *
+ * // UUID = 0x2A19, Min length 2, Max len = 2, Properties = write
+ * GattCharacteristic c = GattCharacteristic( 0x2A19, 2, 2, BLE_GATT_CHAR_PROPERTIES_WRITE );
+ *
+ * @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), _handle(){
+ /* empty */
+ }
+
+public:
+ Handle_t getHandle(void) const {
+ return _handle;
+ }
+
+ void setHandle(Handle_t id) {
+ _handle = id;
+ }
+
+ const UUID &getUUID(void) const {
+ return _uuid;
+ }
+
+ uint16_t getInitialLength(void) const {
+ return _initialLen;
+ }
+
+ uint16_t getMaxLength(void) const {
+ return _lenMax;
+ }
+
+ uint8_t *getValuePtr(void) {
+ return _valuePtr;
+ }
+
+protected:
+ UUID _uuid; /* Characteristic UUID */
+ uint8_t *_valuePtr;
+ uint16_t _initialLen; /* Initial length of the value */
+ uint16_t _lenMax; /* Maximum length of the value */
+ Handle_t _handle;
+};
+
+#endif // ifndef __GATT_ATTRIBUTE_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/public/GattCharacteristic.h Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,360 @@
+/* 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 "blecommon.h"
+#include "UUID.h"
+#include "GattAttribute.h"
+
+/**************************************************************************/
+/*!
+ \brief GATT characteristic
+*/
+/**************************************************************************/
+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 decribe what the raw numeric
+ data in a characteristic actually represents.
+
+ \note See https://developer.bluetooth.org/gatt/units/Pages/default.aspx
+ */
+ /**************************************************************************/
+ typedef enum ble_gatt_unit_e {
+ 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 /**< */
+ } ble_gatt_unit_t;
+
+ /**************************************************************************/
+ /*!
+ \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
+ */
+ /**************************************************************************/
+ typedef enum ble_gatt_format_e {
+ 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. */
+ } ble_gatt_format_t;
+
+ /**************************************************************************/
+ /*!
+ \brief Standard GATT characteritic 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 acknowledgement. */
+ BLE_GATT_CHAR_PROPERTIES_INDICATE = 0x20, /**< Permits indications of a Characteristic Value with acknowledgement. */
+ 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
+ * @param[in] numDescriptors
+ * The number of descriptors
+ *
+ * @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), _descriptors(descriptors), _descriptorCount(numDescriptors) {
+ }
+
+public:
+ GattAttribute& getValueAttribute() {
+ return _valueAttribute;
+ }
+ uint8_t getProperties(void) const {
+ return _properties;
+ }
+ uint8_t getDescriptorCount(void) const {
+ return _descriptorCount;
+ }
+ GattAttribute *getDescriptor(uint8_t index) {
+ if (index >= _descriptorCount) {
+ return NULL;
+ }
+
+ return _descriptors[index];
+ }
+
+private:
+ GattAttribute _valueAttribute;
+ uint8_t _properties;
+ GattAttribute ** _descriptors;
+ uint8_t _descriptorCount;
+};
+
+#endif // ifndef __GATT_CHARACTERISTIC_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/public/GattCharacteristicWriteCBParams.h Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,36 @@
+/* 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 {
+ 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. */
+};
+
+#endif /*__GATT_CHARACTERISTIC_WRITE_CB_PARAMS_H__*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/public/GattServer.h Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,121 @@
+/* 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 "mbed.h"
+#include "blecommon.h"
+#include "GattService.h"
+#include "GattServerEvents.h"
+#include "GattCharacteristicWriteCBParams.h"
+#include "CallChainOfFunctionPointersWithContext.h"
+
+/**************************************************************************/
+/*!
+ \brief
+ The base class used to abstract GATT Server functionality to a specific
+ radio transceiver, SOC or BLE Stack.
+*/
+/**************************************************************************/
+class GattServer
+{
+public:
+ /* 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;
+
+ // 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;
+ }
+ 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);
+ }
+ void setOnUpdatesEnabled(EventCallback_t callback) {
+ onUpdatesEnabled = callback;
+ }
+ void setOnUpdatesDisabled(EventCallback_t callback) {
+ onUpdatesDisabled = callback;
+ }
+ void setOnConfirmationReceived(EventCallback_t callback) {
+ onConfirmationReceived = callback;
+ }
+
+ void handleDataWrittenEvent(const GattCharacteristicWriteCBParams *params) {
+ if (onDataWritten.hasCallbacksAttached()) {
+ onDataWritten.call(params);
+ }
+ }
+
+ void handleEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle) {
+ switch (type) {
+ case GattServerEvents::GATT_EVENT_UPDATES_ENABLED:
+ if (onUpdatesEnabled) {
+ onUpdatesEnabled(charHandle);
+ }
+ break;
+ case GattServerEvents::GATT_EVENT_UPDATES_DISABLED:
+ if (onUpdatesDisabled) {
+ onUpdatesDisabled(charHandle);
+ }
+ break;
+ case GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED:
+ if (onConfirmationReceived) {
+ onConfirmationReceived(charHandle);
+ }
+ break;
+ }
+ }
+
+ void handleDataSentEvent(unsigned count) {
+ if (onDataSent) {
+ onDataSent(count);
+ }
+ }
+
+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;
+ CallChainOfFunctionPointersWithContext<const GattCharacteristicWriteCBParams *> onDataWritten;
+ EventCallback_t onUpdatesEnabled;
+ EventCallback_t onUpdatesDisabled;
+ EventCallback_t onConfirmationReceived;
+};
+
+#endif // ifndef __GATT_SERVER_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/public/GattServerEvents.h Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,49 @@
+/* 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__
+
+#include "blecommon.h"
+#include "mbed.h"
+
+/**************************************************************************/
+/*!
+ \brief
+ The base class used to abstract away the callback events that can be
+ triggered with the GATT Server.
+*/
+/**************************************************************************/
+class GattServerEvents
+{
+public:
+ /******************************************************************/
+ /*!
+ \brief
+ Identifies GATT events generated by the radio HW when an event
+ callback occurs
+ */
+ /******************************************************************/
+ 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 */
+ } gattEvent_t;
+};
+
+#endif // ifndef __GATT_SERVER_EVENTS_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/public/GattService.h Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,98 @@
+/* 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 "blecommon.h"
+#include "UUID.h"
+#include "GattCharacteristic.h"
+
+
+/**************************************************************************/
+/*!
+ \brief GATT service
+*/
+/**************************************************************************/
+class GattService
+{
+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);
+
+ 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
+ };
+
+ const UUID &getUUID(void) const {
+ return _primaryServiceID;
+ }
+ uint16_t getHandle(void) const {
+ return _handle;
+ }
+ void setHandle(uint16_t handle) {
+ _handle = handle;
+ }
+ uint8_t getCharacteristicCount(void) const {
+ return _characteristicCount;
+ }
+ 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__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/public/UUID.h Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,61 @@
+/* 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 "blecommon.h"
+
+const unsigned LENGTH_OF_LONG_UUID = 16;
+typedef uint16_t ShortUUIDBytes_t;
+typedef uint8_t LongUUIDBytes_t[LENGTH_OF_LONG_UUID];
+
+class UUID
+{
+public:
+ enum {
+ UUID_TYPE_SHORT = 0, // Short BLE UUID
+ UUID_TYPE_LONG = 1 // Full 128-bit UUID
+ };
+
+public:
+ UUID(const LongUUIDBytes_t);
+ UUID(ShortUUIDBytes_t);
+ virtual ~UUID(void);
+
+public:
+ uint8_t shortOrLong(void) const {
+ return type;
+ }
+ const uint8_t* getBaseUUID(void) const {
+ return baseUUID;
+ }
+ ShortUUIDBytes_t getShortUUID(void) const {
+ return shortUUID;
+ }
+
+private:
+ 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.*/
+ ShortUUIDBytes_t shortUUID; // 16 bit uuid (byte 2-3 using with base)
+};
+
+#endif // ifndef __UUID_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/public/readme.txt Fri Dec 19 18:54:46 2014 +0000 @@ -0,0 +1,1 @@ +The public API exposed through header files. \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/services/BatteryService.h Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,61 @@
+/* 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_BATTERY_SERVICE_H__
+#define __BLE_BATTERY_SERVICE_H__
+
+#include "BLEDevice.h"
+
+/* Battery Service */
+/* Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.battery_service.xml */
+/* Battery Level Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.battery_level.xml */
+class BatteryService {
+public:
+ BatteryService(BLEDevice &_ble, uint8_t level = 100) :
+ ble(_ble),
+ batteryLevel(level),
+ batteryLevelCharacteristic(GattCharacteristic::UUID_BATTERY_LEVEL_CHAR, &batteryLevel, sizeof(batteryLevel), sizeof(batteryLevel),
+ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | 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;
+ }
+
+ /**
+ * Update the battery level with a new value. Valid values range from
+ * 0..100. Anything outside this range will be ignored.
+ * @param newLevel New level.
+ */
+ void updateBatteryLevel(uint8_t newLevel) {
+ batteryLevel = newLevel;
+ ble.updateCharacteristicValue(batteryLevelCharacteristic.getValueAttribute().getHandle(), &batteryLevel, 1);
+ }
+
+private:
+ BLEDevice &ble;
+ uint8_t batteryLevel;
+ GattCharacteristic batteryLevelCharacteristic;
+};
+
+#endif /* #ifndef __BLE_BATTERY_SERVICE_H__*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/services/DFUService.cpp Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,40 @@
+/* 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 "DFUService.h"
+
+const uint8_t DFUServiceBaseUUID[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x12, 0x12, 0xEF, 0xDE,
+ 0x15, 0x23, 0x78, 0x5F, 0xEA, 0xBC, 0xD1, 0x23,
+};
+const uint16_t DFUServiceShortUUID = 0x1530;
+const uint16_t DFUServiceControlCharacteristicShortUUID = 0x1531;
+const uint16_t DFUServicePacketCharacteristicShortUUID = 0x1532;
+
+const uint8_t DFUServiceUUID[] = {
+ 0x00, 0x00, (uint8_t)(DFUServiceShortUUID >> 8), (uint8_t)(DFUServiceShortUUID & 0xFF), 0x12, 0x12, 0xEF, 0xDE,
+ 0x15, 0x23, 0x78, 0x5F, 0xEA, 0xBC, 0xD1, 0x23,
+};
+const uint8_t DFUServiceControlCharacteristicUUID[] = {
+ 0x00, 0x00, (uint8_t)(DFUServiceControlCharacteristicShortUUID >> 8), (uint8_t)(DFUServiceControlCharacteristicShortUUID & 0xFF), 0x12, 0x12, 0xEF, 0xDE,
+ 0x15, 0x23, 0x78, 0x5F, 0xEA, 0xBC, 0xD1, 0x23,
+};
+const uint8_t DFUServicePacketCharacteristicUUID[] = {
+ 0x00, 0x00, (uint8_t)(DFUServicePacketCharacteristicShortUUID >> 8), (uint8_t)(DFUServicePacketCharacteristicShortUUID & 0xFF), 0x12, 0x12, 0xEF, 0xDE,
+ 0x15, 0x23, 0x78, 0x5F, 0xEA, 0xBC, 0xD1, 0x23,
+};
+
+DFUService::ResetPrepare_t DFUService::handoverCallback = NULL;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/services/DFUService.h Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,115 @@
+/* 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_DFU_SERVICE_H__
+#define __BLE_DFU_SERVICE_H__
+
+#include "BLEDevice.h"
+#include "UUID.h"
+
+extern "C" void bootloader_start(void);
+
+extern const uint8_t DFUServiceBaseUUID[];
+extern const uint16_t DFUServiceShortUUID;
+extern const uint16_t DFUServiceControlCharacteristicShortUUID;
+
+extern const uint8_t DFUServiceUUID[];
+extern const uint8_t DFUServiceControlCharacteristicUUID[];
+extern const uint8_t DFUServicePacketCharacteristicUUID[];
+
+class DFUService {
+public:
+ /**
+ * Signature for the handover callback. The application may provide such a
+ * callback when setting up the DFU service, in which case it will be
+ * invoked before handing control over to the bootloader.
+ */
+ typedef void (*ResetPrepare_t)(void);
+
+public:
+ DFUService(BLEDevice &_ble, ResetPrepare_t _handoverCallback = NULL) :
+ ble(_ble),
+ controlBytes(),
+ packetBytes(),
+ controlPoint(DFUServiceControlCharacteristicUUID, controlBytes, SIZEOF_CONTROL_BYTES, SIZEOF_CONTROL_BYTES,
+ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
+ packet(DFUServicePacketCharacteristicUUID, packetBytes, SIZEOF_PACKET_BYTES, SIZEOF_PACKET_BYTES,
+ 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;
+ }
+
+ /* Set an initial value for control bytes so that the application's DFUService can
+ * be distinguished from the real DFU service provided by the bootloader. */
+ controlBytes[0] = 0xFF;
+ controlBytes[1] = 0xFF;
+
+ GattCharacteristic *dfuChars[] = {&controlPoint, &packet};
+ GattService dfuService(DFUServiceUUID, dfuChars, sizeof(dfuChars) / sizeof(GattCharacteristic *));
+
+ ble.addService(dfuService);
+ handoverCallback = _handoverCallback;
+ serviceAdded = true;
+
+ ble.onDataWritten(this, &DFUService::onDataWritten);
+ }
+
+ uint16_t getControlHandle(void) {
+ return controlPoint.getValueAttribute().getHandle();
+ }
+
+ /**
+ * This callback allows the DFU service to receive the initial trigger to
+ * handover control to the bootloader; but first the application is given a
+ * chance to clean up.
+ */
+ virtual void onDataWritten(const GattCharacteristicWriteCBParams *params) {
+ if (params->charHandle == controlPoint.getValueAttribute().getHandle()) {
+ /* At present, writing anything will do the trick--this needs to be improved. */
+ if (handoverCallback) {
+ handoverCallback();
+ }
+
+ bootloader_start();
+ }
+ }
+
+private:
+ static const unsigned SIZEOF_CONTROL_BYTES = 2;
+ static const unsigned SIZEOF_PACKET_BYTES = 20;
+
+ 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
+ * to be improved. */
+ GattCharacteristic controlPoint;
+
+ /**< The packet characteristic in this service doesn't do anything meaningful, but
+ * is only a placeholder to mimic the corresponding characteristic in the
+ * actual DFU service implemented by the bootloader. Without this, some
+ * FOTA clients might get confused as service definitions change after
+ * handing control over to the bootloader. */
+ GattCharacteristic packet;
+};
+
+#endif /* #ifndef __BLE_DFU_SERVICE_H__*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/services/DeviceInformationService.h Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,124 @@
+/* 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_INFORMATION_SERVICE_H__
+#define __BLE_DEVICE_INFORMATION_SERVICE_H__
+
+#include "BLEDevice.h"
+
+/* Device Information Service */
+/* Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.device_information.xml */
+/* Manufacturer Name String Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.manufacturer_name_string.xml */
+class DeviceInformationService {
+public:
+ /**
+ * Constructor.
+ *
+ * @param[in] _ble
+ * Reference to the BLEDevice.
+ * @param[in] manufacturersName
+ * This characteristic represents the name of the
+ * manufacturer of the device. The name is copied into the
+ * BLE stack during this constructor.
+ * @param[in] modelNumber
+ * This characteristic represents the model number that is
+ * assigned by the device vendor. The value is copied into
+ * the BLE stack during this constructor.
+ * @param[in] serialNumber
+ * This characteristic represents the serial number for a
+ * particular instance of the device. The value is copied
+ * into the BLE stack during this constructor.
+ * @param[in] hardwareRevision
+ * This characteristic represents the hardware revision for
+ * the hardware within the device. The value is copied
+ * into the BLE stack during this constructor.
+ * @param[in] firmwareRevision
+ * This characteristic represents the firmware revision for
+ * the firmware within the device. The value is copied
+ * into the BLE stack during this constructor.
+ * @param[in] softwareRevision
+ * This characteristic represents the software revision for
+ * the software within the device. The value is copied
+ * into the BLE stack during this constructor.
+ */
+ DeviceInformationService(BLEDevice &_ble,
+ const char *manufacturersName = NULL,
+ const char *modelNumber = NULL,
+ const char *serialNumber = NULL,
+ const char *hardwareRevision = NULL,
+ const char *firmwareRevision = NULL,
+ const char *softwareRevision = NULL) :
+ ble(_ble),
+ manufacturersNameStringCharacteristic(GattCharacteristic::UUID_MANUFACTURER_NAME_STRING_CHAR,
+ (uint8_t *)manufacturersName,
+ (manufacturersName != NULL) ? strlen(manufacturersName) : 0, /* minLength */
+ (manufacturersName != NULL) ? strlen(manufacturersName) : 0, /* maxLength */
+ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ),
+ modelNumberStringCharacteristic(GattCharacteristic::UUID_MODEL_NUMBER_STRING_CHAR,
+ (uint8_t *)modelNumber,
+ (modelNumber != NULL) ? strlen(modelNumber) : 0, /* minLength */
+ (modelNumber != NULL) ? strlen(modelNumber) : 0, /* maxLength */
+ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ),
+ serialNumberStringCharacteristic(GattCharacteristic::UUID_SERIAL_NUMBER_STRING_CHAR,
+ (uint8_t *)serialNumber,
+ (serialNumber != NULL) ? strlen(serialNumber) : 0, /* minLength */
+ (serialNumber != NULL) ? strlen(serialNumber) : 0, /* maxLength */
+ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ),
+ hardwareRevisionStringCharacteristic(GattCharacteristic::UUID_HARDWARE_REVISION_STRING_CHAR,
+ (uint8_t *)hardwareRevision,
+ (hardwareRevision != NULL) ? strlen(hardwareRevision) : 0, /* minLength */
+ (hardwareRevision != NULL) ? strlen(hardwareRevision) : 0, /* maxLength */
+ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ),
+ firmwareRevisionStringCharacteristic(GattCharacteristic::UUID_FIRMWARE_REVISION_STRING_CHAR,
+ (uint8_t *)firmwareRevision,
+ (firmwareRevision != NULL) ? strlen(firmwareRevision) : 0, /* minLength */
+ (firmwareRevision != NULL) ? strlen(firmwareRevision) : 0, /* maxLength */
+ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ),
+ softwareRevisionStringCharacteristic(GattCharacteristic::UUID_SOFTWARE_REVISION_STRING_CHAR,
+ (uint8_t *)softwareRevision,
+ (softwareRevision != NULL) ? strlen(softwareRevision) : 0, /* minLength */
+ (softwareRevision != NULL) ? strlen(softwareRevision) : 0, /* maxLength */
+ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ)
+ {
+ static bool serviceAdded = false; /* We should only ever need to add the heart rate service once. */
+ if (serviceAdded) {
+ return;
+ }
+
+ GattCharacteristic *charTable[] = {&manufacturersNameStringCharacteristic,
+ &modelNumberStringCharacteristic,
+ &serialNumberStringCharacteristic,
+ &hardwareRevisionStringCharacteristic,
+ &firmwareRevisionStringCharacteristic,
+ &softwareRevisionStringCharacteristic};
+ GattService deviceInformationService(GattService::UUID_DEVICE_INFORMATION_SERVICE, charTable,
+ sizeof(charTable) / sizeof(GattCharacteristic *));
+
+ ble.addService(deviceInformationService);
+ serviceAdded = true;
+ }
+
+private:
+ BLEDevice &ble;
+ GattCharacteristic manufacturersNameStringCharacteristic;
+ GattCharacteristic modelNumberStringCharacteristic;
+ GattCharacteristic serialNumberStringCharacteristic;
+ GattCharacteristic hardwareRevisionStringCharacteristic;
+ GattCharacteristic firmwareRevisionStringCharacteristic;
+ GattCharacteristic softwareRevisionStringCharacteristic;
+};
+
+#endif /* #ifndef __BLE_DEVICE_INFORMATION_SERVICE_H__*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/services/HealthThermometerService.h Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,131 @@
+/* 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_HEALTH_THERMOMETER_SERVICE_H__
+#define __BLE_HEALTH_THERMOMETER_SERVICE_H__
+
+#include "BLEDevice.h"
+
+/* Health Thermometer Service */
+/* Service: https://developer.bluetooth.org/gatt/profiles/Pages/ProfileViewer.aspx?u=org.bluetooth.profile.health_thermometer.xml */
+/* Temperature Measurement: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_measurement.xml */
+/* Temperature Type: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_type.xml */
+class HealthThermometerService {
+public:
+ enum {
+ LOCATION_ARMPIT = 1,
+ LOCATION_BODY,
+ LOCATION_EAR,
+ LOCATION_FINGER,
+ LOCATION_GI_TRACT,
+ LOCATION_MOUTH,
+ LOCATION_RECTUM,
+ LOCATION_TOE,
+ LOCATION_EAR_DRUM,
+ };
+
+public:
+
+ /**
+ * @param[in] _ble reference to the BLE device
+ * @param[in] initialTemp initial value in celsius
+ * @param[in] _location
+ */
+ HealthThermometerService(BLEDevice &_ble, float initialTemp, uint8_t _location) :
+ ble(_ble),
+ valueBytes(initialTemp),
+ tempMeasurement(GattCharacteristic::UUID_TEMPERATURE_MEASUREMENT_CHAR, valueBytes.getPointer(),
+ sizeof(TemperatureValueBytes), sizeof(TemperatureValueBytes),
+ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
+ tempLocation(GattCharacteristic::UUID_TEMPERATURE_TYPE_CHAR, (uint8_t *)&_location, sizeof(_location), sizeof(_location),
+ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ) {
+
+ GattCharacteristic *hrmChars[] = {&tempMeasurement, &tempLocation, };
+ GattService hrmService(GattService::UUID_HEALTH_THERMOMETER_SERVICE, hrmChars, sizeof(hrmChars) / sizeof(GattCharacteristic *));
+
+ ble.addService(hrmService);
+ }
+
+ void updateTemperature(float temperature) {
+ if (ble.getGapState().connected) {
+ valueBytes.updateTemperature(temperature);
+ ble.updateCharacteristicValue(tempMeasurement.getValueAttribute().getHandle(), valueBytes.getPointer(), sizeof(TemperatureValueBytes));
+ }
+ }
+
+private:
+ /* Private internal representation for the bytes used to work with the vaulue of the heart-rate characteristic. */
+ struct TemperatureValueBytes {
+ static const unsigned OFFSET_OF_FLAGS = 0;
+ static const unsigned OFFSET_OF_VALUE = OFFSET_OF_FLAGS + sizeof(uint8_t);
+ static const unsigned SIZEOF_VALUE_BYTES = sizeof(uint8_t) + sizeof(float);
+
+ static const unsigned TEMPERATURE_UNITS_FLAG_POS = 0;
+ static const unsigned TIMESTAMP_FLAG_POS = 1;
+ static const unsigned TEMPERATURE_TYPE_FLAG_POS = 2;
+
+ static const uint8_t TEMPERATURE_UNITS_CELSIUS = 0;
+ static const uint8_t TEMPERATURE_UNITS_FAHRENHEIT = 1;
+
+ TemperatureValueBytes(float initialTemperature) : bytes() {
+ /* assumption: temperature values are expressed in Celsius */
+ bytes[OFFSET_OF_FLAGS] = (TEMPERATURE_UNITS_CELSIUS << TEMPERATURE_UNITS_FLAG_POS) |
+ (false << TIMESTAMP_FLAG_POS) |
+ (false << TEMPERATURE_TYPE_FLAG_POS);
+ updateTemperature(initialTemperature);
+ }
+
+ void updateTemperature(float temp) {
+ uint32_t temp_ieee11073 = quick_ieee11073_from_float(temp);
+ memcpy(&bytes[OFFSET_OF_VALUE], &temp_ieee11073, sizeof(float));
+ }
+
+ uint8_t *getPointer(void) {
+ return bytes;
+ }
+
+ const uint8_t *getPointer(void) const {
+ return bytes;
+ }
+
+ private:
+ /**
+ * @brief A very quick conversion between a float temperature and 11073-20601 FLOAT-Type.
+ * @param temperature The temperature as a float.
+ * @return The temperature in 11073-20601 FLOAT-Type format.
+ */
+ uint32_t quick_ieee11073_from_float(float temperature) {
+ uint8_t exponent = 0xFE; //exponent is -2
+ uint32_t mantissa = (uint32_t)(temperature * 100);
+
+ return (((uint32_t)exponent) << 24) | mantissa;
+ }
+
+
+ private:
+ /* First byte = 8-bit flags, Second field is a float holding the temperature value. */
+ /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_measurement.xml */
+ uint8_t bytes[SIZEOF_VALUE_BYTES];
+ };
+
+private:
+ BLEDevice &ble;
+ TemperatureValueBytes valueBytes;
+ GattCharacteristic tempMeasurement;
+ GattCharacteristic tempLocation;
+};
+
+#endif /* #ifndef __BLE_HEALTH_THERMOMETER_SERVICE_H__*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/services/HeartRateService.h Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,182 @@
+/* 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_HEART_RATE_SERVICE_H__
+#define __BLE_HEART_RATE_SERVICE_H__
+
+#include "BLEDevice.h"
+
+/* Heart Rate Service */
+/* Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.heart_rate.xml */
+/* HRM Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml */
+/* Location: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.body_sensor_location.xml */
+class HeartRateService {
+public:
+ enum {
+ LOCATION_OTHER = 0,
+ LOCATION_CHEST,
+ LOCATION_WRIST,
+ LOCATION_FINGER,
+ LOCATION_HAND,
+ LOCATION_EAR_LOBE,
+ LOCATION_FOOT,
+ };
+
+public:
+ /**
+ * Constructor.
+ *
+ * param[in] _ble
+ * Reference to the underlying BLEDevice.
+ * param[in] hrmCounter (8-bit)
+ * initial value for the hrm counter.
+ * param[in] location
+ * Sensor's location.
+ */
+ HeartRateService(BLEDevice &_ble, uint8_t hrmCounter, uint8_t location) :
+ ble(_ble),
+ valueBytes(hrmCounter),
+ hrmRate(GattCharacteristic::UUID_HEART_RATE_MEASUREMENT_CHAR, valueBytes.getPointer(),
+ valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES,
+ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
+ hrmLocation(GattCharacteristic::UUID_BODY_SENSOR_LOCATION_CHAR, (uint8_t *)&location, sizeof(location), sizeof(location),
+ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ),
+ controlPoint(GattCharacteristic::UUID_HEART_RATE_CONTROL_POINT_CHAR, (uint8_t *)&controlPointValue,
+ sizeof(controlPointValue), sizeof(controlPointValue), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE) {
+ setupService();
+ }
+
+ /**
+ * Same constructor as above, but with a 16-bit HRM Counter value.
+ */
+ HeartRateService(BLEDevice &_ble, uint16_t hrmCounter, uint8_t location) :
+ ble(_ble),
+ valueBytes(hrmCounter),
+ hrmRate(GattCharacteristic::UUID_HEART_RATE_MEASUREMENT_CHAR, valueBytes.getPointer(),
+ valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES,
+ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
+ hrmLocation(GattCharacteristic::UUID_BODY_SENSOR_LOCATION_CHAR, (uint8_t *)&location, sizeof(location), sizeof(location),
+ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ),
+ controlPoint(GattCharacteristic::UUID_HEART_RATE_CONTROL_POINT_CHAR, (uint8_t *)&controlPointValue,
+ sizeof(controlPointValue), sizeof(controlPointValue), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE) {
+ setupService();
+ }
+
+ /**
+ * Set a new 8-bit value for heart rate.
+ */
+ void updateHeartRate(uint8_t hrmCounter) {
+ valueBytes.updateHeartRate(hrmCounter);
+ ble.updateCharacteristicValue(hrmRate.getValueAttribute().getHandle(), valueBytes.getPointer(), valueBytes.getNumValueBytes());
+ }
+
+ /**
+ * Set a new 16-bit value for heart rate.
+ */
+ void updateHeartRate(uint16_t hrmCounter) {
+ valueBytes.updateHeartRate(hrmCounter);
+ ble.updateCharacteristicValue(hrmRate.getValueAttribute().getHandle(), valueBytes.getPointer(), valueBytes.getNumValueBytes());
+ }
+
+ /**
+ * This callback allows the UART service to receive updates to the
+ * txCharacteristic. The application should forward the call to this
+ * function from the global onDataWritten() callback handler; or if that's
+ * not used, this method can be used as a callback directly.
+ */
+ 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
+ * ble.onDataWritten(this, &ExtendedHRService::onDataWritten); in
+ * your constructor.
+ */
+ }
+ }
+
+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);
+ }
+
+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 */
+ static const unsigned FLAGS_BYTE_INDEX = 0;
+
+ static const unsigned VALUE_FORMAT_BITNUM = 0;
+ static const uint8_t VALUE_FORMAT_FLAG = (1 << VALUE_FORMAT_BITNUM);
+
+ HeartRateValueBytes(uint8_t hrmCounter) : valueBytes() {
+ updateHeartRate(hrmCounter);
+ }
+
+ HeartRateValueBytes(uint16_t hrmCounter) : valueBytes() {
+ updateHeartRate(hrmCounter);
+ }
+
+ void updateHeartRate(uint8_t hrmCounter) {
+ valueBytes[FLAGS_BYTE_INDEX] &= ~VALUE_FORMAT_FLAG;
+ valueBytes[FLAGS_BYTE_INDEX + 1] = hrmCounter;
+ }
+
+ void updateHeartRate(uint16_t hrmCounter) {
+ valueBytes[FLAGS_BYTE_INDEX] |= VALUE_FORMAT_FLAG;
+ valueBytes[FLAGS_BYTE_INDEX + 1] = (uint8_t)(hrmCounter & 0xFF);
+ valueBytes[FLAGS_BYTE_INDEX + 2] = (uint8_t)(hrmCounter >> 8);
+ }
+
+ uint8_t *getPointer(void) {
+ return valueBytes;
+ }
+
+ const uint8_t *getPointer(void) const {
+ return valueBytes;
+ }
+
+ unsigned getNumValueBytes(void) const {
+ return 1 + ((valueBytes[FLAGS_BYTE_INDEX] & VALUE_FORMAT_FLAG) ? sizeof(uint16_t) : sizeof(uint8_t));
+ }
+
+ 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];
+ };
+
+private:
+ BLEDevice &ble;
+ HeartRateValueBytes valueBytes;
+ uint8_t controlPointValue;
+ GattCharacteristic hrmRate;
+ GattCharacteristic hrmLocation;
+ GattCharacteristic controlPoint;
+};
+
+#endif /* #ifndef __BLE_HEART_RATE_SERVICE_H__*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/services/UARTService.cpp Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,41 @@
+/* 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 "UARTService.h"
+
+const uint8_t UARTServiceBaseUUID[LENGTH_OF_LONG_UUID] = {
+ 0x6E, 0x40, 0x00, 0x00, 0xB5, 0xA3, 0xF3, 0x93,
+ 0xE0, 0xA9, 0xE5, 0x0E, 0x24, 0xDC, 0xCA, 0x9E,
+};
+const uint16_t UARTServiceShortUUID = 0x0001;
+const uint16_t UARTServiceTXCharacteristicShortUUID = 0x0002;
+const uint16_t UARTServiceRXCharacteristicShortUUID = 0x0003;
+const uint8_t UARTServiceUUID[LENGTH_OF_LONG_UUID] = {
+ 0x6E, 0x40, (uint8_t)(UARTServiceShortUUID >> 8), (uint8_t)(UARTServiceShortUUID & 0xFF), 0xB5, 0xA3, 0xF3, 0x93,
+ 0xE0, 0xA9, 0xE5, 0x0E, 0x24, 0xDC, 0xCA, 0x9E,
+};
+const uint8_t UARTServiceUUID_reversed[LENGTH_OF_LONG_UUID] = {
+ 0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0,
+ 0x93, 0xF3, 0xA3, 0xB5, (uint8_t)(UARTServiceShortUUID & 0xFF), (uint8_t)(UARTServiceShortUUID >> 8), 0x40, 0x6E
+};
+const uint8_t UARTServiceTXCharacteristicUUID[LENGTH_OF_LONG_UUID] = {
+ 0x6E, 0x40, (uint8_t)(UARTServiceTXCharacteristicShortUUID >> 8), (uint8_t)(UARTServiceTXCharacteristicShortUUID & 0xFF), 0xB5, 0xA3, 0xF3, 0x93,
+ 0xE0, 0xA9, 0xE5, 0x0E, 0x24, 0xDC, 0xCA, 0x9E,
+};
+const uint8_t UARTServiceRXCharacteristicUUID[LENGTH_OF_LONG_UUID] = {
+ 0x6E, 0x40, (uint8_t)(UARTServiceRXCharacteristicShortUUID >> 8), (uint8_t)(UARTServiceRXCharacteristicShortUUID & 0xFF), 0xB5, 0xA3, 0xF3, 0x93,
+ 0xE0, 0xA9, 0xE5, 0x0E, 0x24, 0xDC, 0xCA, 0x9E,
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/services/UARTService.h Fri Dec 19 18:54:46 2014 +0000
@@ -0,0 +1,203 @@
+/* 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_UART_SERVICE_H__
+#define __BLE_UART_SERVICE_H__
+
+#include "Stream.h"
+
+#include "UUID.h"
+#include "BLEDevice.h"
+
+extern const uint8_t UARTServiceBaseUUID[LENGTH_OF_LONG_UUID];
+extern const uint16_t UARTServiceShortUUID;
+extern const uint16_t UARTServiceTXCharacteristicShortUUID;
+extern const uint16_t UARTServiceRXCharacteristicShortUUID;
+
+extern const uint8_t UARTServiceUUID[LENGTH_OF_LONG_UUID];
+extern const uint8_t UARTServiceUUID_reversed[LENGTH_OF_LONG_UUID];
+
+extern const uint8_t UARTServiceTXCharacteristicUUID[LENGTH_OF_LONG_UUID];
+extern const uint8_t UARTServiceRXCharacteristicUUID[LENGTH_OF_LONG_UUID];
+
+class UARTService : public Stream {
+public:
+ /**< Maximum length of data (in bytes) that can be transmitted by the UART service module to the peer. */
+ static const unsigned GATT_MTU_SIZE_DEFAULT = 23;
+ static const unsigned BLE_UART_SERVICE_MAX_DATA_LEN = (GATT_MTU_SIZE_DEFAULT - 3);
+
+public:
+ UARTService(BLEDevice &_ble) :
+ Stream("blueart"),
+ ble(_ble),
+ receiveBuffer(),
+ sendBuffer(),
+ sendBufferIndex(0),
+ numBytesReceived(0),
+ receiveBufferIndex(0),
+ txCharacteristic(UARTServiceTXCharacteristicUUID, receiveBuffer, 1, BLE_UART_SERVICE_MAX_DATA_LEN,
+ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE),
+ rxCharacteristic(UARTServiceRXCharacteristicUUID, sendBuffer, 1, BLE_UART_SERVICE_MAX_DATA_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) {
+ GattCharacteristic *charTable[] = {&txCharacteristic, &rxCharacteristic};
+ GattService uartService(UARTServiceUUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
+
+ ble.addService(uartService);
+ ble.onDataWritten(this, &UARTService::onDataWritten);
+ }
+
+ /**
+ * Note: TX and RX characteristics are to be interpreted from the viewpoint of the GATT client using this service.
+ */
+ uint16_t getTXCharacteristicHandle() {
+ return txCharacteristic.getValueAttribute().getHandle();
+ }
+
+ /**
+ * Note: TX and RX characteristics are to be interpreted from the viewpoint of the GATT client using this service.
+ */
+ uint16_t getRXCharacteristicHandle() {
+ return rxCharacteristic.getValueAttribute().getHandle();
+ }
+
+ /**
+ * Following a call to this function, all writes to stdout (such as from
+ * printf) get redirected to the outbound characteristic of this service.
+ * This might be very useful when wanting to receive debug messages over BLE.
+ *
+ * @Note: debug messages originating from printf() like calls are buffered
+ * before being sent out. A '\n' in the printf() triggers the buffer update
+ * to the underlying characteristic.
+ *
+ * @Note: long messages need to be chopped up into 20-byte updates so that
+ * they flow out completely with notifications. The receiver should be
+ * prepared to stitch these messages back.
+ */
+ void retargetStdout() {
+ freopen("/blueart", "w", stdout);
+ }
+
+ /**
+ * This callback allows the UART service to receive updates to the
+ * txCharacteristic. The application should forward the call to this
+ * function from the global onDataWritten() callback handler; or if that's
+ * not used, this method can be used as a callback directly.
+ */
+ virtual void onDataWritten(const GattCharacteristicWriteCBParams *params) {
+ if (params->charHandle == getTXCharacteristicHandle()) {
+ uint16_t bytesRead = params->len;
+ if (bytesRead <= BLE_UART_SERVICE_MAX_DATA_LEN) {
+ numBytesReceived = bytesRead;
+ receiveBufferIndex = 0;
+ memcpy(receiveBuffer, params->data, numBytesReceived);
+ }
+ }
+ }
+
+protected:
+ /**
+ * Override for Stream::write().
+ *
+ * We attempt to collect bytes before pushing them to the UART RX
+ * characteristic--writing to the RX characteristic will then generate
+ * notifications for the client. Updates made in quick succession to a
+ * notification-generating characteristic will result in data being buffered
+ * in the bluetooth stack as notifications are sent out. The stack will have
+ * its limits for this buffering; typically a small number under 10.
+ * Collecting data into the sendBuffer buffer helps mitigate the rate of
+ * updates. But we shouldn't buffer a large amount of data before updating
+ * the characteristic otherwise the client will need to turn around and make
+ * a long read request; this is because notifications include only the first
+ * 20 bytes of the updated data.
+ *
+ * @param buffer The received update
+ * @param length Amount of characters to be appended.
+ * @return Amount of characters appended to the rxCharacteristic.
+ */
+ virtual ssize_t write(const void* _buffer, size_t length) {
+ size_t origLength = length;
+ const uint8_t *buffer = static_cast<const uint8_t *>(_buffer);
+
+ if (ble.getGapState().connected) {
+ unsigned bufferIndex = 0;
+ while (length) {
+ unsigned bytesRemainingInSendBuffer = BLE_UART_SERVICE_MAX_DATA_LEN - sendBufferIndex;
+ unsigned bytesToCopy = (length < bytesRemainingInSendBuffer) ? length : bytesRemainingInSendBuffer;
+
+ /* copy bytes into sendBuffer */
+ memcpy(&sendBuffer[sendBufferIndex], &buffer[bufferIndex], bytesToCopy);
+ length -= bytesToCopy;
+ sendBufferIndex += bytesToCopy;
+ bufferIndex += bytesToCopy;
+
+ /* have we collected enough? */
+ if ((sendBufferIndex == BLE_UART_SERVICE_MAX_DATA_LEN) ||
+ // (sendBuffer[sendBufferIndex - 1] == '\r') ||
+ (sendBuffer[sendBufferIndex - 1] == '\n')) {
+ ble.updateCharacteristicValue(getRXCharacteristicHandle(), static_cast<const uint8_t *>(sendBuffer), sendBufferIndex);
+ sendBufferIndex = 0;
+ }
+ }
+ }
+
+ return origLength;
+ }
+
+ /**
+ * Override for Stream::_putc()
+ * @param c
+ * This function writes the character c, cast to an unsigned char, to stream.
+ * @return
+ * The character written as an unsigned char cast to an int or EOF on error.
+ */
+ virtual int _putc(int c) {
+ return (write(&c, 1) == 1) ? 1 : EOF;
+ }
+
+ virtual int _getc() {
+ if (receiveBufferIndex == numBytesReceived) {
+ return EOF;
+ }
+
+ return receiveBuffer[receiveBufferIndex++];
+ }
+
+ virtual int isatty() {
+ return 1;
+ }
+
+private:
+ 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
+ * application. */
+
+ uint8_t sendBuffer[BLE_UART_SERVICE_MAX_DATA_LEN]; /**< The local buffer into which outbound data is
+ * accumulated before being pushed to the
+ * rxCharacteristic. */
+ uint8_t sendBufferIndex;
+ uint8_t numBytesReceived;
+ uint8_t receiveBufferIndex;
+
+ GattCharacteristic txCharacteristic; /**< From the point of view of the external client, this is the characteristic
+ * they'd write into in order to communicate with this application. */
+ GattCharacteristic rxCharacteristic; /**< From the point of view of the external client, this is the characteristic
+ * they'd read from in order to receive the bytes transmitted by this
+ * application. */
+};
+
+#endif /* #ifndef __BLE_UART_SERVICE_H__*/
+
