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