Merge branch 'master' into notification-service
[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 NSProviderDiscoveredCallback * NSGetBoneDiscoverCb()
109 {
110     static NSProviderDiscoveredCallback g_discoverCb = NULL;
111
112     return & g_discoverCb;
113 }
114
115 void NSSetDiscoverProviderCb(NSProviderDiscoveredCallback cb)
116 {
117     * NSGetBoneDiscoverCb() = cb;
118 }
119
120 NSProviderDiscoveredCallback NSGetDiscoverCb()
121 {
122     return * NSGetBoneDiscoverCb();
123 }
124
125 void * NSDiscoveredProviderFunc(void * provider)
126 {
127     NSGetDiscoverCb()((NSProvider *) provider);
128
129     return NULL;
130 }
131
132 void NSDiscoveredProvider(NSProvider * provider)
133 {
134     NS_VERIFY_NOT_NULL_V(provider);
135
136     NSProvider * retProvider = (NSProvider *)NSCopyProvider((NSProvider_internal *)provider);
137     NS_VERIFY_NOT_NULL_V(retProvider);
138
139     NSConsumerThread * thread = NSThreadInit(NSDiscoveredProviderFunc, (void *) retProvider);
140     NS_VERIFY_NOT_NULL_V(thread);
141 }
142
143 NSProviderChangedCallback * NSGetProviderChangedCb()
144 {
145     static NSProviderChangedCallback g_changedCb = NULL;
146
147     return & g_changedCb;
148 }
149
150 void NSSetProviderChangedCb(NSProviderChangedCallback cb)
151 {
152     *(NSGetProviderChangedCb()) = cb;
153 }
154
155 void NSProviderChanged(NSProvider * provider, NSResponse response)
156 {
157     (*(NSGetProviderChangedCb()))(provider, response);
158 }
159
160 NSSyncInfoReceivedCallback * NSGetBoneNotificationSyncCb()
161 {
162     static NSSyncInfoReceivedCallback g_syncCb = NULL;
163
164     return & g_syncCb;
165 }
166
167 void NSSetNotificationSyncCb(NSSyncInfoReceivedCallback cb)
168 {
169     * NSGetBoneNotificationSyncCb() = cb;
170 }
171
172 void * NSNotificationSyncFunc(void * obj)
173 {
174     (* NSGetBoneNotificationSyncCb())((NSSyncInfo *) obj);
175     return NULL;
176 }
177
178 void NSNotificationSync(NSSyncInfo * sync)
179 {
180     NS_VERIFY_NOT_NULL_V(sync);
181
182     NSSyncInfo * retSync = (NSSyncInfo *)OICMalloc(sizeof(NSSyncInfo));
183     NS_VERIFY_NOT_NULL_V(retSync);
184     memcpy(retSync, sync, sizeof(NSSyncInfo));
185
186     NSConsumerThread * thread = NSThreadInit(NSNotificationSyncFunc, (void *) retSync);
187     NS_VERIFY_NOT_NULL_V(thread);
188 }
189
190 NSMessageReceivedCallback  * NSGetBoneMessagePostedCb()
191 {
192     static NSMessageReceivedCallback  g_postCb = NULL;
193
194     return & g_postCb;
195 }
196
197 void NSSetMessagePostedCb(NSMessageReceivedCallback  cb)
198 {
199     * NSGetBoneMessagePostedCb() = cb;
200 }
201
202 NSMessageReceivedCallback  NSGetMessagePostedCb()
203 {
204     return * NSGetBoneMessagePostedCb();
205 }
206
207 void * NSMessagePostFunc(void * obj)
208 {
209     NSGetMessagePostedCb()((NSMessage *) obj);
210     return NULL;
211 }
212
213 void NSMessagePost(NSMessage * msg)
214 {
215     NS_VERIFY_NOT_NULL_V(msg);
216
217     NSMessage * retMsg = NSCopyMessage(msg);
218     NS_VERIFY_NOT_NULL_V(retMsg);
219
220     NSConsumerThread * thread = NSThreadInit(NSMessagePostFunc, (void *) retMsg);
221     NS_VERIFY_NOT_NULL_V(thread);
222 }
223
224 NSTask * NSMakeTask(NSTaskType type, void * data)
225 {
226     NSTask * retTask = OICMalloc(sizeof(NSTask));
227     NS_VERIFY_NOT_NULL(retTask, NULL);
228
229     retTask->taskType = type;
230     retTask->taskData = data;
231     retTask->nextTask = NULL;
232
233     return retTask;
234 }
235
236 NSMessage * NSCopyMessage(NSMessage * msg)
237 {
238     NS_VERIFY_NOT_NULL(msg, NULL);
239
240     NSMessage * newMsg = (NSMessage *)OICMalloc(sizeof(NSMessage));
241     NS_VERIFY_NOT_NULL(newMsg, NULL);
242
243     OICStrcpy(newMsg->providerId, NS_DEVICE_ID_LENGTH, msg->providerId);
244
245     newMsg->messageId = msg->messageId;
246     newMsg->title = OICStrdup(msg->title);
247     newMsg->contentText = OICStrdup(msg->contentText);
248     newMsg->sourceName = OICStrdup(msg->sourceName);
249     newMsg->dateTime = OICStrdup(msg->dateTime);
250     newMsg->type = msg->type;
251
252     // TODO change to copy function.
253     newMsg->mediaContents = msg->mediaContents;
254
255     return newMsg;
256 }
257 void NSRemoveMessage(NSMessage * msg)
258 {
259     NS_VERIFY_NOT_NULL_V(msg);
260
261     msg->messageId = 0;
262     NSOICFree(msg->title);
263     NSOICFree(msg->contentText);
264     NSOICFree(msg->sourceName);
265     NSOICFree(msg->dateTime);
266
267     // TODO change to remove function.
268     NSOICFree(msg->mediaContents);
269
270     NSOICFree(msg);
271 }
272
273 void NSRemoveConnections(NSProviderConnectionInfo * connections)
274 {
275     NS_VERIFY_NOT_NULL_V(connections);
276
277     NSProviderConnectionInfo * tmp = connections;
278
279     while(tmp)
280     {
281         tmp->messageHandle = NULL;
282         tmp->syncHandle = NULL;
283         NSOICFree(tmp->addr);
284         tmp = tmp->next;
285     }
286
287     NSOICFree(connections);
288 }
289
290 NSProviderConnectionInfo * NSCreateProviderConnections(OCDevAddr * inAddr)
291 {
292     NSProviderConnectionInfo * connections
293         = (NSProviderConnectionInfo *)OICMalloc(sizeof(NSProviderConnectionInfo));
294     NS_VERIFY_NOT_NULL(connections, NULL);
295
296     connections->addr = NULL;
297     connections->messageHandle = NULL;
298     connections->syncHandle = NULL;
299     connections->isCloudConnection = false;
300     connections->isSubscribing = false;
301     connections->next = NULL;
302
303     if (inAddr)
304     {
305         connections->addr = (OCDevAddr *)OICMalloc(sizeof(OCDevAddr));
306         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(connections->addr, NULL, NSRemoveConnections(connections));
307         memcpy(connections->addr, inAddr, sizeof(OCDevAddr));
308     }
309
310     return connections;
311 }
312
313 NSProviderConnectionInfo * NSCopyProviderConnections(NSProviderConnectionInfo * conn)
314 {
315     NS_VERIFY_NOT_NULL(conn, NULL);
316     NSProviderConnectionInfo * tmp = conn;
317
318     NSProviderConnectionInfo * retInfo = NSCreateProviderConnections(tmp->addr);
319     NS_VERIFY_NOT_NULL(retInfo, NULL);
320     tmp = tmp->next;
321     NSProviderConnectionInfo * copyInfo = retInfo;
322
323     while(tmp)
324     {
325         copyInfo = NSCreateProviderConnections(tmp->addr);
326         NS_VERIFY_NOT_NULL(copyInfo, NULL);
327
328         copyInfo->messageHandle = tmp->messageHandle;
329         copyInfo->syncHandle = tmp->syncHandle;
330         copyInfo->isCloudConnection = tmp->isCloudConnection;
331         copyInfo->isSubscribing = tmp->isSubscribing;
332         tmp = tmp->next;
333         copyInfo = copyInfo->next;
334     }
335
336     return retInfo;
337 }
338
339 void NSRemoveProviderTopicList(NSTopicList * topicList, size_t dimensionSize)
340 {
341     NS_VERIFY_NOT_NULL_V(topicList);
342
343     for (int i = -1; i < (int)dimensionSize; i++)
344     {
345         NSOICFree(topicList->topics[i]);
346     }
347     NSOICFree(topicList);
348 }
349
350 NSTopicList * NSCopyProviderTopicList(NSTopicList * topicList, size_t dimensionSize)
351 {
352     NS_VERIFY_NOT_NULL(topicList, NULL);
353
354     NSTopicList * newTopicList = (NSTopicList *)OICMalloc(sizeof(NSTopicList));
355     NS_VERIFY_NOT_NULL(newTopicList, NULL);
356
357     OICStrcpy(newTopicList->consumerId, NS_DEVICE_ID_LENGTH, topicList->consumerId);
358
359     newTopicList->topics = (NSTopics **) OICMalloc(sizeof(NSTopics *)*dimensionSize);
360     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newTopicList->topics,
361             NULL, NSRemoveProviderTopicList(newTopicList, -1));
362
363     for (int i = 0; i < (int)dimensionSize; i++)
364     {
365         newTopicList->topics[i] = (NSTopics *) OICMalloc(sizeof(NSTopics));
366         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newTopicList->topics[i],
367             NULL, NSRemoveProviderTopicList(newTopicList, i));
368
369         newTopicList->topics[i]->topicName = OICStrdup(topicList->topics[i]->topicName);
370         newTopicList->topics[i]->state = topicList->topics[i]->state;
371     }
372
373     return newTopicList;
374 }
375
376 void NSCopyProviderPostClean(
377         NSProviderConnectionInfo * connections, NSProvider_internal * provider)
378 {
379     NSRemoveConnections(connections);
380     NSOICFree(provider);
381 }
382
383 NSProvider_internal * NSCopyProvider(NSProvider_internal * prov)
384 {
385     NS_VERIFY_NOT_NULL(prov, NULL);
386
387     NSProviderConnectionInfo * connections = NSCopyProviderConnections(prov->connection);
388     NS_VERIFY_NOT_NULL(connections, NULL);
389
390     NSProvider_internal * newProv = (NSProvider_internal *) OICMalloc(sizeof(NSProvider_internal));
391     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newProv, NULL, NSRemoveConnections(connections));
392
393     newProv->topicList = NULL;
394     newProv->topicListSize = 0;
395
396     if (prov->topicList)
397     {
398         NSTopicList * topicList = NSCopyProviderTopicList(prov->topicList, prov->topicListSize);
399         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(topicList, NULL,
400                     NSCopyProviderPostClean(connections, newProv));
401
402         newProv->topicList = topicList;
403         newProv->topicListSize = prov->topicListSize;
404     }
405
406     newProv->connection = connections;
407     OICStrcpy(newProv->providerId, NS_DEVICE_ID_LENGTH, prov->providerId);
408     newProv->messageUri = OICStrdup(prov->messageUri);
409     newProv->syncUri = OICStrdup(prov->syncUri);
410     newProv->topicUri = OICStrdup(prov->topicUri);
411     newProv->accessPolicy = prov->accessPolicy;
412
413     return newProv;
414 }
415
416 void NSRemoveProvider(NSProvider_internal * prov)
417 {
418     NS_VERIFY_NOT_NULL_V(prov);
419
420     NSOICFree(prov->messageUri);
421     NSOICFree(prov->syncUri);
422     NSOICFree(prov->topicUri);
423     NSRemoveConnections(prov->connection);
424     NSRemoveProviderTopicList(prov->topicList, prov->topicListSize);
425
426     NSOICFree(prov);
427 }
428
429 NSSyncInfo_internal * NSCopySyncInfo(NSSyncInfo_internal * syncInfo)
430 {
431     NS_VERIFY_NOT_NULL(syncInfo, NULL);
432
433     NSProviderConnectionInfo * connections = NSCopyProviderConnections(syncInfo->connection);
434     NS_VERIFY_NOT_NULL(connections, NULL);
435
436     NSSyncInfo_internal * newSyncInfo = (NSSyncInfo_internal *)OICMalloc(sizeof(NSSyncInfo_internal));
437     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newSyncInfo, NULL, NSRemoveConnections(connections));
438
439     OICStrcpy(newSyncInfo->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, syncInfo->providerId);
440     newSyncInfo->messageId = syncInfo->messageId;
441     newSyncInfo->state = syncInfo->state;
442     newSyncInfo->connection = connections;
443
444     return newSyncInfo;
445 }
446
447 void NSRemoveSyncInfo(NSSyncInfo_internal * syncInfo)
448 {
449     NS_VERIFY_NOT_NULL_V(syncInfo);
450
451     NSRemoveConnections(syncInfo->connection);
452
453     NSOICFree(syncInfo);
454 }
455
456 OCStackResult NSInvokeRequest(OCDoHandle * handle,
457         OCMethod method, const OCDevAddr * addr,
458         const char * queryUrl, OCPayload * payload,
459         void * callbackFunc, void * callbackData, OCConnectivityType type)
460 {
461     int mutexRet = pthread_mutex_lock(*(NSGetStackMutex()));
462     NS_VERIFY_NOT_NULL(mutexRet != 0 ? NULL : (void *)1, OC_STACK_ERROR);
463
464     OCCallbackData cbdata = { 0, };
465
466     cbdata.cb = callbackFunc;
467     cbdata.context = callbackData;
468     cbdata.cd = NULL;
469
470     OCStackResult ret = OCDoResource(handle, method, queryUrl, addr,
471                                      payload, type, NS_QOS, &cbdata, NULL, 0);
472
473     mutexRet = pthread_mutex_unlock(*(NSGetStackMutex()));
474     NS_VERIFY_NOT_NULL(mutexRet != 0 ? NULL : (void *)1, OC_STACK_ERROR);
475
476     return ret;
477 }
478
479 bool NSOCResultToSuccess(OCStackResult ret)
480 {
481     switch (ret)
482     {
483         case OC_STACK_OK:
484         case OC_STACK_RESOURCE_CREATED:
485         case OC_STACK_RESOURCE_DELETED:
486         case OC_STACK_CONTINUE:
487         case OC_STACK_RESOURCE_CHANGED:
488             return true;
489         default:
490             return false;
491     }
492 }