High level Bluetooth Low Energy API and radio abstraction layer
Fork of BLE_API by
Revision 712:b04b5db36865, committed 2015-06-19
- Comitter:
- rgrover1
- Date:
- Fri Jun 19 15:53:29 2015 +0100
- Parent:
- 711:ea0c4bf9ec99
- Child:
- 713:9f4251b3355c
- Commit message:
- Synchronized with git rev 75beb803
Author: Rohit Grover
switch to a yotta layout
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/services/BatteryService.h Fri Jun 19 15:53:29 2015 +0100 @@ -0,0 +1,66 @@ +/* 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 "ble/BLE.h" + +/** +* @class BatteryService +* @brief BLE Battery Service. This service displays the battery level from 0%->100% represented as a 8bit number.<br> +* Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.battery_service.xml <br> +* Battery Level Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.battery_level.xml +*/ +class BatteryService { +public: + /** + * @param[ref] _ble + * BLE object for the underlying controller. + * @param[in] level + * 8bit batterly level. Usually used to represent percentage of batterly charge remaining. + */ + BatteryService(BLE &_ble, uint8_t level = 100) : + ble(_ble), + batteryLevel(level), + batteryLevelCharacteristic(GattCharacteristic::UUID_BATTERY_LEVEL_CHAR, &batteryLevel, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) { + + GattCharacteristic *charTable[] = {&batteryLevelCharacteristic}; + GattService batteryService(GattService::UUID_BATTERY_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); + + ble.addService(batteryService); + } + + /** + * @brief Update the battery level with a new value. Valid values range from + * 0..100. Anything outside this range will be ignored. + * + * @param newLevel + * update to battery level. + */ + void updateBatteryLevel(uint8_t newLevel) { + batteryLevel = newLevel; + ble.updateCharacteristicValue(batteryLevelCharacteristic.getValueAttribute().getHandle(), &batteryLevel, 1); + } + +protected: + BLE &ble; + + uint8_t batteryLevel; + ReadOnlyGattCharacteristic<uint8_t> batteryLevelCharacteristic; +}; + +#endif /* #ifndef __BLE_BATTERY_SERVICE_H__*/ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/services/DFUService.h Fri Jun 19 15:53:29 2015 +0100 @@ -0,0 +1,133 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BLE_DFU_SERVICE_H__ +#define __BLE_DFU_SERVICE_H__ + +#include "ble/BLE.h" +#include "ble/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 +* @brief Device Firmware Update Service. +*/ +class DFUService { +public: + /** + * @brief 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: + /** + * @brief Adds Device Firmware Update service to an existing ble object. + * + * @param[ref] _ble + * BLE object for the underlying controller. + * @param[in] _handoverCallback + * Application specific handover callback. + */ + DFUService(BLE &_ble, ResetPrepare_t _handoverCallback = NULL) : + ble(_ble), + controlPoint(DFUServiceControlCharacteristicUUID, controlBytes, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), + packet(DFUServicePacketCharacteristicUUID, packetBytes, SIZEOF_PACKET_BYTES, SIZEOF_PACKET_BYTES, + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE), + controlBytes(), + packetBytes() { + 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); + } + + /** + * @brief get the handle for the value attribute of the control characteristic. + */ + uint16_t getControlHandle(void) const { + return controlPoint.getValueHandle(); + } + + /** + * @brief 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. + * + * @param[in] params + * Information about the characterisitc being updated. + */ + virtual void onDataWritten(const GattWriteCallbackParams *params) { + if (params->handle == controlPoint.getValueHandle()) { + /* At present, writing anything will do the trick--this needs to be improved. */ + if (handoverCallback) { + handoverCallback(); + } + + bootloader_start(); + } + } + +protected: + static const unsigned SIZEOF_CONTROL_BYTES = 2; + static const unsigned SIZEOF_PACKET_BYTES = 20; + +protected: + BLE &ble; + + /**< Writing to the control characteristic triggers the handover to dfu- + * bootloader. At present, writing anything will do the trick--this needs + * to be improved. */ + WriteOnlyArrayGattCharacteristic<uint8_t, SIZEOF_CONTROL_BYTES> 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; + + uint8_t controlBytes[SIZEOF_CONTROL_BYTES]; + uint8_t packetBytes[SIZEOF_PACKET_BYTES]; + + static ResetPrepare_t handoverCallback; /**< application specific handover callback. */ +}; + +#endif /* #ifndef __BLE_DFU_SERVICE_H__*/ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/services/DeviceInformationService.h Fri Jun 19 15:53:29 2015 +0100 @@ -0,0 +1,127 @@ +/* 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 "ble/BLE.h" + +/** +* @class DeviceInformationService +* @brief BLE Device Information Service <br> +* Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.device_information.xml <br> +* Manufacturer Name String Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.manufacturer_name_string.xml +*/ +class DeviceInformationService { +public: + /** + * @brief Device Information Service Constructor. + * + * @param[ref] _ble + * BLE object for the underlying controller. + * @param[in] manufacturersName + * This characteristic represents the name of the + * manufacturer of the device. The name is copied into the + * 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(BLE &_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; + } + +protected: + BLE &ble; + GattCharacteristic manufacturersNameStringCharacteristic; + GattCharacteristic modelNumberStringCharacteristic; + GattCharacteristic serialNumberStringCharacteristic; + GattCharacteristic hardwareRevisionStringCharacteristic; + GattCharacteristic firmwareRevisionStringCharacteristic; + GattCharacteristic softwareRevisionStringCharacteristic; +}; + +#endif /* #ifndef __BLE_DEVICE_INFORMATION_SERVICE_H__*/ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/services/HealthThermometerService.h Fri Jun 19 15:53:29 2015 +0100 @@ -0,0 +1,150 @@ +/* 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 "BLE.h" + +/** +* @class HealthThermometerService +* @brief BLE Health Thermometer Service. This service provides the location of the thermometer and the temperature. <br> +* Service: https://developer.bluetooth.org/gatt/profiles/Pages/ProfileViewer.aspx?u=org.bluetooth.profile.health_thermometer.xml <br> +* Temperature Measurement: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_measurement.xml <br> +* Temperature Type: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_type.xml +*/ +class HealthThermometerService { +public: + /** + * @enum Sensor Location + * @brief Location of sensor on the body + */ + enum SensorLocation_t { + LOCATION_ARMPIT = 1, /*!< armpit */ + LOCATION_BODY, /*!< body */ + LOCATION_EAR, /*!< ear */ + LOCATION_FINGER, /*!< finger */ + LOCATION_GI_TRACT, /*!< GI tract */ + LOCATION_MOUTH, /*!< mouth */ + LOCATION_RECTUM, /*!< rectum */ + LOCATION_TOE, /*!< toe */ + LOCATION_EAR_DRUM, /*!< ear drum */ + }; + +public: + /** + * @brief Add the Health Thermometer Service to an existing ble object, initialize with temperature and location. + * @param[ref] _ble reference to the BLE device + * @param[in] initialTemp initial value in celsius + * @param[in] _location + */ + HealthThermometerService(BLE &_ble, float initialTemp, uint8_t _location) : + ble(_ble), + valueBytes(initialTemp), + tempMeasurement(GattCharacteristic::UUID_TEMPERATURE_MEASUREMENT_CHAR, (TemperatureValueBytes *)valueBytes.getPointer(), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), + tempLocation(GattCharacteristic::UUID_TEMPERATURE_TYPE_CHAR, &_location) { + + GattCharacteristic *hrmChars[] = {&tempMeasurement, &tempLocation, }; + GattService hrmService(GattService::UUID_HEALTH_THERMOMETER_SERVICE, hrmChars, sizeof(hrmChars) / sizeof(GattCharacteristic *)); + + ble.addService(hrmService); + } + + /** + * @brief Update the temperature being broadcast + * + * @param[in] temperature + * Floating point value of the temperature + * + */ + void updateTemperature(float temperature) { + if (ble.getGapState().connected) { + valueBytes.updateTemperature(temperature); + ble.updateCharacteristicValue(tempMeasurement.getValueAttribute().getHandle(), valueBytes.getPointer(), sizeof(TemperatureValueBytes)); + } + } + + /** + * @brief Update the location. + * @param loc + * new location value. + */ + void updateLocation(SensorLocation_t loc) { + ble.updateCharacteristicValue(tempLocation.getValueHandle(), reinterpret_cast<uint8_t *>(&loc), sizeof(uint8_t)); + } + +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: + BLE &ble; + TemperatureValueBytes valueBytes; + ReadOnlyGattCharacteristic<TemperatureValueBytes> tempMeasurement; + ReadOnlyGattCharacteristic<uint8_t> tempLocation; +}; + +#endif /* #ifndef __BLE_HEALTH_THERMOMETER_SERVICE_H__*/ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/services/HeartRateService.h Fri Jun 19 15:53:29 2015 +0100 @@ -0,0 +1,194 @@ +/* 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 "ble/BLE.h" + +/** +* @class HeartRateService +* @brief BLE Service for HeartRate. This BLE Service contains the location of the sensor, the heartrate in beats per minute. <br> +* Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.heart_rate.xml <br> +* HRM Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml <br> +* Location: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.body_sensor_location.xml +*/ +class HeartRateService { +public: + /** + * @enum SensorLocation + * @brief Location of HeartRate sensor on body. + */ + enum { + LOCATION_OTHER = 0, /*!< Other Location */ + LOCATION_CHEST, /*!< Chest */ + LOCATION_WRIST, /*!< Wrist */ + LOCATION_FINGER, /*!< Finger */ + LOCATION_HAND, /*!< Hand */ + LOCATION_EAR_LOBE, /*!< Earlobe */ + LOCATION_FOOT, /*!< Foot */ + }; + +public: + /** + * @brief Constructor with 8bit HRM Counter value. + * + * @param[ref] _ble + * Reference to the underlying BLE. + * @param[in] hrmCounter (8-bit) + * initial value for the hrm counter. + * @param[in] location + * Sensor's location. + */ + HeartRateService(BLE &_ble, uint8_t hrmCounter, uint8_t location) : + ble(_ble), + valueBytes(hrmCounter), + hrmRate(GattCharacteristic::UUID_HEART_RATE_MEASUREMENT_CHAR, valueBytes.getPointer(), + valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES, + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), + hrmLocation(GattCharacteristic::UUID_BODY_SENSOR_LOCATION_CHAR, &location), + controlPoint(GattCharacteristic::UUID_HEART_RATE_CONTROL_POINT_CHAR, &controlPointValue) { + setupService(); + } + + /** + * @brief Constructor with a 16-bit HRM Counter value. + * + * @param[in] _ble + * Reference to the underlying BLE. + * @param[in] hrmCounter (8-bit) + * initial value for the hrm counter. + * @param[in] location + * Sensor's location. + */ + HeartRateService(BLE &_ble, uint16_t hrmCounter, uint8_t location) : + 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, &location), + controlPoint(GattCharacteristic::UUID_HEART_RATE_CONTROL_POINT_CHAR, &controlPointValue) { + setupService(); + } + + /** + * @brief Set a new 8-bit value for heart rate. + * + * @param[in] hrmCounter + * HeartRate in bpm. + */ + 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. + * + * @param[in] hrmCounter + * HeartRate in bpm. + */ + void updateHeartRate(uint16_t hrmCounter) { + valueBytes.updateHeartRate(hrmCounter); + ble.updateCharacteristicValue(hrmRate.getValueAttribute().getHandle(), valueBytes.getPointer(), valueBytes.getNumValueBytes()); + } + + /** + * This callback allows the HeartRateService to receive updates to the + * controlPoint Characteristic. + * + * @param[in] params + * Information about the characterisitc being updated. + */ + virtual void onDataWritten(const GattWriteCallbackParams *params) { + if (params->handle == 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. + */ + } + } + +protected: + void setupService(void) { + GattCharacteristic *charTable[] = {&hrmRate, &hrmLocation, &controlPoint}; + GattService hrmService(GattService::UUID_HEART_RATE_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); + + ble.addService(hrmService); + ble.onDataWritten(this, &HeartRateService::onDataWritten); + } + +protected: + /* 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]; + }; + +protected: + BLE &ble; + + HeartRateValueBytes valueBytes; + uint8_t controlPointValue; + + GattCharacteristic hrmRate; + ReadOnlyGattCharacteristic<uint8_t> hrmLocation; + WriteOnlyGattCharacteristic<uint8_t> controlPoint; +}; + +#endif /* #ifndef __BLE_HEART_RATE_SERVICE_H__*/ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/services/LinkLossService.h Fri Jun 19 15:53:29 2015 +0100 @@ -0,0 +1,103 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BLE_LINK_LOSS_SERVICE_H__ +#define __BLE_LINK_LOSS_SERVICE_H__ + +#include "Gap.h" + +/** +* @class LinkLossService +* @brief This service defines behavior when a link is lost between two devices. <br> +* Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.link_loss.xml <br> +* Alertness Level Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.alert_level.xml <br> +*/ +class LinkLossService { +public: + enum AlertLevel_t { + NO_ALERT = 0, + MILD_ALERT = 1, + HIGH_ALERT = 2 + }; + + typedef void (* callback_t)(AlertLevel_t level); + + /** + * @param[ref] ble + * BLE object for the underlying controller. + */ + LinkLossService(BLE &bleIn, callback_t callbackIn, AlertLevel_t levelIn = NO_ALERT) : + ble(bleIn), + alertLevel(levelIn), + callback(callbackIn), + alertLevelChar(GattCharacteristic::UUID_ALERT_LEVEL_CHAR, reinterpret_cast<uint8_t *>(&alertLevel)) { + static bool serviceAdded = false; /* We should only ever add one LinkLoss service. */ + if (serviceAdded) { + return; + } + + GattCharacteristic *charTable[] = {&alertLevelChar}; + GattService linkLossService(GattService::UUID_LINK_LOSS_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); + + ble.addService(linkLossService); + serviceAdded = true; + + ble.addToDisconnectionCallChain(this, &LinkLossService::onDisconnectionFilter); + ble.onDataWritten(this, &LinkLossService::onDataWritten); + } + + /** + * Update the callback. + */ + void setCallback(callback_t newCallback) { + callback = newCallback; + } + + /** + * Update Alertness Level. + */ + void setAlertLevel(AlertLevel_t newLevel) { + alertLevel = newLevel; + } + +private: + /** + * This callback allows receiving updates to the AlertLevel Characteristic. + * + * @param[in] params + * Information about the characterisitc being updated. + */ + virtual void onDataWritten(const GattWriteCallbackParams *params) { + if (params->charHandle == alertLevelChar.getValueHandle()) { + alertLevel = *reinterpret_cast<const AlertLevel_t *>(params->data); + } + } + + void onDisconnectionFilter(void) { + if (alertLevel != NO_ALERT) { + callback(alertLevel); + } + } + +protected: + BLE &ble; + AlertLevel_t alertLevel; + callback_t callback; + + ReadWriteGattCharacteristic<uint8_t> alertLevelChar; +}; + +#endif /* __BLE_LINK_LOSS_SERVICE_H__ */ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/services/UARTService.h Fri Jun 19 15:53:29 2015 +0100 @@ -0,0 +1,202 @@ +/* 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 "mbed.h" +#include "Stream.h" + +#include "ble/UUID.h" +#include "ble/BLE.h" + +extern const uint8_t UARTServiceBaseUUID[UUID::LENGTH_OF_LONG_UUID]; +extern const uint16_t UARTServiceShortUUID; +extern const uint16_t UARTServiceTXCharacteristicShortUUID; +extern const uint16_t UARTServiceRXCharacteristicShortUUID; + +extern const uint8_t UARTServiceUUID[UUID::LENGTH_OF_LONG_UUID]; +extern const uint8_t UARTServiceUUID_reversed[UUID::LENGTH_OF_LONG_UUID]; + +extern const uint8_t UARTServiceTXCharacteristicUUID[UUID::LENGTH_OF_LONG_UUID]; +extern const uint8_t UARTServiceRXCharacteristicUUID[UUID::LENGTH_OF_LONG_UUID]; + +/** +* @class UARTService +* @brief BLE Service to enable UART over BLE +*/ +class UARTService { +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: + + /** + * @param[ref] ble + * BLE object for the underlying controller. + */ + UARTService(BLE &_ble) : + 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(); + } + + /** + * 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. + */ + size_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; + } + + /** + * Helper function to write out strings. + * @param str The received string. + * @return Amount of characters appended to the rxCharacteristic. + */ + size_t writeString(const char *str) { + return write(str, strlen(str)); + } + + /** + * 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. + */ + int _putc(int c) { + return (write(&c, 1) == 1) ? 1 : EOF; + } + + /** + * Override for Stream::_getc() + * @return + * The character read. + */ + int _getc() { + if (receiveBufferIndex == numBytesReceived) { + return EOF; + } + + return receiveBuffer[receiveBufferIndex++]; + } + +private: + /** + * 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. + */ + void onDataWritten(const GattWriteCallbackParams *params) { + if (params->handle == getTXCharacteristicHandle()) { + uint16_t bytesRead = params->len; + if (bytesRead <= BLE_UART_SERVICE_MAX_DATA_LEN) { + numBytesReceived = bytesRead; + receiveBufferIndex = 0; + memcpy(receiveBuffer, params->data, numBytesReceived); + } + } + } + +private: + BLE &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__*/ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/services/URIBeaconConfigService.h Fri Jun 19 15:53:29 2015 +0100 @@ -0,0 +1,468 @@ +/* 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 SERVICES_URIBEACONCONFIGSERVICE_H_ +#define SERVICES_URIBEACONCONFIGSERVICE_H_ + +#include "ble/BLE.h" +#include "mbed.h" + +extern const uint8_t UUID_URI_BEACON_SERVICE[UUID::LENGTH_OF_LONG_UUID]; +extern const uint8_t UUID_LOCK_STATE_CHAR[UUID::LENGTH_OF_LONG_UUID]; +extern const uint8_t UUID_LOCK_CHAR[UUID::LENGTH_OF_LONG_UUID]; +extern const uint8_t UUID_UNLOCK_CHAR[UUID::LENGTH_OF_LONG_UUID]; +extern const uint8_t UUID_URI_DATA_CHAR[UUID::LENGTH_OF_LONG_UUID]; +extern const uint8_t UUID_FLAGS_CHAR[UUID::LENGTH_OF_LONG_UUID]; +extern const uint8_t UUID_ADV_POWER_LEVELS_CHAR[UUID::LENGTH_OF_LONG_UUID]; +extern const uint8_t UUID_TX_POWER_MODE_CHAR[UUID::LENGTH_OF_LONG_UUID]; +extern const uint8_t UUID_BEACON_PERIOD_CHAR[UUID::LENGTH_OF_LONG_UUID]; +extern const uint8_t UUID_RESET_CHAR[UUID::LENGTH_OF_LONG_UUID]; + +extern const uint8_t BEACON_UUID[sizeof(UUID::ShortUUIDBytes_t)]; + +/** +* @class URIBeaconConfigService +* @brief UriBeacon Configuration Service. Can be used to set URL, adjust power levels, and set flags. +* See http://uribeacon.org +* +*/ +class URIBeaconConfigService { + public: + /** + * @brief Transmission Power Modes for UriBeacon + */ + static const uint8_t TX_POWER_MODE_LOWEST = 0; /*!< Lowest TX power mode */ + static const uint8_t TX_POWER_MODE_LOW = 1; /*!< Low TX power mode */ + static const uint8_t TX_POWER_MODE_MEDIUM = 2; /*!< Medium TX power mode */ + static const uint8_t TX_POWER_MODE_HIGH = 3; /*!< High TX power mode */ + static const unsigned NUM_POWER_MODES = 4; /*!< Number of Power Modes defined */ + + static const int ADVERTISING_INTERVAL_MSEC = 1000; // Advertising interval for config service. + static const int SERVICE_DATA_MAX = 31; // Maximum size of service data in ADV packets + + typedef uint8_t Lock_t[16]; /* 128 bits */ + typedef int8_t PowerLevels_t[NUM_POWER_MODES]; + + static const int URI_DATA_MAX = 18; + typedef uint8_t UriData_t[URI_DATA_MAX]; + + struct Params_t { + Lock_t lock; + uint8_t uriDataLength; + UriData_t uriData; + uint8_t flags; + PowerLevels_t advPowerLevels; // Current value of AdvertisedPowerLevels + uint8_t txPowerMode; // Firmware power levels used with setTxPower() + uint16_t beaconPeriod; + }; + + /** + * @param[ref] ble + * BLE object for the underlying controller. + * @param[in/out] paramsIn + * Reference to application-visible beacon state, loaded + * from persistent storage at startup. + * @paramsP[in] resetToDefaultsFlag + * Applies to the state of the 'paramsIn' parameter. + * If true, it indicates that paramsIn is potentially + * un-initialized, and default values should be used + * instead. Otherwise, paramsIn overrides the defaults. + * @param[in] defaultUriDataIn + * Default un-encoded URI; applies only if the resetToDefaultsFlag is true. + * @param[in] defaultAdvPowerLevelsIn + * Default power-levels array; applies only if the resetToDefaultsFlag is true. + */ + URIBeaconConfigService(BLE &bleIn, + Params_t ¶msIn, + bool resetToDefaultsFlag, + const char *defaultURIDataIn, + PowerLevels_t &defaultAdvPowerLevelsIn) : + ble(bleIn), + params(paramsIn), + defaultUriDataLength(), + defaultUriData(), + defaultAdvPowerLevels(defaultAdvPowerLevelsIn), + initSucceeded(false), + resetFlag(), + lockedStateChar(UUID_LOCK_STATE_CHAR, &lockedState), + lockChar(UUID_LOCK_CHAR, ¶ms.lock), + uriDataChar(UUID_URI_DATA_CHAR, params.uriData, 0, URI_DATA_MAX, + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE), + unlockChar(UUID_UNLOCK_CHAR, ¶ms.lock), + flagsChar(UUID_FLAGS_CHAR, ¶ms.flags), + advPowerLevelsChar(UUID_ADV_POWER_LEVELS_CHAR, ¶ms.advPowerLevels), + txPowerModeChar(UUID_TX_POWER_MODE_CHAR, ¶ms.txPowerMode), + beaconPeriodChar(UUID_BEACON_PERIOD_CHAR, ¶ms.beaconPeriod), + resetChar(UUID_RESET_CHAR, &resetFlag) { + + encodeURI(defaultURIDataIn, defaultUriData, defaultUriDataLength); + if (defaultUriDataLength > URI_DATA_MAX) { + return; + } + + if (!resetToDefaultsFlag && (params.uriDataLength > URI_DATA_MAX)) { + resetToDefaultsFlag = true; + } + if (resetToDefaultsFlag) { + resetToDefaults(); + } else { + updateCharacteristicValues(); + } + + lockedState = isLocked(); + + lockChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::lockAuthorizationCallback); + unlockChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::unlockAuthorizationCallback); + uriDataChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::uriDataWriteAuthorizationCallback); + flagsChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::basicAuthorizationCallback<uint8_t>); + advPowerLevelsChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::basicAuthorizationCallback<PowerLevels_t>); + txPowerModeChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::powerModeAuthorizationCallback); + beaconPeriodChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::basicAuthorizationCallback<uint16_t>); + resetChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::basicAuthorizationCallback<uint8_t>); + + static GattCharacteristic *charTable[] = { + &lockedStateChar, &lockChar, &unlockChar, &uriDataChar, + &flagsChar, &advPowerLevelsChar, &txPowerModeChar, &beaconPeriodChar, &resetChar + }; + + GattService configService(UUID_URI_BEACON_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); + + ble.addService(configService); + ble.onDataWritten(this, &URIBeaconConfigService::onDataWrittenCallback); + + setupURIBeaconConfigAdvertisements(); /* Setup advertising for the configService. */ + + initSucceeded = true; + } + + bool configuredSuccessfully(void) const { + return initSucceeded; + } + + /* Start out by advertising the configService for a limited time after + * startup; and switch to the normal non-connectible beacon functionality + * afterwards. */ + void setupURIBeaconConfigAdvertisements() + { + const char DEVICE_NAME[] = "mUriBeacon Config"; + + ble.gap().clearAdvertisingPayload(); + + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); + + // UUID is in different order in the ADV frame (!) + uint8_t reversedServiceUUID[sizeof(UUID_URI_BEACON_SERVICE)]; + for (unsigned int i = 0; i < sizeof(UUID_URI_BEACON_SERVICE); i++) { + reversedServiceUUID[i] = UUID_URI_BEACON_SERVICE[sizeof(UUID_URI_BEACON_SERVICE) - i - 1]; + } + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, reversedServiceUUID, sizeof(reversedServiceUUID)); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_TAG); + ble.gap().accumulateScanResponse(GapAdvertisingData::COMPLETE_LOCAL_NAME, reinterpret_cast<const uint8_t *>(&DEVICE_NAME), sizeof(DEVICE_NAME)); + ble.gap().accumulateScanResponse(GapAdvertisingData::TX_POWER_LEVEL, + reinterpret_cast<uint8_t *>(&defaultAdvPowerLevels[URIBeaconConfigService::TX_POWER_MODE_LOW]), + sizeof(uint8_t)); + + ble.gap().setTxPower(params.advPowerLevels[params.txPowerMode]); + ble.gap().setDeviceName(reinterpret_cast<const uint8_t *>(&DEVICE_NAME)); + ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); + ble.gap().setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(ADVERTISING_INTERVAL_MSEC)); + } + + /* Helper function to switch to the non-connectible normal mode for URIBeacon. This gets called after a timeout. */ + void setupURIBeaconAdvertisements() + { + uint8_t serviceData[SERVICE_DATA_MAX]; + unsigned serviceDataLen = 0; + + /* Reinitialize the BLE stack. This will clear away the existing services and advertising state. */ + ble.shutdown(); + ble.init(); + + // Fields from the Service + unsigned beaconPeriod = params.beaconPeriod; + unsigned txPowerMode = params.txPowerMode; + unsigned uriDataLength = params.uriDataLength; + URIBeaconConfigService::UriData_t &uriData = params.uriData; + URIBeaconConfigService::PowerLevels_t &advPowerLevels = params.advPowerLevels; + uint8_t flags = params.flags; + + extern void saveURIBeaconConfigParams(const Params_t *paramsP); /* forward declaration; necessary to avoid a circular dependency. */ + saveURIBeaconConfigParams(¶ms); + + ble.gap().clearAdvertisingPayload(); + ble.gap().setTxPower(params.advPowerLevels[params.txPowerMode]); + ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED); + ble.gap().setAdvertisingInterval(beaconPeriod); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, BEACON_UUID, sizeof(BEACON_UUID)); + + serviceData[serviceDataLen++] = BEACON_UUID[0]; + serviceData[serviceDataLen++] = BEACON_UUID[1]; + serviceData[serviceDataLen++] = flags; + serviceData[serviceDataLen++] = advPowerLevels[txPowerMode]; + for (unsigned j = 0; j < uriDataLength; j++) { + serviceData[serviceDataLen++] = uriData[j]; + } + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, serviceData, serviceDataLen); + } + + private: + // True if the lock bits are non-zero + bool isLocked() { + Lock_t testLock; + memset(testLock, 0, sizeof(Lock_t)); + return memcmp(params.lock, testLock, sizeof(Lock_t)); + } + + /* + * This callback is invoked when a GATT client attempts to modify any of the + * characteristics of this service. Attempts to do so are also applied to + * the internal state of this service object. + */ + void onDataWrittenCallback(const GattWriteCallbackParams *writeParams) { + uint16_t handle = writeParams->handle; + + if (handle == lockChar.getValueHandle()) { + // Validated earlier + memcpy(params.lock, writeParams->data, sizeof(Lock_t)); + // use isLocked() in case bits are being set to all 0's + lockedState = isLocked(); + } else if (handle == unlockChar.getValueHandle()) { + // Validated earlier + memset(params.lock, 0, sizeof(Lock_t)); + lockedState = false; + } else if (handle == uriDataChar.getValueHandle()) { + params.uriDataLength = writeParams->len; + memcpy(params.uriData, writeParams->data, params.uriDataLength); + } else if (handle == flagsChar.getValueHandle()) { + params.flags = *(writeParams->data); + } else if (handle == advPowerLevelsChar.getValueHandle()) { + memcpy(params.advPowerLevels, writeParams->data, sizeof(PowerLevels_t)); + } else if (handle == txPowerModeChar.getValueHandle()) { + params.txPowerMode = *(writeParams->data); + } else if (handle == beaconPeriodChar.getValueHandle()) { + params.beaconPeriod = *((uint16_t *)(writeParams->data)); + + /* Re-map beaconPeriod to within permissible bounds if necessary. */ + if (params.beaconPeriod != 0) { + bool paramsUpdated = false; + if (params.beaconPeriod < ble.gap().getMinAdvertisingInterval()) { + params.beaconPeriod = ble.gap().getMinAdvertisingInterval(); + paramsUpdated = true; + } else if (params.beaconPeriod > ble.gap().getMaxAdvertisingInterval()) { + params.beaconPeriod = ble.gap().getMaxAdvertisingInterval(); + paramsUpdated = true; + } + if (paramsUpdated) { + ble.updateCharacteristicValue(beaconPeriodChar.getValueHandle(), reinterpret_cast<uint8_t *>(¶ms.beaconPeriod), sizeof(uint16_t)); + } + } + } else if (handle == resetChar.getValueHandle()) { + resetToDefaults(); + } + } + + /* + * Reset the default values. + */ + void resetToDefaults(void) { + lockedState = false; + memset(params.lock, 0, sizeof(Lock_t)); + memcpy(params.uriData, defaultUriData, URI_DATA_MAX); + params.uriDataLength = defaultUriDataLength; + params.flags = 0; + memcpy(params.advPowerLevels, defaultAdvPowerLevels, sizeof(PowerLevels_t)); + params.txPowerMode = TX_POWER_MODE_LOW; + params.beaconPeriod = 1000; + updateCharacteristicValues(); + } + + /* + * Internal helper function used to update the GATT database following any + * change to the internal state of the service object. + */ + void updateCharacteristicValues(void) { + ble.updateCharacteristicValue(lockedStateChar.getValueHandle(), &lockedState, 1); + ble.updateCharacteristicValue(uriDataChar.getValueHandle(), params.uriData, params.uriDataLength); + ble.updateCharacteristicValue(flagsChar.getValueHandle(), ¶ms.flags, 1); + ble.updateCharacteristicValue(beaconPeriodChar.getValueHandle(), + reinterpret_cast<uint8_t *>(¶ms.beaconPeriod), sizeof(uint16_t)); + ble.updateCharacteristicValue(txPowerModeChar.getValueHandle(), ¶ms.txPowerMode, 1); + ble.updateCharacteristicValue(advPowerLevelsChar.getValueHandle(), + reinterpret_cast<uint8_t *>(params.advPowerLevels), sizeof(PowerLevels_t)); + } + +private: + void lockAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { + if (lockedState) { + authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; + } else if (authParams->len != sizeof(Lock_t)) { + authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH; + } else if (authParams->offset != 0) { + authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; + } else { + authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; + } + } + + + void unlockAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { + if (!lockedState) { + authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; + } else if (authParams->len != sizeof(Lock_t)) { + authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH; + } else if (authParams->offset != 0) { + authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; + } else if (memcmp(authParams->data, params.lock, sizeof(Lock_t)) != 0) { + authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; + } else { + authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; + } + } + + void uriDataWriteAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { + if (lockedState) { + authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; + } else if (authParams->offset != 0) { + authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; + } else { + authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; + } + } + + void powerModeAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { + if (lockedState) { + authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; + } else if (authParams->len != sizeof(uint8_t)) { + authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH; + } else if (authParams->offset != 0) { + authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; + } else if (*((uint8_t *)authParams->data) >= NUM_POWER_MODES) { + authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED; + } else { + authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; + } + } + + template <typename T> + void basicAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { + if (lockedState) { + authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; + } else if (authParams->len != sizeof(T)) { + authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH; + } else if (authParams->offset != 0) { + authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; + } else { + authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; + } + } + +protected: + BLE &ble; + Params_t ¶ms; + + size_t defaultUriDataLength; // Default value that is restored on reset + UriData_t defaultUriData; // Default value that is restored on reset + PowerLevels_t &defaultAdvPowerLevels; // Default value that is restored on reset + + uint8_t lockedState; + bool initSucceeded; + uint8_t resetFlag; + + ReadOnlyGattCharacteristic<uint8_t> lockedStateChar; + WriteOnlyGattCharacteristic<Lock_t> lockChar; + GattCharacteristic uriDataChar; + WriteOnlyGattCharacteristic<Lock_t> unlockChar; + ReadWriteGattCharacteristic<uint8_t> flagsChar; + ReadWriteGattCharacteristic<PowerLevels_t> advPowerLevelsChar; + ReadWriteGattCharacteristic<uint8_t> txPowerModeChar; + ReadWriteGattCharacteristic<uint16_t> beaconPeriodChar; + WriteOnlyGattCharacteristic<uint8_t> resetChar; + +public: + /* + * Encode a human-readable URI into the binary format defined by URIBeacon spec (https://github.com/google/uribeacon/tree/master/specification). + */ + static void encodeURI(const char *uriDataIn, UriData_t uriDataOut, size_t &sizeofURIDataOut) { + const char *prefixes[] = { + "http://www.", + "https://www.", + "http://", + "https://", + "urn:uuid:" + }; + const size_t NUM_PREFIXES = sizeof(prefixes) / sizeof(char *); + const char *suffixes[] = { + ".com/", + ".org/", + ".edu/", + ".net/", + ".info/", + ".biz/", + ".gov/", + ".com", + ".org", + ".edu", + ".net", + ".info", + ".biz", + ".gov" + }; + const size_t NUM_SUFFIXES = sizeof(suffixes) / sizeof(char *); + + sizeofURIDataOut = 0; + memset(uriDataOut, 0, sizeof(UriData_t)); + + if ((uriDataIn == NULL) || (strlen(uriDataIn) == 0)) { + return; + } + + /* + * handle prefix + */ + for (unsigned i = 0; i < NUM_PREFIXES; i++) { + size_t prefixLen = strlen(prefixes[i]); + if (strncmp(uriDataIn, prefixes[i], prefixLen) == 0) { + uriDataOut[sizeofURIDataOut++] = i; + uriDataIn += prefixLen; + break; + } + } + + /* + * handle suffixes + */ + while (*uriDataIn && (sizeofURIDataOut < URI_DATA_MAX)) { + /* check for suffix match */ + unsigned i; + for (i = 0; i < NUM_SUFFIXES; i++) { + size_t suffixLen = strlen(suffixes[i]); + if (strncmp(uriDataIn, suffixes[i], suffixLen) == 0) { + uriDataOut[sizeofURIDataOut++] = i; + uriDataIn += suffixLen; + break; /* from the for loop for checking against suffixes */ + } + } + /* This is the default case where we've got an ordinary character which doesn't match a suffix. */ + if (i == NUM_SUFFIXES) { + uriDataOut[sizeofURIDataOut++] = *uriDataIn; + ++uriDataIn; + } + } + } +}; + +#endif // SERVICES_URIBEACONCONFIGSERVICE_H_ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ble/services/iBeaconService.h Fri Jun 19 15:53:29 2015 +0100 @@ -0,0 +1,74 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __BLE_IBEACON_SERVICE_H__ +#define __BLE_IBEACON_SERVICE_H__ + +#include "core_cmInstr.h" +#include "BLE.h" + +/** +* @class iBeaconService +* @brief iBeacon Service. This service sets up a device to broadcast advertising packets to mimic an iBeacon<br> +*/ + +class iBeaconService +{ +public: + typedef const uint8_t LocationUUID_t[16]; + + union Payload { + uint8_t raw[25]; + struct { + uint16_t companyID; + uint8_t ID; + uint8_t len; + uint8_t proximityUUID[16]; + uint16_t majorNumber; + uint16_t minorNumber; + uint8_t txPower; + }; + + Payload(LocationUUID_t uuid, uint16_t majNum, uint16_t minNum, uint8_t transmitPower, uint16_t companyIDIn) : + companyID(companyIDIn), ID(0x02), len(0x15), majorNumber(__REV16(majNum)), minorNumber(__REV16(minNum)), txPower(transmitPower) + { + memcpy(proximityUUID, uuid, sizeof(LocationUUID_t)); + } + }; + +public: + iBeaconService(BLE &_ble, + LocationUUID_t uuid, + uint16_t majNum, + uint16_t minNum, + uint8_t txP = 0xC8, + uint16_t compID = 0x004C) : + ble(_ble), data(uuid, majNum, minNum, txP, compID) + { + // Generate the 0x020106 part of the iBeacon Prefix + ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE ); + // Generate the 0x1AFF part of the iBeacon Prefix + ble.accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, data.raw, sizeof(data.raw)); + + // Set advertising type + ble.setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED); + } + +private: + BLE &ble; + Payload data; +}; + +#endif //__BLE_IBEACON_SERVICE_H__ \ No newline at end of file
--- a/common/BLEDevice.cpp Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "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; -} \ No newline at end of file
--- a/common/BLEDeviceInstanceBase.h Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __BLE_DEVICE_INSTANCE_BASE__ -#define __BLE_DEVICE_INSTANCE_BASE__ - -/** - * The interface for the transport object to be created by the target library's - * createBLEDeviceInstance(). - */ -class BLEDeviceInstanceBase -{ -public: - virtual const char *getVersion(void) = 0; - virtual Gap& getGap() = 0; - virtual GattServer& getGattServer() = 0; - virtual ble_error_t init(void) = 0; - virtual ble_error_t shutdown(void) = 0; - virtual ble_error_t reset(void) = 0; - virtual ble_error_t initializeSecurity(bool enableBonding = true, - bool requireMITM = true, - Gap::SecurityIOCapabilities_t iocaps = Gap::IO_CAPS_NONE, - const Gap::Passkey_t passkey = NULL) = 0; - virtual ble_error_t setTxPower(int8_t txPower) = 0; - virtual void getPermittedTxPowerValues(const int8_t **, size_t *) = 0; - virtual void waitForEvent(void) = 0; -}; - -/** - * BLEDevice uses composition to hide an interface object encapsulating the - * backend transport. - * - * The following API is used to create the singleton interface object. An - * implementation for this function must be provided by the device-specific - * library, otherwise there will be a linker error. - */ -extern BLEDeviceInstanceBase *createBLEDeviceInstance(void); - -#endif // ifndef __BLE_DEVICE_INSTANCE_BASE__ \ No newline at end of file
--- a/common/blecommon.h Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,135 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __BLE_COMMON_H__ -#define __BLE_COMMON_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stdint.h> -#include <stddef.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_ERROR_INVALID_PARAM = 4, /**< One of the supplied parameters is invalid */ - BLE_STACK_BUSY = 5, /**< The stack is busy */ - BLE_ERROR_INVALID_STATE = 6, /**< Invalid state. */ - BLE_ERROR_NO_MEM = 7, /**< Out of Memory */ - BLE_ERROR_UNSPECIFIED = 8, /**< Unknown error. */ -} ble_error_t; - -#ifdef __cplusplus -} -#endif - -#endif // ifndef __BLE_COMMON_H__ \ No newline at end of file
--- a/common/readme.txt Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -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/module.json Fri Jun 19 15:53:29 2015 +0100 @@ -0,0 +1,29 @@ +{ + "name": "ble", + "version": "0.0.0", + "description": "The BLE module offers a high level abstraction for using Bluetooth Low Energy on multiple platforms.", + "keywords": [ + "Bluetooth", + "BLE" + ], + "author": "Rohit Grover", + "repository": { + "url": "git@github.com:mbedmicro/BLE_API.git", + "type": "git" + }, + "homepage": "http://mbed.org/ble", + "licenses": [ + { + "url": "https://spdx.org/licenses/Apache-2.0", + "type": "Apache-2.0" + } + ], + "dependencies": { + "mbed": "^3.0.2" + }, + "targetDependencies": { + "nrf51822": { + "ble-nrf51822":"~0.0.1" + } + } +} \ No newline at end of file
--- a/public/BLEDevice.h Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1090 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __BLE_DEVICE__ -#define __BLE_DEVICE__ - -#include "blecommon.h" -#include "Gap.h" -#include "GattServer.h" -#include "GapScanningParams.h" -#include "BLEDeviceInstanceBase.h" - -/** - * The base class used to abstract away BLE capable radio transceivers or SOCs, - * to enable this BLE API to work with any radio transparently. - */ -class BLEDevice -{ -public: - /** - * Initialize the BLE controller. This should be called before using - * anything else in the BLE_API. - * - * init() hands control to the underlying BLE module to accomplish - * initialization. This initialization may tacitly depend on other hardware - * setup (such as clocks or power-modes) which happens early on during - * system startup. It may not be safe to call init() from global static - * context where ordering is compiler specific and can't be guaranteed--it - * is safe to call BLEDevice::init() from within main(). - */ - ble_error_t init(); - - ble_error_t reset(void); - - /** - * Purge the BLE stack of GATT and GAP state. init() must be called afterwards to re-instate services and GAP state. - */ - ble_error_t shutdown(void); - - /* GAP specific APIs */ -public: - /** - * Set the BTLE MAC address and type. - * @return BLE_ERROR_NONE on success. - */ - ble_error_t setAddress(Gap::AddressType_t type, const Gap::Address_t address); - - /** - * Fetch the BTLE MAC address and type. - * @return BLE_ERROR_NONE on success. - */ - ble_error_t getAddress(Gap::AddressType_t *typeP, Gap::Address_t address); - - /** - * @param[in] advType - * The GAP advertising mode to use for this device. Valid - * values are defined in AdvertisingType: - * - * \par ADV_NON_CONNECTABLE_UNDIRECTED - * All connections to the peripheral device will be refused. - * - * \par ADV_CONNECTABLE_DIRECTED - * Only connections from a pre-defined central device will be - * accepted. - * - * \par ADV_CONNECTABLE_UNDIRECTED - * Any central device can connect to this peripheral. - * - * \par ADV_SCANNABLE_UNDIRECTED - * Include support for Scan Response payloads. - * - * \par - * See Bluetooth Core Specification 4.0 (Vol. 3), Part C, - * Section 9.3 and Core Specification 4.0 (Vol. 6), Part B, - * Section 2.3.1 for further information on GAP connection - * modes - */ - void setAdvertisingType(GapAdvertisingParams::AdvertisingType); - - /** - * @param[in] interval - * Advertising interval in units of milliseconds. Advertising - * is disabled if interval is 0. If interval is smaller than - * the minimum supported value, then the minimum supported - * value is used instead. - * - * \par - * Decreasing this value will allow central devices to detect - * your peripheral faster at the expense of more power being - * used by the radio due to the higher data transmit rate. - * - * \par - * This field must be set to 0 if connectionMode is equal - * to ADV_CONNECTABLE_DIRECTED - * - * \par - * See Bluetooth Core Specification, Vol 3., Part C, - * Appendix A for suggested advertising intervals. - * - * @Note: [WARNING] This API previously used 0.625ms as the unit for its - * 'interval' argument. That required an explicit conversion from - * milliseconds using Gap::MSEC_TO_GAP_DURATION_UNITS(). This conversion is - * no longer required as the new units are milliseconds. Any application - * code depending on the old semantics would need to be updated accordingly. - */ - void setAdvertisingInterval(uint16_t interval); - - /** - * @return Minimum Advertising interval in milliseconds. - */ - uint16_t getMinAdvertisingInterval(void) const; - /** - * @return Minimum Advertising interval in milliseconds for non connectible mode. - */ - uint16_t getMinNonConnectableAdvertisingInterval(void) const; - /** - * @return Maximum Advertising interval in milliseconds. - */ - uint16_t getMaxAdvertisingInterval(void) const; - - /** - * @param[in] timeout - * Advertising timeout between 0x1 and 0x3FFF (1 and 16383) - * in seconds. Enter 0 to disable the advertising timeout. - */ - void setAdvertisingTimeout(uint16_t timeout); - - /** - * Please refer to the APIs above. - */ - void setAdvertisingParams(const GapAdvertisingParams &advParams); - - /** - * @return Read back advertising parameters. Useful for storing and - * restoring parameters rapidly. - */ - const GapAdvertisingParams &getAdvertisingParams(void) const; - - /** - * This API is typically used as an internal helper to udpate the transport - * backend with advertising data before starting to advertise. It may also - * be explicity used to dynamically reset the accumulated advertising - * payload and scanResponse; to do this, the application can clear and re- - * accumulate a new advertising payload (and scanResponse) before using this - * API. - */ - ble_error_t setAdvertisingPayload(void); - - /** - * Set advertising data using object. - */ - ble_error_t setAdvertisingData(const GapAdvertisingData &advData); - - /** - * @return Read back advertising data. Useful for storing and - * restoring payload. - */ - const GapAdvertisingData &getAdvertisingData(void) const; - - /** - * Reset any advertising payload prepared from prior calls to - * accumulateAdvertisingPayload(). - * - * Note: This should be followed by a call to setAdvertisingPayload() or - * startAdvertising() before the update takes effect. - */ - void clearAdvertisingPayload(void); - - /** - * Accumulate an AD structure in the advertising payload. Please note that - * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used - * as an additional 31 bytes if the advertising payload proves to be too - * small. - * - * @param flags - * The flags to be added. Multiple flags may be specified in - * combination. - */ - ble_error_t accumulateAdvertisingPayload(uint8_t flags); - - /** - * Accumulate an AD structure in the advertising payload. Please note that - * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used - * as an additional 31 bytes if the advertising payload proves to be too - * small. - * - * @param app - * The appearance of the peripheral. - */ - ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::Appearance app); - - /** - * Accumulate an AD structure in the advertising payload. Please note that - * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used - * as an additional 31 bytes if the advertising payload proves to be too - * small. - * - * @param app - * The max transmit power to be used by the controller. This is - * only a hint. - */ - ble_error_t accumulateAdvertisingPayloadTxPower(int8_t power); - - /** - * Accumulate a variable length byte-stream as an AD structure in the - * advertising payload. Please note that the payload is limited to 31 bytes. - * The SCAN_RESPONSE message may be used as an additional 31 bytes if the - * advertising payload proves to be too small. - * - * @param type The type which describes the variable length data. - * @param data data bytes. - * @param len length of data. - */ - ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len); - - /** - * Accumulate a variable length byte-stream as an AD structure in the - * scanResponse payload. - * - * @param type The type which describes the variable length data. - * @param data data bytes. - * @param len length of data. - */ - ble_error_t accumulateScanResponse(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len); - - /** - * Reset any scan response prepared from prior calls to - * accumulateScanResponse(). - * - * Note: This should be followed by a call to setAdvertisingPayload() or - * startAdvertising() before the update takes effect. - */ - void clearScanResponse(void); - - /** - * Start advertising (GAP Discoverable, Connectable modes, Broadcast - * Procedure). - */ - ble_error_t startAdvertising(void); - - /** - * Stop advertising (GAP Discoverable, Connectable modes, Broadcast - * Procedure). - */ - ble_error_t stopAdvertising(void); - - /** - * Setup parameters for GAP scanning--i.e. observer mode. - * @param interval Scan interval (in milliseconds) [valid values lie between 2.5ms and 10.24s]. - * @param window Scan Window (in milliseconds) [valid values lie between 2.5ms and 10.24s]. - * @param timeout Scan timeout (in seconds) between 0x0001 and 0xFFFF, 0x0000 disables timeout. - * @param activeScanning Set to True if active-scanning is required. This is used to fetch the - * scan response from a peer if possible. - * - * The scanning window divided by the interval determines the duty cycle for - * scanning. For example, if the interval is 100ms and the window is 10ms, - * then the controller will scan for 10 percent of the time. It is possible - * to have the interval and window set to the same value. In this case, - * scanning is continuous, with a change of scanning frequency once every - * interval. - * - * Once the scanning parameters have been configured, scanning can be - * enabled by using startScan(). - * - * @Note: The scan interval and window are recommendations to the BLE stack. - */ - ble_error_t setScanParams(uint16_t interval = GapScanningParams::SCAN_INTERVAL_MAX, - uint16_t window = GapScanningParams::SCAN_WINDOW_MAX, - uint16_t timeout = 0, - bool activeScanning = false); - ble_error_t setScanInterval(uint16_t interval); - ble_error_t setScanWindow (uint16_t window); - ble_error_t setScanTimeout (uint16_t timeout); - void setActiveScan (bool activeScanning); - - /** - * Start scanning (Observer Procedure) based on the scan-params currently - * in effect. - * - * @param callback The application callback to be invoked upon receiving - * every advertisement report. Can be passed in as NULL, in which case - * scanning may not be enabled at all. - */ - ble_error_t startScan(void (*callback)(const Gap::AdvertisementCallbackParams_t *params)); - - /** - * Start scanning (Observer Procedure) based on the scan-params currently - * in effect. - * - * @param[in] object - * @param[in] callbackMember - * The above pair of parameters define the callback object - * and member function to receive the advertisement params. - */ - template<typename T> - ble_error_t startScan(T *object, void (T::*memberCallback)(const Gap::AdvertisementCallbackParams_t *params)); - - /** - * Stop scanning. The current scanning parameters remain in effect. - * - * @retval BLE_ERROR_NONE if successfully stopped scanning procedure. - */ - ble_error_t stopScan(void); - - /** - * This call initiates the disconnection procedure, and its completion will - * be communicated to the application with an invocation of the - * onDisconnection callback. - * - * @param reason - * The reason for disconnection to be sent back to the peer. - */ - ble_error_t disconnect(Gap::DisconnectionReason_t reason); - - /* APIs to set GAP callbacks. */ - void onTimeout(Gap::EventCallback_t timeoutCallback); - - void onConnection(Gap::ConnectionEventCallback_t connectionCallback); - /** - * Used to setup a callback for GAP disconnection. - */ - void onDisconnection(Gap::DisconnectionEventCallback_t disconnectionCallback); - - /** - * Append to a chain of callbacks to be invoked upon disconnection; these - * callbacks receive no context and are therefore different from the - * onDisconnection callback. - */ - template<typename T> - void addToDisconnectionCallChain(T *tptr, void (T::*mptr)(void)); - - /** - * Add a callback for the GATT event DATA_SENT (which is triggered when - * updates are sent out by GATT in the form of notifications). - * - * @Note: it is possible to chain together multiple onDataSent callbacks - * (potentially from different modules of an application) to receive updates - * to characteristics. - * - * @Note: it is also possible to setup a callback into a member function of - * some object. - */ - void onDataSent(void (*callback)(unsigned count)); - template <typename T> void onDataSent(T * objPtr, void (T::*memberPtr)(unsigned count)); - - /** - * Setup a callback for when a characteristic has its value updated by a - * client. - * - * @Note: it is possible to chain together multiple onDataWritten callbacks - * (potentially from different modules of an application) to receive updates - * to characteristics. Many services, such as DFU and UART add their own - * onDataWritten callbacks behind the scenes to trap interesting events. - * - * @Note: it is also possible to setup a callback into a member function of - * some object. - */ - void onDataWritten(void (*callback)(const GattCharacteristicWriteCBParams *eventDataP)); - template <typename T> void onDataWritten(T * objPtr, void (T::*memberPtr)(const GattCharacteristicWriteCBParams *context)); - - /** - * Setup a callback for when a characteristic is being read by a client. - * - * @Note: this functionality may not be available on all underlying stacks. - * You could use GattCharacteristic::setReadAuthorizationCallback() as an - * alternative. - * - * @Note: it is possible to chain together multiple onDataRead callbacks - * (potentially from different modules of an application) to receive updates - * to characteristics. Services may add their own onDataRead callbacks - * behind the scenes to trap interesting events. - * - * @Note: it is also possible to setup a callback into a member function of - * some object. - * - * @return BLE_ERROR_NOT_IMPLEMENTED if this functionality isn't available; - * else BLE_ERROR_NONE. - */ - ble_error_t onDataRead(void (*callback)(const GattCharacteristicReadCBParams *eventDataP)); - template <typename T> ble_error_t onDataRead(T * objPtr, void (T::*memberPtr)(const GattCharacteristicReadCBParams *context)); - - void onUpdatesEnabled(GattServer::EventCallback_t callback); - void onUpdatesDisabled(GattServer::EventCallback_t callback); - void onConfirmationReceived(GattServer::EventCallback_t callback); - - /** - * Radio Notification is a feature that enables ACTIVE and INACTIVE - * (nACTIVE) signals from the stack that notify the application when the - * radio is in use. The signal is sent using software interrupt. - * - * The ACTIVE signal is sent before the Radio Event starts. The nACTIVE - * signal is sent at the end of the Radio Event. These signals can be used - * by the application programmer to synchronize application logic with radio - * activity. For example, the ACTIVE signal can be used to shut off external - * devices to manage peak current drawn during periods when the radio is on, - * or to trigger sensor data collection for transmission in the Radio Event. - * - * @param callback - * The application handler to be invoked in response to a radio - * ACTIVE/INACTIVE event. - */ - void onRadioNotification(Gap::RadioNotificationEventCallback_t callback); - - /** - * Add a service declaration to the local server ATT table. Also add the - * characteristics contained within. - */ - ble_error_t addService(GattService &service); - - /** - * Returns the current GAP state of the device using a bitmask which - * describes whether the device is advertising and/or connected. - */ - Gap::GapState_t getGapState(void) const; - - /** - * @param[in/out] lengthP - * input: Length in bytes to be read, - * output: Total length of attribute value upon successful return. - */ - ble_error_t readCharacteristicValue(GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP); - /** - * A version of the same as above with connection handle parameter to allow fetches for connection-specific multivalued attribtues (such as the CCCDs). - */ - ble_error_t readCharacteristicValue(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP); - - /** - * @param localOnly - * Only update the characteristic locally regardless of notify/indicate flags in the CCCD. - */ - ble_error_t updateCharacteristicValue(GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size, bool localOnly = false); - /** - * A version of the same as above with connection handle parameter to allow updates for connection-specific multivalued attribtues (such as the CCCDs). - */ - ble_error_t updateCharacteristicValue(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size, bool localOnly = false); - - /** - * Yield control to the BLE stack or to other tasks waiting for events. This - * is a sleep function which will return when there is an application - * specific interrupt, but the MCU might wake up several times before - * returning (to service the stack). This is not always interchangeable with - * WFE(). - */ - void waitForEvent(void); - - ble_error_t getPreferredConnectionParams(Gap::ConnectionParams_t *params); - ble_error_t setPreferredConnectionParams(const Gap::ConnectionParams_t *params); - ble_error_t updateConnectionParams(Gap::Handle_t handle, const Gap::ConnectionParams_t *params); - - /** - * This call allows the application to get the BLE stack version information. - * - * @return A pointer to a const string representing the version. - * Note: The string is owned by the BLE_API. - */ - const char *getVersion(void); - - /** - * Set the device name characteristic in the GAP service. - * @param deviceName The new value for the device-name. This is a UTF-8 encoded, <b>NULL-terminated</b> string. - */ - ble_error_t setDeviceName(const uint8_t *deviceName); - - /** - * Get the value of the device name characteristic in the GAP service. - * @param[out] deviceName Pointer to an empty buffer where the UTF-8 *non NULL- - * terminated* string will be placed. Set this - * value to NULL in order to obtain the deviceName-length - * from the 'length' parameter. - * - * @param[in/out] lengthP (on input) Length of the buffer pointed to by deviceName; - * (on output) the complete device name length (without the - * null terminator). - * - * @note If the device name is longer than the size of the supplied buffer, - * length will return the complete device name length, - * and not the number of bytes actually returned in deviceName. - * The application may use this information to retry with a suitable buffer size. - * - * Sample use: - * uint8_t deviceName[20]; - * unsigned length = sizeof(deviceName); - * ble.getDeviceName(deviceName, &length); - * if (length < sizeof(deviceName)) { - * deviceName[length] = 0; - * } - * DEBUG("length: %u, deviceName: %s\r\n", length, deviceName); - */ - ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP); - - /** - * Set the appearance characteristic in the GAP service. - * @param[in] appearance The new value for the device-appearance. - */ - ble_error_t setAppearance(uint16_t appearance); - - /** - * Set the appearance characteristic in the GAP service. - * @param[out] appearance The new value for the device-appearance. - */ - ble_error_t getAppearance(uint16_t *appearanceP); - - /** - * Set the radio's transmit power. - * @param[in] txPower Radio transmit power in dBm. - */ - ble_error_t setTxPower(int8_t txPower); - - /** - * Query the underlying stack for permitted arguments for setTxPower(). - * - * @param[out] valueArrayPP - * Out parameter to receive the immutable array of Tx values. - * @param[out] countP - * Out parameter to receive the array's size. - */ - void getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP); - - /** - * Enable the BLE stack's Security Manager. The Security Manager implements - * the actual cryptographic algorithms and protocol exchanges that allow two - * devices to securely exchange data and privately detect each other. - * Calling this API is a prerequisite for encryption and pairing (bonding). - * - * @param[in] enableBonding Allow for bonding. - * @param[in] requireMITM Require protection for man-in-the-middle attacks. - * @param[in] iocaps To specify IO capabilities of this peripheral, - * such as availability of a display or keyboard to - * support out-of-band exchanges of security data. - * @param[in] passkey To specify a static passkey. - * - * @return BLE_ERROR_NONE on success. - */ - ble_error_t initializeSecurity(bool enableBonding = true, - bool requireMITM = true, - Gap::SecurityIOCapabilities_t iocaps = Gap::IO_CAPS_NONE, - const Gap::Passkey_t passkey = NULL); - - /** - * Setup a callback for when the security setup procedure (key generation - * and exchange) for a link has started. This will be skipped for bonded - * devices. The callback is passed in parameters received from the peer's - * security request: bool allowBonding, bool requireMITM, and - * SecurityIOCapabilities_t. - */ - void onSecuritySetupInitiated(Gap::SecuritySetupInitiatedCallback_t callback); - - /** - * Setup a callback for when the security setup procedure (key generation - * and exchange) for a link has completed. This will be skipped for bonded - * devices. The callback is passed in the success/failure status of the - * security setup procedure. - */ - void onSecuritySetupCompleted(Gap::SecuritySetupCompletedCallback_t callback); - - /** - * Setup a callback for when a link with the peer is secured. For bonded - * devices, subsequent reconnections with bonded peer will result only in - * this callback when the link is secured and setup procedures will not - * occur unless the bonding information is either lost or deleted on either - * or both sides. The callback is passed in a Gap::SecurityMode_t according - * to the level of security in effect for the secured link. - */ - void onLinkSecured(Gap::LinkSecuredCallback_t callback); - - /** - * Setup a callback for successful bonding; i.e. that link-specific security - * context is stored persistently for a peer device. - */ - void onSecurityContextStored(Gap::HandleSpecificEvent_t callback); - - /** - * Setup a callback for when the passkey needs to be displayed on a - * peripheral with DISPLAY capability. This happens when security is - * configured to prevent Man-In-The-Middle attacks, and a PIN (or passkey) - * needs to be exchanged between the peers to authenticate the connection - * attempt. - */ - void onPasskeyDisplay(Gap::PasskeyDisplayCallback_t callback); - - /** - * Get the security status of a connection. - * - * @param[in] connectionHandle Handle to identify the connection. - * @param[out] securityStatusP security status. - * - * @return BLE_SUCCESS Or appropriate error code indicating reason for failure. - */ - ble_error_t getLinkSecurity(Gap::Handle_t connectionHandle, Gap::LinkSecurityStatus_t *securityStatusP); - - /** - * Delete all peer device context and all related bonding information from - * the database within the security manager. - * - * @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure. - * @retval BLE_ERROR_INVALID_STATE If the API is called without module initialization and/or - * application registration. - */ - ble_error_t purgeAllBondingState(void); - -public: - BLEDevice() : transport(createBLEDeviceInstance()), advParams(), advPayload(), scanResponse(), needToSetAdvPayload(true), scanningParams() { - advPayload.clear(); - scanResponse.clear(); - } - -private: - BLEDeviceInstanceBase *const transport; /* the device specific backend */ - - GapAdvertisingParams advParams; - GapAdvertisingData advPayload; - GapAdvertisingData scanResponse; - - /* Accumulation of AD structures in the advertisement payload should - * eventually result in a call to the target's setAdvertisingData() before - * the server begins advertising. This flag marks the status of the pending update.*/ - bool needToSetAdvPayload; - - GapScanningParams scanningParams; -}; - -/* BLEDevice methods. Most of these simply forward the calls to the underlying - * transport.*/ - -inline ble_error_t -BLEDevice::reset(void) -{ - return transport->reset(); -} - -inline ble_error_t -BLEDevice::shutdown(void) -{ - clearAdvertisingPayload(); - return transport->shutdown(); -} - -inline ble_error_t -BLEDevice::setAddress(Gap::AddressType_t type, const Gap::Address_t address) -{ - return transport->getGap().setAddress(type, address); -} - -inline ble_error_t -BLEDevice::getAddress(Gap::AddressType_t *typeP, Gap::Address_t address) -{ - return transport->getGap().getAddress(typeP, address); -} - -inline void -BLEDevice::setAdvertisingType(GapAdvertisingParams::AdvertisingType advType) -{ - advParams.setAdvertisingType(advType); -} - -inline void -BLEDevice::setAdvertisingInterval(uint16_t interval) -{ - if (interval == 0) { - stopAdvertising(); - } else if (interval < getMinAdvertisingInterval()) { - interval = getMinAdvertisingInterval(); - } - advParams.setInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(interval)); -} - -inline uint16_t -BLEDevice::getMinAdvertisingInterval(void) const { - return transport->getGap().getMinAdvertisingInterval(); -} - -inline uint16_t -BLEDevice::getMinNonConnectableAdvertisingInterval(void) const { - return transport->getGap().getMinNonConnectableAdvertisingInterval(); -} - -inline uint16_t -BLEDevice::getMaxAdvertisingInterval(void) const { - return transport->getGap().getMaxAdvertisingInterval(); -} - -inline void -BLEDevice::setAdvertisingTimeout(uint16_t timeout) -{ - advParams.setTimeout(timeout); -} - -inline void -BLEDevice::setAdvertisingParams(const GapAdvertisingParams &newAdvParams) -{ - advParams = newAdvParams; -} - -inline const GapAdvertisingParams & -BLEDevice::getAdvertisingParams(void) const -{ - return advParams; -} - -inline void -BLEDevice::clearAdvertisingPayload(void) -{ - needToSetAdvPayload = true; - advPayload.clear(); -} - -inline ble_error_t -BLEDevice::accumulateAdvertisingPayload(uint8_t flags) -{ - needToSetAdvPayload = true; - return advPayload.addFlags(flags); -} - -inline ble_error_t -BLEDevice::accumulateAdvertisingPayload(GapAdvertisingData::Appearance app) -{ - needToSetAdvPayload = true; - transport->getGap().setAppearance(app); - return advPayload.addAppearance(app); -} - -inline ble_error_t -BLEDevice::accumulateAdvertisingPayloadTxPower(int8_t txPower) -{ - needToSetAdvPayload = true; - return advPayload.addTxPower(txPower); -} - -inline ble_error_t -BLEDevice::accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) -{ - needToSetAdvPayload = true; - if (type == GapAdvertisingData::COMPLETE_LOCAL_NAME) { - transport->getGap().setDeviceName(data); - } - return advPayload.addData(type, data, len); -} - -inline ble_error_t -BLEDevice::accumulateScanResponse(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) -{ - needToSetAdvPayload = true; - return scanResponse.addData(type, data, len); -} - -inline void -BLEDevice::clearScanResponse(void) -{ - needToSetAdvPayload = true; - scanResponse.clear(); -} - -inline ble_error_t -BLEDevice::setAdvertisingPayload(void) { - needToSetAdvPayload = false; - return transport->getGap().setAdvertisingData(advPayload, scanResponse); -} - -inline ble_error_t -BLEDevice::setAdvertisingData(const GapAdvertisingData& newPayload) -{ - advPayload = newPayload; - - return setAdvertisingPayload(); -} - -inline const GapAdvertisingData & -BLEDevice::getAdvertisingData(void) const { - return advPayload; -} - -inline ble_error_t -BLEDevice::startAdvertising(void) -{ - ble_error_t rc; - if ((rc = transport->getGattServer().initializeGATTDatabase()) != BLE_ERROR_NONE) { - return rc; - } - if (needToSetAdvPayload) { - if ((rc = setAdvertisingPayload()) != BLE_ERROR_NONE) { - return rc; - } - } - - return transport->getGap().startAdvertising(advParams); -} - -inline ble_error_t -BLEDevice::stopAdvertising(void) -{ - return transport->getGap().stopAdvertising(); -} - -inline ble_error_t -BLEDevice::setScanParams(uint16_t interval, uint16_t window, uint16_t timeout, bool activeScanning) { - ble_error_t rc; - if (((rc = scanningParams.setInterval(interval)) == BLE_ERROR_NONE) && - ((rc = scanningParams.setWindow(window)) == BLE_ERROR_NONE) && - ((rc = scanningParams.setTimeout(timeout)) == BLE_ERROR_NONE)) { - scanningParams.setActiveScanning(activeScanning); - return BLE_ERROR_NONE; - } - - return rc; -} - -inline ble_error_t -BLEDevice::setScanInterval(uint16_t interval) { - return scanningParams.setInterval(interval); -} - -inline ble_error_t -BLEDevice::setScanWindow(uint16_t window) { - return scanningParams.setWindow(window); -} - -inline ble_error_t -BLEDevice::setScanTimeout(uint16_t timeout) { - return scanningParams.setTimeout(timeout); -} - -inline void -BLEDevice::setActiveScan(bool activeScanning) { - return scanningParams.setActiveScanning(activeScanning); -} - -inline ble_error_t -BLEDevice::startScan(void (*callback)(const Gap::AdvertisementCallbackParams_t *params)) { - return transport->getGap().startScan(scanningParams, callback); -} - -template<typename T> -inline ble_error_t -BLEDevice::startScan(T *object, void (T::*memberCallback)(const Gap::AdvertisementCallbackParams_t *params)) { - return transport->getGap().startScan(scanningParams, object, memberCallback); -} - -inline ble_error_t -BLEDevice::stopScan(void) { - return transport->getGap().stopScan(); -} - -inline ble_error_t -BLEDevice::disconnect(Gap::DisconnectionReason_t reason) -{ - return transport->getGap().disconnect(reason); -} - -inline void -BLEDevice::onTimeout(Gap::EventCallback_t timeoutCallback) -{ - transport->getGap().setOnTimeout(timeoutCallback); -} - -inline void -BLEDevice::onConnection(Gap::ConnectionEventCallback_t connectionCallback) -{ - transport->getGap().setOnConnection(connectionCallback); -} - -inline void -BLEDevice::onDisconnection(Gap::DisconnectionEventCallback_t disconnectionCallback) -{ - transport->getGap().setOnDisconnection(disconnectionCallback); -} - -template<typename T> -inline void -BLEDevice::addToDisconnectionCallChain(T *tptr, void (T::*mptr)(void)) { - transport->getGap().addToDisconnectionCallChain(tptr, mptr); -} - -inline void -BLEDevice::onDataSent(void (*callback)(unsigned count)) { - transport->getGattServer().setOnDataSent(callback); -} - -template <typename T> inline void -BLEDevice::onDataSent(T *objPtr, void (T::*memberPtr)(unsigned count)) { - transport->getGattServer().setOnDataSent(objPtr, memberPtr); -} - -inline void -BLEDevice::onDataWritten(void (*callback)(const GattCharacteristicWriteCBParams *eventDataP)) { - transport->getGattServer().setOnDataWritten(callback); -} - -template <typename T> inline void -BLEDevice::onDataWritten(T *objPtr, void (T::*memberPtr)(const GattCharacteristicWriteCBParams *context)) { - transport->getGattServer().setOnDataWritten(objPtr, memberPtr); -} - -inline ble_error_t -BLEDevice::onDataRead(void (*callback)(const GattCharacteristicReadCBParams *eventDataP)) { - return transport->getGattServer().setOnDataRead(callback); -} - -template <typename T> inline ble_error_t -BLEDevice::onDataRead(T *objPtr, void (T::*memberPtr)(const GattCharacteristicReadCBParams *context)) { - return transport->getGattServer().setOnDataRead(objPtr, memberPtr); -} - -inline void -BLEDevice::onUpdatesEnabled(GattServer::EventCallback_t callback) -{ - transport->getGattServer().setOnUpdatesEnabled(callback); -} - -inline void -BLEDevice::onUpdatesDisabled(GattServer::EventCallback_t callback) -{ - transport->getGattServer().setOnUpdatesDisabled(callback); -} - -inline void -BLEDevice::onConfirmationReceived(GattServer::EventCallback_t callback) -{ - transport->getGattServer().setOnConfirmationReceived(callback); -} - -inline void -BLEDevice::onRadioNotification(Gap::RadioNotificationEventCallback_t callback) -{ - transport->getGap().setOnRadioNotification(callback); -} - -inline ble_error_t -BLEDevice::addService(GattService &service) -{ - return transport->getGattServer().addService(service); -} - -inline Gap::GapState_t -BLEDevice::getGapState(void) const -{ - return transport->getGap().getState(); -} - -inline ble_error_t BLEDevice::readCharacteristicValue(GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP) -{ - return transport->getGattServer().readValue(attributeHandle, buffer, lengthP); -} - -inline ble_error_t BLEDevice::readCharacteristicValue(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP) -{ - return transport->getGattServer().readValue(connectionHandle, attributeHandle, buffer, lengthP); -} - -inline ble_error_t -BLEDevice::updateCharacteristicValue(GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size, bool localOnly) -{ - return transport->getGattServer().updateValue(attributeHandle, const_cast<uint8_t *>(value), size, localOnly); -} - -inline ble_error_t -BLEDevice::updateCharacteristicValue(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size, bool localOnly) -{ - return transport->getGattServer().updateValue(connectionHandle, attributeHandle, const_cast<uint8_t *>(value), size, localOnly); -} - -inline void -BLEDevice::waitForEvent(void) -{ - transport->waitForEvent(); -} - -inline ble_error_t -BLEDevice::getPreferredConnectionParams(Gap::ConnectionParams_t *params) -{ - return transport->getGap().getPreferredConnectionParams(params); -} - -inline ble_error_t -BLEDevice::setPreferredConnectionParams(const Gap::ConnectionParams_t *params) -{ - return transport->getGap().setPreferredConnectionParams(params); -} - -inline ble_error_t -BLEDevice::updateConnectionParams(Gap::Handle_t handle, const Gap::ConnectionParams_t *params) { - return transport->getGap().updateConnectionParams(handle, params); -} - -inline const char * -BLEDevice::getVersion(void) -{ - return transport->getVersion(); -} - -inline ble_error_t -BLEDevice::setDeviceName(const uint8_t *deviceName) -{ - return transport->getGap().setDeviceName(deviceName); -} - -inline ble_error_t -BLEDevice::getDeviceName(uint8_t *deviceName, unsigned *lengthP) -{ - return transport->getGap().getDeviceName(deviceName, lengthP); -} - -inline ble_error_t -BLEDevice::setAppearance(uint16_t appearance) -{ - return transport->getGap().setAppearance(appearance); -} - -inline ble_error_t -BLEDevice::getAppearance(uint16_t *appearanceP) -{ - return transport->getGap().getAppearance(appearanceP); -} - -inline ble_error_t -BLEDevice::setTxPower(int8_t txPower) -{ - return transport->setTxPower(txPower); -} - -inline void -BLEDevice::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) -{ - transport->getPermittedTxPowerValues(valueArrayPP, countP); -} - -inline ble_error_t -BLEDevice::initializeSecurity(bool enableBonding, - bool requireMITM, - Gap::SecurityIOCapabilities_t iocaps, - const Gap::Passkey_t passkey) -{ - return transport->initializeSecurity(enableBonding, requireMITM, iocaps, passkey); -} - -inline void -BLEDevice::onSecuritySetupInitiated(Gap::SecuritySetupInitiatedCallback_t callback) -{ - transport->getGap().setOnSecuritySetupInitiated(callback); -} - -inline void -BLEDevice::onSecuritySetupCompleted(Gap::SecuritySetupCompletedCallback_t callback) -{ - transport->getGap().setOnSecuritySetupCompleted(callback); -} - -inline void -BLEDevice::onLinkSecured(Gap::LinkSecuredCallback_t callback) -{ - transport->getGap().setOnLinkSecured(callback); -} - -inline void -BLEDevice::onSecurityContextStored(Gap::HandleSpecificEvent_t callback) -{ - transport->getGap().setOnSecurityContextStored(callback); -} - -inline void -BLEDevice::onPasskeyDisplay(Gap::PasskeyDisplayCallback_t callback) -{ - return transport->getGap().setOnPasskeyDisplay(callback); -} - -inline ble_error_t -BLEDevice::getLinkSecurity(Gap::Handle_t connectionHandle, Gap::LinkSecurityStatus_t *securityStatusP) -{ - return transport->getGap().getLinkSecurity(connectionHandle, securityStatusP); -} - -inline ble_error_t -BLEDevice::purgeAllBondingState(void) -{ - return transport->getGap().purgeAllBondingState(); -} - -#endif // ifndef __BLE_DEVICE__ \ No newline at end of file
--- a/public/CallChainOfFunctionPointersWithContext.h Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,149 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef MBED_CALLCHAIN_OF_FUNCTION_POINTERS_WITH_CONTEXT_H -#define MBED_CALLCHAIN_OF_FUNCTION_POINTERS_WITH_CONTEXT_H - -#include <string.h> -#include "FunctionPointerWithContext.h" - - -/** Group one or more functions in an instance of a CallChainOfFunctionPointersWithContext, then call them in - * sequence using CallChainOfFunctionPointersWithContext::call(). Used mostly by the interrupt chaining code, - * but can be used for other purposes. - * - * Example: - * @code - * - * CallChainOfFunctionPointersWithContext<void *> chain; - * - * void first(void *context) { - * printf("'first' function.\n"); - * } - * - * void second(void *context) { - * printf("'second' function.\n"); - * } - * - * class Test { - * public: - * void f(void *context) { - * printf("A::f (class member).\n"); - * } - * }; - * - * int main() { - * Test test; - * - * chain.add(second); - * chain.add_front(first); - * chain.add(&test, &Test::f); - * chain.call(); - * } - * @endcode - */ - -template <typename ContextType> -class CallChainOfFunctionPointersWithContext { -public: - typedef FunctionPointerWithContext<ContextType> *pFunctionPointerWithContext_t; - -public: - /** Create an empty chain - * - * @param size (optional) Initial size of the chain - */ - CallChainOfFunctionPointersWithContext() : chainHead(NULL) { - /* empty */ - } - - virtual ~CallChainOfFunctionPointersWithContext() { - clear(); - } - - /** Add a function at the front of the chain - * - * @param function A pointer to a void function - * - * @returns - * The function object created for 'function' - */ - pFunctionPointerWithContext_t add(void (*function)(ContextType context)) { - return common_add(new FunctionPointerWithContext<ContextType>(function)); - } - - /** Add a function at the front of the chain - * - * @param tptr pointer to the object to call the member function on - * @param mptr pointer to the member function to be called - * - * @returns - * The function object created for 'tptr' and 'mptr' - */ - template<typename T> - pFunctionPointerWithContext_t add(T *tptr, void (T::*mptr)(ContextType context)) { - return common_add(new FunctionPointerWithContext<ContextType>(tptr, mptr)); - } - - /** Clear the call chain (remove all functions in the chain). - */ - void clear(void) { - pFunctionPointerWithContext_t fptr = chainHead; - while (fptr) { - pFunctionPointerWithContext_t deadPtr = fptr; - fptr = deadPtr->getNext(); - delete deadPtr; - } - - chainHead = NULL; - } - - bool hasCallbacksAttached(void) const { - return (chainHead != NULL); - } - - /** Call all the functions in the chain in sequence - * @Note: the stack frames of all the callbacks within the chained - * FunctionPointers will stack up. Hopefully there won't be too many - * chained FunctionPointers. - */ - void call(ContextType context) { - if (chainHead) { - chainHead->call(context); - } - } - -private: - pFunctionPointerWithContext_t common_add(pFunctionPointerWithContext_t pf) { - if (chainHead == NULL) { - chainHead = pf; - } else { - pf->chainAsNext(chainHead); - chainHead = pf; - } - - return chainHead; - } - -private: - pFunctionPointerWithContext_t chainHead; - - /* disallow copy constructor and assignment operators */ -private: - CallChainOfFunctionPointersWithContext(const CallChainOfFunctionPointersWithContext &); - CallChainOfFunctionPointersWithContext & operator = (const CallChainOfFunctionPointersWithContext &); -}; - -#endif \ No newline at end of file
--- a/public/FunctionPointerWithContext.h Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,129 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MBED_FUNCTIONPOINTER_WITH_CONTEXT_H -#define MBED_FUNCTIONPOINTER_WITH_CONTEXT_H - -#include <string.h> - - -/** A class for storing and calling a pointer to a static or member void function - * which takes a context. - */ -template <typename ContextType> -class FunctionPointerWithContext { -public: - typedef FunctionPointerWithContext<ContextType> *pFunctionPointerWithContext_t; - typedef void (*pvoidfcontext_t)(ContextType context); - - /** Create a FunctionPointerWithContext, attaching a static function - * - * @param function The void static function to attach (default is none) - */ - FunctionPointerWithContext(void (*function)(ContextType context) = NULL) : - _function(NULL), _object(NULL), _member(), _membercaller(NULL), _next(NULL) { - attach(function); - } - - /** Create a FunctionPointerWithContext, attaching a member function - * - * @param object The object pointer to invoke the member function on (i.e. the this pointer) - * @param function The address of the void member function to attach - */ - template<typename T> - FunctionPointerWithContext(T *object, void (T::*member)(ContextType context)) : - _function(NULL), _object(NULL), _member(), _membercaller(NULL), _next(NULL) { - attach(object, member); - } - - /** Attach a static function - * - * @param function The void static function to attach (default is none) - */ - void attach(void (*function)(ContextType context) = NULL) { - _function = function; - } - - /** Attach a member function - * - * @param object The object pointer to invoke the member function on (i.e. the this pointer) - * @param function The address of the void member function to attach - */ - template<typename T> - void attach(T *object, void (T::*member)(ContextType context)) { - _object = static_cast<void *>(object); - memcpy(_member, (char *)&member, sizeof(member)); - _membercaller = &FunctionPointerWithContext::membercaller<T>; - } - - /** Call the attached static or member function; and if there are chained - * FunctionPointers their callbacks are invoked as well. - * @Note: all chained callbacks stack up; so hopefully there won't be too - * many FunctionPointers in a chain. */ - void call(ContextType context) { - if (_function) { - _function(context); - } else if (_object && _membercaller) { - _membercaller(_object, _member, context); - } - - /* Propagate the call to next in the chain. */ - if (_next) { - _next->call(context); - } - } - - /** - * Setup an external FunctionPointer as a next in the chain of related - * callbacks. Invoking call() on the head FunctionPointer will invoke all - * chained callbacks. - * - * Refer to 'CallChain' as an alternative. - */ - void chainAsNext(pFunctionPointerWithContext_t next) { - _next = next; - } - - pFunctionPointerWithContext_t getNext(void) const { - return _next; - } - - pvoidfcontext_t get_function() const { - return (pvoidfcontext_t)_function; - } - -private: - template<typename T> - static void membercaller(void *object, char *member, ContextType context) { - T *o = static_cast<T *>(object); - void (T::*m)(ContextType); - memcpy((char *)&m, member, sizeof(m)); - (o->*m)(context); - } - - void (*_function)(ContextType context); /**< static function pointer - NULL if none attached */ - void *_object; /**< object this pointer - NULL if none attached */ - char _member[16]; /**< raw member function pointer storage - converted back by - * registered _membercaller */ - void (*_membercaller)(void *, char *, ContextType); /**< registered membercaller function to convert back and call - * _member on _object passing the context. */ - pFunctionPointerWithContext_t _next; /**< Optional link to make a chain out of functionPointers; this - * allows chaining function pointers without requiring - * external memory to manage the chain. Also refer to - * 'CallChain' as an alternative. */ -}; - -#endif // ifndef MBED_FUNCTIONPOINTER_WITH_CONTEXT_H \ No newline at end of file
--- a/public/Gap.h Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,398 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __GAP_H__ -#define __GAP_H__ - -#include "GapAdvertisingData.h" -#include "GapAdvertisingParams.h" -#include "GapEvents.h" -#include "CallChain.h" -#include "FunctionPointerWithContext.h" - -using namespace mbed; - -class GapScanningParams; /* forward declaration */ - -class Gap { -public: - enum AddressType_t { - ADDR_TYPE_PUBLIC = 0, - ADDR_TYPE_RANDOM_STATIC, - ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE, - ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE - }; - typedef enum AddressType_t addr_type_t; /* @Note: deprecated. Use AddressType_t instead. */ - - static const unsigned ADDR_LEN = 6; - typedef uint8_t Address_t[ADDR_LEN]; /* 48-bit address, LSB format. */ - typedef Address_t address_t; /* @Note: deprecated. Use Address_t instead. */ - - enum AdvertisementType_t { - ADV_IND = 0x00, /**< Connectable undirected. */ - ADV_DIRECT_IND = 0x01, /**< Connectable directed. */ - ADV_SCAN_IND = 0x02, /**< Scannable undirected. */ - ADV_NONCONN_IND = 0x03, /**< Non connectable undirected. */ - }; - - /** - * 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) */ - struct GapState_t { - unsigned advertising : 1; /**< peripheral is currently advertising */ - unsigned connected : 1; /**< peripheral is connected to a central */ - }; - - 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; - - enum SecurityMode_t { - SECURITY_MODE_NO_ACCESS, - SECURITY_MODE_ENCRYPTION_OPEN_LINK, /**< require no protection, open link. */ - SECURITY_MODE_ENCRYPTION_NO_MITM, /**< require encryption, but no MITM protection. */ - SECURITY_MODE_ENCRYPTION_WITH_MITM, /**< require encryption and MITM protection. */ - SECURITY_MODE_SIGNED_NO_MITM, /**< require signing or encryption, but no MITM protection. */ - SECURITY_MODE_SIGNED_WITH_MITM, /**< require signing or encryption, and MITM protection. */ - }; - - /** - * @brief Defines possible security status/states. - * - * @details Defines possible security status/states of a link when requested by getLinkSecurity(). - */ - enum LinkSecurityStatus_t { - NOT_ENCRYPTED, /**< The link is not secured. */ - ENCRYPTION_IN_PROGRESS, /**< Link security is being established.*/ - ENCRYPTED /**< The link is secure.*/ - }; - - enum SecurityIOCapabilities_t { - IO_CAPS_DISPLAY_ONLY = 0x00, /**< Display Only. */ - IO_CAPS_DISPLAY_YESNO = 0x01, /**< Display and Yes/No entry. */ - IO_CAPS_KEYBOARD_ONLY = 0x02, /**< Keyboard Only. */ - IO_CAPS_NONE = 0x03, /**< No I/O capabilities. */ - IO_CAPS_KEYBOARD_DISPLAY = 0x04, /**< Keyboard and Display. */ - }; - - enum SecurityCompletionStatus_t { - SEC_STATUS_SUCCESS = 0x00, /**< Procedure completed with success. */ - SEC_STATUS_TIMEOUT = 0x01, /**< Procedure timed out. */ - SEC_STATUS_PDU_INVALID = 0x02, /**< Invalid PDU received. */ - SEC_STATUS_PASSKEY_ENTRY_FAILED = 0x81, /**< Passkey entry failed (user canceled or other). */ - SEC_STATUS_OOB_NOT_AVAILABLE = 0x82, /**< Out of Band Key not available. */ - SEC_STATUS_AUTH_REQ = 0x83, /**< Authentication requirements not met. */ - SEC_STATUS_CONFIRM_VALUE = 0x84, /**< Confirm value failed. */ - SEC_STATUS_PAIRING_NOT_SUPP = 0x85, /**< Pairing not supported. */ - SEC_STATUS_ENC_KEY_SIZE = 0x86, /**< Encryption key size. */ - SEC_STATUS_SMP_CMD_UNSUPPORTED = 0x87, /**< Unsupported SMP command. */ - SEC_STATUS_UNSPECIFIED = 0x88, /**< Unspecified reason. */ - SEC_STATUS_REPEATED_ATTEMPTS = 0x89, /**< Too little time elapsed since last attempt. */ - SEC_STATUS_INVALID_PARAMS = 0x8A, /**< Invalid parameters. */ - }; - - /** - * Declaration of type containing a passkey to be used during pairing. This - * is passed into initializeSecurity() to specify a pre-programmed passkey - * for authentication instead of generating a random one. - */ - static const unsigned PASSKEY_LEN = 6; - typedef uint8_t Passkey_t[PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */ - - static const uint16_t UNIT_1_25_MS = 1250; /**< Number of microseconds in 1.25 milliseconds. */ - static const uint16_t UNIT_0_625_MS = 625; /**< Number of microseconds in 0.625 milliseconds. */ - static uint16_t MSEC_TO_GAP_DURATION_UNITS(uint32_t durationInMillis) { - return (durationInMillis * 1000) / UNIT_1_25_MS; - } - static uint16_t MSEC_TO_ADVERTISEMENT_DURATION_UNITS(uint32_t durationInMillis) { - return (durationInMillis * 1000) / UNIT_0_625_MS; - } - static uint16_t ADVERTISEMENT_DURATION_UNITS_TO_MS(uint16_t gapUnits) { - return (gapUnits * UNIT_0_625_MS) / 1000; - } - - typedef void (*EventCallback_t)(void); - typedef void (*ConnectionEventCallback_t)(Handle_t, - AddressType_t peerAddrType, const Address_t peerAddr, - AddressType_t ownAddrType, const Address_t ownAddr, - const ConnectionParams_t *); - typedef void (*HandleSpecificEvent_t)(Handle_t handle); - typedef void (*DisconnectionEventCallback_t)(Handle_t, DisconnectionReason_t); - typedef void (*RadioNotificationEventCallback_t) (bool radio_active); /* gets passed true for ACTIVE; false for INACTIVE. */ - typedef void (*SecuritySetupInitiatedCallback_t)(Handle_t, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps); - typedef void (*SecuritySetupCompletedCallback_t)(Handle_t, SecurityCompletionStatus_t status); - typedef void (*LinkSecuredCallback_t)(Handle_t handle, SecurityMode_t securityMode); - typedef void (*PasskeyDisplayCallback_t)(Handle_t handle, const Passkey_t passkey); - - struct AdvertisementCallbackParams_t { - Address_t peerAddr; - int8_t rssi; - bool isScanResponse; - AdvertisementType_t type; - uint8_t advertisingDataLen; - const uint8_t *advertisingData; - }; - typedef FunctionPointerWithContext<const AdvertisementCallbackParams_t *> AdvertisementReportCallback_t; - - friend class BLEDevice; - -private: - /* These functions must be defined in the sub-class */ - virtual ble_error_t setAddress(AddressType_t type, const Address_t address) = 0; - virtual ble_error_t getAddress(AddressType_t *typeP, Address_t address) = 0; - virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &) = 0; - virtual ble_error_t startAdvertising(const GapAdvertisingParams &) = 0; - virtual ble_error_t stopAdvertising(void) = 0; - virtual ble_error_t stopScan() = 0; - virtual uint16_t getMinAdvertisingInterval(void) const = 0; - virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const = 0; - virtual uint16_t getMaxAdvertisingInterval(void) const = 0; - virtual ble_error_t disconnect(DisconnectionReason_t reason) = 0; - virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params) = 0; - virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params) = 0; - virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params) = 0; - - virtual ble_error_t purgeAllBondingState(void) = 0; - virtual ble_error_t getLinkSecurity(Handle_t connectionHandle, LinkSecurityStatus_t *securityStatusP) = 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; - - ble_error_t startScan(const GapScanningParams &scanningParams, void (*callback)(const AdvertisementCallbackParams_t *params)) { - ble_error_t err = BLE_ERROR_NONE; - if (callback) { - if ((err = startRadioScan(scanningParams)) == BLE_ERROR_NONE) { - onAdvertisementReport.attach(callback); - } - } - - return err; - } - - template<typename T> - ble_error_t startScan(const GapScanningParams &scanningParams, T *object, void (T::*callbackMember)(const AdvertisementCallbackParams_t *params)) { - ble_error_t err = BLE_ERROR_NONE; - if (object && callbackMember) { - if ((err = startRadioScan(scanningParams)) == BLE_ERROR_NONE) { - onAdvertisementReport.attach(object, callbackMember); - } - } - - return err; - } - -protected: - virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams) = 0; - - /* Event callback handlers */ - void setOnTimeout(EventCallback_t callback) {onTimeout = callback;} - void setOnConnection(ConnectionEventCallback_t callback) {onConnection = callback;} - - /** - * Set the application callback for disconnection events. - * @param callback - * Pointer to the unique callback. - */ - void setOnDisconnection(DisconnectionEventCallback_t callback) {onDisconnection = callback;} - - /** - * Set the application callback for radio-notification events. - * @param callback - * Handler to be executed in response to a radio notification event. - */ - virtual void setOnRadioNotification(RadioNotificationEventCallback_t callback) {onRadioNotification = callback;} - - /** - * To indicate that security procedure for link has started. - */ - virtual void setOnSecuritySetupInitiated(SecuritySetupInitiatedCallback_t callback) {onSecuritySetupInitiated = callback;} - - /** - * To indicate that security procedure for link has completed. - */ - virtual void setOnSecuritySetupCompleted(SecuritySetupCompletedCallback_t callback) {onSecuritySetupCompleted = callback;} - - /** - * To indicate that link with the peer is secured. For bonded devices, - * subsequent re-connections with bonded peer will result only in this callback - * when the link is secured and setup procedures will not occur unless the - * bonding information is either lost or deleted on either or both sides. - */ - virtual void setOnLinkSecured(LinkSecuredCallback_t callback) {onLinkSecured = callback;} - - /** - * To indicate that device context is stored persistently. - */ - virtual void setOnSecurityContextStored(HandleSpecificEvent_t callback) {onSecurityContextStored = callback;} - - /** - * To set the callback for when the passkey needs to be displayed on a peripheral with DISPLAY capability. - */ - virtual void setOnPasskeyDisplay(PasskeyDisplayCallback_t callback) {onPasskeyDisplay = callback;} - - /** - * Append to a chain of callbacks to be invoked upon disconnection; these - * callbacks receive no context and are therefore different from the - * onDisconnection callback. - * @param callback - * function pointer to be invoked upon disconnection; receives no context. - * - * @note the disconnection CallChain should have been merged with - * onDisconnctionCallback; but this was not possible because - * FunctionPointer (which is a building block for CallChain) doesn't - * accept variadic templates. - */ - template<typename T> - void addToDisconnectionCallChain(T *tptr, void (T::*mptr)(void)) {disconnectionCallChain.add(tptr, mptr);} - -private: - GapState_t getState(void) const { - return state; - } - -protected: - Gap() : - state(), - onTimeout(NULL), - onConnection(NULL), - onDisconnection(NULL), - onRadioNotification(), - onSecuritySetupInitiated(), - onSecuritySetupCompleted(), - onLinkSecured(), - onSecurityContextStored(), - onPasskeyDisplay(), - onAdvertisementReport(), - disconnectionCallChain() { - /* empty */ - } - -public: - void processConnectionEvent(Handle_t handle, AddressType_t peerAddrType, const Address_t peerAddr, AddressType_t ownAddrType, const Address_t ownAddr, const ConnectionParams_t *params) { - state.connected = 1; - if (onConnection) { - onConnection(handle, peerAddrType, peerAddr, ownAddrType, ownAddr, params); - } - } - - void processDisconnectionEvent(Handle_t handle, DisconnectionReason_t reason) { - state.connected = 0; - if (onDisconnection) { - onDisconnection(handle, reason); - } - disconnectionCallChain.call(); - } - - void processSecuritySetupInitiatedEvent(Handle_t handle, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps) { - if (onSecuritySetupInitiated) { - onSecuritySetupInitiated(handle, allowBonding, requireMITM, iocaps); - } - } - - void processSecuritySetupCompletedEvent(Handle_t handle, SecurityCompletionStatus_t status) { - if (onSecuritySetupCompleted) { - onSecuritySetupCompleted(handle, status); - } - } - - void processLinkSecuredEvent(Handle_t handle, SecurityMode_t securityMode) { - if (onLinkSecured) { - onLinkSecured(handle, securityMode); - } - } - - void processSecurityContextStoredEvent(Handle_t handle) { - if (onSecurityContextStored) { - onSecurityContextStored(handle); - } - } - - void processPasskeyDisplayEvent(Handle_t handle, const Passkey_t passkey) { - if (onPasskeyDisplay) { - onPasskeyDisplay(handle, passkey); - } - } - - void processAdvertisementReport(const Address_t peerAddr, - int8_t rssi, - bool isScanResponse, - AdvertisementType_t type, - uint8_t advertisingDataLen, - const uint8_t *advertisingData) { - AdvertisementCallbackParams_t params; - memcpy(params.peerAddr, peerAddr, ADDR_LEN); - params.rssi = rssi; - params.isScanResponse = isScanResponse; - params.type = type; - params.advertisingDataLen = advertisingDataLen; - params.advertisingData = advertisingData; - onAdvertisementReport.call(¶ms); - } - - void processEvent(GapEvents::gapEvent_e type) { - switch (type) { - case GapEvents::GAP_EVENT_TIMEOUT: - state.advertising = 0; - if (onTimeout) { - onTimeout(); - } - break; - default: - break; - } - } - -protected: - GapState_t state; - -protected: - EventCallback_t onTimeout; - ConnectionEventCallback_t onConnection; - DisconnectionEventCallback_t onDisconnection; - RadioNotificationEventCallback_t onRadioNotification; - SecuritySetupInitiatedCallback_t onSecuritySetupInitiated; - SecuritySetupCompletedCallback_t onSecuritySetupCompleted; - LinkSecuredCallback_t onLinkSecured; - HandleSpecificEvent_t onSecurityContextStored; - PasskeyDisplayCallback_t onPasskeyDisplay; - AdvertisementReportCallback_t onAdvertisementReport; - CallChain disconnectionCallChain; - -private: - /* disallow copy and assignment */ - Gap(const Gap &); - Gap& operator=(const Gap &); -}; - -#endif // ifndef __GAP_H__ \ No newline at end of file
--- a/public/GapAdvertisingData.h Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,309 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __GAP_ADVERTISING_DATA_H__ -#define __GAP_ADVERTISING_DATA_H__ - -#include <string.h> - -#include "blecommon.h" - -#define GAP_ADVERTISING_DATA_MAX_PAYLOAD (31) - -/**************************************************************************/ -/*! - \brief - This class provides several helper functions to generate properly - formatted GAP Advertising and Scan Response data payloads - - \note - See Bluetooth Specification 4.0 (Vol. 3), Part C, Section 11 and 18 - for further information on Advertising and Scan Response data. - - \par Advertising and Scan Response Payloads - Advertising data and Scan Response data are organized around a set of - data types called 'AD types' in Bluetooth 4.0 (see the Bluetooth Core - Specification v4.0, Vol. 3, Part C, Sections 11 and 18). - - \par - Each AD type has it's own standardized 'assigned number', as defined - by the Bluetooth SIG: - https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile - - \par - For convenience sake, all appropriate AD types have been encapsulated - into GapAdvertisingData::DataType. - - \par - Before the AD Types and their payload (if any) can be inserted into - the Advertising or Scan Response frames, they need to be formatted as - follows: - - \li \c Record length (1 byte) - \li \c AD Type (1 byte) - \li \c AD payload (optional, only present if record length > 1) - - \par - This class takes care of properly formatting the payload, performs - some basic checks on the payload length, and tries to avoid common - errors like adding an exclusive AD field twice in the Advertising - or Scan Response payload. - - \par EXAMPLE - - \code - - // ToDo - - \endcode -*/ -/**************************************************************************/ -class GapAdvertisingData -{ -public: - /**********************************************************************/ - /*! - \brief - A list of Advertising Data types commonly used by peripherals. - These AD types are used to describe the capabilities of the - peripheral, and get inserted inside the advertising or scan - response payloads. - - \par Source - \li \c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 11, 18 - \li \c https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile - */ - /**********************************************************************/ - enum DataType { - FLAGS = 0x01, /**< \ref *Flags */ - INCOMPLETE_LIST_16BIT_SERVICE_IDS = 0x02, /**< Incomplete list of 16-bit Service IDs */ - COMPLETE_LIST_16BIT_SERVICE_IDS = 0x03, /**< Complete list of 16-bit Service IDs */ - INCOMPLETE_LIST_32BIT_SERVICE_IDS = 0x04, /**< Incomplete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */ - COMPLETE_LIST_32BIT_SERVICE_IDS = 0x05, /**< Complete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */ - INCOMPLETE_LIST_128BIT_SERVICE_IDS = 0x06, /**< Incomplete list of 128-bit Service IDs */ - COMPLETE_LIST_128BIT_SERVICE_IDS = 0x07, /**< Complete list of 128-bit Service IDs */ - SHORTENED_LOCAL_NAME = 0x08, /**< Shortened Local Name */ - COMPLETE_LOCAL_NAME = 0x09, /**< Complete Local Name */ - TX_POWER_LEVEL = 0x0A, /**< TX Power Level (in dBm) */ - DEVICE_ID = 0x10, /**< Device ID */ - SLAVE_CONNECTION_INTERVAL_RANGE = 0x12, /**< Slave Connection Interval Range */ - SERVICE_DATA = 0x16, /**< Service Data */ - APPEARANCE = 0x19, /**< \ref Appearance */ - ADVERTISING_INTERVAL = 0x1A, /**< Advertising Interval */ - MANUFACTURER_SPECIFIC_DATA = 0xFF /**< Manufacturer Specific Data */ - }; - - /**********************************************************************/ - /*! - \brief - A list of values for the FLAGS AD Type - - \note - You can use more than one value in the FLAGS AD Type (ex. - LE_GENERAL_DISCOVERABLE and BREDR_NOT_SUPPORTED). - - \par Source - \li \c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 18.1 - */ - /**********************************************************************/ - enum Flags { - LE_LIMITED_DISCOVERABLE = 0x01, /**< *Peripheral device is discoverable for a limited period of time */ - LE_GENERAL_DISCOVERABLE = 0x02, /**< Peripheral device is discoverable at any moment */ - BREDR_NOT_SUPPORTED = 0x04, /**< Peripheral device is LE only */ - SIMULTANEOUS_LE_BREDR_C = 0x08, /**< Not relevant - central mode only */ - SIMULTANEOUS_LE_BREDR_H = 0x10 /**< Not relevant - central mode only */ - }; - - /**********************************************************************/ - /*! - \brief - A list of values for the APPEARANCE AD Type, which describes the - physical shape or appearance of the device - - \par Source - \li \c Bluetooth Core Specification Supplement, Part A, Section 1.12 - \li \c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 12.2 - \li \c https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml - */ - /**********************************************************************/ - enum Appearance { - UNKNOWN = 0, /**< Unknown of unspecified appearance type */ - GENERIC_PHONE = 64, /**< Generic Phone */ - GENERIC_COMPUTER = 128, /**< Generic Computer */ - GENERIC_WATCH = 192, /**< Generic Watch */ - WATCH_SPORTS_WATCH = 193, /**< Sports Watch */ - GENERIC_CLOCK = 256, /**< Generic Clock */ - GENERIC_DISPLAY = 320, /**< Generic Display */ - GENERIC_REMOTE_CONTROL = 384, /**< Generic Remote Control */ - GENERIC_EYE_GLASSES = 448, /**< Generic Eye Glasses */ - GENERIC_TAG = 512, /**< Generic Tag */ - GENERIC_KEYRING = 576, /**< Generic Keyring */ - GENERIC_MEDIA_PLAYER = 640, /**< Generic Media Player */ - GENERIC_BARCODE_SCANNER = 704, /**< Generic Barcode Scanner */ - GENERIC_THERMOMETER = 768, /**< Generic Thermometer */ - THERMOMETER_EAR = 769, /**< Ear Thermometer */ - GENERIC_HEART_RATE_SENSOR = 832, /**< Generic Heart Rate Sensor */ - HEART_RATE_SENSOR_HEART_RATE_BELT = 833, /**< Belt Heart Rate Sensor */ - GENERIC_BLOOD_PRESSURE = 896, /**< Generic Blood Pressure */ - BLOOD_PRESSURE_ARM = 897, /**< Arm Blood Pressure */ - BLOOD_PRESSURE_WRIST = 898, /**< Wrist Blood Pressure */ - HUMAN_INTERFACE_DEVICE_HID = 960, /**< Human Interface Device (HID) */ - KEYBOARD = 961, /**< Keyboard */ - MOUSE = 962, /**< Mouse */ - JOYSTICK = 963, /**< Joystick */ - GAMEPAD = 964, /**< Gamepad */ - DIGITIZER_TABLET = 965, /**< Digitizer Tablet */ - CARD_READER = 966, /**< Card Read */ - DIGITAL_PEN = 967, /**< Digital Pen */ - BARCODE_SCANNER = 968, /**< Barcode Scanner */ - GENERIC_GLUCOSE_METER = 1024, /**< Generic Glucose Meter */ - GENERIC_RUNNING_WALKING_SENSOR = 1088, /**< Generic Running/Walking Sensor */ - RUNNING_WALKING_SENSOR_IN_SHOE = 1089, /**< In Shoe Running/Walking Sensor */ - RUNNING_WALKING_SENSOR_ON_SHOE = 1090, /**< On Shoe Running/Walking Sensor */ - RUNNING_WALKING_SENSOR_ON_HIP = 1091, /**< On Hip Running/Walking Sensor */ - GENERIC_CYCLING = 1152, /**< Generic Cycling */ - CYCLING_CYCLING_COMPUTER = 1153, /**< Cycling Computer */ - CYCLING_SPEED_SENSOR = 1154, /**< Cycling Speed Senspr */ - CYCLING_CADENCE_SENSOR = 1155, /**< Cycling Cadence Sensor */ - CYCLING_POWER_SENSOR = 1156, /**< Cycling Power Sensor */ - CYCLING_SPEED_AND_CADENCE_SENSOR = 1157, /**< Cycling Speed and Cadence Sensor */ - PULSE_OXIMETER_GENERIC = 3136, /**< Generic Pulse Oximeter */ - PULSE_OXIMETER_FINGERTIP = 3137, /**< Fingertip Pulse Oximeter */ - PULSE_OXIMETER_WRIST_WORN = 3138, /**< Wrist Worn Pulse Oximeter */ - OUTDOOR_GENERIC = 5184, /**< Generic Outdoor */ - OUTDOOR_LOCATION_DISPLAY_DEVICE = 5185, /**< Outdoor Location Display Device */ - OUTDOOR_LOCATION_AND_NAVIGATION_DISPLAY_DEVICE = 5186, /**< Outdoor Location and Navigation Display Device */ - OUTDOOR_LOCATION_POD = 5187, /**< Outdoor Location Pod */ - OUTDOOR_LOCATION_AND_NAVIGATION_POD = 5188 /**< Outdoor Location and Navigation Pod */ - }; - - GapAdvertisingData(void) : _payload(), _payloadLen(0), _appearance(GENERIC_TAG) { - /* empty */ - } - - /** - * Adds advertising data based on the specified AD type (see DataType) - * - * @param advDataType The Advertising 'DataType' to add - * @param payload Pointer to the payload contents - * @param len Size of the payload in bytes - * - * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the - * advertising buffer to overflow, else BLE_ERROR_NONE. - */ - ble_error_t addData(DataType advDataType, const uint8_t *payload, uint8_t len) - { - /* ToDo: Check if an AD type already exists and if the existing */ - /* value is exclusive or not (flags, etc.) */ - - /* Make sure we don't exceed the 31 byte payload limit */ - if (_payloadLen + len + 2 > GAP_ADVERTISING_DATA_MAX_PAYLOAD) { - return BLE_ERROR_BUFFER_OVERFLOW; - } - - /* Field length */ - memset(&_payload[_payloadLen], len + 1, 1); - _payloadLen++; - - /* Field ID */ - memset(&_payload[_payloadLen], (uint8_t)advDataType, 1); - _payloadLen++; - - /* Payload */ - memcpy(&_payload[_payloadLen], payload, len); - _payloadLen += len; - - return BLE_ERROR_NONE; - } - - /** - * Helper function to add APPEARANCE data to the advertising payload - * - * @param appearance - * The APPEARANCE value to add - * - * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the - * advertising buffer to overflow, else BLE_ERROR_NONE. - */ - ble_error_t addAppearance(Appearance appearance = GENERIC_TAG) { - _appearance = appearance; - return addData(GapAdvertisingData::APPEARANCE, (uint8_t *)&appearance, 2); - } - - /** - * Helper function to add FLAGS data to the advertising payload. - * @param flags - * LE_LIMITED_DISCOVERABLE - * The peripheral is discoverable for a limited period of time. - * LE_GENERAL_DISCOVERABLE - * The peripheral is permanently discoverable. - * BREDR_NOT_SUPPORTED - * This peripheral is a Bluetooth Low Energy only device (no EDR support). - * - * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the - * advertising buffer to overflow, else BLE_ERROR_NONE. - */ - ble_error_t addFlags(uint8_t flags = LE_GENERAL_DISCOVERABLE) { - return addData(GapAdvertisingData::FLAGS, &flags, 1); - } - - /** - * Helper function to add TX_POWER_LEVEL data to the advertising payload - * - * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the - * advertising buffer to overflow, else BLE_ERROR_NONE. - */ - ble_error_t addTxPower(int8_t txPower) { - /* ToDo: Basic error checking to make sure txPower is in range */ - return addData(GapAdvertisingData::TX_POWER_LEVEL, (uint8_t *)&txPower, 1); - } - - /** - * Clears the payload and resets the payload length counter - */ - void clear(void) { - memset(&_payload, 0, GAP_ADVERTISING_DATA_MAX_PAYLOAD); - _payloadLen = 0; - } - - /** - * Returns a pointer to the the current payload - */ - const uint8_t *getPayload(void) const { - return (_payloadLen > 0) ? _payload : NULL; - } - - /** - * Returns the current payload length (0..31 bytes) - */ - uint8_t getPayloadLen(void) const { - return _payloadLen; - } - - /** - * Returns the 16-bit appearance value for this device - */ - uint16_t getAppearance(void) const { - return (uint16_t)_appearance; - } - -private: - uint8_t _payload[GAP_ADVERTISING_DATA_MAX_PAYLOAD]; - uint8_t _payloadLen; - uint16_t _appearance; -}; - -#endif // ifndef __GAP_ADVERTISING_DATA_H__ \ No newline at end of file
--- a/public/GapAdvertisingParams.h Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,111 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - -#ifndef __GAP_ADVERTISING_PARAMS_H__ -#define __GAP_ADVERTISING_PARAMS_H__ - -/**************************************************************************/ -/*! - \brief - This class provides a wrapper for the core advertising parameters, - including the advertising type (Connectable Undirected, - Non Connectable Undirected, etc.), as well as the advertising and - timeout intervals. - - \par - See the following for more information on advertising types: - - \li \c Bluetooth Core Specification 4.0 (Vol. 6), Part B, Section 2.3.1 - \li \c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 9.3 -*/ -/**************************************************************************/ -class GapAdvertisingParams { -public: - static const unsigned GAP_ADV_PARAMS_INTERVAL_MIN = 0x0020; - static const unsigned GAP_ADV_PARAMS_INTERVAL_MIN_NONCON = 0x00A0; - static const unsigned GAP_ADV_PARAMS_INTERVAL_MAX = 0x4000; - static const unsigned GAP_ADV_PARAMS_TIMEOUT_MAX = 0x3FFF; - - /**************************************************************************/ - /*! - \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 */ - }; - -public: - GapAdvertisingParams(AdvertisingType advType = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED, - uint16_t interval = GAP_ADV_PARAMS_INTERVAL_MIN_NONCON, - uint16_t timeout = 0) : _advType(advType), _interval(interval), _timeout(timeout) { - /* Interval checks */ - if (_advType == ADV_CONNECTABLE_DIRECTED) { - /* Interval must be 0 in directed connectable mode */ - _interval = 0; - } else if (_advType == ADV_NON_CONNECTABLE_UNDIRECTED) { - /* Min interval is slightly larger than in other modes */ - if (_interval < GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) { - _interval = GAP_ADV_PARAMS_INTERVAL_MIN_NONCON; - } - if (_interval > GAP_ADV_PARAMS_INTERVAL_MAX) { - _interval = GAP_ADV_PARAMS_INTERVAL_MAX; - } - } else { - /* Stay within interval limits */ - if (_interval < GAP_ADV_PARAMS_INTERVAL_MIN) { - _interval = GAP_ADV_PARAMS_INTERVAL_MIN; - } - if (_interval > GAP_ADV_PARAMS_INTERVAL_MAX) { - _interval = GAP_ADV_PARAMS_INTERVAL_MAX; - } - } - - /* Timeout checks */ - if (timeout) { - /* Stay within timeout limits */ - if (_timeout > GAP_ADV_PARAMS_TIMEOUT_MAX) { - _timeout = GAP_ADV_PARAMS_TIMEOUT_MAX; - } - } - } - - AdvertisingType getAdvertisingType(void) const {return _advType; } - uint16_t getInterval(void) const {return _interval;} - uint16_t getTimeout(void) const {return _timeout; } - - void setAdvertisingType(AdvertisingType newAdvType) {_advType = newAdvType; } - void setInterval(uint16_t newInterval) {_interval = newInterval;} - void setTimeout(uint16_t newTimeout) {_timeout = newTimeout; } - -private: - AdvertisingType _advType; - uint16_t _interval; - uint16_t _timeout; -}; - -#endif // ifndef __GAP_ADVERTISING_PARAMS_H__ \ No newline at end of file
--- a/public/GapEvents.h Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __GAP_EVENTS_H__ -#define __GAP_EVENTS_H__ - -#include "blecommon.h" - -/**************************************************************************/ -/*! - \brief - The base class used to abstract away the callback events that can be - triggered with the GAP. -*/ -/**************************************************************************/ -class GapEvents -{ -public: - /******************************************************************/ - /*! - \brief - Identifies GAP events generated by the radio HW when an event - callback occurs - */ - /******************************************************************/ - typedef enum gapEvent_e { - GAP_EVENT_TIMEOUT = 1, /**< Advertising timed out before a connection was established */ - GAP_EVENT_CONNECTED = 2, /**< A connection was established with a central device */ - GAP_EVENT_DISCONNECTED = 3 /**< A connection was closed or lost with a central device */ - } gapEvent_t; -}; - -#endif // ifndef __GAP_EVENTS_H__ \ No newline at end of file
--- a/public/GapScanningParams.h Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,103 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - -#ifndef __GAP_SCANNING_PARAMS_H__ -#define __GAP_SCANNING_PARAMS_H__ - -#include "Gap.h" - -class GapScanningParams { -public: - static const unsigned SCAN_INTERVAL_MIN = 0x0004; /**< Minimum Scan interval in 625 us units, i.e. 2.5 ms. */ - static const unsigned SCAN_INTERVAL_MAX = 0x4000; /**< Maximum Scan interval in 625 us units, i.e. 10.24 s. */ - static const unsigned SCAN_WINDOW_MIN = 0x0004; /**< Minimum Scan window in 625 us units, i.e. 2.5 ms. */ - static const unsigned SCAN_WINDOW_MAX = 0x4000; /**< Maximum Scan window in 625 us units, i.e. 10.24 s. */ - static const unsigned SCAN_TIMEOUT_MIN = 0x0001; /**< Minimum Scan timeout in seconds. */ - static const unsigned SCAN_TIMEOUT_MAX = 0xFFFF; /**< Maximum Scan timeout in seconds. */ - -public: - GapScanningParams(uint16_t interval = SCAN_INTERVAL_MAX, - uint16_t window = SCAN_WINDOW_MAX, - uint16_t timeout = 0, - bool activeScanning = false) : _interval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(interval)), - _window(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(window)), - _timeout(timeout), - _activeScanning(activeScanning) { - /* stay within limits */ - if (_interval < SCAN_INTERVAL_MIN) { - _interval = SCAN_INTERVAL_MIN; - } - if (_interval > SCAN_INTERVAL_MAX) { - _interval = SCAN_INTERVAL_MAX; - } - if (_window < SCAN_WINDOW_MIN) { - _window = SCAN_WINDOW_MIN; - } - if (_window > SCAN_WINDOW_MAX) { - _window = SCAN_WINDOW_MAX; - } - } - - ble_error_t setInterval(uint16_t newIntervalInMS) { - uint16_t newInterval = Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(newIntervalInMS); - if ((newInterval >= SCAN_INTERVAL_MIN) && (newInterval < SCAN_INTERVAL_MAX)) { - _interval = newInterval; - return BLE_ERROR_NONE; - } - - return BLE_ERROR_PARAM_OUT_OF_RANGE; - } - - ble_error_t setWindow(uint16_t newWindowInMS) { - uint16_t newWindow = Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(newWindowInMS); - if ((newWindow >= SCAN_WINDOW_MIN) && (newWindow < SCAN_WINDOW_MAX)) { - _window = newWindow; - return BLE_ERROR_NONE; - } - - return BLE_ERROR_PARAM_OUT_OF_RANGE; - } - - ble_error_t setTimeout(uint16_t newTimeout) { - _timeout = newTimeout; - return BLE_ERROR_NONE; - } - - void setActiveScanning(bool activeScanning) { - _activeScanning = activeScanning; - } - - - /* @Note: The following return durations in units of 0.625 ms */ - uint16_t getInterval(void) const {return _interval;} - uint16_t getWindow(void) const {return _window; } - - uint16_t getTimeout(void) const {return _timeout; } - bool getActiveScanning(void) const {return _activeScanning;} - -private: - uint16_t _interval; /**< Scan interval in units of 625us (between 2.5ms to 10.24s). */ - uint16_t _window; /**< Scan window in units of 625us (between 2.5ms to 10.24s). */ - uint16_t _timeout; /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */ - bool _activeScanning; /**< obtain not only the advertising data from the peer device, but also their scanResponse if possible. */ - -private: - /* disallow copy constructor */ - GapScanningParams(const GapScanningParams &); - GapScanningParams& operator =(const GapScanningParams &in); -}; - -#endif // ifndef __GAP_SCANNING_PARAMS_H__ \ No newline at end of file
--- a/public/GattAttribute.h Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __GATT_ATTRIBUTE_H__ -#define __GATT_ATTRIBUTE_H__ - -class GattAttribute { -public: - typedef uint16_t Handle_t; - static const Handle_t INVALID_HANDLE = 0x0000; - -public: - /** - * @brief Creates a new GattAttribute using the specified - * UUID, value length, and inital value - * - * @param[in] uuid - * The UUID to use for this attribute - * @param[in] valuePtr - * The memory holding the initial value. - * @param[in] initialLen - * The min length in bytes of this attribute's value - * @param[in] maxLen - * The max length in bytes of this attribute's value - * - * @section EXAMPLE - * - * @code - * - * // UUID = 0x2A19, Min length 2, Max len = 2 - * GattAttribute attr = GattAttribute(0x2A19, &someValue, 2, 2); - * - * @endcode - */ - GattAttribute(const UUID &uuid, uint8_t *valuePtr = NULL, uint16_t initialLen = 0, uint16_t maxLen = 0) : - _uuid(uuid), _valuePtr(valuePtr), _initialLen(initialLen), _lenMax(maxLen), _len(initialLen), _handle() { - /* empty */ - } - -public: - Handle_t getHandle(void) const {return _handle; } - const UUID &getUUID(void) const {return _uuid; } - uint16_t getLength(void) const {return _len; } - uint16_t getInitialLength(void) const {return _initialLen;} - uint16_t getMaxLength(void) const {return _lenMax; } - uint16_t *getLengthPtr(void) {return &_len; } - void setHandle(Handle_t id) {_handle = id; } - uint8_t *getValuePtr(void) {return _valuePtr; } - -private: - UUID _uuid; /* Characteristic UUID */ - uint8_t *_valuePtr; - uint16_t _initialLen; /* Initial length of the value */ - uint16_t _lenMax; /* Maximum length of the value */ - uint16_t _len; /* Current length of the value */ - Handle_t _handle; - -private: - /* disallow copy and assignment */ - GattAttribute(const GattAttribute &); - GattAttribute& operator=(const GattAttribute &); -}; - -#endif // ifndef __GATT_ATTRIBUTE_H__ \ No newline at end of file
--- a/public/GattCharacteristic.h Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,514 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __GATT_CHARACTERISTIC_H__ -#define __GATT_CHARACTERISTIC_H__ - -#include "Gap.h" -#include "GattAttribute.h" -#include "GattCharacteristicCallbackParams.h" -#include "FunctionPointerWithContext.h" - -class GattCharacteristic { -public: - enum { - UUID_BATTERY_LEVEL_STATE_CHAR = 0x2A1B, - UUID_BATTERY_POWER_STATE_CHAR = 0x2A1A, - UUID_REMOVABLE_CHAR = 0x2A3A, - UUID_SERVICE_REQUIRED_CHAR = 0x2A3B, - UUID_ALERT_CATEGORY_ID_CHAR = 0x2A43, - UUID_ALERT_CATEGORY_ID_BIT_MASK_CHAR = 0x2A42, - UUID_ALERT_LEVEL_CHAR = 0x2A06, - UUID_ALERT_NOTIFICATION_CONTROL_POINT_CHAR = 0x2A44, - UUID_ALERT_STATUS_CHAR = 0x2A3F, - UUID_BATTERY_LEVEL_CHAR = 0x2A19, - UUID_BLOOD_PRESSURE_FEATURE_CHAR = 0x2A49, - UUID_BLOOD_PRESSURE_MEASUREMENT_CHAR = 0x2A35, - UUID_BODY_SENSOR_LOCATION_CHAR = 0x2A38, - UUID_BOOT_KEYBOARD_INPUT_REPORT_CHAR = 0x2A22, - UUID_BOOT_KEYBOARD_OUTPUT_REPORT_CHAR = 0x2A32, - UUID_BOOT_MOUSE_INPUT_REPORT_CHAR = 0x2A33, - UUID_CURRENT_TIME_CHAR = 0x2A2B, - UUID_DATE_TIME_CHAR = 0x2A08, - UUID_DAY_DATE_TIME_CHAR = 0x2A0A, - UUID_DAY_OF_WEEK_CHAR = 0x2A09, - UUID_DST_OFFSET_CHAR = 0x2A0D, - UUID_EXACT_TIME_256_CHAR = 0x2A0C, - UUID_FIRMWARE_REVISION_STRING_CHAR = 0x2A26, - UUID_GLUCOSE_FEATURE_CHAR = 0x2A51, - UUID_GLUCOSE_MEASUREMENT_CHAR = 0x2A18, - UUID_GLUCOSE_MEASUREMENT_CONTEXT_CHAR = 0x2A34, - UUID_HARDWARE_REVISION_STRING_CHAR = 0x2A27, - UUID_HEART_RATE_CONTROL_POINT_CHAR = 0x2A39, - UUID_HEART_RATE_MEASUREMENT_CHAR = 0x2A37, - UUID_HID_CONTROL_POINT_CHAR = 0x2A4C, - UUID_HID_INFORMATION_CHAR = 0x2A4A, - UUID_IEEE_REGULATORY_CERTIFICATION_DATA_LIST_CHAR = 0x2A2A, - UUID_INTERMEDIATE_CUFF_PRESSURE_CHAR = 0x2A36, - UUID_INTERMEDIATE_TEMPERATURE_CHAR = 0x2A1E, - UUID_LOCAL_TIME_INFORMATION_CHAR = 0x2A0F, - UUID_MANUFACTURER_NAME_STRING_CHAR = 0x2A29, - UUID_MEASUREMENT_INTERVAL_CHAR = 0x2A21, - UUID_MODEL_NUMBER_STRING_CHAR = 0x2A24, - UUID_UNREAD_ALERT_CHAR = 0x2A45, - UUID_NEW_ALERT_CHAR = 0x2A46, - UUID_PNP_ID_CHAR = 0x2A50, - UUID_PROTOCOL_MODE_CHAR = 0x2A4E, - UUID_RECORD_ACCESS_CONTROL_POINT_CHAR = 0x2A52, - UUID_REFERENCE_TIME_INFORMATION_CHAR = 0x2A14, - UUID_REPORT_CHAR = 0x2A4D, - UUID_REPORT_MAP_CHAR = 0x2A4B, - UUID_RINGER_CONTROL_POINT_CHAR = 0x2A40, - UUID_RINGER_SETTING_CHAR = 0x2A41, - UUID_SCAN_INTERVAL_WINDOW_CHAR = 0x2A4F, - UUID_SCAN_REFRESH_CHAR = 0x2A31, - UUID_SERIAL_NUMBER_STRING_CHAR = 0x2A25, - UUID_SOFTWARE_REVISION_STRING_CHAR = 0x2A28, - UUID_SUPPORTED_NEW_ALERT_CATEGORY_CHAR = 0x2A47, - UUID_SUPPORTED_UNREAD_ALERT_CATEGORY_CHAR = 0x2A48, - UUID_SYSTEM_ID_CHAR = 0x2A23, - UUID_TEMPERATURE_MEASUREMENT_CHAR = 0x2A1C, - UUID_TEMPERATURE_TYPE_CHAR = 0x2A1D, - UUID_TIME_ACCURACY_CHAR = 0x2A12, - UUID_TIME_SOURCE_CHAR = 0x2A13, - UUID_TIME_UPDATE_CONTROL_POINT_CHAR = 0x2A16, - UUID_TIME_UPDATE_STATE_CHAR = 0x2A17, - UUID_TIME_WITH_DST_CHAR = 0x2A11, - UUID_TIME_ZONE_CHAR = 0x2A0E, - UUID_TX_POWER_LEVEL_CHAR = 0x2A07, - UUID_CSC_FEATURE_CHAR = 0x2A5C, - UUID_CSC_MEASUREMENT_CHAR = 0x2A5B, - UUID_RSC_FEATURE_CHAR = 0x2A54, - UUID_RSC_MEASUREMENT_CHAR = 0x2A53, - }; - - /**************************************************************************/ - /*! - \brief Standard GATT characteristic presentation format unit types. - These unit types are used to describe what the raw numeric - data in a characteristic actually represents. - - \note See https://developer.bluetooth.org/gatt/units/Pages/default.aspx - */ - /**************************************************************************/ - enum { - BLE_GATT_UNIT_NONE = 0x2700, /**< No specified unit type */ - BLE_GATT_UNIT_LENGTH_METRE = 0x2701, /**< Length, Metre */ - BLE_GATT_UNIT_MASS_KILOGRAM = 0x2702, /**< Mass, Kilogram */ - BLE_GATT_UNIT_TIME_SECOND = 0x2703, /**< Time, Second */ - BLE_GATT_UNIT_ELECTRIC_CURRENT_AMPERE = 0x2704, /**< Electric Current, Ampere */ - BLE_GATT_UNIT_THERMODYNAMIC_TEMPERATURE_KELVIN = 0x2705, /**< Thermodynamic Temperature, Kelvin */ - BLE_GATT_UNIT_AMOUNT_OF_SUBSTANCE_MOLE = 0x2706, /**< Amount of Substance, Mole */ - BLE_GATT_UNIT_LUMINOUS_INTENSITY_CANDELA = 0x2707, /**< Luminous Intensity, Candela */ - BLE_GATT_UNIT_AREA_SQUARE_METRES = 0x2710, /**< Area, Square Metres */ - BLE_GATT_UNIT_VOLUME_CUBIC_METRES = 0x2711, /**< Volume, Cubic Metres*/ - BLE_GATT_UNIT_VELOCITY_METRES_PER_SECOND = 0x2712, /**< Velocity, Metres per Second*/ - BLE_GATT_UNIT_ACCELERATION_METRES_PER_SECOND_SQUARED = 0x2713, /**< Acceleration, Metres per Second Squared */ - BLE_GATT_UNIT_WAVENUMBER_RECIPROCAL_METRE = 0x2714, /**< Wave Number Reciprocal, Metre */ - BLE_GATT_UNIT_DENSITY_KILOGRAM_PER_CUBIC_METRE = 0x2715, /**< Density, Kilogram per Cubic Metre */ - BLE_GATT_UNIT_SURFACE_DENSITY_KILOGRAM_PER_SQUARE_METRE = 0x2716, /**< */ - BLE_GATT_UNIT_SPECIFIC_VOLUME_CUBIC_METRE_PER_KILOGRAM = 0x2717, /**< */ - BLE_GATT_UNIT_CURRENT_DENSITY_AMPERE_PER_SQUARE_METRE = 0x2718, /**< */ - BLE_GATT_UNIT_MAGNETIC_FIELD_STRENGTH_AMPERE_PER_METRE = 0x2719, /**< Magnetic Field Strength, Ampere per Metre */ - BLE_GATT_UNIT_AMOUNT_CONCENTRATION_MOLE_PER_CUBIC_METRE = 0x271A, /**< */ - BLE_GATT_UNIT_MASS_CONCENTRATION_KILOGRAM_PER_CUBIC_METRE = 0x271B, /**< */ - BLE_GATT_UNIT_LUMINANCE_CANDELA_PER_SQUARE_METRE = 0x271C, /**< */ - BLE_GATT_UNIT_REFRACTIVE_INDEX = 0x271D, /**< */ - BLE_GATT_UNIT_RELATIVE_PERMEABILITY = 0x271E, /**< */ - BLE_GATT_UNIT_PLANE_ANGLE_RADIAN = 0x2720, /**< */ - BLE_GATT_UNIT_SOLID_ANGLE_STERADIAN = 0x2721, /**< */ - BLE_GATT_UNIT_FREQUENCY_HERTZ = 0x2722, /**< Frequency, Hertz */ - BLE_GATT_UNIT_FORCE_NEWTON = 0x2723, /**< Force, Newton */ - BLE_GATT_UNIT_PRESSURE_PASCAL = 0x2724, /**< Pressure, Pascal */ - BLE_GATT_UNIT_ENERGY_JOULE = 0x2725, /**< Energy, Joule */ - BLE_GATT_UNIT_POWER_WATT = 0x2726, /**< Power, Watt */ - BLE_GATT_UNIT_ELECTRIC_CHARGE_COULOMB = 0x2727, /**< Electrical Charge, Coulomb */ - BLE_GATT_UNIT_ELECTRIC_POTENTIAL_DIFFERENCE_VOLT = 0x2728, /**< Electrical Potential Difference, Voltage */ - BLE_GATT_UNIT_CAPACITANCE_FARAD = 0x2729, /**< */ - BLE_GATT_UNIT_ELECTRIC_RESISTANCE_OHM = 0x272A, /**< */ - BLE_GATT_UNIT_ELECTRIC_CONDUCTANCE_SIEMENS = 0x272B, /**< */ - BLE_GATT_UNIT_MAGNETIC_FLEX_WEBER = 0x272C, /**< */ - BLE_GATT_UNIT_MAGNETIC_FLEX_DENSITY_TESLA = 0x272D, /**< */ - BLE_GATT_UNIT_INDUCTANCE_HENRY = 0x272E, /**< */ - BLE_GATT_UNIT_THERMODYNAMIC_TEMPERATURE_DEGREE_CELSIUS = 0x272F, /**< */ - BLE_GATT_UNIT_LUMINOUS_FLUX_LUMEN = 0x2730, /**< */ - BLE_GATT_UNIT_ILLUMINANCE_LUX = 0x2731, /**< */ - BLE_GATT_UNIT_ACTIVITY_REFERRED_TO_A_RADIONUCLIDE_BECQUEREL = 0x2732, /**< */ - BLE_GATT_UNIT_ABSORBED_DOSE_GRAY = 0x2733, /**< */ - BLE_GATT_UNIT_DOSE_EQUIVALENT_SIEVERT = 0x2734, /**< */ - BLE_GATT_UNIT_CATALYTIC_ACTIVITY_KATAL = 0x2735, /**< */ - BLE_GATT_UNIT_DYNAMIC_VISCOSITY_PASCAL_SECOND = 0x2740, /**< */ - BLE_GATT_UNIT_MOMENT_OF_FORCE_NEWTON_METRE = 0x2741, /**< */ - BLE_GATT_UNIT_SURFACE_TENSION_NEWTON_PER_METRE = 0x2742, /**< */ - BLE_GATT_UNIT_ANGULAR_VELOCITY_RADIAN_PER_SECOND = 0x2743, /**< */ - BLE_GATT_UNIT_ANGULAR_ACCELERATION_RADIAN_PER_SECOND_SQUARED = 0x2744, /**< */ - BLE_GATT_UNIT_HEAT_FLUX_DENSITY_WATT_PER_SQUARE_METRE = 0x2745, /**< */ - BLE_GATT_UNIT_HEAT_CAPACITY_JOULE_PER_KELVIN = 0x2746, /**< */ - BLE_GATT_UNIT_SPECIFIC_HEAT_CAPACITY_JOULE_PER_KILOGRAM_KELVIN = 0x2747, /**< */ - BLE_GATT_UNIT_SPECIFIC_ENERGY_JOULE_PER_KILOGRAM = 0x2748, /**< */ - BLE_GATT_UNIT_THERMAL_CONDUCTIVITY_WATT_PER_METRE_KELVIN = 0x2749, /**< */ - BLE_GATT_UNIT_ENERGY_DENSITY_JOULE_PER_CUBIC_METRE = 0x274A, /**< */ - BLE_GATT_UNIT_ELECTRIC_FIELD_STRENGTH_VOLT_PER_METRE = 0x274B, /**< */ - BLE_GATT_UNIT_ELECTRIC_CHARGE_DENSITY_COULOMB_PER_CUBIC_METRE = 0x274C, /**< */ - BLE_GATT_UNIT_SURFACE_CHARGE_DENSITY_COULOMB_PER_SQUARE_METRE = 0x274D, /**< */ - BLE_GATT_UNIT_ELECTRIC_FLUX_DENSITY_COULOMB_PER_SQUARE_METRE = 0x274E, /**< */ - BLE_GATT_UNIT_PERMITTIVITY_FARAD_PER_METRE = 0x274F, /**< */ - BLE_GATT_UNIT_PERMEABILITY_HENRY_PER_METRE = 0x2750, /**< */ - BLE_GATT_UNIT_MOLAR_ENERGY_JOULE_PER_MOLE = 0x2751, /**< */ - BLE_GATT_UNIT_MOLAR_ENTROPY_JOULE_PER_MOLE_KELVIN = 0x2752, /**< */ - BLE_GATT_UNIT_EXPOSURE_COULOMB_PER_KILOGRAM = 0x2753, /**< */ - BLE_GATT_UNIT_ABSORBED_DOSE_RATE_GRAY_PER_SECOND = 0x2754, /**< */ - BLE_GATT_UNIT_RADIANT_INTENSITY_WATT_PER_STERADIAN = 0x2755, /**< */ - BLE_GATT_UNIT_RADIANCE_WATT_PER_SQUARE_METRE_STERADIAN = 0x2756, /**< */ - BLE_GATT_UNIT_CATALYTIC_ACTIVITY_CONCENTRATION_KATAL_PER_CUBIC_METRE = 0x2757, /**< */ - BLE_GATT_UNIT_TIME_MINUTE = 0x2760, /**< Time, Minute */ - BLE_GATT_UNIT_TIME_HOUR = 0x2761, /**< Time, Hour */ - BLE_GATT_UNIT_TIME_DAY = 0x2762, /**< Time, Day */ - BLE_GATT_UNIT_PLANE_ANGLE_DEGREE = 0x2763, /**< */ - BLE_GATT_UNIT_PLANE_ANGLE_MINUTE = 0x2764, /**< */ - BLE_GATT_UNIT_PLANE_ANGLE_SECOND = 0x2765, /**< */ - BLE_GATT_UNIT_AREA_HECTARE = 0x2766, /**< */ - BLE_GATT_UNIT_VOLUME_LITRE = 0x2767, /**< */ - BLE_GATT_UNIT_MASS_TONNE = 0x2768, /**< */ - BLE_GATT_UNIT_PRESSURE_BAR = 0x2780, /**< Pressure, Bar */ - BLE_GATT_UNIT_PRESSURE_MILLIMETRE_OF_MERCURY = 0x2781, /**< Pressure, Millimetre of Mercury */ - BLE_GATT_UNIT_LENGTH_ANGSTROM = 0x2782, /**< */ - BLE_GATT_UNIT_LENGTH_NAUTICAL_MILE = 0x2783, /**< */ - BLE_GATT_UNIT_AREA_BARN = 0x2784, /**< */ - BLE_GATT_UNIT_VELOCITY_KNOT = 0x2785, /**< */ - BLE_GATT_UNIT_LOGARITHMIC_RADIO_QUANTITY_NEPER = 0x2786, /**< */ - BLE_GATT_UNIT_LOGARITHMIC_RADIO_QUANTITY_BEL = 0x2787, /**< */ - BLE_GATT_UNIT_LENGTH_YARD = 0x27A0, /**< Length, Yard */ - BLE_GATT_UNIT_LENGTH_PARSEC = 0x27A1, /**< Length, Parsec */ - BLE_GATT_UNIT_LENGTH_INCH = 0x27A2, /**< Length, Inch */ - BLE_GATT_UNIT_LENGTH_FOOT = 0x27A3, /**< Length, Foot */ - BLE_GATT_UNIT_LENGTH_MILE = 0x27A4, /**< Length, Mile */ - BLE_GATT_UNIT_PRESSURE_POUND_FORCE_PER_SQUARE_INCH = 0x27A5, /**< */ - BLE_GATT_UNIT_VELOCITY_KILOMETRE_PER_HOUR = 0x27A6, /**< Velocity, Kilometre per Hour */ - BLE_GATT_UNIT_VELOCITY_MILE_PER_HOUR = 0x27A7, /**< Velocity, Mile per Hour */ - BLE_GATT_UNIT_ANGULAR_VELOCITY_REVOLUTION_PER_MINUTE = 0x27A8, /**< Angular Velocity, Revolution per Minute */ - BLE_GATT_UNIT_ENERGY_GRAM_CALORIE = 0x27A9, /**< Energy, Gram Calorie */ - BLE_GATT_UNIT_ENERGY_KILOGRAM_CALORIE = 0x27AA, /**< Energy, Kilogram Calorie */ - BLE_GATT_UNIT_ENERGY_KILOWATT_HOUR = 0x27AB, /**< Energy, Killowatt Hour */ - BLE_GATT_UNIT_THERMODYNAMIC_TEMPERATURE_DEGREE_FAHRENHEIT = 0x27AC, /**< */ - BLE_GATT_UNIT_PERCENTAGE = 0x27AD, /**< Percentage */ - BLE_GATT_UNIT_PER_MILLE = 0x27AE, /**< */ - BLE_GATT_UNIT_PERIOD_BEATS_PER_MINUTE = 0x27AF, /**< */ - BLE_GATT_UNIT_ELECTRIC_CHARGE_AMPERE_HOURS = 0x27B0, /**< */ - BLE_GATT_UNIT_MASS_DENSITY_MILLIGRAM_PER_DECILITRE = 0x27B1, /**< */ - BLE_GATT_UNIT_MASS_DENSITY_MILLIMOLE_PER_LITRE = 0x27B2, /**< */ - BLE_GATT_UNIT_TIME_YEAR = 0x27B3, /**< Time, Year */ - BLE_GATT_UNIT_TIME_MONTH = 0x27B4, /**< Time, Month */ - BLE_GATT_UNIT_CONCENTRATION_COUNT_PER_CUBIC_METRE = 0x27B5, /**< */ - BLE_GATT_UNIT_IRRADIANCE_WATT_PER_SQUARE_METRE = 0x27B6 /**< */ - }; - - /**************************************************************************/ - /*! - \brief Standard GATT number types - - \note See Bluetooth Specification 4.0 (Vol. 3), Part G, Section 3.3.3.5.2 - \note See http://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml - */ - /**************************************************************************/ - enum { - BLE_GATT_FORMAT_RFU = 0x00, /**< Reserved For Future Use. */ - BLE_GATT_FORMAT_BOOLEAN = 0x01, /**< Boolean. */ - BLE_GATT_FORMAT_2BIT = 0x02, /**< Unsigned 2-bit integer. */ - BLE_GATT_FORMAT_NIBBLE = 0x03, /**< Unsigned 4-bit integer. */ - BLE_GATT_FORMAT_UINT8 = 0x04, /**< Unsigned 8-bit integer. */ - BLE_GATT_FORMAT_UINT12 = 0x05, /**< Unsigned 12-bit integer. */ - BLE_GATT_FORMAT_UINT16 = 0x06, /**< Unsigned 16-bit integer. */ - BLE_GATT_FORMAT_UINT24 = 0x07, /**< Unsigned 24-bit integer. */ - BLE_GATT_FORMAT_UINT32 = 0x08, /**< Unsigned 32-bit integer. */ - BLE_GATT_FORMAT_UINT48 = 0x09, /**< Unsigned 48-bit integer. */ - BLE_GATT_FORMAT_UINT64 = 0x0A, /**< Unsigned 64-bit integer. */ - BLE_GATT_FORMAT_UINT128 = 0x0B, /**< Unsigned 128-bit integer. */ - BLE_GATT_FORMAT_SINT8 = 0x0C, /**< Signed 2-bit integer. */ - BLE_GATT_FORMAT_SINT12 = 0x0D, /**< Signed 12-bit integer. */ - BLE_GATT_FORMAT_SINT16 = 0x0E, /**< Signed 16-bit integer. */ - BLE_GATT_FORMAT_SINT24 = 0x0F, /**< Signed 24-bit integer. */ - BLE_GATT_FORMAT_SINT32 = 0x10, /**< Signed 32-bit integer. */ - BLE_GATT_FORMAT_SINT48 = 0x11, /**< Signed 48-bit integer. */ - BLE_GATT_FORMAT_SINT64 = 0x12, /**< Signed 64-bit integer. */ - BLE_GATT_FORMAT_SINT128 = 0x13, /**< Signed 128-bit integer. */ - BLE_GATT_FORMAT_FLOAT32 = 0x14, /**< IEEE-754 32-bit floating point. */ - BLE_GATT_FORMAT_FLOAT64 = 0x15, /**< IEEE-754 64-bit floating point. */ - BLE_GATT_FORMAT_SFLOAT = 0x16, /**< IEEE-11073 16-bit SFLOAT. */ - BLE_GATT_FORMAT_FLOAT = 0x17, /**< IEEE-11073 32-bit FLOAT. */ - BLE_GATT_FORMAT_DUINT16 = 0x18, /**< IEEE-20601 format. */ - BLE_GATT_FORMAT_UTF8S = 0x19, /**< UTF-8 string. */ - BLE_GATT_FORMAT_UTF16S = 0x1A, /**< UTF-16 string. */ - BLE_GATT_FORMAT_STRUCT = 0x1B /**< Opaque Structure. */ - }; - - /**************************************************************************/ - /*! - \brief Standard GATT characteristic properties - - \note See Bluetooth Specification 4.0 (Vol. 3), Part G, Section 3.3.1.1 - and Section 3.3.3.1 for Extended Properties - */ - /**************************************************************************/ - typedef enum ble_gatt_char_properties_e { - BLE_GATT_CHAR_PROPERTIES_NONE = 0x00, - BLE_GATT_CHAR_PROPERTIES_BROADCAST = 0x01, /**< Permits broadcasts of the Characteristic Value using Server Characteristic Configuration Descriptor. */ - BLE_GATT_CHAR_PROPERTIES_READ = 0x02, /**< Permits reads of the Characteristic Value. */ - BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE = 0x04, /**< Permits writes of the Characteristic Value without response. */ - BLE_GATT_CHAR_PROPERTIES_WRITE = 0x08, /**< Permits writes of the Characteristic Value with response. */ - BLE_GATT_CHAR_PROPERTIES_NOTIFY = 0x10, /**< Permits notifications of a Characteristic Value without acknowledgment. */ - BLE_GATT_CHAR_PROPERTIES_INDICATE = 0x20, /**< Permits indications of a Characteristic Value with acknowledgment. */ - BLE_GATT_CHAR_PROPERTIES_AUTHENTICATED_SIGNED_WRITES = 0x40, /**< Permits signed writes to the Characteristic Value. */ - BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES = 0x80 /**< Additional characteristic properties are defined in the Characteristic Extended Properties Descriptor */ - } ble_gatt_char_properties_t; - - /**************************************************************************/ - /*! - \brief GATT presentation format wrapper - - \note See Bluetooth Specification 4.0 (Vol. 3), Part G, Section 3.3.3.5 - \note See https://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml - */ - /**************************************************************************/ - typedef struct PresentationFormat { - uint8_t gatt_format; /**< Format of the value, see @ref ble_gatt_format_t. */ - int8_t exponent; /**< Exponent for integer data types. Ex. if Exponent = -3 and the char value is 3892, the actual value is 3.892 */ - uint16_t gatt_unit; /**< UUID from Bluetooth Assigned Numbers, see @ref ble_gatt_unit_t. */ - uint8_t gatt_namespace; /**< Namespace from Bluetooth Assigned Numbers, normally '1', see @ref BLE_GATT_CPF_NAMESPACES. */ - uint16_t gatt_nsdesc; /**< Namespace description from Bluetooth Assigned Numbers, normally '0', see @ref BLE_GATT_CPF_NAMESPACES. */ - } presentation_format_t; - - /** - * @brief Creates a new GattCharacteristic using the specified 16-bit - * UUID, value length, and properties - * - * @note The UUID value must be unique in the service and is normally >1 - * - * @param[in] uuid - * The UUID to use for this characteristic - * @param[in] valuePtr - * The memory holding the initial value. The value is copied - * into the stack when the enclosing service is added; and - * thereafter maintained internally by the stack. - * @param[in] initialLen - * The min length in bytes of this characteristic's value - * @param[in] maxLen - * The max length in bytes of this characteristic's value - * @param[in] props - * The 8-bit bit field containing the characteristic's properties - * @param[in] descriptors - * A pointer to an array of descriptors to be included within - * this characteristic. The memory for the descriptor array is - * owned by the caller, and should remain valid at least until - * the enclosing service is added to the GATT table. - * @param[in] numDescriptors - * The number of descriptors in the previous array. - * - * @NOTE: If valuePtr == NULL, initialLength == 0, and properties == READ - * for the value attribute of a characteristic, then that particular - * characteristic may be considered optional and dropped while - * instantiating the service with the underlying BLE stack. - */ - GattCharacteristic(const UUID &uuid, - uint8_t *valuePtr = NULL, - uint16_t initialLen = 0, - uint16_t maxLen = 0, - uint8_t props = BLE_GATT_CHAR_PROPERTIES_NONE, - GattAttribute *descriptors[] = NULL, - unsigned numDescriptors = 0) : - _valueAttribute(uuid, valuePtr, initialLen, maxLen), - _properties(props), - _requiredSecurity(Gap::SECURITY_MODE_ENCRYPTION_OPEN_LINK), - _descriptors(descriptors), - _descriptorCount(numDescriptors), - enabledReadAuthorization(false), - enabledWriteAuthorization(false), - readAuthorizationCallback(), - writeAuthorizationCallback() { - /* empty */ - } - -public: - /** - * Setup the minimum security (mode and level) requirements for access to the characteristic's value attribute. - * - * @param securityMode Can be one of encryption or signing, with or without protection for MITM (man in the middle attacks). - */ - void requireSecurity(Gap::SecurityMode_t securityMode) { - _requiredSecurity = securityMode; - } - -public: - /** - * Authorization. - */ - void setWriteAuthorizationCallback(void (*callback)(GattCharacteristicWriteAuthCBParams *)) { - writeAuthorizationCallback.attach(callback); - enabledWriteAuthorization = true; - } - template <typename T> - void setWriteAuthorizationCallback(T *object, void (T::*member)(GattCharacteristicWriteAuthCBParams *)) { - writeAuthorizationCallback.attach(object, member); - enabledWriteAuthorization = true; - } - void setReadAuthorizationCallback(void (*callback)(GattCharacteristicReadAuthCBParams *)) { - readAuthorizationCallback.attach(callback); - enabledReadAuthorization = true; - } - template <typename T> - void setReadAuthorizationCallback(T *object, void (T::*member)(GattCharacteristicReadAuthCBParams *)) { - readAuthorizationCallback.attach(object, member); - enabledReadAuthorization = true; - } - - /** - * Helper function meant to be called from the guts of the BLE stack to - * determine the authorization reply for a write request. - * @param params to capture the context of the write-auth request; and also contains an out-parameter for reply. - * @return true if the write is authorized to proceed. - */ - GattCharacteristicAuthCBReply_t authorizeWrite(GattCharacteristicWriteAuthCBParams *params) { - if (!isWriteAuthorizationEnabled()) { - return AUTH_CALLBACK_REPLY_SUCCESS; - } - - params->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; /* initialized to no-error by default */ - writeAuthorizationCallback.call(params); - return params->authorizationReply; - } - - /** - * Helper function meant to be called from the guts of the BLE stack to - * determine the authorization reply for a read request. - * @param params to capture the context of the read-auth request. - * - * @NOTE: To authorize/deny the read the params->authorizationReply field - * should be set to true/false. - * - * If the read is approved and params->data is unchanged (NULL), - * the current characteristic value will be used. - * - * If the read is approved, a new value can be provided by setting - * the params->data pointer and params->len fields. - * - * @return true if the read is authorized to proceed. - */ - GattCharacteristicAuthCBReply_t authorizeRead(GattCharacteristicReadAuthCBParams *params) { - if (!isReadAuthorizationEnabled()) { - return AUTH_CALLBACK_REPLY_SUCCESS; - } - - params->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; /* initialized to no-error by default */ - readAuthorizationCallback.call(params); - return params->authorizationReply; - } - - /* accessors */ -public: - GattAttribute& getValueAttribute() {return _valueAttribute; } - const GattAttribute& getValueAttribute() const {return _valueAttribute; } - GattAttribute::Handle_t getValueHandle(void) const {return getValueAttribute().getHandle();} - uint8_t getProperties(void) const {return _properties; } - Gap::SecurityMode_t getRequiredSecurity() const {return _requiredSecurity; } - uint8_t getDescriptorCount(void) const {return _descriptorCount; } - bool isReadAuthorizationEnabled() const {return enabledReadAuthorization; } - bool isWriteAuthorizationEnabled() const {return enabledWriteAuthorization; } - - GattAttribute *getDescriptor(uint8_t index) { - if (index >= _descriptorCount) { - return NULL; - } - - return _descriptors[index]; - } - -private: - GattAttribute _valueAttribute; - uint8_t _properties; - Gap::SecurityMode_t _requiredSecurity; - GattAttribute **_descriptors; - uint8_t _descriptorCount; - - bool enabledReadAuthorization; - bool enabledWriteAuthorization; - FunctionPointerWithContext<GattCharacteristicReadAuthCBParams *> readAuthorizationCallback; - FunctionPointerWithContext<GattCharacteristicWriteAuthCBParams *> writeAuthorizationCallback; - -private: - /* disallow copy and assignment */ - GattCharacteristic(const GattCharacteristic &); - GattCharacteristic& operator=(const GattCharacteristic &); -}; - -template <typename T> -class ReadOnlyGattCharacteristic : public GattCharacteristic { -public: - ReadOnlyGattCharacteristic<T>(const UUID &uuid, T *valuePtr, uint8_t additionalProperties = BLE_GATT_CHAR_PROPERTIES_NONE) : - GattCharacteristic(uuid, reinterpret_cast<uint8_t *>(valuePtr), sizeof(T), sizeof(T), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | additionalProperties) { - /* empty */ - } -}; - -template <typename T> -class WriteOnlyGattCharacteristic : public GattCharacteristic { -public: - WriteOnlyGattCharacteristic<T>(const UUID &uuid, T *valuePtr, uint8_t additionalProperties = BLE_GATT_CHAR_PROPERTIES_NONE) : - GattCharacteristic(uuid, reinterpret_cast<uint8_t *>(valuePtr), sizeof(T), sizeof(T), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | additionalProperties) { - /* empty */ - } -}; - -template <typename T> -class ReadWriteGattCharacteristic : public GattCharacteristic { -public: - ReadWriteGattCharacteristic<T>(const UUID &uuid, T *valuePtr, uint8_t additionalProperties = BLE_GATT_CHAR_PROPERTIES_NONE) : - GattCharacteristic(uuid, reinterpret_cast<uint8_t *>(valuePtr), sizeof(T), sizeof(T), - GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | additionalProperties) { - /* empty */ - } -}; - -template <typename T, unsigned NUM_ELEMENTS> -class WriteOnlyArrayGattCharacteristic : public GattCharacteristic { -public: - WriteOnlyArrayGattCharacteristic<T, NUM_ELEMENTS>(const UUID &uuid, T valuePtr[NUM_ELEMENTS], uint8_t additionalProperties = BLE_GATT_CHAR_PROPERTIES_NONE) : - GattCharacteristic(uuid, reinterpret_cast<uint8_t *>(valuePtr), sizeof(T) * NUM_ELEMENTS, sizeof(T) * NUM_ELEMENTS, - GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | additionalProperties) { - /* empty */ - } -}; - -template <typename T, unsigned NUM_ELEMENTS> -class ReadOnlyArrayGattCharacteristic : public GattCharacteristic { -public: - ReadOnlyArrayGattCharacteristic<T, NUM_ELEMENTS>(const UUID &uuid, T valuePtr[NUM_ELEMENTS], uint8_t additionalProperties = BLE_GATT_CHAR_PROPERTIES_NONE) : - GattCharacteristic(uuid, reinterpret_cast<uint8_t *>(valuePtr), sizeof(T) * NUM_ELEMENTS, sizeof(T) * NUM_ELEMENTS, - GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | additionalProperties) { - /* empty */ - } -}; - -template <typename T, unsigned NUM_ELEMENTS> -class ReadWriteArrayGattCharacteristic : public GattCharacteristic { -public: - ReadWriteArrayGattCharacteristic<T, NUM_ELEMENTS>(const UUID &uuid, T valuePtr[NUM_ELEMENTS], uint8_t additionalProperties = BLE_GATT_CHAR_PROPERTIES_NONE) : - GattCharacteristic(uuid, reinterpret_cast<uint8_t *>(valuePtr), sizeof(T) * NUM_ELEMENTS, sizeof(T) * NUM_ELEMENTS, - GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | additionalProperties) { - /* empty */ - } -}; - -#endif // ifndef __GATT_CHARACTERISTIC_H__ \ No newline at end of file
--- a/public/GattCharacteristicCallbackParams.h Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __GATT_CHARACTERISTIC_CALLBACK_PARAMS_H__ -#define __GATT_CHARACTERISTIC_CALLBACK_PARAMS_H__ - -struct GattCharacteristicWriteCBParams { - GattAttribute::Handle_t charHandle; - enum Type { - GATTS_CHAR_OP_INVALID = 0x00, /**< Invalid Operation. */ - GATTS_CHAR_OP_WRITE_REQ = 0x01, /**< Write Request. */ - GATTS_CHAR_OP_WRITE_CMD = 0x02, /**< Write Command. */ - GATTS_CHAR_OP_SIGN_WRITE_CMD = 0x03, /**< Signed Write Command. */ - GATTS_CHAR_OP_PREP_WRITE_REQ = 0x04, /**< Prepare Write Request. */ - GATTS_CHAR_OP_EXEC_WRITE_REQ_CANCEL = 0x05, /**< Execute Write Request: Cancel all prepared writes. */ - GATTS_CHAR_OP_EXEC_WRITE_REQ_NOW = 0x06, /**< Execute Write Request: Immediately execute all prepared writes. */ - } op; /**< Type of write operation, */ - uint16_t offset; /**< Offset for the write operation. */ - uint16_t len; /**< Length of the incoming data. */ - const uint8_t *data; /**< Incoming data, variable length. */ -}; - -struct GattCharacteristicReadCBParams { - GattAttribute::Handle_t charHandle; - enum Type { - GATTS_CHAR_OP_INVALID = 0x00, /**< Invalid Operation. */ - GATTS_CHAR_OP_READ_REQ = 0x0A, /**< Read Request. */ - } op; /**< Type of write operation, */ - uint16_t offset; /**< Offset for the read operation. */ - uint16_t *len; /**< Length of the outgoing data. */ - uint8_t *data; /**< Outgoing data, variable length. */ -}; - -enum GattCharacteristicAuthCBReply_t { - AUTH_CALLBACK_REPLY_SUCCESS = 0x00, /**< Success. */ - AUTH_CALLBACK_REPLY_ATTERR_INVALID_HANDLE = 0x0101, /**< ATT Error: Invalid Attribute Handle. */ - AUTH_CALLBACK_REPLY_ATTERR_READ_NOT_PERMITTED = 0x0102, /**< ATT Error: Read not permitted. */ - AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED = 0x0103, /**< ATT Error: Write not permitted. */ - AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHENTICATION = 0x0105, /**< ATT Error: Authenticated link required. */ - AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET = 0x0107, /**< ATT Error: Offset specified was past the end of the attribute. */ - AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION = 0x0108, /**< ATT Error: Used in ATT as Insufficient Authorisation. */ - AUTH_CALLBACK_REPLY_ATTERR_PREPARE_QUEUE_FULL = 0x0109, /**< ATT Error: Used in ATT as Prepare Queue Full. */ - AUTH_CALLBACK_REPLY_ATTERR_ATTRIBUTE_NOT_FOUND = 0x010A, /**< ATT Error: Used in ATT as Attribute not found. */ - AUTH_CALLBACK_REPLY_ATTERR_ATTRIBUTE_NOT_LONG = 0x010B, /**< ATT Error: Attribute cannot be read or written using read/write blob requests. */ - AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH = 0x010D, /**< ATT Error: Invalid value size. */ - AUTH_CALLBACK_REPLY_ATTERR_INSUF_RESOURCES = 0x0111, /**< ATT Error: Encrypted link required. */ -}; - -struct GattCharacteristicWriteAuthCBParams { - GattAttribute::Handle_t charHandle; - uint16_t offset; /**< Offset for the write operation. */ - uint16_t len; /**< Length of the incoming data. */ - const uint8_t *data; /**< Incoming data, variable length. */ - GattCharacteristicAuthCBReply_t authorizationReply; /* This is the out parameter which needs to be set to true by the callback if the - * request is to proceed; false otherwise. */ -}; - -struct GattCharacteristicReadAuthCBParams { - GattAttribute::Handle_t charHandle; - uint16_t offset; /**< Offset for the read operation. */ - uint16_t len; /**< Optional: new length of the outgoing data. */ - uint8_t *data; /**< Optional: new outgoing data. Leave at NULL if data is unchanged. */ - GattCharacteristicAuthCBReply_t authorizationReply; /* This is the out parameter which needs to be set to true by the callback if the - * request is to proceed; false otherwise. */ -}; - -#endif /*__GATT_CHARACTERISTIC_CALLBACK_PARAMS_H__*/ \ No newline at end of file
--- a/public/GattServer.h Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,159 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __GATT_SERVER_H__ -#define __GATT_SERVER_H__ - -#include "Gap.h" -#include "GattService.h" -#include "GattAttribute.h" -#include "GattServerEvents.h" -#include "GattCharacteristicCallbackParams.h" -#include "CallChainOfFunctionPointersWithContext.h" - -class GattServer { -public: - /* Event callback handlers. */ - typedef void (*EventCallback_t)(GattAttribute::Handle_t attributeHandle); - typedef void (*ServerEventCallback_t)(void); /**< independent of any particular attribute */ - -protected: - GattServer() : - serviceCount(0), - characteristicCount(0), - onDataSent(), - onDataWritten(), - onDataRead(), - onUpdatesEnabled(NULL), - onUpdatesDisabled(NULL), - onConfirmationReceived(NULL) { - /* empty */ - } - - friend class BLEDevice; -private: - /* These functions must be defined in the sub-class */ - virtual ble_error_t addService(GattService &) = 0; - virtual ble_error_t readValue(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) = 0; - virtual ble_error_t readValue(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) = 0; - virtual ble_error_t updateValue(GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false) = 0; - virtual ble_error_t updateValue(Gap::Handle_t connectionHandle, GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false) = 0; - virtual ble_error_t initializeGATTDatabase(void) = 0; - - // 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! - - void setOnDataSent(void (*callback)(unsigned count)) {onDataSent.add(callback);} - template <typename T> - void setOnDataSent(T *objPtr, void (T::*memberPtr)(unsigned count)) { - onDataSent.add(objPtr, memberPtr); - } - 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); - } - - /** - * A virtual function to allow underlying stacks to indicate if they support - * onDataRead(). It should be overridden to return true as applicable. - */ - virtual bool isOnDataReadAvailable() const { - return false; - } - ble_error_t setOnDataRead(void (*callback)(const GattCharacteristicReadCBParams *eventDataP)) { - if (!isOnDataReadAvailable()) { - return BLE_ERROR_NOT_IMPLEMENTED; - } - - onDataRead.add(callback); - return BLE_ERROR_NONE; - } - template <typename T> - ble_error_t setOnDataRead(T *objPtr, void (T::*memberPtr)(const GattCharacteristicReadCBParams *context)) { - if (!isOnDataReadAvailable()) { - return BLE_ERROR_NOT_IMPLEMENTED; - } - - onDataRead.add(objPtr, memberPtr); - return BLE_ERROR_NONE; - } - void setOnUpdatesEnabled(EventCallback_t callback) {onUpdatesEnabled = callback;} - void setOnUpdatesDisabled(EventCallback_t callback) {onUpdatesDisabled = callback;} - void setOnConfirmationReceived(EventCallback_t callback) {onConfirmationReceived = callback;} - -protected: - void handleDataWrittenEvent(const GattCharacteristicWriteCBParams *params) { - if (onDataWritten.hasCallbacksAttached()) { - onDataWritten.call(params); - } - } - - void handleDataReadEvent(const GattCharacteristicReadCBParams *params) { - if (onDataRead.hasCallbacksAttached()) { - onDataRead.call(params); - } - } - - void handleEvent(GattServerEvents::gattEvent_e type, GattAttribute::Handle_t charHandle) { - switch (type) { - case GattServerEvents::GATT_EVENT_UPDATES_ENABLED: - if (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; - default: - break; - } - } - - void handleDataSentEvent(unsigned count) { - if (onDataSent.hasCallbacksAttached()) { - onDataSent.call(count); - } - } - -protected: - uint8_t serviceCount; - uint8_t characteristicCount; - -private: - CallChainOfFunctionPointersWithContext<unsigned> onDataSent; - CallChainOfFunctionPointersWithContext<const GattCharacteristicWriteCBParams *> onDataWritten; - CallChainOfFunctionPointersWithContext<const GattCharacteristicReadCBParams *> onDataRead; - EventCallback_t onUpdatesEnabled; - EventCallback_t onUpdatesDisabled; - EventCallback_t onConfirmationReceived; - -private: - /* disallow copy and assignment */ - GattServer(const GattServer &); - GattServer& operator=(const GattServer &); -}; - -#endif // ifndef __GATT_SERVER_H__ \ No newline at end of file
--- a/public/GattServerEvents.h Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __GATT_SERVER_EVENTS_H__ -#define __GATT_SERVER_EVENTS_H__ - -/*! - \brief - The base class used to abstract away the callback events that can be - triggered with the GATT Server. -*/ -class GattServerEvents -{ -public: - typedef enum gattEvent_e { - GATT_EVENT_DATA_SENT = 1, /**< Fired when a msg was successfully sent out (notify only?) */ - GATT_EVENT_DATA_WRITTEN = 2, /**< Client wrote data to Server (separate into char and descriptor writes?) */ - GATT_EVENT_UPDATES_ENABLED = 3, /**< Notify/Indicate Enabled in CCCD */ - GATT_EVENT_UPDATES_DISABLED = 4, /**< Notify/Indicate Disabled in CCCD */ - GATT_EVENT_CONFIRMATION_RECEIVED = 5, /**< Response received from Indicate message */ - GATT_EVENT_READ_AUTHORIZATION_REQ = 6, /**< Request application to authorize read */ - GATT_EVENT_WRITE_AUTHORIZATION_REQ = 7, /**< Request application to authorize write */ - } gattEvent_t; -}; - -#endif // ifndef __GATT_SERVER_EVENTS_H__ \ No newline at end of file
--- a/public/GattService.h Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - -#ifndef __GATT_SERVICE_H__ -#define __GATT_SERVICE_H__ - -#include "UUID.h" -#include "GattCharacteristic.h" - -class GattService { -public: - enum { - UUID_ALERT_NOTIFICATION_SERVICE = 0x1811, - UUID_BATTERY_SERVICE = 0x180F, - UUID_BLOOD_PRESSURE_SERVICE = 0x1810, - UUID_CURRENT_TIME_SERVICE = 0x1805, - UUID_CYCLING_SPEED_AND_CADENCE = 0x1816, - UUID_DEVICE_INFORMATION_SERVICE = 0x180A, - UUID_GLUCOSE_SERVICE = 0x1808, - UUID_HEALTH_THERMOMETER_SERVICE = 0x1809, - UUID_HEART_RATE_SERVICE = 0x180D, - UUID_HUMAN_INTERFACE_DEVICE_SERVICE = 0x1812, - UUID_IMMEDIATE_ALERT_SERVICE = 0x1802, - UUID_LINK_LOSS_SERVICE = 0x1803, - UUID_NEXT_DST_CHANGE_SERVICE = 0x1807, - UUID_PHONE_ALERT_STATUS_SERVICE = 0x180E, - UUID_REFERENCE_TIME_UPDATE_SERVICE = 0x1806, - UUID_RUNNING_SPEED_AND_CADENCE = 0x1814, - UUID_SCAN_PARAMETERS_SERVICE = 0x1813, - UUID_TX_POWER_SERVICE = 0x1804 - }; - -public: - /** - * @brief Creates a new GattCharacteristic using the specified 16-bit - * UUID, value length, and properties - * - * @note The UUID value must be unique in the service and is normally >1 - * - * @param[in] uuid - * The UUID to use for this characteristic - * @param[in] characteristics - * A pointer to an array of characteristics to be included within this service - * @param[in] numCharacteristics - * The number of characteristics - */ - GattService(const UUID &uuid, GattCharacteristic *characteristics[], unsigned numCharacteristics) : - _primaryServiceID(uuid), _characteristicCount(numCharacteristics), _characteristics(characteristics), _handle(0) { - /* empty */ - } - - const UUID &getUUID(void) const {return _primaryServiceID; } - uint16_t getHandle(void) const {return _handle; } - uint8_t getCharacteristicCount(void) const {return _characteristicCount;} - void setHandle(uint16_t handle) {_handle = handle;} - - GattCharacteristic *getCharacteristic(uint8_t index) { - if (index >= _characteristicCount) { - return NULL; - } - - return _characteristics[index]; - } - -private: - UUID _primaryServiceID; - uint8_t _characteristicCount; - GattCharacteristic **_characteristics; - uint16_t _handle; -}; - -#endif // ifndef __GATT_SERVICE_H__ \ No newline at end of file
--- a/public/UUID.h Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,141 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __UUID_H__ -#define __UUID_H__ - -#include <string.h> - -#include "blecommon.h" - -class UUID { -public: - enum UUID_Type_t { - UUID_TYPE_SHORT = 0, // Short BLE UUID - UUID_TYPE_LONG = 1 // Full 128-bit UUID - }; - - static const unsigned LENGTH_OF_LONG_UUID = 16; - typedef uint16_t ShortUUIDBytes_t; - typedef uint8_t LongUUIDBytes_t[LENGTH_OF_LONG_UUID]; - -public: - /** - * Creates a new 128-bit UUID - * - * @note The UUID is a unique 128-bit (16 byte) ID used to identify - * different service or characteristics on the BLE device. - * - * @param longUUID - * The 128-bit (16-byte) UUID value, MSB first (big-endian). - */ - UUID(const LongUUIDBytes_t longUUID) : type(UUID_TYPE_LONG), baseUUID(), shortUUID(0) { - setupLong(longUUID); - } - - /** - * Creates a new 16-bit UUID - * - * @note The UUID is a unique 16-bit (2 byte) ID used to identify - * different service or characteristics on the BLE device. - * - * For efficiency, and because 16 bytes would take a large chunk of the - * 27-byte data payload length of the Link Layer, the BLE specification adds - * two additional UUID formats: 16-bit and 32-bit UUIDs. These shortened - * formats can be used only with UUIDs that are defined in the Bluetooth - * specification (i.e., that are listed by the Bluetooth SIG as standard - * Bluetooth UUIDs). - * - * To reconstruct the full 128-bit UUID from the shortened version, insert - * the 16-bit short value (indicated by xxxx, including leading zeros) into - * the Bluetooth Base UUID: - * - * 0000xxxx-0000-1000-8000-00805F9B34FB - * - * @note Shortening is not available for UUIDs that are not derived from the - * Bluetooth Base UUID. Such non-standard UUIDs are commonly called - * vendor-specific UUIDs. In these cases, you’ll need to use the full - * 128-bit UUID value at all times. - * - * @note we don't yet support 32-bit shortened UUIDs. - */ - UUID(ShortUUIDBytes_t shortUUID) : type(UUID_TYPE_SHORT), baseUUID(), shortUUID(shortUUID) { - /* empty */ - } - - UUID(const UUID &source) { - type = source.type; - shortUUID = source.shortUUID; - memcpy(baseUUID, source.baseUUID, LENGTH_OF_LONG_UUID); - } - - UUID(void) : type(UUID_TYPE_SHORT), shortUUID(BLE_UUID_UNKNOWN) { - /* empty */ - } - - /** - * Fill in a 128-bit UUID; this is useful when UUID isn't known at the time of object construction. - */ - void setupLong(const LongUUIDBytes_t longUUID) { - type = UUID_TYPE_LONG; - memcpy(baseUUID, longUUID, LENGTH_OF_LONG_UUID); - shortUUID = (uint16_t)((longUUID[2] << 8) | (longUUID[3])); - } - -public: - UUID_Type_t shortOrLong(void) const {return type; } - const uint8_t *getBaseUUID(void) const { - if (type == UUID_TYPE_SHORT) { - return (const uint8_t*)&shortUUID; - } else { - return baseUUID; - } - } - - ShortUUIDBytes_t getShortUUID(void) const {return shortUUID;} - uint8_t getLen(void) const { - return ((type == UUID_TYPE_SHORT) ? sizeof(ShortUUIDBytes_t) : LENGTH_OF_LONG_UUID); - } - - bool operator== (const UUID &other) const { - if ((this->type == UUID_TYPE_SHORT) && (other.type == UUID_TYPE_SHORT) && - (this->shortUUID == other.shortUUID)) { - return true; - } - - if ((this->type == UUID_TYPE_LONG) && (other.type == UUID_TYPE_LONG) && - (memcmp(this->baseUUID, other.baseUUID, LENGTH_OF_LONG_UUID) == 0)) { - return true; - } - - return false; - } - - bool operator!= (const UUID &other) const { - return !(*this == other); - } - -private: - UUID_Type_t type; // UUID_TYPE_SHORT or UUID_TYPE_LONG - LongUUIDBytes_t baseUUID; /* the base of the long UUID (if - * used). Note: bytes 12 and 13 (counting from LSB) - * are zeroed out to allow comparison with other long - * UUIDs which differ only in the 16-bit relative - * part.*/ - ShortUUIDBytes_t shortUUID; // 16 bit uuid (byte 2-3 using with base) -}; - -#endif // ifndef __UUID_H__ \ No newline at end of file
--- a/public/readme.txt Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -The public API exposed through header files. \ No newline at end of file
--- a/services/BatteryService.h Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __BLE_BATTERY_SERVICE_H__ -#define __BLE_BATTERY_SERVICE_H__ - -#include "BLEDevice.h" - -/** -* @class BatteryService -* @brief BLE Battery Service. This service displays the battery level from 0%->100% represented as a 8bit number.<br> -* Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.battery_service.xml <br> -* Battery Level Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.battery_level.xml -*/ -class BatteryService { -public: - /** - * @param[ref] _ble - * BLEDevice object for the underlying controller. - * @param[in] level - * 8bit batterly level. Usually used to represent percentage of batterly charge remaining. - */ - BatteryService(BLEDevice &_ble, uint8_t level = 100) : - ble(_ble), - batteryLevel(level), - batteryLevelCharacteristic(GattCharacteristic::UUID_BATTERY_LEVEL_CHAR, &batteryLevel, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) { - - static bool serviceAdded = false; /* We should only ever need to add the heart rate service once. */ - if (serviceAdded) { - return; - } - - GattCharacteristic *charTable[] = {&batteryLevelCharacteristic}; - GattService batteryService(GattService::UUID_BATTERY_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); - - ble.addService(batteryService); - serviceAdded = true; - } - - /** - * @brief Update the battery level with a new value. Valid values range from - * 0..100. Anything outside this range will be ignored. - * - * @param newLevel - * update to battery level. - */ - void updateBatteryLevel(uint8_t newLevel) { - batteryLevel = newLevel; - ble.updateCharacteristicValue(batteryLevelCharacteristic.getValueAttribute().getHandle(), &batteryLevel, 1); - } - -private: - BLEDevice &ble; - - uint8_t batteryLevel; - ReadOnlyGattCharacteristic<uint8_t> batteryLevelCharacteristic; -}; - -#endif /* #ifndef __BLE_BATTERY_SERVICE_H__*/ \ No newline at end of file
--- a/services/DFUService.cpp Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "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; \ No newline at end of file
--- a/services/DFUService.h Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,132 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __BLE_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 -* @brief Device Firmware Update Service. -*/ -class DFUService { -public: - /** - * @brief 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: - /** - * @brief Adds Device Firmware Update service to an existing ble object. - * - * @param[ref] _ble - * BLEDevice object for the underlying controller. - * @param[in] _handoverCallback - * Application specific handover callback. - */ - DFUService(BLEDevice &_ble, ResetPrepare_t _handoverCallback = NULL) : - ble(_ble), - controlBytes(), - packetBytes(), - controlPoint(DFUServiceControlCharacteristicUUID, controlBytes, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), - packet(DFUServicePacketCharacteristicUUID, packetBytes, SIZEOF_PACKET_BYTES, SIZEOF_PACKET_BYTES, - GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE) { - 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); - } - - /** - * @brief get the handle for the value attribute of the control characteristic. - */ - uint16_t getControlHandle(void) const { - return controlPoint.getValueHandle(); - } - - /** - * @brief 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. - * - * @param[in] params - * Information about the characterisitc being updated. - */ - virtual void onDataWritten(const GattCharacteristicWriteCBParams *params) { - if (params->charHandle == controlPoint.getValueHandle()) { - /* At present, writing anything will do the trick--this needs to be improved. */ - if (handoverCallback) { - handoverCallback(); - } - - 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. */ - WriteOnlyArrayGattCharacteristic<uint8_t, SIZEOF_CONTROL_BYTES> 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__*/ \ No newline at end of file
--- a/services/DeviceInformationService.h Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __BLE_DEVICE_INFORMATION_SERVICE_H__ -#define __BLE_DEVICE_INFORMATION_SERVICE_H__ - -#include "BLEDevice.h" - -/** -* @class DeviceInformationService -* @brief BLE Device Information Service <br> -* Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.device_information.xml <br> -* Manufacturer Name String Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.manufacturer_name_string.xml -*/ -class DeviceInformationService { -public: - /** - * @brief Device Information Service Constructor. - * - * @param[ref] _ble - * BLEDevice object for the underlying controller. - * @param[in] manufacturersName - * This characteristic represents the name of the - * manufacturer of the device. The name is copied into the - * 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__*/ \ No newline at end of file
--- a/services/HealthThermometerService.h Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,150 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __BLE_HEALTH_THERMOMETER_SERVICE_H__ -#define __BLE_HEALTH_THERMOMETER_SERVICE_H__ - -#include "BLEDevice.h" - -/** -* @class HealthThermometerService -* @brief BLE Health Thermometer Service. This service provides the location of the thermometer and the temperature. <br> -* Service: https://developer.bluetooth.org/gatt/profiles/Pages/ProfileViewer.aspx?u=org.bluetooth.profile.health_thermometer.xml <br> -* Temperature Measurement: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_measurement.xml <br> -* Temperature Type: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_type.xml -*/ -class HealthThermometerService { -public: - /** - * @enum Sensor Location - * @brief Location of sensor on the body - */ - enum SensorLocation_t { - LOCATION_ARMPIT = 1, /*!< armpit */ - LOCATION_BODY, /*!< body */ - LOCATION_EAR, /*!< ear */ - LOCATION_FINGER, /*!< finger */ - LOCATION_GI_TRACT, /*!< GI tract */ - LOCATION_MOUTH, /*!< mouth */ - LOCATION_RECTUM, /*!< rectum */ - LOCATION_TOE, /*!< toe */ - LOCATION_EAR_DRUM, /*!< ear drum */ - }; - -public: - /** - * @brief Add the Health Thermometer Service to an existing ble object, initialize with temperature and location. - * @param[ref] _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, (TemperatureValueBytes *)valueBytes.getPointer(), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), - tempLocation(GattCharacteristic::UUID_TEMPERATURE_TYPE_CHAR, &_location) { - - GattCharacteristic *hrmChars[] = {&tempMeasurement, &tempLocation, }; - GattService hrmService(GattService::UUID_HEALTH_THERMOMETER_SERVICE, hrmChars, sizeof(hrmChars) / sizeof(GattCharacteristic *)); - - ble.addService(hrmService); - } - - /** - * @brief Update the temperature being broadcast - * - * @param[in] temperature - * Floating point value of the temperature - * - */ - void updateTemperature(float temperature) { - if (ble.getGapState().connected) { - valueBytes.updateTemperature(temperature); - ble.updateCharacteristicValue(tempMeasurement.getValueAttribute().getHandle(), valueBytes.getPointer(), sizeof(TemperatureValueBytes)); - } - } - - /** - * @brief Update the location. - * @param loc - * new location value. - */ - void updateLocation(SensorLocation_t loc) { - ble.updateCharacteristicValue(tempLocation.getValueHandle(), reinterpret_cast<uint8_t *>(&loc), sizeof(uint8_t)); - } - -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; - ReadOnlyGattCharacteristic<TemperatureValueBytes> tempMeasurement; - ReadOnlyGattCharacteristic<uint8_t> tempLocation; -}; - -#endif /* #ifndef __BLE_HEALTH_THERMOMETER_SERVICE_H__*/ \ No newline at end of file
--- a/services/HeartRateService.h Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,201 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __BLE_HEART_RATE_SERVICE_H__ -#define __BLE_HEART_RATE_SERVICE_H__ - -#include "BLEDevice.h" - -/** -* @class HeartRateService -* @brief BLE Service for HeartRate. This BLE Service contains the location of the sensor, the heartrate in beats per minute. <br> -* Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.heart_rate.xml <br> -* HRM Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml <br> -* Location: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.body_sensor_location.xml -*/ -class HeartRateService { -public: - /** - * @enum SensorLocation - * @brief Location of HeartRate sensor on body. - */ - enum { - LOCATION_OTHER = 0, /*!< Other Location */ - LOCATION_CHEST, /*!< Chest */ - LOCATION_WRIST, /*!< Wrist */ - LOCATION_FINGER, /*!< Finger */ - LOCATION_HAND, /*!< Hand */ - LOCATION_EAR_LOBE, /*!< Earlobe */ - LOCATION_FOOT, /*!< Foot */ - }; - -public: - /** - * @brief Constructor with 8bit HRM Counter value. - * - * @param[ref] _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_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), - hrmLocation(GattCharacteristic::UUID_BODY_SENSOR_LOCATION_CHAR, &location), - controlPoint(GattCharacteristic::UUID_HEART_RATE_CONTROL_POINT_CHAR, &controlPointValue) { - setupService(); - } - - /** - * @brief Constructor with a 16-bit HRM Counter value. - * - * @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, 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, &location), - controlPoint(GattCharacteristic::UUID_HEART_RATE_CONTROL_POINT_CHAR, &controlPointValue) { - setupService(); - } - - /** - * @brief Set a new 8-bit value for heart rate. - * - * @param[in] hrmCounter - * HeartRate in bpm. - */ - 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. - * - * @param[in] hrmCounter - * HeartRate in bpm. - */ - void updateHeartRate(uint16_t hrmCounter) { - valueBytes.updateHeartRate(hrmCounter); - ble.updateCharacteristicValue(hrmRate.getValueAttribute().getHandle(), valueBytes.getPointer(), valueBytes.getNumValueBytes()); - } - - /** - * This callback allows the HeartRateService to receive updates to the - * controlPoint Characteristic. - * - * @param[in] params - * Information about the characterisitc being updated. - */ - 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; - ReadOnlyGattCharacteristic<uint8_t> hrmLocation; - WriteOnlyGattCharacteristic<uint8_t> controlPoint; -}; - -#endif /* #ifndef __BLE_HEART_RATE_SERVICE_H__*/ \ No newline at end of file
--- a/services/LinkLossService.h Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,103 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __BLE_LINK_LOSS_SERVICE_H__ -#define __BLE_LINK_LOSS_SERVICE_H__ - -#include "Gap.h" - -/** -* @class LinkLossService -* @brief This service defines behavior when a link is lost between two devices. <br> -* Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.link_loss.xml <br> -* Alertness Level Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.alert_level.xml <br> -*/ -class LinkLossService { -public: - enum AlertLevel_t { - NO_ALERT = 0, - MILD_ALERT = 1, - HIGH_ALERT = 2 - }; - - typedef void (* callback_t)(AlertLevel_t level); - - /** - * @param[ref] ble - * BLEDevice object for the underlying controller. - */ - LinkLossService(BLEDevice &bleIn, callback_t callbackIn, AlertLevel_t levelIn = NO_ALERT) : - ble(bleIn), - alertLevel(levelIn), - callback(callbackIn), - alertLevelChar(GattCharacteristic::UUID_ALERT_LEVEL_CHAR, reinterpret_cast<uint8_t *>(&alertLevel)) { - static bool serviceAdded = false; /* We should only ever add one LinkLoss service. */ - if (serviceAdded) { - return; - } - - GattCharacteristic *charTable[] = {&alertLevelChar}; - GattService linkLossService(GattService::UUID_LINK_LOSS_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); - - ble.addService(linkLossService); - serviceAdded = true; - - ble.addToDisconnectionCallChain(this, &LinkLossService::onDisconnectionFilter); - ble.onDataWritten(this, &LinkLossService::onDataWritten); - } - - /** - * Update the callback. - */ - void setCallback(callback_t newCallback) { - callback = newCallback; - } - - /** - * Update Alertness Level. - */ - void setAlertLevel(AlertLevel_t newLevel) { - alertLevel = newLevel; - } - -private: - /** - * This callback allows receiving updates to the AlertLevel Characteristic. - * - * @param[in] params - * Information about the characterisitc being updated. - */ - virtual void onDataWritten(const GattCharacteristicWriteCBParams *params) { - if (params->charHandle == alertLevelChar.getValueHandle()) { - alertLevel = *reinterpret_cast<const AlertLevel_t *>(params->data); - } - } - - void onDisconnectionFilter(void) { - if (alertLevel != NO_ALERT) { - callback(alertLevel); - } - } - -private: - BLEDevice &ble; - AlertLevel_t alertLevel; - callback_t callback; - - ReadWriteGattCharacteristic<uint8_t> alertLevelChar; -}; - -#endif /* __BLE_LINK_LOSS_SERVICE_H__ */ \ No newline at end of file
--- a/services/UARTService.cpp Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "UARTService.h" - -const uint8_t UARTServiceBaseUUID[UUID::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[UUID::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[UUID::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[UUID::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[UUID::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, -}; \ No newline at end of file
--- a/services/UARTService.h Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,202 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __BLE_UART_SERVICE_H__ -#define __BLE_UART_SERVICE_H__ - -#include "mbed.h" -#include "Stream.h" - -#include "UUID.h" -#include "BLEDevice.h" - -extern const uint8_t UARTServiceBaseUUID[UUID::LENGTH_OF_LONG_UUID]; -extern const uint16_t UARTServiceShortUUID; -extern const uint16_t UARTServiceTXCharacteristicShortUUID; -extern const uint16_t UARTServiceRXCharacteristicShortUUID; - -extern const uint8_t UARTServiceUUID[UUID::LENGTH_OF_LONG_UUID]; -extern const uint8_t UARTServiceUUID_reversed[UUID::LENGTH_OF_LONG_UUID]; - -extern const uint8_t UARTServiceTXCharacteristicUUID[UUID::LENGTH_OF_LONG_UUID]; -extern const uint8_t UARTServiceRXCharacteristicUUID[UUID::LENGTH_OF_LONG_UUID]; - -/** -* @class UARTService -* @brief BLE Service to enable UART over BLE -*/ -class UARTService { -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: - - /** - * @param[ref] ble - * BLEDevice object for the underlying controller. - */ - UARTService(BLEDevice &_ble) : - 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(); - } - - /** - * 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. - */ - size_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; - } - - /** - * Helper function to write out strings. - * @param str The received string. - * @return Amount of characters appended to the rxCharacteristic. - */ - size_t writeString(const char *str) { - return write(str, strlen(str)); - } - - /** - * 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. - */ - int _putc(int c) { - return (write(&c, 1) == 1) ? 1 : EOF; - } - - /** - * Override for Stream::_getc() - * @return - * The character read. - */ - int _getc() { - if (receiveBufferIndex == numBytesReceived) { - return EOF; - } - - return receiveBuffer[receiveBufferIndex++]; - } - -private: - /** - * 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. - */ - 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); - } - } - } - -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__*/ \ No newline at end of file
--- a/services/URIBeaconConfigService.cpp Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "URIBeaconConfigService.h" - -#define UUID_URI_BEACON(FIRST, SECOND) { \ - 0xee, 0x0c, FIRST, SECOND, 0x87, 0x86, 0x40, 0xba, \ - 0xab, 0x96, 0x99, 0xb9, 0x1a, 0xc9, 0x81, 0xd8, \ -} - -const uint8_t UUID_URI_BEACON_SERVICE[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x80); -const uint8_t UUID_LOCK_STATE_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x81); -const uint8_t UUID_LOCK_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x82); -const uint8_t UUID_UNLOCK_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x83); -const uint8_t UUID_URI_DATA_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x84); -const uint8_t UUID_FLAGS_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x85); -const uint8_t UUID_ADV_POWER_LEVELS_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x86); -const uint8_t UUID_TX_POWER_MODE_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x87); -const uint8_t UUID_BEACON_PERIOD_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x88); -const uint8_t UUID_RESET_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x89); - -const uint8_t BEACON_UUID[sizeof(UUID::ShortUUIDBytes_t)] = {0xD8, 0xFE}; \ No newline at end of file
--- a/services/URIBeaconConfigService.h Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,467 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef SERVICES_URIBEACONCONFIGSERVICE_H_ -#define SERVICES_URIBEACONCONFIGSERVICE_H_ - -#include "BLEDevice.h" -#include "mbed.h" - -extern const uint8_t UUID_URI_BEACON_SERVICE[UUID::LENGTH_OF_LONG_UUID]; -extern const uint8_t UUID_LOCK_STATE_CHAR[UUID::LENGTH_OF_LONG_UUID]; -extern const uint8_t UUID_LOCK_CHAR[UUID::LENGTH_OF_LONG_UUID]; -extern const uint8_t UUID_UNLOCK_CHAR[UUID::LENGTH_OF_LONG_UUID]; -extern const uint8_t UUID_URI_DATA_CHAR[UUID::LENGTH_OF_LONG_UUID]; -extern const uint8_t UUID_FLAGS_CHAR[UUID::LENGTH_OF_LONG_UUID]; -extern const uint8_t UUID_ADV_POWER_LEVELS_CHAR[UUID::LENGTH_OF_LONG_UUID]; -extern const uint8_t UUID_TX_POWER_MODE_CHAR[UUID::LENGTH_OF_LONG_UUID]; -extern const uint8_t UUID_BEACON_PERIOD_CHAR[UUID::LENGTH_OF_LONG_UUID]; -extern const uint8_t UUID_RESET_CHAR[UUID::LENGTH_OF_LONG_UUID]; - -extern const uint8_t BEACON_UUID[sizeof(UUID::ShortUUIDBytes_t)]; - -/** -* @class URIBeaconConfigService -* @brief UriBeacon Configuration Service. Can be used to set URL, adjust power levels, and set flags. -* See http://uribeacon.org -* -*/ -class URIBeaconConfigService { - public: - /** - * @brief Transmission Power Modes for UriBeacon - */ - static const uint8_t TX_POWER_MODE_LOWEST = 0; /*!< Lowest TX power mode */ - static const uint8_t TX_POWER_MODE_LOW = 1; /*!< Low TX power mode */ - static const uint8_t TX_POWER_MODE_MEDIUM = 2; /*!< Medium TX power mode */ - static const uint8_t TX_POWER_MODE_HIGH = 3; /*!< High TX power mode */ - static const unsigned NUM_POWER_MODES = 4; /*!< Number of Power Modes defined */ - - static const int ADVERTISING_INTERVAL_MSEC = 1000; // Advertising interval for config service. - static const int SERVICE_DATA_MAX = 31; // Maximum size of service data in ADV packets - - typedef uint8_t Lock_t[16]; /* 128 bits */ - typedef int8_t PowerLevels_t[NUM_POWER_MODES]; - - static const int URI_DATA_MAX = 18; - typedef uint8_t UriData_t[URI_DATA_MAX]; - - struct Params_t { - Lock_t lock; - uint8_t uriDataLength; - UriData_t uriData; - uint8_t flags; - PowerLevels_t advPowerLevels; // Current value of AdvertisedPowerLevels - uint8_t txPowerMode; // Firmware power levels used with setTxPower() - uint16_t beaconPeriod; - }; - - /** - * @param[ref] ble - * BLEDevice object for the underlying controller. - * @param[in/out] paramsIn - * Reference to application-visible beacon state, loaded - * from persistent storage at startup. - * @paramsP[in] resetToDefaultsFlag - * Applies to the state of the 'paramsIn' parameter. - * If true, it indicates that paramsIn is potentially - * un-initialized, and default values should be used - * instead. Otherwise, paramsIn overrides the defaults. - * @param[in] defaultUriDataIn - * Default un-encoded URI; applies only if the resetToDefaultsFlag is true. - * @param[in] defaultAdvPowerLevelsIn - * Default power-levels array; applies only if the resetToDefaultsFlag is true. - */ - URIBeaconConfigService(BLEDevice &bleIn, - Params_t ¶msIn, - bool resetToDefaultsFlag, - const char *defaultURIDataIn, - PowerLevels_t &defaultAdvPowerLevelsIn) : - ble(bleIn), - params(paramsIn), - defaultUriDataLength(), - defaultUriData(), - defaultAdvPowerLevels(defaultAdvPowerLevelsIn), - initSucceeded(false), - resetFlag(), - lockedStateChar(UUID_LOCK_STATE_CHAR, &lockedState), - lockChar(UUID_LOCK_CHAR, ¶ms.lock), - uriDataChar(UUID_URI_DATA_CHAR, params.uriData, 0, URI_DATA_MAX, - GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE), - unlockChar(UUID_UNLOCK_CHAR, ¶ms.lock), - flagsChar(UUID_FLAGS_CHAR, ¶ms.flags), - advPowerLevelsChar(UUID_ADV_POWER_LEVELS_CHAR, ¶ms.advPowerLevels), - txPowerModeChar(UUID_TX_POWER_MODE_CHAR, ¶ms.txPowerMode), - beaconPeriodChar(UUID_BEACON_PERIOD_CHAR, ¶ms.beaconPeriod), - resetChar(UUID_RESET_CHAR, &resetFlag) { - - encodeURI(defaultURIDataIn, defaultUriData, defaultUriDataLength); - if (defaultUriDataLength > URI_DATA_MAX) { - return; - } - - if (!resetToDefaultsFlag && (params.uriDataLength > URI_DATA_MAX)) { - resetToDefaultsFlag = true; - } - if (resetToDefaultsFlag) { - resetToDefaults(); - } else { - updateCharacteristicValues(); - } - - lockedState = isLocked(); - - lockChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::lockAuthorizationCallback); - unlockChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::unlockAuthorizationCallback); - uriDataChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::uriDataWriteAuthorizationCallback); - flagsChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::basicAuthorizationCallback<uint8_t>); - advPowerLevelsChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::basicAuthorizationCallback<PowerLevels_t>); - txPowerModeChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::powerModeAuthorizationCallback); - beaconPeriodChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::basicAuthorizationCallback<uint16_t>); - resetChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::basicAuthorizationCallback<uint8_t>); - - static GattCharacteristic *charTable[] = { - &lockedStateChar, &lockChar, &unlockChar, &uriDataChar, - &flagsChar, &advPowerLevelsChar, &txPowerModeChar, &beaconPeriodChar, &resetChar - }; - - GattService configService(UUID_URI_BEACON_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); - - ble.addService(configService); - ble.onDataWritten(this, &URIBeaconConfigService::onDataWrittenCallback); - - setupURIBeaconConfigAdvertisements(); /* Setup advertising for the configService. */ - - initSucceeded = true; - } - - bool configuredSuccessfully(void) const { - return initSucceeded; - } - - /* Start out by advertising the configService for a limited time after - * startup; and switch to the normal non-connectible beacon functionality - * afterwards. */ - void setupURIBeaconConfigAdvertisements() - { - const char DEVICE_NAME[] = "mUriBeacon Config"; - - ble.clearAdvertisingPayload(); - - ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); - - // UUID is in different order in the ADV frame (!) - uint8_t reversedServiceUUID[sizeof(UUID_URI_BEACON_SERVICE)]; - for (unsigned int i = 0; i < sizeof(UUID_URI_BEACON_SERVICE); i++) { - reversedServiceUUID[i] = UUID_URI_BEACON_SERVICE[sizeof(UUID_URI_BEACON_SERVICE) - i - 1]; - } - ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, reversedServiceUUID, sizeof(reversedServiceUUID)); - ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_TAG); - ble.accumulateScanResponse(GapAdvertisingData::COMPLETE_LOCAL_NAME, reinterpret_cast<const uint8_t *>(&DEVICE_NAME), sizeof(DEVICE_NAME)); - ble.accumulateScanResponse(GapAdvertisingData::TX_POWER_LEVEL, - reinterpret_cast<uint8_t *>(&defaultAdvPowerLevels[URIBeaconConfigService::TX_POWER_MODE_LOW]), - sizeof(uint8_t)); - - ble.setTxPower(params.advPowerLevels[params.txPowerMode]); - ble.setDeviceName(reinterpret_cast<const uint8_t *>(&DEVICE_NAME)); - ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); - ble.setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(ADVERTISING_INTERVAL_MSEC)); - } - - /* Helper function to switch to the non-connectible normal mode for URIBeacon. This gets called after a timeout. */ - void setupURIBeaconAdvertisements() - { - uint8_t serviceData[SERVICE_DATA_MAX]; - unsigned serviceDataLen = 0; - - /* Reinitialize the BLE stack. This will clear away the existing services and advertising state. */ - ble.shutdown(); - ble.init(); - - // Fields from the Service - unsigned beaconPeriod = params.beaconPeriod; - unsigned txPowerMode = params.txPowerMode; - unsigned uriDataLength = params.uriDataLength; - URIBeaconConfigService::UriData_t &uriData = params.uriData; - URIBeaconConfigService::PowerLevels_t &advPowerLevels = params.advPowerLevels; - uint8_t flags = params.flags; - - extern void saveURIBeaconConfigParams(const Params_t *paramsP); /* forward declaration; necessary to avoid a circular dependency. */ - saveURIBeaconConfigParams(¶ms); - - ble.clearAdvertisingPayload(); - ble.setTxPower(params.advPowerLevels[params.txPowerMode]); - ble.setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED); - ble.setAdvertisingInterval(beaconPeriod); - ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); - ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, BEACON_UUID, sizeof(BEACON_UUID)); - - serviceData[serviceDataLen++] = BEACON_UUID[0]; - serviceData[serviceDataLen++] = BEACON_UUID[1]; - serviceData[serviceDataLen++] = flags; - serviceData[serviceDataLen++] = advPowerLevels[txPowerMode]; - for (unsigned j = 0; j < uriDataLength; j++) { - serviceData[serviceDataLen++] = uriData[j]; - } - ble.accumulateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, serviceData, serviceDataLen); - } - - private: - // True if the lock bits are non-zero - bool isLocked() { - Lock_t testLock; - memset(testLock, 0, sizeof(Lock_t)); - return memcmp(params.lock, testLock, sizeof(Lock_t)); - } - - /* - * This callback is invoked when a GATT client attempts to modify any of the - * characteristics of this service. Attempts to do so are also applied to - * the internal state of this service object. - */ - void onDataWrittenCallback(const GattCharacteristicWriteCBParams *writeParams) { - uint16_t handle = writeParams->charHandle; - - if (handle == lockChar.getValueHandle()) { - // Validated earlier - memcpy(params.lock, writeParams->data, sizeof(Lock_t)); - // use isLocked() in case bits are being set to all 0's - lockedState = isLocked(); - } else if (handle == unlockChar.getValueHandle()) { - // Validated earlier - memset(params.lock, 0, sizeof(Lock_t)); - lockedState = false; - } else if (handle == uriDataChar.getValueHandle()) { - params.uriDataLength = writeParams->len; - memcpy(params.uriData, writeParams->data, params.uriDataLength); - } else if (handle == flagsChar.getValueHandle()) { - params.flags = *(writeParams->data); - } else if (handle == advPowerLevelsChar.getValueHandle()) { - memcpy(params.advPowerLevels, writeParams->data, sizeof(PowerLevels_t)); - } else if (handle == txPowerModeChar.getValueHandle()) { - params.txPowerMode = *(writeParams->data); - } else if (handle == beaconPeriodChar.getValueHandle()) { - params.beaconPeriod = *((uint16_t *)(writeParams->data)); - - /* Re-map beaconPeriod to within permissible bounds if necessary. */ - if (params.beaconPeriod != 0) { - bool paramsUpdated = false; - if (params.beaconPeriod < ble.getMinAdvertisingInterval()) { - params.beaconPeriod = ble.getMinAdvertisingInterval(); - paramsUpdated = true; - } else if (params.beaconPeriod > ble.getMaxAdvertisingInterval()) { - params.beaconPeriod = ble.getMaxAdvertisingInterval(); - paramsUpdated = true; - } - if (paramsUpdated) { - ble.updateCharacteristicValue(beaconPeriodChar.getValueHandle(), reinterpret_cast<uint8_t *>(¶ms.beaconPeriod), sizeof(uint16_t)); - } - } - } else if (handle == resetChar.getValueHandle()) { - resetToDefaults(); - } - } - - /* - * Reset the default values. - */ - void resetToDefaults(void) { - lockedState = false; - memset(params.lock, 0, sizeof(Lock_t)); - memcpy(params.uriData, defaultUriData, URI_DATA_MAX); - params.uriDataLength = defaultUriDataLength; - params.flags = 0; - memcpy(params.advPowerLevels, defaultAdvPowerLevels, sizeof(PowerLevels_t)); - params.txPowerMode = TX_POWER_MODE_LOW; - params.beaconPeriod = 1000; - updateCharacteristicValues(); - } - - /* - * Internal helper function used to update the GATT database following any - * change to the internal state of the service object. - */ - void updateCharacteristicValues(void) { - ble.updateCharacteristicValue(lockedStateChar.getValueHandle(), &lockedState, 1); - ble.updateCharacteristicValue(uriDataChar.getValueHandle(), params.uriData, params.uriDataLength); - ble.updateCharacteristicValue(flagsChar.getValueHandle(), ¶ms.flags, 1); - ble.updateCharacteristicValue(beaconPeriodChar.getValueHandle(), - reinterpret_cast<uint8_t *>(¶ms.beaconPeriod), sizeof(uint16_t)); - ble.updateCharacteristicValue(txPowerModeChar.getValueHandle(), ¶ms.txPowerMode, 1); - ble.updateCharacteristicValue(advPowerLevelsChar.getValueHandle(), - reinterpret_cast<uint8_t *>(params.advPowerLevels), sizeof(PowerLevels_t)); - } - - private: - void lockAuthorizationCallback(GattCharacteristicWriteAuthCBParams *authParams) { - if (lockedState) { - authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; - } else if (authParams->len != sizeof(Lock_t)) { - authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH; - } else if (authParams->offset != 0) { - authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; - } else { - authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; - } - } - - - void unlockAuthorizationCallback(GattCharacteristicWriteAuthCBParams *authParams) { - if (!lockedState) { - authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; - } else if (authParams->len != sizeof(Lock_t)) { - authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH; - } else if (authParams->offset != 0) { - authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; - } else if (memcmp(authParams->data, params.lock, sizeof(Lock_t)) != 0) { - authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; - } else { - authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; - } - } - - void uriDataWriteAuthorizationCallback(GattCharacteristicWriteAuthCBParams *authParams) { - if (lockedState) { - authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; - } else if (authParams->offset != 0) { - authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; - } else { - authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; - } - } - - void powerModeAuthorizationCallback(GattCharacteristicWriteAuthCBParams *authParams) { - if (lockedState) { - authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; - } else if (authParams->len != sizeof(uint8_t)) { - authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH; - } else if (authParams->offset != 0) { - authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; - } else if (*((uint8_t *)authParams->data) >= NUM_POWER_MODES) { - authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED; - } else { - authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; - } - } - - template <typename T> - void basicAuthorizationCallback(GattCharacteristicWriteAuthCBParams *authParams) { - if (lockedState) { - authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; - } else if (authParams->len != sizeof(T)) { - authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH; - } else if (authParams->offset != 0) { - authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; - } else { - authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; - } - } - - BLEDevice &ble; - Params_t ¶ms; - - size_t defaultUriDataLength; // Default value that is restored on reset - UriData_t defaultUriData; // Default value that is restored on reset - PowerLevels_t &defaultAdvPowerLevels; // Default value that is restored on reset - - uint8_t lockedState; - bool initSucceeded; - uint8_t resetFlag; - - ReadOnlyGattCharacteristic<uint8_t> lockedStateChar; - WriteOnlyGattCharacteristic<Lock_t> lockChar; - GattCharacteristic uriDataChar; - WriteOnlyGattCharacteristic<Lock_t> unlockChar; - ReadWriteGattCharacteristic<uint8_t> flagsChar; - ReadWriteGattCharacteristic<PowerLevels_t> advPowerLevelsChar; - ReadWriteGattCharacteristic<uint8_t> txPowerModeChar; - ReadWriteGattCharacteristic<uint16_t> beaconPeriodChar; - WriteOnlyGattCharacteristic<uint8_t> resetChar; - - public: - /* - * Encode a human-readable URI into the binary format defined by URIBeacon spec (https://github.com/google/uribeacon/tree/master/specification). - */ - static void encodeURI(const char *uriDataIn, UriData_t uriDataOut, size_t &sizeofURIDataOut) { - const char *prefixes[] = { - "http://www.", - "https://www.", - "http://", - "https://", - "urn:uuid:" - }; - const size_t NUM_PREFIXES = sizeof(prefixes) / sizeof(char *); - const char *suffixes[] = { - ".com/", - ".org/", - ".edu/", - ".net/", - ".info/", - ".biz/", - ".gov/", - ".com", - ".org", - ".edu", - ".net", - ".info", - ".biz", - ".gov" - }; - const size_t NUM_SUFFIXES = sizeof(suffixes) / sizeof(char *); - - sizeofURIDataOut = 0; - memset(uriDataOut, 0, sizeof(UriData_t)); - - if ((uriDataIn == NULL) || (strlen(uriDataIn) == 0)) { - return; - } - - /* - * handle prefix - */ - for (unsigned i = 0; i < NUM_PREFIXES; i++) { - size_t prefixLen = strlen(prefixes[i]); - if (strncmp(uriDataIn, prefixes[i], prefixLen) == 0) { - uriDataOut[sizeofURIDataOut++] = i; - uriDataIn += prefixLen; - break; - } - } - - /* - * handle suffixes - */ - while (*uriDataIn && (sizeofURIDataOut < URI_DATA_MAX)) { - /* check for suffix match */ - unsigned i; - for (i = 0; i < NUM_SUFFIXES; i++) { - size_t suffixLen = strlen(suffixes[i]); - if (strncmp(uriDataIn, suffixes[i], suffixLen) == 0) { - uriDataOut[sizeofURIDataOut++] = i; - uriDataIn += suffixLen; - break; /* from the for loop for checking against suffixes */ - } - } - /* This is the default case where we've got an ordinary character which doesn't match a suffix. */ - if (i == NUM_SUFFIXES) { - uriDataOut[sizeofURIDataOut++] = *uriDataIn; - ++uriDataIn; - } - } - } -}; - -#endif // SERVICES_URIBEACONCONFIGSERVICE_H_ \ No newline at end of file
--- a/services/iBeaconService.h Fri Jun 19 15:53:28 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2015 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef __BLE_IBEACON_SERVICE_H__ -#define __BLE_IBEACON_SERVICE_H__ - -#include "core_cmInstr.h" -#include "BLEDevice.h" - -/** -* @class iBeaconService -* @brief iBeacon Service. This service sets up a device to broadcast advertising packets to mimic an iBeacon<br> -*/ - -class iBeaconService -{ -public: - typedef const uint8_t LocationUUID_t[16]; - - union Payload { - uint8_t raw[25]; - struct { - uint16_t companyID; - uint8_t ID; - uint8_t len; - uint8_t proximityUUID[16]; - uint16_t majorNumber; - uint16_t minorNumber; - uint8_t txPower; - }; - - Payload(LocationUUID_t uuid, uint16_t majNum, uint16_t minNum, uint8_t transmitPower, uint16_t companyIDIn) : - companyID(companyIDIn), ID(0x02), len(0x15), majorNumber(__REV16(majNum)), minorNumber(__REV16(minNum)), txPower(transmitPower) - { - memcpy(proximityUUID, uuid, sizeof(LocationUUID_t)); - } - }; - -public: - iBeaconService(BLEDevice &_ble, - LocationUUID_t uuid, - uint16_t majNum, - uint16_t minNum, - uint8_t txP = 0xC8, - uint16_t compID = 0x004C) : - ble(_ble), data(uuid, majNum, minNum, txP, compID) - { - // Generate the 0x020106 part of the iBeacon Prefix - ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE ); - // Generate the 0x1AFF part of the iBeacon Prefix - ble.accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, data.raw, sizeof(data.raw)); - - // Set advertising type - ble.setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED); - } - -private: - BLEDevice &ble; - Payload data; -}; - -#endif //__BLE_IBEACON_SERVICE_H__ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/BLE.cpp Fri Jun 19 15:53:29 2015 +0100 @@ -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 "ble/BLE.h" + +#if defined(TARGET_OTA_ENABLED) +#include "DFUService.h" +#endif + +ble_error_t +BLE::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; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/DiscoveredCharacteristic.cpp Fri Jun 19 15:53:29 2015 +0100 @@ -0,0 +1,69 @@ +/* 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 "ble/DiscoveredCharacteristic.h" +#include "ble/GattClient.h" + +GattClient::ReadCallback_t DiscoveredCharacteristic::onDataReadCallback; +GattClient::WriteCallback_t DiscoveredCharacteristic::onDataWriteCallback; + +ble_error_t +DiscoveredCharacteristic::read(uint16_t offset) const +{ + if (!props.read()) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + if (!gattc) { + return BLE_ERROR_INVALID_STATE; + } + + return gattc->read(connHandle, valueHandle, offset); +} + +ble_error_t +DiscoveredCharacteristic::write(uint16_t length, const uint8_t *value) const +{ + if (!props.write()) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + if (!gattc) { + return BLE_ERROR_INVALID_STATE; + } + + return gattc->write(GattClient::GATT_OP_WRITE_REQ, connHandle, valueHandle, length, value); +} + +ble_error_t +DiscoveredCharacteristic::writeWoResponse(uint16_t length, const uint8_t *value) const +{ + if (!props.writeWoResp()) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + if (!gattc) { + return BLE_ERROR_INVALID_STATE; + } + + return gattc->write(GattClient::GATT_OP_WRITE_CMD, connHandle, valueHandle, length, value); +} + +ble_error_t +DiscoveredCharacteristic::discoverDescriptors(DescriptorCallback_t callback, const UUID &matchingUUID) const +{ + return BLE_ERROR_NOT_IMPLEMENTED; /* TODO: this needs to be filled in. */ +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/GapScanningParams.cpp Fri Jun 19 15:53:29 2015 +0100 @@ -0,0 +1,75 @@ +/* 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 "ble/Gap.h" +#include "ble/GapScanningParams.h" + +GapScanningParams::GapScanningParams(uint16_t interval, uint16_t window, uint16_t timeout, bool activeScanning) : + _interval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(interval)), + _window(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(window)), + _timeout(timeout), + _activeScanning(activeScanning) { + /* stay within limits */ + if (_interval < SCAN_INTERVAL_MIN) { + _interval = SCAN_INTERVAL_MIN; + } + if (_interval > SCAN_INTERVAL_MAX) { + _interval = SCAN_INTERVAL_MAX; + } + if (_window < SCAN_WINDOW_MIN) { + _window = SCAN_WINDOW_MIN; + } + if (_window > SCAN_WINDOW_MAX) { + _window = SCAN_WINDOW_MAX; + } +} + +ble_error_t +GapScanningParams::setInterval(uint16_t newIntervalInMS) +{ + uint16_t newInterval = Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(newIntervalInMS); + if ((newInterval >= SCAN_INTERVAL_MIN) && (newInterval < SCAN_INTERVAL_MAX)) { + _interval = newInterval; + return BLE_ERROR_NONE; + } + + return BLE_ERROR_PARAM_OUT_OF_RANGE; +} + +ble_error_t +GapScanningParams::setWindow(uint16_t newWindowInMS) +{ + uint16_t newWindow = Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(newWindowInMS); + if ((newWindow >= SCAN_WINDOW_MIN) && (newWindow < SCAN_WINDOW_MAX)) { + _window = newWindow; + return BLE_ERROR_NONE; + } + + return BLE_ERROR_PARAM_OUT_OF_RANGE; +} + +ble_error_t +GapScanningParams::setTimeout(uint16_t newTimeout) +{ + _timeout = newTimeout; + return BLE_ERROR_NONE; +} + +void +GapScanningParams::setActiveScanning(bool activeScanning) +{ + _activeScanning = activeScanning; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/services/DFUService.cpp Fri Jun 19 15:53:29 2015 +0100 @@ -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 "ble/services/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; \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/services/UARTService.cpp Fri Jun 19 15:53:29 2015 +0100 @@ -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 "ble/services/UARTService.h" + +const uint8_t UARTServiceBaseUUID[UUID::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[UUID::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[UUID::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[UUID::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[UUID::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, +}; \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/services/URIBeaconConfigService.cpp Fri Jun 19 15:53:29 2015 +0100 @@ -0,0 +1,35 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ble/services/URIBeaconConfigService.h" + +#define UUID_URI_BEACON(FIRST, SECOND) { \ + 0xee, 0x0c, FIRST, SECOND, 0x87, 0x86, 0x40, 0xba, \ + 0xab, 0x96, 0x99, 0xb9, 0x1a, 0xc9, 0x81, 0xd8, \ +} + +const uint8_t UUID_URI_BEACON_SERVICE[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x80); +const uint8_t UUID_LOCK_STATE_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x81); +const uint8_t UUID_LOCK_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x82); +const uint8_t UUID_UNLOCK_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x83); +const uint8_t UUID_URI_DATA_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x84); +const uint8_t UUID_FLAGS_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x85); +const uint8_t UUID_ADV_POWER_LEVELS_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x86); +const uint8_t UUID_TX_POWER_MODE_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x87); +const uint8_t UUID_BEACON_PERIOD_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x88); +const uint8_t UUID_RESET_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x89); + +const uint8_t BEACON_UUID[sizeof(UUID::ShortUUIDBytes_t)] = {0xD8, 0xFE}; \ No newline at end of file