From 92ee16946430aa26263d47957dcc5edbebeb173c Mon Sep 17 00:00:00 2001 From: KIM JungYong Date: Thu, 18 Aug 2016 15:56:54 +0900 Subject: [PATCH] Add consumer logic for provider was stopped. When consumer presence listener received event of stopped provider or deleted notification resource of provider, consumer service does not act anything. In this patch, consumer service will process for canceling observe and removing provider infomation. Change-Id: I9133ddbcbe8e341584ebaf8152c22df003cbb2ff Signed-off-by: KIM JungYong Reviewed-on: https://gerrit.iotivity.org/gerrit/10587 Reviewed-by: Chihyun Cho Tested-by: jenkins-iotivity Reviewed-by: Uze Choi --- .../notification/src/consumer/NSConsumerCommon.c | 1 + .../src/consumer/NSConsumerDiscovery.c | 9 +++- .../consumer/NSConsumerInternalTaskController.c | 19 +++++++ .../consumer/NSConsumerInternalTaskController.h | 2 + .../src/consumer/NSConsumerMemoryCache.c | 37 +++++++++++++ .../src/consumer/NSConsumerMemoryCache.h | 2 + .../src/consumer/NSConsumerScheduler.c | 62 ++++++++++++++++++---- 7 files changed, 121 insertions(+), 11 deletions(-) diff --git a/service/notification/src/consumer/NSConsumerCommon.c b/service/notification/src/consumer/NSConsumerCommon.c index 7f36b32..93ced34 100644 --- a/service/notification/src/consumer/NSConsumerCommon.c +++ b/service/notification/src/consumer/NSConsumerCommon.c @@ -572,6 +572,7 @@ bool NSOCResultToSuccess(OCStackResult ret) case OC_STACK_RESOURCE_CHANGED: return true; default: + NS_LOG_V(DEBUG, "OCStackResult : %d", (int)ret); return false; } } diff --git a/service/notification/src/consumer/NSConsumerDiscovery.c b/service/notification/src/consumer/NSConsumerDiscovery.c index 48a7041..435430d 100644 --- a/service/notification/src/consumer/NSConsumerDiscovery.c +++ b/service/notification/src/consumer/NSConsumerDiscovery.c @@ -64,9 +64,14 @@ OCStackApplicationResult NSConsumerPresenceListener( if (payload->trigger == OC_PRESENCE_TRIGGER_DELETE || clientResponse->result == OC_STACK_PRESENCE_STOPPED) { - // TODO find request and cancel NS_LOG(DEBUG, "stopped presence or resource is deleted."); - //OCCancel(handle, NS_QOS, NULL, 0); + NS_LOG(DEBUG, "build NSTask"); + OCDevAddr * addr = (OCDevAddr *)OICMalloc(sizeof(OCDevAddr)); + NS_VERIFY_NOT_NULL(addr, OC_STACK_KEEP_TRANSACTION); + memcpy(addr, clientResponse->addr, sizeof(OCDevAddr)); + + NSTask * task = NSMakeTask(TASK_CONSUMER_PROVIDER_DELETED, addr); + NS_VERIFY_NOT_NULL(task, OC_STACK_KEEP_TRANSACTION); } else if (payload->trigger == OC_PRESENCE_TRIGGER_CREATE) diff --git a/service/notification/src/consumer/NSConsumerInternalTaskController.c b/service/notification/src/consumer/NSConsumerInternalTaskController.c index e6f285d..06742bf 100644 --- a/service/notification/src/consumer/NSConsumerInternalTaskController.c +++ b/service/notification/src/consumer/NSConsumerInternalTaskController.c @@ -112,6 +112,25 @@ NSProvider_internal * NSProviderCacheFind(const char * providerId) return NSCopyProvider_internal((NSProvider_internal *) cacheElement->data); } +NSProvider_internal * NSFindProviderFromAddr(OCDevAddr * addr) +{ + NS_VERIFY_NOT_NULL(addr, NULL); + + NSCacheList * ProviderCache = *(NSGetProviderCacheList()); + if (!ProviderCache) + { + NS_LOG(DEBUG, "Provider Cache does not intialized."); + return NULL; + } + + NSCacheElement * cacheElement = + NSGetProviderFromAddr(ProviderCache, addr->addr, addr->port); + + NS_VERIFY_NOT_NULL(cacheElement, NULL); + + return NSCopyProvider_internal((NSProvider_internal *) cacheElement->data); +} + void NSRemoveCacheElementMessage(NSCacheElement * obj) { NSRemoveMessage(((NSStoreMessage *)obj->data)->msg); diff --git a/service/notification/src/consumer/NSConsumerInternalTaskController.h b/service/notification/src/consumer/NSConsumerInternalTaskController.h index de3394d..cbe4cfa 100644 --- a/service/notification/src/consumer/NSConsumerInternalTaskController.h +++ b/service/notification/src/consumer/NSConsumerInternalTaskController.h @@ -48,6 +48,8 @@ NSMessage * NSMessageCacheFind(const char *); NSProvider_internal * NSProviderCacheFind(const char *); +NSProvider_internal * NSFindProviderFromAddr(OCDevAddr * addr); + void NSConsumerInternalTaskProcessing(NSTask *); #ifdef __cplusplus diff --git a/service/notification/src/consumer/NSConsumerMemoryCache.c b/service/notification/src/consumer/NSConsumerMemoryCache.c index 38fce40..22672bc 100644 --- a/service/notification/src/consumer/NSConsumerMemoryCache.c +++ b/service/notification/src/consumer/NSConsumerMemoryCache.c @@ -78,6 +78,43 @@ NSCacheElement * NSStorageRead(NSCacheList * list, const char * findId) return NULL; } +NSCacheElement * NSGetProviderFromAddr(NSCacheList * list, const char * addr, uint16_t port) +{ + NS_VERIFY_NOT_NULL(list, NULL); + NS_VERIFY_NOT_NULL(addr, NULL); + NS_VERIFY_NOT_NULL( + (list->cacheType != NS_CONSUMER_CACHE_PROVIDER) ? NULL : (void *) 1, NULL); + + pthread_mutex_t * mutex = NSGetCacheMutex(); + pthread_mutex_lock(mutex); + + NSCacheElement * iter = list->head; + + while (iter) + { + NSProviderConnectionInfo * connection = + ((NSProviderConnectionInfo *) iter->data)->next; + while (connection) + { + char * conAddr = connection->addr->addr; + uint16_t conPort = connection->addr->port; + + if (!strcmp(conAddr, addr) && conPort == port) + { + pthread_mutex_unlock(mutex); + return iter; + } + connection = connection->next; + } + + iter = iter->next; + } + + NS_LOG (DEBUG, "No Cache Element"); + pthread_mutex_unlock(mutex); + return NULL; +} + NSResult NSStorageWrite(NSCacheList * list, NSCacheElement * newObj) { NS_VERIFY_NOT_NULL(list, NS_ERROR); diff --git a/service/notification/src/consumer/NSConsumerMemoryCache.h b/service/notification/src/consumer/NSConsumerMemoryCache.h index 69702a4..76ab968 100644 --- a/service/notification/src/consumer/NSConsumerMemoryCache.h +++ b/service/notification/src/consumer/NSConsumerMemoryCache.h @@ -37,6 +37,8 @@ NSResult NSConsumerCacheWriteMessage(NSCacheList * list, NSCacheElement * newObj NSResult NSConsumerCacheWriteProvider(NSCacheList * list, NSCacheElement * newObj); NSCacheElement * NSPopProviderCacheList(NSCacheList * list); +NSCacheElement * NSGetProviderFromAddr(NSCacheList * list, const char * addr, uint16_t port); + #ifdef __cplusplus } #endif // __cplusplus diff --git a/service/notification/src/consumer/NSConsumerScheduler.c b/service/notification/src/consumer/NSConsumerScheduler.c index 1e4b5f8..7e85eab 100644 --- a/service/notification/src/consumer/NSConsumerScheduler.c +++ b/service/notification/src/consumer/NSConsumerScheduler.c @@ -211,6 +211,33 @@ void * NSConsumerMsgPushThreadFunc(void * data) return NULL; } +void NSProviderDeletedPostClean( + NSTask * task, NSProvider_internal * prov1, NSProvider_internal * prov2) +{ + if (task && task->taskData) + { + if (task->taskType == TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL) + { + NSRemoveProvider((NSProvider *) task->taskData); + } + else if (task->taskType == TASK_CONSUMER_PROVIDER_DELETED) + { + NSOICFree(task->taskData); + } + NSOICFree(task); + } + + if (prov1) + { + NSRemoveProvider_internal(prov1); + } + + if (prov2) + { + NSRemoveProvider_internal(prov2); + } +} + void NSConsumerTaskProcessing(NSTask * task) { switch (task->taskType) @@ -256,21 +283,38 @@ void NSConsumerTaskProcessing(NSTask * task) break; } case TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL: + case TASK_CONSUMER_PROVIDER_DELETED: { - NSProvider_internal * data = - NSConsumerFindNSProvider(((NSProvider *)task->taskData)->providerId); - NS_VERIFY_NOT_NULL_V(data); + NSProvider_internal * data = NULL; + + if (task->taskType == TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL) + { + data = NSConsumerFindNSProvider(((NSProvider *) task->taskData)->providerId); + NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V( + data, NSProviderDeletedPostClean(task, NULL, NULL)); + } + else if (task->taskType == TASK_CONSUMER_PROVIDER_DELETED) + { + data = NSFindProviderFromAddr((OCDevAddr *) task->taskData); + NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V( + data, NSProviderDeletedPostClean(task, NULL, NULL)); + } + + NSProvider_internal * data2 = NSCopyProvider_internal(data); + NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V( + data2, NSProviderDeletedPostClean(task, data, NULL)); + NSTask * conTask = NSMakeTask(TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL, data); - NS_VERIFY_NOT_NULL_V(conTask); + NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V( + conTask, NSProviderDeletedPostClean(task, data, data2)); NSConsumerCommunicationTaskProcessing(conTask); - data = NSConsumerFindNSProvider(((NSProvider *)task->taskData)->providerId); - NS_VERIFY_NOT_NULL_V(data); - NSTask * conTask2 = NSMakeTask(TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL, data); + NSTask * conTask2 = NSMakeTask(TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL, data2); + NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V( + conTask, NSProviderDeletedPostClean(task, NULL, data2)); NSConsumerInternalTaskProcessing(conTask2); - NSRemoveProvider((NSProvider *)task->taskData); - NSOICFree(task); + NSProviderDeletedPostClean(task, NULL, NULL); break; } case TASK_RECV_SYNCINFO: -- 2.7.4