Modify Consumer example & Logic to copy provider
[platform/upstream/iotivity.git] / service / notification / src / consumer / NSConsumerCommunication.c
1 //******************************************************************
2 //
3 // Copyright 2016 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include "NSConsumerCommunication.h"
22
23 #include "NSConstants.h"
24 #include "NSUtil.h"
25 #include "NSConsumerCommon.h"
26 #include "oic_malloc.h"
27 #include "oic_string.h"
28 #include "ocpayload.h"
29
30 #define NS_SYNC_URI "/notification/sync"
31
32 static unsigned long NS_MESSAGE_ACCEPTANCE = 1;
33
34 NSMessage * NSCreateMessage_internal(uint64_t msgId, const char * providerId);
35 NSSyncInfo * NSCreateSyncInfo_consumer(uint64_t msgId, const char * providerId, NSSyncType state);
36
37 NSMessage * NSGetMessage(OCClientResponse * clientResponse);
38 NSSyncInfo * NSGetSyncInfoc(OCClientResponse * clientResponse);
39 NSTopicLL * NSGetTopicLL(OCClientResponse * clientResponse);
40
41 char * NSGetCloudUri(const char * providerId, char * uri);
42
43 NSResult NSConsumerSubscribeProvider(NSProvider * provider)
44 {
45     NSProvider_internal * provider_internal = (NSProvider_internal *) provider;
46     NS_VERIFY_NOT_NULL(provider_internal, NS_ERROR);
47
48     NSProviderConnectionInfo * connections = provider_internal->connection;
49     while(connections)
50     {
51         if (connections->isSubscribing == true)
52         {
53             connections = connections->next;
54             continue;
55         }
56
57         char * msgUri = OICStrdup(provider_internal->messageUri);
58         NS_VERIFY_NOT_NULL(msgUri, NS_ERROR);
59         char * syncUri = OICStrdup(provider_internal->syncUri);
60         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(syncUri, NS_ERROR, NSOICFree(msgUri));
61
62         OCConnectivityType type = CT_DEFAULT;
63         if (connections->addr->adapter == OC_ADAPTER_TCP)
64         {
65             type = CT_ADAPTER_TCP;
66             if (connections->isCloudConnection == true)
67             {
68                 msgUri = NSGetCloudUri(provider_internal->providerId, msgUri);
69                 NS_VERIFY_NOT_NULL(msgUri, NS_ERROR);
70                 syncUri = NSGetCloudUri(provider_internal->providerId, syncUri);
71                 NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(syncUri, NS_ERROR, NSOICFree(msgUri));
72             }
73         }
74
75         NS_LOG_V(DEBUG, "subscribe to %s:%d", connections->addr->addr, connections->addr->port);
76
77         NS_LOG(DEBUG, "get subscribe message query");
78         char * query = NULL;
79         query = NSMakeRequestUriWithConsumerId(msgUri);
80         NS_VERIFY_NOT_NULL(query, NS_ERROR);
81
82         NS_LOG(DEBUG, "subscribe message");
83         NS_LOG_V(DEBUG, "subscribe query : %s", query);
84         OCStackResult ret = NSInvokeRequest(&(connections->messageHandle),
85                               OC_REST_OBSERVE, connections->addr, query, NULL,
86                               NSConsumerMessageListener, NULL, type);
87         NS_VERIFY_STACK_SUCCESS_WITH_POST_CLEANING(
88                 NSOCResultToSuccess(ret), NS_ERROR, NSOICFree(query));
89         NSOICFree(query);
90         NSOICFree(msgUri);
91
92         NS_LOG(DEBUG, "get subscribe sync query");
93         query = NSMakeRequestUriWithConsumerId(syncUri);
94         NS_VERIFY_NOT_NULL(query, NS_ERROR);
95
96         NS_LOG(DEBUG, "subscribe sync");
97         NS_LOG_V(DEBUG, "subscribe query : %s", query);
98         ret = NSInvokeRequest(&(connections->syncHandle),
99                               OC_REST_OBSERVE, connections->addr, query, NULL,
100                               NSConsumerSyncInfoListener, NULL, type);
101         NS_VERIFY_STACK_SUCCESS_WITH_POST_CLEANING(
102                 NSOCResultToSuccess(ret), NS_ERROR, NSOICFree(query));
103         NSOICFree(query);
104         NSOICFree(syncUri);
105
106         connections->isSubscribing = true;
107
108         connections = connections->next;
109     }
110
111     NSProvider_internal * taskProvider = NSCopyProvider_internal(provider_internal);
112     NSTask * task = NSMakeTask(TASK_CONSUMER_SENT_REQ_OBSERVE, (void *) taskProvider);
113     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(task,
114                     NS_ERROR, NSRemoveProvider_internal(taskProvider));
115
116     NSConsumerPushEvent(task);
117
118     return NS_OK;
119 }
120
121 OCStackApplicationResult NSConsumerCheckPostResult(
122         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
123 {
124     (void) ctx;
125     (void) handle;
126
127     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
128     NS_VERIFY_STACK_SUCCESS(
129             NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
130
131     return OC_STACK_KEEP_TRANSACTION;
132 }
133
134 void NSRemoveSyncInfoObj(NSSyncInfo * sync)
135 {
136     NSOICFree(sync);
137 }
138
139 OCStackApplicationResult NSConsumerSyncInfoListener(
140         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
141 {
142     (void) ctx;
143     (void) handle;
144
145     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
146     NS_VERIFY_STACK_SUCCESS(
147             NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
148
149     NS_LOG(DEBUG, "get NSSyncInfo");
150     NSSyncInfo * newSync = NSGetSyncInfoc(clientResponse);
151     NS_VERIFY_NOT_NULL(newSync, OC_STACK_KEEP_TRANSACTION);
152
153     NSTaskType taskType = TASK_RECV_SYNCINFO;
154
155     NS_LOG(DEBUG, "build NSTask");
156     NSTask * task = NSMakeTask(taskType, (void *) newSync);
157     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(task,
158                OC_STACK_KEEP_TRANSACTION, NSRemoveSyncInfoObj(newSync));
159
160     NSConsumerPushEvent(task);
161
162     return OC_STACK_KEEP_TRANSACTION;
163 }
164
165 OCStackApplicationResult NSConsumerMessageListener(
166         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
167 {
168     (void) ctx;
169     (void) handle;
170
171     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
172     NS_VERIFY_STACK_SUCCESS(NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
173
174     NS_LOG(DEBUG, "build NSMessage");
175     NSMessage * newNoti = NSGetMessage(clientResponse);
176     NS_VERIFY_NOT_NULL(newNoti, OC_STACK_KEEP_TRANSACTION);
177
178     NSTaskType type = TASK_CONSUMER_RECV_MESSAGE;
179
180     if (newNoti->messageId == NS_MESSAGE_ACCEPTANCE || newNoti->messageId == NS_DENY)
181     {
182         NS_LOG(DEBUG, "Receive subscribe result");
183         type = TASK_CONSUMER_RECV_PROVIDER_CHANGED;
184     }
185     else if (newNoti->messageId == NS_TOPIC)
186     {
187         NS_LOG(DEBUG, "Receive Topic change");
188         type = TASK_CONSUMER_REQ_TOPIC_URI;
189     }
190     else
191     {
192         NS_LOG(DEBUG, "Receive new message");
193     }
194
195     NS_LOG(DEBUG, "build NSTask");
196     NSTask * task = NSMakeTask(type, (void *) newNoti);
197     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(task, NS_ERROR, NSRemoveMessage(newNoti));
198
199     NSConsumerPushEvent(task);
200
201     return OC_STACK_KEEP_TRANSACTION;
202 }
203
204 void NSGetMessagePostClean(char * pId, OCDevAddr * addr)
205 {
206     NSOICFree(pId);
207     NSOICFree(addr);
208 }
209
210 NSMessage * NSGetMessage(OCClientResponse * clientResponse)
211 {
212     NS_VERIFY_NOT_NULL(clientResponse->payload, NULL);
213     OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;
214
215     NS_LOG(DEBUG, "get msg id");
216     uint64_t id = NULL;
217     bool getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, (int64_t *)&id);
218     NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
219
220     NS_LOG(DEBUG, "get provider id");
221     char * pId = NULL;
222     getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, &pId);
223     NS_LOG_V (DEBUG, "provider id: %s", pId);
224     NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
225
226     NS_LOG(DEBUG, "create NSMessage");
227     NSMessage * retMsg = NSCreateMessage_internal(id, pId);
228     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(retMsg, NULL, NSOICFree(pId));
229     NSOICFree(pId);
230
231     NS_LOG(DEBUG, "get msg optional field");
232     OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TITLE, &retMsg->title);
233     OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TEXT, &retMsg->contentText);
234     OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_SOURCE, &retMsg->sourceName);
235     OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TOPIC_NAME, &retMsg->topic);
236
237     OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_TYPE, (int64_t *)&retMsg->type);
238     OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_DATETIME, &retMsg->dateTime);
239     OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_TTL, (int64_t *)&retMsg->ttl);
240
241     NS_LOG_V(DEBUG, "Msg ID      : %lld", (long long int)retMsg->messageId);
242     NS_LOG_V(DEBUG, "Msg Title   : %s", retMsg->title);
243     NS_LOG_V(DEBUG, "Msg Content : %s", retMsg->contentText);
244     NS_LOG_V(DEBUG, "Msg Source  : %s", retMsg->sourceName);
245     NS_LOG_V(DEBUG, "Msg Topic   : %s", retMsg->topic);
246     NS_LOG_V(DEBUG, "Msg Type    : %d", retMsg->type);
247     NS_LOG_V(DEBUG, "Msg Date    : %s", retMsg->dateTime);
248     NS_LOG_V(DEBUG, "Msg ttl     : %lld", (long long int)retMsg->ttl);
249
250     return retMsg;
251 }
252
253 NSSyncInfo * NSGetSyncInfoc(OCClientResponse * clientResponse)
254 {
255     NS_VERIFY_NOT_NULL(clientResponse->payload, NULL);
256
257     OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;
258
259     NS_LOG(DEBUG, "get msg id");
260     uint64_t id = NULL;
261     bool getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, (int64_t *)&id);
262     NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
263
264     NS_LOG(DEBUG, "get provider id");
265     char * pId = NULL;
266     getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, &pId);
267     NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
268
269     NS_LOG(DEBUG, "get state");
270     int64_t state = 0;
271     getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_STATE, & state);
272     NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
273
274     NS_LOG(DEBUG, "create NSSyncInfo");
275     NSSyncInfo * retSync = NSCreateSyncInfo_consumer(id, pId, (NSSyncType)state);
276     NS_VERIFY_NOT_NULL(retSync, NULL);
277
278     NS_LOG_V(DEBUG, "Sync ID : %lld", (long long int)retSync->messageId);
279     NS_LOG_V(DEBUG, "Sync State : %d", (int) retSync->state);
280     NS_LOG_V(DEBUG, "Sync Provider ID : %s", retSync->providerId);
281
282     return retSync;
283 }
284
285 NSMessage * NSCreateMessage_internal(uint64_t id, const char * providerId)
286 {
287     NSMessage * retMsg = (NSMessage *)OICMalloc(sizeof(NSMessage));
288     NS_VERIFY_NOT_NULL(retMsg, NULL);
289
290     retMsg->messageId = id;
291     OICStrcpy(retMsg->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, providerId);
292     retMsg->title = NULL;
293     retMsg->contentText = NULL;
294     retMsg->sourceName = NULL;
295     retMsg->topic = NULL;
296     retMsg->type = NS_MESSAGE_INFO;
297     retMsg->dateTime = NULL;
298     retMsg->ttl = 0;
299     retMsg->mediaContents = NULL;
300
301     return retMsg;
302 }
303
304 NSSyncInfo * NSCreateSyncInfo_consumer(uint64_t msgId, const char * providerId, NSSyncType state)
305 {
306     NS_VERIFY_NOT_NULL(providerId, NULL);
307
308     NSSyncInfo * retSync = (NSSyncInfo *)OICMalloc(sizeof(NSSyncInfo));
309     NS_VERIFY_NOT_NULL(retSync, NULL);
310
311     retSync->messageId = msgId;
312     retSync->state = state;
313     OICStrcpy(retSync->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, providerId);
314
315     return retSync;
316 }
317
318 OCStackResult NSSendSyncInfo(NSSyncInfo * syncInfo, OCDevAddr * addr)
319 {
320     NS_VERIFY_NOT_NULL(syncInfo, OC_STACK_ERROR);
321     NS_VERIFY_NOT_NULL(addr, OC_STACK_ERROR);
322
323     OCRepPayload * payload = OCRepPayloadCreate();
324     NS_VERIFY_NOT_NULL(payload, OC_STACK_ERROR);
325
326     OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, (int64_t)syncInfo->messageId);
327     OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_STATE, syncInfo->state);
328     OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, syncInfo->providerId);
329
330     char * uri = (char*)OICStrdup(NS_SYNC_URI);
331     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(uri, OC_STACK_ERROR, OCRepPayloadDestroy(payload));
332
333     OCConnectivityType type = CT_DEFAULT;
334     if(addr->adapter == OC_ADAPTER_TCP)
335     {
336         type = CT_ADAPTER_TCP;
337         uri = NSGetCloudUri(syncInfo->providerId, uri);
338         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(uri, OC_STACK_ERROR, OCRepPayloadDestroy(payload));
339     }
340
341     OCStackResult ret = NSInvokeRequest(NULL, OC_REST_POST, addr,
342                             uri, (OCPayload*)payload,
343                             NSConsumerCheckPostResult, NULL, type);
344     NSOICFree(uri);
345
346     return ret;
347 }
348
349 char * NSGetCloudUri(const char * providerId, char * uri)
350 {
351     size_t uriLen = NS_DEVICE_ID_LENGTH + 1 + strlen(uri) + 1;
352     char * retUri = (char *)OICMalloc(uriLen);
353     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(retUri, NULL, NSOICFree(uri));
354
355     snprintf(retUri, uriLen, "/%s%s", providerId, uri);
356     NSOICFree(uri);
357     NS_LOG_V(DEBUG, "Cloud uri : %s", retUri);
358
359     return retUri;
360 }
361
362 void NSConsumerCommunicationTaskProcessing(NSTask * task)
363 {
364     NS_VERIFY_NOT_NULL_V(task);
365
366     NS_LOG_V(DEBUG, "Receive Event : %d", (int)task->taskType);
367     if (task->taskType == TASK_CONSUMER_REQ_SUBSCRIBE)
368     {
369         NS_VERIFY_NOT_NULL_V(task->taskData);
370         NS_LOG(DEBUG, "Request Subscribe");
371         NSResult ret = NSConsumerSubscribeProvider((NSProvider *)task->taskData);
372         NS_VERIFY_NOT_NULL_V(ret == NS_OK ? (void *)1 : NULL);
373     }
374     else if (task->taskType == TASK_SEND_SYNCINFO)
375     {
376         NS_VERIFY_NOT_NULL_V(task->taskData);
377         NSSyncInfo_internal * syncInfo = (NSSyncInfo_internal *)task->taskData;
378         NSProviderConnectionInfo * info = syncInfo->connection;
379
380         while(info)
381         {
382             OCStackResult ret = NSSendSyncInfo((NSSyncInfo *)(task->taskData), info->addr);
383             if (ret != OC_STACK_OK)
384             {
385                 NS_LOG_V(ERROR, "send sync info fail : %d", info->addr->adapter);
386             }
387
388             info = info->next;
389         }
390
391         NSRemoveConnections(syncInfo->connection);
392         NSOICFree(syncInfo);
393     }
394     else if (task->taskType == TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL)
395     {
396         NSProvider_internal * provider = (NSProvider_internal *)task->taskData;
397
398         NSProviderConnectionInfo * connections = provider->connection;
399         while(connections)
400         {
401             if (connections->isSubscribing == false)
402             {
403                 NS_LOG_V(DEBUG, "unsubscribed to %s:%d",
404                      connections->addr->addr, connections->addr->port);
405                 connections = connections->next;
406                 continue;
407             }
408             NS_LOG_V(DEBUG, "cancel subscribe to %s:%d",
409                      connections->addr->addr, connections->addr->port);
410             OCCancel(connections->messageHandle, NS_QOS, NULL, 0);
411             OCCancel(connections->syncHandle, NS_QOS, NULL, 0);
412             connections->messageHandle = NULL;
413             connections->syncHandle = NULL;
414             connections->isSubscribing = false;
415             connections = connections->next;
416         }
417     }
418     else if (task->taskType == TASK_CONSUMER_REQ_TOPIC_LIST
419                 || task->taskType == TASK_CONSUMER_GET_TOPIC_LIST)
420     {
421         NSProvider_internal * provider = (NSProvider_internal *)task->taskData;
422
423         NSProviderConnectionInfo * connections = provider->connection;
424         NS_VERIFY_NOT_NULL_V(connections);
425
426         char * topicUri = OICStrdup(provider->topicUri);
427
428         OCConnectivityType type = CT_DEFAULT;
429         if (connections->addr->adapter == OC_ADAPTER_TCP)
430         {
431             type = CT_ADAPTER_TCP;
432             if (connections->isCloudConnection == true)
433             {
434                 topicUri = NSGetCloudUri(provider->providerId, topicUri);
435             }
436         }
437
438         NS_LOG(DEBUG, "get topic query");
439         char * query = NULL;
440         if (task->taskType == TASK_CONSUMER_REQ_TOPIC_LIST)
441         {
442             query = OICStrdup(topicUri);
443         }
444         else if (task->taskType == TASK_CONSUMER_GET_TOPIC_LIST)
445         {
446             query = NSMakeRequestUriWithConsumerId(topicUri);
447         }
448         NS_VERIFY_NOT_NULL_V(query);
449         NS_LOG_V(DEBUG, "topic query : %s", query);
450
451         OCStackResult ret = NSInvokeRequest(NULL, OC_REST_GET, connections->addr,
452                                 query, NULL, NSIntrospectTopic, (void *) provider, type);
453         NS_VERIFY_STACK_SUCCESS_V(NSOCResultToSuccess(ret));
454
455         NSOICFree(query);
456         NSOICFree(topicUri);
457     }
458     else if (task->taskType == TASK_CONSUMER_SELECT_TOPIC_LIST)
459     {
460         NSProvider_internal * provider = (NSProvider_internal *)task->taskData;
461
462         NSProviderConnectionInfo * connections = provider->connection;
463         NS_VERIFY_NOT_NULL_V(connections);
464
465         OCRepPayload * payload = OCRepPayloadCreate();
466         NS_VERIFY_NOT_NULL_V(payload);
467
468         NSTopicLL * topicLL = provider->topicLL;
469         NSTopicLL * iter = topicLL;
470         int topicLLSize = 0;
471         while (iter)
472         {
473             topicLLSize ++;
474             NS_LOG_V(DEBUG, "[%d] Topic Name:%s\tTopic State:%d",
475                                         topicLLSize, iter->topicName, iter->state);
476             iter = (NSTopicLL *) iter->next;
477         }
478
479         OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_CONSUMER_ID, *NSGetConsumerId());
480         NS_LOG_V(DEBUG, "NS_ATTRIBUTE_CONSUMER_ID: %s", *NSGetConsumerId());
481
482         iter = topicLL;
483         int iterSize = 0;
484         NS_LOG_V(DEBUG, "DimensionSize: %d", topicLLSize);
485
486         OCRepPayload ** topicPayload = NULL;
487         if (topicLLSize > 0)
488         {
489             topicPayload = (OCRepPayload **) OICMalloc(sizeof(OCRepPayload *)*topicLLSize);
490             NS_VERIFY_NOT_NULL_V(topicPayload);
491
492             while (iter || iterSize < topicLLSize)
493             {
494                 topicPayload[iterSize] = OCRepPayloadCreate();
495                 OCRepPayloadSetPropString(topicPayload[iterSize], NS_ATTRIBUTE_TOPIC_NAME,
496                                             iter->topicName);
497                 OCRepPayloadSetPropInt(topicPayload[iterSize], NS_ATTRIBUTE_TOPIC_SELECTION,
498                                             iter->state);
499                 NS_LOG_V(DEBUG, "NS_ATTRIBUTE_TOPIC_NAME: %s", iter->topicName);
500                 NS_LOG_V(DEBUG, "NS_ATTRIBUTE_TOPIC_SELECTION: %d", iter->state);
501                 iterSize++;
502                 iter = iter->next;
503             }
504             size_t dimensions[3] = {topicLLSize, 0, 0};
505
506             OCRepPayloadSetPropObjectArrayAsOwner(payload, NS_ATTRIBUTE_TOPIC_LIST,
507                                                     topicPayload, dimensions);
508         }
509         else
510         {
511             OCRepPayloadSetNull(payload, NS_ATTRIBUTE_TOPIC_LIST);
512         }
513
514         char * topicUri = OICStrdup(provider->topicUri);
515
516         OCConnectivityType type = CT_DEFAULT;
517         if (connections->addr->adapter == OC_ADAPTER_TCP)
518         {
519             type = CT_ADAPTER_TCP;
520             if (connections->isCloudConnection == true)
521             {
522                 topicUri = NSGetCloudUri(provider->providerId, topicUri);
523             }
524         }
525
526         NS_LOG(DEBUG, "get topic query");
527         char * query = NULL;
528         query = NSMakeRequestUriWithConsumerId(topicUri);
529         NS_VERIFY_NOT_NULL_V(query);
530         NS_LOG_V(DEBUG, "topic query : %s", query);
531
532         OCStackResult ret = NSInvokeRequest(NULL, OC_REST_POST, connections->addr,
533                                 query, (OCPayload*)payload, NSConsumerCheckPostResult, NULL, type);
534         NS_VERIFY_STACK_SUCCESS_V(NSOCResultToSuccess(ret));
535
536         NSOICFree(query);
537         NSOICFree(topicUri);
538     }
539     else
540     {
541         NS_LOG(ERROR, "Unknown type message");
542     }
543
544     NSOICFree(task);
545 }
546
547 NSTopicLL * NSGetTopicLL(OCClientResponse * clientResponse)
548 {
549     NS_LOG(DEBUG, "create NSTopicLL");
550     NS_VERIFY_NOT_NULL(clientResponse->payload, NULL);
551
552     OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;
553     while (payload)
554     {
555         NS_LOG_V(DEBUG, "Payload Key : %s", payload->values->name);
556         payload = payload->next;
557     }
558
559     payload = (OCRepPayload *)clientResponse->payload;
560
561     char * consumerId = NULL;
562     OCRepPayload ** topicLLPayload = NULL;
563
564     NS_LOG(DEBUG, "get information of consumerId");
565
566     bool getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_CONSUMER_ID, & consumerId);
567     NSOICFree(consumerId);
568
569     OCRepPayloadValue * payloadValue = NULL;
570     payloadValue = NSPayloadFindValue(payload, NS_ATTRIBUTE_TOPIC_LIST);
571     NS_VERIFY_NOT_NULL(payloadValue, NULL);
572
573     size_t dimensionSize = calcDimTotal(payloadValue->arr.dimensions);
574     NS_LOG_V(DEBUG, "DimensionSize: %d", (int)dimensionSize);
575
576     if (dimensionSize == 0 || payloadValue->type == OCREP_PROP_NULL ||
577             payloadValue->arr.objArray == NULL)
578     {
579         NS_LOG(DEBUG, "No TopicLL");
580         return NULL;
581     }
582
583     topicLLPayload = payloadValue->arr.objArray;
584
585     NSTopicLL * topicLL = NULL;
586     for (int i = 0; i < (int)dimensionSize; i++)
587     {
588         char * topicName = NULL;
589         int64_t state = 0;
590
591         NSTopicLL * topicNode = (NSTopicLL *) OICMalloc(sizeof(NSTopicLL));
592         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(topicNode, NULL, NSRemoveTopicLL(topicLL));
593
594         NS_LOG(DEBUG, "get topic selection");
595         getResult = OCRepPayloadGetPropInt(topicLLPayload[i],
596                 NS_ATTRIBUTE_TOPIC_SELECTION, & state);
597         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(getResult == true ? (void *) 1 : NULL,
598                 NULL, NSRemoveTopicLL(topicLL));
599
600         NS_LOG(DEBUG, "get topic name");
601         getResult = OCRepPayloadGetPropString(topicLLPayload[i],
602                 NS_ATTRIBUTE_TOPIC_NAME, & topicName);
603         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(getResult == true ? (void *) 1 : NULL,
604                 NULL, NSRemoveTopicLL(topicLL));
605         NS_LOG_V(DEBUG, "topic name: %s", topicName);
606         NS_LOG_V(DEBUG, "topic selection: %d", (int)state);
607
608         topicNode->topicName = topicName;
609         topicNode->state = state;
610
611         if (i == 0)
612         {
613             topicLL = topicNode;
614             topicNode->next = NULL;
615             continue;
616         }
617
618         NSResult ret = NSInsertTopicNode(topicLL, topicNode);
619         NS_VERIFY_STACK_SUCCESS_WITH_POST_CLEANING(ret, NULL, NSRemoveTopicLL(topicLL));
620     }
621
622     return topicLL;
623 }
624
625 OCStackApplicationResult NSIntrospectTopic(
626         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
627 {
628     (void) handle;
629
630     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(clientResponse, OC_STACK_KEEP_TRANSACTION,
631             NSRemoveProvider_internal((NSProvider_internal *) ctx));
632     NS_VERIFY_STACK_SUCCESS_WITH_POST_CLEANING(NSOCResultToSuccess(clientResponse->result),
633             OC_STACK_KEEP_TRANSACTION, NSRemoveProvider_internal((NSProvider_internal *) ctx));
634
635     NS_LOG_V(DEBUG, "GET response income : %s:%d",
636             clientResponse->devAddr.addr, clientResponse->devAddr.port);
637     NS_LOG_V(DEBUG, "GET response result : %d",
638             clientResponse->result);
639     NS_LOG_V(DEBUG, "GET response sequenceNum : %d",
640             clientResponse->sequenceNumber);
641     NS_LOG_V(DEBUG, "GET response resource uri : %s",
642             clientResponse->resourceUri);
643     NS_LOG_V(DEBUG, "GET response Transport Type : %d",
644             clientResponse->devAddr.adapter);
645
646     NSTopicLL * newTopicLL = NSGetTopicLL(clientResponse);
647     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newTopicLL, OC_STACK_KEEP_TRANSACTION,
648           NSRemoveProvider_internal((NSProvider_internal *) ctx));
649
650     NSProvider_internal * provider = (NSProvider_internal *) ctx;
651     provider->topicLL = NSCopyTopicLL(newTopicLL);
652
653     NS_LOG(DEBUG, "build NSTask");
654     NSTask * task = NSMakeTask(TASK_CONSUMER_RECV_TOPIC_LIST, (void *) provider);
655     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(task, NS_ERROR, NSRemoveProvider_internal(provider));
656
657     NSConsumerPushEvent(task);
658     NSRemoveTopicLL(newTopicLL);
659
660     return OC_STACK_KEEP_TRANSACTION;
661 }