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