Modify Consumer example & Logic to copy provider
[platform/upstream/iotivity.git] / service / notification / src / consumer / NSConsumerScheduler.c
index 2ab4c9b..8c8f5c9 100644 (file)
@@ -74,10 +74,13 @@ NSResult NSConsumerMessageHandlerInit()
     NSConsumerThread * handle = NULL;
     NSConsumerQueue * queue = NULL;
 
-    uint8_t uuid[UUID_SIZE];
-    char uuidString[UUID_STRING_SIZE];
-    OCGenerateUuid(uuid);
-    OCConvertUuidToString(uuid, uuidString);
+    uint8_t uuid[UUID_SIZE] = {0,};
+    char uuidString[UUID_STRING_SIZE] = {0,};
+    OCRandomUuidResult randomRet = OCGenerateUuid(uuid);
+    NS_VERIFY_NOT_NULL(randomRet == RAND_UUID_OK ? (void *) 1 : NULL, NS_ERROR);
+    randomRet = OCConvertUuidToString(uuid, uuidString);
+    NS_VERIFY_NOT_NULL(randomRet == RAND_UUID_OK ? (void *) 1 : NULL, NS_ERROR);
+
     NSSetConsumerId(uuidString);
     NS_LOG_V(DEBUG, "Consumer ID : %s", *NSGetConsumerId());
 
@@ -107,6 +110,8 @@ NSResult NSConsumerPushEvent(NSTask * task)
     NSConsumerThread * thread = NSThreadInit(NSConsumerMsgPushThreadFunc, (void *) task);
     NS_VERIFY_NOT_NULL(thread, NS_ERROR);
 
+    NSDestroyThreadHandle(thread);
+
     return NS_OK;
 }
 
@@ -171,16 +176,18 @@ void * NSConsumerMsgHandleThreadFunc(void * threadHandle)
 
 void * NSConsumerMsgPushThreadFunc(void * data)
 {
+    NSThreadDetach();
+
     NSConsumerQueueObject * obj = NULL;
     NSConsumerQueue * queue = NULL;
 
     NS_LOG(DEBUG, "get queueThread handle");
     NSConsumerThread * msgHandleThread = *(NSGetMsgHandleThreadHandle());
-    NS_VERIFY_NOT_NULL(msgHandleThread, NULL);
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(msgHandleThread, NULL, NSOICFree(data));
 
     NS_LOG(DEBUG, "create queue object");
     obj = (NSConsumerQueueObject *)OICMalloc(sizeof(NSConsumerQueueObject));
-    NS_VERIFY_NOT_NULL(obj, NULL);
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(obj, NULL, NSOICFree(data));
 
     obj->data = data;
     obj->next = NULL;
@@ -204,45 +211,136 @@ void * NSConsumerMsgPushThreadFunc(void * data)
     return NULL;
 }
 
-void NSConsumerTaskProcessing(NSTask * task)
+void NSProviderDeletedPostClean(
+        NSTask * task, NSProvider_internal * prov1, NSProvider_internal * prov2)
 {
-    switch (task->taskType)
+    if (task && task->taskData)
     {
-    case TASK_EVENT_CONNECTED:
-    case TASK_EVENT_CONNECTED_TCP:
-    case TASK_CONSUMER_REQ_DISCOVER:
-    {
-        NSConsumerDiscoveryTaskProcessing(task);
-        break;
+        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);
     }
-    case TASK_CONSUMER_REQ_SUBSCRIBE:
-    case TASK_SEND_SYNCINFO:
+
+    if (prov1)
     {
-        NSConsumerCommunicationTaskProcessing(task);
-        break;
+        NSRemoveProvider_internal(prov1);
     }
-    case TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL:
+
+    if (prov2)
     {
-        NSProvider_internal * data = NSCopyProvider((NSProvider_internal *)task->taskData);
-        NS_VERIFY_NOT_NULL_V(data);
-        NSTask * conTask = NSMakeTask(TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL, data);
-        NS_VERIFY_NOT_NULL_V(conTask);
-        NSConsumerCommunicationTaskProcessing(task);
-        NSConsumerInternalTaskProcessing(conTask);
-        break;
+        NSRemoveProvider_internal(prov2);
     }
-    case TASK_RECV_SYNCINFO:
-    case TASK_CONSUMER_RECV_MESSAGE:
-    case TASK_CONSUMER_PROVIDER_DISCOVERED:
-    case TASK_CONSUMER_RECV_SUBSCRIBE_CONFIRMED:
-    case TASK_MAKE_SYNCINFO:
+}
+
+void NSConsumerTaskProcessing(NSTask * task)
+{
+    switch (task->taskType)
     {
-        NSConsumerInternalTaskProcessing(task);
-        break;
-    }
-    default:
-        NS_LOG(ERROR, "Unknown type of task");
-        break;
+        case TASK_EVENT_CONNECTED:
+        case TASK_EVENT_CONNECTED_TCP:
+        case TASK_CONSUMER_REQ_DISCOVER:
+        {
+            NSConsumerDiscoveryTaskProcessing(task);
+            break;
+        }
+        case TASK_CONSUMER_REQ_SUBSCRIBE:
+        {
+            NSProvider_internal * prov =
+                    NSConsumerFindNSProvider(((NSProvider *)task->taskData)->providerId);
+            NS_VERIFY_NOT_NULL_V(prov);
+            NSTask * subTask = NSMakeTask(TASK_CONSUMER_REQ_SUBSCRIBE, prov);
+            NS_VERIFY_NOT_NULL_V(subTask);
+            NSConsumerCommunicationTaskProcessing(subTask);
+
+            NSRemoveProvider((NSProvider *)task->taskData);
+            NSOICFree(task);
+            break;
+        }
+        case TASK_SEND_SYNCINFO:
+        case TASK_CONSUMER_REQ_TOPIC_LIST:
+        {
+            NSConsumerCommunicationTaskProcessing(task);
+            break;
+        }
+        case TASK_CONSUMER_GET_TOPIC_LIST:
+        case TASK_CONSUMER_SELECT_TOPIC_LIST:
+        {
+            NSProvider * provider = (NSProvider *)task->taskData;
+            NSProvider_internal * prov =
+                    NSConsumerFindNSProvider(provider->providerId);
+            NS_VERIFY_NOT_NULL_V(prov);
+            if (task->taskType == TASK_CONSUMER_SELECT_TOPIC_LIST)
+            {
+                NSRemoveTopicLL(prov->topicLL);
+                prov->topicLL = NSCopyTopicLL((NSTopicLL *)provider->topicLL);
+            }
+
+            NSTask * topTask = NSMakeTask(task->taskType, prov);
+            NS_VERIFY_NOT_NULL_V(topTask);
+            NSConsumerCommunicationTaskProcessing(topTask);
+
+            NSRemoveProvider((NSProvider *)task->taskData);
+            NSOICFree(task);
+            break;
+        }
+        case TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL:
+        case TASK_CONSUMER_PROVIDER_DELETED:
+        {
+            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_WITH_POST_CLEANING_V(
+                        conTask, NSProviderDeletedPostClean(task, data, data2));
+            NSConsumerCommunicationTaskProcessing(conTask);
+
+            NSTask * conTask2 = NSMakeTask(TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL, data2);
+            NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(
+                        conTask, NSProviderDeletedPostClean(task, NULL, data2));
+            NSConsumerInternalTaskProcessing(conTask2);
+
+            NSProviderDeletedPostClean(task, NULL, NULL);
+            break;
+        }
+        case TASK_RECV_SYNCINFO:
+        case TASK_CONSUMER_RECV_MESSAGE:
+        case TASK_CONSUMER_PROVIDER_DISCOVERED:
+        case TASK_CONSUMER_SENT_REQ_OBSERVE:
+        case TASK_CONSUMER_RECV_PROVIDER_CHANGED:
+        case TASK_MAKE_SYNCINFO:
+        case TASK_CONSUMER_REQ_TOPIC_URI:
+        case TASK_CONSUMER_RECV_TOPIC_LIST:
+        {
+            NSConsumerInternalTaskProcessing(task);
+            break;
+        }
+        default:
+        {
+            NS_LOG(ERROR, "Unknown type of task");
+            break;
+        }
     }
 }