Add consumer logic for provider was stopped.
[platform/upstream/iotivity.git] / service / notification / src / consumer / NSConsumerMemoryCache.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 "NSConsumerMemoryCache.h"
22 #include "oic_malloc.h"
23 #include "oic_string.h"
24
25 pthread_mutex_t * NSGetCacheMutex()
26 {
27     static pthread_mutex_t * g_NSCacheMutex = NULL;
28     if (g_NSCacheMutex == NULL)
29     {
30         g_NSCacheMutex = (pthread_mutex_t *) OICMalloc(sizeof(pthread_mutex_t));
31         NS_VERIFY_NOT_NULL(g_NSCacheMutex, NULL);
32
33         pthread_mutex_init(g_NSCacheMutex, NULL);
34     }
35     return g_NSCacheMutex;
36 }
37
38 NSCacheList * NSStorageCreate()
39 {
40     pthread_mutex_t * mutex = NSGetCacheMutex();
41     pthread_mutex_lock(mutex);
42
43     NSCacheList * newList = (NSCacheList *) OICMalloc(sizeof(NSCacheList));
44     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newList, NULL, pthread_mutex_unlock(mutex));
45
46     newList->head = NULL;
47     newList->tail = NULL;
48
49     pthread_mutex_unlock(mutex);
50
51     return newList;
52 }
53
54 NSCacheElement * NSStorageRead(NSCacheList * list, const char * findId)
55 {
56     NS_VERIFY_NOT_NULL(list, NULL);
57     NS_VERIFY_NOT_NULL(findId, NULL);
58
59     pthread_mutex_t * mutex = NSGetCacheMutex();
60     pthread_mutex_lock(mutex);
61
62     NSCacheElement * iter = list->head;
63     NSCacheType type = list->cacheType;
64
65     while (iter)
66     {
67         if (NSConsumerCompareIdCacheData(type, iter->data, findId))
68         {
69             pthread_mutex_unlock(mutex);
70             return iter;
71         }
72
73         iter = iter->next;
74     }
75
76     NS_LOG (DEBUG, "No Cache Element");
77     pthread_mutex_unlock(mutex);
78     return NULL;
79 }
80
81 NSCacheElement * NSGetProviderFromAddr(NSCacheList * list, const char * addr, uint16_t port)
82 {
83     NS_VERIFY_NOT_NULL(list, NULL);
84     NS_VERIFY_NOT_NULL(addr, NULL);
85     NS_VERIFY_NOT_NULL(
86             (list->cacheType != NS_CONSUMER_CACHE_PROVIDER) ? NULL : (void *) 1, NULL);
87
88     pthread_mutex_t * mutex = NSGetCacheMutex();
89     pthread_mutex_lock(mutex);
90
91     NSCacheElement * iter = list->head;
92
93     while (iter)
94     {
95         NSProviderConnectionInfo * connection =
96                 ((NSProviderConnectionInfo *) iter->data)->next;
97         while (connection)
98         {
99             char * conAddr = connection->addr->addr;
100             uint16_t conPort = connection->addr->port;
101
102             if (!strcmp(conAddr, addr) && conPort == port)
103             {
104                 pthread_mutex_unlock(mutex);
105                 return iter;
106             }
107             connection = connection->next;
108         }
109
110         iter = iter->next;
111     }
112
113     NS_LOG (DEBUG, "No Cache Element");
114     pthread_mutex_unlock(mutex);
115     return NULL;
116 }
117
118 NSResult NSStorageWrite(NSCacheList * list, NSCacheElement * newObj)
119 {
120     NS_VERIFY_NOT_NULL(list, NS_ERROR);
121     NS_VERIFY_NOT_NULL(newObj, NS_ERROR);
122
123     NSCacheType type = list->cacheType;
124     NS_LOG_V(DEBUG, "cache type : %d", type);
125
126     if (type == NS_CONSUMER_CACHE_MESSAGE)
127     {
128         return NSConsumerCacheWriteMessage(list, newObj);
129     }
130     else if (type == NS_CONSUMER_CACHE_PROVIDER)
131     {
132         return NSConsumerCacheWriteProvider(list, newObj);
133     }
134
135     NS_LOG (ERROR, "Not Supported Type");
136
137     return NS_ERROR;
138 }
139
140 NSResult NSStorageDelete(NSCacheList * list, const char * delId)
141 {
142     NS_VERIFY_NOT_NULL(list, NS_ERROR);
143     NS_VERIFY_NOT_NULL(delId, NS_ERROR);
144
145     NSCacheType type = list->cacheType;
146
147     pthread_mutex_t * mutex = NSGetCacheMutex();
148     pthread_mutex_lock(mutex);
149
150     NSCacheElement * prev = list->head;
151     NSCacheElement * del = list->head;
152     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(del, NS_ERROR, pthread_mutex_unlock(mutex));
153
154     if (NSConsumerCompareIdCacheData(type, del->data, delId))
155     {
156         if (del == list->head)
157         {
158             if (del == list->tail)
159             {
160                 list->tail = del->next;
161             }
162
163             list->head = del->next;
164
165             if (type == NS_CONSUMER_CACHE_MESSAGE)
166             {
167                 NSRemoveMessage((NSMessage *) del->data);
168             }
169             else if (type == NS_CONSUMER_CACHE_PROVIDER)
170             {
171                 NSRemoveProvider_internal((NSProvider_internal *) del->data);
172             }
173             NSOICFree(del);
174             pthread_mutex_unlock(mutex);
175
176             return NS_OK;
177         }
178     }
179
180     del = del->next;
181     while (del)
182     {
183         if (NSConsumerCompareIdCacheData(type, del->data, delId))
184         {
185             if (del == list->tail)
186             {
187                 list->tail = prev;
188             }
189
190             prev->next = del->next;
191             if (type == NS_CONSUMER_CACHE_MESSAGE)
192             {
193                 NSRemoveMessage((NSMessage *) del->data);
194             }
195             else if (type == NS_CONSUMER_CACHE_PROVIDER)
196             {
197                 NSRemoveProvider_internal((NSProvider_internal *) del->data);
198             }
199             NSOICFree(del);
200             pthread_mutex_unlock(mutex);
201
202             return NS_OK;
203         }
204
205         prev = del;
206         del = del->next;
207     }
208     pthread_mutex_unlock(mutex);
209     return NS_OK;
210 }
211
212 void NSConsumerRemoveMessageStore(NSCacheElement * ele, NSStoreMessage * msg)
213 {
214     NSOICFree(ele);
215     NSOICFree(msg);
216 }
217
218 NSResult NSConsumerCacheWriteMessage(NSCacheList * list, NSCacheElement * newObj)
219 {
220     NS_VERIFY_NOT_NULL(list, NS_ERROR);
221     NS_VERIFY_NOT_NULL(newObj, NS_ERROR);
222
223     pthread_mutex_t * mutex = NSGetCacheMutex();
224
225     NSMessage * newMsgObj = ((NSStoreMessage *)newObj->data)->msg;
226
227     char msgId[NS_DEVICE_ID_LENGTH] = {0, };
228     snprintf(msgId, NS_DEVICE_ID_LENGTH, "%lld", (long long int)newMsgObj->messageId);
229     NSCacheElement * it = NSStorageRead(list, msgId);
230
231     if (it)
232     {
233         NS_LOG(DEBUG, "Update message status.");
234         pthread_mutex_lock(mutex);
235         NSStoreMessage * sMsgObj = (NSStoreMessage *) it->data;
236         if(sMsgObj->status == ((NSStoreMessage *)newObj->data)->status)
237         {
238             NS_LOG (DEBUG, "Already receive message");
239             pthread_mutex_unlock(mutex);
240             return NS_ERROR;
241         }
242
243         sMsgObj->status = ((NSStoreMessage *)newObj->data)->status;
244         pthread_mutex_unlock(mutex);
245         return NS_OK;
246     }
247
248     NS_LOG(DEBUG, "Add message at storage.");
249     NSStoreMessage * sMsgObj = (NSStoreMessage *) OICMalloc(sizeof(NSStoreMessage));
250     NS_VERIFY_NOT_NULL(sMsgObj, NS_ERROR);
251
252     NSCacheElement * obj = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement));
253     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(obj, NS_ERROR, NSOICFree(sMsgObj));
254
255     sMsgObj->status = NS_SYNC_UNREAD;
256     sMsgObj->msg = (void *) NSCopyMessage(newMsgObj);
257     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(sMsgObj->msg, NS_ERROR,
258           NSConsumerRemoveMessageStore(obj, sMsgObj));
259
260     obj->next = NULL;
261     obj->data = (NSCacheData *) sMsgObj;
262
263     pthread_mutex_lock(mutex);
264     if (!list->head)
265     {
266         list->head = obj;
267         list->tail = obj;
268         pthread_mutex_unlock(mutex);
269         return NS_OK;
270     }
271
272     (list->tail)->next = obj;
273     list->tail = obj;
274     pthread_mutex_unlock(mutex);
275
276     return NS_OK;
277 }
278
279 NSResult NSConsumerCacheWriteProvider(NSCacheList * list, NSCacheElement * newObj)
280 {
281     NS_VERIFY_NOT_NULL(list, NS_ERROR);
282     NS_VERIFY_NOT_NULL(newObj, NS_ERROR);
283
284     pthread_mutex_t * mutex = NSGetCacheMutex();
285
286     NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1");
287     NSProvider_internal * prov = (NSProvider_internal *)newObj->data;
288     NS_LOG_V (DEBUG, "%s", prov->providerId);
289     NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1");
290
291     NSProvider_internal * newProvObj = (NSProvider_internal *) newObj->data;
292
293     NSCacheElement * it = NSStorageRead(list, newProvObj->providerId);
294     pthread_mutex_lock(mutex);
295
296     if (it)
297     {
298         NSProvider_internal * provObj = (NSProvider_internal *) it->data;
299
300         NSProviderConnectionInfo * infos = provObj->connection;
301         NSProviderConnectionInfo * lastConn = infos->next;
302         while(lastConn)
303         {
304             infos = lastConn;
305             lastConn = lastConn->next;
306         }
307         infos->next = NSCopyProviderConnections(newProvObj->connection);
308
309         pthread_mutex_unlock(mutex);
310
311         return NS_OK;
312     }
313
314     NSCacheElement * obj = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement));
315     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(obj, NS_ERROR, pthread_mutex_unlock(mutex));
316
317     NS_LOG_V(DEBUG, "New Object address : %s:%d", newProvObj->connection->addr->addr, newProvObj->connection->addr->port);
318     obj->data = (void *) NSCopyProvider_internal(newProvObj);
319
320     NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2");
321     prov = (NSProvider_internal *)obj->data;
322     NS_LOG_V (DEBUG, "%s", prov->providerId);
323     NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2");
324
325     if (!obj->data)
326     {
327         NS_LOG (ERROR, "Failed to CopyProvider");
328         pthread_mutex_unlock(mutex);
329
330         return NS_ERROR;
331     }
332     obj->next = NULL;
333
334     if (!list->head)
335     {
336         list->head = obj;
337         list->tail = obj;
338
339         NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3");
340         prov = (NSProvider_internal *)list->tail->data;
341         NS_LOG_V (DEBUG, "%s", prov->providerId);
342         NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3");
343
344         pthread_mutex_unlock(mutex);
345
346         return NS_OK;
347     }
348
349     (list->tail)->next = obj;
350     list->tail = obj;
351
352     NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4");
353     prov = (NSProvider_internal *)list->tail->data;
354     NS_LOG_V (DEBUG, "%s", prov->providerId);
355     NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4");
356
357     pthread_mutex_unlock(mutex);
358
359     return NS_OK;
360 }
361
362 NSCacheElement * NSPopProviderCacheList(NSCacheList * list)
363 {
364     NS_VERIFY_NOT_NULL(list, NULL);
365
366     pthread_mutex_t * mutex = NSGetCacheMutex();
367     pthread_mutex_lock(mutex);
368
369     NSCacheElement * head = list->head;
370     if (head)
371     {
372         if (list->tail == head)
373         {
374             list->tail = NULL;
375         }
376
377         list->head = head->next;
378         head->next = NULL;
379     }
380
381     pthread_mutex_unlock(mutex);
382     return head;
383 }
384
385
386 NSResult NSStorageDestroy(NSCacheList * list)
387 {
388     NS_VERIFY_NOT_NULL(list, NS_ERROR);
389
390     pthread_mutex_t * mutex = NSGetCacheMutex();
391     pthread_mutex_lock(mutex);
392
393     NSCacheElement * iter = list->head;
394     NSCacheElement * next = NULL;
395
396     NSCacheType type = list->cacheType;
397
398     if (type == NS_CONSUMER_CACHE_MESSAGE)
399     {
400         while (iter)
401         {
402             next = (NSCacheElement *) iter->next;
403
404             NSRemoveMessage(((NSStoreMessage *) iter->data)->msg);
405             NSOICFree(iter->data);
406             NSOICFree(iter);
407
408             iter = next;
409         }
410
411         NSOICFree(list);
412     }
413     else if (type == NS_CONSUMER_CACHE_PROVIDER)
414     {
415         while (iter)
416         {
417             next = (NSCacheElement *) iter->next;
418
419             NSRemoveProvider_internal((NSProvider_internal *) iter->data);
420             NSOICFree(iter);
421
422             iter = next;
423         }
424
425         NSOICFree(list);
426     }
427
428     pthread_mutex_unlock(mutex);
429
430     return NS_OK;
431 }
432
433 bool NSConsumerCompareIdCacheData(NSCacheType type, void * data, const char * id)
434 {
435     NS_VERIFY_NOT_NULL(data, false);
436     NS_VERIFY_NOT_NULL(id, false);
437
438     if (type == NS_CONSUMER_CACHE_MESSAGE)
439     {
440         NSMessage * msg = ((NSStoreMessage *) data)->msg;
441
442         char msgId[NS_DEVICE_ID_LENGTH] = {0, };
443         snprintf(msgId, NS_DEVICE_ID_LENGTH, "%lld", (long long int)msg->messageId);
444         if (!strcmp(msgId, id))
445         {
446             return true;
447         }
448
449         return false;
450     }
451     else if (type == NS_CONSUMER_CACHE_PROVIDER)
452     {
453         NSProvider_internal * prov = (NSProvider_internal *) data;
454         if (!strcmp(prov->providerId, id))
455         {
456             return true;
457         }
458
459         return false;
460     }
461
462     return false;
463 }