Remove potential defects detected in the static analyzer.
[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 * 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 NSResult NSStorageWrite(NSCacheList * list, NSCacheElement * newObj)
82 {
83     NS_VERIFY_NOT_NULL(list, NS_ERROR);
84     NS_VERIFY_NOT_NULL(newObj, NS_ERROR);
85
86     NSCacheType type = list->cacheType;
87     NS_LOG_V(DEBUG, "cache type : %d", type);
88
89     if (type == NS_CONSUMER_CACHE_MESSAGE)
90     {
91         return NSConsumerCacheWriteMessage(list, newObj);
92     }
93     else if (type == NS_CONSUMER_CACHE_PROVIDER)
94     {
95         return NSConsumerCacheWriteProvider(list, newObj);
96     }
97
98     NS_LOG (ERROR, "Not Supported Type");
99
100     return NS_ERROR;
101 }
102
103 NSResult NSStorageDelete(NSCacheList * list, const char * delId)
104 {
105     NS_VERIFY_NOT_NULL(list, NS_ERROR);
106     NS_VERIFY_NOT_NULL(delId, NS_ERROR);
107
108     NSCacheType type = list->cacheType;
109
110     pthread_mutex_t * mutex = NSGetCacheMutex();
111     pthread_mutex_lock(mutex);
112
113     NSCacheElement * prev = list->head;
114     NSCacheElement * del = list->head;
115     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(del, NS_ERROR, pthread_mutex_unlock(mutex));
116
117     if (NSConsumerCompareIdCacheData(type, del->data, delId))
118     {
119         if (del == list->head)
120         {
121             if (del == list->tail)
122             {
123                 list->tail = del->next;
124             }
125
126             list->head = del->next;
127
128             if (type == NS_CONSUMER_CACHE_MESSAGE)
129             {
130                 NSRemoveMessage((NSMessage *) del->data);
131             }
132             else if (type == NS_CONSUMER_CACHE_PROVIDER)
133             {
134                 NSRemoveProvider((NSProvider_internal *) del->data);
135             }
136             NSOICFree(del);
137             pthread_mutex_unlock(mutex);
138
139             return NS_OK;
140         }
141     }
142
143     del = del->next;
144     while (del)
145     {
146         if (NSConsumerCompareIdCacheData(type, del->data, delId))
147         {
148             if (del == list->tail)
149             {
150                 list->tail = prev;
151             }
152
153             prev->next = del->next;
154             if (type == NS_CONSUMER_CACHE_MESSAGE)
155             {
156                 NSRemoveMessage((NSMessage *) del->data);
157             }
158             else if (type == NS_CONSUMER_CACHE_PROVIDER)
159             {
160                 NSRemoveProvider((NSProvider_internal *) del->data);
161             }
162             NSOICFree(del);
163             pthread_mutex_unlock(mutex);
164
165             return NS_OK;
166         }
167
168         prev = del;
169         del = del->next;
170     }
171     pthread_mutex_unlock(mutex);
172     return NS_OK;
173 }
174
175 void NSConsumerRemoveMessageStore(NSCacheElement * ele, NSStoreMessage * msg)
176 {
177     NSOICFree(ele);
178     NSOICFree(msg);
179 }
180
181 NSResult NSConsumerCacheWriteMessage(NSCacheList * list, NSCacheElement * newObj)
182 {
183     NS_VERIFY_NOT_NULL(list, NS_ERROR);
184     NS_VERIFY_NOT_NULL(newObj, NS_ERROR);
185
186     pthread_mutex_t * mutex = NSGetCacheMutex();
187
188     NSMessage * newMsgObj = ((NSStoreMessage *)newObj->data)->msg;
189
190     char msgId[NS_DEVICE_ID_LENGTH] = {0, };
191     snprintf(msgId, NS_DEVICE_ID_LENGTH, "%lld", (long long int)newMsgObj->messageId);
192     NSCacheElement * it = NSStorageRead(list, msgId);
193
194     if (it)
195     {
196         NS_LOG(DEBUG, "Update message status.");
197         pthread_mutex_lock(mutex);
198         NSStoreMessage * sMsgObj = (NSStoreMessage *) it->data;
199         if(sMsgObj->status == ((NSStoreMessage *)newObj->data)->status)
200         {
201             NS_LOG (DEBUG, "Already receive message");
202             pthread_mutex_unlock(mutex);
203             return NS_ERROR;
204         }
205
206         sMsgObj->status = ((NSStoreMessage *)newObj->data)->status;
207         pthread_mutex_unlock(mutex);
208         return NS_OK;
209     }
210
211     NS_LOG(DEBUG, "Add message at storage.");
212     NSStoreMessage * sMsgObj = (NSStoreMessage *) OICMalloc(sizeof(NSStoreMessage));
213     NS_VERIFY_NOT_NULL(sMsgObj, NS_ERROR);
214
215     NSCacheElement * obj = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement));
216     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(obj, NS_ERROR, NSOICFree(sMsgObj));
217
218     sMsgObj->status = NS_SYNC_UNREAD;
219     sMsgObj->msg = (void *) NSCopyMessage(newMsgObj);
220     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(sMsgObj->msg, NS_ERROR,
221           NSConsumerRemoveMessageStore(obj, sMsgObj));
222
223     obj->next = NULL;
224     obj->data = (NSCacheData *) sMsgObj;
225
226     pthread_mutex_lock(mutex);
227     if (!list->head)
228     {
229         list->head = obj;
230         list->tail = obj;
231         pthread_mutex_unlock(mutex);
232         return NS_OK;
233     }
234
235     (list->tail)->next = obj;
236     list->tail = obj;
237     pthread_mutex_unlock(mutex);
238
239     return NS_OK;
240 }
241
242 NSResult NSConsumerCacheWriteProvider(NSCacheList * list, NSCacheElement * newObj)
243 {
244     NS_VERIFY_NOT_NULL(list, NS_ERROR);
245     NS_VERIFY_NOT_NULL(newObj, NS_ERROR);
246
247     pthread_mutex_t * mutex = NSGetCacheMutex();
248
249     NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1");
250     NSProvider_internal * prov = (NSProvider_internal *)newObj->data;
251     NS_LOG_V (DEBUG, "%s", prov->providerId);
252     NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1");
253
254     NSProvider_internal * newProvObj = (NSProvider_internal *) newObj->data;
255
256     NSCacheElement * it = NSStorageRead(list, newProvObj->providerId);
257     pthread_mutex_lock(mutex);
258
259     if (it)
260     {
261         NSProvider_internal * provObj = (NSProvider_internal *) it->data;
262
263         NSProviderConnectionInfo * infos = provObj->connection;
264         NSProviderConnectionInfo * lastConn = infos->next;
265         while(lastConn)
266         {
267             infos = lastConn;
268             lastConn = lastConn->next;
269         }
270         infos->next = NSCopyProviderConnections(newProvObj->connection);
271
272         pthread_mutex_unlock(mutex);
273
274         return NS_OK;
275     }
276
277     NSCacheElement * obj = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement));
278     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(obj, NS_ERROR, pthread_mutex_unlock(mutex));
279
280     NS_LOG_V(DEBUG, "New Object address : %s:%d", newProvObj->connection->addr->addr, newProvObj->connection->addr->port);
281     obj->data = (void *) NSCopyProvider(newProvObj);
282
283     NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2");
284     prov = (NSProvider_internal *)obj->data;
285     NS_LOG_V (DEBUG, "%s", prov->providerId);
286     NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2");
287
288     if (!obj->data)
289     {
290         NS_LOG (ERROR, "Failed to CopyProvider");
291         pthread_mutex_unlock(mutex);
292
293         return NS_ERROR;
294     }
295     obj->next = NULL;
296
297     if (!list->head)
298     {
299         list->head = obj;
300         list->tail = obj;
301
302         NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3");
303         prov = (NSProvider_internal *)list->tail->data;
304         NS_LOG_V (DEBUG, "%s", prov->providerId);
305         NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3");
306
307         pthread_mutex_unlock(mutex);
308
309         return NS_OK;
310     }
311
312     (list->tail)->next = obj;
313     list->tail = obj;
314
315     NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4");
316     prov = (NSProvider_internal *)list->tail->data;
317     NS_LOG_V (DEBUG, "%s", prov->providerId);
318     NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4");
319
320     pthread_mutex_unlock(mutex);
321
322     return NS_OK;
323 }
324
325 NSCacheElement * NSPopProviderCacheList(NSCacheList * list)
326 {
327     NS_VERIFY_NOT_NULL(list, NULL);
328
329     pthread_mutex_t * mutex = NSGetCacheMutex();
330     pthread_mutex_lock(mutex);
331
332     NSCacheElement * head = list->head;
333     if (head)
334     {
335         if (list->tail == head)
336         {
337             list->tail = NULL;
338         }
339
340         list->head = head->next;
341         head->next = NULL;
342     }
343
344     pthread_mutex_unlock(mutex);
345     return head;
346 }
347
348
349 NSResult NSStorageDestroy(NSCacheList * list)
350 {
351     NS_VERIFY_NOT_NULL(list, NS_ERROR);
352
353     pthread_mutex_t * mutex = NSGetCacheMutex();
354     pthread_mutex_lock(mutex);
355
356     NSCacheElement * iter = list->head;
357     NSCacheElement * next = NULL;
358
359     NSCacheType type = list->cacheType;
360
361     if (type == NS_CONSUMER_CACHE_MESSAGE)
362     {
363         while (iter)
364         {
365             next = (NSCacheElement *) iter->next;
366
367             NSRemoveMessage(((NSStoreMessage *) iter->data)->msg);
368             NSOICFree(iter->data);
369             NSOICFree(iter);
370
371             iter = next;
372         }
373
374         NSOICFree(list);
375     }
376     else if (type == NS_CONSUMER_CACHE_PROVIDER)
377     {
378         while (iter)
379         {
380             next = (NSCacheElement *) iter->next;
381
382             NSRemoveProvider((NSProvider_internal *) iter->data);
383             NSOICFree(iter);
384
385             iter = next;
386         }
387
388         NSOICFree(list);
389     }
390
391     pthread_mutex_unlock(mutex);
392
393     return NS_OK;
394 }
395
396 bool NSConsumerCompareIdCacheData(NSCacheType type, void * data, const char * id)
397 {
398     NS_VERIFY_NOT_NULL(data, false);
399     NS_VERIFY_NOT_NULL(id, false);
400
401     if (type == NS_CONSUMER_CACHE_MESSAGE)
402     {
403         NSMessage * msg = ((NSStoreMessage *) data)->msg;
404
405         char msgId[NS_DEVICE_ID_LENGTH] = {0, };
406         snprintf(msgId, NS_DEVICE_ID_LENGTH, "%lld", (long long int)msg->messageId);
407         if (!strcmp(msgId, id))
408         {
409             return true;
410         }
411
412         return false;
413     }
414     else if (type == NS_CONSUMER_CACHE_PROVIDER)
415     {
416         NSProvider_internal * prov = (NSProvider_internal *) data;
417         if (!strcmp(prov->providerId, id))
418         {
419             return true;
420         }
421
422         return false;
423     }
424
425     return false;
426 }