From d43b1d1a8b3b7fd3b200d208182d0aa57bb861bc Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Tue, 29 Sep 2015 12:58:14 +0100 Subject: [PATCH 01/24] update LinkLoss service due to recent changes in APIs --- ble/services/LinkLossService.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ble/services/LinkLossService.h b/ble/services/LinkLossService.h index 66a1ac2..5fe65f2 100644 --- a/ble/services/LinkLossService.h +++ b/ble/services/LinkLossService.h @@ -55,7 +55,7 @@ public: ble.addService(linkLossService); serviceAdded = true; - ble.addToDisconnectionCallChain(this, &LinkLossService::onDisconnectionFilter); + ble.onDisconnection(this, &LinkLossService::onDisconnectionFilter); ble.onDataWritten(this, &LinkLossService::onDataWritten); } @@ -86,7 +86,7 @@ protected: } } - void onDisconnectionFilter(void) { + void onDisconnectionFilter(const Gap::DisconnectionCallbackParams_t *params) { if (alertLevel != NO_ALERT) { callback(alertLevel); } From f0f42d110bbc9b25f6a0f28ce4c973e66bf4af79 Mon Sep 17 00:00:00 2001 From: Xabi Crespo Date: Thu, 24 Sep 2015 16:39:24 +0200 Subject: [PATCH 02/24] Support for Environmental Service (temperature, pressure and humidity characteristics) --- ble/GattCharacteristic.h | 5 +- ble/GattService.h | 1 + ble/services/EnvironmentalService.h | 102 ++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 ble/services/EnvironmentalService.h diff --git a/ble/GattCharacteristic.h b/ble/GattCharacteristic.h index 2e27c19..37d745f 100644 --- a/ble/GattCharacteristic.h +++ b/ble/GattCharacteristic.h @@ -57,6 +57,7 @@ public: UUID_HEART_RATE_MEASUREMENT_CHAR = 0x2A37, UUID_HID_CONTROL_POINT_CHAR = 0x2A4C, UUID_HID_INFORMATION_CHAR = 0x2A4A, + UUID_HUMIDITY_CHAR = 0x2A6F, UUID_IEEE_REGULATORY_CERTIFICATION_DATA_LIST_CHAR = 0x2A2A, UUID_INTERMEDIATE_CUFF_PRESSURE_CHAR = 0x2A36, UUID_INTERMEDIATE_TEMPERATURE_CHAR = 0x2A1E, @@ -67,6 +68,7 @@ public: UUID_UNREAD_ALERT_CHAR = 0x2A45, UUID_NEW_ALERT_CHAR = 0x2A46, UUID_PNP_ID_CHAR = 0x2A50, + UUID_PRESSURE_CHAR = 0x2A6D, UUID_PROTOCOL_MODE_CHAR = 0x2A4E, UUID_RECORD_ACCESS_CONTROL_POINT_CHAR = 0x2A52, UUID_REFERENCE_TIME_INFORMATION_CHAR = 0x2A14, @@ -81,6 +83,7 @@ public: UUID_SUPPORTED_NEW_ALERT_CATEGORY_CHAR = 0x2A47, UUID_SUPPORTED_UNREAD_ALERT_CATEGORY_CHAR = 0x2A48, UUID_SYSTEM_ID_CHAR = 0x2A23, + UUID_TEMPERATURE_CHAR = 0x2A6E, UUID_TEMPERATURE_MEASUREMENT_CHAR = 0x2A1C, UUID_TEMPERATURE_TYPE_CHAR = 0x2A1D, UUID_TIME_ACCURACY_CHAR = 0x2A12, @@ -93,7 +96,7 @@ public: UUID_CSC_FEATURE_CHAR = 0x2A5C, UUID_CSC_MEASUREMENT_CHAR = 0x2A5B, UUID_RSC_FEATURE_CHAR = 0x2A54, - UUID_RSC_MEASUREMENT_CHAR = 0x2A53, + UUID_RSC_MEASUREMENT_CHAR = 0x2A53 }; /**************************************************************************/ diff --git a/ble/GattService.h b/ble/GattService.h index f3d3b85..d2ff649 100644 --- a/ble/GattService.h +++ b/ble/GattService.h @@ -29,6 +29,7 @@ public: UUID_CURRENT_TIME_SERVICE = 0x1805, UUID_CYCLING_SPEED_AND_CADENCE = 0x1816, UUID_DEVICE_INFORMATION_SERVICE = 0x180A, + UUID_ENVIRONMENTAL_SERVICE = 0x181A, UUID_GLUCOSE_SERVICE = 0x1808, UUID_HEALTH_THERMOMETER_SERVICE = 0x1809, UUID_HEART_RATE_SERVICE = 0x180D, diff --git a/ble/services/EnvironmentalService.h b/ble/services/EnvironmentalService.h new file mode 100644 index 0000000..61d9b3e --- /dev/null +++ b/ble/services/EnvironmentalService.h @@ -0,0 +1,102 @@ + +#ifndef __BLE_ENVIRONMENTAL_SERVICE_H__ +#define __BLE_ENVIRONMENTAL_SERVICE_H__ + +#include "ble/BLE.h" + + /** +* @class EnvironmentalService +* @brief BLE Environmental Service. This service provides the location of the thermometer and the temperature.
+* Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.environmental_sensing.xml
+* Temperature: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature.xml
+* Humidity: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.humidity.xml
+* Pressure: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.pressure.xml +*/ +class EnvironmentalService { +public: + /** + * @brief EnvironmentalService constructor. + * @param ble Reference to BLE device. + * @param temperature_en Enable this characteristic. + * @param humidity_en Enable this characteristic. + * @param pressure_en Enable this characteristic. + */ + EnvironmentalService(BLE &_ble, + bool temperature_en = false, + bool humidity_en = false, + bool pressure_en = false) : + ble(_ble), + temperatureCharacteristic(GattCharacteristic::UUID_TEMPERATURE_CHAR, + (uint8_t *) &temperature, + (temperature_en) ? 2 : 0, // minLength + (temperature_en) ? 2 : 0, // maxLength + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), + humidityCharacteristic(GattCharacteristic::UUID_HUMIDITY_CHAR, + (uint8_t *) &humidity, + (humidity_en) ? 2 : 0, // minLength + (humidity_en) ? 2 : 0, // maxLength + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), + pressureCharacteristic(GattCharacteristic::UUID_PRESSURE_CHAR, + (uint8_t *) &pressure, + (pressure_en) ? 4 : 0, // minLength + (pressure_en) ? 4 : 0, // maxLength + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ) + { + static bool serviceAdded = false; /* We should only ever need to add the information service once. */ + if (serviceAdded) { + return; + } + + GattCharacteristic *charTable[] = { &humidityCharacteristic, + &pressureCharacteristic, + &temperatureCharacteristic }; + + GattService environmentalService(GattService::UUID_ENVIRONMENTAL_SERVICE, charTable, + sizeof(charTable) / sizeof(GattCharacteristic *)); + + ble.gattServer().addService(environmentalService); + serviceAdded = true; + } + + /** + * @brief Update humidity characteristic. + * @param newHumidityVal New humidity measurement. + */ + void updateHumidity(uint16_t newHumidityVal) + { + humidity = (uint32_t) (newHumidityVal*100); + ble.gattServer().write(humidityCharacteristic.getValueHandle(), (uint8_t *) &humidity, 2); + } + + /** + * @brief Update pressure characteristic. + * @param newPressureVal New pressure measurement. + */ + void updatePressure(uint32_t newPressureVal) + { + pressure = (uint32_t) (newPressureVal*10); + ble.gattServer().write(pressureCharacteristic.getValueHandle(), (uint8_t *) &pressure, 4); + } + + /** + * @brief Update temperature characteristic. + * @param newTemperatureVal New temperature measurement. + */ + void updateTemperature(float newTemperatureVal) + { + temperature = (int16_t) (newTemperatureVal*100); + ble.gattServer().write(temperatureCharacteristic.getValueHandle(), (uint8_t *) &temperature, 2); + } + +private: + BLE &ble; + + int16_t temperature; + GattCharacteristic temperatureCharacteristic; + uint16_t humidity; + GattCharacteristic humidityCharacteristic; + uint32_t pressure; + GattCharacteristic pressureCharacteristic; +}; + +#endif /* #ifndef __BLE_ENVIRONMENTAL_SERVICE_H__*/ \ No newline at end of file From da2b104e16bfc69c1bc19fb19d0ec6e47582d41d Mon Sep 17 00:00:00 2001 From: xcrespo Date: Mon, 5 Oct 2015 10:32:05 +0200 Subject: [PATCH 03/24] Added license header for EnvironmentalService --- ble/services/EnvironmentalService.h | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/ble/services/EnvironmentalService.h b/ble/services/EnvironmentalService.h index 61d9b3e..990d7cb 100644 --- a/ble/services/EnvironmentalService.h +++ b/ble/services/EnvironmentalService.h @@ -1,4 +1,19 @@ - +/* 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_ENVIRONMENTAL_SERVICE_H__ #define __BLE_ENVIRONMENTAL_SERVICE_H__ From 13a9c192d7360d196cdfbe586816fb14a48a71fb Mon Sep 17 00:00:00 2001 From: xcrespo Date: Mon, 5 Oct 2015 10:37:46 +0200 Subject: [PATCH 04/24] New call to onDisconnection callback in LinkLossService --- ble/services/LinkLossService.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ble/services/LinkLossService.h b/ble/services/LinkLossService.h index 66a1ac2..137b378 100644 --- a/ble/services/LinkLossService.h +++ b/ble/services/LinkLossService.h @@ -52,11 +52,12 @@ public: GattCharacteristic *charTable[] = {&alertLevelChar}; GattService linkLossService(GattService::UUID_LINK_LOSS_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); - ble.addService(linkLossService); + ble.gattServer().addService(linkLossService); serviceAdded = true; - ble.addToDisconnectionCallChain(this, &LinkLossService::onDisconnectionFilter); - ble.onDataWritten(this, &LinkLossService::onDataWritten); + ble.gap().onDisconnection(this, &LinkLossService::onDisconnectionFilter); + ble.gattServer().onDataWritten(this, &LinkLossService::onDataWritten); + } /** @@ -86,7 +87,7 @@ protected: } } - void onDisconnectionFilter(void) { + void onDisconnectionFilter(const Gap::DisconnectionCallbackParams_t *params) { if (alertLevel != NO_ALERT) { callback(alertLevel); } From 18dcc913820ae688d4885625e73ce39354894fb3 Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Wed, 21 Oct 2015 15:02:37 +0100 Subject: [PATCH 05/24] Introduced fix for defect IOTSFW-1058 Introduced a fix for defect IOTSFW-1058 that caused the BLE_EddystoneBeaconConfigService example in ARMmbed/ble-examples repo to fail. Refer to JIRA defect for more details. --- ble/services/EddystoneConfigService.h | 2 +- ble/services/EddystoneService.h | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/ble/services/EddystoneConfigService.h b/ble/services/EddystoneConfigService.h index 5a06b8b..94d6067 100644 --- a/ble/services/EddystoneConfigService.h +++ b/ble/services/EddystoneConfigService.h @@ -306,7 +306,7 @@ public: eddyServ.setTLMFrameData(params.tlmVersion, params.tlmBeaconPeriod); } if (params.uriEnabled) { - eddyServ.setURLFrameData(params.advPowerLevels[params.txPowerMode], (const char *) params.uriData, params.uriBeaconPeriod); + eddyServ.setURLFrameEncodedData(params.advPowerLevels[params.txPowerMode], (const char *) params.uriData, params.uriDataLength, params.uriBeaconPeriod); } if (params.uidEnabled) { eddyServ.setUIDFrameData(params.advPowerLevels[params.txPowerMode], diff --git a/ble/services/EddystoneService.h b/ble/services/EddystoneService.h index dcf0eaf..c562500 100644 --- a/ble/services/EddystoneService.h +++ b/ble/services/EddystoneService.h @@ -185,6 +185,29 @@ public: return false; } + /** + * Set Eddystone URL Frame information. + * @param[in] power TX Power in dB measured at 0 meters from the device. + * @param[in] url Encoded URL + * @param[in] urlAdvPeriodIn How long to advertise the URL frame (measured in # of adv periods) + * @return false on success, true on failure. + */ + bool setURLFrameEncodedData(int8_t power, const char *encodedUrlIn, uint8_t encodedUriInLength, uint32_t urlAdvPeriodIn) { + if (0 == urlAdvPeriodIn) { + urlIsSet = false; + return false; + } + defaultUrlPower = power; + memcpy(defaultUriData, encodedUrlIn, URI_DATA_MAX); + defaultUriDataLength = encodedUriInLength; + if (defaultUriDataLength > URI_DATA_MAX) { + return true; // error, URL is too big + } + urlAdvPeriod = urlAdvPeriodIn; + urlIsSet = true; + return false; + } + /* * Construct URL frame from private variables * @param[in/out] Data pointer to array to store constructed frame in From f8e3d2f44c5c70ce8f6bfcf5b13b74a3f060cb34 Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Thu, 22 Oct 2015 11:05:00 +0100 Subject: [PATCH 06/24] Introduced fixes after review Introduced fixes after review of previous commit with regards to JIRA defect IOTSFW-1058. --- ble/services/EddystoneService.h | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/ble/services/EddystoneService.h b/ble/services/EddystoneService.h index c562500..aa24a6c 100644 --- a/ble/services/EddystoneService.h +++ b/ble/services/EddystoneService.h @@ -175,11 +175,11 @@ public: urlIsSet = false; return false; } - defaultUrlPower = power; encodeURL(urlIn, defaultUriData, defaultUriDataLength); // encode URL to URL Formatting if (defaultUriDataLength > URI_DATA_MAX) { return true; // error, URL is too big } + defaultUrlPower = power; urlAdvPeriod = urlAdvPeriodIn; urlIsSet = true; return false; @@ -187,24 +187,25 @@ public: /** * Set Eddystone URL Frame information. - * @param[in] power TX Power in dB measured at 0 meters from the device. - * @param[in] url Encoded URL - * @param[in] urlAdvPeriodIn How long to advertise the URL frame (measured in # of adv periods) + * @param[in] power TX Power in dB measured at 0 meters from the device. + * @param[in] encodedUrlIn Encoded URL + * @param[in] encodedUrlInLength Length of the encoded URL + * @param[in] urlAdvPeriodIn How long to advertise the URL frame (measured in # of adv periods) * @return false on success, true on failure. */ - bool setURLFrameEncodedData(int8_t power, const char *encodedUrlIn, uint8_t encodedUriInLength, uint32_t urlAdvPeriodIn) { + bool setURLFrameEncodedData(int8_t power, const char *encodedUrlIn, uint8_t encodedUrlInLength, uint32_t urlAdvPeriodIn) { if (0 == urlAdvPeriodIn) { urlIsSet = false; return false; } - defaultUrlPower = power; - memcpy(defaultUriData, encodedUrlIn, URI_DATA_MAX); - defaultUriDataLength = encodedUriInLength; + memcpy(defaultUriData, encodedUrlIn, encodedUrlInLength); if (defaultUriDataLength > URI_DATA_MAX) { return true; // error, URL is too big } - urlAdvPeriod = urlAdvPeriodIn; - urlIsSet = true; + defaultUrlPower = power; + defaultUriDataLength = encodedUrlInLength; + urlAdvPeriod = urlAdvPeriodIn; + urlIsSet = true; return false; } From 84f434a99496617f0bb374a0ed41e169cb7c05d7 Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Fri, 23 Oct 2015 10:31:33 +0100 Subject: [PATCH 07/24] Fix compiler warnings due to header includes. Some header include paths have diverged between mbed OS and mbed-classic. --- ble/BLE.h | 4 ++++ ble/services/UARTService.h | 5 +++++ ble/services/URIBeaconConfigService.h | 5 +++++ 3 files changed, 14 insertions(+) diff --git a/ble/BLE.h b/ble/BLE.h index d95471c..952318d 100644 --- a/ble/BLE.h +++ b/ble/BLE.h @@ -23,7 +23,11 @@ #include "GattClient.h" #include "BLEInstanceBase.h" +#ifdef YOTTA_CFG_MBED_OS +#include "mbed-drivers/mbed_error.h" +#else #include "mbed_error.h" +#endif /** * The base class used to abstract away BLE capable radio transceivers or SOCs, diff --git a/ble/services/UARTService.h b/ble/services/UARTService.h index ef9914e..b3840bc 100644 --- a/ble/services/UARTService.h +++ b/ble/services/UARTService.h @@ -17,8 +17,13 @@ #ifndef __BLE_UART_SERVICE_H__ #define __BLE_UART_SERVICE_H__ +#ifdef YOTTA_CFG_MBED_OS +#include "mbed-drivers/mbed.h" +#include "mbed-drivers/Stream.h" +#else #include "mbed.h" #include "Stream.h" +#endif #include "ble/UUID.h" #include "ble/BLE.h" diff --git a/ble/services/URIBeaconConfigService.h b/ble/services/URIBeaconConfigService.h index 8e4e878..e2b54f1 100644 --- a/ble/services/URIBeaconConfigService.h +++ b/ble/services/URIBeaconConfigService.h @@ -18,7 +18,12 @@ #define SERVICES_URIBEACONCONFIGSERVICE_H_ #include "ble/BLE.h" + +#ifdef YOTTA_CFG_MBED_OS +#include "mbed-drivers/mbed.h" +#else #include "mbed.h" +#endif 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]; From 17f2e99d2bd4cadb17ac86b487ae7e558351fb95 Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Fri, 23 Oct 2015 10:32:31 +0100 Subject: [PATCH 08/24] fix minor compiler warning due to a shadowed member variable. --- ble/UUID.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ble/UUID.h b/ble/UUID.h index fc32098..0e0e087 100644 --- a/ble/UUID.h +++ b/ble/UUID.h @@ -74,7 +74,7 @@ public: * * @note we don't yet support 32-bit shortened UUIDs. */ - UUID(ShortUUIDBytes_t shortUUID) : type(UUID_TYPE_SHORT), baseUUID(), shortUUID(shortUUID) { + UUID(ShortUUIDBytes_t _shortUUID) : type(UUID_TYPE_SHORT), baseUUID(), shortUUID(_shortUUID) { /* empty */ } From 7aac367d990c0c510222695b5aee59f85148675f Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Fri, 23 Oct 2015 10:33:47 +0100 Subject: [PATCH 09/24] add a target specific dependency --- module.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/module.json b/module.json index 1230e27..288f206 100644 --- a/module.json +++ b/module.json @@ -23,6 +23,9 @@ "nrf51822": { "ble-nrf51822": "~0.4.7" }, + "cordio": { + "ble-wicentric": "~0.0.0" + }, "mbed-classic": { "mbed-classic": "~0.0.1" }, From a0335c2e8d8bbe4090a7b1d6dd52f3b726468653 Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Fri, 23 Oct 2015 14:32:51 +0100 Subject: [PATCH 10/24] add a missing include file --- ble/BLEInstanceBase.h | 1 + 1 file changed, 1 insertion(+) diff --git a/ble/BLEInstanceBase.h b/ble/BLEInstanceBase.h index db050f5..ab7ba04 100644 --- a/ble/BLEInstanceBase.h +++ b/ble/BLEInstanceBase.h @@ -18,6 +18,7 @@ #define __BLE_DEVICE_INSTANCE_BASE__ #include "Gap.h" +#include "ble/SecurityManager.h" /* forward declarations */ class GattServer; From 57c160c25ca2d457eaabce104bf55238756eac63 Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Fri, 23 Oct 2015 15:59:53 +0100 Subject: [PATCH 11/24] Reduce the memory size consummed by a FunctionPointerWithContext to 20 bytes (oryginally, it was 32 bytes !). Enforce alignement constraints of the embedded pointer to member function. Symplify and unify call mecanic, everything is delegated uniformally to the actual implementation. --- ble/FunctionPointerWithContext.h | 73 +++++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 21 deletions(-) diff --git a/ble/FunctionPointerWithContext.h b/ble/FunctionPointerWithContext.h index c886bb3..ff76ee3 100644 --- a/ble/FunctionPointerWithContext.h +++ b/ble/FunctionPointerWithContext.h @@ -20,6 +20,7 @@ #include + /** A class for storing and calling a pointer to a static or member void function * which takes a context. */ @@ -34,7 +35,7 @@ public: * @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) { + _function(NULL), _caller(NULL), _next(NULL) { attach(function); } @@ -45,7 +46,7 @@ public: */ template FunctionPointerWithContext(T *object, void (T::*member)(ContextType context)) : - _function(NULL), _object(NULL), _member(), _membercaller(NULL), _next(NULL) { + _memberFunctionAndPointer(), _caller(NULL), _next(NULL) { attach(object, member); } @@ -55,6 +56,7 @@ public: */ void attach(void (*function)(ContextType context) = NULL) { _function = function; + _caller = functioncaller; } /** Attach a member function @@ -64,9 +66,9 @@ public: */ template void attach(T *object, void (T::*member)(ContextType context)) { - _object = static_cast(object); - memcpy(_member, (char *)&member, sizeof(member)); - _membercaller = &FunctionPointerWithContext::membercaller; + _memberFunctionAndPointer._object = static_cast(object); + memcpy(_memberFunctionAndPointer._memberFunction, (char*) &member, sizeof(member)); + _caller = &FunctionPointerWithContext::membercaller; } /** Call the attached static or member function; and if there are chained @@ -74,11 +76,7 @@ public: * @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); - } + _caller(this, context); /* Propagate the call to next in the chain. */ if (_next) { @@ -107,19 +105,52 @@ public: private: template - static void membercaller(void *object, char *member, ContextType context) { - T *o = static_cast(object); - void (T::*m)(ContextType); - memcpy((char *)&m, member, sizeof(m)); - (o->*m)(context); + static void membercaller(FunctionPointerWithContext* self, ContextType context) { + if(self->_memberFunctionAndPointer._object) { + T *o = static_cast(self->_memberFunctionAndPointer._object); + void (T::*m)(ContextType); + memcpy((char*) &m, self->_memberFunctionAndPointer._memberFunction, 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. */ + static void functioncaller(FunctionPointerWithContext* self, ContextType context) { + if(self->_function) { + self->_function(context); + } + } + + struct MemberFunctionAndPtr { + /* + * forward declaration of a class and a member function to this class. + * Because the compiler doesnt know anything about the member function, it + * will always take the biggest size that a member function can take. + * This also guarantee that the proper alignement will be chosen + */ + class UndefinedClass; + typedef void (UndefinedClass::*UndefinedMemberFunction)(ContextType); + + + void* _object; + union { + char _memberFunction[sizeof(UndefinedMemberFunction)]; + UndefinedMemberFunction _allignement; + }; + }; + + + + union { + void (*_function)(ContextType context); /**< static function pointer - NULL if none attached */ + /** + * object this pointer and pointer to member - + * _memberFunctionAndPointer._object will be NULL if none attached + */ + MemberFunctionAndPtr _memberFunctionAndPointer; + }; + + void (*_caller)(FunctionPointerWithContext*, ContextType); + 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 From 8bad0486cd890aacc19681893afa5e4fd96eb63a Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Fri, 23 Oct 2015 19:03:33 +0100 Subject: [PATCH 12/24] Remove unneeded blank lines. --- ble/FunctionPointerWithContext.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/ble/FunctionPointerWithContext.h b/ble/FunctionPointerWithContext.h index ff76ee3..5152c4b 100644 --- a/ble/FunctionPointerWithContext.h +++ b/ble/FunctionPointerWithContext.h @@ -130,7 +130,6 @@ private: class UndefinedClass; typedef void (UndefinedClass::*UndefinedMemberFunction)(ContextType); - void* _object; union { char _memberFunction[sizeof(UndefinedMemberFunction)]; @@ -138,8 +137,6 @@ private: }; }; - - union { void (*_function)(ContextType context); /**< static function pointer - NULL if none attached */ /** From 129683bdc03e6d259a2530d6250f8fdc206857b6 Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Mon, 26 Oct 2015 10:44:21 +0000 Subject: [PATCH 13/24] Code and command cleanup: - add a space after if keyword - Use typedef types instead of direct declarations for pFunctionPointerWithContext_t and pvoidfcontext_t - Fix typos and enhance comment about how alignement and size requirements of the member function pointer are computed. --- ble/FunctionPointerWithContext.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ble/FunctionPointerWithContext.h b/ble/FunctionPointerWithContext.h index 5152c4b..41f8687 100644 --- a/ble/FunctionPointerWithContext.h +++ b/ble/FunctionPointerWithContext.h @@ -105,8 +105,8 @@ public: private: template - static void membercaller(FunctionPointerWithContext* self, ContextType context) { - if(self->_memberFunctionAndPointer._object) { + static void membercaller(pFunctionPointerWithContext_t self, ContextType context) { + if (self->_memberFunctionAndPointer._object) { T *o = static_cast(self->_memberFunctionAndPointer._object); void (T::*m)(ContextType); memcpy((char*) &m, self->_memberFunctionAndPointer._memberFunction, sizeof(m)); @@ -114,8 +114,8 @@ private: } } - static void functioncaller(FunctionPointerWithContext* self, ContextType context) { - if(self->_function) { + static void functioncaller(pFunctionPointerWithContext_t self, ContextType context) { + if (self->_function) { self->_function(context); } } @@ -123,9 +123,9 @@ private: struct MemberFunctionAndPtr { /* * forward declaration of a class and a member function to this class. - * Because the compiler doesnt know anything about the member function, it - * will always take the biggest size that a member function can take. - * This also guarantee that the proper alignement will be chosen + * Because the compiler doesn't know anything about the forwarded member + * function, it will always use the biggest size and the biggest alignment + * that a member function can take for objects of type UndefinedMemberFunction. */ class UndefinedClass; typedef void (UndefinedClass::*UndefinedMemberFunction)(ContextType); @@ -133,12 +133,12 @@ private: void* _object; union { char _memberFunction[sizeof(UndefinedMemberFunction)]; - UndefinedMemberFunction _allignement; + UndefinedMemberFunction _alignment; }; }; union { - void (*_function)(ContextType context); /**< static function pointer - NULL if none attached */ + pvoidfcontext_t _function; /**< static function pointer - NULL if none attached */ /** * object this pointer and pointer to member - * _memberFunctionAndPointer._object will be NULL if none attached From da3d9f811abf1550ed17300166d60f519d52b47f Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Tue, 27 Oct 2015 14:19:20 +0000 Subject: [PATCH 14/24] Fixed include problem in HealthThermometer header Modified the HealthThermometer header file to include BLE.h from ble/BLE.h. --- ble/services/HealthThermometerService.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ble/services/HealthThermometerService.h b/ble/services/HealthThermometerService.h index 063d5fc..e119fff 100644 --- a/ble/services/HealthThermometerService.h +++ b/ble/services/HealthThermometerService.h @@ -17,7 +17,7 @@ #ifndef __BLE_HEALTH_THERMOMETER_SERVICE_H__ #define __BLE_HEALTH_THERMOMETER_SERVICE_H__ -#include "BLE.h" +#include "ble/BLE.h" /** * @class HealthThermometerService From bde2e465c8fd28a9a6c76dd5e5f2243303f07382 Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Tue, 27 Oct 2015 17:23:49 +0000 Subject: [PATCH 15/24] fix #86: update includes from within services to use paths starting from subfolder 'ble' --- ble/services/HealthThermometerService.h | 2 +- ble/services/LinkLossService.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ble/services/HealthThermometerService.h b/ble/services/HealthThermometerService.h index 063d5fc..e119fff 100644 --- a/ble/services/HealthThermometerService.h +++ b/ble/services/HealthThermometerService.h @@ -17,7 +17,7 @@ #ifndef __BLE_HEALTH_THERMOMETER_SERVICE_H__ #define __BLE_HEALTH_THERMOMETER_SERVICE_H__ -#include "BLE.h" +#include "ble/BLE.h" /** * @class HealthThermometerService diff --git a/ble/services/LinkLossService.h b/ble/services/LinkLossService.h index 5fe65f2..166cede 100644 --- a/ble/services/LinkLossService.h +++ b/ble/services/LinkLossService.h @@ -17,7 +17,7 @@ #ifndef __BLE_LINK_LOSS_SERVICE_H__ #define __BLE_LINK_LOSS_SERVICE_H__ -#include "Gap.h" +#include "ble/Gap.h" /** * @class LinkLossService From 918af4fbacec39d64f2752afa4e3008ef5154848 Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Wed, 28 Oct 2015 11:30:10 +0000 Subject: [PATCH 16/24] Major change: - There's a new type: BLE::InitializationCompleteCallback_t - init() now takes a completion callback. This is an optional parameter, if no callback is setup the application can still determine the status of initialization using BLE::hasInitialized() (see below). - There's a new API: BLEInstanceBase::hasInitialized() which transports need to implement. - BLEInstanceBase.h is no longer included from BLE.h. We use a forward declaration of BLEInstanceBase instead. This is required us to move implementations of BLE methods out of the header and into BLE.cpp. - There's a new API: BLE::getInstanceID(), which simply returns the ID of an instance. - There are new error types around initialization. --- ble/BLE.h | 118 +++++++++++++++++------------------------- ble/BLEInstanceBase.h | 22 ++++---- ble/blecommon.h | 22 ++++---- source/BLE.cpp | 116 +++++++++++++++++++++++++++++++++++++++-- 4 files changed, 185 insertions(+), 93 deletions(-) diff --git a/ble/BLE.h b/ble/BLE.h index 952318d..8654f7a 100644 --- a/ble/BLE.h +++ b/ble/BLE.h @@ -21,7 +21,6 @@ #include "Gap.h" #include "GattServer.h" #include "GattClient.h" -#include "BLEInstanceBase.h" #ifdef YOTTA_CFG_MBED_OS #include "mbed-drivers/mbed_error.h" @@ -29,6 +28,9 @@ #include "mbed_error.h" #endif +/* forward declaration for the implementation class */ +class BLEInstanceBase; + /** * The base class used to abstract away BLE capable radio transceivers or SOCs, * to enable this BLE API to work with any radio transparently. @@ -36,6 +38,9 @@ class BLE { public: + typedef unsigned InstanceID_t; + typedef void (*InitializationCompleteCallback_t)(BLE &bleInstance); + /** * Initialize the BLE controller. This should be called before using * anything else in the BLE_API. @@ -46,21 +51,38 @@ public: * system startup. It may not be safe to call init() from global static * context where ordering is compiler specific and can't be guaranteed--it * is safe to call BLE::init() from within main(). + * + * @param callback + * A callback for when initialization completes for a BLE + * instance. This is an optional parameter, if no callback is + * setup the application can still determine the status of + * initialization using BLE::hasInitialized() (see below). + * + * @return BLE_ERROR_NONE if the initialization procedure was started + * successfully. + * + * @note Nearly all BLE APIs would return + * BLE_ERROR_INITIALIZATION_INCOMPLETE if used on an instance before the + * corresponding transport is initialized. */ - ble_error_t init(); + ble_error_t init(InitializationCompleteCallback_t callback = NULL); + + /** + * @return true if initialization has completed for the underlying BLE + * transport. + * + * The application can setup a callback to signal completion of + * initialization when using init(). Otherwise, this method can be used to + * poll the state of initialization. + */ + bool hasInitialized(void) const; /** * Purge the BLE stack of GATT and GAP state. init() must be called * afterwards to re-instate services and GAP state. This API offers a way to * repopulate the GATT database with new services and characteristics. */ - ble_error_t shutdown(void) { - clearAdvertisingPayload(); - if (!transport) { - error("bad handle to underlying transport"); - } - return transport->shutdown(); - } + ble_error_t shutdown(void); /** * This call allows the application to get the BLE stack version information. @@ -68,81 +90,36 @@ public: * @return A pointer to a const string representing the version. * Note: The string is owned by the BLE_API. */ - const char *getVersion(void) { - if (!transport) { - error("bad handle to underlying transport"); - } - return transport->getVersion(); - } + const char *getVersion(void); /* * Accessors to GAP. Please refer to Gap.h. All GAP related functionality requires * going through this accessor. */ - const Gap &gap() const { - if (!transport) { - error("bad handle to underlying transport"); - } - return transport->getGap(); - } - Gap &gap() { - if (!transport) { - error("bad handle to underlying transport"); - } - return transport->getGap(); - } + const Gap &gap() const; + Gap &gap(); /* * Accessors to GATT Server. Please refer to GattServer.h. All GATTServer related * functionality requires going through this accessor. */ - const GattServer& gattServer() const { - if (!transport) { - error("bad handle to underlying transport"); - } - return transport->getGattServer(); - } - GattServer& gattServer() { - if (!transport) { - error("bad handle to underlying transport"); - } - return transport->getGattServer(); - } + const GattServer& gattServer() const; + GattServer& gattServer(); /* * Accessors to GATT Client. Please refer to GattClient.h. All GATTClient related * functionality requires going through this accessor. */ - const GattClient& gattClient() const { - if (!transport) { - error("bad handle to underlying transport"); - } - return transport->getGattClient(); - } - GattClient& gattClient() { - if (!transport) { - error("bad handle to underlying transport"); - } - return transport->getGattClient(); - } + const GattClient& gattClient() const; + GattClient& gattClient(); /* * Accessors to Security Manager. Please refer to SecurityManager.h. All * SecurityManager related functionality requires going through this * accessor. */ - const SecurityManager& securityManager() const { - if (!transport) { - error("bad handle to underlying transport"); - } - return transport->getSecurityManager(); - } - SecurityManager& securityManager() { - if (!transport) { - error("bad handle to underlying transport"); - } - return transport->getSecurityManager(); - } + const SecurityManager& securityManager() const; + SecurityManager& securityManager(); /** * Yield control to the BLE stack or to other tasks waiting for events. This @@ -151,15 +128,9 @@ public: * returning (to service the stack). This is not always interchangeable with * WFE(). */ - void waitForEvent(void) { - if (!transport) { - error("bad handle to underlying transport"); - } - transport->waitForEvent(); - } + void waitForEvent(void); public: - typedef unsigned InstanceID_t; static const InstanceID_t DEFAULT_INSTANCE = 0; #ifndef YOTTA_CFG_BLE_INSTANCES_COUNT static const InstanceID_t NUM_INSTANCES = 1; @@ -194,6 +165,12 @@ public: */ BLE(InstanceID_t instanceID = DEFAULT_INSTANCE); + /** + * Fetch the ID of a BLE instance. Typically there would only be the DEFAULT_INSTANCE. + */ + InstanceID_t getInstanceID(void) const { + return instanceID; + } /* * Deprecation alert! @@ -1398,6 +1375,7 @@ private: BLE &operator=(const BLE &); private: + InstanceID_t instanceID; BLEInstanceBase *transport; /* the device specific backend */ }; diff --git a/ble/BLEInstanceBase.h b/ble/BLEInstanceBase.h index ab7ba04..e8cfc0d 100644 --- a/ble/BLEInstanceBase.h +++ b/ble/BLEInstanceBase.h @@ -19,6 +19,7 @@ #include "Gap.h" #include "ble/SecurityManager.h" +#include "ble/BLE.h" /* forward declarations */ class GattServer; @@ -31,17 +32,18 @@ class GattClient; class BLEInstanceBase { public: - virtual ble_error_t init(void) = 0; - virtual ble_error_t shutdown(void) = 0; - virtual const char *getVersion(void) = 0; - virtual Gap& getGap() = 0; - virtual const Gap& getGap() const = 0; - virtual GattServer& getGattServer() = 0; - virtual const GattServer& getGattServer() const = 0; - virtual GattClient& getGattClient() = 0; - virtual SecurityManager& getSecurityManager() = 0; + virtual ble_error_t init(BLE::InstanceID_t instanceID, BLE::InitializationCompleteCallback_t) = 0; + virtual bool hasInitialized(void) const = 0; + virtual ble_error_t shutdown(void) = 0; + virtual const char * getVersion(void) = 0; + virtual Gap& getGap() = 0; + virtual const Gap& getGap() const = 0; + virtual GattServer& getGattServer() = 0; + virtual const GattServer& getGattServer() const = 0; + virtual GattClient& getGattClient() = 0; + virtual SecurityManager& getSecurityManager() = 0; virtual const SecurityManager& getSecurityManager() const = 0; - virtual void waitForEvent(void) = 0; + virtual void waitForEvent(void) = 0; }; /** diff --git a/ble/blecommon.h b/ble/blecommon.h index 07e5b63..c2c49db 100644 --- a/ble/blecommon.h +++ b/ble/blecommon.h @@ -114,16 +114,18 @@ enum { */ /**************************************************************************/ enum ble_error_t { - BLE_ERROR_NONE = 0, /**< No error */ - BLE_ERROR_BUFFER_OVERFLOW = 1, /**< The requested action would cause a buffer overflow and has been aborted */ - BLE_ERROR_NOT_IMPLEMENTED = 2, /**< Requested a feature that isn't yet implement or isn't supported by the target HW */ - BLE_ERROR_PARAM_OUT_OF_RANGE = 3, /**< One of the supplied parameters is outside the valid range */ - BLE_ERROR_INVALID_PARAM = 4, /**< One of the supplied parameters is invalid */ - BLE_STACK_BUSY = 5, /**< The stack is busy */ - BLE_ERROR_INVALID_STATE = 6, /**< Invalid state. */ - BLE_ERROR_NO_MEM = 7, /**< Out of Memory */ - BLE_ERROR_OPERATION_NOT_PERMITTED = 8, - BLE_ERROR_UNSPECIFIED = 9, /**< Unknown error. */ + BLE_ERROR_NONE = 0, /**< No error */ + BLE_ERROR_BUFFER_OVERFLOW = 1, /**< The requested action would cause a buffer overflow and has been aborted */ + BLE_ERROR_NOT_IMPLEMENTED = 2, /**< Requested a feature that isn't yet implement or isn't supported by the target HW */ + BLE_ERROR_PARAM_OUT_OF_RANGE = 3, /**< One of the supplied parameters is outside the valid range */ + BLE_ERROR_INVALID_PARAM = 4, /**< One of the supplied parameters is invalid */ + BLE_STACK_BUSY = 5, /**< The stack is busy */ + BLE_ERROR_INVALID_STATE = 6, /**< Invalid state. */ + BLE_ERROR_NO_MEM = 7, /**< Out of Memory */ + BLE_ERROR_OPERATION_NOT_PERMITTED = 8, + BLE_ERROR_INITIALIZATION_INCOMPLETE = 9, + BLE_ERROR_ALREADY_INITIALIZED = 10, + BLE_ERROR_UNSPECIFIED = 11, /**< Unknown error. */ }; /** @brief Default MTU size. */ diff --git a/source/BLE.cpp b/source/BLE.cpp index 28bfd0b..0328ef9 100644 --- a/source/BLE.cpp +++ b/source/BLE.cpp @@ -15,15 +15,16 @@ */ #include "ble/BLE.h" +#include "ble/BLEInstanceBase.h" #if defined(TARGET_OTA_ENABLED) #include "ble/services/DFUService.h" #endif ble_error_t -BLE::init() +BLE::init(BLE::InitializationCompleteCallback_t callback) { - ble_error_t err = transport->init(); + ble_error_t err = transport->init(instanceID, callback); if (err != BLE_ERROR_NONE) { return err; } @@ -105,7 +106,7 @@ BLE::Instance(InstanceID_t id) return badSingleton; } -BLE::BLE(InstanceID_t instanceID) : transport() +BLE::BLE(InstanceID_t instanceIDIn) : instanceID(instanceIDIn), transport() { static BLEInstanceBase *transportInstances[NUM_INSTANCES]; @@ -118,3 +119,112 @@ BLE::BLE(InstanceID_t instanceID) : transport() transport = NULL; } } + +bool BLE::hasInitialized(void) const +{ + if (!transport) { + error("bad handle to underlying transport"); + } + + return transport->hasInitialized(); +} + +ble_error_t BLE::shutdown(void) +{ + clearAdvertisingPayload(); + if (!transport) { + error("bad handle to underlying transport"); + } + + return transport->shutdown(); +} + +const char *BLE::getVersion(void) +{ + if (!transport) { + error("bad handle to underlying transport"); + } + + return transport->getVersion(); +} + +const Gap &BLE::gap() const +{ + if (!transport) { + error("bad handle to underlying transport"); + } + + return transport->getGap(); +} + +Gap &BLE::gap() +{ + if (!transport) { + error("bad handle to underlying transport"); + } + + return transport->getGap(); +} + +const GattServer& BLE::gattServer() const +{ + if (!transport) { + error("bad handle to underlying transport"); + } + + return transport->getGattServer(); +} + +GattServer& BLE::gattServer() +{ + if (!transport) { + error("bad handle to underlying transport"); + } + + return transport->getGattServer(); +} + +const GattClient& BLE::gattClient() const +{ + if (!transport) { + error("bad handle to underlying transport"); + } + + return transport->getGattClient(); +} + +GattClient& BLE::gattClient() +{ + if (!transport) { + error("bad handle to underlying transport"); + } + + return transport->getGattClient(); +} + +const SecurityManager& BLE::securityManager() const +{ + if (!transport) { + error("bad handle to underlying transport"); + } + + return transport->getSecurityManager(); +} + +SecurityManager& BLE::securityManager() +{ + if (!transport) { + error("bad handle to underlying transport"); + } + + return transport->getSecurityManager(); +} + +void BLE::waitForEvent(void) +{ + if (!transport) { + error("bad handle to underlying transport"); + } + + transport->waitForEvent(); +} From 5c7f26e06fb53505c21d3c9ac42034daf8e7d7d4 Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Wed, 28 Oct 2015 11:55:22 +0000 Subject: [PATCH 17/24] fix #90: add a ble_error_t paramter to initializationCompletionCallback --- ble/BLE.h | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/ble/BLE.h b/ble/BLE.h index 8654f7a..00bce18 100644 --- a/ble/BLE.h +++ b/ble/BLE.h @@ -38,8 +38,19 @@ class BLEInstanceBase; class BLE { public: - typedef unsigned InstanceID_t; - typedef void (*InitializationCompleteCallback_t)(BLE &bleInstance); + typedef unsigned InstanceID_t; /** The type returned by BLE::getInstanceID(). */ + + /** + * The function signature for callbacks for initialization completion. + * @param ble + * A reference to the BLE instance being initialized. + * @param error + * This captures the result of initialization. It is set to + * BLE_ERROR_NONE if initialization completed successfully. Else + * the error value is implementation specific. + * + */ + typedef void (*InitializationCompleteCallback_t)(BLE &ble, ble_error_t error); /** * Initialize the BLE controller. This should be called before using @@ -61,6 +72,12 @@ public: * @return BLE_ERROR_NONE if the initialization procedure was started * successfully. * + * @note The underlying stack must invoke the initialization completion + * callback in response to init(). In some cases, initialization is + * instantaneous (or blocking); if so, it is acceptable for the stack- + * specific implementation of init() to invoke the completion callback + * directly--i.e. within its own context. + * * @note Nearly all BLE APIs would return * BLE_ERROR_INITIALIZATION_INCOMPLETE if used on an instance before the * corresponding transport is initialized. From 902e17e3007c71bc1033ec92546478765cf286d0 Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Wed, 28 Oct 2015 12:53:57 +0000 Subject: [PATCH 18/24] version v1.1.0 --- module.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module.json b/module.json index ed94418..d515da2 100644 --- a/module.json +++ b/module.json @@ -1,6 +1,6 @@ { "name": "ble", - "version": "1.0.0", + "version": "1.1.0", "description": "The BLE module offers a high level abstraction for using Bluetooth Low Energy on multiple platforms.", "keywords": [ "Bluetooth", From 976bcd4e614fdececf72db769a5e99cbd8d43a4c Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Thu, 29 Oct 2015 11:25:27 +0000 Subject: [PATCH 19/24] Introduced fixes to Eddystone implementation Fixed wrong memcpy arguments that caused the wrong number of bytes to be copied and merged energy saving changes. --- ble/services/EddystoneConfigService.h | 4 ++-- ble/services/EddystoneService.h | 18 ++++++++---------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/ble/services/EddystoneConfigService.h b/ble/services/EddystoneConfigService.h index 94d6067..1d39824 100644 --- a/ble/services/EddystoneConfigService.h +++ b/ble/services/EddystoneConfigService.h @@ -285,7 +285,7 @@ public: ble.setTxPower(radioPowerLevels[params.txPowerMode]); ble.setDeviceName(reinterpret_cast(&DEVICE_NAME)); ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); - ble.setAdvertisingInterval(GapAdvertisingParams::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(ADVERTISING_INTERVAL_MSEC)); + ble.setAdvertisingInterval(ADVERTISING_INTERVAL_MSEC); } /* @@ -340,7 +340,7 @@ private: } else if (handle == uriDataChar.getValueHandle()) { params.uriDataLength = writeParams->len; memset(params.uriData, 0x00, URI_DATA_MAX); // clear URI string - memcpy(params.uriData, writeParams->data, params.uriDataLength); // set URI string + memcpy(params.uriData, writeParams->data, writeParams->len); // set URI string params.uriEnabled = true; INFO("URI = %s, URILen = %d", writeParams->data, writeParams->len); } else if (handle == flagsChar.getValueHandle()) { diff --git a/ble/services/EddystoneService.h b/ble/services/EddystoneService.h index aa24a6c..a3c1bd0 100644 --- a/ble/services/EddystoneService.h +++ b/ble/services/EddystoneService.h @@ -260,6 +260,10 @@ public: * @return number of bytes used. negative number indicates error message. */ int constructTLMFrame(uint8_t *Data, uint8_t maxSize) { + uint32_t now = timeSinceBootTimer.read_ms(); + TlmTimeSinceBoot += (now - lastBootTimerRead) / 100; + lastBootTimerRead = now; + int index = 0; Data[index++] = FRAME_TYPE_TLM; // Eddystone frame type = Telemetry Data[index++] = TlmVersion; // TLM Version Number @@ -315,14 +319,6 @@ public: TlmTimeSinceBoot = timeSinceBoot; } - /* - * callback function, called every 0.1s, incriments the TimeSinceBoot field in the TLM frame - * @return nothing - */ - void tsbCallback(void) { - TlmTimeSinceBoot++; - } - /* * Update advertising data * @return true on success, false on failure @@ -524,7 +520,8 @@ public: // Make double sure the PDUCount and TimeSinceBoot fields are set to zero at reset updateTlmPduCount(0); updateTlmTimeSinceBoot(0); - timeSinceBootTick.attach(this, &EddystoneService::tsbCallback, 0.1); // incriment the TimeSinceBoot ticker every 0.1s + lastBootTimerRead = 0; + timeSinceBootTimer.start(); tlmTicker.attach(this, &EddystoneService::tlmCallback, TlmAdvPeriod); DBG("attached tlmCallback every %d seconds", TlmAdvPeriod); } @@ -543,7 +540,8 @@ private: BLEDevice &ble; uint16_t advPeriodus; uint8_t txPower; - Ticker timeSinceBootTick; // counter that counts time since boot + Timer timeSinceBootTimer; + volatile uint32_t lastBootTimerRead; volatile bool advLock; volatile FrameTypes frameIndex; Timeout stopAdv; From ec545b79dc00eba96d14e3935e632ab43a282140 Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Thu, 29 Oct 2015 12:59:02 +0000 Subject: [PATCH 20/24] cosmetic changes. --- ble/Gap.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ble/Gap.h b/ble/Gap.h index 06793e9..66165b1 100644 --- a/ble/Gap.h +++ b/ble/Gap.h @@ -867,8 +867,8 @@ private: } private: - virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &) = 0; - virtual ble_error_t startAdvertising(const GapAdvertisingParams &) = 0; + virtual ble_error_t setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse) = 0; + virtual ble_error_t startAdvertising(const GapAdvertisingParams &) = 0; public: /** From 45e80c8ba8e91d0246c336d012399584451c5857 Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Fri, 30 Oct 2015 09:23:40 +0000 Subject: [PATCH 21/24] white space diffs; mostly alignment --- ble/services/EnvironmentalService.h | 52 ++++++++++++++--------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/ble/services/EnvironmentalService.h b/ble/services/EnvironmentalService.h index 990d7cb..dbff2df 100644 --- a/ble/services/EnvironmentalService.h +++ b/ble/services/EnvironmentalService.h @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + #ifndef __BLE_ENVIRONMENTAL_SERVICE_H__ #define __BLE_ENVIRONMENTAL_SERVICE_H__ #include "ble/BLE.h" - /** +/** * @class EnvironmentalService * @brief BLE Environmental Service. This service provides the location of the thermometer and the temperature.
* Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.environmental_sensing.xml
@@ -42,21 +42,21 @@ public: bool pressure_en = false) : ble(_ble), temperatureCharacteristic(GattCharacteristic::UUID_TEMPERATURE_CHAR, - (uint8_t *) &temperature, - (temperature_en) ? 2 : 0, // minLength - (temperature_en) ? 2 : 0, // maxLength - GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), + (uint8_t *) &temperature, + (temperature_en) ? 2 : 0, // minLength + (temperature_en) ? 2 : 0, // maxLength + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), humidityCharacteristic(GattCharacteristic::UUID_HUMIDITY_CHAR, - (uint8_t *) &humidity, - (humidity_en) ? 2 : 0, // minLength - (humidity_en) ? 2 : 0, // maxLength - GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), + (uint8_t *) &humidity, + (humidity_en) ? 2 : 0, // minLength + (humidity_en) ? 2 : 0, // maxLength + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), pressureCharacteristic(GattCharacteristic::UUID_PRESSURE_CHAR, - (uint8_t *) &pressure, - (pressure_en) ? 4 : 0, // minLength - (pressure_en) ? 4 : 0, // maxLength - GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ) - { + (uint8_t *) &pressure, + (pressure_en) ? 4 : 0, // minLength + (pressure_en) ? 4 : 0, // maxLength + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ) + { static bool serviceAdded = false; /* We should only ever need to add the information service once. */ if (serviceAdded) { return; @@ -66,9 +66,9 @@ public: &pressureCharacteristic, &temperatureCharacteristic }; - GattService environmentalService(GattService::UUID_ENVIRONMENTAL_SERVICE, charTable, - sizeof(charTable) / sizeof(GattCharacteristic *)); - + GattService environmentalService(GattService::UUID_ENVIRONMENTAL_SERVICE, charTable, + sizeof(charTable) / sizeof(GattCharacteristic *)); + ble.gattServer().addService(environmentalService); serviceAdded = true; } @@ -79,7 +79,7 @@ public: */ void updateHumidity(uint16_t newHumidityVal) { - humidity = (uint32_t) (newHumidityVal*100); + humidity = (uint32_t) (newHumidityVal * 100); ble.gattServer().write(humidityCharacteristic.getValueHandle(), (uint8_t *) &humidity, 2); } @@ -89,7 +89,7 @@ public: */ void updatePressure(uint32_t newPressureVal) { - pressure = (uint32_t) (newPressureVal*10); + pressure = (uint32_t) (newPressureVal * 10); ble.gattServer().write(pressureCharacteristic.getValueHandle(), (uint8_t *) &pressure, 4); } @@ -99,19 +99,19 @@ public: */ void updateTemperature(float newTemperatureVal) { - temperature = (int16_t) (newTemperatureVal*100); + temperature = (int16_t) (newTemperatureVal * 100); ble.gattServer().write(temperatureCharacteristic.getValueHandle(), (uint8_t *) &temperature, 2); } private: - BLE &ble; + BLE & ble; - int16_t temperature; + int16_t temperature; GattCharacteristic temperatureCharacteristic; - uint16_t humidity; + uint16_t humidity; GattCharacteristic humidityCharacteristic; - uint32_t pressure; + uint32_t pressure; GattCharacteristic pressureCharacteristic; }; -#endif /* #ifndef __BLE_ENVIRONMENTAL_SERVICE_H__*/ \ No newline at end of file +#endif /* #ifndef __BLE_ENVIRONMENTAL_SERVICE_H__*/ From bdc1ca08cd2116d9c19998a75d37cfa421049ab8 Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Fri, 30 Oct 2015 09:41:28 +0000 Subject: [PATCH 22/24] introduce types for temperature/humidity/pressure. --- ble/services/EnvironmentalService.h | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/ble/services/EnvironmentalService.h b/ble/services/EnvironmentalService.h index dbff2df..8ad5073 100644 --- a/ble/services/EnvironmentalService.h +++ b/ble/services/EnvironmentalService.h @@ -29,6 +29,10 @@ */ class EnvironmentalService { public: + typedef int16_t TemperatureType_t; + typedef uint16_t HumidityType_t; + typedef uint32_t PressureType_t; + /** * @brief EnvironmentalService constructor. * @param ble Reference to BLE device. @@ -77,20 +81,20 @@ public: * @brief Update humidity characteristic. * @param newHumidityVal New humidity measurement. */ - void updateHumidity(uint16_t newHumidityVal) + void updateHumidity(HumidityType_t newHumidityVal) { - humidity = (uint32_t) (newHumidityVal * 100); - ble.gattServer().write(humidityCharacteristic.getValueHandle(), (uint8_t *) &humidity, 2); + humidity = (HumidityType_t) (newHumidityVal * 100); + ble.gattServer().write(humidityCharacteristic.getValueHandle(), (uint8_t *) &humidity, sizeof(HumidityType_t)); } /** * @brief Update pressure characteristic. * @param newPressureVal New pressure measurement. */ - void updatePressure(uint32_t newPressureVal) + void updatePressure(PressureType_t newPressureVal) { - pressure = (uint32_t) (newPressureVal * 10); - ble.gattServer().write(pressureCharacteristic.getValueHandle(), (uint8_t *) &pressure, 4); + pressure = (PressureType_t) (newPressureVal * 10); + ble.gattServer().write(pressureCharacteristic.getValueHandle(), (uint8_t *) &pressure, sizeof(PressureType_t)); } /** @@ -99,8 +103,8 @@ public: */ void updateTemperature(float newTemperatureVal) { - temperature = (int16_t) (newTemperatureVal * 100); - ble.gattServer().write(temperatureCharacteristic.getValueHandle(), (uint8_t *) &temperature, 2); + temperature = (TemperatureType_t) (newTemperatureVal * 100); + ble.gattServer().write(temperatureCharacteristic.getValueHandle(), (uint8_t *) &temperature, sizeof(TemperatureType_t)); } private: From be09e516984716de27f1b32ffb4bd32b449aec21 Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Fri, 30 Oct 2015 09:42:56 +0000 Subject: [PATCH 23/24] use types like ReadOnlyGattCharacteristic --- ble/services/EnvironmentalService.h | 41 +++++++++-------------------- 1 file changed, 13 insertions(+), 28 deletions(-) diff --git a/ble/services/EnvironmentalService.h b/ble/services/EnvironmentalService.h index 8ad5073..d9ef455 100644 --- a/ble/services/EnvironmentalService.h +++ b/ble/services/EnvironmentalService.h @@ -40,26 +40,11 @@ public: * @param humidity_en Enable this characteristic. * @param pressure_en Enable this characteristic. */ - EnvironmentalService(BLE &_ble, - bool temperature_en = false, - bool humidity_en = false, - bool pressure_en = false) : + EnvironmentalService(BLE& _ble) : ble(_ble), - temperatureCharacteristic(GattCharacteristic::UUID_TEMPERATURE_CHAR, - (uint8_t *) &temperature, - (temperature_en) ? 2 : 0, // minLength - (temperature_en) ? 2 : 0, // maxLength - GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), - humidityCharacteristic(GattCharacteristic::UUID_HUMIDITY_CHAR, - (uint8_t *) &humidity, - (humidity_en) ? 2 : 0, // minLength - (humidity_en) ? 2 : 0, // maxLength - GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), - pressureCharacteristic(GattCharacteristic::UUID_PRESSURE_CHAR, - (uint8_t *) &pressure, - (pressure_en) ? 4 : 0, // minLength - (pressure_en) ? 4 : 0, // maxLength - GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ) + temperatureCharacteristic(GattCharacteristic::UUID_TEMPERATURE_CHAR, &temperature), + humidityCharacteristic(GattCharacteristic::UUID_HUMIDITY_CHAR, &humidity), + pressureCharacteristic(GattCharacteristic::UUID_PRESSURE_CHAR, &pressure) { static bool serviceAdded = false; /* We should only ever need to add the information service once. */ if (serviceAdded) { @@ -70,8 +55,7 @@ public: &pressureCharacteristic, &temperatureCharacteristic }; - GattService environmentalService(GattService::UUID_ENVIRONMENTAL_SERVICE, charTable, - sizeof(charTable) / sizeof(GattCharacteristic *)); + GattService environmentalService(GattService::UUID_ENVIRONMENTAL_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); ble.gattServer().addService(environmentalService); serviceAdded = true; @@ -108,14 +92,15 @@ public: } private: - BLE & ble; + BLE& ble; - int16_t temperature; - GattCharacteristic temperatureCharacteristic; - uint16_t humidity; - GattCharacteristic humidityCharacteristic; - uint32_t pressure; - GattCharacteristic pressureCharacteristic; + TemperatureType_t temperature; + HumidityType_t humidity; + PressureType_t pressure; + + ReadOnlyGattCharacteristic temperatureCharacteristic; + ReadOnlyGattCharacteristic humidityCharacteristic; + ReadOnlyGattCharacteristic pressureCharacteristic; }; #endif /* #ifndef __BLE_ENVIRONMENTAL_SERVICE_H__*/ From 2f92904fbe06cea582a46bdbe03f73388afaff24 Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Fri, 30 Oct 2015 15:18:02 +0000 Subject: [PATCH 24/24] Release 2.0.0 ============= * Major change to the APIs around stack initialization. BLE::init() is now meant to only trigger the initialization of the underlying BLE stack. init() now takes a completion callback as an optional parameter; this callback gets invoked when initialization completes. - There's a new type: BLE::InitializationCompleteCallback_t - There's a new API: BLEInstanceBase::hasInitialized() which transports need to implement. - If no init-completion callback is setup, the application can still determine the status of initialization using BLE::hasInitialized(). !This update may require in a minor change to existing apps! mbed-classic demos would look something like: ``` main() { BLE::Instance().init(); while (!BLE::Instance().hasInitialized()) { /* spin wait */ } /* rest of the initialization ending in the waitForEvent loop */ } ``` whereas mbedOS demos would look like: ``` void bleInitComplete(BLE &ble, ble_error_t error) { WsfTrace("bleInitComplete"); if (error != BLE_ERROR_NONE) { WsfTrace("initailization failed with error: %u", error); return; } if (ble.getInstanceID() == BLE::DEFAULT_INSTANCE) { /* use the BLE instance */ } } extern "C" void app_start(int argc, char *argv[]) { BLE::Instance().init(bleInitComplete); } ``` The Nordic stack initializes right-away, and so existing demos based on Nordic should continue to work. * There's a new API: BLE::getInstanceID(), which simply returns the ID of an instance. * Reduce the memory footprint consumed by a FunctionPointerWithContext to 20 bytes (originally, it was 32 bytes !). Also enforce alignment constraints of the embedded pointer to member function. This should help with the size of a GattCharacteristic. * Add EnvironmentalService.h under services/. * There have been minor improvements to EddystoneService and EddystoneConfigService. * We've added a CONTRIBUTING.md to help guide user contributions. --- CONTRIBUTING.md | 7 +++++++ module.json | 6 +++--- 2 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..4b9f4ce --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,7 @@ +# Hello! +We are an open source project of [ARM mbed](www.mbed.com). Contributions via [pull request](https://github.com/armmbed/yotta/pulls), and [bug reports](https://github.com/armmbed/yotta/issues) are welcome! + +Please submit your pull request to the 'develop' branch of this module. Commits to develop will merge into master at the time of the next release. + +# Contributor agreement +For your pull request to be accepted, we will need you to agree to our [contributor agreement](http://developer.mbed.org/contributor_agreement/) to give us the necessary rights to use and distribute your contributions. (To click through the agreement create an account on mbed.com and log in.) diff --git a/module.json b/module.json index 9db338b..5f13f41 100644 --- a/module.json +++ b/module.json @@ -1,6 +1,6 @@ { "name": "ble", - "version": "1.1.0", + "version": "2.0.0", "description": "The BLE module offers a high level abstraction for using Bluetooth Low Energy on multiple platforms.", "keywords": [ "Bluetooth", @@ -26,10 +26,10 @@ "x-nucleo-idb0xa1": "ARMmbed/ble-x-nucleo-idb0xa1" }, "nrf51822": { - "ble-nrf51822": "^1.0.0" + "ble-nrf51822": "^2.0.0" }, "cordio": { - "ble-wicentric": "~0.0.0" + "ble-wicentric": "~0.0.4" }, "mbed-classic": { "mbed-classic": "~0.0.1"