Allow for multiple callers to otSetStateChangeCallback. (#811)

* Allow for multiple callers to otSetStateChangeCallback.
This commit is contained in:
pvanhorn
2016-10-13 17:32:16 -07:00
committed by Jonathan Hui
parent 9c252dbac7
commit ddd0704b76
6 changed files with 126 additions and 5 deletions
+14 -1
View File
@@ -868,8 +868,21 @@ typedef void (*otStateChangedCallback)(uint32_t aFlags, void *aContext);
* @param[in] aCallback A pointer to a function that is called with certain configuration or state changes.
* @param[in] aContext A pointer to application-specific context.
*
* @retval kThreadError_None Added the callback to the list of callbacks.
* @retval kThreadError_NoBufs Could not add the callback due to resource constraints.
*
*/
void otSetStateChangedCallback(otInstance *aInstance, otStateChangedCallback aCallback, void *aContext);
ThreadError otSetStateChangedCallback(otInstance *aInstance, otStateChangedCallback aCallback, void *aContext);
/**
* This function removes a callback to indicate when certain configuration or state changes within OpenThread.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aCallback A pointer to a function that is called with certain configuration or state changes.
* @param[in] aContext A pointer to application-specific context.
*
*/
void otRemoveStateChangeCallback(otInstance *aInstance, otStateChangedCallback aCallback, void *aCallbackContext);
/**
* This function gets the Active Operational Dataset.
+29
View File
@@ -74,6 +74,35 @@ exit:
return error;
}
ThreadError Netif::RemoveCallback(NetifCallback &aCallback)
{
ThreadError error = kThreadError_Already;
NetifCallback *prev = NULL;
for (NetifCallback *cur = mCallbacks; cur; cur = cur->mNext)
{
if (cur == &aCallback)
{
if (prev)
{
prev->mNext = cur->mNext;
}
else
{
mCallbacks = mCallbacks->mNext;
}
cur->mNext = NULL;
error = kThreadError_None;
break;
}
prev = cur;
}
return error;
}
Netif *Netif::GetNext() const
{
return mNext;
+43
View File
@@ -176,6 +176,39 @@ public:
mContext = aContext;
}
/**
* This method tests whether the object is free or in use.
*
* @returns True if the object is free, false otherwise.
*
*/
bool IsFree(void) {
return (mCallback == NULL);
}
/**
* This method frees the object.
*
*/
void Free(void) {
mCallback = NULL;
mContext = NULL;
mNext = NULL;
}
/**
* This method tests whether the object is set to the provided elements.
*
* @param[in] aCallback A pointer to a function that is called when configuration or state changes.
* @param[in] aContext A pointer to arbitrary context information.
*
* @returns True if the object elements equal the input params, false otherwise.
*
*/
bool IsServing(otStateChangedCallback aCallback, void *aContext) {
return (aCallback == mCallback && aContext == mContext);
}
private:
void Callback(uint32_t aFlags) {
if (mCallback != NULL) {
@@ -347,6 +380,16 @@ public:
*/
ThreadError RegisterCallback(NetifCallback &aCallback);
/**
* This method removes a network interface callback.
*
* @param[in] aCallback A reference to the callback.
*
* @retval kThreadError_None Successfully removed the callback.
* @retval kThreadError_Already The callback was not in the list.
*/
ThreadError RemoveCallback(NetifCallback &aCallback);
/**
* This method indicates whether or not a state changed callback is pending.
*
+11
View File
@@ -185,6 +185,17 @@
#define OPENTHREAD_CONFIG_MAX_JOINER_ENTRIES 2
#endif // OPENTHREAD_CONFIG_MAX_JOINER_ENTRIES
/**
* @def OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS
*
* The number of message buffers in the buffer pool.
*
*/
#ifndef OPENTHREAD_CONFIG_MAX_STATECHANGE_HANDLERS
#define OPENTHREAD_CONFIG_MAX_STATECHANGE_HANDLERS 1
#endif // OPENTHREAD_CONFIG_MAX_STATECHANGE_HANDLERS
/**
* @def OPENTHREAD_CONFIG_LOG_LEVEL
*
+2 -1
View File
@@ -38,6 +38,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <openthread-core-config.h>
#include <openthread-types.h>
#include <crypto/mbedtls.hpp>
#include <net/ip6.hpp>
@@ -52,7 +53,7 @@ typedef struct otInstance
// Callbacks
//
Thread::Ip6::NetifCallback mNetifCallback;
Thread::Ip6::NetifCallback mNetifCallback[OPENTHREAD_CONFIG_MAX_STATECHANGE_HANDLERS];
otReceiveIp6DatagramCallback mReceiveIp6DatagramCallback;
void *mReceiveIp6DatagramCallbackContext;
+27 -3
View File
@@ -925,10 +925,34 @@ ThreadError otCreateSemanticallyOpaqueIid(otInstance *aInstance, otNetifAddress
return static_cast<Utils::SemanticallyOpaqueIidGenerator *>(aContext)->CreateIid(aInstance, aAddress);
}
void otSetStateChangedCallback(otInstance *aInstance, otStateChangedCallback aCallback, void *aCallbackContext)
ThreadError otSetStateChangedCallback(otInstance *aInstance, otStateChangedCallback aCallback, void *aCallbackContext)
{
aInstance->mNetifCallback.Set(aCallback, aCallbackContext);
aInstance->mThreadNetif.RegisterCallback(aInstance->mNetifCallback);
ThreadError error = kThreadError_NoBufs;
for (size_t i = 0; i < OPENTHREAD_CONFIG_MAX_STATECHANGE_HANDLERS; i++)
{
if (aInstance->mNetifCallback[i].IsFree())
{
aInstance->mNetifCallback[i].Set(aCallback, aCallbackContext);
error = aInstance->mThreadNetif.RegisterCallback(aInstance->mNetifCallback[i]);
break;
}
}
return error;
}
void otRemoveStateChangeCallback(otInstance *aInstance, otStateChangedCallback aCallback, void *aCallbackContext)
{
for (size_t i = 0; i < OPENTHREAD_CONFIG_MAX_STATECHANGE_HANDLERS; i++)
{
if (aInstance->mNetifCallback[i].IsServing(aCallback, aCallbackContext))
{
aInstance->mThreadNetif.RemoveCallback(aInstance->mNetifCallback[i]);
aInstance->mNetifCallback[i].Free();
break;
}
}
}
const char *otGetVersionString(void)