From b817cf3e57cecece4ce92a03d1bd1375a6d2dc64 Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Fri, 11 Dec 2015 18:00:17 +0000 Subject: [PATCH 01/27] Improve API to facilitate full shutdown procedure The BLE API exposes a shutdown() function in BLE.h. This function is meant to be overwridden by platform-specific sub-classes to clear all GAP and GATT state. However, from the platform-specific implementation it is dificult to achieve this because the Gap, GattClient, GattServer and SecurityManager components of the API do not expose any functionality to shutdown. This commit introduces the following changes: * Add a static member pointer to Gap, GattClient, GattServer and SecurityManager that is used to keep track of the initialized objects. * Add a function member cleanup() to Gap, GattClient, GattServer and SecurityManager to allow easy reset of the instance's state. This function is meant to be overriden and called from the derived classes to fully clear the state of the BLE API and the platform-specific implementation. * Add a static member function shutdown() to Gap, GattClient, GattServer and SecurityManager. This function shall be called from the shutdown() overriding BLE::shutdown() for Gap, GattClient, GattServer and SecurityManager that will in-turn clear the state of each of the components. **NOTE:** Platform-specific implementations of this API must be modified to this changes into account. --- ble/Gap.h | 52 ++++++++++++++++++++++++++++++++++++++ ble/GattClient.h | 44 ++++++++++++++++++++++++++++++++ ble/GattServer.h | 50 ++++++++++++++++++++++++++++++++++++ ble/SecurityManager.h | 47 ++++++++++++++++++++++++++++++++++ ble/ServiceDiscovery.h | 21 +++++++++++++++ source/Gap.cpp | 19 ++++++++++++++ source/GattClient.cpp | 19 ++++++++++++++ source/GattServer.cpp | 19 ++++++++++++++ source/SecurityManager.cpp | 19 ++++++++++++++ 9 files changed, 290 insertions(+) create mode 100644 source/Gap.cpp create mode 100644 source/GattClient.cpp create mode 100644 source/GattServer.cpp create mode 100644 source/SecurityManager.cpp diff --git a/ble/Gap.h b/ble/Gap.h index dfa07c1..05bf290 100644 --- a/ble/Gap.h +++ b/ble/Gap.h @@ -983,6 +983,54 @@ public: radioNotificationCallback.attach(tptr, mptr); } +protected: + /** + * Clear all Gap state of the associated object. + * + * This function is meant to be overridden in the platform-specific + * sub-class. Nevertheless, the sub-class is only expected to clean up its + * state and not the data held in Gap members. This shall be achieved by a + * call to Gap::cleanup() from the sub-class' cleanup() implementation. + * + * @return BLE_ERROR_NONE on success. + * + * @note: Currently a call to cleanup() does not reset the advertising and + * scan parameters to default values. + */ + virtual ble_error_t cleanup(void) { + /* Clear Gap state */ + state.advertising = 0; + state.connected = 0; + + /* Clear scanning state */ + scanningActive = false; + + /* Clear advertising and scanning data */ + _advPayload.clear(); + _scanResponse.clear(); + + return BLE_ERROR_NONE; + } + +public: + /** + * Clear all Gap state of the object pointed to by gapInstance. + * + * This function is meant to be called by the overridden BLE::shutdown() + * in the platform-specific sub-class. + * + * @return BLE_ERROR_NONE on success. + * + * @note: If gapInstance is NULL then it is assumed that Gap has not been + * instantiated and a call to Gap::shutdown() will succeed. + */ + static ble_error_t shutdown(void) { + if (gapInstance) { + return gapInstance->cleanup(); + } + return BLE_ERROR_NONE; + } + protected: Gap() : _advParams(), @@ -1051,6 +1099,10 @@ protected: GapState_t state; bool scanningActive; +protected: + static Gap *gapInstance; /**< Pointer to the Gap object instance. + * If NULL, then Gap has not been initialized. */ + protected: TimeoutEventCallbackChain_t timeoutCallbackChain; RadioNotificationEventCallback_t radioNotificationCallback; diff --git a/ble/GattClient.h b/ble/GattClient.h index a4109d3..e05698c 100644 --- a/ble/GattClient.h +++ b/ble/GattClient.h @@ -325,6 +325,46 @@ public: return onHVXCallbackChain; } +protected: + /** + * Clear all GattClient state of the associated object. + * + * This function is meant to be overridden in the platform-specific + * sub-class. Nevertheless, the sub-class is only expected to clean up its + * state and not the data held in GattClient members. This shall be achieved + * by a call to GattClient::cleanup() from the sub-class' cleanup() + * implementation. + * + * @return BLE_ERROR_NONE on success. + */ + virtual ble_error_t cleanup(void) { + onDataReadCallbackChain.clear(); + onDataWriteCallbackChain.clear(); + onHVXCallbackChain.clear(); + + return BLE_ERROR_NONE; + } + +public: + /** + * Clear all GattClient state of the object pointed to by + * gattClientInstance. + * + * This function is meant to be called by the overridden BLE::shutdown() + * in the platform-specific sub-class. + * + * @return BLE_ERROR_NONE on success. + * + * @note: If gattClientInstance is NULL then it is assumed that Gap has not + * been instantiated and a call to GattClient::shutdown() will succeed. + */ + static ble_error_t shutdown(void) { + if (gattClientInstance) { + return gattClientInstance->cleanup(); + } + return BLE_ERROR_NONE; + } + protected: GattClient() { /* Empty */ @@ -351,6 +391,10 @@ protected: WriteCallbackChain_t onDataWriteCallbackChain; HVXCallbackChain_t onHVXCallbackChain; +protected: + static GattClient *gattClientInstance; /**< Pointer to the GattClient object instance. + * If NULL, then GattClient has not been initialized. */ + private: /* Disallow copy and assignment. */ GattClient(const GattClient &); diff --git a/ble/GattServer.h b/ble/GattServer.h index 6a6324b..3485158 100644 --- a/ble/GattServer.h +++ b/ble/GattServer.h @@ -396,10 +396,60 @@ protected: dataSentCallChain.call(count); } +protected: + /** + * Clear all GattServer state of the associated object. + * + * This function is meant to be overridden in the platform-specific + * sub-class. Nevertheless, the sub-class is only expected to clean up its + * state and not the data held in GattServer members. This shall be achieved + * by a call to GattServer::cleanup() from the sub-class' cleanup() + * implementation. + * + * @return BLE_ERROR_NONE on success. + */ + virtual ble_error_t cleanup(void) { + serviceCount = 0; + characteristicCount = 0; + + dataSentCallChain.clear(); + dataWrittenCallChain.clear(); + dataReadCallChain.clear(); + updatesEnabledCallback = NULL; + updatesDisabledCallback = NULL; + confirmationReceivedCallback = NULL; + + return BLE_ERROR_NONE; + } + +public: + /** + * Clear all GattServer state of the object pointed to by + * gattServerInstance. + * + * This function is meant to be called by the overridden BLE::shutdown() + * in the platform-specific sub-class. + * + * @return BLE_ERROR_NONE on success. + * + * @note: If gattServerInstance is NULL then it is assumed that Gap has not + * been instantiated and a call to GattServer::shutdown() will succeed. + */ + static ble_error_t shutdown(void) { + if (gattServerInstance) { + return gattServerInstance->cleanup(); + } + return BLE_ERROR_NONE; + } + protected: uint8_t serviceCount; uint8_t characteristicCount; +protected: + static GattServer *gattServerInstance; /**< Pointer to the GattServer object instance. + * If NULL, then GattServer has not been initialized. */ + private: DataSentCallbackChain_t dataSentCallChain; DataWrittenCallbackChain_t dataWrittenCallChain; diff --git a/ble/SecurityManager.h b/ble/SecurityManager.h index 444e3aa..b80a410 100644 --- a/ble/SecurityManager.h +++ b/ble/SecurityManager.h @@ -231,6 +231,53 @@ protected: /* empty */ } +protected: + /** + * Clear all SecurityManager state of the associated object. + * + * This function is meant to be overridden in the platform-specific + * sub-class. Nevertheless, the sub-class is only expected to clean up its + * state and not the data held in SecurityManager members. This shall be + * achieved by a call to SecurityManager::cleanup() from the sub-class' + * cleanup() implementation. + * + * @return BLE_ERROR_NONE on success. + */ + virtual ble_error_t cleanup(void) { + securitySetupInitiatedCallback = NULL; + securitySetupCompletedCallback = NULL; + linkSecuredCallback = NULL; + securityContextStoredCallback = NULL; + passkeyDisplayCallback = NULL; + + return BLE_ERROR_NONE; + } + +public: + /** + * Clear all SecurityManager state of the object pointed to by + * securityManagerInstance. + * + * This function is meant to be called by the overridden BLE::shutdown() + * in the platform-specific sub-class. + * + * @return BLE_ERROR_NONE on success. + * + * @note: If securityManagerInstance is NULL then it is assumed that Gap has + * not been instantiated and a call to SecurityManager::shutdown() will + * succeed. + */ + static ble_error_t shutdown(void) { + if (securityManagerInstance) { + return securityManagerInstance->cleanup(); + } + return BLE_ERROR_NONE; + } + +protected: + static SecurityManager *securityManagerInstance; /**< Pointer to the SecurityManager object instance. + * If NULL, then SecurityManager has not been initialized. */ + protected: SecuritySetupInitiatedCallback_t securitySetupInitiatedCallback; SecuritySetupCompletedCallback_t securitySetupCompletedCallback; diff --git a/ble/ServiceDiscovery.h b/ble/ServiceDiscovery.h index 595bc20..89ad140 100644 --- a/ble/ServiceDiscovery.h +++ b/ble/ServiceDiscovery.h @@ -132,6 +132,27 @@ public: */ virtual void onTermination(TerminationCallback_t callback) = 0; + /** + * Clear all ServiceDiscovery state of the associated object. + * + * This function is meant to be overridden in the platform-specific + * sub-class. Nevertheless, the sub-class is only expected to clean up its + * state and not the data held in ServiceDiscovery members. This shall be + * achieved by a call to ServiceDiscovery::cleanup() from the sub-class' + * cleanup() implementation. + * + * @return BLE_ERROR_NONE on success. + */ + virtual ble_error_t cleanup(void) { + connHandle = 0; + matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN); + serviceCallback = NULL; + matchingCharacteristicUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN); + characteristicCallback = NULL; + + return BLE_ERROR_NONE; + } + protected: Gap::Handle_t connHandle; /**< Connection handle as provided by the SoftDevice. */ UUID matchingServiceUUID; diff --git a/source/Gap.cpp b/source/Gap.cpp new file mode 100644 index 0000000..17a50c5 --- /dev/null +++ b/source/Gap.cpp @@ -0,0 +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. + */ + +#include "ble/Gap.h" + +Gap *Gap::gapInstance = NULL; diff --git a/source/GattClient.cpp b/source/GattClient.cpp new file mode 100644 index 0000000..5186e7c --- /dev/null +++ b/source/GattClient.cpp @@ -0,0 +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. + */ + +#include "ble/GattClient.h" + +GattClient *GattClient::gattClientInstance = NULL; diff --git a/source/GattServer.cpp b/source/GattServer.cpp new file mode 100644 index 0000000..35c475d --- /dev/null +++ b/source/GattServer.cpp @@ -0,0 +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. + */ + +#include "ble/GattServer.h" + +GattServer *GattServer::gattServerInstance = NULL; diff --git a/source/SecurityManager.cpp b/source/SecurityManager.cpp new file mode 100644 index 0000000..f36026a --- /dev/null +++ b/source/SecurityManager.cpp @@ -0,0 +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. + */ + +#include "ble/SecurityManager.h" + +SecurityManager *SecurityManager::securityManagerInstance = NULL; From cd809e2a2c9d9a1aaba758d477b44196a0561e4e Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Mon, 14 Dec 2015 15:34:38 +0000 Subject: [PATCH 02/27] Modify shutdown API and functionality Modify the shutdown API to remove the static shutdown function in Gap, SecurityManager, GattClient and GattServer. Futhermore, remove the static references to Gap, SecurityManager, GattClient and GattServer objects inside their own classes. The cleanup method is renamed to `reset()` and made public. Finally, additional functionality is added to the reset implementation in Gap. --- ble/Gap.h | 38 +++++++++++--------------------------- ble/GattClient.h | 32 ++++---------------------------- ble/GattServer.h | 32 ++++---------------------------- ble/SecurityManager.h | 35 +++++------------------------------ ble/ServiceDiscovery.h | 8 ++++---- source/BLE.cpp | 1 - source/Gap.cpp | 19 ------------------- source/GattClient.cpp | 19 ------------------- source/GattServer.cpp | 19 ------------------- source/SecurityManager.cpp | 19 ------------------- 10 files changed, 28 insertions(+), 194 deletions(-) delete mode 100644 source/Gap.cpp delete mode 100644 source/GattClient.cpp delete mode 100644 source/GattServer.cpp delete mode 100644 source/SecurityManager.cpp diff --git a/ble/Gap.h b/ble/Gap.h index 05bf290..8accfaa 100644 --- a/ble/Gap.h +++ b/ble/Gap.h @@ -983,21 +983,21 @@ public: radioNotificationCallback.attach(tptr, mptr); } -protected: +public: /** * Clear all Gap state of the associated object. * * This function is meant to be overridden in the platform-specific - * sub-class. Nevertheless, the sub-class is only expected to clean up its + * sub-class. Nevertheless, the sub-class is only expected to reset its * state and not the data held in Gap members. This shall be achieved by a - * call to Gap::cleanup() from the sub-class' cleanup() implementation. + * call to Gap::reset() from the sub-class' reset() implementation. * * @return BLE_ERROR_NONE on success. * - * @note: Currently a call to cleanup() does not reset the advertising and + * @note: Currently a call to reset() does not reset the advertising and * scan parameters to default values. */ - virtual ble_error_t cleanup(void) { + virtual ble_error_t reset(void) { /* Clear Gap state */ state.advertising = 0; state.connected = 0; @@ -1009,25 +1009,13 @@ protected: _advPayload.clear(); _scanResponse.clear(); - return BLE_ERROR_NONE; - } + /* Clear callbacks */ + timeoutCallbackChain.clear(); + connectionCallChain.clear(); + disconnectionCallChain.clear(); + radioNotificationCallback = NULL; + onAdvertisementReport = NULL; -public: - /** - * Clear all Gap state of the object pointed to by gapInstance. - * - * This function is meant to be called by the overridden BLE::shutdown() - * in the platform-specific sub-class. - * - * @return BLE_ERROR_NONE on success. - * - * @note: If gapInstance is NULL then it is assumed that Gap has not been - * instantiated and a call to Gap::shutdown() will succeed. - */ - static ble_error_t shutdown(void) { - if (gapInstance) { - return gapInstance->cleanup(); - } return BLE_ERROR_NONE; } @@ -1099,10 +1087,6 @@ protected: GapState_t state; bool scanningActive; -protected: - static Gap *gapInstance; /**< Pointer to the Gap object instance. - * If NULL, then Gap has not been initialized. */ - protected: TimeoutEventCallbackChain_t timeoutCallbackChain; RadioNotificationEventCallback_t radioNotificationCallback; diff --git a/ble/GattClient.h b/ble/GattClient.h index e05698c..1df6066 100644 --- a/ble/GattClient.h +++ b/ble/GattClient.h @@ -325,19 +325,19 @@ public: return onHVXCallbackChain; } -protected: +public: /** * Clear all GattClient state of the associated object. * * This function is meant to be overridden in the platform-specific - * sub-class. Nevertheless, the sub-class is only expected to clean up its + * sub-class. Nevertheless, the sub-class is only expected to reset its * state and not the data held in GattClient members. This shall be achieved - * by a call to GattClient::cleanup() from the sub-class' cleanup() + * by a call to GattClient::reset() from the sub-class' reset() * implementation. * * @return BLE_ERROR_NONE on success. */ - virtual ble_error_t cleanup(void) { + virtual ble_error_t reset(void) { onDataReadCallbackChain.clear(); onDataWriteCallbackChain.clear(); onHVXCallbackChain.clear(); @@ -345,26 +345,6 @@ protected: return BLE_ERROR_NONE; } -public: - /** - * Clear all GattClient state of the object pointed to by - * gattClientInstance. - * - * This function is meant to be called by the overridden BLE::shutdown() - * in the platform-specific sub-class. - * - * @return BLE_ERROR_NONE on success. - * - * @note: If gattClientInstance is NULL then it is assumed that Gap has not - * been instantiated and a call to GattClient::shutdown() will succeed. - */ - static ble_error_t shutdown(void) { - if (gattClientInstance) { - return gattClientInstance->cleanup(); - } - return BLE_ERROR_NONE; - } - protected: GattClient() { /* Empty */ @@ -391,10 +371,6 @@ protected: WriteCallbackChain_t onDataWriteCallbackChain; HVXCallbackChain_t onHVXCallbackChain; -protected: - static GattClient *gattClientInstance; /**< Pointer to the GattClient object instance. - * If NULL, then GattClient has not been initialized. */ - private: /* Disallow copy and assignment. */ GattClient(const GattClient &); diff --git a/ble/GattServer.h b/ble/GattServer.h index 3485158..73a75c1 100644 --- a/ble/GattServer.h +++ b/ble/GattServer.h @@ -396,19 +396,19 @@ protected: dataSentCallChain.call(count); } -protected: +public: /** * Clear all GattServer state of the associated object. * * This function is meant to be overridden in the platform-specific - * sub-class. Nevertheless, the sub-class is only expected to clean up its + * sub-class. Nevertheless, the sub-class is only expected to reset its * state and not the data held in GattServer members. This shall be achieved - * by a call to GattServer::cleanup() from the sub-class' cleanup() + * by a call to GattServer::reset() from the sub-class' reset() * implementation. * * @return BLE_ERROR_NONE on success. */ - virtual ble_error_t cleanup(void) { + virtual ble_error_t reset(void) { serviceCount = 0; characteristicCount = 0; @@ -422,34 +422,10 @@ protected: return BLE_ERROR_NONE; } -public: - /** - * Clear all GattServer state of the object pointed to by - * gattServerInstance. - * - * This function is meant to be called by the overridden BLE::shutdown() - * in the platform-specific sub-class. - * - * @return BLE_ERROR_NONE on success. - * - * @note: If gattServerInstance is NULL then it is assumed that Gap has not - * been instantiated and a call to GattServer::shutdown() will succeed. - */ - static ble_error_t shutdown(void) { - if (gattServerInstance) { - return gattServerInstance->cleanup(); - } - return BLE_ERROR_NONE; - } - protected: uint8_t serviceCount; uint8_t characteristicCount; -protected: - static GattServer *gattServerInstance; /**< Pointer to the GattServer object instance. - * If NULL, then GattServer has not been initialized. */ - private: DataSentCallbackChain_t dataSentCallChain; DataWrittenCallbackChain_t dataWrittenCallChain; diff --git a/ble/SecurityManager.h b/ble/SecurityManager.h index b80a410..75ed860 100644 --- a/ble/SecurityManager.h +++ b/ble/SecurityManager.h @@ -231,19 +231,19 @@ protected: /* empty */ } -protected: +public: /** * Clear all SecurityManager state of the associated object. * * This function is meant to be overridden in the platform-specific - * sub-class. Nevertheless, the sub-class is only expected to clean up its + * sub-class. Nevertheless, the sub-class is only expected to reset its * state and not the data held in SecurityManager members. This shall be - * achieved by a call to SecurityManager::cleanup() from the sub-class' - * cleanup() implementation. + * achieved by a call to SecurityManager::reset() from the sub-class' + * reset() implementation. * * @return BLE_ERROR_NONE on success. */ - virtual ble_error_t cleanup(void) { + virtual ble_error_t reset(void) { securitySetupInitiatedCallback = NULL; securitySetupCompletedCallback = NULL; linkSecuredCallback = NULL; @@ -253,31 +253,6 @@ protected: return BLE_ERROR_NONE; } -public: - /** - * Clear all SecurityManager state of the object pointed to by - * securityManagerInstance. - * - * This function is meant to be called by the overridden BLE::shutdown() - * in the platform-specific sub-class. - * - * @return BLE_ERROR_NONE on success. - * - * @note: If securityManagerInstance is NULL then it is assumed that Gap has - * not been instantiated and a call to SecurityManager::shutdown() will - * succeed. - */ - static ble_error_t shutdown(void) { - if (securityManagerInstance) { - return securityManagerInstance->cleanup(); - } - return BLE_ERROR_NONE; - } - -protected: - static SecurityManager *securityManagerInstance; /**< Pointer to the SecurityManager object instance. - * If NULL, then SecurityManager has not been initialized. */ - protected: SecuritySetupInitiatedCallback_t securitySetupInitiatedCallback; SecuritySetupCompletedCallback_t securitySetupCompletedCallback; diff --git a/ble/ServiceDiscovery.h b/ble/ServiceDiscovery.h index 89ad140..ed7df10 100644 --- a/ble/ServiceDiscovery.h +++ b/ble/ServiceDiscovery.h @@ -136,14 +136,14 @@ public: * Clear all ServiceDiscovery state of the associated object. * * This function is meant to be overridden in the platform-specific - * sub-class. Nevertheless, the sub-class is only expected to clean up its + * sub-class. Nevertheless, the sub-class is only expected to reset its * state and not the data held in ServiceDiscovery members. This shall be - * achieved by a call to ServiceDiscovery::cleanup() from the sub-class' - * cleanup() implementation. + * achieved by a call to ServiceDiscovery::reset() from the sub-class' + * reset() implementation. * * @return BLE_ERROR_NONE on success. */ - virtual ble_error_t cleanup(void) { + virtual ble_error_t reset(void) { connHandle = 0; matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN); serviceCallback = NULL; diff --git a/source/BLE.cpp b/source/BLE.cpp index f2e537a..c1ac1b2 100644 --- a/source/BLE.cpp +++ b/source/BLE.cpp @@ -131,7 +131,6 @@ bool BLE::hasInitialized(void) const ble_error_t BLE::shutdown(void) { - clearAdvertisingPayload(); if (!transport) { error("bad handle to underlying transport"); } diff --git a/source/Gap.cpp b/source/Gap.cpp deleted file mode 100644 index 17a50c5..0000000 --- a/source/Gap.cpp +++ /dev/null @@ -1,19 +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 "ble/Gap.h" - -Gap *Gap::gapInstance = NULL; diff --git a/source/GattClient.cpp b/source/GattClient.cpp deleted file mode 100644 index 5186e7c..0000000 --- a/source/GattClient.cpp +++ /dev/null @@ -1,19 +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 "ble/GattClient.h" - -GattClient *GattClient::gattClientInstance = NULL; diff --git a/source/GattServer.cpp b/source/GattServer.cpp deleted file mode 100644 index 35c475d..0000000 --- a/source/GattServer.cpp +++ /dev/null @@ -1,19 +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 "ble/GattServer.h" - -GattServer *GattServer::gattServerInstance = NULL; diff --git a/source/SecurityManager.cpp b/source/SecurityManager.cpp deleted file mode 100644 index f36026a..0000000 --- a/source/SecurityManager.cpp +++ /dev/null @@ -1,19 +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 "ble/SecurityManager.h" - -SecurityManager *SecurityManager::securityManagerInstance = NULL; From 17d6e5fe80d085131411e7fb191126dfa1cc4463 Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Mon, 14 Dec 2015 16:59:21 +0000 Subject: [PATCH 03/27] Extract Adress related types from Gap.h into BLEProtocol.h --- ble/BLE.h | 12 +++---- ble/BLEProtocol.h | 49 +++++++++++++++++++++++++++ ble/Gap.h | 84 ++++++++++++++++++++++++++--------------------- 3 files changed, 102 insertions(+), 43 deletions(-) create mode 100644 ble/BLEProtocol.h diff --git a/ble/BLE.h b/ble/BLE.h index 0966b91..cf4c28d 100644 --- a/ble/BLE.h +++ b/ble/BLE.h @@ -196,7 +196,7 @@ public: * directly, as it returns references to singletons. * * @param[in] id - * Instance-ID. This should be less than NUM_INSTANCES + * Instance-ID. This should be less than NUM_INSTANCES * for the returned BLE singleton to be useful. * * @return a reference to a single object. @@ -239,7 +239,7 @@ public: * ble.setAddress(...) should be replaced with * ble.gap().setAddress(...). */ - ble_error_t setAddress(Gap::AddressType_t type, const Gap::Address_t address) { + ble_error_t setAddress(BLEProtocol::AddressType::Type type, const Gap::Address_t address) { return gap().setAddress(type, address); } @@ -252,7 +252,7 @@ public: * ble.getAddress(...) should be replaced with * ble.gap().getAddress(...). */ - ble_error_t getAddress(Gap::AddressType_t *typeP, Gap::Address_t address) { + ble_error_t getAddress(BLEProtocol::AddressType::Type *typeP, Gap::Address_t address) { return gap().getAddress(typeP, address); } @@ -753,7 +753,7 @@ public: * ble.gap().connect(...). */ ble_error_t connect(const Gap::Address_t peerAddr, - Gap::AddressType_t peerAddrType = Gap::ADDR_TYPE_RANDOM_STATIC, + BLEProtocol::AddressType::Type peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC, const Gap::ConnectionParams_t *connectionParams = NULL, const GapScanningParams *scanParams = NULL) { return gap().connect(peerAddr, peerAddrType, connectionParams, scanParams); @@ -773,7 +773,7 @@ public: } /** - * This call initiates the disconnection procedure, and its completion + * This call initiates the disconnection procedure, and its completion * is communicated to the application with an invocation of the * onDisconnection callback. * @@ -1407,7 +1407,7 @@ public: /** * Set up 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 the peers need to exchange + * configured to prevent Man-In-The-Middle attacks, and the peers need to exchange * a passkey (or PIN) to authenticate the connection * attempt. * diff --git a/ble/BLEProtocol.h b/ble/BLEProtocol.h new file mode 100644 index 0000000..17eef3b --- /dev/null +++ b/ble/BLEProtocol.h @@ -0,0 +1,49 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BLE_PROTOCOL_H__ +#define __BLE_PROTOCOL_H__ + +#include +#include + +/** + * A common container for types and constants used everywhere in BLE API. + */ +struct BLEProtocol { + /**< Address-type for Protocol addresses. */ + struct AddressType { /* Adding a struct to encapsulate the contained enumeration + * prevents polluting the BLEProtocol namespace with the + * enumerated values. It also allows type-aliases for the + * enumeration while retaining the enumerated values. i.e. + * + * doing: + * typedef AddressType_t AliasedType_t; + * would allow the use of AliasedType_t::PUBLIC in code. + */ + enum Type { + PUBLIC = 0, + RANDOM_STATIC, + RANDOM_PRIVATE_RESOLVABLE, + RANDOM_PRIVATE_NON_RESOLVABLE + }; + }; + + static const size_t ADDR_LEN = 6; /**< Length (in octets) of the BLE MAC address. */ + typedef uint8_t Address_t[ADDR_LEN]; /**< 48-bit address, in LSB format. */ +}; + +#endif /* __BLE_PROTOCOL_H__ */ diff --git a/ble/Gap.h b/ble/Gap.h index dfa07c1..54ee73a 100644 --- a/ble/Gap.h +++ b/ble/Gap.h @@ -17,6 +17,7 @@ #ifndef __GAP_H__ #define __GAP_H__ +#include "ble/BLEProtocol.h" #include "GapAdvertisingData.h" #include "GapAdvertisingParams.h" #include "GapScanningParams.h" @@ -30,19 +31,28 @@ class GapScanningParams; class GapAdvertisingData; class Gap { + /* + * DEPRECATION ALERT: all of the APIs in this `public` block are deprecated. + * They have been relocated to the class BLEProtocol. + */ 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. */ + /** + * Address-type for BLEProtocol addresses. + * @note: deprecated. Use BLEProtocol::AddressType::Type instead. + */ + typedef BLEProtocol::AddressType::Type AddressType_t; - 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. */ + /** + * Address-type for BLEProtocol addresses. + * @note: deprecated. Use BLEProtocol::AddressType::Type instead. + */ + typedef BLEProtocol::AddressType::Type addr_type_t; + static const unsigned ADDR_LEN = BLEProtocol::ADDR_LEN; /**< Length (in octets) of the BLE MAC address. */ + typedef BLEProtocol::Address_t Address_t; /**< 48-bit address, LSB format. @Note: Deprecated. Use BLEProtocol::Address_t instead. */ + typedef BLEProtocol::Address_t address_t; /**< 48-bit address, LSB format. @Note: Deprecated. Use BLEProtocol::Address_t instead. */ + +public: enum TimeoutSource_t { TIMEOUT_SRC_ADVERTISING = 0x00, /**< Advertising timeout. */ TIMEOUT_SRC_SECURITY_REQUEST = 0x01, /**< Security request timeout. */ @@ -97,21 +107,21 @@ public: typedef FunctionPointerWithContext AdvertisementReportCallback_t; struct ConnectionCallbackParams_t { - Handle_t handle; - Role_t role; - AddressType_t peerAddrType; - Address_t peerAddr; - AddressType_t ownAddrType; - Address_t ownAddr; - const ConnectionParams_t *connectionParams; + Handle_t handle; + Role_t role; + BLEProtocol::AddressType::Type peerAddrType; + Address_t peerAddr; + BLEProtocol::AddressType::Type ownAddrType; + Address_t ownAddr; + const ConnectionParams_t *connectionParams; - ConnectionCallbackParams_t(Handle_t handleIn, - Role_t roleIn, - AddressType_t peerAddrTypeIn, - const uint8_t *peerAddrIn, - AddressType_t ownAddrTypeIn, - const uint8_t *ownAddrIn, - const ConnectionParams_t *connectionParamsIn) : + ConnectionCallbackParams_t(Handle_t handleIn, + Role_t roleIn, + BLEProtocol::AddressType::Type peerAddrTypeIn, + const uint8_t *peerAddrIn, + BLEProtocol::AddressType::Type ownAddrTypeIn, + const uint8_t *ownAddrIn, + const ConnectionParams_t *connectionParamsIn) : handle(handleIn), role(roleIn), peerAddrType(peerAddrTypeIn), @@ -161,7 +171,7 @@ public: * * @return BLE_ERROR_NONE on success. */ - virtual ble_error_t setAddress(AddressType_t type, const Address_t address) { + virtual ble_error_t setAddress(BLEProtocol::AddressType::Type type, const Address_t address) { /* avoid compiler warnings about unused variables */ (void)type; (void)address; @@ -174,7 +184,7 @@ public: * * @return BLE_ERROR_NONE on success. */ - virtual ble_error_t getAddress(AddressType_t *typeP, Address_t address) { + virtual ble_error_t getAddress(BLEProtocol::AddressType::Type *typeP, Address_t address) { /* Avoid compiler warnings about unused variables. */ (void)typeP; (void)address; @@ -233,10 +243,10 @@ public: * successfully. The connectionCallChain (if set) will be invoked upon * a connection event. */ - virtual ble_error_t connect(const Address_t peerAddr, - Gap::AddressType_t peerAddrType, - const ConnectionParams_t *connectionParams, - const GapScanningParams *scanParams) { + virtual ble_error_t connect(const Address_t peerAddr, + BLEProtocol::AddressType::Type peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams) { /* Avoid compiler warnings about unused variables. */ (void)peerAddr; (void)peerAddrType; @@ -1002,13 +1012,13 @@ protected: /* Entry points for the underlying stack to report events back to the user. */ public: - void processConnectionEvent(Handle_t handle, - Role_t role, - AddressType_t peerAddrType, - const Address_t peerAddr, - AddressType_t ownAddrType, - const Address_t ownAddr, - const ConnectionParams_t *connectionParams) { + void processConnectionEvent(Handle_t handle, + Role_t role, + BLEProtocol::AddressType::Type peerAddrType, + const Address_t peerAddr, + BLEProtocol::AddressType::Type ownAddrType, + const Address_t ownAddr, + const ConnectionParams_t *connectionParams) { state.connected = 1; ConnectionCallbackParams_t callbackParams(handle, role, peerAddrType, peerAddr, ownAddrType, ownAddr, connectionParams); connectionCallChain.call(&callbackParams); From 05c42ffc310f04e2019d98bd3e8238679b4cab99 Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Mon, 14 Dec 2015 17:08:07 +0000 Subject: [PATCH 04/27] had meant to use namespace for BLEProtocol instead of struct --- ble/BLEProtocol.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ble/BLEProtocol.h b/ble/BLEProtocol.h index 17eef3b..6e539b6 100644 --- a/ble/BLEProtocol.h +++ b/ble/BLEProtocol.h @@ -21,9 +21,9 @@ #include /** - * A common container for types and constants used everywhere in BLE API. + * A common namespace for types and constants used everywhere in BLE API. */ -struct BLEProtocol { +namespace BLEProtocol { /**< Address-type for Protocol addresses. */ struct AddressType { /* Adding a struct to encapsulate the contained enumeration * prevents polluting the BLEProtocol namespace with the From 4774e2cd84812f98c78b07a3156cfce4925a21d6 Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Tue, 15 Dec 2015 08:50:47 +0000 Subject: [PATCH 05/27] Add an alias for BLEProtocol::AddressType::Type --- ble/BLE.h | 8 +++--- ble/BLEProtocol.h | 20 +++++++-------- ble/Gap.h | 62 +++++++++++++++++++++++------------------------ 3 files changed, 45 insertions(+), 45 deletions(-) diff --git a/ble/BLE.h b/ble/BLE.h index cf4c28d..097e8a4 100644 --- a/ble/BLE.h +++ b/ble/BLE.h @@ -239,7 +239,7 @@ public: * ble.setAddress(...) should be replaced with * ble.gap().setAddress(...). */ - ble_error_t setAddress(BLEProtocol::AddressType::Type type, const Gap::Address_t address) { + ble_error_t setAddress(BLEProtocol::AddressType_t type, const BLEProtocol::Address_t address) { return gap().setAddress(type, address); } @@ -252,7 +252,7 @@ public: * ble.getAddress(...) should be replaced with * ble.gap().getAddress(...). */ - ble_error_t getAddress(BLEProtocol::AddressType::Type *typeP, Gap::Address_t address) { + ble_error_t getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::Address_t address) { return gap().getAddress(typeP, address); } @@ -752,8 +752,8 @@ public: * ble.connect(...) should be replaced with * ble.gap().connect(...). */ - ble_error_t connect(const Gap::Address_t peerAddr, - BLEProtocol::AddressType::Type peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC, + ble_error_t connect(const BLEProtocol::Address_t peerAddr, + BLEProtocol::AddressType_t peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC, const Gap::ConnectionParams_t *connectionParams = NULL, const GapScanningParams *scanParams = NULL) { return gap().connect(peerAddr, peerAddrType, connectionParams, scanParams); diff --git a/ble/BLEProtocol.h b/ble/BLEProtocol.h index 6e539b6..1454022 100644 --- a/ble/BLEProtocol.h +++ b/ble/BLEProtocol.h @@ -26,14 +26,13 @@ namespace BLEProtocol { /**< Address-type for Protocol addresses. */ struct AddressType { /* Adding a struct to encapsulate the contained enumeration - * prevents polluting the BLEProtocol namespace with the - * enumerated values. It also allows type-aliases for the - * enumeration while retaining the enumerated values. i.e. - * - * doing: - * typedef AddressType_t AliasedType_t; - * would allow the use of AliasedType_t::PUBLIC in code. - */ + * prevents polluting the BLEProtocol namespace with the + * enumerated values. It also allows type-aliases for the + * enumeration while retaining the enumerated values. i.e. + * + * doing: + * typedef AddressType_t AliasedType_t; + * would allow the use of AliasedType_t::PUBLIC in code. */ enum Type { PUBLIC = 0, RANDOM_STATIC, @@ -41,9 +40,10 @@ namespace BLEProtocol { RANDOM_PRIVATE_NON_RESOLVABLE }; }; + typedef AddressType::Type AddressType_t; /**< Alias for AddressType::Type */ - static const size_t ADDR_LEN = 6; /**< Length (in octets) of the BLE MAC address. */ - typedef uint8_t Address_t[ADDR_LEN]; /**< 48-bit address, in LSB format. */ + static const size_t ADDR_LEN = 6; /**< Length (in octets) of the BLE MAC address. */ + typedef uint8_t Address_t[ADDR_LEN]; /**< 48-bit address, in LSB format. */ }; #endif /* __BLE_PROTOCOL_H__ */ diff --git a/ble/Gap.h b/ble/Gap.h index 54ee73a..824d863 100644 --- a/ble/Gap.h +++ b/ble/Gap.h @@ -38,15 +38,15 @@ class Gap { public: /** * Address-type for BLEProtocol addresses. - * @note: deprecated. Use BLEProtocol::AddressType::Type instead. + * @note: deprecated. Use BLEProtocol::AddressType_t instead. */ - typedef BLEProtocol::AddressType::Type AddressType_t; + typedef BLEProtocol::AddressType_t AddressType_t; /** * Address-type for BLEProtocol addresses. - * @note: deprecated. Use BLEProtocol::AddressType::Type instead. + * @note: deprecated. Use BLEProtocol::AddressType_t instead. */ - typedef BLEProtocol::AddressType::Type addr_type_t; + typedef BLEProtocol::AddressType_t addr_type_t; static const unsigned ADDR_LEN = BLEProtocol::ADDR_LEN; /**< Length (in octets) of the BLE MAC address. */ typedef BLEProtocol::Address_t Address_t; /**< 48-bit address, LSB format. @Note: Deprecated. Use BLEProtocol::Address_t instead. */ @@ -107,21 +107,21 @@ public: typedef FunctionPointerWithContext AdvertisementReportCallback_t; struct ConnectionCallbackParams_t { - Handle_t handle; - Role_t role; - BLEProtocol::AddressType::Type peerAddrType; - Address_t peerAddr; - BLEProtocol::AddressType::Type ownAddrType; - Address_t ownAddr; - const ConnectionParams_t *connectionParams; + Handle_t handle; + Role_t role; + BLEProtocol::AddressType_t peerAddrType; + Address_t peerAddr; + BLEProtocol::AddressType_t ownAddrType; + Address_t ownAddr; + const ConnectionParams_t *connectionParams; - ConnectionCallbackParams_t(Handle_t handleIn, - Role_t roleIn, - BLEProtocol::AddressType::Type peerAddrTypeIn, - const uint8_t *peerAddrIn, - BLEProtocol::AddressType::Type ownAddrTypeIn, - const uint8_t *ownAddrIn, - const ConnectionParams_t *connectionParamsIn) : + ConnectionCallbackParams_t(Handle_t handleIn, + Role_t roleIn, + BLEProtocol::AddressType_t peerAddrTypeIn, + const uint8_t *peerAddrIn, + BLEProtocol::AddressType_t ownAddrTypeIn, + const uint8_t *ownAddrIn, + const ConnectionParams_t *connectionParamsIn) : handle(handleIn), role(roleIn), peerAddrType(peerAddrTypeIn), @@ -171,7 +171,7 @@ public: * * @return BLE_ERROR_NONE on success. */ - virtual ble_error_t setAddress(BLEProtocol::AddressType::Type type, const Address_t address) { + virtual ble_error_t setAddress(BLEProtocol::AddressType_t type, const Address_t address) { /* avoid compiler warnings about unused variables */ (void)type; (void)address; @@ -184,7 +184,7 @@ public: * * @return BLE_ERROR_NONE on success. */ - virtual ble_error_t getAddress(BLEProtocol::AddressType::Type *typeP, Address_t address) { + virtual ble_error_t getAddress(BLEProtocol::AddressType_t *typeP, Address_t address) { /* Avoid compiler warnings about unused variables. */ (void)typeP; (void)address; @@ -243,10 +243,10 @@ public: * successfully. The connectionCallChain (if set) will be invoked upon * a connection event. */ - virtual ble_error_t connect(const Address_t peerAddr, - BLEProtocol::AddressType::Type peerAddrType, - const ConnectionParams_t *connectionParams, - const GapScanningParams *scanParams) { + virtual ble_error_t connect(const Address_t peerAddr, + BLEProtocol::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams) { /* Avoid compiler warnings about unused variables. */ (void)peerAddr; (void)peerAddrType; @@ -1012,13 +1012,13 @@ protected: /* Entry points for the underlying stack to report events back to the user. */ public: - void processConnectionEvent(Handle_t handle, - Role_t role, - BLEProtocol::AddressType::Type peerAddrType, - const Address_t peerAddr, - BLEProtocol::AddressType::Type ownAddrType, - const Address_t ownAddr, - const ConnectionParams_t *connectionParams) { + void processConnectionEvent(Handle_t handle, + Role_t role, + BLEProtocol::AddressType_t peerAddrType, + const Address_t peerAddr, + BLEProtocol::AddressType_t ownAddrType, + const Address_t ownAddr, + const ConnectionParams_t *connectionParams) { state.connected = 1; ConnectionCallbackParams_t callbackParams(handle, role, peerAddrType, peerAddr, ownAddrType, ownAddr, connectionParams); connectionCallChain.call(&callbackParams); From 1cab4222d5d3c7e08768a9c0f29a57d7b3429ac8 Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Tue, 15 Dec 2015 11:58:15 +0000 Subject: [PATCH 06/27] replace uses of GapAddress_t with BLEProtocol::Address_t --- ble/Gap.h | 54 +++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/ble/Gap.h b/ble/Gap.h index 824d863..d73d840 100644 --- a/ble/Gap.h +++ b/ble/Gap.h @@ -97,12 +97,12 @@ public: }; struct AdvertisementCallbackParams_t { - Address_t peerAddr; - int8_t rssi; - bool isScanResponse; - GapAdvertisingParams::AdvertisingType_t type; - uint8_t advertisingDataLen; - const uint8_t *advertisingData; + BLEProtocol::Address_t peerAddr; + int8_t rssi; + bool isScanResponse; + GapAdvertisingParams::AdvertisingType_t type; + uint8_t advertisingDataLen; + const uint8_t *advertisingData; }; typedef FunctionPointerWithContext AdvertisementReportCallback_t; @@ -110,9 +110,9 @@ public: Handle_t handle; Role_t role; BLEProtocol::AddressType_t peerAddrType; - Address_t peerAddr; + BLEProtocol::Address_t peerAddr; BLEProtocol::AddressType_t ownAddrType; - Address_t ownAddr; + BLEProtocol::Address_t ownAddr; const ConnectionParams_t *connectionParams; ConnectionCallbackParams_t(Handle_t handleIn, @@ -167,11 +167,11 @@ public: public: /** * Set the BTLE MAC address and type. Please note that the address format is - * least significant byte first (LSB). Please refer to Address_t. + * least significant byte first (LSB). Please refer to BLEProtocol::Address_t. * * @return BLE_ERROR_NONE on success. */ - virtual ble_error_t setAddress(BLEProtocol::AddressType_t type, const Address_t address) { + virtual ble_error_t setAddress(BLEProtocol::AddressType_t type, const BLEProtocol::Address_t address) { /* avoid compiler warnings about unused variables */ (void)type; (void)address; @@ -184,7 +184,7 @@ public: * * @return BLE_ERROR_NONE on success. */ - virtual ble_error_t getAddress(BLEProtocol::AddressType_t *typeP, Address_t address) { + virtual ble_error_t getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::Address_t address) { /* Avoid compiler warnings about unused variables. */ (void)typeP; (void)address; @@ -243,10 +243,10 @@ public: * successfully. The connectionCallChain (if set) will be invoked upon * a connection event. */ - virtual ble_error_t connect(const Address_t peerAddr, - BLEProtocol::AddressType_t peerAddrType, - const ConnectionParams_t *connectionParams, - const GapScanningParams *scanParams) { + virtual ble_error_t connect(const BLEProtocol::Address_t peerAddr, + BLEProtocol::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams) { /* Avoid compiler warnings about unused variables. */ (void)peerAddr; (void)peerAddrType; @@ -1012,13 +1012,13 @@ protected: /* Entry points for the underlying stack to report events back to the user. */ public: - void processConnectionEvent(Handle_t handle, - Role_t role, - BLEProtocol::AddressType_t peerAddrType, - const Address_t peerAddr, - BLEProtocol::AddressType_t ownAddrType, - const Address_t ownAddr, - const ConnectionParams_t *connectionParams) { + void processConnectionEvent(Handle_t handle, + Role_t role, + BLEProtocol::AddressType_t peerAddrType, + const BLEProtocol::Address_t peerAddr, + BLEProtocol::AddressType_t ownAddrType, + const BLEProtocol::Address_t ownAddr, + const ConnectionParams_t *connectionParams) { state.connected = 1; ConnectionCallbackParams_t callbackParams(handle, role, peerAddrType, peerAddr, ownAddrType, ownAddr, connectionParams); connectionCallChain.call(&callbackParams); @@ -1030,12 +1030,12 @@ public: disconnectionCallChain.call(&callbackParams); } - void processAdvertisementReport(const Address_t peerAddr, - int8_t rssi, - bool isScanResponse, + void processAdvertisementReport(const BLEProtocol::Address_t peerAddr, + int8_t rssi, + bool isScanResponse, GapAdvertisingParams::AdvertisingType_t type, - uint8_t advertisingDataLen, - const uint8_t *advertisingData) { + uint8_t advertisingDataLen, + const uint8_t *advertisingData) { AdvertisementCallbackParams_t params; memcpy(params.peerAddr, peerAddr, ADDR_LEN); params.rssi = rssi; From 87ab48899dbea85e15cf87d92f8c72d95aa057d9 Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Tue, 15 Dec 2015 13:04:25 +0000 Subject: [PATCH 07/27] version v2.1.15 --- module.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module.json b/module.json index 7386e78..e2db73d 100644 --- a/module.json +++ b/module.json @@ -1,6 +1,6 @@ { "name": "ble", - "version": "2.1.14", + "version": "2.1.15", "description": "The BLE module offers a high level abstraction for using Bluetooth Low Energy on multiple platforms.", "keywords": [ "Bluetooth", From b8fde928149ba5ddd47c7504b712e4e5491dc8bd Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Tue, 15 Dec 2015 13:06:52 +0000 Subject: [PATCH 08/27] update dependency for ble-nrf51822 to have version >=2.2.6 --- module.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module.json b/module.json index e2db73d..96fc998 100644 --- a/module.json +++ b/module.json @@ -26,7 +26,7 @@ "x-nucleo-idb0xa1": "^2.0.0" }, "nrf51822": { - "ble-nrf51822": "^2.1.3" + "ble-nrf51822": "^2.2.6" }, "cordio": { "ble-wicentric": "~0.0.4" From 8b513a7ba2f2561477b298d38b1329d54afad1e0 Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Wed, 16 Dec 2015 06:51:35 +0000 Subject: [PATCH 09/27] add an interdependency to "ble-nrf51822": "^2.2.8" --- module.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module.json b/module.json index 96fc998..f7b1c38 100644 --- a/module.json +++ b/module.json @@ -1,6 +1,6 @@ { "name": "ble", - "version": "2.1.15", + "version": "2.1.16", "description": "The BLE module offers a high level abstraction for using Bluetooth Low Energy on multiple platforms.", "keywords": [ "Bluetooth", @@ -26,7 +26,7 @@ "x-nucleo-idb0xa1": "^2.0.0" }, "nrf51822": { - "ble-nrf51822": "^2.2.6" + "ble-nrf51822": "^2.2.8" }, "cordio": { "ble-wicentric": "~0.0.4" From 022c37ce31fe49ae3bdfc964d6e1f0cf47ff4469 Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Wed, 16 Dec 2015 07:00:50 +0000 Subject: [PATCH 10/27] white space diffs --- ble/Gap.h | 4 ++-- ble/GattServer.h | 21 ++++++++++----------- ble/SecurityManager.h | 6 +++--- ble/ServiceDiscovery.h | 8 ++++---- 4 files changed, 19 insertions(+), 20 deletions(-) diff --git a/ble/Gap.h b/ble/Gap.h index 7ff3a0a..5e3f31b 100644 --- a/ble/Gap.h +++ b/ble/Gap.h @@ -1010,7 +1010,7 @@ public: virtual ble_error_t reset(void) { /* Clear Gap state */ state.advertising = 0; - state.connected = 0; + state.connected = 0; /* Clear scanning state */ scanningActive = false; @@ -1024,7 +1024,7 @@ public: connectionCallChain.clear(); disconnectionCallChain.clear(); radioNotificationCallback = NULL; - onAdvertisementReport = NULL; + onAdvertisementReport = NULL; return BLE_ERROR_NONE; } diff --git a/ble/GattServer.h b/ble/GattServer.h index 73a75c1..944822a 100644 --- a/ble/GattServer.h +++ b/ble/GattServer.h @@ -26,13 +26,12 @@ class GattServer { public: - /* Event callback handlers. */ typedef FunctionPointerWithContext DataSentCallback_t; typedef CallChainOfFunctionPointersWithContext DataSentCallbackChain_t; typedef FunctionPointerWithContext DataWrittenCallback_t; - typedef CallChainOfFunctionPointersWithContext DataWrittenCallbackChain_t; + typedef CallChainOfFunctionPointersWithContext DataWrittenCallbackChain_t; typedef FunctionPointerWithContext DataReadCallback_t; typedef CallChainOfFunctionPointersWithContext DataReadCallbackChain_t; @@ -254,9 +253,9 @@ public: } /** - * @brief get the callback chain called when the event DATA_EVENT is triggered. + * @brief get the callback chain called when the event DATA_EVENT is triggered. */ - DataSentCallbackChain_t& onDataSent() { + DataSentCallbackChain_t& onDataSent() { return dataSentCallChain; } @@ -274,7 +273,7 @@ public: * * @Note: It is also possible to set up a callback into a member function of * some object. - * + * * @Note It is possible to unregister a callback using onDataWritten().detach(callback) */ void onDataWritten(const DataWrittenCallback_t& callback) {dataWrittenCallChain.add(callback);} @@ -286,9 +285,9 @@ public: /** * @brief provide access to the callchain of data written event callbacks * It is possible to register callbacks using onDataWritten().add(callback); - * It is possible to unregister callbacks using onDataWritten().detach(callback) + * It is possible to unregister callbacks using onDataWritten().detach(callback) * @return The data written event callbacks chain - */ + */ DataWrittenCallbackChain_t& onDataWritten() { return dataWrittenCallChain; } @@ -335,7 +334,7 @@ public: /** * @brief provide access to the callchain of data read event callbacks * It is possible to register callbacks using onDataRead().add(callback); - * It is possible to unregister callbacks using onDataRead().detach(callback) + * It is possible to unregister callbacks using onDataRead().detach(callback) * @return The data read event callbacks chain */ DataReadCallbackChain_t& onDataRead() { @@ -409,14 +408,14 @@ public: * @return BLE_ERROR_NONE on success. */ virtual ble_error_t reset(void) { - serviceCount = 0; + serviceCount = 0; characteristicCount = 0; dataSentCallChain.clear(); dataWrittenCallChain.clear(); dataReadCallChain.clear(); - updatesEnabledCallback = NULL; - updatesDisabledCallback = NULL; + updatesEnabledCallback = NULL; + updatesDisabledCallback = NULL; confirmationReceivedCallback = NULL; return BLE_ERROR_NONE; diff --git a/ble/SecurityManager.h b/ble/SecurityManager.h index 75ed860..33dbae4 100644 --- a/ble/SecurityManager.h +++ b/ble/SecurityManager.h @@ -246,9 +246,9 @@ public: virtual ble_error_t reset(void) { securitySetupInitiatedCallback = NULL; securitySetupCompletedCallback = NULL; - linkSecuredCallback = NULL; - securityContextStoredCallback = NULL; - passkeyDisplayCallback = NULL; + linkSecuredCallback = NULL; + securityContextStoredCallback = NULL; + passkeyDisplayCallback = NULL; return BLE_ERROR_NONE; } diff --git a/ble/ServiceDiscovery.h b/ble/ServiceDiscovery.h index ed7df10..c023aea 100644 --- a/ble/ServiceDiscovery.h +++ b/ble/ServiceDiscovery.h @@ -144,11 +144,11 @@ public: * @return BLE_ERROR_NONE on success. */ virtual ble_error_t reset(void) { - connHandle = 0; - matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN); - serviceCallback = NULL; + connHandle = 0; + matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN); + serviceCallback = NULL; matchingCharacteristicUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN); - characteristicCallback = NULL; + characteristicCallback = NULL; return BLE_ERROR_NONE; } From 2f527dbb7e1c62e84a1f5f9b06a96b617a46a833 Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Wed, 16 Dec 2015 08:54:09 +0000 Subject: [PATCH 11/27] transparenly support existing applications which may have used Gap::ADDR_TYPE_*. --- ble/Gap.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/ble/Gap.h b/ble/Gap.h index 5e3f31b..ad6e4ce 100644 --- a/ble/Gap.h +++ b/ble/Gap.h @@ -38,9 +38,17 @@ class Gap { public: /** * Address-type for BLEProtocol addresses. - * @note: deprecated. Use BLEProtocol::AddressType_t instead. + * + * @note: deprecated. Use BLEProtocol::AddressType_t instead. This declaration will soon be changed to: + * typedef BLEProtocol::AddressType_t AddressType_t; + * It has been left in this current state to transparenly support existing applications which may have used Gap::ADDR_TYPE_*. */ - typedef BLEProtocol::AddressType_t AddressType_t; + enum AddressType_t { + ADDR_TYPE_PUBLIC = BLEProtocol::AddressType::PUBLIC, + ADDR_TYPE_RANDOM_STATIC, + ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE, + ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE + }; /** * Address-type for BLEProtocol addresses. From f30fe6bcdacd60a8392d26e1ddf16835a7f786fd Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Wed, 16 Dec 2015 09:07:57 +0000 Subject: [PATCH 12/27] use an anonymous enum instead --- ble/Gap.h | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/ble/Gap.h b/ble/Gap.h index ad6e4ce..0d6eb8a 100644 --- a/ble/Gap.h +++ b/ble/Gap.h @@ -39,15 +39,23 @@ public: /** * Address-type for BLEProtocol addresses. * - * @note: deprecated. Use BLEProtocol::AddressType_t instead. This declaration will soon be changed to: - * typedef BLEProtocol::AddressType_t AddressType_t; - * It has been left in this current state to transparenly support existing applications which may have used Gap::ADDR_TYPE_*. + * @note: deprecated. Use BLEProtocol::AddressType_t instead. */ - enum AddressType_t { - ADDR_TYPE_PUBLIC = BLEProtocol::AddressType::PUBLIC, - ADDR_TYPE_RANDOM_STATIC, - ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE, - ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE + typedef BLEProtocol::AddressType_t AddressType_t; + + /** + * Address-type for BLEProtocol addresses. + * @note: deprecated. Use BLEProtocol::AddressType_t instead. + * + * DEPRECATION ALERT: The following constants have been left in their + * deprecated state to transparenly support existing applications which may + * have used Gap::ADDR_TYPE_*. + */ + enum { + ADDR_TYPE_PUBLIC = BLEProtocol::AddressType::PUBLIC, + ADDR_TYPE_RANDOM_STATIC = BLEProtocol::AddressType::RANDOM_STATIC, + ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE = BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE, + ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE = BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE }; /** From 3c15a7dfcc4010d3a8034963fdb89bfab1aad2cd Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Wed, 16 Dec 2015 09:09:38 +0000 Subject: [PATCH 13/27] minor re-organization --- ble/Gap.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ble/Gap.h b/ble/Gap.h index 0d6eb8a..97e8e41 100644 --- a/ble/Gap.h +++ b/ble/Gap.h @@ -43,6 +43,12 @@ public: */ typedef BLEProtocol::AddressType_t AddressType_t; + /** + * Address-type for BLEProtocol addresses. + * @note: deprecated. Use BLEProtocol::AddressType_t instead. + */ + typedef BLEProtocol::AddressType_t addr_type_t; + /** * Address-type for BLEProtocol addresses. * @note: deprecated. Use BLEProtocol::AddressType_t instead. @@ -58,12 +64,6 @@ public: ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE = BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE }; - /** - * Address-type for BLEProtocol addresses. - * @note: deprecated. Use BLEProtocol::AddressType_t instead. - */ - typedef BLEProtocol::AddressType_t addr_type_t; - static const unsigned ADDR_LEN = BLEProtocol::ADDR_LEN; /**< Length (in octets) of the BLE MAC address. */ typedef BLEProtocol::Address_t Address_t; /**< 48-bit address, LSB format. @Note: Deprecated. Use BLEProtocol::Address_t instead. */ typedef BLEProtocol::Address_t address_t; /**< 48-bit address, LSB format. @Note: Deprecated. Use BLEProtocol::Address_t instead. */ From 0781293bdaf6363438d7942bd0ac6751ae52aaed Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Tue, 15 Dec 2015 15:53:12 +0000 Subject: [PATCH 14/27] Add onShutdown to register callbacks Add an onShutdown() function to Gap, GattClient, GattServer and SecurityManager. The callbacks are added to a private callback chain in each of the instances. The callbacks will be executed inside each object's reset() function BEFORE the state of the instance is cleared. The developers of the platform-specific implementation must call the parent class' reset() function for the callbacks to be executed. Finally, an onShutdown() function that returns the shutdown callchain is added to allow detaching callbacks. --- ble/Gap.h | 45 +++++++++++++++++++++++++++++++++- ble/GattClient.h | 48 +++++++++++++++++++++++++++++++++--- ble/GattServer.h | 57 +++++++++++++++++++++++++++++++++++++------ ble/SecurityManager.h | 46 +++++++++++++++++++++++++++++++++- 4 files changed, 182 insertions(+), 14 deletions(-) diff --git a/ble/Gap.h b/ble/Gap.h index 5e3f31b..f94880e 100644 --- a/ble/Gap.h +++ b/ble/Gap.h @@ -161,6 +161,9 @@ public: typedef FunctionPointerWithContext RadioNotificationEventCallback_t; + typedef FunctionPointerWithContext GapShutdownCallback_t; + typedef CallChainOfFunctionPointersWithContext GapShutdownCallbackChain_t; + /* * The following functions are meant to be overridden in the platform-specific sub-class. */ @@ -993,9 +996,43 @@ public: radioNotificationCallback.attach(tptr, mptr); } + /** + * Setup a callback to be invoked to notify the user application that the + * Gap instance is about to shutdown (possibly as a result of a call + * to BLE::shutdown()). + * + * @Note: It is possible to chain together multiple onShutdown callbacks + * (potentially from different modules of an application) to be notified + * before the Gap instance is shutdown. + * + * @Note: It is also possible to set up a callback into a member function of + * some object. + * + * @Note It is possible to unregister a callback using onShutdown().detach(callback) + */ + void onShutdown(const GapShutdownCallback_t& callback) { + shutdownCallChain.add(callback); + } + template + void onShutdown(T *objPtr, void (T::*memberPtr)(void)) { + shutdownCallChain.add(objPtr, memberPtr); + } + + /** + * @brief provide access to the callchain of shutdown event callbacks + * It is possible to register callbacks using onShutdown().add(callback); + * It is possible to unregister callbacks using onShutdown().detach(callback) + * @return The shutdown event callbacks chain + */ + GapShutdownCallbackChain_t& onShutdown() { + return shutdownCallChain; + } + public: /** - * Clear all Gap state of the associated object. + * Notify all registered onShutdown callbacks that the Gap instance is + * about to be shutdown and clear all Gap state of the + * associated object. * * This function is meant to be overridden in the platform-specific * sub-class. Nevertheless, the sub-class is only expected to reset its @@ -1008,6 +1045,9 @@ public: * scan parameters to default values. */ virtual ble_error_t reset(void) { + /* Notify that the instance is about to shutdown */ + shutdownCallChain.call(this); + /* Clear Gap state */ state.advertising = 0; state.connected = 0; @@ -1104,6 +1144,9 @@ protected: ConnectionEventCallbackChain_t connectionCallChain; DisconnectionEventCallbackChain_t disconnectionCallChain; +private: + GapShutdownCallbackChain_t shutdownCallChain; + private: /* Disallow copy and assignment. */ Gap(const Gap &); diff --git a/ble/GattClient.h b/ble/GattClient.h index 1df6066..d523e0c 100644 --- a/ble/GattClient.h +++ b/ble/GattClient.h @@ -41,6 +41,9 @@ public: typedef FunctionPointerWithContext HVXCallback_t; typedef CallChainOfFunctionPointersWithContext HVXCallbackChain_t; + typedef FunctionPointerWithContext GattClientShutdownCallback_t; + typedef CallChainOfFunctionPointersWithContext GattClientShutdownCallbackChain_t; + /* * The following functions are meant to be overridden in the platform-specific sub-class. */ @@ -314,6 +317,37 @@ public: onHVXCallbackChain.add(callback); } + /** + * Setup a callback to be invoked to notify the user application that the + * GattClient instance is about to shutdown (possibly as a result of a call + * to BLE::shutdown()). + * + * @Note: It is possible to chain together multiple onShutdown callbacks + * (potentially from different modules of an application) to be notified + * before the GattClient is shutdown. + * + * @Note: It is also possible to set up a callback into a member function of + * some object. + * + * @Note It is possible to unregister a callback using onShutdown().detach(callback) + */ + void onShutdown(const GattClientShutdownCallback_t& callback) { + shutdownCallChain.add(callback); + } + template + void onShutdown(T *objPtr, void (T::*memberPtr)(void)) { + shutdownCallChain.add(objPtr, memberPtr); + } + + /** + * @brief provide access to the callchain of shutdown event callbacks + * It is possible to register callbacks using onShutdown().add(callback); + * It is possible to unregister callbacks using onShutdown().detach(callback) + * @return The shutdown event callbacks chain + */ + GattClientShutdownCallbackChain_t& onShutdown() { + return shutdownCallChain; + } /** * @brief provide access to the callchain of HVX callbacks @@ -327,7 +361,9 @@ public: public: /** - * Clear all GattClient state of the associated object. + * Notify all registered onShutdown callbacks that the GattClient is + * about to be shutdown and clear all GattClient state of the + * associated object. * * This function is meant to be overridden in the platform-specific * sub-class. Nevertheless, the sub-class is only expected to reset its @@ -338,6 +374,9 @@ public: * @return BLE_ERROR_NONE on success. */ virtual ble_error_t reset(void) { + /* Notify that the instance is about to shutdown */ + shutdownCallChain.call(this); + onDataReadCallbackChain.clear(); onDataWriteCallbackChain.clear(); onHVXCallbackChain.clear(); @@ -367,9 +406,10 @@ public: } protected: - ReadCallbackChain_t onDataReadCallbackChain; - WriteCallbackChain_t onDataWriteCallbackChain; - HVXCallbackChain_t onHVXCallbackChain; + ReadCallbackChain_t onDataReadCallbackChain; + WriteCallbackChain_t onDataWriteCallbackChain; + HVXCallbackChain_t onHVXCallbackChain; + GattClientShutdownCallbackChain_t shutdownCallChain; private: /* Disallow copy and assignment. */ diff --git a/ble/GattServer.h b/ble/GattServer.h index 944822a..3f89bc8 100644 --- a/ble/GattServer.h +++ b/ble/GattServer.h @@ -36,6 +36,9 @@ public: typedef FunctionPointerWithContext DataReadCallback_t; typedef CallChainOfFunctionPointersWithContext DataReadCallbackChain_t; + typedef FunctionPointerWithContext GattServerShutdownCallback_t; + typedef CallChainOfFunctionPointersWithContext GattServerShutdownCallbackChain_t; + typedef FunctionPointerWithContext EventCallback_t; protected: @@ -341,6 +344,38 @@ public: return dataReadCallChain; } + /** + * Setup a callback to be invoked to notify the user application that the + * GattServer instance is about to shutdown (possibly as a result of a call + * to BLE::shutdown()). + * + * @Note: It is possible to chain together multiple onShutdown callbacks + * (potentially from different modules of an application) to be notified + * before the GattServer is shutdown. + * + * @Note: It is also possible to set up a callback into a member function of + * some object. + * + * @Note It is possible to unregister a callback using onShutdown().detach(callback) + */ + void onShutdown(const GattServerShutdownCallback_t& callback) { + shutdownCallChain.add(callback); + } + template + void onShutdown(T *objPtr, void (T::*memberPtr)(void)) { + shutdownCallChain.add(objPtr, memberPtr); + } + + /** + * @brief provide access to the callchain of shutdown event callbacks + * It is possible to register callbacks using onShutdown().add(callback); + * It is possible to unregister callbacks using onShutdown().detach(callback) + * @return The shutdown event callbacks chain + */ + GattServerShutdownCallbackChain_t& onShutdown() { + return shutdownCallChain; + } + /** * Set up a callback for when notifications or indications are enabled for a * characteristic on the local GATT server. @@ -397,7 +432,9 @@ protected: public: /** - * Clear all GattServer state of the associated object. + * Notify all registered onShutdown callbacks that the GattServer is + * about to be shutdown and clear all GattServer state of the + * associated object. * * This function is meant to be overridden in the platform-specific * sub-class. Nevertheless, the sub-class is only expected to reset its @@ -408,7 +445,10 @@ public: * @return BLE_ERROR_NONE on success. */ virtual ble_error_t reset(void) { - serviceCount = 0; + /* Notify that the instance is about to shutdown */ + shutdownCallChain.call(this); + + serviceCount = 0; characteristicCount = 0; dataSentCallChain.clear(); @@ -426,12 +466,13 @@ protected: uint8_t characteristicCount; private: - DataSentCallbackChain_t dataSentCallChain; - DataWrittenCallbackChain_t dataWrittenCallChain; - DataReadCallbackChain_t dataReadCallChain; - EventCallback_t updatesEnabledCallback; - EventCallback_t updatesDisabledCallback; - EventCallback_t confirmationReceivedCallback; + DataSentCallbackChain_t dataSentCallChain; + DataWrittenCallbackChain_t dataWrittenCallChain; + DataReadCallbackChain_t dataReadCallChain; + GattServerShutdownCallbackChain_t shutdownCallChain; + EventCallback_t updatesEnabledCallback; + EventCallback_t updatesDisabledCallback; + EventCallback_t confirmationReceivedCallback; private: /* Disallow copy and assignment. */ diff --git a/ble/SecurityManager.h b/ble/SecurityManager.h index 33dbae4..e9996c5 100644 --- a/ble/SecurityManager.h +++ b/ble/SecurityManager.h @@ -20,6 +20,7 @@ #include #include "Gap.h" +#include "CallChainOfFunctionPointersWithContext.h" class SecurityManager { public: @@ -82,6 +83,9 @@ public: typedef void (*LinkSecuredCallback_t)(Gap::Handle_t handle, SecurityMode_t securityMode); typedef void (*PasskeyDisplayCallback_t)(Gap::Handle_t handle, const Passkey_t passkey); + typedef FunctionPointerWithContext SecurityManagerShutdownCallback_t; + typedef CallChainOfFunctionPointersWithContext SecurityManagerShutdownCallbackChain_t; + /* * The following functions are meant to be overridden in the platform-specific sub-class. */ @@ -161,6 +165,38 @@ public: /* Event callback handlers. */ public: + /** + * Setup a callback to be invoked to notify the user application that the + * SecurityManager instance is about to shutdown (possibly as a result of a call + * to BLE::shutdown()). + * + * @Note: It is possible to chain together multiple onShutdown callbacks + * (potentially from different modules of an application) to be notified + * before the SecurityManager is shutdown. + * + * @Note: It is also possible to set up a callback into a member function of + * some object. + * + * @Note It is possible to unregister a callback using onShutdown().detach(callback) + */ + void onShutdown(const SecurityManagerShutdownCallback_t& callback) { + shutdownCallChain.add(callback); + } + template + void onShutdown(T *objPtr, void (T::*memberPtr)(void)) { + shutdownCallChain.add(objPtr, memberPtr); + } + + /** + * @brief provide access to the callchain of shutdown event callbacks + * It is possible to register callbacks using onShutdown().add(callback); + * It is possible to unregister callbacks using onShutdown().detach(callback) + * @return The shutdown event callbacks chain + */ + SecurityManagerShutdownCallbackChain_t& onShutdown() { + return shutdownCallChain; + } + /** * To indicate that a security procedure for the link has started. */ @@ -233,7 +269,9 @@ protected: public: /** - * Clear all SecurityManager state of the associated object. + * Notify all registered onShutdown callbacks that the SecurityManager is + * about to be shutdown and clear all SecurityManager state of the + * associated object. * * This function is meant to be overridden in the platform-specific * sub-class. Nevertheless, the sub-class is only expected to reset its @@ -244,6 +282,9 @@ public: * @return BLE_ERROR_NONE on success. */ virtual ble_error_t reset(void) { + /* Notify that the instance is about to shutdown */ + shutdownCallChain.call(this); + securitySetupInitiatedCallback = NULL; securitySetupCompletedCallback = NULL; linkSecuredCallback = NULL; @@ -259,6 +300,9 @@ protected: LinkSecuredCallback_t linkSecuredCallback; HandleSpecificEvent_t securityContextStoredCallback; PasskeyDisplayCallback_t passkeyDisplayCallback; + +private: + SecurityManagerShutdownCallbackChain_t shutdownCallChain; }; #endif /*__SECURITY_MANAGER_H__*/ From 0024b78a396b696a6ecc72285c60a1f771f04d92 Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Wed, 16 Dec 2015 16:43:04 +0000 Subject: [PATCH 15/27] Clear shutdown callchain after exec callbacks --- ble/Gap.h | 1 + ble/GattClient.h | 1 + ble/GattServer.h | 1 + ble/SecurityManager.h | 1 + 4 files changed, 4 insertions(+) diff --git a/ble/Gap.h b/ble/Gap.h index f94880e..5b4067a 100644 --- a/ble/Gap.h +++ b/ble/Gap.h @@ -1047,6 +1047,7 @@ public: virtual ble_error_t reset(void) { /* Notify that the instance is about to shutdown */ shutdownCallChain.call(this); + shutdownCallChain.clear(); /* Clear Gap state */ state.advertising = 0; diff --git a/ble/GattClient.h b/ble/GattClient.h index d523e0c..c65207f 100644 --- a/ble/GattClient.h +++ b/ble/GattClient.h @@ -376,6 +376,7 @@ public: virtual ble_error_t reset(void) { /* Notify that the instance is about to shutdown */ shutdownCallChain.call(this); + shutdownCallChain.clear(); onDataReadCallbackChain.clear(); onDataWriteCallbackChain.clear(); diff --git a/ble/GattServer.h b/ble/GattServer.h index 3f89bc8..ea46a88 100644 --- a/ble/GattServer.h +++ b/ble/GattServer.h @@ -447,6 +447,7 @@ public: virtual ble_error_t reset(void) { /* Notify that the instance is about to shutdown */ shutdownCallChain.call(this); + shutdownCallChain.clear(); serviceCount = 0; characteristicCount = 0; diff --git a/ble/SecurityManager.h b/ble/SecurityManager.h index e9996c5..e508954 100644 --- a/ble/SecurityManager.h +++ b/ble/SecurityManager.h @@ -284,6 +284,7 @@ public: virtual ble_error_t reset(void) { /* Notify that the instance is about to shutdown */ shutdownCallChain.call(this); + shutdownCallChain.clear(); securitySetupInitiatedCallback = NULL; securitySetupCompletedCallback = NULL; From 7ded8ae7848a73c3b54153ed67c3a1fe9b129f05 Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Thu, 17 Dec 2015 08:52:14 +0000 Subject: [PATCH 16/27] version v2.2.0 --- module.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module.json b/module.json index f7b1c38..569053e 100644 --- a/module.json +++ b/module.json @@ -1,6 +1,6 @@ { "name": "ble", - "version": "2.1.16", + "version": "2.2.0", "description": "The BLE module offers a high level abstraction for using Bluetooth Low Energy on multiple platforms.", "keywords": [ "Bluetooth", From 7ce1b80b8c9c580123548eb0fc8d16b986b91521 Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Thu, 17 Dec 2015 15:42:29 +0000 Subject: [PATCH 17/27] Removed deprecated appearance enum from blecommon.h --- ble/GapAdvertisingData.h | 1 + ble/blecommon.h | 56 ---------------------------------------- 2 files changed, 1 insertion(+), 56 deletions(-) diff --git a/ble/GapAdvertisingData.h b/ble/GapAdvertisingData.h index 8d0ffb5..6cce093 100644 --- a/ble/GapAdvertisingData.h +++ b/ble/GapAdvertisingData.h @@ -187,6 +187,7 @@ public: PULSE_OXIMETER_GENERIC = 3136, /**< Generic Pulse Oximeter. */ PULSE_OXIMETER_FINGERTIP = 3137, /**< Fingertip Pulse Oximeter. */ PULSE_OXIMETER_WRIST_WORN = 3138, /**< Wrist Worn Pulse Oximeter. */ + GENERIC_WEIGHT_SCALE = 3200, /**< Generic Weight Scale. */ 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. */ diff --git a/ble/blecommon.h b/ble/blecommon.h index ed71fff..caea0a4 100644 --- a/ble/blecommon.h +++ b/ble/blecommon.h @@ -49,62 +49,6 @@ enum { BLE_UUID_GAP_CHARACTERISTIC_PPCP = 0x2A04, /**< Peripheral Preferred Connection Parameters Characteristic. */ }; -/*! 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, /**< Joystick (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. */ enum ble_error_t { BLE_ERROR_NONE = 0, /**< No error. */ From e40dc0642cd08e82aec24e65db220ebd15561fb1 Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Thu, 17 Dec 2015 15:45:04 +0000 Subject: [PATCH 18/27] Fix comment in GapAdvertisingParams.h --- ble/GapAdvertisingData.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ble/GapAdvertisingData.h b/ble/GapAdvertisingData.h index 6cce093..82a893d 100644 --- a/ble/GapAdvertisingData.h +++ b/ble/GapAdvertisingData.h @@ -187,7 +187,7 @@ public: PULSE_OXIMETER_GENERIC = 3136, /**< Generic Pulse Oximeter. */ PULSE_OXIMETER_FINGERTIP = 3137, /**< Fingertip Pulse Oximeter. */ PULSE_OXIMETER_WRIST_WORN = 3138, /**< Wrist Worn Pulse Oximeter. */ - GENERIC_WEIGHT_SCALE = 3200, /**< Generic Weight Scale. */ + GENERIC_WEIGHT_SCALE = 3200, /**< Generic Weight Scale. */ 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. */ From 002c761381f243750f691bac8a9dc9945caef956 Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Fri, 18 Dec 2015 13:23:52 +0000 Subject: [PATCH 19/27] version v2.2.1 --- module.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module.json b/module.json index 569053e..80ba9c0 100644 --- a/module.json +++ b/module.json @@ -1,6 +1,6 @@ { "name": "ble", - "version": "2.2.0", + "version": "2.2.1", "description": "The BLE module offers a high level abstraction for using Bluetooth Low Energy on multiple platforms.", "keywords": [ "Bluetooth", From 39e3e8d151ab509847c80fef4753b440797f1bab Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Fri, 18 Dec 2015 13:53:51 +0000 Subject: [PATCH 20/27] Modify functions that manipulate adv payload Modify the functions addData() and updateData() to correctly update the payload information for a specified AD type if that type was already present in the payload. For addData() if the AD type is not found, it is added to the payload. In contrast, in updateData() if the AD type is not found an error is returned. Documentation was updated accordingly. --- ble/Gap.h | 5 +- ble/GapAdvertisingData.h | 261 +++++++++++++++++++-------------------- 2 files changed, 129 insertions(+), 137 deletions(-) diff --git a/ble/Gap.h b/ble/Gap.h index 4765faf..1c1fe81 100644 --- a/ble/Gap.h +++ b/ble/Gap.h @@ -620,8 +620,7 @@ public: /** * Update a particular ADV field in the advertising payload (based on - * matching type and length). Note: the length of the new data must be the - * same as the old one. + * matching type). * * @param[in] type The ADV type field describing the variable length data. * @param[in] data Data bytes. @@ -630,7 +629,7 @@ public: * @note: If advertisements are enabled, then the update will take effect immediately. * * @return BLE_ERROR_NONE if the advertisement payload was updated based on - * a match; otherwise, an appropriate error. + * matching AD type; otherwise, an appropriate error. */ ble_error_t updateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) { if (type == GapAdvertisingData::COMPLETE_LOCAL_NAME) { diff --git a/ble/GapAdvertisingData.h b/ble/GapAdvertisingData.h index 82a893d..df090fb 100644 --- a/ble/GapAdvertisingData.h +++ b/ble/GapAdvertisingData.h @@ -202,149 +202,63 @@ public: /** * 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) - { - ble_error_t result = BLE_ERROR_BUFFER_OVERFLOW; - - // find field - uint8_t* field = findField(advDataType); - - // Field type already exist, either add to field or replace - if (field) { - switch(advDataType) { - // These fields will be overwritten with the new value - case FLAGS: - case SHORTENED_LOCAL_NAME: - case COMPLETE_LOCAL_NAME: - case TX_POWER_LEVEL: - case DEVICE_ID: - case SLAVE_CONNECTION_INTERVAL_RANGE: - case SERVICE_DATA: - case APPEARANCE: - case ADVERTISING_INTERVAL: - case MANUFACTURER_SPECIFIC_DATA: { - // current field length, with the type subtracted - uint8_t dataLength = field[0] - 1; - - // new data has same length, do in-order replacement - if (len == dataLength) { - for (uint8_t idx = 0; idx < dataLength; idx++) { - field[2 + idx] = payload[idx]; - } - } else { - // check if data fits - if ((_payloadLen - dataLength + len) <= GAP_ADVERTISING_DATA_MAX_PAYLOAD) { - - // remove old field - while ((field + dataLength + 2) < &_payload[_payloadLen]) { - *field = field[dataLength + 2]; - field++; - } - - // reduce length - _payloadLen -= dataLength + 2; - - // add new field - result = appendField(advDataType, payload, len); - } - } - - break; - } - // These fields will have the new data appended if there is sufficient space - case INCOMPLETE_LIST_16BIT_SERVICE_IDS: - case COMPLETE_LIST_16BIT_SERVICE_IDS: - case INCOMPLETE_LIST_32BIT_SERVICE_IDS: - case COMPLETE_LIST_32BIT_SERVICE_IDS: - case INCOMPLETE_LIST_128BIT_SERVICE_IDS: - case COMPLETE_LIST_128BIT_SERVICE_IDS: - case LIST_128BIT_SOLICITATION_IDS: { - // check if data fits - if ((_payloadLen + len) <= GAP_ADVERTISING_DATA_MAX_PAYLOAD) { - // make room for new field by moving the remainder of the - // advertisement payload "to the right" starting after the - // TYPE field. - uint8_t* end = &_payload[_payloadLen]; - - while (&field[1] < end) { - end[len] = *end; - end--; - } - - // insert new data - for (uint8_t idx = 0; idx < len; idx++) { - field[2 + idx] = payload[idx]; - } - - // increment lengths - field[0] += len; - _payloadLen += len; - - result = BLE_ERROR_NONE; - } - - break; - } - // Field exists but updating it is not supported. Abort operation. - default: - result = BLE_ERROR_NOT_IMPLEMENTED; - break; - } - } else { - // field doesn't exists, insert new - result = appendField(advDataType, payload, len); - } - - return result; - } - - /** - * Update a particular ADV field in the advertising payload (based on - * matching type and length). Note: the length of the new data must be the - * same as the old one. + * If the supplied AD type is already present in the advertising + * payload, then the value is updated. * * @param[in] advDataType The Advertising 'DataType' to add. * @param[in] payload Pointer to the payload contents. * @param[in] len Size of the payload in bytes. * - * @return BLE_ERROR_UNSPECIFIED if the specified field is not found, else - * BLE_ERROR_NONE. + * @return BLE_ERROR_BUFFER_OVERFLOW if the new value causes the + * advertising buffer to overflow. BLE_ERROR_NONE is returned + * on success. + * + * @note When the specified AD type is INCOMPLETE_LIST_16BIT_SERVICE_IDS, + * COMPLETE_LIST_16BIT_SERVICE_IDS, INCOMPLETE_LIST_32BIT_SERVICE_IDS, + * COMPLETE_LIST_32BIT_SERVICE_IDS, INCOMPLETE_LIST_128BIT_SERVICE_IDS, + * COMPLETE_LIST_128BIT_SERVICE_IDS or LIST_128BIT_SOLICITATION_IDS the + * supplied value is appended to the values previously added to the + * payload. + */ + ble_error_t addData(DataType_t advDataType, const uint8_t *payload, uint8_t len) + { + // find field + uint8_t* field = findField(advDataType); + + if (field) { + // Field type already exist, either add to field or replace + return updateFieldPayload(advDataType, payload, len, field); + } else { + // field doesn't exists, insert new + return appendField(advDataType, payload, len); + } + } + + /** + * Update a particular ADV field in the advertising payload (based on + * matching type). + * + * @param[in] advDataType The Advertising 'DataType' to add. + * @param[in] payload Pointer to the payload contents. + * @param[in] len Size of the payload in bytes. + * + * @return BLE_ERROR_UNSPECIFIED if the specified field is not found, + * BLE_ERROR_BUFFER_OVERFLOW if the new value causes the + * advertising buffer to overflow. BLE_ERROR_NONE is returned + * on success. */ ble_error_t updateData(DataType_t advDataType, const uint8_t *payload, uint8_t len) { - if ((payload == NULL) || (len == 0)) { - return BLE_ERROR_INVALID_PARAM; + // find field + uint8_t* field = findField(advDataType); + + if (field) { + // Field type already exist, either add to field or replace + return updateFieldPayload(advDataType, payload, len, field); + } else { + // field doesn't exists, return an error + return BLE_ERROR_UNSPECIFIED; } - - /* A local struct to describe an ADV field. This definition comes from the Bluetooth Core Spec. (v4.2) Part C, Section 11. */ - struct ADVField_t { - uint8_t len; /* Describes the length (in bytes) of the following type and bytes. */ - uint8_t type; /* Should have the same representation of DataType_t (above). */ - uint8_t bytes[0]; /* A placeholder for variable length data. */ - }; - - /* Iterate over the adv fields looking for the first match. */ - uint8_t byteIndex = 0; - while (byteIndex < _payloadLen) { - ADVField_t *currentADV = (ADVField_t *)&_payload[byteIndex]; - if ((currentADV->len == (len + 1)) && /* Incoming len only describes the payload, whereas ADV->len describes [type + payload]. */ - (currentADV->type == advDataType)) { - memcpy(currentADV->bytes, payload, len); - return BLE_ERROR_NONE; - } - - byteIndex += (currentADV->len + 1); /* Advance by len+1; '+1' is needed to span the len field itself. */ - } - - return BLE_ERROR_UNSPECIFIED; } /** @@ -475,6 +389,85 @@ private: return NULL; } + /** + * Given the a pointer to a field in the advertising payload it replaces + * the existing data in the field with the supplied data. + * Returns BLE_ERROR_NONE on success. + */ + ble_error_t updateFieldPayload(DataType_t advDataType, const uint8_t *payload, uint8_t len, uint8_t* field) + { + ble_error_t result = BLE_ERROR_BUFFER_OVERFLOW; + + switch(advDataType) { + // These fields will have the new data appended if there is sufficient space + case INCOMPLETE_LIST_16BIT_SERVICE_IDS: + case COMPLETE_LIST_16BIT_SERVICE_IDS: + case INCOMPLETE_LIST_32BIT_SERVICE_IDS: + case COMPLETE_LIST_32BIT_SERVICE_IDS: + case INCOMPLETE_LIST_128BIT_SERVICE_IDS: + case COMPLETE_LIST_128BIT_SERVICE_IDS: + case LIST_128BIT_SOLICITATION_IDS: { + // check if data fits + if ((_payloadLen + len) <= GAP_ADVERTISING_DATA_MAX_PAYLOAD) { + // make room for new field by moving the remainder of the + // advertisement payload "to the right" starting after the + // TYPE field. + uint8_t* end = &_payload[_payloadLen]; + + while (&field[1] < end) { + end[len] = *end; + end--; + } + + // insert new data + for (uint8_t idx = 0; idx < len; idx++) { + field[2 + idx] = payload[idx]; + } + + // increment lengths + field[0] += len; + _payloadLen += len; + + result = BLE_ERROR_NONE; + } + + break; + } + // These fields will be overwritten with the new value + default: { + // current field length, with the type subtracted + uint8_t dataLength = field[0] - 1; + + // new data has same length, do in-order replacement + if (len == dataLength) { + for (uint8_t idx = 0; idx < dataLength; idx++) { + field[2 + idx] = payload[idx]; + } + } else { + // check if data fits + if ((_payloadLen - dataLength + len) <= GAP_ADVERTISING_DATA_MAX_PAYLOAD) { + + // remove old field + while ((field + dataLength + 2) < &_payload[_payloadLen]) { + *field = field[dataLength + 2]; + field++; + } + + // reduce length + _payloadLen -= dataLength + 2; + + // add new field + result = appendField(advDataType, payload, len); + } + } + + break; + } + } + + return result; + } + uint8_t _payload[GAP_ADVERTISING_DATA_MAX_PAYLOAD]; uint8_t _payloadLen; uint16_t _appearance; From 4fb7c06886c197ebc0a62b6f0fb8e58cee659e86 Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Fri, 18 Dec 2015 14:02:44 +0000 Subject: [PATCH 21/27] Rename updateFieldPayload to updateField --- ble/GapAdvertisingData.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ble/GapAdvertisingData.h b/ble/GapAdvertisingData.h index df090fb..3591bf0 100644 --- a/ble/GapAdvertisingData.h +++ b/ble/GapAdvertisingData.h @@ -227,7 +227,7 @@ public: if (field) { // Field type already exist, either add to field or replace - return updateFieldPayload(advDataType, payload, len, field); + return updateField(advDataType, payload, len, field); } else { // field doesn't exists, insert new return appendField(advDataType, payload, len); @@ -254,7 +254,7 @@ public: if (field) { // Field type already exist, either add to field or replace - return updateFieldPayload(advDataType, payload, len, field); + return updateField(advDataType, payload, len, field); } else { // field doesn't exists, return an error return BLE_ERROR_UNSPECIFIED; @@ -394,7 +394,7 @@ private: * the existing data in the field with the supplied data. * Returns BLE_ERROR_NONE on success. */ - ble_error_t updateFieldPayload(DataType_t advDataType, const uint8_t *payload, uint8_t len, uint8_t* field) + ble_error_t updateField(DataType_t advDataType, const uint8_t *payload, uint8_t len, uint8_t* field) { ble_error_t result = BLE_ERROR_BUFFER_OVERFLOW; From ae516d1aba513134ad52291803a50dc3585989f0 Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Fri, 18 Dec 2015 16:17:28 +0000 Subject: [PATCH 22/27] Clean up code in DiscoveredCharacteristic.cpp Clean up the code by removing white spaces and adding statements to supress unused-parameter compiler warnings. --- source/DiscoveredCharacteristic.cpp | 44 ++++++++++++++++------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/source/DiscoveredCharacteristic.cpp b/source/DiscoveredCharacteristic.cpp index 91119e0..72214e3 100644 --- a/source/DiscoveredCharacteristic.cpp +++ b/source/DiscoveredCharacteristic.cpp @@ -31,29 +31,29 @@ DiscoveredCharacteristic::read(uint16_t offset) const return gattc->read(connHandle, valueHandle, offset); } -struct OneShotReadCallback { - static void launch(GattClient* client, Gap::Handle_t connHandle, - GattAttribute::Handle_t handle, const GattClient::ReadCallback_t& cb) { +struct OneShotReadCallback { + static void launch(GattClient* client, Gap::Handle_t connHandle, + GattAttribute::Handle_t handle, const GattClient::ReadCallback_t& cb) { OneShotReadCallback* oneShot = new OneShotReadCallback(client, connHandle, handle, cb); oneShot->attach(); // delete will be made when this callback is called } private: - OneShotReadCallback(GattClient* client, Gap::Handle_t connHandle, - GattAttribute::Handle_t handle, const GattClient::ReadCallback_t& cb) : + OneShotReadCallback(GattClient* client, Gap::Handle_t connHandle, + GattAttribute::Handle_t handle, const GattClient::ReadCallback_t& cb) : _client(client), _connHandle(connHandle), - _handle(handle), - _callback(cb) { } + _handle(handle), + _callback(cb) { } - void attach() { + void attach() { _client->onDataRead(makeFunctionPointer(this, &OneShotReadCallback::call)); } void call(const GattReadCallbackParams* params) { // verifiy that it is the right characteristic on the right connection - if (params->connHandle == _connHandle && params->handle == _handle) { + if (params->connHandle == _connHandle && params->handle == _handle) { _callback(params); _client->onDataRead().detach(makeFunctionPointer(this, &OneShotReadCallback::call)); delete this; @@ -68,7 +68,7 @@ private: ble_error_t DiscoveredCharacteristic::read(uint16_t offset, const GattClient::ReadCallback_t& onRead) const { ble_error_t error = read(offset); - if (error) { + if (error) { return error; } @@ -105,29 +105,29 @@ DiscoveredCharacteristic::writeWoResponse(uint16_t length, const uint8_t *value) return gattc->write(GattClient::GATT_OP_WRITE_CMD, connHandle, valueHandle, length, value); } -struct OneShotWriteCallback { - static void launch(GattClient* client, Gap::Handle_t connHandle, - GattAttribute::Handle_t handle, const GattClient::WriteCallback_t& cb) { +struct OneShotWriteCallback { + static void launch(GattClient* client, Gap::Handle_t connHandle, + GattAttribute::Handle_t handle, const GattClient::WriteCallback_t& cb) { OneShotWriteCallback* oneShot = new OneShotWriteCallback(client, connHandle, handle, cb); oneShot->attach(); // delete will be made when this callback is called } private: - OneShotWriteCallback(GattClient* client, Gap::Handle_t connHandle, - GattAttribute::Handle_t handle, const GattClient::WriteCallback_t& cb) : + OneShotWriteCallback(GattClient* client, Gap::Handle_t connHandle, + GattAttribute::Handle_t handle, const GattClient::WriteCallback_t& cb) : _client(client), _connHandle(connHandle), - _handle(handle), - _callback(cb) { } + _handle(handle), + _callback(cb) { } - void attach() { + void attach() { _client->onDataWritten(makeFunctionPointer(this, &OneShotWriteCallback::call)); } void call(const GattWriteCallbackParams* params) { // verifiy that it is the right characteristic on the right connection - if (params->connHandle == _connHandle && params->handle == _handle) { + if (params->connHandle == _connHandle && params->handle == _handle) { _callback(params); _client->onDataWritten().detach(makeFunctionPointer(this, &OneShotWriteCallback::call)); delete this; @@ -142,7 +142,7 @@ private: ble_error_t DiscoveredCharacteristic::write(uint16_t length, const uint8_t *value, const GattClient::WriteCallback_t& onRead) const { ble_error_t error = write(length, value); - if (error) { + if (error) { return error; } @@ -154,5 +154,9 @@ ble_error_t DiscoveredCharacteristic::write(uint16_t length, const uint8_t *valu ble_error_t DiscoveredCharacteristic::discoverDescriptors(DescriptorCallback_t callback, const UUID &matchingUUID) const { + /* Avoid compiler warnings */ + (void) callback; + (void) matchingUUID; + return BLE_ERROR_NOT_IMPLEMENTED; /* TODO: this needs to be filled in. */ } From fec4e5ec531348141fabf664d8ede8d3da4e1810 Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Fri, 18 Dec 2015 16:27:18 +0000 Subject: [PATCH 23/27] Add documentation missing for updateData() --- ble/GapAdvertisingData.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ble/GapAdvertisingData.h b/ble/GapAdvertisingData.h index 3591bf0..94b8a96 100644 --- a/ble/GapAdvertisingData.h +++ b/ble/GapAdvertisingData.h @@ -246,6 +246,13 @@ public: * BLE_ERROR_BUFFER_OVERFLOW if the new value causes the * advertising buffer to overflow. BLE_ERROR_NONE is returned * on success. + * + * @note When the specified AD type is INCOMPLETE_LIST_16BIT_SERVICE_IDS, + * COMPLETE_LIST_16BIT_SERVICE_IDS, INCOMPLETE_LIST_32BIT_SERVICE_IDS, + * COMPLETE_LIST_32BIT_SERVICE_IDS, INCOMPLETE_LIST_128BIT_SERVICE_IDS, + * COMPLETE_LIST_128BIT_SERVICE_IDS or LIST_128BIT_SOLICITATION_IDS the + * supplied value is appended to the values previously added to the + * payload. */ ble_error_t updateData(DataType_t advDataType, const uint8_t *payload, uint8_t len) { From c64decef7331a9ec9d6dd08d29f4439f2272a8d8 Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Fri, 18 Dec 2015 17:22:35 +0000 Subject: [PATCH 24/27] Add BLE_ERROR_INTERNAL_STACK_FAILURE error code Add an additional error code to the ble_error_t enum to describe a failure state caused by the internal platform-specific stack. This state was not described by any of the existing error codes. --- ble/blecommon.h | 1 + 1 file changed, 1 insertion(+) diff --git a/ble/blecommon.h b/ble/blecommon.h index caea0a4..16fdec0 100644 --- a/ble/blecommon.h +++ b/ble/blecommon.h @@ -63,6 +63,7 @@ enum ble_error_t { BLE_ERROR_INITIALIZATION_INCOMPLETE = 9, BLE_ERROR_ALREADY_INITIALIZED = 10, BLE_ERROR_UNSPECIFIED = 11, /**< Unknown error. */ + BLE_ERROR_INTERNAL_STACK_FAILURE = 12, /**< The platform-specific stack failed */ }; /** @brief Default MTU size. */ From bd2b3cd05b1f172b0b84e784b26097cde6e924e9 Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Mon, 21 Dec 2015 08:10:30 +0000 Subject: [PATCH 25/27] version v2.2.2 --- module.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module.json b/module.json index 80ba9c0..dd87d83 100644 --- a/module.json +++ b/module.json @@ -1,6 +1,6 @@ { "name": "ble", - "version": "2.2.1", + "version": "2.2.2", "description": "The BLE module offers a high level abstraction for using Bluetooth Low Energy on multiple platforms.", "keywords": [ "Bluetooth", From 02ca65bc9fa2f86d76ff2e2af25d759172206b93 Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Mon, 21 Dec 2015 10:38:51 +0000 Subject: [PATCH 26/27] Make update adv payload replace previous data Accumulate and update advertising payload now differ in their implementations. Accumulate updates the previous value, if it is UUID then the previously added values are kept and the new one is simple appended. In contrast, update replaces the previous value in all cases. --- ble/Gap.h | 10 +++++ ble/GapAdvertisingData.h | 83 ++++++++++++++++++++++++---------------- 2 files changed, 59 insertions(+), 34 deletions(-) diff --git a/ble/Gap.h b/ble/Gap.h index 1c1fe81..181a3c5 100644 --- a/ble/Gap.h +++ b/ble/Gap.h @@ -604,6 +604,16 @@ public: * @param type The type describing the variable length data. * @param data Data bytes. * @param len Length of data. + * + * @return BLE_ERROR_NONE if the advertisement payload was updated based on + * matching AD type; otherwise, an appropriate error. + * + * @note When the specified AD type is INCOMPLETE_LIST_16BIT_SERVICE_IDS, + * COMPLETE_LIST_16BIT_SERVICE_IDS, INCOMPLETE_LIST_32BIT_SERVICE_IDS, + * COMPLETE_LIST_32BIT_SERVICE_IDS, INCOMPLETE_LIST_128BIT_SERVICE_IDS, + * COMPLETE_LIST_128BIT_SERVICE_IDS or LIST_128BIT_SOLICITATION_IDS the + * supplied value is appended to the values previously added to the + * payload. */ ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) { if (type == GapAdvertisingData::COMPLETE_LOCAL_NAME) { diff --git a/ble/GapAdvertisingData.h b/ble/GapAdvertisingData.h index 94b8a96..ae9116b 100644 --- a/ble/GapAdvertisingData.h +++ b/ble/GapAdvertisingData.h @@ -227,7 +227,7 @@ public: if (field) { // Field type already exist, either add to field or replace - return updateField(advDataType, payload, len, field); + return addField(advDataType, payload, len, field); } else { // field doesn't exists, insert new return appendField(advDataType, payload, len); @@ -246,13 +246,6 @@ public: * BLE_ERROR_BUFFER_OVERFLOW if the new value causes the * advertising buffer to overflow. BLE_ERROR_NONE is returned * on success. - * - * @note When the specified AD type is INCOMPLETE_LIST_16BIT_SERVICE_IDS, - * COMPLETE_LIST_16BIT_SERVICE_IDS, INCOMPLETE_LIST_32BIT_SERVICE_IDS, - * COMPLETE_LIST_32BIT_SERVICE_IDS, INCOMPLETE_LIST_128BIT_SERVICE_IDS, - * COMPLETE_LIST_128BIT_SERVICE_IDS or LIST_128BIT_SOLICITATION_IDS the - * supplied value is appended to the values previously added to the - * payload. */ ble_error_t updateData(DataType_t advDataType, const uint8_t *payload, uint8_t len) { @@ -399,9 +392,17 @@ private: /** * Given the a pointer to a field in the advertising payload it replaces * the existing data in the field with the supplied data. + * + * When the specified AD type is INCOMPLETE_LIST_16BIT_SERVICE_IDS, + * COMPLETE_LIST_16BIT_SERVICE_IDS, INCOMPLETE_LIST_32BIT_SERVICE_IDS, + * COMPLETE_LIST_32BIT_SERVICE_IDS, INCOMPLETE_LIST_128BIT_SERVICE_IDS, + * COMPLETE_LIST_128BIT_SERVICE_IDS or LIST_128BIT_SOLICITATION_IDS the + * supplied value is appended to the values previously added to the + * payload. + * * Returns BLE_ERROR_NONE on success. */ - ble_error_t updateField(DataType_t advDataType, const uint8_t *payload, uint8_t len, uint8_t* field) + ble_error_t addField(DataType_t advDataType, const uint8_t *payload, uint8_t len, uint8_t* field) { ble_error_t result = BLE_ERROR_BUFFER_OVERFLOW; @@ -442,31 +443,7 @@ private: } // These fields will be overwritten with the new value default: { - // current field length, with the type subtracted - uint8_t dataLength = field[0] - 1; - - // new data has same length, do in-order replacement - if (len == dataLength) { - for (uint8_t idx = 0; idx < dataLength; idx++) { - field[2 + idx] = payload[idx]; - } - } else { - // check if data fits - if ((_payloadLen - dataLength + len) <= GAP_ADVERTISING_DATA_MAX_PAYLOAD) { - - // remove old field - while ((field + dataLength + 2) < &_payload[_payloadLen]) { - *field = field[dataLength + 2]; - field++; - } - - // reduce length - _payloadLen -= dataLength + 2; - - // add new field - result = appendField(advDataType, payload, len); - } - } + result = updateField(advDataType, payload, len, field); break; } @@ -475,6 +452,44 @@ private: return result; } + /** + * Given the a pointer to a field in the advertising payload it replaces + * the existing data in the field with the supplied data. + * Returns BLE_ERROR_NONE on success. + */ + ble_error_t updateField(DataType_t advDataType, const uint8_t *payload, uint8_t len, uint8_t* field) + { + ble_error_t result = BLE_ERROR_BUFFER_OVERFLOW; + uint8_t dataLength = field[0] - 1; + + // new data has same length, do in-order replacement + if (len == dataLength) { + for (uint8_t idx = 0; idx < dataLength; idx++) { + field[2 + idx] = payload[idx]; + } + + result = BLE_ERROR_NONE; + } else { + // check if data fits + if ((_payloadLen - dataLength + len) <= GAP_ADVERTISING_DATA_MAX_PAYLOAD) { + + // remove old field + while ((field + dataLength + 2) < &_payload[_payloadLen]) { + *field = field[dataLength + 2]; + field++; + } + + // reduce length + _payloadLen -= dataLength + 2; + + // add new field + result = appendField(advDataType, payload, len); + } + } + + return result; + } + uint8_t _payload[GAP_ADVERTISING_DATA_MAX_PAYLOAD]; uint8_t _payloadLen; uint16_t _appearance; From 484382e2aa8cfaa2a3095f67b1b0990fe26f536f Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Mon, 21 Dec 2015 10:44:55 +0000 Subject: [PATCH 27/27] Fix comment in GapAdvertisingData --- ble/GapAdvertisingData.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ble/GapAdvertisingData.h b/ble/GapAdvertisingData.h index ae9116b..7032042 100644 --- a/ble/GapAdvertisingData.h +++ b/ble/GapAdvertisingData.h @@ -253,7 +253,7 @@ public: uint8_t* field = findField(advDataType); if (field) { - // Field type already exist, either add to field or replace + // Field type already exist, replace field contents return updateField(advDataType, payload, len, field); } else { // field doesn't exists, return an error