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