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