Imported Upstream version 1.2.0
[platform/upstream/iotivity.git] / service / notification / src / provider / NSProviderInterface.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 "NSProviderInterface.h"
22 #include "NSProviderScheduler.h"
23 #include "NSProviderListener.h"
24 #include "NSProviderSubscription.h"
25 #include "NSProviderNotification.h"
26 #include "NSProviderCallbackResponse.h"
27 #include "NSProviderMemoryCache.h"
28 #include "NSProviderTopic.h"
29 #include "oic_malloc.h"
30 #include "oic_string.h"
31 #include "cautilinterface.h"
32 #include "NSProviderSystem.h"
33 #include "oic_time.h"
34 #include <pthread.h>
35
36 bool initProvider = false;
37
38 pthread_mutex_t nsInitMutex;
39 pthread_cond_t nstopicCond;
40
41 void initializeMutex()
42 {
43     static pthread_mutex_t initMutex = PTHREAD_MUTEX_INITIALIZER;
44     nsInitMutex = initMutex;
45 }
46
47 void NSInitialize()
48 {
49     NS_LOG(DEBUG, "NSSetList - IN");
50
51     pthread_mutexattr_init(&NSCacheMutexAttr);
52     pthread_mutexattr_settype(&NSCacheMutexAttr, PTHREAD_MUTEX_RECURSIVE);
53     pthread_mutex_init(&NSCacheMutex, &NSCacheMutexAttr);
54     pthread_cond_init(&nstopicCond, NULL);
55
56     NSInitSubscriptionList();
57     NSInitTopicList();
58     NS_LOG(DEBUG, "NSSetList - OUT");
59 }
60
61 void NSDeinitailize()
62 {
63     NSProviderStorageDestroy(consumerSubList);
64     NSProviderStorageDestroy(consumerTopicList);
65     NSProviderStorageDestroy(registeredTopicList);
66
67     pthread_mutex_destroy(&NSCacheMutex);
68     pthread_mutexattr_destroy(&NSCacheMutexAttr);
69     pthread_cond_destroy(&nstopicCond);
70 }
71
72 NSResult NSStartProvider(NSProviderConfig config)
73 {
74     NS_LOG(DEBUG, "NSStartProvider - IN");
75
76     initializeMutex();
77
78     pthread_mutex_lock(&nsInitMutex);
79
80     if (!initProvider)
81     {
82         NS_LOG(DEBUG, "Init Provider");
83         initProvider = true;
84         NSInitProviderInfo(config.userInfo);
85         NSSetSubscriptionAccessPolicy(config.subControllability);
86         NSRegisterSubscribeRequestCb(config.subRequestCallback);
87         NSRegisterSyncCb(config.syncInfoCallback);
88         CARegisterNetworkMonitorHandler((CAAdapterStateChangedCB)NSProviderAdapterStateListener,
89                 (CAConnectionStateChangedCB)NSProviderConnectionStateListener);
90
91         NS_LOG(DEBUG, "Check secured build option..");
92 #ifdef SECURED
93         NS_LOG(DEBUG, "Built with SECURED");
94
95         if(!config.resourceSecurity)
96         {
97             NS_LOG(DEBUG, "Resource Security Off");
98         }
99         NSSetResourceSecurity(config.resourceSecurity);
100 #endif
101
102         NSInitialize();
103         NSInitScheduler();
104         NSStartScheduler();
105
106         NSPushQueue(DISCOVERY_SCHEDULER, TASK_START_PRESENCE, NULL);
107         NSPushQueue(DISCOVERY_SCHEDULER, TASK_REGISTER_RESOURCE, NULL);
108     }
109     else
110     {
111         NS_LOG(DEBUG, "Already started Notification Provider");
112     }
113     pthread_mutex_unlock(&nsInitMutex);
114
115     NS_LOG(DEBUG, "NSStartProvider - OUT");
116     return NS_OK;
117 }
118
119 NSResult NSStopProvider()
120 {
121     NS_LOG(DEBUG, "NSStopProvider - IN");
122     pthread_mutex_lock(&nsInitMutex);
123
124     if(initProvider)
125     {
126         NSPushQueue(DISCOVERY_SCHEDULER, TASK_STOP_PRESENCE, NULL);
127         NSDeinitProviderInfo();
128         NSUnRegisterResource();
129         NSRegisterSubscribeRequestCb((NSSubscribeRequestCallback)NULL);
130         NSRegisterSyncCb((NSProviderSyncInfoCallback)NULL);
131         NSStopScheduler();
132         NSDeinitailize();
133
134         initProvider = false;
135     }
136
137     pthread_mutex_unlock(&nsInitMutex);
138     NS_LOG(DEBUG, "NSStopProvider - OUT");
139     return NS_OK;
140 }
141
142 NSResult NSProviderEnableRemoteService(char *serverAddress)
143 {
144 #if(defined WITH_CLOUD && defined RD_CLIENT)
145     NS_LOG(DEBUG, "NSProviderEnableRemoteService - IN");
146     pthread_mutex_lock(&nsInitMutex);
147
148     if(!initProvider || !serverAddress)
149     {
150         NS_LOG(DEBUG, "Provider service has not been started yet");
151         pthread_mutex_unlock(&nsInitMutex);
152         return NS_FAIL;
153     }
154     NS_LOG_V(DEBUG, "Remote server address: %s", serverAddress);
155     NS_LOG(DEBUG, "Request to publish resource");
156     NSPushQueue(DISCOVERY_SCHEDULER, TASK_PUBLISH_RESOURCE, serverAddress);
157
158     pthread_mutex_unlock(&nsInitMutex);
159     NS_LOG(DEBUG, "NSProviderEnableRemoteService - OUT");
160     return NS_OK;
161 #else
162     (void) serverAddress;
163 #endif
164     NS_LOG_V(DEBUG, "Not logged in remote server: %s", serverAddress);
165     return NS_FAIL;
166 }
167
168 NSResult NSProviderDisableRemoteService(char *serverAddress)
169 {
170 #if(defined WITH_CLOUD && defined RD_CLIENT)
171     NS_LOG(DEBUG, "NSProviderDisableRemoteService - IN");
172     pthread_mutex_lock(&nsInitMutex);
173
174     if(!initProvider || !serverAddress)
175     {
176         NS_LOG(DEBUG, "Provider service has not been started yet");
177         return NS_FAIL;
178     }
179     NS_LOG_V(DEBUG, "Remote server address: %s", serverAddress);
180
181     NS_LOG(DEBUG, "Delete remote server info");
182     NSDeleteRemoteServerAddress(serverAddress);
183
184     pthread_mutex_unlock(&nsInitMutex);
185     NS_LOG(DEBUG, "NSProviderDisableRemoteService - OUT");
186     return NS_OK;
187 #else
188     (void) serverAddress;
189 #endif
190     NS_LOG_V(DEBUG, "Not logged in remote server : %s", serverAddress);
191     return NS_FAIL;
192 }
193
194 NSResult NSSendMessage(NSMessage * msg)
195 {
196     NS_LOG(DEBUG, "NSSendNotification - IN");
197
198     pthread_mutex_lock(&nsInitMutex);
199
200     if (!initProvider || msg == NULL)
201     {
202         NS_LOG(ERROR, "Msg is NULL");
203         pthread_mutex_unlock(&nsInitMutex);
204         return NS_FAIL;
205     }
206
207     NSMessage * newMsg = NSDuplicateMessage(msg);
208     NSPushQueue(NOTIFICATION_SCHEDULER, TASK_SEND_NOTIFICATION, newMsg);
209
210     pthread_mutex_unlock(&nsInitMutex);
211
212     NS_LOG(DEBUG, "NSSendNotification - OUT");
213     return NS_OK;
214 }
215
216 NSResult NSProviderSendSyncInfo(uint64_t messageId, NSSyncType type)
217 {
218     NS_LOG(DEBUG, "NSProviderReadCheck - IN");
219     pthread_mutex_lock(&nsInitMutex);
220
221     NSSyncInfo * syncInfo = (NSSyncInfo *)OICMalloc(sizeof(NSSyncInfo));
222
223     if (!initProvider || !syncInfo)
224     {
225         NS_LOG(ERROR, "Provider is not started");
226         pthread_mutex_unlock(&nsInitMutex);
227         return NS_FAIL;
228     }
229
230     OICStrcpy(syncInfo->providerId, UUID_STRING_SIZE, NSGetProviderInfo()->providerId);
231     syncInfo->messageId = messageId;
232     syncInfo->state = type;
233     NSPushQueue(NOTIFICATION_SCHEDULER, TASK_SEND_READ, syncInfo);
234
235     pthread_mutex_unlock(&nsInitMutex);
236     NS_LOG(DEBUG, "NSProviderReadCheck - OUT");
237     return NS_OK;
238 }
239
240 NSResult NSAcceptSubscription(const char * consumerId, bool accepted)
241 {
242     NS_LOG(DEBUG, "NSAccept - IN");
243     pthread_mutex_lock(&nsInitMutex);
244
245     if(!initProvider || !consumerId || consumerId[0] == '\0' || NSGetPolicy() == NS_POLICY_CONSUMER)
246     {
247         NS_LOG(ERROR, "Provider is not started or consumerId is NULL or NS Policy is Consumer");
248         pthread_mutex_unlock(&nsInitMutex);
249         return NS_FAIL;
250     }
251
252     char * newConsumerId = OICStrdup(consumerId);
253     if(accepted)
254     {
255         NS_LOG(DEBUG, "accepted is true - ALLOW");
256         NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_SEND_ALLOW, newConsumerId);
257     }
258     else
259     {
260         NS_LOG(DEBUG, "accepted is false - DENY");
261         NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_SEND_DENY, newConsumerId);
262     }
263
264     pthread_mutex_unlock(&nsInitMutex);
265     NS_LOG(DEBUG, "NSAccept - OUT");
266     return NS_OK;
267 }
268
269 NSMessage * NSCreateMessage()
270 {
271     NS_LOG(DEBUG, "NSCreateMessage - IN");
272     pthread_mutex_lock(&nsInitMutex);
273
274     NSMessage * msg = NSInitializeMessage();
275
276     OICStrcpy(msg->providerId, UUID_STRING_SIZE, NSGetProviderInfo()->providerId);
277
278     pthread_mutex_unlock(&nsInitMutex);
279     NS_LOG(DEBUG, "NSCreateMessage - OUT");
280     return msg;
281 }
282
283 NSTopicLL * NSProviderGetConsumerTopics(const char * consumerId)
284 {
285     NS_LOG(DEBUG, "NSProviderGetConsumerTopics - IN");
286     pthread_mutex_lock(&nsInitMutex);
287
288     if(!initProvider || !consumerId || consumerId[0] == '\0')
289     {
290         NS_LOG(DEBUG, "Provider is not started or consumer id should be set");
291         pthread_mutex_unlock(&nsInitMutex);
292         return NULL;
293     }
294
295     NSTopicSync topicSync;
296     topicSync.consumerId = OICStrdup(consumerId);
297     topicSync.topics = NULL;
298     topicSync.condition = &nstopicCond;
299     topicSync.mutex = &nsInitMutex;
300
301     NSPushQueue(TOPIC_SCHEDULER, TAST_GET_CONSUMER_TOPICS, &topicSync);
302     pthread_cond_wait(topicSync.condition, &nsInitMutex);
303     OICFree(topicSync.consumerId);
304
305     pthread_mutex_unlock(&nsInitMutex);
306     NS_LOG(DEBUG, "NSProviderGetConsumerTopics - OUT");
307     return topicSync.topics;
308 }
309
310 NSTopicLL * NSProviderGetTopics()
311 {
312     NS_LOG(DEBUG, "NSProviderGetTopics - IN");
313     pthread_mutex_lock(&nsInitMutex);
314
315     if (!initProvider)
316     {
317         NS_LOG(ERROR, "Provider is not started");
318         pthread_mutex_unlock(&nsInitMutex);
319         return NULL;
320     }
321
322     NSTopicSync topicSync;
323     topicSync.consumerId = NULL;
324     topicSync.topics = NULL;
325     topicSync.condition = &nstopicCond;
326     topicSync.mutex = &nsInitMutex;
327
328     NSPushQueue(TOPIC_SCHEDULER, TASK_GET_TOPICS, &topicSync);
329     pthread_cond_wait(topicSync.condition, &nsInitMutex);
330
331     pthread_mutex_unlock(&nsInitMutex);
332     NS_LOG(DEBUG, "NSProviderGetTopics - OUT");
333     return topicSync.topics;
334 }
335
336 NSResult NSProviderRegisterTopic(const char * topicName)
337 {
338     NS_LOG(DEBUG, "NSProviderAddTopics - IN");
339     pthread_mutex_lock(&nsInitMutex);
340
341     if(!initProvider || !topicName || topicName[0] == '\0')
342     {
343         pthread_mutex_unlock(&nsInitMutex);
344         NS_LOG(DEBUG, "Provider is not started or topic Name should be set");
345         return NS_FAIL;
346     }
347
348     NSTopicSyncResult topicSyncResult;
349     topicSyncResult.topicData = (void *) OICStrdup(topicName);
350     topicSyncResult.condition = &nstopicCond;
351     topicSyncResult.result = NS_OK;
352     topicSyncResult.mutex = &nsInitMutex;
353
354     NSPushQueue(TOPIC_SCHEDULER, TASK_REGISTER_TOPIC, &topicSyncResult);
355     pthread_cond_wait(topicSyncResult.condition, &nsInitMutex);
356     if(topicSyncResult.result != NS_OK)
357     {
358         pthread_mutex_unlock(&nsInitMutex);
359         return NS_FAIL;
360     }
361
362     pthread_mutex_unlock(&nsInitMutex);
363     NS_LOG(DEBUG, "NSProviderAddTopics - OUT");
364     return NS_OK;
365 }
366
367 NSResult NSProviderUnregisterTopic(const char * topicName)
368 {
369     NS_LOG(DEBUG, "NSProviderDeleteTopics - IN");
370     pthread_mutex_lock(&nsInitMutex);
371
372     if(!initProvider || !topicName || topicName[0] == '\0')
373     {
374         pthread_mutex_unlock(&nsInitMutex);
375         NS_LOG(DEBUG, "Provider is not started or topic Name should be set");
376         return NS_FAIL;
377     }
378
379     NSTopicSyncResult topicSyncResult;
380     topicSyncResult.topicData = (void *) OICStrdup(topicName);
381     topicSyncResult.condition = &nstopicCond;
382     topicSyncResult.result = NS_OK;
383     topicSyncResult.mutex = &nsInitMutex;
384
385     NSPushQueue(TOPIC_SCHEDULER, TASK_UNREGISTER_TOPIC, &topicSyncResult);
386     pthread_cond_wait(topicSyncResult.condition, &nsInitMutex);
387     if(topicSyncResult.result != NS_OK)
388     {
389         pthread_mutex_unlock(&nsInitMutex);
390         return NS_FAIL;
391     }
392     OICFree(topicSyncResult.topicData);
393
394     pthread_mutex_unlock(&nsInitMutex);
395     NS_LOG(DEBUG, "NSProviderDeleteTopics - OUT");
396     return NS_OK;
397 }
398
399 NSResult NSProviderSetConsumerTopic(const char * consumerId, const char * topicName)
400 {
401     NS_LOG(DEBUG, "NSProviderSelectTopics - IN");
402     pthread_mutex_lock(&nsInitMutex);
403
404     NSCacheTopicSubData * topicSubData =
405             (NSCacheTopicSubData *) OICMalloc(sizeof(NSCacheTopicSubData));
406
407     if(!initProvider || !consumerId || consumerId[0] == '\0' || !topicName || topicName[0] == '\0'
408             || !NSGetPolicy() || !topicSubData)
409     {
410         NS_LOG(DEBUG, "provider is not started or "
411                 "consumer id should be set for topic subscription or "
412                 "Configuration must set to true.");
413         pthread_mutex_unlock(&nsInitMutex);
414         return NS_FAIL;
415     }
416
417     OICStrcpy(topicSubData->id, NS_UUID_STRING_SIZE, consumerId);
418     topicSubData->topicName = OICStrdup(topicName);
419
420     NSTopicSyncResult topicSyncResult;
421     topicSyncResult.topicData = (void *) topicSubData;
422     topicSyncResult.condition = &nstopicCond;
423     topicSyncResult.result = NS_FAIL;
424     topicSyncResult.mutex = &nsInitMutex;
425
426     NSPushQueue(TOPIC_SCHEDULER, TASK_SUBSCRIBE_TOPIC, (void *)&topicSyncResult);
427     pthread_cond_wait(topicSyncResult.condition, &nsInitMutex);
428
429     pthread_mutex_unlock(&nsInitMutex);
430     NS_LOG(DEBUG, "NSProviderSelectTopics - OUT");
431     return topicSyncResult.result;
432 }
433
434 NSResult NSProviderUnsetConsumerTopic(const char * consumerId, const char * topicName)
435 {
436     NS_LOG(DEBUG, "NSProviderUnselectTopics - IN");
437     pthread_mutex_lock(&nsInitMutex);
438
439     NSCacheTopicSubData * topicSubData =
440             (NSCacheTopicSubData *) OICMalloc(sizeof(NSCacheTopicSubData));
441
442     if(!initProvider || !consumerId || consumerId[0] == '\0' || !topicName || topicName[0] == '\0'
443             || !NSGetPolicy() || !topicSubData)
444     {
445         NS_LOG(DEBUG, "provider is not started or "
446                 "consumer id should be set for topic subscription or "
447                 "Configuration must set to true.");
448         pthread_mutex_unlock(&nsInitMutex);
449         return NS_FAIL;
450     }
451
452     OICStrcpy(topicSubData->id, NS_UUID_STRING_SIZE, consumerId);
453     topicSubData->topicName = OICStrdup(topicName);
454
455     NSTopicSyncResult topicSyncResult;
456     topicSyncResult.topicData = (void *) topicSubData;
457     topicSyncResult.condition = &nstopicCond;
458     topicSyncResult.result = NS_FAIL;
459     topicSyncResult.mutex = &nsInitMutex;
460
461     NSPushQueue(TOPIC_SCHEDULER, TASK_UNSUBSCRIBE_TOPIC, (void *)&topicSyncResult);
462     pthread_cond_wait(topicSyncResult.condition, &nsInitMutex);
463
464     pthread_mutex_unlock(&nsInitMutex);
465     NS_LOG(DEBUG, "NSProviderUnselectTopics - OUT");
466     return topicSyncResult.result;
467 }