replace : iotivity -> iotivity-sec
[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 * NSConsumerStorageCreate()
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 * NSConsumerStorageRead(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                 ((NSProvider_internal *) iter->data)->connection;
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 NSConsumerStorageWrite(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_PROVIDER)
127     {
128         return NSConsumerCacheWriteProvider(list, newObj);
129     }
130
131     NS_LOG (ERROR, "Not Supported Type");
132
133     return NS_ERROR;
134 }
135
136 NSResult NSConsumerStorageDelete(NSCacheList * list, const char * delId)
137 {
138     NS_VERIFY_NOT_NULL(list, NS_ERROR);
139     NS_VERIFY_NOT_NULL(delId, NS_ERROR);
140
141     NSCacheType type = list->cacheType;
142
143     pthread_mutex_t * mutex = NSGetCacheMutex();
144     pthread_mutex_lock(mutex);
145
146     NSCacheElement * prev = list->head;
147     NSCacheElement * del = list->head;
148     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(del, NS_ERROR, pthread_mutex_unlock(mutex));
149
150     if (NSConsumerCompareIdCacheData(type, del->data, delId))
151     {
152         if (del == list->head)
153         {
154             if (del == list->tail)
155             {
156                 list->tail = del->next;
157             }
158
159             list->head = del->next;
160
161             if (type == NS_CONSUMER_CACHE_PROVIDER)
162             {
163                 NSRemoveProvider_internal((void *) del->data);
164             }
165             NSOICFree(del);
166             pthread_mutex_unlock(mutex);
167
168             return NS_OK;
169         }
170     }
171
172     del = del->next;
173     while (del)
174     {
175         if (NSConsumerCompareIdCacheData(type, del->data, delId))
176         {
177             if (del == list->tail)
178             {
179                 list->tail = prev;
180             }
181
182             prev->next = del->next;
183
184             if (type == NS_CONSUMER_CACHE_PROVIDER)
185             {
186                 NSRemoveProvider_internal((NSProvider_internal *) del->data);
187             }
188             NSOICFree(del);
189             pthread_mutex_unlock(mutex);
190
191             return NS_OK;
192         }
193
194         prev = del;
195         del = del->next;
196     }
197     pthread_mutex_unlock(mutex);
198     return NS_OK;
199 }
200
201 NSResult NSConsumerCacheWriteProvider(NSCacheList * list, NSCacheElement * newObj)
202 {
203     NS_VERIFY_NOT_NULL(list, NS_ERROR);
204     NS_VERIFY_NOT_NULL(newObj, NS_ERROR);
205
206     pthread_mutex_t * mutex = NSGetCacheMutex();
207
208     NSProvider_internal * newProvObj = (NSProvider_internal *) newObj->data;
209
210     NSCacheElement * it = NSConsumerStorageRead(list, newProvObj->providerId);
211
212     pthread_mutex_lock(mutex);
213
214     if (it)
215     {
216         if (newProvObj->connection)
217         {
218             NSProvider_internal * provObj = (NSProvider_internal *) it->data;
219
220             NSProviderConnectionInfo * infos = provObj->connection;
221             NSProviderConnectionInfo * lastConn = infos->next;
222             while(lastConn)
223             {
224                 infos = lastConn;
225                 lastConn = lastConn->next;
226             }
227             infos->next = NSCopyProviderConnections(newProvObj->connection);
228         }
229
230         if (newProvObj->topicLL)
231         {
232             NSProvider_internal * provObj = (NSProvider_internal *) it->data;
233             NSRemoveTopicLL(provObj->topicLL);
234             provObj->topicLL = NSCopyTopicLL(newProvObj->topicLL);
235         }
236
237         pthread_mutex_unlock(mutex);
238
239         return NS_OK;
240     }
241
242     NSCacheElement * obj = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement));
243     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(obj, NS_ERROR, pthread_mutex_unlock(mutex));
244
245     NS_LOG_V(INFO_PRIVATE, "New Object address : %s:%d", newProvObj->connection->addr->addr, newProvObj->connection->addr->port);
246     obj->data = (void *) NSCopyProvider_internal(newProvObj);
247
248     if (!obj->data)
249     {
250         NS_LOG (ERROR, "Failed to CopyProvider");
251         NSOICFree(obj);
252         pthread_mutex_unlock(mutex);
253
254         return NS_ERROR;
255     }
256     obj->next = NULL;
257
258     if (!list->head)
259     {
260         list->head = obj;
261         list->tail = obj;
262
263         pthread_mutex_unlock(mutex);
264
265         return NS_OK;
266     }
267
268     (list->tail)->next = obj;
269     list->tail = obj;
270
271     pthread_mutex_unlock(mutex);
272
273     return NS_OK;
274 }
275
276 NSCacheElement * NSPopProviderCacheList(NSCacheList * list)
277 {
278     NS_VERIFY_NOT_NULL(list, NULL);
279
280     pthread_mutex_t * mutex = NSGetCacheMutex();
281     pthread_mutex_lock(mutex);
282
283     NSCacheElement * head = list->head;
284     if (head)
285     {
286         if (list->tail == head)
287         {
288             list->tail = NULL;
289         }
290
291         list->head = head->next;
292         head->next = NULL;
293     }
294
295     pthread_mutex_unlock(mutex);
296     return head;
297 }
298
299
300 NSResult NSConsumerStorageDestroy(NSCacheList * list)
301 {
302     NS_VERIFY_NOT_NULL(list, NS_ERROR);
303
304     pthread_mutex_t * mutex = NSGetCacheMutex();
305     pthread_mutex_lock(mutex);
306
307     NSCacheElement * iter = list->head;
308     NSCacheElement * next = NULL;
309
310     NSCacheType type = list->cacheType;
311
312     if (type == NS_CONSUMER_CACHE_PROVIDER)
313     {
314         while (iter)
315         {
316             next = (NSCacheElement *) iter->next;
317
318             NSRemoveProvider_internal((void *) iter->data);
319             NSOICFree(iter);
320
321             iter = next;
322         }
323
324         NSOICFree(list);
325     }
326
327     pthread_mutex_unlock(mutex);
328
329     return NS_OK;
330 }
331
332 bool NSConsumerCompareIdCacheData(NSCacheType type, void * data, const char * id)
333 {
334     NS_VERIFY_NOT_NULL(data, false);
335     NS_VERIFY_NOT_NULL(id, false);
336
337     if (type == NS_CONSUMER_CACHE_PROVIDER)
338     {
339         NSProvider_internal * prov = (NSProvider_internal *) data;
340         if (!strcmp(prov->providerId, id))
341         {
342             return true;
343         }
344
345         return false;
346     }
347
348     return false;
349 }