Modify to call of provider state callback.
[platform/upstream/iotivity.git] / service / notification / src / consumer / NSConsumerInternalTaskController.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 "NSConstants.h"
22 #include "NSConsumerCommon.h"
23 #include "NSConsumerInternalTaskController.h"
24 #include "NSStructs.h"
25
26 #include "oic_malloc.h"
27 #include "oic_string.h"
28
29 NSCacheList ** NSGetMessageCacheList()
30 {
31     static NSCacheList * messageCache = NULL;
32     return & messageCache;
33 }
34
35 void NSSetMessageCacheList(NSCacheList * cache)
36 {
37     *(NSGetMessageCacheList()) = cache;
38 }
39
40 NSCacheList ** NSGetProviderCacheList()
41 {
42     static NSCacheList * providerCache = NULL;
43     return & providerCache;
44 }
45
46 void NSSetProviderCacheList(NSCacheList * cache)
47 {
48     *(NSGetProviderCacheList()) = cache;
49 }
50
51 void NSDestroyMessageCacheList()
52 {
53     NSCacheList * cache = *(NSGetMessageCacheList());
54     if (cache)
55     {
56         NSStorageDestroy(cache);
57     }
58
59     NSSetMessageCacheList(NULL);
60 }
61
62 void NSDestroyProviderCacheList()
63 {
64     NSCacheList * cache = *(NSGetProviderCacheList());
65     if (cache)
66     {
67         NSStorageDestroy(cache);
68     }
69
70     NSSetProviderCacheList(NULL);
71 }
72
73 NSMessage * NSMessageCacheFind(const char * messageId)
74 {
75     NS_VERIFY_NOT_NULL(messageId, NULL);
76
77     NSCacheList * MessageCache = *(NSGetMessageCacheList());
78     if (!MessageCache)
79     {
80         NS_LOG(DEBUG, "Message Cache Init");
81         MessageCache = NSStorageCreate();
82         NS_VERIFY_NOT_NULL(MessageCache, NULL);
83
84         MessageCache->cacheType = NS_CONSUMER_CACHE_MESSAGE;
85         NSSetMessageCacheList(MessageCache);
86     }
87
88     NSCacheElement * cacheElement = NSStorageRead(MessageCache, messageId);
89     NS_VERIFY_NOT_NULL(cacheElement, NULL);
90
91     return NSCopyMessage(((NSStoreMessage *) cacheElement->data)->msg);
92 }
93
94 NSProvider_internal * NSProviderCacheFind(const char * providerId)
95 {
96     NS_VERIFY_NOT_NULL(providerId, NULL);
97
98     NSCacheList * ProviderCache = *(NSGetProviderCacheList());
99     if (!ProviderCache)
100     {
101         NS_LOG(DEBUG, "Provider Cache Init");
102         ProviderCache = NSStorageCreate();
103         NS_VERIFY_NOT_NULL(ProviderCache, NULL);
104
105         ProviderCache->cacheType = NS_CONSUMER_CACHE_PROVIDER;
106         NSSetProviderCacheList(ProviderCache);
107     }
108
109     NSCacheElement * cacheElement = NSStorageRead(ProviderCache, providerId);
110     NS_VERIFY_NOT_NULL(cacheElement, NULL);
111
112     return NSCopyProvider_internal((NSProvider_internal *) cacheElement->data);
113 }
114
115 NSProvider_internal * NSFindProviderFromAddr(OCDevAddr * addr)
116 {
117     NS_VERIFY_NOT_NULL(addr, NULL);
118
119     NSCacheList * ProviderCache = *(NSGetProviderCacheList());
120     if (!ProviderCache)
121     {
122         NS_LOG(DEBUG, "Provider Cache does not intialized.");
123         return NULL;
124     }
125
126     NSCacheElement * cacheElement =
127             NSGetProviderFromAddr(ProviderCache, addr->addr, addr->port);
128
129     NS_VERIFY_NOT_NULL(cacheElement, NULL);
130
131     return NSCopyProvider_internal((NSProvider_internal *) cacheElement->data);
132 }
133
134 void NSRemoveCacheElementMessage(NSCacheElement * obj)
135 {
136     NSRemoveMessage(((NSStoreMessage *)obj->data)->msg);
137     NSOICFree(obj->data);
138     NSOICFree(obj);
139 }
140
141 NSResult NSMessageCacheUpdate(NSMessage * msg, NSSyncType type)
142 {
143     NS_VERIFY_NOT_NULL(msg, NS_ERROR);
144
145     NSCacheList * MessageCache = *(NSGetMessageCacheList());
146     if (!MessageCache)
147     {
148         NS_LOG(DEBUG, "Message Cache Init");
149         MessageCache = NSStorageCreate();
150         NS_VERIFY_NOT_NULL(MessageCache, NS_ERROR);
151
152         MessageCache->cacheType = NS_CONSUMER_CACHE_MESSAGE;
153         NSSetMessageCacheList(MessageCache);
154     }
155
156     NSStoreMessage * sMsg = (NSStoreMessage *)OICMalloc(sizeof(NSStoreMessage));
157     NS_VERIFY_NOT_NULL(sMsg, NS_ERROR);
158
159     NSCacheElement * obj = (NSCacheElement *)OICMalloc(sizeof(NSCacheElement));
160     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(obj, NS_ERROR, NSOICFree(sMsg));
161
162     sMsg->status = type;
163     sMsg->msg = NSCopyMessage(msg);
164
165     obj->data = (NSCacheData *) sMsg;
166     obj->next = NULL;
167
168     NS_LOG(DEBUG, "try to write to storage");
169     NSResult ret = NSStorageWrite(MessageCache, obj);
170     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(ret == NS_OK ? (void *) 1 : NULL,
171             NS_ERROR, NSRemoveCacheElementMessage(obj));
172
173     NSRemoveCacheElementMessage(obj);
174
175     NS_LOG(DEBUG, "Update message done");
176     return NS_OK;
177 }
178
179 NSResult NSProviderCacheUpdate(NSProvider_internal * provider)
180 {
181     NSCacheList * ProviderCache = *(NSGetProviderCacheList());
182     if (!ProviderCache)
183     {
184         NS_LOG(DEBUG, "Provider Cache Init");
185         ProviderCache = NSStorageCreate();
186         NS_VERIFY_NOT_NULL(ProviderCache, NS_ERROR);
187
188         ProviderCache->cacheType = NS_CONSUMER_CACHE_PROVIDER;
189         NSSetProviderCacheList(ProviderCache);
190     }
191
192     NS_VERIFY_NOT_NULL(provider, NS_ERROR);
193
194     NSCacheElement * obj = (NSCacheElement *)OICMalloc(sizeof(NSCacheElement));
195     NS_VERIFY_NOT_NULL(obj, NS_ERROR);
196
197     obj->data = (NSCacheData *) provider;
198     obj->next = NULL;
199
200     NS_LOG(DEBUG, "try to write to storage");
201     NSResult ret = NSStorageWrite(ProviderCache, obj);
202     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(ret == NS_OK ? (void *) 1 : NULL,
203             NS_ERROR, NSOICFree(obj));
204
205     return NS_OK;
206 }
207
208 void NSCancelAllSubscription()
209 {
210     NSCacheList * ProviderCache = *(NSGetProviderCacheList());
211     if (!ProviderCache)
212     {
213         NS_LOG(DEBUG, "Provider Cache Init");
214         ProviderCache = NSStorageCreate();
215         NS_VERIFY_NOT_NULL_V(ProviderCache);
216
217         ProviderCache->cacheType = NS_CONSUMER_CACHE_PROVIDER;
218         NSSetProviderCacheList(ProviderCache);
219     }
220
221     NSCacheElement * obj = NULL;
222     while ((obj = NSPopProviderCacheList(ProviderCache)))
223     {
224         NS_LOG(DEBUG, "build NSTask");
225         NSProvider * prov = NSCopyProvider((NSProvider_internal *) obj->data);
226         NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(prov,
227                     NSRemoveProvider_internal((NSProvider_internal *) obj->data));
228
229         NSTask * task = NSMakeTask(TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL, prov);
230         NS_VERIFY_NOT_NULL_V(task);
231
232         NSConsumerPushEvent(task);
233     }
234 }
235
236 void NSConsumerHandleProviderDiscovered(NSProvider_internal * provider)
237 {
238     NS_VERIFY_NOT_NULL_V(provider);
239
240     bool isAdded = true;
241     bool isSubscribing = false;
242
243     NSProvider_internal * providerCacheDataFromAddr
244         = NSFindProviderFromAddr(provider->connection->addr);
245     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(
246         (providerCacheDataFromAddr == NULL) ? (void *)1 : NULL,
247         NSRemoveProvider_internal(providerCacheDataFromAddr));
248
249     NSProvider_internal * providerCacheData = NSProviderCacheFind(provider->providerId);
250
251     if (providerCacheData == NULL)
252     {
253         isAdded = false;
254     }
255     else
256     {
257         providerCacheData->accessPolicy = provider->accessPolicy;
258         NSProviderConnectionInfo * infos = providerCacheData->connection;
259         OCTransportAdapter newAdapter = provider->connection->addr->adapter;
260         while (infos)
261         {
262             isSubscribing |= infos->isSubscribing;
263             if (infos->addr->adapter == newAdapter && infos->isSubscribing == true)
264             {
265                 NS_LOG_V(DEBUG, "This provider already discovered : %s:%d",
266                          infos->addr->addr, infos->addr->port);
267                 NS_LOG_V(DEBUG, "Subscription : %d", infos->isSubscribing);
268                 return;
269             }
270             infos = infos->next;
271         }
272     }
273
274     NSResult ret = NSProviderCacheUpdate(provider);
275     NS_VERIFY_NOT_NULL_V(ret == NS_OK ? (void *) 1 : NULL);
276
277     if (isAdded == false)
278     {
279         NS_LOG(DEBUG, "New provider is discovered");
280     }
281     else
282     {
283         provider = providerCacheData;
284         NS_LOG(DEBUG, "provider's connection is updated.");
285     }
286
287     if (provider->accessPolicy == NS_SELECTION_CONSUMER && isSubscribing == false)
288     {
289         NS_LOG(DEBUG, "accepter is NS_ACCEPTER_CONSUMER, Callback to user");
290         NSProvider * providerForCb = NSCopyProvider(provider);
291         NSProviderChanged(providerForCb, NS_DISCOVERED);
292     }
293     else
294     {
295         NS_LOG(DEBUG, "accepter is NS_ACCEPTER_PROVIDER, request subscribe");
296         NSProvider_internal * subProvider = NSCopyProvider_internal(provider);
297         NSTask * task = NSMakeTask(TASK_CONSUMER_REQ_SUBSCRIBE, (void *) subProvider);
298         NS_VERIFY_NOT_NULL_V(task);
299
300         NSConsumerPushEvent(task);
301     }
302
303     NSRemoveProvider_internal(providerCacheData);
304 }
305
306 void NSConsumerHandleProviderDeleted(NSProvider_internal * provider)
307 {
308     NS_VERIFY_NOT_NULL_V(provider);
309
310     NSCacheList * providerCache = *(NSGetProviderCacheList());
311     NS_VERIFY_NOT_NULL_V(providerCache);
312
313     NSResult ret = NSStorageDelete(providerCache, provider->providerId);
314     NS_VERIFY_NOT_NULL_V(ret == NS_OK ? (void *)1 : NULL);
315
316     NS_LOG_V(DEBUG, "Stopped Provider : %s", provider->providerId);
317     NSProvider * providerForCb = NSCopyProvider(provider);
318     NSProviderChanged(providerForCb, NS_STOPPED);
319 }
320
321 void NSConsumerHandleSubscribeSucceed(NSProvider_internal * provider)
322 {
323     NS_VERIFY_NOT_NULL_V(provider);
324
325     NSCacheList * ProviderCache = *(NSGetProviderCacheList());
326
327     NSCacheElement * cacheElement = NSStorageRead(ProviderCache, provider->providerId);
328     NS_VERIFY_NOT_NULL_V(cacheElement);
329
330     pthread_mutex_t * mutex = NSGetCacheMutex();
331     pthread_mutex_lock(mutex);
332
333     NS_VERIFY_NOT_NULL_V(cacheElement);
334     NSProvider_internal * prov = (NSProvider_internal *)cacheElement->data;
335     NSProviderConnectionInfo *infos = prov->connection;
336     while(infos)
337     {
338         infos->isSubscribing = true;
339         infos = infos->next;
340     }
341
342     pthread_mutex_unlock(mutex);
343 }
344
345 void NSConsumerHandleRecvProviderChanged(NSMessage * msg)
346 {
347     NS_VERIFY_NOT_NULL_V(msg);
348
349     NS_LOG_V(DEBUG, "confirmed by : %s", msg->providerId);
350
351     NSCacheList * ProviderCache = *(NSGetProviderCacheList());
352
353     NSCacheElement * cacheElement = NSStorageRead(ProviderCache, msg->providerId);
354     NS_VERIFY_NOT_NULL_V(cacheElement);
355
356     pthread_mutex_t * mutex = NSGetCacheMutex();
357     pthread_mutex_lock(mutex);
358     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(cacheElement, pthread_mutex_unlock(mutex));
359     NSProvider_internal * provider = (NSProvider_internal *) cacheElement->data;
360     if (provider->state == (NSProviderState) msg->messageId)
361     {
362         NS_LOG_V(DEBUG, "Already receive message(ALLOW/DENY) : %d", (int) msg->messageId);
363         pthread_mutex_unlock(mutex);
364         return;
365     }
366
367     NS_LOG_V(DEBUG, "Provider State Changed %d -> %d",
368              (int) provider->state, (int) msg->messageId);
369     NS_LOG(DEBUG, "call back to user");
370     provider->state = (NSProviderState) msg->messageId;
371
372     NSProvider * prov = NSCopyProvider(provider);
373
374     pthread_mutex_unlock(mutex);
375     NSProviderChanged(prov, (NSProviderState) msg->messageId);
376 }
377
378 void NSConsumerHandleRecvMessage(NSMessage * msg)
379 {
380     NS_VERIFY_NOT_NULL_V(msg);
381
382     NSResult ret = NSMessageCacheUpdate(msg, NS_SYNC_UNREAD);
383     NS_VERIFY_NOT_NULL_V(ret == NS_OK ? (void *) 1 : NULL);
384
385     NSMessagePost((NSMessage *) msg);
386 }
387
388 void NSConsumerHandleRecvSyncInfo(NSSyncInfo * sync)
389 {
390     NS_VERIFY_NOT_NULL_V(sync);
391
392     char msgId[NS_DEVICE_ID_LENGTH] = { 0, };
393     snprintf(msgId, NS_DEVICE_ID_LENGTH, "%lld", (long long int)sync->messageId);
394
395     NSMessage * msg = NSMessageCacheFind(msgId);
396     NS_VERIFY_NOT_NULL_V(msg);
397
398     NSResult ret = NSMessageCacheUpdate(msg, sync->state);
399     NS_VERIFY_NOT_NULL_V(ret == NS_OK ? (void *) 1 : NULL);
400     NSRemoveMessage(msg);
401
402     NSNotificationSync(sync);
403 }
404
405 void NSConsumerHandleMakeSyncInfo(NSSyncInfo * sync)
406 {
407     NS_VERIFY_NOT_NULL_V(sync);
408
409     NSProvider_internal * provider = NSProviderCacheFind(sync->providerId);
410     NS_VERIFY_NOT_NULL_V (provider);
411
412     NSProviderConnectionInfo * connections = NSCopyProviderConnections(provider->connection);
413     NS_VERIFY_NOT_NULL_V (connections);
414
415     NSSyncInfo_internal * syncInfo = (NSSyncInfo_internal *)OICMalloc(sizeof(NSSyncInfo_internal));
416     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(syncInfo, NSRemoveConnections(connections));
417
418     OICStrcpy(syncInfo->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, sync->providerId);
419     syncInfo->messageId = sync->messageId;
420     syncInfo->state = sync->state;
421     syncInfo->connection = connections;
422
423     NSTask * syncTask = NSMakeTask(TASK_SEND_SYNCINFO, (void *) syncInfo);
424     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(syncTask, NSOICFree(syncInfo));
425
426     NSConsumerPushEvent(syncTask);
427 }
428
429 void NSConsumerHandleGetTopicUri(NSMessage * msg)
430 {
431     NS_VERIFY_NOT_NULL_V(msg);
432
433     NSProvider_internal * provider = NSProviderCacheFind(msg->providerId);
434     NS_VERIFY_NOT_NULL_V(provider);
435
436     NSTask * topicTask = NSMakeTask(TASK_CONSUMER_REQ_TOPIC_LIST, (void *) provider);
437     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(topicTask, NSRemoveProvider_internal(provider));
438
439     NSConsumerPushEvent(topicTask);
440 }
441
442 void NSConsumerHandleRecvTopicLL(NSProvider_internal * provider)
443 {
444     NS_VERIFY_NOT_NULL_V(provider);
445
446     NSRemoveConnections(provider->connection);
447     provider->connection = NULL;
448
449     NSResult ret = NSProviderCacheUpdate(provider);
450     NS_VERIFY_NOT_NULL_V(ret == NS_OK ? (void *) 1 : NULL);
451
452     NS_LOG(DEBUG, "call back to user");
453     NSProvider * prov = NSCopyProvider(provider);
454     NSProviderChanged((NSProvider *) prov, (NSProviderState) NS_TOPIC);
455 }
456
457 void NSConsumerInternalTaskProcessing(NSTask * task)
458 {
459     NS_VERIFY_NOT_NULL_V(task);
460
461     NS_LOG_V(DEBUG, "Receive Event : %d", (int)task->taskType);
462     switch (task->taskType)
463     {
464         case TASK_CONSUMER_SENT_REQ_OBSERVE:
465         {
466             NS_LOG(DEBUG, "Receive Subscribe succeed from provider.");
467             NSConsumerHandleSubscribeSucceed((NSProvider_internal *)task->taskData);
468             NSRemoveProvider_internal((NSProvider_internal *)task->taskData);
469             break;
470         }
471         case TASK_CONSUMER_RECV_PROVIDER_CHANGED:
472         {
473             NS_LOG(DEBUG, "Receive Provider Changed");
474             NSConsumerHandleRecvProviderChanged((NSMessage *)task->taskData);
475             NSRemoveMessage((NSMessage *)task->taskData);
476             break;
477         }
478         case TASK_CONSUMER_RECV_MESSAGE:
479         {
480             NS_LOG(DEBUG, "Receive New Notification");
481             NSConsumerHandleRecvMessage((NSMessage *)task->taskData);
482             NSRemoveMessage((NSMessage *)task->taskData);
483             break;
484         }
485         case TASK_CONSUMER_PROVIDER_DISCOVERED:
486         {
487             NS_LOG(DEBUG, "Receive New Provider is discovered.");
488             NSConsumerHandleProviderDiscovered((NSProvider_internal *)task->taskData);
489             NSRemoveProvider_internal((NSProvider_internal *)task->taskData);
490             break;
491         }
492         case TASK_RECV_SYNCINFO:
493         {
494             NS_LOG(DEBUG, "Receive SyncInfo.");
495             NSConsumerHandleRecvSyncInfo((NSSyncInfo *)task->taskData);
496             NSOICFree(task->taskData);
497             break;
498         }
499         case TASK_MAKE_SYNCINFO:
500         {
501             NS_LOG(DEBUG, "Make SyncInfo, get Provider's Addr");
502             NSConsumerHandleMakeSyncInfo((NSSyncInfo *)task->taskData);
503             NSOICFree(task->taskData);
504             break;
505         }
506         case TASK_CONSUMER_REQ_TOPIC_URI:
507         {
508             NS_LOG(DEBUG, "Request Topic Uri");
509             NSConsumerHandleGetTopicUri((NSMessage *)task->taskData);
510             NSRemoveMessage((NSMessage *)task->taskData);
511             break;
512         }
513         case TASK_CONSUMER_RECV_TOPIC_LIST:
514         {
515             NS_LOG(DEBUG, "Receive Topic List");
516             NSConsumerHandleRecvTopicLL((NSProvider_internal *)task->taskData);
517             NSRemoveProvider_internal((NSProvider_internal *)task->taskData);
518             break;
519         }
520         case TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL:
521         {
522             NS_LOG(DEBUG, "Make Subscribe cancel from provider.");
523             NSConsumerHandleProviderDeleted((NSProvider_internal *)task->taskData);
524             NSRemoveProvider_internal((NSProvider_internal *)task->taskData);
525             break;
526         }
527         default :
528         {
529             NS_LOG(ERROR, "Unknown TASK Type");
530             return ;
531         }
532     }
533     NSOICFree(task);
534 }