replace : iotivity -> iotivity-sec
[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
100         NSSetResourceSecurity(config.resourceSecurity);
101 #endif
102
103         NSInitialize();
104         NSInitScheduler();
105         NSStartScheduler();
106
107         NSPushQueue(DISCOVERY_SCHEDULER, TASK_START_PRESENCE, NULL);
108         NSPushQueue(DISCOVERY_SCHEDULER, TASK_REGISTER_RESOURCE, NULL);
109     }
110     else
111     {
112         NS_LOG(DEBUG, "Already started Notification Provider");
113     }
114     pthread_mutex_unlock(&nsInitMutex);
115
116     NS_LOG(DEBUG, "NSStartProvider - OUT");
117     return NS_OK;
118 }
119
120 NSResult NSStopProvider()
121 {
122     NS_LOG(DEBUG, "NSStopProvider - IN");
123     pthread_mutex_lock(&nsInitMutex);
124
125     if (initProvider)
126     {
127         CAUnregisterNetworkMonitorHandler((CAAdapterStateChangedCB)NSProviderAdapterStateListener,
128                 (CAConnectionStateChangedCB)NSProviderConnectionStateListener);
129         NSPushQueue(DISCOVERY_SCHEDULER, TASK_STOP_PRESENCE, NULL);
130         NSRegisterSubscribeRequestCb((NSSubscribeRequestCallback)NULL);
131         NSRegisterSyncCb((NSProviderSyncInfoCallback)NULL);
132         NSUnRegisterResource();
133         NSDeinitProviderInfo();
134         NSStopScheduler();
135         NSDeinitailize();
136
137         initProvider = false;
138     }
139
140     pthread_mutex_unlock(&nsInitMutex);
141     NS_LOG(DEBUG, "NSStopProvider - OUT");
142     return NS_OK;
143 }
144
145 NSResult NSProviderEnableRemoteService(char *serverAddress)
146 {
147 #if (defined WITH_CLOUD)
148     NS_LOG(DEBUG, "NSProviderEnableRemoteService - IN");
149     pthread_mutex_lock(&nsInitMutex);
150
151     if (!initProvider || !serverAddress)
152     {
153         NS_LOG(DEBUG, "Provider service has not been started yet");
154         pthread_mutex_unlock(&nsInitMutex);
155         return NS_FAIL;
156     }
157
158     NS_LOG_V(INFO_PRIVATE, "Remote server address: %s", serverAddress);
159     NS_LOG(DEBUG, "Request to publish resource");
160     NSPushQueue(DISCOVERY_SCHEDULER, TASK_PUBLISH_RESOURCE, serverAddress);
161
162     pthread_mutex_unlock(&nsInitMutex);
163     NS_LOG(DEBUG, "NSProviderEnableRemoteService - OUT");
164     return NS_OK;
165 #else
166     (void) serverAddress;
167 #endif
168     NS_LOG_V(INFO_PRIVATE, "Not logged in remote server: %s", serverAddress);
169     return NS_FAIL;
170 }
171
172 NSResult NSProviderDisableRemoteService(char *serverAddress)
173 {
174 #if (defined WITH_CLOUD)
175     NS_LOG(DEBUG, "NSProviderDisableRemoteService - IN");
176     pthread_mutex_lock(&nsInitMutex);
177
178     if (!initProvider || !serverAddress)
179     {
180         NS_LOG(DEBUG, "Provider service has not been started yet");
181         pthread_mutex_unlock(&nsInitMutex);
182         return NS_FAIL;
183     }
184
185     NS_LOG_V(INFO_PRIVATE, "Remote server address: %s", serverAddress);
186
187     NS_LOG(DEBUG, "Delete remote server info");
188     NSDeleteRemoteServerAddress(serverAddress);
189
190     pthread_mutex_unlock(&nsInitMutex);
191     NS_LOG(DEBUG, "NSProviderDisableRemoteService - OUT");
192     return NS_OK;
193 #else
194     (void) serverAddress;
195 #endif
196     NS_LOG_V(INFO_PRIVATE, "Not logged in remote server : %s", serverAddress);
197     return NS_FAIL;
198 }
199
200 #ifdef WITH_MQ
201 NSResult NSProviderSubscribeMQService(const char * serverAddress, const char * topicName)
202 {
203     NS_LOG(DEBUG, "NSProviderSubscribeMQService - IN");
204     pthread_mutex_lock(&nsInitMutex);
205
206     if (!initProvider || !serverAddress || !topicName)
207     {
208         NS_LOG(DEBUG, "Provider service has not been started yet or set the server "
209                 "address and topicName");
210         pthread_mutex_unlock(&nsInitMutex);
211         return NS_FAIL;
212     }
213
214     NSMQTopicAddress * topicAddr = (NSMQTopicAddress *)OICMalloc(sizeof(NSMQTopicAddress));
215
216     if (!topicAddr)
217     {
218         NS_LOG(DEBUG, "fail to memory allocate");
219         pthread_mutex_unlock(&nsInitMutex);
220         return NS_FAIL;
221     }
222
223     topicAddr->serverAddr = NSGetQueryAddress(serverAddress);
224     topicAddr->topicName = OICStrdup(topicName);
225
226     NS_LOG_V(DEBUG, "input Topic Name : %s", topicAddr->topicName);
227
228     NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_MQ_REQ_SUBSCRIBE, (void *) topicAddr);
229
230     pthread_mutex_unlock(&nsInitMutex);
231     NS_LOG(DEBUG, "NSProviderSubscribeMQService - OUT");
232     return NS_OK;
233 }
234 #endif
235
236 NSResult NSSendMessage(NSMessage * msg)
237 {
238     NS_LOG(DEBUG, "NSSendNotification - IN");
239
240     pthread_mutex_lock(&nsInitMutex);
241
242     if (!initProvider || msg == NULL)
243     {
244         NS_LOG(ERROR, "Msg is NULL");
245         pthread_mutex_unlock(&nsInitMutex);
246         return NS_FAIL;
247     }
248
249     NSMessage * newMsg = NSDuplicateMessage(msg);
250     NSPushQueue(NOTIFICATION_SCHEDULER, TASK_SEND_NOTIFICATION, newMsg);
251
252     pthread_mutex_unlock(&nsInitMutex);
253
254     NS_LOG(DEBUG, "NSSendNotification - OUT");
255     return NS_OK;
256 }
257
258 NSResult NSProviderSendSyncInfo(uint64_t messageId, NSSyncType type)
259 {
260     NS_LOG(DEBUG, "NSProviderReadCheck - IN");
261     pthread_mutex_lock(&nsInitMutex);
262
263     NSSyncInfo * syncInfo = (NSSyncInfo *)OICMalloc(sizeof(NSSyncInfo));
264
265     if (!initProvider || !syncInfo)
266     {
267         NS_LOG(ERROR, "Provider is not started");
268         NSOICFree(syncInfo);
269         pthread_mutex_unlock(&nsInitMutex);
270         return NS_FAIL;
271     }
272
273     OICStrcpy(syncInfo->providerId, UUID_STRING_SIZE, NSGetProviderInfo()->providerId);
274     syncInfo->messageId = messageId;
275     syncInfo->state = type;
276     NSPushQueue(NOTIFICATION_SCHEDULER, TASK_SEND_READ, syncInfo);
277
278     pthread_mutex_unlock(&nsInitMutex);
279     NS_LOG(DEBUG, "NSProviderReadCheck - OUT");
280     return NS_OK;
281 }
282
283 NSResult NSAcceptSubscription(const char * consumerId, bool accepted)
284 {
285     NS_LOG(DEBUG, "NSAccept - IN");
286     pthread_mutex_lock(&nsInitMutex);
287
288     if(!initProvider || !consumerId || consumerId[0] == '\0' || NSGetPolicy() == NS_POLICY_CONSUMER)
289     {
290         NS_LOG(ERROR, "Provider is not started or consumerId is NULL or NS Policy is Consumer");
291         pthread_mutex_unlock(&nsInitMutex);
292         return NS_FAIL;
293     }
294
295     char * newConsumerId = OICStrdup(consumerId);
296     if (accepted)
297     {
298         NS_LOG(DEBUG, "accepted is true - ALLOW");
299         NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_SEND_ALLOW, newConsumerId);
300     }
301     else
302     {
303         NS_LOG(DEBUG, "accepted is false - DENY");
304         NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_SEND_DENY, newConsumerId);
305     }
306
307     pthread_mutex_unlock(&nsInitMutex);
308     NS_LOG(DEBUG, "NSAccept - OUT");
309     return NS_OK;
310 }
311
312 NSMessage * NSCreateMessage()
313 {
314     NS_LOG(DEBUG, "NSCreateMessage - IN");
315     pthread_mutex_lock(&nsInitMutex);
316
317     NSMessage * msg = NSInitializeMessage();
318
319     OICStrcpy(msg->providerId, UUID_STRING_SIZE, NSGetProviderInfo()->providerId);
320
321     pthread_mutex_unlock(&nsInitMutex);
322     NS_LOG(DEBUG, "NSCreateMessage - OUT");
323     return msg;
324 }
325
326 NSTopicLL * NSProviderGetConsumerTopics(const char * consumerId)
327 {
328     NS_LOG(DEBUG, "NSProviderGetConsumerTopics - IN");
329     pthread_mutex_lock(&nsInitMutex);
330
331     if(!initProvider || !consumerId || consumerId[0] == '\0')
332     {
333         NS_LOG(DEBUG, "Provider is not started or consumer id should be set");
334         pthread_mutex_unlock(&nsInitMutex);
335         return NULL;
336     }
337
338     NSTopicSync topicSync;
339     topicSync.consumerId = OICStrdup(consumerId);
340     topicSync.topics = NULL;
341     topicSync.condition = &nstopicCond;
342     topicSync.mutex = &nsInitMutex;
343
344     NSPushQueue(TOPIC_SCHEDULER, TAST_GET_CONSUMER_TOPICS, &topicSync);
345     pthread_cond_wait(topicSync.condition, &nsInitMutex);
346     NSOICFree(topicSync.consumerId);
347
348     pthread_mutex_unlock(&nsInitMutex);
349     NS_LOG(DEBUG, "NSProviderGetConsumerTopics - OUT");
350     return topicSync.topics;
351 }
352
353 NSTopicLL * NSProviderGetTopics()
354 {
355     NS_LOG(DEBUG, "NSProviderGetTopics - IN");
356     pthread_mutex_lock(&nsInitMutex);
357
358     if (!initProvider)
359     {
360         NS_LOG(ERROR, "Provider is not started");
361         pthread_mutex_unlock(&nsInitMutex);
362         return NULL;
363     }
364
365     NSTopicSync topicSync;
366     topicSync.consumerId = NULL;
367     topicSync.topics = NULL;
368     topicSync.condition = &nstopicCond;
369     topicSync.mutex = &nsInitMutex;
370
371     NSPushQueue(TOPIC_SCHEDULER, TASK_GET_TOPICS, &topicSync);
372     pthread_cond_wait(topicSync.condition, &nsInitMutex);
373
374     pthread_mutex_unlock(&nsInitMutex);
375     NS_LOG(DEBUG, "NSProviderGetTopics - OUT");
376     return topicSync.topics;
377 }
378
379 NSResult NSProviderRegisterTopic(const char * topicName)
380 {
381     NS_LOG(DEBUG, "NSProviderAddTopics - IN");
382     pthread_mutex_lock(&nsInitMutex);
383
384     if(!initProvider || !topicName || topicName[0] == '\0')
385     {
386         pthread_mutex_unlock(&nsInitMutex);
387         NS_LOG(DEBUG, "Provider is not started or topic Name should be set");
388         return NS_FAIL;
389     }
390
391     NSTopicSyncResult topicSyncResult;
392     topicSyncResult.topicData = (void *) OICStrdup(topicName);
393     topicSyncResult.condition = &nstopicCond;
394     topicSyncResult.result = NS_OK;
395     topicSyncResult.mutex = &nsInitMutex;
396
397     NSPushQueue(TOPIC_SCHEDULER, TASK_REGISTER_TOPIC, &topicSyncResult);
398     pthread_cond_wait(topicSyncResult.condition, &nsInitMutex);
399     if(topicSyncResult.result != NS_OK)
400     {
401         pthread_mutex_unlock(&nsInitMutex);
402         return NS_FAIL;
403     }
404
405     pthread_mutex_unlock(&nsInitMutex);
406     NS_LOG(DEBUG, "NSProviderAddTopics - OUT");
407     return NS_OK;
408 }
409
410 NSResult NSProviderUnregisterTopic(const char * topicName)
411 {
412     NS_LOG(DEBUG, "NSProviderDeleteTopics - IN");
413     pthread_mutex_lock(&nsInitMutex);
414
415     if(!initProvider || !topicName || topicName[0] == '\0')
416     {
417         pthread_mutex_unlock(&nsInitMutex);
418         NS_LOG(DEBUG, "Provider is not started or topic Name should be set");
419         return NS_FAIL;
420     }
421
422     NSTopicSyncResult topicSyncResult;
423     topicSyncResult.topicData = (void *) OICStrdup(topicName);
424     topicSyncResult.condition = &nstopicCond;
425     topicSyncResult.result = NS_OK;
426     topicSyncResult.mutex = &nsInitMutex;
427
428     NSPushQueue(TOPIC_SCHEDULER, TASK_UNREGISTER_TOPIC, &topicSyncResult);
429     pthread_cond_wait(topicSyncResult.condition, &nsInitMutex);
430     if (topicSyncResult.result != NS_OK)
431     {
432         pthread_mutex_unlock(&nsInitMutex);
433         return NS_FAIL;
434     }
435     NSOICFree(topicSyncResult.topicData);
436
437     pthread_mutex_unlock(&nsInitMutex);
438     NS_LOG(DEBUG, "NSProviderDeleteTopics - OUT");
439     return NS_OK;
440 }
441
442 NSResult NSProviderSetConsumerTopic(const char * consumerId, const char * topicName)
443 {
444     NS_LOG(DEBUG, "NSProviderSelectTopics - IN");
445     pthread_mutex_lock(&nsInitMutex);
446
447     NSCacheTopicSubData * topicSubData =
448             (NSCacheTopicSubData *) OICMalloc(sizeof(NSCacheTopicSubData));
449
450     if (!initProvider || !consumerId || consumerId[0] == '\0' || !topicName || topicName[0] == '\0'
451             || !NSGetPolicy() || !topicSubData)
452     {
453         NS_LOG(DEBUG, "provider is not started or "
454                 "consumer id should be set for topic subscription or "
455                 "Configuration must set to true.");
456         NSOICFree(topicSubData);
457         topicSubData = NULL;
458         pthread_mutex_unlock(&nsInitMutex);
459         return NS_FAIL;
460     }
461
462     OICStrcpy(topicSubData->id, NS_UUID_STRING_SIZE, consumerId);
463     topicSubData->topicName = OICStrdup(topicName);
464
465     NSTopicSyncResult topicSyncResult;
466     topicSyncResult.topicData = (void *) topicSubData;
467     topicSyncResult.condition = &nstopicCond;
468     topicSyncResult.result = NS_FAIL;
469     topicSyncResult.mutex = &nsInitMutex;
470
471     NSPushQueue(TOPIC_SCHEDULER, TASK_SUBSCRIBE_TOPIC, (void *)&topicSyncResult);
472     pthread_cond_wait(topicSyncResult.condition, &nsInitMutex);
473
474     pthread_mutex_unlock(&nsInitMutex);
475     NS_LOG(DEBUG, "NSProviderSelectTopics - OUT");
476     return topicSyncResult.result;
477 }
478
479 NSResult NSProviderUnsetConsumerTopic(const char * consumerId, const char * topicName)
480 {
481     NS_LOG(DEBUG, "NSProviderUnselectTopics - IN");
482     pthread_mutex_lock(&nsInitMutex);
483
484     NSCacheTopicSubData * topicSubData =
485             (NSCacheTopicSubData *) OICMalloc(sizeof(NSCacheTopicSubData));
486
487     if (!initProvider || !consumerId || consumerId[0] == '\0' || !topicName || topicName[0] == '\0'
488             || !NSGetPolicy() || !topicSubData)
489     {
490         NS_LOG(DEBUG, "provider is not started or "
491                 "consumer id should be set for topic subscription or "
492                 "Configuration must set to true.");
493         NSOICFree(topicSubData);
494         topicSubData = NULL;
495         pthread_mutex_unlock(&nsInitMutex);
496         return NS_FAIL;
497     }
498
499     OICStrcpy(topicSubData->id, NS_UUID_STRING_SIZE, consumerId);
500     topicSubData->topicName = OICStrdup(topicName);
501
502     NSTopicSyncResult topicSyncResult;
503     topicSyncResult.topicData = (void *) topicSubData;
504     topicSyncResult.condition = &nstopicCond;
505     topicSyncResult.result = NS_FAIL;
506     topicSyncResult.mutex = &nsInitMutex;
507
508     NSPushQueue(TOPIC_SCHEDULER, TASK_UNSUBSCRIBE_TOPIC, (void *)&topicSyncResult);
509     pthread_cond_wait(topicSyncResult.condition, &nsInitMutex);
510
511     pthread_mutex_unlock(&nsInitMutex);
512     NS_LOG(DEBUG, "NSProviderUnselectTopics - OUT");
513     return topicSyncResult.result;
514 }