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