From f24df33e7721ba8457a19051851efd2177f53613 Mon Sep 17 00:00:00 2001 From: "hyuna0213.jo" Date: Wed, 23 Nov 2016 22:51:58 +0900 Subject: [PATCH] [IOT-1602] Remove observer when the tcp connection is disconnected If the client observes one or more resources over a reliable connection, then the CoAP server (or intermediary in the role of the CoAP server) MUST remove all entries associated with the client endpoint from the lists of observers when the connection is either closed or times out. Bug: https://jira.iotivity.org/browse/IOT-1602 Change-Id: I31dcf26a3dc731b4479c9d7a7a4755c7afd07ff8 Signed-off-by: hyuna0213.jo Reviewed-on: https://gerrit.iotivity.org/gerrit/14683 Tested-by: jenkins-iotivity Reviewed-by: Jaewook Jung Reviewed-by: Ziran Sun (cherry picked from commit 76ac4cfd9ffb58a17c93d74c3f6a21b11b07cf50) Reviewed-on: https://gerrit.iotivity.org/gerrit/15147 Reviewed-by: jihwan seo Reviewed-by: Jaehong Jo Reviewed-by: Dan Mihai --- .../connectivity/src/tcp_adapter/catcpserver.c | 6 +++++ resource/csdk/stack/include/internal/ocobserve.h | 10 +++++++++ resource/csdk/stack/src/ocobserve.c | 26 ++++++++++++++++++++++ resource/csdk/stack/src/ocstack.c | 15 +++++++++++++ 4 files changed, 57 insertions(+) diff --git a/resource/csdk/connectivity/src/tcp_adapter/catcpserver.c b/resource/csdk/connectivity/src/tcp_adapter/catcpserver.c index 1ee5820..4d872a0 100644 --- a/resource/csdk/connectivity/src/tcp_adapter/catcpserver.c +++ b/resource/csdk/connectivity/src/tcp_adapter/catcpserver.c @@ -364,6 +364,12 @@ static void CAAcceptConnection(CATransportFlags_t flag, CASocket_t *sock) oc_mutex_unlock(g_mutexObjectList); CHECKFD(sockfd); + + // pass the connection information to CA Common Layer. + if (g_connectionCallback) + { + g_connectionCallback(&(svritem->sep.endpoint), true); + } } } diff --git a/resource/csdk/stack/include/internal/ocobserve.h b/resource/csdk/stack/include/internal/ocobserve.h index 85ecd4e..284cfba 100644 --- a/resource/csdk/stack/include/internal/ocobserve.h +++ b/resource/csdk/stack/include/internal/ocobserve.h @@ -191,6 +191,16 @@ OCStackResult AddObserver (const char *resUri, */ OCStackResult DeleteObserverUsingToken (CAToken_t token, uint8_t tokenLength); + /** + * Delete observer with device address from list of observers. + * Free memory that was allocated for the observer in the list. + * + * @param devAddr Device's address. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult DeleteObserverUsingDevAddr(const OCDevAddr *devAddr); + /** * Search the list of observers for the specified token. * diff --git a/resource/csdk/stack/src/ocobserve.c b/resource/csdk/stack/src/ocobserve.c index b074ffe..5bb1a6b 100644 --- a/resource/csdk/stack/src/ocobserve.c +++ b/resource/csdk/stack/src/ocobserve.c @@ -552,6 +552,32 @@ OCStackResult DeleteObserverUsingToken (CAToken_t token, uint8_t tokenLength) return OC_STACK_OK; } +OCStackResult DeleteObserverUsingDevAddr(const OCDevAddr *devAddr) +{ + if (!devAddr) + { + return OC_STACK_INVALID_PARAM; + } + + ResourceObserver *out = NULL; + ResourceObserver *tmp = NULL; + LL_FOREACH_SAFE(g_serverObsList, out, tmp) + { + if (out) + { + if ((strcmp(out->devAddr.addr, devAddr->addr) == 0) + && out->devAddr.port == devAddr->port) + { + OIC_LOG_V(INFO, TAG, "deleting observer id %u with %s:%u", + out->observeId, out->devAddr.addr, out->devAddr.port); + OCStackFeedBack(out->token, out->tokenLength, OC_OBSERVER_NOT_INTERESTED); + } + } + } + + return OC_STACK_OK; +} + void DeleteObserverList() { ResourceObserver *out = NULL; diff --git a/resource/csdk/stack/src/ocstack.c b/resource/csdk/stack/src/ocstack.c index 4bfd27d..25adfbf 100644 --- a/resource/csdk/stack/src/ocstack.c +++ b/resource/csdk/stack/src/ocstack.c @@ -5179,6 +5179,21 @@ void OCDefaultConnectionStateChangedHandler(const CAEndpoint_t *info, bool isCon { g_connectionHandler(info, isConnected); } + + /* + * If the client observes one or more resources over a reliable connection, + * then the CoAP server (or intermediary in the role of the CoAP server) + * MUST remove all entries associated with the client endpoint from the lists + * of observers when the connection is either closed or times out. + */ + if (!isConnected) + { + OCDevAddr devAddr = { OC_DEFAULT_ADAPTER }; + CopyEndpointToDevAddr(info, &devAddr); + + // remove observer list with remote device address. + DeleteObserverUsingDevAddr(&devAddr); + } } void OCSetNetworkMonitorHandler(CAAdapterStateChangedCB adapterHandler, -- 2.7.4