Remove consumer callback for discovered provider.
[platform/upstream/iotivity.git] / service / notification / src / consumer / NSConsumerCommon.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 "NSConsumerCommon.h"
22 #include "NSConstants.h"
23 #include "NSThread.h"
24 #include "oic_malloc.h"
25 #include "oic_string.h"
26
27 #include <pthread.h>
28
29 #define NS_QUERY_CONSUMER_ID "consumerid"
30
31 pthread_mutex_t ** NSGetStackMutex()
32 {
33     static pthread_mutex_t * g_stackMutext = NULL;
34     if (g_stackMutext == NULL)
35     {
36         g_stackMutext = (pthread_mutex_t *)OICMalloc(sizeof(pthread_mutex_t));
37         NS_VERIFY_NOT_NULL(g_stackMutext, NULL);
38         pthread_mutex_init(g_stackMutext, NULL);
39     }
40
41     return & g_stackMutext;
42 }
43
44 char ** NSGetConsumerId()
45 {
46     static char * g_consumerId = NULL;
47     return & g_consumerId;
48 }
49
50 void NSSetConsumerId(char * cId)
51 {
52     NS_VERIFY_NOT_NULL_V(cId);
53     char ** consumerId = NSGetConsumerId();
54     NSOICFree(*consumerId);
55     *consumerId = (char *)OICMalloc(sizeof(char) * NS_DEVICE_ID_LENGTH);
56     NS_VERIFY_NOT_NULL_V(*consumerId);
57
58     OICStrcpy(*consumerId, sizeof(char) * NS_DEVICE_ID_LENGTH, cId);
59 }
60
61 char * NSMakeRequestUriWithConsumerId(const char * uri)
62 {
63     NS_VERIFY_NOT_NULL(uri, NULL);
64
65     char * consumerId = OICStrdup(*NSGetConsumerId());
66     NS_VERIFY_NOT_NULL(consumerId, NULL);
67
68     size_t uriLen = strlen(uri) + 1;
69     size_t qKeyLen = sizeof(NS_QUERY_CONSUMER_ID);
70     size_t queryLen = NS_DEVICE_ID_LENGTH + uriLen + qKeyLen + 2;
71
72     char * retQuery = (char *)OICMalloc(sizeof(char) * queryLen);
73     NS_VERIFY_NOT_NULL(retQuery, NULL);
74
75     size_t index = 0;
76     OICStrcpy((retQuery + index), uriLen, uri);
77     index += uriLen - 1;
78     OICStrcpy((retQuery + index), 2, "?");
79     index += 1;
80     OICStrcpy((retQuery + index), qKeyLen, NS_QUERY_CONSUMER_ID);
81     index += qKeyLen - 1;
82     OICStrcpy((retQuery + index), 2, "=");
83     index += 1;
84     OICStrcpy((retQuery + index), NS_DEVICE_ID_LENGTH, consumerId);
85
86     NSOICFree(consumerId);
87
88     return retQuery;
89 }
90
91 bool * NSGetBoneIsStartedConsumer()
92 {
93     static bool g_isStartedConsumer = false;
94
95     return & g_isStartedConsumer;
96 }
97
98 void NSSetIsStartedConsumer(bool setValue)
99 {
100     * NSGetBoneIsStartedConsumer() = setValue;
101 }
102
103 bool NSIsStartedConsumer()
104 {
105     return * NSGetBoneIsStartedConsumer();
106 }
107
108 NSProviderStateCallback * NSGetProviderChangedCb()
109 {
110     static NSProviderStateCallback g_changedCb = NULL;
111
112     return & g_changedCb;
113 }
114
115 void NSSetProviderChangedCb(NSProviderStateCallback cb)
116 {
117     *(NSGetProviderChangedCb()) = cb;
118 }
119
120 void NSProviderChanged(NSProvider * provider, NSResponse response)
121 {
122     (*(NSGetProviderChangedCb()))(provider, response);
123 }
124
125 NSSyncInfoReceivedCallback * NSGetBoneNotificationSyncCb()
126 {
127     static NSSyncInfoReceivedCallback g_syncCb = NULL;
128
129     return & g_syncCb;
130 }
131
132 void NSSetNotificationSyncCb(NSSyncInfoReceivedCallback cb)
133 {
134     * NSGetBoneNotificationSyncCb() = cb;
135 }
136
137 void * NSNotificationSyncFunc(void * obj)
138 {
139     (* NSGetBoneNotificationSyncCb())((NSSyncInfo *) obj);
140     return NULL;
141 }
142
143 void NSNotificationSync(NSSyncInfo * sync)
144 {
145     NS_VERIFY_NOT_NULL_V(sync);
146
147     NSSyncInfo * retSync = (NSSyncInfo *)OICMalloc(sizeof(NSSyncInfo));
148     NS_VERIFY_NOT_NULL_V(retSync);
149     memcpy(retSync, sync, sizeof(NSSyncInfo));
150
151     NSConsumerThread * thread = NSThreadInit(NSNotificationSyncFunc, (void *) retSync);
152     NS_VERIFY_NOT_NULL_V(thread);
153 }
154
155 NSMessageReceivedCallback  * NSGetBoneMessagePostedCb()
156 {
157     static NSMessageReceivedCallback  g_postCb = NULL;
158
159     return & g_postCb;
160 }
161
162 void NSSetMessagePostedCb(NSMessageReceivedCallback  cb)
163 {
164     * NSGetBoneMessagePostedCb() = cb;
165 }
166
167 NSMessageReceivedCallback  NSGetMessagePostedCb()
168 {
169     return * NSGetBoneMessagePostedCb();
170 }
171
172 void * NSMessagePostFunc(void * obj)
173 {
174     NSGetMessagePostedCb()((NSMessage *) obj);
175     return NULL;
176 }
177
178 void NSMessagePost(NSMessage * msg)
179 {
180     NS_VERIFY_NOT_NULL_V(msg);
181
182     NSMessage * retMsg = NSCopyMessage(msg);
183     NS_VERIFY_NOT_NULL_V(retMsg);
184
185     NSConsumerThread * thread = NSThreadInit(NSMessagePostFunc, (void *) retMsg);
186     NS_VERIFY_NOT_NULL_V(thread);
187 }
188
189 NSTask * NSMakeTask(NSTaskType type, void * data)
190 {
191     NSTask * retTask = OICMalloc(sizeof(NSTask));
192     NS_VERIFY_NOT_NULL(retTask, NULL);
193
194     retTask->taskType = type;
195     retTask->taskData = data;
196     retTask->nextTask = NULL;
197
198     return retTask;
199 }
200
201 NSMessage * NSCopyMessage(NSMessage * msg)
202 {
203     NS_VERIFY_NOT_NULL(msg, NULL);
204
205     NSMessage * newMsg = (NSMessage *)OICMalloc(sizeof(NSMessage));
206     NS_VERIFY_NOT_NULL(newMsg, NULL);
207
208     OICStrcpy(newMsg->providerId, NS_DEVICE_ID_LENGTH, msg->providerId);
209
210     newMsg->messageId = msg->messageId;
211     newMsg->title = OICStrdup(msg->title);
212     newMsg->contentText = OICStrdup(msg->contentText);
213     newMsg->sourceName = OICStrdup(msg->sourceName);
214     newMsg->dateTime = OICStrdup(msg->dateTime);
215     newMsg->type = msg->type;
216     newMsg->topic = NULL;
217     if (msg->topic && strlen(msg->topic) > 0)
218     {
219         newMsg->topic = OICStrdup(msg->topic);
220     }
221
222     // TODO change to copy function.
223     newMsg->mediaContents = msg->mediaContents;
224
225     return newMsg;
226 }
227 void NSRemoveMessage(NSMessage * msg)
228 {
229     NS_VERIFY_NOT_NULL_V(msg);
230
231     msg->messageId = 0;
232     NSOICFree(msg->title);
233     NSOICFree(msg->contentText);
234     NSOICFree(msg->sourceName);
235     NSOICFree(msg->dateTime);
236     NSOICFree(msg->topic);
237
238     // TODO change to remove function.
239     NSOICFree(msg->mediaContents);
240
241     NSOICFree(msg);
242 }
243
244 void NSRemoveConnections(NSProviderConnectionInfo * connections)
245 {
246     NS_VERIFY_NOT_NULL_V(connections);
247
248     NSProviderConnectionInfo * tmp = connections;
249
250     while(tmp)
251     {
252         tmp->messageHandle = NULL;
253         tmp->syncHandle = NULL;
254         NSOICFree(tmp->addr);
255         tmp = tmp->next;
256     }
257
258     NSOICFree(connections);
259 }
260
261 NSProviderConnectionInfo * NSCreateProviderConnections(OCDevAddr * inAddr)
262 {
263     NSProviderConnectionInfo * connections
264         = (NSProviderConnectionInfo *)OICMalloc(sizeof(NSProviderConnectionInfo));
265     NS_VERIFY_NOT_NULL(connections, NULL);
266
267     connections->addr = NULL;
268     connections->messageHandle = NULL;
269     connections->syncHandle = NULL;
270     connections->isCloudConnection = false;
271     connections->isSubscribing = false;
272     connections->next = NULL;
273
274     if (inAddr)
275     {
276         connections->addr = (OCDevAddr *)OICMalloc(sizeof(OCDevAddr));
277         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(connections->addr, NULL, NSRemoveConnections(connections));
278         memcpy(connections->addr, inAddr, sizeof(OCDevAddr));
279     }
280
281     return connections;
282 }
283
284 NSProviderConnectionInfo * NSCopyProviderConnections(NSProviderConnectionInfo * conn)
285 {
286     NS_VERIFY_NOT_NULL(conn, NULL);
287     NSProviderConnectionInfo * tmp = conn;
288
289     NSProviderConnectionInfo * retInfo = NSCreateProviderConnections(tmp->addr);
290     NS_VERIFY_NOT_NULL(retInfo, NULL);
291     retInfo->messageHandle = tmp->messageHandle;
292     retInfo->syncHandle = tmp->syncHandle;
293     retInfo->isCloudConnection = tmp->isCloudConnection;
294     retInfo->isSubscribing = tmp->isSubscribing;
295
296     tmp = tmp->next;
297     NSProviderConnectionInfo * copyInfo = retInfo;
298
299     while(tmp)
300     {
301         NSProviderConnectionInfo * tmpInfo = NSCreateProviderConnections(tmp->addr);
302         NS_VERIFY_NOT_NULL(tmpInfo, NULL);
303
304         tmpInfo->messageHandle = tmp->messageHandle;
305         tmpInfo->syncHandle = tmp->syncHandle;
306         tmpInfo->isCloudConnection = tmp->isCloudConnection;
307         tmpInfo->isSubscribing = tmp->isSubscribing;
308         tmp = tmp->next;
309         copyInfo->next = tmpInfo;
310         copyInfo = tmpInfo;
311     }
312
313     return retInfo;
314 }
315
316 void NSRemoveTopicNode(NSTopicLL * topicNode)
317 {
318     NS_VERIFY_NOT_NULL_V(topicNode);
319
320     NSOICFree(topicNode->topicName);
321     topicNode->next = NULL;
322
323     NSOICFree(topicNode);
324 }
325
326 NSTopicLL * NSCopyTopicNode(NSTopicLL * topicNode)
327 {
328     NS_VERIFY_NOT_NULL(topicNode, NULL);
329
330     NSTopicLL * newTopicNode = (NSTopicLL *)OICMalloc(sizeof(NSTopicLL));
331     NS_VERIFY_NOT_NULL(newTopicNode, NULL);
332
333     newTopicNode->topicName = OICStrdup(topicNode->topicName);
334     newTopicNode->state = topicNode->state;
335     newTopicNode->next = NULL;
336
337     return newTopicNode;
338 }
339
340 NSResult NSInsertTopicNode(NSTopicLL * topicHead, NSTopicLL * topicNode)
341 {
342     NS_VERIFY_NOT_NULL(topicHead, NS_ERROR);
343     NS_VERIFY_NOT_NULL(topicNode, NS_ERROR);
344
345     NSTopicLL * iter = topicHead;
346     NSTopicLL * prev = NULL;
347
348     while (iter)
349     {
350         prev = iter;
351         iter = (NSTopicLL *) iter->next;
352     }
353
354     prev->next = topicNode;
355     topicNode->next = NULL;
356
357     return NS_OK;
358 }
359
360 void NSRemoveTopicLL(NSTopicLL * topicHead)
361 {
362     NS_VERIFY_NOT_NULL_V(topicHead);
363
364     NSTopicLL * iter = topicHead;
365     NSTopicLL * following = NULL;
366
367     while (iter)
368     {
369         following = iter->next;
370
371         NSRemoveTopicNode(iter);
372
373         iter = following;
374     }
375 }
376
377 NSTopicLL * NSCopyTopicLL(NSTopicLL * topicHead)
378 {
379     NS_VERIFY_NOT_NULL(topicHead, NULL);
380
381     NSTopicLL * iter = topicHead;
382
383     NS_LOG_V(DEBUG, "[NSCopyTopicLL] Name:%s\t State:%d", iter->topicName, iter->state);
384     NSTopicLL * newTopicHead = NSCopyTopicNode(iter);
385     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newTopicHead, NULL, NSRemoveTopicLL(newTopicHead));
386
387     iter = (NSTopicLL *) iter->next;
388
389     while (iter)
390     {
391         NS_LOG_V(DEBUG, "[NSCopyTopicLL] Name:%s\t State:%d", iter->topicName, iter->state);
392         NSTopicLL * newTopicNode = NSCopyTopicNode(iter);
393         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newTopicNode, NULL, NSRemoveTopicLL(newTopicHead));
394
395         NSResult ret = NSInsertTopicNode(newTopicHead, newTopicNode);
396         NS_VERIFY_STACK_SUCCESS_WITH_POST_CLEANING(ret, NULL, NSRemoveTopicLL(newTopicHead));
397
398         iter = (NSTopicLL *) iter->next;
399     }
400
401     return newTopicHead;
402 }
403
404 void NSCopyProviderPostClean(
405         NSProviderConnectionInfo * connections, NSProvider_internal * provider)
406 {
407     NSRemoveConnections(connections);
408     NSOICFree(provider);
409 }
410
411 NSProvider_internal * NSCopyProvider_internal(NSProvider_internal * prov)
412 {
413     NS_VERIFY_NOT_NULL(prov, NULL);
414
415     NSProviderConnectionInfo * connections = NSCopyProviderConnections(prov->connection);
416     NS_VERIFY_NOT_NULL(connections, NULL);
417
418     NSProvider_internal * newProv = (NSProvider_internal *) OICMalloc(sizeof(NSProvider_internal));
419     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newProv, NULL, NSRemoveConnections(connections));
420
421     newProv->topicLL = NULL;
422
423     if (prov->topicLL)
424     {
425         NSTopicLL * newTopicLL = NSCopyTopicLL(prov->topicLL);
426         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newTopicLL, NULL,
427                     NSCopyProviderPostClean(connections, newProv));
428
429         newProv->topicLL = newTopicLL;
430     }
431
432     newProv->connection = connections;
433     OICStrcpy(newProv->providerId, NS_DEVICE_ID_LENGTH, prov->providerId);
434     newProv->messageUri = OICStrdup(prov->messageUri);
435     newProv->syncUri = OICStrdup(prov->syncUri);
436     newProv->topicUri = OICStrdup(prov->topicUri);
437     newProv->accessPolicy = prov->accessPolicy;
438
439     return newProv;
440 }
441
442 NSProvider * NSCopyProvider(NSProvider_internal * prov)
443 {
444     NS_VERIFY_NOT_NULL(prov, NULL);
445
446     NSProvider * newProv = (NSProvider *) OICMalloc(sizeof(NSProvider));
447     NS_VERIFY_NOT_NULL(newProv, NULL);
448
449     newProv->topicLL = NULL;
450
451     if (prov->topicLL)
452     {
453         NSTopicLL * topicList = NSCopyTopicLL(prov->topicLL);
454         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(topicList, NULL, NSRemoveProvider(newProv));
455
456         newProv->topicLL = topicList;
457     }
458
459     OICStrcpy(newProv->providerId, NS_DEVICE_ID_LENGTH, prov->providerId);
460
461     return newProv;
462 }
463
464 void NSRemoveProvider_internal(NSProvider_internal * prov)
465 {
466     NS_VERIFY_NOT_NULL_V(prov);
467
468     NSOICFree(prov->messageUri);
469     NSOICFree(prov->syncUri);
470     NSOICFree(prov->topicUri);
471     NSRemoveConnections(prov->connection);
472     if (prov->topicLL)
473     {
474         NSRemoveTopicLL(prov->topicLL);
475     }
476
477     NSOICFree(prov);
478 }
479
480 void NSRemoveProvider(NSProvider * prov)
481 {
482     NS_VERIFY_NOT_NULL_V(prov);
483
484     if (prov->topicLL)
485     {
486         NSRemoveTopicLL(prov->topicLL);
487     }
488
489     NSOICFree(prov);
490 }
491
492 NSSyncInfo_internal * NSCopySyncInfo(NSSyncInfo_internal * syncInfo)
493 {
494     NS_VERIFY_NOT_NULL(syncInfo, NULL);
495
496     NSProviderConnectionInfo * connections = NSCopyProviderConnections(syncInfo->connection);
497     NS_VERIFY_NOT_NULL(connections, NULL);
498
499     NSSyncInfo_internal * newSyncInfo = (NSSyncInfo_internal *)OICMalloc(sizeof(NSSyncInfo_internal));
500     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newSyncInfo, NULL, NSRemoveConnections(connections));
501
502     OICStrcpy(newSyncInfo->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, syncInfo->providerId);
503     newSyncInfo->messageId = syncInfo->messageId;
504     newSyncInfo->state = syncInfo->state;
505     newSyncInfo->connection = connections;
506
507     return newSyncInfo;
508 }
509
510 void NSRemoveSyncInfo(NSSyncInfo_internal * syncInfo)
511 {
512     NS_VERIFY_NOT_NULL_V(syncInfo);
513
514     NSRemoveConnections(syncInfo->connection);
515
516     NSOICFree(syncInfo);
517 }
518
519 OCStackResult NSInvokeRequest(OCDoHandle * handle,
520         OCMethod method, const OCDevAddr * addr,
521         const char * queryUrl, OCPayload * payload,
522         void * callbackFunc, void * callbackData, OCConnectivityType type)
523 {
524     int mutexRet = pthread_mutex_lock(*(NSGetStackMutex()));
525     NS_VERIFY_NOT_NULL(mutexRet != 0 ? NULL : (void *)1, OC_STACK_ERROR);
526
527     OCCallbackData cbdata = { 0, };
528
529     cbdata.cb = callbackFunc;
530     cbdata.context = callbackData;
531     cbdata.cd = NULL;
532
533     OCStackResult ret = OCDoResource(handle, method, queryUrl, addr,
534                                      payload, type, NS_QOS, &cbdata, NULL, 0);
535
536     mutexRet = pthread_mutex_unlock(*(NSGetStackMutex()));
537     NS_VERIFY_NOT_NULL(mutexRet != 0 ? NULL : (void *)1, OC_STACK_ERROR);
538
539     return ret;
540 }
541
542 bool NSOCResultToSuccess(OCStackResult ret)
543 {
544     switch (ret)
545     {
546         case OC_STACK_OK:
547         case OC_STACK_RESOURCE_CREATED:
548         case OC_STACK_RESOURCE_DELETED:
549         case OC_STACK_PRESENCE_STOPPED:
550         case OC_STACK_CONTINUE:
551         case OC_STACK_RESOURCE_CHANGED:
552             return true;
553         default:
554             NS_LOG_V(DEBUG, "OCStackResult : %d", (int)ret);
555             return false;
556     }
557 }