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