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