diff --git a/ble/Gap.h b/ble/Gap.h index 5e3f31b..5b4067a 100644 --- a/ble/Gap.h +++ b/ble/Gap.h @@ -161,6 +161,9 @@ class Gap { 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 @@ class Gap { 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,10 @@ class Gap { * scan parameters to default values. */ 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; state.connected = 0; @@ -1104,6 +1145,9 @@ class Gap { 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..c65207f 100644 --- a/ble/GattClient.h +++ b/ble/GattClient.h @@ -41,6 +41,9 @@ class GattClient { 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 @@ class GattClient { 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 @@ class GattClient { 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,10 @@ class GattClient { * @return BLE_ERROR_NONE on success. */ virtual ble_error_t reset(void) { + /* Notify that the instance is about to shutdown */ + shutdownCallChain.call(this); + shutdownCallChain.clear(); + onDataReadCallbackChain.clear(); onDataWriteCallbackChain.clear(); onHVXCallbackChain.clear(); @@ -367,9 +407,10 @@ class GattClient { } 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..ea46a88 100644 --- a/ble/GattServer.h +++ b/ble/GattServer.h @@ -36,6 +36,9 @@ class GattServer { 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 @@ class GattServer { 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 @@ class GattServer { 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,11 @@ class GattServer { * @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); + shutdownCallChain.clear(); + + serviceCount = 0; characteristicCount = 0; dataSentCallChain.clear(); @@ -426,12 +467,13 @@ class GattServer { 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..e508954 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 @@ class SecurityManager { 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 @@ class SecurityManager { /* 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 @@ class SecurityManager { 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,10 @@ class SecurityManager { * @return BLE_ERROR_NONE on success. */ virtual ble_error_t reset(void) { + /* Notify that the instance is about to shutdown */ + shutdownCallChain.call(this); + shutdownCallChain.clear(); + securitySetupInitiatedCallback = NULL; securitySetupCompletedCallback = NULL; linkSecuredCallback = NULL; @@ -259,6 +301,9 @@ class SecurityManager { LinkSecuredCallback_t linkSecuredCallback; HandleSpecificEvent_t securityContextStoredCallback; PasskeyDisplayCallback_t passkeyDisplayCallback; + +private: + SecurityManagerShutdownCallbackChain_t shutdownCallChain; }; #endif /*__SECURITY_MANAGER_H__*/