From de70e6c5ce8f379e454941bc47bee31e5a161bfa Mon Sep 17 00:00:00 2001 From: "jihwan.seo" Date: Wed, 7 Sep 2016 20:40:29 +0900 Subject: [PATCH] [IOT-1332] support multi network state changed callback in base layer. Change-Id: I1027bb11d276d1daceafea1673ceaa5f2d9b4411 Signed-off-by: jihwan.seo Reviewed-on: https://gerrit.iotivity.org/gerrit/11505 Tested-by: jenkins-iotivity Reviewed-by: Ashok Babu Channa --- .../csdk/connectivity/src/cainterfacecontroller.c | 145 ++++++++++++++++++--- resource/csdk/stack/src/ocstack.c | 60 +++++++++ 2 files changed, 189 insertions(+), 16 deletions(-) diff --git a/resource/csdk/connectivity/src/cainterfacecontroller.c b/resource/csdk/connectivity/src/cainterfacecontroller.c index 5153b69..5d728a8 100644 --- a/resource/csdk/connectivity/src/cainterfacecontroller.c +++ b/resource/csdk/connectivity/src/cainterfacecontroller.c @@ -35,6 +35,7 @@ #include "cathreadpool.h" #include "caipadapter.h" #include "cainterface.h" +#include #ifdef RA_ADAPTER #include "caraadapter.h" @@ -55,11 +56,26 @@ static uint32_t g_numberOfAdapters = 0; static CANetworkPacketReceivedCallback g_networkPacketReceivedCallback = NULL; -static CAAdapterStateChangedCB g_adapterChangeCallback = NULL; +static CAErrorHandleCallback g_errorHandleCallback = NULL; -static CAConnectionStateChangedCB g_connChangeCallback = NULL; +static struct CANetworkCallback_t * g_networkChangeCallbackList = NULL; -static CAErrorHandleCallback g_errorHandleCallback = NULL; +/** + * network callback structure is handling + * for adapter state changed and connection state changed event. + */ +typedef struct CANetworkCallback_t { + + /** Linked list; for multiple callback list.*/ + struct CANetworkCallback_t * next; + + /** Adapter state changed event callback. */ + CAAdapterStateChangedCB adapter; + + /** Connection state changed event callback. */ + CAConnectionStateChangedCB conn; + +} CANetworkCallback_t; static int CAGetAdapterIndex(CATransportAdapter_t cType) { @@ -104,6 +120,93 @@ static void CARegisterCallback(CAConnectivityHandler_t handler) OIC_LOG_V(DEBUG, TAG, "%d type adapter, register complete!", handler.cType); } +/** + * Add a network callback from caller to the network callback list + * + * @param adapterCB adapter state changed callback + * @param connCB connection state changed callback + * + * @return + * CAResult_t + */ +static CAResult_t AddNetworkStateChangedCallback(CAAdapterStateChangedCB adapterCB, + CAConnectionStateChangedCB connCB) +{ + OIC_LOG(DEBUG, TAG, "Add NetworkStateChanged Callback"); + + if (!adapterCB || !connCB) + { + OIC_LOG(ERROR, TAG, "parameter is null"); + return CA_STATUS_INVALID_PARAM; + } + + CANetworkCallback_t* callback = NULL; + LL_FOREACH(g_networkChangeCallbackList, callback) + { + if (callback && adapterCB == callback->adapter && connCB == callback->conn) + { + OIC_LOG(DEBUG, TAG, "this callback is already added"); + return CA_STATUS_OK; + } + } + + callback = (CANetworkCallback_t *) OICCalloc(1, sizeof(CANetworkCallback_t)); + if (NULL == callback) + { + OIC_LOG(ERROR, TAG, "Memory allocation failed during registration"); + return CA_MEMORY_ALLOC_FAILED; + } + + callback->adapter = adapterCB; + callback->conn = connCB; + LL_APPEND(g_networkChangeCallbackList, callback); + return CA_STATUS_OK; +} + +/** + * Remove a network callback from the network callback list + * + * @param adapterCB adapter state changed callback + * @param connCB connection state changed callback + * + * @return + * CAResult_t + */ +static CAResult_t RemoveNetworkStateChangedCallback(CAAdapterStateChangedCB adapterCB, + CAConnectionStateChangedCB connCB) +{ + OIC_LOG(DEBUG, TAG, "Remove NetworkStateChanged Callback"); + + CANetworkCallback_t* callback = NULL; + LL_FOREACH(g_networkChangeCallbackList, callback) + { + if (callback && adapterCB == callback->adapter && connCB == callback->conn) + { + OIC_LOG(DEBUG, TAG, "remove specific callback"); + LL_DELETE(g_networkChangeCallbackList, callback); + OICFree(callback); + return CA_STATUS_OK; + } + } + return CA_STATUS_OK; +} + +/** + * Remove all network callback from the network callback list + */ +static void RemoveAllNetworkStateChangedCallback() +{ + OIC_LOG(DEBUG, TAG, "Remove All NetworkStateChanged Callback"); + + CANetworkCallback_t* callback = NULL; + LL_FOREACH(g_networkChangeCallbackList, callback) + { + OIC_LOG(DEBUG, TAG, "remove all callbacks"); + LL_DELETE(g_networkChangeCallbackList, callback); + OICFree(callback); + } +} + #ifdef RA_ADAPTER CAResult_t CASetAdapterRAInfo(const CARAInfo_t *caraInfo) { @@ -127,27 +230,35 @@ static void CAReceivedPacketCallback(const CASecureEndpoint_t *sep, static void CAAdapterChangedCallback(CATransportAdapter_t adapter, CANetworkStatus_t status) { // Call the callback. - if (g_adapterChangeCallback != NULL) + CANetworkCallback_t* callback = NULL; + LL_FOREACH(g_networkChangeCallbackList, callback) { - if (CA_INTERFACE_UP == status) - { - g_adapterChangeCallback(adapter, true); - } - else if (CA_INTERFACE_DOWN == status) + if (callback && callback->adapter) { - g_adapterChangeCallback(adapter, false); + if (CA_INTERFACE_UP == status) + { + callback->adapter(adapter, true); + } + else if (CA_INTERFACE_DOWN == status) + { + callback->adapter(adapter, false); + } } } - OIC_LOG_V(DEBUG, TAG, "[%d]adapter status is changed to [%d]", adapter, status); + OIC_LOG_V(DEBUG, TAG, "[%d] adapter status is changed to [%d]", adapter, status); } #if defined(TCP_ADAPTER) || defined(EDR_ADAPTER) || defined(LE_ADAPTER) static void CAConnectionChangedCallback(const CAEndpoint_t *info, bool isConnected) { // Call the callback. - if (g_connChangeCallback != NULL) + CANetworkCallback_t* callback = NULL; + LL_FOREACH(g_networkChangeCallbackList, callback) { - g_connChangeCallback(info, isConnected); + if (callback && callback->conn) + { + callback->conn(info, isConnected); + } } OIC_LOG_V(DEBUG, TAG, "[%s] connection status is changed to [%d]", info->addr, isConnected); } @@ -213,9 +324,11 @@ void CASetNetworkMonitorCallbacks(CAAdapterStateChangedCB adapterCB, CAConnectionStateChangedCB connCB) { OIC_LOG(DEBUG, TAG, "Set network monitoring callback"); - - g_adapterChangeCallback = adapterCB; - g_connChangeCallback = connCB; + CAResult_t res = AddNetworkStateChangedCallback(adapterCB, connCB); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "AddNetworkStateChangedCallback has failed"); + } } void CASetErrorHandleCallback(CAErrorHandleCallback errorCallback) diff --git a/resource/csdk/stack/src/ocstack.c b/resource/csdk/stack/src/ocstack.c index 7d7cd1b..a2082bf 100644 --- a/resource/csdk/stack/src/ocstack.c +++ b/resource/csdk/stack/src/ocstack.c @@ -58,6 +58,7 @@ #include "cainterface.h" #include "ocpayload.h" #include "ocpayloadcbor.h" +#include "cautilinterface.h" #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP) #include "routingutility.h" @@ -139,6 +140,9 @@ static const char COAP_TCP_SCHEME[] = "coap+tcp:"; static const char COAPS_TCP_SCHEME[] = "coaps+tcp:"; static const char CORESPEC[] = "core"; +CAAdapterStateChangedCB g_adapterHandler = NULL; +CAConnectionStateChangedCB g_connectionHandler = NULL; + //----------------------------------------------------------------------------- // Macros //----------------------------------------------------------------------------- @@ -413,6 +417,31 @@ static OCStackResult ResetPresenceTTL(ClientCB *cbNode, uint32_t maxAgeSeconds); */ static OCStackResult OCSendRequest(const CAEndpoint_t *object, CARequestInfo_t *requestInfo); +/** + * default adapter state change callback method + * + * @param adapter CA network adapter type. + * @param enabled current adapter state. + */ +static void OCDefaultAdapterStateChangedHandler(CATransportAdapter_t adapter, bool enabled); + +/** + * default connection state change callback method + * + * @param info CAEndpoint which has address, port and etc. + * @param isConnected current connection state. + */ +static void OCDefaultConnectionStateChangedHandler(const CAEndpoint_t *info, bool isConnected); + +/** + * Register network monitoring callback. + * Network status changes are delivered these callback. + * @param adapterHandler Adapter state monitoring callback. + * @param connectionHandler Connection state monitoring callback. + */ +static void OCSetNetworkMonitorHandler(CAAdapterStateChangedCB adapterHandler, + CAConnectionStateChangedCB connectionHandler); + //----------------------------------------------------------------------------- // Internal functions //----------------------------------------------------------------------------- @@ -2220,6 +2249,10 @@ OCStackResult OCInit1(OCMode mode, OCTransportFlags serverFlags, OCTransportFlag result = CAResultToOCResult(OCSelectNetwork()); VERIFY_SUCCESS(result, OC_STACK_OK); + result = CAResultToOCResult(CARegisterNetworkMonitorHandler( + OCDefaultAdapterStateChangedHandler, OCDefaultConnectionStateChangedHandler)); + VERIFY_SUCCESS(result, OC_STACK_OK); + switch (myStackMode) { case OC_CLIENT: @@ -4885,3 +4918,30 @@ OCStackResult OCGetResourceIns(OCResourceHandle handle, uint8_t *ins) return OC_STACK_ERROR; } #endif + +void OCDefaultAdapterStateChangedHandler(CATransportAdapter_t adapter, bool enabled) +{ + OIC_LOG(DEBUG, TAG, "OCDefaultAdapterStateChangedHandler"); + if (g_adapterHandler) + { + g_adapterHandler(adapter, enabled); + } +} + +void OCDefaultConnectionStateChangedHandler(const CAEndpoint_t *info, bool isConnected) +{ + OIC_LOG(DEBUG, TAG, "OCDefaultConnectionStateChangedHandler"); + if (g_connectionHandler) + { + g_connectionHandler(info, isConnected); + } +} + +void OCSetNetworkMonitorHandler(CAAdapterStateChangedCB adapterHandler, + CAConnectionStateChangedCB connectionHandler) +{ + OIC_LOG(DEBUG, TAG, "OCSetNetworkMonitorHandler"); + g_adapterHandler = adapterHandler; + g_connectionHandler = connectionHandler; +} + -- 2.7.4