From 80c944e64b1febb010ed0dee8dd8feeb60c051e5 Mon Sep 17 00:00:00 2001 From: "hyuna0213.jo" Date: Mon, 12 Dec 2016 21:02:51 +0900 Subject: [PATCH] [IOT-1671] Fixed base layer terminate logic - ObserverList should be removed before destroying ResourceList to avoid the error of dangling pointer. because ResourceObserver object includes a resource handle which is memory address allocated when resource is created. - Add function to unset network monitoring callback when OCStop() is called. bug: https://jira.iotivity.org/browse/IOT-1671 Change-Id: I8a367a24a2100c97bf612db26bc41db5f47f2feb Signed-off-by: hyuna0213.jo Reviewed-on: https://gerrit.iotivity.org/gerrit/15499 Tested-by: jenkins-iotivity Reviewed-by: Dan Mihai Reviewed-by: jihwan seo Reviewed-by: Ashok Babu Channa --- resource/csdk/connectivity/api/cautilinterface.h | 10 ++++ .../csdk/connectivity/inc/cainterfacecontroller.h | 9 ++++ .../csdk/connectivity/src/cainterfacecontroller.c | 12 +++++ .../csdk/connectivity/util/src/cautilinterface.c | 8 ++++ resource/csdk/stack/src/ocstack.c | 53 +++++++++++++--------- 5 files changed, 71 insertions(+), 21 deletions(-) diff --git a/resource/csdk/connectivity/api/cautilinterface.h b/resource/csdk/connectivity/api/cautilinterface.h index 8904814..47d840a 100644 --- a/resource/csdk/connectivity/api/cautilinterface.h +++ b/resource/csdk/connectivity/api/cautilinterface.h @@ -56,6 +56,16 @@ CAResult_t CARegisterNetworkMonitorHandler(CAAdapterStateChangedCB adapterStateC CAConnectionStateChangedCB connStateCB); /** + * Unregister network monitoring callback. + * @param[in] adapterStateCB Adapter state monitoring callback. + * @param[in] connStateCB Connection state monitoring callback. + * + * @return ::CA_STATUS_OK or ::CA_STATUS_FAILED or ::CA_MEMORY_ALLOC_FAILED + */ +CAResult_t CAUnregisterNetworkMonitorHandler(CAAdapterStateChangedCB adapterStateCB, + CAConnectionStateChangedCB connStateCB); + +/** * Set device to handle for auto connection. * @param[in] address LE address to set. * diff --git a/resource/csdk/connectivity/inc/cainterfacecontroller.h b/resource/csdk/connectivity/inc/cainterfacecontroller.h index 1fe36e9..4f48452 100644 --- a/resource/csdk/connectivity/inc/cainterfacecontroller.h +++ b/resource/csdk/connectivity/inc/cainterfacecontroller.h @@ -76,6 +76,15 @@ void CASetNetworkMonitorCallbacks(CAAdapterStateChangedCB adapterCB, CAConnectionStateChangedCB connCB); /** + * Unset the network status changed callback for CAUtil. + * @param[in] adapterCB CAUtil callback to receive adapter status changes. + * @param[in] connCB CAUtil callback to receive connection status changes. + * @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h). + */ +CAResult_t CAUnsetNetworkMonitorCallbacks(CAAdapterStateChangedCB adapterCB, + CAConnectionStateChangedCB connCB); + +/** * Starting different connectivity adapters based on the network selection. * @param[in] transportType interested network for starting. * @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h). diff --git a/resource/csdk/connectivity/src/cainterfacecontroller.c b/resource/csdk/connectivity/src/cainterfacecontroller.c index 5d728a8..b0ffc3f 100644 --- a/resource/csdk/connectivity/src/cainterfacecontroller.c +++ b/resource/csdk/connectivity/src/cainterfacecontroller.c @@ -331,6 +331,18 @@ void CASetNetworkMonitorCallbacks(CAAdapterStateChangedCB adapterCB, } } +CAResult_t CAUnsetNetworkMonitorCallbacks(CAAdapterStateChangedCB adapterCB, + CAConnectionStateChangedCB connCB) +{ + OIC_LOG(DEBUG, TAG, "Unset network monitoring callback"); + CAResult_t res = RemoveNetworkStateChangedCallback(adapterCB, connCB); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "RemoveNetworkStateChangedCallback has failed"); + } + return res; +} + void CASetErrorHandleCallback(CAErrorHandleCallback errorCallback) { OIC_LOG(DEBUG, TAG, "Set error handle callback"); diff --git a/resource/csdk/connectivity/util/src/cautilinterface.c b/resource/csdk/connectivity/util/src/cautilinterface.c index 6a848ff..11a108c 100644 --- a/resource/csdk/connectivity/util/src/cautilinterface.c +++ b/resource/csdk/connectivity/util/src/cautilinterface.c @@ -36,6 +36,14 @@ CAResult_t CARegisterNetworkMonitorHandler(CAAdapterStateChangedCB adapterStateC return CA_STATUS_OK; } +CAResult_t CAUnregisterNetworkMonitorHandler(CAAdapterStateChangedCB adapterStateCB, + CAConnectionStateChangedCB connStateCB) +{ + OIC_LOG(DEBUG, TAG, "CAUnregisterNetworkMonitorHandler"); + + return CAUnsetNetworkMonitorCallbacks(adapterStateCB, connStateCB); +} + CAResult_t CASetAutoConnectionDeviceInfo(const char *address) { OIC_LOG(DEBUG, TAG, "CASetAutoConnectionDeviceInfo"); diff --git a/resource/csdk/stack/src/ocstack.c b/resource/csdk/stack/src/ocstack.c index bde9b0e..66ac3bf 100644 --- a/resource/csdk/stack/src/ocstack.c +++ b/resource/csdk/stack/src/ocstack.c @@ -544,8 +544,8 @@ OCStackResult OCStackFeedBack(CAToken_t token, uint8_t tokenLength, uint8_t stat { case OC_OBSERVER_NOT_INTERESTED: OIC_LOG(DEBUG, TAG, "observer not interested in our notifications"); - observer = GetObserverUsingToken (token, tokenLength); - if(observer) + observer = GetObserverUsingToken(token, tokenLength); + if (observer) { result = FormOCEntityHandlerRequest(&ehRequest, 0, @@ -557,16 +557,20 @@ OCStackResult OCStackFeedBack(CAToken_t token, uint8_t tokenLength, uint8_t stat OC_OBSERVE_DEREGISTER, observer->observeId, 0); - if(result != OC_STACK_OK) + if (result != OC_STACK_OK) { return result; } - observer->resource->entityHandler(OC_OBSERVE_FLAG, &ehRequest, - observer->resource->entityHandlerCallbackParam); + + if (observer->resource && observer->resource->entityHandler) + { + observer->resource->entityHandler(OC_OBSERVE_FLAG, &ehRequest, + observer->resource->entityHandlerCallbackParam); + } } - result = DeleteObserverUsingToken (token, tokenLength); - if(result == OC_STACK_OK) + result = DeleteObserverUsingToken(token, tokenLength); + if (result == OC_STACK_OK) { OIC_LOG(DEBUG, TAG, "Removed observer successfully"); } @@ -579,8 +583,8 @@ OCStackResult OCStackFeedBack(CAToken_t token, uint8_t tokenLength, uint8_t stat case OC_OBSERVER_STILL_INTERESTED: OIC_LOG(DEBUG, TAG, "observer still interested, reset the failedCount"); - observer = GetObserverUsingToken (token, tokenLength); - if(observer) + observer = GetObserverUsingToken(token, tokenLength); + if (observer) { observer->forceHighQos = 0; observer->failedCommCount = 0; @@ -595,9 +599,9 @@ OCStackResult OCStackFeedBack(CAToken_t token, uint8_t tokenLength, uint8_t stat case OC_OBSERVER_FAILED_COMM: OIC_LOG(DEBUG, TAG, "observer is unreachable"); observer = GetObserverUsingToken (token, tokenLength); - if(observer) + if (observer) { - if(observer->failedCommCount >= MAX_OBSERVER_FAILED_COMM) + if (observer->failedCommCount >= MAX_OBSERVER_FAILED_COMM) { result = FormOCEntityHandlerRequest(&ehRequest, 0, @@ -609,15 +613,19 @@ OCStackResult OCStackFeedBack(CAToken_t token, uint8_t tokenLength, uint8_t stat OC_OBSERVE_DEREGISTER, observer->observeId, 0); - if(result != OC_STACK_OK) + if (result != OC_STACK_OK) { return OC_STACK_ERROR; } - observer->resource->entityHandler(OC_OBSERVE_FLAG, &ehRequest, - observer->resource->entityHandlerCallbackParam); - result = DeleteObserverUsingToken (token, tokenLength); - if(result == OC_STACK_OK) + if (observer->resource && observer->resource->entityHandler) + { + observer->resource->entityHandler(OC_OBSERVE_FLAG, &ehRequest, + observer->resource->entityHandlerCallbackParam); + } + + result = DeleteObserverUsingToken(token, tokenLength); + if (result == OC_STACK_OK) { OIC_LOG(DEBUG, TAG, "Removed observer successfully"); } @@ -2238,9 +2246,9 @@ exit: if(result != OC_STACK_OK) { OIC_LOG(ERROR, TAG, "Stack initialization error"); + TerminateScheduleResourceList(); deleteAllResources(); CATerminate(); - TerminateScheduleResourceList(); stackState = OC_STACK_UNINITIALIZED; } return result; @@ -2263,6 +2271,9 @@ OCStackResult OCStop() stackState = OC_STACK_UNINIT_IN_PROGRESS; + CAUnregisterNetworkMonitorHandler(OCDefaultAdapterStateChangedHandler, + OCDefaultConnectionStateChangedHandler); + #ifdef WITH_PRESENCE // Ensure that the TTL associated with ANY and ALL presence notifications originating from // here send with the code "OC_STACK_PRESENCE_STOPPED" result. @@ -2280,20 +2291,20 @@ OCStackResult OCStop() TerminateKeepAlive(myStackMode); #endif - // Free memory dynamically allocated for resources - deleteAllResources(); - CATerminate(); TerminateScheduleResourceList(); // Remove all observers DeleteObserverList(); + // Free memory dynamically allocated for resources + deleteAllResources(); // Remove all the client callbacks DeleteClientCBList(); + // Terminate connectivity-abstraction layer. + CATerminate(); // De-init the SRM Policy Engine // TODO after BeachHead delivery: consolidate into single SRMDeInit() SRMDeInitPolicyEngine(); - stackState = OC_STACK_UNINITIALIZED; return OC_STACK_OK; } -- 2.7.4