Bug fixes for initialize condition of TopicList.
[platform/upstream/iotivity.git] / service / notification / src / provider / NSProviderTopic.c
1 //******************************************************************\r
2 //\r
3 // Copyright 2016 Samsung Electronics All Rights Reserved.\r
4 //\r
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
6 //\r
7 // Licensed under the Apache License, Version 2.0 (the "License");\r
8 // you may not use this file except in compliance with the License.\r
9 // You may obtain a copy of the License at\r
10 //\r
11 //      http://www.apache.org/licenses/LICENSE-2.0\r
12 //\r
13 // Unless required by applicable law or agreed to in writing, software\r
14 // distributed under the License is distributed on an "AS IS" BASIS,\r
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16 // See the License for the specific language governing permissions and\r
17 // limitations under the License.\r
18 //\r
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
20 \r
21 #include "NSProviderTopic.h"\r
22 \r
23 NSResult NSSendTopicUpdation();\r
24 \r
25 NSResult NSInitTopicList()\r
26 {\r
27     NS_LOG(DEBUG, "NSInitTopicList - IN");\r
28     consumerTopicList = NSStorageCreate();\r
29     consumerTopicList->cacheType = NS_PROVIDER_CACHE_CONSUMER_TOPIC_NAME;\r
30 \r
31     registeredTopicList = NSStorageCreate();\r
32     registeredTopicList->cacheType = NS_PROVIDER_CACHE_REGISTER_TOPIC;\r
33 \r
34     NS_LOG(DEBUG, "NSInitTopicList - OUT");\r
35     return NS_OK;\r
36 }\r
37 \r
38 NSTopicList * NSGetTopics(char *consumerId)\r
39 {\r
40     NS_LOG(DEBUG, "NSGetTopics()");\r
41 \r
42     NSTopicList  * topicList;\r
43 \r
44     if(consumerId == NULL)\r
45     {\r
46         NS_LOG(DEBUG, "All registered topic list");\r
47         //TODO: get registered topic list\r
48     }\r
49     else\r
50     {\r
51         NS_LOG_V(DEBUG, "Subscribed topic list for consumerId(%s)", consumerId);\r
52         //TODO: get subscribed topic list for consumer\r
53     }\r
54 \r
55     NS_LOG(DEBUG, "NSGetTopics() NS_OK");\r
56     return topicList;\r
57 }\r
58 \r
59 NSResult NSAddTopics(const char * topicName)\r
60 {\r
61     NS_LOG(DEBUG, "NSWriteTopicsToStorage()");\r
62 \r
63     NSCacheTopicData * data = (NSCacheTopicData *)OICMalloc(sizeof(NSCacheTopicData));\r
64     data->topicName = topicName;\r
65     data->state = NS_TOPIC_UNSUBSCRIBED;\r
66 \r
67     NSCacheElement * element = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement));\r
68     element->data = (void *) data;\r
69     element->next = NULL;\r
70 \r
71     if(NSStorageWrite(registeredTopicList, element) != NS_OK)\r
72     {\r
73         NS_LOG(DEBUG, "fail to write cache");\r
74     }\r
75     NSSendTopicUpdation();\r
76 \r
77     NS_LOG(DEBUG, "NSWriteTopicsToStorage() NS_OK");\r
78     return NS_OK;\r
79 }\r
80 \r
81 NSResult NSDeleteTopics(const char * topicName)\r
82 {\r
83     NS_LOG(DEBUG, "NSDeleteTopics()");\r
84 \r
85     if(!topicName)\r
86     {\r
87         NS_LOG(ERROR, "topicName is NULL");\r
88         return NS_ERROR;\r
89     }\r
90 \r
91     NSStorageDelete(registeredTopicList, topicName);\r
92     while(NSStorageDelete(consumerTopicList, topicName) != NS_FAIL);\r
93     return NS_OK;\r
94 }\r
95 \r
96 NSResult NSSubscribeTopicList(char *consumerId, NSTopicList *topicList)\r
97 {\r
98     NS_LOG(DEBUG, "NSSubscribeTopicList()");\r
99 \r
100     if(!topicList)\r
101     {\r
102         NS_LOG(ERROR, "no topics");\r
103         return NS_ERROR;\r
104     }\r
105 \r
106     if(!consumerId)\r
107     {\r
108         NS_LOG(ERROR, "invalid consumer id");\r
109         return NS_ERROR;\r
110     }\r
111 \r
112     OCResourceHandle rHandle = NULL;\r
113     if(NSPutTopicResource(topicList, &rHandle) != NS_OK)\r
114     {\r
115         NS_LOG(ERROR, "Fail to put topic resource");\r
116         return NS_ERROR;\r
117     }\r
118 \r
119     //TODO it will change logic.\r
120     //NSStoreTopics(consumerId, topicList->head);\r
121 \r
122     NS_LOG(DEBUG, "NSSubscribeTopicList() NS_OK");\r
123     return NS_OK;\r
124 }\r
125 \r
126 NSResult NSSendTopicUpdation()\r
127 {\r
128     NS_LOG(DEBUG, "NSSendTopicUpdation - IN");\r
129 \r
130     OCRepPayload* payload = OCRepPayloadCreate();\r
131 \r
132     if (!payload)\r
133     {\r
134         NS_LOG(ERROR, "fail to create playload");\r
135         return NS_ERROR;\r
136     }\r
137 \r
138     OCResourceHandle rHandle = NULL;\r
139     if (NSPutMessageResource(NULL, &rHandle) != NS_OK)\r
140     {\r
141         NS_LOG(ERROR, "Fail to put message resource");\r
142         return NS_ERROR;\r
143     }\r
144 \r
145     OCRepPayloadSetUri(payload, NS_COLLECTION_MESSAGE_URI);\r
146     OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, NS_TOPIC);\r
147     OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, NSGetProviderInfo()->providerId);\r
148 \r
149     OCObservationId obArray[255] = { 0, };\r
150     int obCount = 0;\r
151 \r
152     NSCacheElement * it = consumerSubList->head;\r
153 \r
154     while (it)\r
155     {\r
156         NSCacheSubData * subData = (NSCacheSubData *) it->data;\r
157 \r
158         if (subData->isWhite)\r
159         {\r
160             if(subData->messageObId != 0)\r
161             {\r
162                 obArray[obCount++] = subData->messageObId;\r
163             }\r
164 \r
165 #ifdef WITH_CLOUD\r
166             if(subData->remote_messageObId != 0)\r
167             {\r
168                 obArray[obCount++] = subData->remote_messageObId;\r
169             }\r
170 #endif\r
171 \r
172         }\r
173         it = it->next;\r
174     }\r
175 \r
176     if(!obCount)\r
177     {\r
178         NS_LOG(ERROR, "observer count is zero");\r
179         return NS_ERROR;\r
180     }\r
181 \r
182     if (OCNotifyListOfObservers(rHandle, obArray, obCount, payload, OC_HIGH_QOS)\r
183             != OC_STACK_OK)\r
184     {\r
185         NS_LOG(ERROR, "fail to send topic updation");\r
186         OCRepPayloadDestroy(payload);\r
187         return NS_ERROR;\r
188 \r
189     }\r
190     OCRepPayloadDestroy(payload);\r
191 \r
192     NS_LOG(DEBUG, "NSSendTopicUpdation - OUT");\r
193     return NS_OK;\r
194 }\r
195 \r
196 NSResult NSSendTopicUpdationToConsumer(char *consumerId)\r
197 {\r
198     NS_LOG(DEBUG, "NSSendTopicUpdationToConsumer - IN");\r
199 \r
200     OCRepPayload* payload = OCRepPayloadCreate();\r
201 \r
202     if (!payload)\r
203     {\r
204         NS_LOG(ERROR, "fail to create playload");\r
205         return NS_ERROR;\r
206     }\r
207 \r
208     OCResourceHandle rHandle = NULL;\r
209     if (NSPutMessageResource(NULL, &rHandle) != NS_OK)\r
210     {\r
211         NS_LOG(ERROR, "Fail to put message resource");\r
212         return NS_ERROR;\r
213     }\r
214 \r
215     OCRepPayloadSetUri(payload, NS_COLLECTION_MESSAGE_URI);\r
216     OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, NS_TOPIC);\r
217     OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, NSGetProviderInfo()->providerId);\r
218 \r
219     NSCacheElement * element = NSStorageRead(consumerSubList, consumerId);\r
220 \r
221     if(element == NULL)\r
222     {\r
223         NS_LOG(ERROR, "element is NULL");\r
224         return NS_ERROR;\r
225     }\r
226 \r
227     NSCacheSubData * subData = (NSCacheSubData*) element->data;\r
228 \r
229     if (OCNotifyListOfObservers(rHandle, (OCObservationId*)&subData->messageObId, 1, payload, OC_HIGH_QOS)\r
230             != OC_STACK_OK)\r
231     {\r
232         NS_LOG(ERROR, "fail to send topic updation");\r
233         OCRepPayloadDestroy(payload);\r
234         return NS_ERROR;\r
235 \r
236     }\r
237 \r
238     OCRepPayloadDestroy(payload);\r
239 \r
240     NS_LOG(DEBUG, "NSSendTopicUpdationToConsumer - OUT");\r
241     return NS_OK;\r
242 }\r
243 \r
244 NSResult NSSendTopicList(OCEntityHandlerRequest * entityHandlerRequest)\r
245 {\r
246     NS_LOG(DEBUG, "NSSendTopicList - IN");\r
247 \r
248     char * id = NSGetValueFromQuery(OICStrdup(entityHandlerRequest->query), NS_QUERY_CONSUMER_ID);\r
249     if(!id)\r
250     {\r
251         NS_LOG(DEBUG, "Send registered topic list");\r
252         //TODO: get registered topic list\r
253         // NSGetTopics(NULL);\r
254     }\r
255     else\r
256     {\r
257         NS_LOG(DEBUG, "Send subscribed topic list to consumer");\r
258         //TODO: get subscribed topic list for consumer\r
259         // NSGetTopics(consumerid);\r
260     }\r
261 \r
262     // make response for the Get Request\r
263     OCEntityHandlerResponse response;\r
264     response.numSendVendorSpecificHeaderOptions = 0;\r
265     memset(response.sendVendorSpecificHeaderOptions, 0,\r
266             sizeof response.sendVendorSpecificHeaderOptions);\r
267     memset(response.resourceUri, 0, sizeof response.resourceUri);\r
268 \r
269     OCRepPayload* payload = OCRepPayloadCreate();\r
270     if (!payload)\r
271     {\r
272         NS_LOG(ERROR, "payload is NULL");\r
273         return NS_ERROR;\r
274     }\r
275 \r
276     // set topics to the array of resource property\r
277     const int TOPIC_MAX_SIZE = 100;\r
278     int dimensions = 0;\r
279     OCRepPayload* payloadTopicArray[TOPIC_MAX_SIZE];\r
280     //TODO: use while(NSTopicList)\r
281     OCRepPayload* payloadTopic1;\r
282     OCRepPayload* payloadTopic2;\r
283 \r
284     OCRepPayloadSetPropString(payloadTopic1, NS_ATTRIBUTE_TOPIC_NAME, "test topic name1");\r
285     OCRepPayloadSetPropBool(payloadTopic1, NS_ATTRIBUTE_TOPIC_SELECTION, true);\r
286 \r
287     OCRepPayloadSetPropString(payloadTopic2, NS_ATTRIBUTE_TOPIC_NAME, "test topic name2");\r
288     OCRepPayloadSetPropBool(payloadTopic2, NS_ATTRIBUTE_TOPIC_SELECTION, false);\r
289 \r
290     payloadTopicArray[dimensions++] = payloadTopic1;\r
291     payloadTopicArray[dimensions++] = payloadTopic2;\r
292     // end of set topics\r
293 \r
294     OCRepPayloadSetUri(payload, NS_COLLECTION_TOPIC_URI);\r
295     OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_CONSUMER_ID, id);\r
296     // TODO: add PayLoadSet with topic list got above\r
297     OCRepPayloadSetPropObjectArray(payload, NS_ATTRIBUTE_TOPIC_LIST, (const OCRepPayload**)(payloadTopicArray), dimensions);\r
298 \r
299     response.requestHandle = entityHandlerRequest->requestHandle;\r
300     response.resourceHandle = entityHandlerRequest->resource;\r
301     response.persistentBufferFlag = 0;\r
302     response.ehResult = OC_EH_OK;\r
303     response.payload = (OCPayload *) payload;\r
304 \r
305     // Send Response\r
306     if (OCDoResponse(&response) != OC_STACK_OK)\r
307     {\r
308         NS_LOG(ERROR, "Fail to response topic list");\r
309         return NS_ERROR;\r
310     }\r
311     OCRepPayloadDestroy(payload);\r
312     NSFreeOCEntityHandlerRequest(entityHandlerRequest);\r
313 \r
314     NS_LOG(DEBUG, "NSSendTopicList - OUT");\r
315     return NS_OK;\r
316 }\r
317 \r
318 bool NSIsTopicSubscribed(char * consumerId, char * topic)\r
319 {\r
320     //TODO: implement function\r
321     return true;\r
322 }\r
323 \r
324 void * NSTopicSchedule(void * ptr)\r
325 {\r
326     if (ptr == NULL)\r
327     {\r
328         NS_LOG(DEBUG, "Create NSTopicSchedule");\r
329     }\r
330 \r
331     while (NSIsRunning[TOPIC_SCHEDULER])\r
332     {\r
333         sem_wait(&NSSemaphore[TOPIC_SCHEDULER]);\r
334         pthread_mutex_lock(&NSMutex[TOPIC_SCHEDULER]);\r
335 \r
336         if (NSHeadMsg[TOPIC_SCHEDULER] != NULL)\r
337         {\r
338             NSTask *node = NSHeadMsg[TOPIC_SCHEDULER];\r
339             NSHeadMsg[TOPIC_SCHEDULER] = node->nextTask;\r
340 \r
341             switch (node->taskType)\r
342             {\r
343                 case TASK_SEND_TOPICS:\r
344                     NS_LOG(DEBUG, "CASE TASK_SEND_TOPICS : ");\r
345                     NSSendTopicList((OCEntityHandlerRequest*) node->taskData);\r
346                     break;\r
347                 case TASK_SUBSCRIBE_TOPIC:\r
348                     NS_LOG(DEBUG, "CASE TASK_SUBSCRIBE_TOPIC : ");\r
349                     NSCacheElement * newObj = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement));\r
350                     newObj->data = node->taskData;\r
351                     newObj->next = NULL;\r
352                     NSStorageWrite(consumerTopicList, newObj);\r
353                     break;\r
354                 case TASK_UNSUBSCRIBE_TOPIC:\r
355                     consumerTopicList->cacheType = NS_PROVIDER_CACHE_CONSUMER_TOPIC_CID;\r
356                     NSStorageDelete(consumerTopicList, (const char *) node->taskData);\r
357                     consumerTopicList->cacheType = NS_PROVIDER_CACHE_CONSUMER_TOPIC_NAME;\r
358                     OICFree((char *)node->taskData);\r
359                     break;\r
360                 case TASK_ADD_TOPIC:\r
361                 {\r
362                     NS_LOG(DEBUG, "CASE TASK_ADD_TOPIC : ");\r
363                     NSAddTopics((const char *) node->taskData);\r
364                 }\r
365                     break;\r
366                 case TASK_DELETE_TOPIC:\r
367                 {\r
368                     NS_LOG(DEBUG, "CASE_TASK_DELETE_TOPIC : ");\r
369                     NSDeleteTopics((const char *) node->taskData);\r
370                 }\r
371                     break;\r
372                 default:\r
373                     break;\r
374             }\r
375 \r
376             OICFree(node);\r
377         }\r
378 \r
379         pthread_mutex_unlock(&NSMutex[TOPIC_SCHEDULER]);\r
380     }\r
381 \r
382     NS_LOG(DEBUG, "Destroy NSTopicSchedule");\r
383     return NULL;\r
384 }\r