Fix bugs for result of dynamic analizer.
[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 NSMessage * NSCreateMessage_internal(uint64_t msgId, const char * providerId);
33 NSSyncInfo * NSCreateSyncInfo_consumer(uint64_t msgId, const char * providerId, NSSyncType state);
34
35 NSMessage * NSGetMessage(OCClientResponse * clientResponse);
36 NSSyncInfo * NSGetSyncInfoc(OCClientResponse * clientResponse);
37 NSTopicLL * NSGetTopicLL(OCClientResponse * clientResponse);
38
39 char * NSGetCloudUri(const char * providerId, char * uri);
40
41 NSResult NSUpdateObserveResult(NSProvider_internal * prov, char * query)
42 {
43     NSOICFree(query);
44
45     NSProvider_internal * taskProvider = NSCopyProvider_internal(prov);
46     NSTask * task = NSMakeTask(TASK_CONSUMER_SENT_REQ_OBSERVE, (void *) taskProvider);
47     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(task,
48                     NS_ERROR, NSRemoveProvider_internal(taskProvider));
49
50     NSConsumerPushEvent(task);
51
52     return NS_OK;
53 }
54
55 NSResult NSConsumerSubscribeProvider(NSProvider * provider)
56 {
57     NSProvider_internal * provider_internal = (NSProvider_internal *) provider;
58     NS_VERIFY_NOT_NULL(provider_internal, NS_ERROR);
59
60     NSProviderConnectionInfo * connections = provider_internal->connection;
61     while(connections)
62     {
63         if (connections->isSubscribing == true)
64         {
65             connections = connections->next;
66             continue;
67         }
68
69         char * msgUri = OICStrdup(provider_internal->messageUri);
70         NS_VERIFY_NOT_NULL(msgUri, NS_ERROR);
71         char * syncUri = OICStrdup(provider_internal->syncUri);
72         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(syncUri, NS_ERROR, NSOICFree(msgUri));
73
74         OCConnectivityType type = CT_DEFAULT;
75         if (connections->addr->adapter == OC_ADAPTER_TCP)
76         {
77             type = CT_ADAPTER_TCP;
78             if (connections->isCloudConnection == true)
79             {
80                 msgUri = NSGetCloudUri(provider_internal->providerId, msgUri);
81                 NS_VERIFY_NOT_NULL(msgUri, NS_ERROR);
82                 syncUri = NSGetCloudUri(provider_internal->providerId, syncUri);
83                 NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(syncUri, NS_ERROR, NSOICFree(msgUri));
84             }
85         }
86
87         NS_LOG_V(DEBUG, "subscribe to %s:%d", connections->addr->addr, connections->addr->port);
88
89         NS_LOG(DEBUG, "get subscribe message query");
90         char * query = NULL;
91         query = NSMakeRequestUriWithConsumerId(msgUri);
92         NS_VERIFY_NOT_NULL(query, NS_ERROR);
93
94         NS_LOG(DEBUG, "subscribe message");
95         NS_LOG_V(DEBUG, "subscribe query : %s", query);
96         OCStackResult ret = NSInvokeRequest(&(connections->messageHandle),
97                               OC_REST_OBSERVE, connections->addr, query, NULL,
98                               NSConsumerMessageListener, NULL, NULL, type);
99         NS_VERIFY_STACK_SUCCESS_WITH_POST_CLEANING(NSOCResultToSuccess(ret),
100                             NS_ERROR, NSUpdateObserveResult(provider_internal, query));
101         NSOICFree(query);
102         NSOICFree(msgUri);
103
104         NS_LOG(DEBUG, "get subscribe sync query");
105         query = NSMakeRequestUriWithConsumerId(syncUri);
106         NS_VERIFY_NOT_NULL(query, NS_ERROR);
107
108         NS_LOG(DEBUG, "subscribe sync");
109         NS_LOG_V(DEBUG, "subscribe query : %s", query);
110         ret = NSInvokeRequest(&(connections->syncHandle),
111                               OC_REST_OBSERVE, connections->addr, query, NULL,
112                               NSConsumerSyncInfoListener, NULL, NULL, type);
113         NS_VERIFY_STACK_SUCCESS_WITH_POST_CLEANING(NSOCResultToSuccess(ret),
114                             NS_ERROR, NSUpdateObserveResult(provider_internal, query));
115         NSOICFree(query);
116         NSOICFree(syncUri);
117
118         connections->isSubscribing = true;
119
120         connections = connections->next;
121     }
122
123     NSProvider_internal * taskProvider = NSCopyProvider_internal(provider_internal);
124     NSTask * task = NSMakeTask(TASK_CONSUMER_SENT_REQ_OBSERVE, (void *) taskProvider);
125     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(task,
126                     NS_ERROR, NSRemoveProvider_internal(taskProvider));
127
128     NSConsumerPushEvent(task);
129
130     return NS_OK;
131 }
132
133 OCStackApplicationResult NSConsumerCheckPostResult(
134         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
135 {
136     (void) ctx;
137     (void) handle;
138
139     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
140     NS_VERIFY_STACK_SUCCESS(
141             NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
142
143     return OC_STACK_KEEP_TRANSACTION;
144 }
145
146 void NSRemoveSyncInfoObj(NSSyncInfo * sync)
147 {
148     NSOICFree(sync);
149 }
150
151 OCStackApplicationResult NSConsumerSyncInfoListener(
152         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
153 {
154     (void) ctx;
155     (void) handle;
156
157     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
158     NS_VERIFY_STACK_SUCCESS(
159             NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
160
161     NS_LOG(DEBUG, "get NSSyncInfo");
162     NSSyncInfo * newSync = NSGetSyncInfoc(clientResponse);
163     NS_VERIFY_NOT_NULL(newSync, OC_STACK_KEEP_TRANSACTION);
164
165     NSTaskType taskType = TASK_RECV_SYNCINFO;
166
167     NS_LOG(DEBUG, "build NSTask");
168     NSTask * task = NSMakeTask(taskType, (void *) newSync);
169     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(task,
170                OC_STACK_KEEP_TRANSACTION, NSRemoveSyncInfoObj(newSync));
171
172     NSConsumerPushEvent(task);
173
174     return OC_STACK_KEEP_TRANSACTION;
175 }
176
177 OCStackApplicationResult NSConsumerMessageListener(
178         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
179 {
180     (void) ctx;
181     (void) handle;
182
183     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
184     NS_VERIFY_STACK_SUCCESS(NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
185
186     NS_LOG(DEBUG, "build NSMessage");
187     NSMessage * newNoti = NSGetMessage(clientResponse);
188     NS_VERIFY_NOT_NULL(newNoti, OC_STACK_KEEP_TRANSACTION);
189
190     NSTaskType type = TASK_CONSUMER_RECV_MESSAGE;
191
192     if (newNoti->messageId == NS_ALLOW || newNoti->messageId == NS_DENY)
193     {
194         NS_LOG(DEBUG, "Receive subscribe result");
195         type = TASK_CONSUMER_RECV_PROVIDER_CHANGED;
196     }
197     else if (newNoti->messageId == NS_TOPIC)
198     {
199         NS_LOG(DEBUG, "Receive Topic change");
200         type = TASK_CONSUMER_REQ_TOPIC_URI;
201     }
202     else
203     {
204         NS_LOG(DEBUG, "Receive new message");
205     }
206
207     NS_LOG(DEBUG, "build NSTask");
208     NSTask * task = NSMakeTask(type, (void *) newNoti);
209     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(task, NS_ERROR, NSRemoveMessage(newNoti));
210
211     NSConsumerPushEvent(task);
212
213     return OC_STACK_KEEP_TRANSACTION;
214 }
215
216 void NSGetMessagePostClean(char * pId, OCDevAddr * addr)
217 {
218     NSOICFree(pId);
219     NSOICFree(addr);
220 }
221
222 bool NSIsExtraValue(const char * name)
223 {
224     if (!strcmp(name, NS_ATTRIBUTE_MESSAGE_ID) ||
225         !strcmp(name, NS_ATTRIBUTE_PROVIDER_ID) ||
226         !strcmp(name, NS_ATTRIBUTE_TITLE) ||
227         !strcmp(name, NS_ATTRIBUTE_TEXT) ||
228         !strcmp(name, NS_ATTRIBUTE_SOURCE) ||
229         !strcmp(name, NS_ATTRIBUTE_TOPIC_NAME) ||
230         !strcmp(name, NS_ATTRIBUTE_TYPE) ||
231         !strcmp(name, NS_ATTRIBUTE_DATETIME) ||
232         !strcmp(name, NS_ATTRIBUTE_TTL) ||
233         !strcmp(name, NS_ATTRIBUTE_ICON_IMAGE))
234     {
235         return false;
236     }
237
238     return true;
239 }
240
241 void NSCopyPayloadValueArray(OCRepPayloadValue* dest, OCRepPayloadValue* source)
242 {
243     NS_VERIFY_NOT_NULL_V(source);
244
245     size_t dimTotal = calcDimTotal(source->arr.dimensions);
246     switch(source->arr.type)
247     {
248         case OCREP_PROP_INT:
249             dest->arr.iArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
250             NS_VERIFY_NOT_NULL_V(dest->arr.iArray);
251             memcpy(dest->arr.iArray, source->arr.iArray, dimTotal * sizeof(int64_t));
252             break;
253         case OCREP_PROP_DOUBLE:
254             dest->arr.dArray = (double*)OICMalloc(dimTotal * sizeof(double));
255             NS_VERIFY_NOT_NULL_V(dest->arr.dArray);
256             memcpy(dest->arr.dArray, source->arr.dArray, dimTotal * sizeof(double));
257             break;
258         case OCREP_PROP_BOOL:
259             dest->arr.bArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
260             NS_VERIFY_NOT_NULL_V(dest->arr.bArray);
261             memcpy(dest->arr.bArray, source->arr.bArray, dimTotal * sizeof(bool));
262             break;
263         case OCREP_PROP_STRING:
264             dest->arr.strArray = (char**)OICMalloc(dimTotal * sizeof(char*));
265             NS_VERIFY_NOT_NULL_V(dest->arr.strArray);
266             for(size_t i = 0; i < dimTotal; ++i)
267             {
268                 dest->arr.strArray[i] = OICStrdup(source->arr.strArray[i]);
269             }
270             break;
271         case OCREP_PROP_OBJECT:
272             dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
273             NS_VERIFY_NOT_NULL_V(dest->arr.objArray);
274             for(size_t i = 0; i < dimTotal; ++i)
275             {
276                 dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
277             }
278             break;
279         case OCREP_PROP_ARRAY:
280             dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
281             NS_VERIFY_NOT_NULL_V(dest->arr.objArray);
282             for(size_t i = 0; i < dimTotal; ++i)
283             {
284                 dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
285             }
286             break;
287         case OCREP_PROP_BYTE_STRING:
288             dest->arr.ocByteStrArray = (OCByteString*)OICMalloc(dimTotal * sizeof(OCByteString));
289             NS_VERIFY_NOT_NULL_V(dest->arr.ocByteStrArray);
290             for (size_t i = 0; i < dimTotal; ++i)
291             {
292                 OCByteStringCopy(&dest->arr.ocByteStrArray[i], &source->arr.ocByteStrArray[i]);
293                 NS_VERIFY_NOT_NULL_V(dest->arr.ocByteStrArray[i].bytes);
294             }
295             break;
296         default:
297             break;
298     }
299 }
300
301 OCRepPayloadValue * NSCopyPayloadValue(OCRepPayloadValue * value)
302 {
303     OCRepPayloadValue * retValue = (OCRepPayloadValue *)OICMalloc(sizeof(OCRepPayloadValue));
304     NS_VERIFY_NOT_NULL(retValue, NULL);
305
306     * retValue = * value;
307     retValue->next = NULL;
308     retValue->name = OICStrdup(value->name);
309
310     switch(value->type)
311     {
312         case OCREP_PROP_STRING:
313             retValue->str = OICStrdup(value->str);
314             break;
315         case OCREP_PROP_BYTE_STRING:
316             retValue->ocByteStr.bytes = (uint8_t * )OICMalloc(value->ocByteStr.len * sizeof(uint8_t));
317             NS_VERIFY_NOT_NULL(retValue->ocByteStr.bytes, NULL);
318             retValue->ocByteStr.len = value->ocByteStr.len;
319             memcpy(retValue->ocByteStr.bytes, value->ocByteStr.bytes, retValue->ocByteStr.len);
320             break;
321         case OCREP_PROP_OBJECT:
322             retValue->obj = OCRepPayloadClone(value->obj);
323             break;
324         case OCREP_PROP_ARRAY:
325             NSCopyPayloadValueArray(retValue, value);
326             break;
327         default:
328             break;
329     }
330
331     return retValue;
332 }
333
334 OCRepPayload * NSGetExtraInfo(OCRepPayload * payload)
335 {
336     NS_LOG(DEBUG, "get extra info");
337     OCRepPayload * extraInfo = OCRepPayloadCreate();
338     OCRepPayload * origin = OCRepPayloadClone(payload);
339
340     bool isFirstExtra = true;
341     OCRepPayloadValue * headValue = NULL;
342     OCRepPayloadValue * curValue = NULL;
343     OCRepPayloadValue * value = origin->values;
344     while(value)
345     {
346         if (NSIsExtraValue(value->name))
347         {
348             curValue = NSCopyPayloadValue(value);
349             NS_LOG_V(DEBUG, " key : %s", curValue->name);
350             if (isFirstExtra)
351             {
352                 headValue = curValue;
353                 extraInfo->values = headValue;
354                 isFirstExtra = false;
355             }
356             else
357             {
358                 headValue->next = curValue;
359                 headValue = curValue;
360             }
361             curValue = NULL;
362         }
363         value = value->next;
364     }
365     OCRepPayloadDestroy(origin);
366
367
368     if (!isFirstExtra && extraInfo->values)
369     {
370         return extraInfo;
371     }
372     else
373     {
374         OCRepPayloadDestroy(extraInfo);
375         return NULL;
376     }
377 }
378
379 NSMessage * NSGetMessage(OCClientResponse * clientResponse)
380 {
381     NS_VERIFY_NOT_NULL(clientResponse->payload, NULL);
382     OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;
383
384     NS_LOG(DEBUG, "get msg id");
385     uint64_t id = NULL;
386     bool getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, (int64_t *)&id);
387     NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
388
389     NS_LOG(DEBUG, "get provider id");
390     char * pId = NULL;
391     getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, &pId);
392     NS_LOG_V (DEBUG, "provider id: %s", pId);
393     NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
394
395     NS_LOG(DEBUG, "create NSMessage");
396     NSMessage * retMsg = NSCreateMessage_internal(id, pId);
397     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(retMsg, NULL, NSOICFree(pId));
398     NSOICFree(pId);
399
400     NS_LOG(DEBUG, "get msg optional field");
401     OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TITLE, &retMsg->title);
402     OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TEXT, &retMsg->contentText);
403     OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_SOURCE, &retMsg->sourceName);
404     OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TOPIC_NAME, &retMsg->topic);
405
406     OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_TYPE, (int64_t *)&retMsg->type);
407     OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_DATETIME, &retMsg->dateTime);
408     OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_TTL, (int64_t *)&retMsg->ttl);
409
410     char * icon = NULL;
411     OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_ICON_IMAGE, &icon);
412
413     if (icon && strlen(icon))
414     {
415         NSMediaContents * contents = (NSMediaContents *)OICMalloc(sizeof(NSMediaContents));
416         if (contents)
417         {
418             contents->iconImage = icon;
419             retMsg->mediaContents = contents;
420         }
421         else
422         {
423             NSOICFree(icon);
424         }
425     }
426
427     retMsg->extraInfo = NSGetExtraInfo(payload);
428
429     NS_LOG_V(DEBUG, "Msg ID      : %lld", (long long int)retMsg->messageId);
430     NS_LOG_V(DEBUG, "Msg Title   : %s", retMsg->title);
431     NS_LOG_V(DEBUG, "Msg Content : %s", retMsg->contentText);
432     NS_LOG_V(DEBUG, "Msg Source  : %s", retMsg->sourceName);
433     NS_LOG_V(DEBUG, "Msg Topic   : %s", retMsg->topic);
434     NS_LOG_V(DEBUG, "Msg Type    : %d", retMsg->type);
435     NS_LOG_V(DEBUG, "Msg Date    : %s", retMsg->dateTime);
436     NS_LOG_V(DEBUG, "Msg ttl     : %lld", (long long int)retMsg->ttl);
437
438     return retMsg;
439 }
440
441 NSSyncInfo * NSGetSyncInfoc(OCClientResponse * clientResponse)
442 {
443     NS_VERIFY_NOT_NULL(clientResponse->payload, NULL);
444
445     OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;
446
447     NS_LOG(DEBUG, "get msg id");
448     uint64_t id = NULL;
449     bool getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, (int64_t *)&id);
450     NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
451
452     NS_LOG(DEBUG, "get provider id");
453     char * pId = NULL;
454     getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, &pId);
455     NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
456
457     NS_LOG(DEBUG, "get state");
458     int64_t state = 0;
459     getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_STATE, & state);
460     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(getResult == true ? (void *) 1 : NULL,
461             NULL, NSOICFree(pId));
462
463     NS_LOG(DEBUG, "create NSSyncInfo");
464     NSSyncInfo * retSync = NSCreateSyncInfo_consumer(id, pId, (NSSyncType)state);
465     NSOICFree(pId);
466     NS_VERIFY_NOT_NULL(retSync, NULL);
467
468     NS_LOG_V(DEBUG, "Sync ID : %lld", (long long int)retSync->messageId);
469     NS_LOG_V(DEBUG, "Sync State : %d", (int) retSync->state);
470     NS_LOG_V(DEBUG, "Sync Provider ID : %s", retSync->providerId);
471
472     return retSync;
473 }
474
475 NSMessage * NSCreateMessage_internal(uint64_t id, const char * providerId)
476 {
477     NSMessage * retMsg = (NSMessage *)OICMalloc(sizeof(NSMessage));
478     NS_VERIFY_NOT_NULL(retMsg, NULL);
479
480     retMsg->messageId = id;
481     OICStrcpy(retMsg->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, providerId);
482     retMsg->title = NULL;
483     retMsg->contentText = NULL;
484     retMsg->sourceName = NULL;
485     retMsg->topic = NULL;
486     retMsg->type = NS_MESSAGE_INFO;
487     retMsg->dateTime = NULL;
488     retMsg->ttl = 0;
489     retMsg->mediaContents = NULL;
490     retMsg->extraInfo = NULL;
491
492     return retMsg;
493 }
494
495 NSSyncInfo * NSCreateSyncInfo_consumer(uint64_t msgId, const char * providerId, NSSyncType state)
496 {
497     NS_VERIFY_NOT_NULL(providerId, NULL);
498
499     NSSyncInfo * retSync = (NSSyncInfo *)OICMalloc(sizeof(NSSyncInfo));
500     NS_VERIFY_NOT_NULL(retSync, NULL);
501
502     retSync->messageId = msgId;
503     retSync->state = state;
504     OICStrcpy(retSync->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, providerId);
505
506     return retSync;
507 }
508
509 OCStackResult NSSendSyncInfo(NSSyncInfo * syncInfo, OCDevAddr * addr)
510 {
511     NS_VERIFY_NOT_NULL(syncInfo, OC_STACK_ERROR);
512     NS_VERIFY_NOT_NULL(addr, OC_STACK_ERROR);
513
514     OCRepPayload * payload = OCRepPayloadCreate();
515     NS_VERIFY_NOT_NULL(payload, OC_STACK_ERROR);
516
517     OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, (int64_t)syncInfo->messageId);
518     OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_STATE, syncInfo->state);
519     OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, syncInfo->providerId);
520
521     char * uri = (char*)OICStrdup(NS_SYNC_URI);
522     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(uri, OC_STACK_ERROR, OCRepPayloadDestroy(payload));
523
524     OCConnectivityType type = CT_DEFAULT;
525     if(addr->adapter == OC_ADAPTER_TCP)
526     {
527         type = CT_ADAPTER_TCP;
528         uri = NSGetCloudUri(syncInfo->providerId, uri);
529         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(uri, OC_STACK_ERROR, OCRepPayloadDestroy(payload));
530     }
531
532     OCStackResult ret = NSInvokeRequest(NULL, OC_REST_POST, addr,
533                             uri, (OCPayload*)payload,
534                             NSConsumerCheckPostResult, NULL, NULL, type);
535     NSOICFree(uri);
536
537     return ret;
538 }
539
540 char * NSGetCloudUri(const char * providerId, char * uri)
541 {
542     size_t uriLen = NS_DEVICE_ID_LENGTH + 1 + strlen(uri) + 1 + 3;
543     char * retUri = (char *)OICMalloc(uriLen);
544     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(retUri, NULL, NSOICFree(uri));
545
546     snprintf(retUri, uriLen, "/di/%s%s", providerId, uri);
547     NSOICFree(uri);
548     NS_LOG_V(DEBUG, "Cloud uri : %s", retUri);
549
550     return retUri;
551 }
552
553 void NSConsumerCommunicationTaskProcessing(NSTask * task)
554 {
555     NS_VERIFY_NOT_NULL_V(task);
556
557     NS_LOG_V(DEBUG, "Receive Event : %d", (int)task->taskType);
558     if (task->taskType == TASK_CONSUMER_REQ_SUBSCRIBE)
559     {
560         NS_VERIFY_NOT_NULL_V(task->taskData);
561         NS_LOG(DEBUG, "Request Subscribe");
562         NSResult ret = NSConsumerSubscribeProvider((NSProvider *)task->taskData);
563         NSRemoveProvider_internal((void *) task->taskData);
564         NS_VERIFY_NOT_NULL_V(ret == NS_OK ? (void *)1 : NULL);
565     }
566     else if (task->taskType == TASK_SEND_SYNCINFO)
567     {
568         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(task->taskData, NSOICFree(task));
569         NSSyncInfo_internal * syncInfo = (NSSyncInfo_internal *)task->taskData;
570         NSProviderConnectionInfo * info = syncInfo->connection;
571
572         while(info)
573         {
574             OCStackResult ret = NSSendSyncInfo((NSSyncInfo *)(task->taskData), info->addr);
575             if (ret != OC_STACK_OK)
576             {
577                 NS_LOG_V(ERROR, "send sync info fail : %d", info->addr->adapter);
578             }
579
580             info = info->next;
581         }
582
583         NSRemoveConnections(syncInfo->connection);
584         NSOICFree(syncInfo);
585     }
586     else if (task->taskType == TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL)
587     {
588         NSProvider_internal * provider = (NSProvider_internal *)task->taskData;
589         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(provider,
590         {
591             NSRemoveProvider_internal(provider);
592             NSOICFree(task);
593         });
594
595         NSProviderConnectionInfo * connections = provider->connection;
596         while(connections)
597         {
598             if (connections->isSubscribing == false)
599             {
600                 NS_LOG_V(DEBUG, "unsubscribed to %s:%d",
601                      connections->addr->addr, connections->addr->port);
602                 connections = connections->next;
603                 continue;
604             }
605             NS_LOG_V(DEBUG, "cancel subscribe to %s:%d",
606                      connections->addr->addr, connections->addr->port);
607             OCCancel(connections->messageHandle, NS_QOS, NULL, 0);
608             OCCancel(connections->syncHandle, NS_QOS, NULL, 0);
609             connections->messageHandle = NULL;
610             connections->syncHandle = NULL;
611             connections->isSubscribing = false;
612             connections = connections->next;
613         }
614
615         NSRemoveProvider_internal(provider);
616     }
617     else if (task->taskType == TASK_CONSUMER_REQ_TOPIC_LIST)
618     {
619         NSProvider_internal * provider = NSCopyProvider_internal(task->taskData);
620         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(provider,
621         {
622             NSRemoveProvider_internal((void *) task->taskData);
623             NSOICFree(task);
624         });
625         NSRemoveProvider_internal((NSProvider_internal *)task->taskData);
626
627         NSProviderConnectionInfo * connections = provider->connection;
628         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(connections,
629         {
630             NSRemoveProvider_internal((void *) provider);
631             NSRemoveProvider_internal((void *) task->taskData);
632             NSOICFree(task);
633         });
634
635         char * topicUri = OICStrdup(provider->topicUri);
636         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(topicUri,
637         {
638             NSRemoveProvider_internal((void *) provider);
639             NSRemoveProvider_internal((void *) task->taskData);
640             NSOICFree(task);
641         });
642
643         OCConnectivityType type = CT_DEFAULT;
644         if (connections->addr->adapter == OC_ADAPTER_TCP)
645         {
646             type = CT_ADAPTER_TCP;
647             if (connections->isCloudConnection == true)
648             {
649                 topicUri = NSGetCloudUri(provider->providerId, topicUri);
650             }
651         }
652
653         NS_LOG(DEBUG, "get topic query");
654         char * query = NSMakeRequestUriWithConsumerId(topicUri);
655         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(query,
656         {
657             NSRemoveProvider_internal((void *) provider);
658             NSRemoveProvider_internal((void *) task->taskData);
659             NSOICFree(task);
660         });
661         NS_LOG_V(DEBUG, "topic query : %s", query);
662
663         OCStackResult ret = NSInvokeRequest(NULL, OC_REST_GET, connections->addr,
664                                 query, NULL, NSIntrospectTopic, (void *) provider,
665                                 NSRemoveProvider_internal, type);
666         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(NSOCResultToSuccess(ret) == true ? (void *) 1 : NULL,
667         {
668             NSRemoveProvider_internal((void *) provider);
669             NSRemoveProvider_internal((void *) task->taskData);
670             NSOICFree(task);
671         });
672
673         NSOICFree(query);
674         NSOICFree(topicUri);
675     }
676     else if (task->taskType == TASK_CONSUMER_SELECT_TOPIC_LIST)
677     {
678         NSProvider_internal * provider = (NSProvider_internal *)task->taskData;
679         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(provider,
680         {
681             NSRemoveProvider_internal(provider);
682             NSOICFree(task);
683         });
684
685         NSProviderConnectionInfo * connections = provider->connection;
686         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(connections,
687         {
688             NSRemoveProvider_internal(provider);
689             NSOICFree(task);
690         });
691
692         OCRepPayload * payload = OCRepPayloadCreate();
693         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(payload,
694         {
695             NSRemoveProvider_internal(provider);
696             NSOICFree(task);
697         });
698
699         NSTopicLL * topicLL = provider->topicLL;
700         NSTopicLL * iter = topicLL;
701         int topicLLSize = 0;
702         while (iter)
703         {
704             topicLLSize ++;
705             NS_LOG_V(DEBUG, "[%d] Topic Name:%s\tTopic State:%d",
706                                         topicLLSize, iter->topicName, iter->state);
707             iter = (NSTopicLL *) iter->next;
708         }
709
710         OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_CONSUMER_ID, *NSGetConsumerId());
711         NS_LOG_V(DEBUG, "NS_ATTRIBUTE_CONSUMER_ID: %s", *NSGetConsumerId());
712
713         iter = topicLL;
714         int iterSize = 0;
715         NS_LOG_V(DEBUG, "DimensionSize: %d", topicLLSize);
716
717         OCRepPayload ** topicPayload = NULL;
718         if (topicLLSize > 0)
719         {
720             topicPayload = (OCRepPayload **) OICMalloc(sizeof(OCRepPayload *)*topicLLSize);
721             NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(topicPayload,
722             {
723                 OCRepPayloadDestroy(payload);
724                 NSRemoveProvider_internal(provider);
725                 NSOICFree(task);
726             });
727
728             while (iter || iterSize < topicLLSize)
729             {
730                 topicPayload[iterSize] = OCRepPayloadCreate();
731                 OCRepPayloadSetPropString(topicPayload[iterSize], NS_ATTRIBUTE_TOPIC_NAME,
732                                             iter->topicName);
733                 OCRepPayloadSetPropInt(topicPayload[iterSize], NS_ATTRIBUTE_TOPIC_SELECTION,
734                                             iter->state);
735                 NS_LOG_V(DEBUG, "NS_ATTRIBUTE_TOPIC_NAME: %s", iter->topicName);
736                 NS_LOG_V(DEBUG, "NS_ATTRIBUTE_TOPIC_SELECTION: %d", iter->state);
737                 iterSize++;
738                 iter = iter->next;
739             }
740             size_t dimensions[3] = {topicLLSize, 0, 0};
741
742             OCRepPayloadSetPropObjectArrayAsOwner(payload, NS_ATTRIBUTE_TOPIC_LIST,
743                                                     topicPayload, dimensions);
744         }
745         else
746         {
747             OCRepPayloadSetNull(payload, NS_ATTRIBUTE_TOPIC_LIST);
748         }
749
750         char * topicUri = OICStrdup(provider->topicUri);
751         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(topicUri,
752         {
753             OCRepPayloadDestroy(payload);
754             NSRemoveProvider_internal(provider);
755             NSOICFree(task);
756         });
757
758         OCConnectivityType type = CT_DEFAULT;
759         if (connections->addr->adapter == OC_ADAPTER_TCP)
760         {
761             type = CT_ADAPTER_TCP;
762             if (connections->isCloudConnection == true)
763             {
764                 topicUri = NSGetCloudUri(provider->providerId, topicUri);
765             }
766         }
767
768         NS_LOG(DEBUG, "get topic query");
769         char * query = NULL;
770         query = NSMakeRequestUriWithConsumerId(topicUri);
771         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(query,
772         {
773             NSOICFree(topicUri);
774             OCRepPayloadDestroy(payload);
775             NSRemoveProvider_internal(provider);
776             NSOICFree(task);
777         });
778         NS_LOG_V(DEBUG, "topic query : %s", query);
779
780         OCStackResult ret = NSInvokeRequest(NULL, OC_REST_POST, connections->addr,
781                                 query, (OCPayload*)payload, NSConsumerCheckPostResult,
782                                 NULL, NULL, type);
783         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(
784                 NSOCResultToSuccess(ret) == true ? (void *) 1 : NULL,
785         {
786             NSOICFree(query);
787             NSOICFree(topicUri);
788             NSRemoveProvider_internal(provider);
789             NSOICFree(task);
790         });
791
792         NSRemoveProvider_internal(provider);
793         NSOICFree(query);
794         NSOICFree(topicUri);
795     }
796     else
797     {
798         NS_LOG(ERROR, "Unknown type message");
799     }
800
801     NSOICFree(task);
802 }
803
804 NSTopicLL * NSGetTopicLL(OCClientResponse * clientResponse)
805 {
806     NS_LOG(DEBUG, "create NSTopicLL");
807     NS_VERIFY_NOT_NULL(clientResponse->payload, NULL);
808
809     OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;
810     OCRepPayloadValue * value = payload->values;
811     while (value)
812     {
813         NS_LOG_V(DEBUG, "Payload Key : %s", value->name);
814         value = value->next;
815     }
816
817     char * consumerId = NULL;
818     OCRepPayload ** topicLLPayload = NULL;
819
820     NS_LOG(DEBUG, "get information of consumerId");
821
822     bool getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_CONSUMER_ID, & consumerId);
823     NSOICFree(consumerId);
824
825     OCRepPayloadValue * payloadValue = NULL;
826     payloadValue = NSPayloadFindValue(payload, NS_ATTRIBUTE_TOPIC_LIST);
827     NS_VERIFY_NOT_NULL(payloadValue, NULL);
828
829     size_t dimensionSize = calcDimTotal(payloadValue->arr.dimensions);
830     NS_LOG_V(DEBUG, "DimensionSize: %d", (int)dimensionSize);
831
832     if (dimensionSize == 0 || payloadValue->type == OCREP_PROP_NULL ||
833             payloadValue->arr.objArray == NULL)
834     {
835         NS_LOG(DEBUG, "No TopicLL");
836         return NULL;
837     }
838
839     topicLLPayload = payloadValue->arr.objArray;
840
841     NSTopicLL * topicLL = NULL;
842     for (int i = 0; i < (int)dimensionSize; i++)
843     {
844         char * topicName = NULL;
845         int64_t state = 0;
846
847         NSTopicLL * topicNode = (NSTopicLL *) OICMalloc(sizeof(NSTopicLL));
848         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(topicNode, NULL, NSRemoveTopicLL(topicLL));
849
850         NS_LOG(DEBUG, "get topic selection");
851         getResult = OCRepPayloadGetPropInt(topicLLPayload[i],
852                 NS_ATTRIBUTE_TOPIC_SELECTION, & state);
853         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(getResult == true ? (void *) 1 : NULL,
854                 NULL, NSRemoveTopicLL(topicLL));
855
856         NS_LOG(DEBUG, "get topic name");
857         getResult = OCRepPayloadGetPropString(topicLLPayload[i],
858                 NS_ATTRIBUTE_TOPIC_NAME, & topicName);
859         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(getResult == true ? (void *) 1 : NULL,
860                 NULL, NSRemoveTopicLL(topicLL));
861         NS_LOG_V(DEBUG, "topic name: %s", topicName);
862         NS_LOG_V(DEBUG, "topic selection: %d", (int)state);
863
864         topicNode->topicName = topicName;
865         topicNode->state = state;
866
867         if (i == 0)
868         {
869             topicLL = topicNode;
870             topicNode->next = NULL;
871             continue;
872         }
873
874         NSResult ret = NSInsertTopicNode(topicLL, topicNode);
875         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(ret == NS_OK ? (void *)1 : NULL,
876                                                     NULL, NSRemoveTopicLL(topicLL));
877     }
878
879     return topicLL;
880 }
881
882 OCStackApplicationResult NSIntrospectTopic(
883         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
884 {
885     (void) handle;
886
887     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
888     NS_VERIFY_STACK_SUCCESS(NSOCResultToSuccess(clientResponse->result),
889                             OC_STACK_KEEP_TRANSACTION)
890
891     NS_LOG_V(DEBUG, "GET response income : %s:%d",
892             clientResponse->devAddr.addr, clientResponse->devAddr.port);
893     NS_LOG_V(DEBUG, "GET response result : %d",
894             clientResponse->result);
895     NS_LOG_V(DEBUG, "GET response sequenceNum : %d",
896             clientResponse->sequenceNumber);
897     NS_LOG_V(DEBUG, "GET response resource uri : %s",
898             clientResponse->resourceUri);
899     NS_LOG_V(DEBUG, "GET response Transport Type : %d",
900             clientResponse->devAddr.adapter);
901
902     NSTopicLL * newTopicLL = NSGetTopicLL(clientResponse);
903
904     NSProvider_internal * provider = NSCopyProvider_internal((NSProvider_internal *) ctx);
905     NS_VERIFY_NOT_NULL(provider, OC_STACK_KEEP_TRANSACTION);
906     NSRemoveTopicLL(provider->topicLL);
907     provider->topicLL = NSCopyTopicLL(newTopicLL);
908     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(provider->topicLL, OC_STACK_KEEP_TRANSACTION,
909                           NSRemoveProvider_internal((void *) provider));
910
911     NS_LOG(DEBUG, "build NSTask");
912     NSTask * task = NSMakeTask(TASK_CONSUMER_RECV_TOPIC_LIST, (void *) provider);
913     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(task, NS_ERROR, NSRemoveProvider_internal(provider));
914
915     NSConsumerPushEvent(task);
916     NSRemoveTopicLL(newTopicLL);
917
918     return OC_STACK_KEEP_TRANSACTION;
919 }