Implement APIs for topic notification.
[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 NSInitTopicStorage()\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     topicStorage = NSStorageCreate();\r
36     topicStorage->cacheType = NS_PROVIDER_CACHE_TOPIC;\r
37     isTopicList = true;\r
38 \r
39     NS_LOG(DEBUG, "NSInitTopicList - OUT");\r
40     return NS_OK;\r
41 }\r
42 \r
43 NSTopicList * NSGetTopics(char *consumerId)\r
44 {\r
45     NS_LOG(DEBUG, "NSGetTopics()");\r
46 \r
47     NSTopicList  * topicList;\r
48 \r
49     if(consumerId == NULL)\r
50     {\r
51         NS_LOG(DEBUG, "All registered topic list");\r
52     }\r
53     else\r
54     {\r
55         NS_LOG_V(DEBUG, "Subscribed topic list for consumerId(%s)", consumerId);\r
56     }\r
57 \r
58     NS_LOG(DEBUG, "NSGetTopics() NS_OK");\r
59     return topicList;\r
60 }\r
61 \r
62 //TODO: update parameter\r
63 NSResult NSStoreTopics(char * consumerId, NSTopic** topics)\r
64 {\r
65     NS_LOG(DEBUG, "NSWriteTopicsToStorage()");\r
66 \r
67     NSCacheElement * element = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement));\r
68     NSCacheTopicData * topicData = (NSCacheTopicData *) OICMalloc(sizeof(NSCacheTopicData));\r
69 \r
70     OICStrcpy(topicData->consumerId, UUID_STRING_SIZE, consumerId);\r
71     NS_LOG_V(DEBUG, "consumer id: %s", topicData->consumerId);\r
72 \r
73     // TODO: print topic list\r
74     topicData->topics = topics;\r
75     NS_LOG(DEBUG, "print topic list");\r
76 \r
77     element->data = (void*) topicData;\r
78     element->next = NULL;\r
79 \r
80     if(NSStorageWrite(topicStorage, element) != NS_OK)\r
81     {\r
82         NS_LOG(DEBUG, "fail to write cache");\r
83     }\r
84 \r
85     NS_LOG(DEBUG, "NSWriteTopicsToStorage() NS_OK");\r
86     return NS_OK;\r
87 }\r
88 \r
89 NSResult NSRegisterTopicList(NSTopicList *topicList)\r
90 {\r
91     NS_LOG(DEBUG, "NSRegisterTopicList()");\r
92 \r
93     if(!topicList)\r
94     {\r
95         NS_LOG(ERROR, "no topics");\r
96         return NS_ERROR;\r
97     }\r
98 \r
99     OCResourceHandle rHandle = NULL;\r
100     if(NSPutTopicResource(topicList, &rHandle) != NS_OK)\r
101     {\r
102         NS_LOG(ERROR, "Fail to put topic resource");\r
103         return NS_ERROR;\r
104     }\r
105 \r
106     if(topicList->consumerId != NULL)\r
107     {\r
108         // id should be null to register topic list\r
109         NS_LOG(ERROR, "invalid consumer id");\r
110         return NS_ERROR;\r
111     }\r
112 \r
113     NSStoreTopics(topicList->consumerId, topicList->head);\r
114 \r
115     NS_LOG(DEBUG, "NSRegisterTopicList() NS_OK");\r
116     return NS_OK;\r
117 }\r
118 \r
119 NSResult NSSendTopicUpdation()\r
120 {\r
121     NS_LOG(DEBUG, "NSSendTopicUpdation - IN");\r
122 \r
123     OCRepPayload* payload = OCRepPayloadCreate();\r
124 \r
125     if (!payload)\r
126     {\r
127         NS_LOG(ERROR, "fail to create playload");\r
128         return NS_ERROR;\r
129     }\r
130 \r
131     OCResourceHandle rHandle = NULL;\r
132     if (NSPutMessageResource(NULL, &rHandle) != NS_OK)\r
133     {\r
134         NS_LOG(ERROR, "Fail to put message resource");\r
135         return NS_ERROR;\r
136     }\r
137 \r
138     OCRepPayloadSetUri(payload, NS_COLLECTION_MESSAGE_URI);\r
139     OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, NS_TOPIC);\r
140     OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, NSGetProviderInfo()->providerId);\r
141 \r
142     OCObservationId obArray[255] = { 0, };\r
143     int obCount = 0;\r
144 \r
145     NSCacheElement * it = consumerSubList->head;\r
146 \r
147     while (it)\r
148     {\r
149         NSCacheSubData * subData = (NSCacheSubData *) it->data;\r
150 \r
151         if (subData->isWhite)\r
152         {\r
153             if(subData->messageObId != 0)\r
154             {\r
155                 obArray[obCount++] = subData->messageObId;\r
156             }\r
157 \r
158 #ifdef WITH_CLOUD\r
159             if(subData->remote_messageObId != 0)\r
160             {\r
161                 obArray[obCount++] = subData->remote_messageObId;\r
162             }\r
163 #endif\r
164 \r
165         }\r
166         it = it->next;\r
167     }\r
168 \r
169     if(!obCount)\r
170     {\r
171         NS_LOG(ERROR, "observer count is zero");\r
172         return NS_ERROR;\r
173     }\r
174 \r
175     if (OCNotifyListOfObservers(rHandle, obArray, obCount, payload, OC_HIGH_QOS)\r
176             != OC_STACK_OK)\r
177     {\r
178         NS_LOG(ERROR, "fail to send topic updation");\r
179         OCRepPayloadDestroy(payload);\r
180         return NS_ERROR;\r
181 \r
182     }\r
183     OCRepPayloadDestroy(payload);\r
184 \r
185     NS_LOG(DEBUG, "NSSendTopicUpdation - OUT");\r
186     return NS_OK;\r
187 }\r
188 \r
189 NSResult NSSendTopicUpdationToConsumer(char *consumerId)\r
190 {\r
191     NS_LOG(DEBUG, "NSSendTopicUpdationToConsumer - IN");\r
192 \r
193     OCRepPayload* payload = OCRepPayloadCreate();\r
194 \r
195     if (!payload)\r
196     {\r
197         NS_LOG(ERROR, "fail to create playload");\r
198         return NS_ERROR;\r
199     }\r
200 \r
201     OCResourceHandle rHandle = NULL;\r
202     if (NSPutMessageResource(NULL, &rHandle) != NS_OK)\r
203     {\r
204         NS_LOG(ERROR, "Fail to put message resource");\r
205         return NS_ERROR;\r
206     }\r
207 \r
208     OCRepPayloadSetUri(payload, NS_COLLECTION_MESSAGE_URI);\r
209     OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, NS_TOPIC);\r
210     OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, NSGetProviderInfo()->providerId);\r
211 \r
212     NSCacheElement * element = NSStorageRead(consumerSubList, consumerId);\r
213 \r
214     if(element == NULL)\r
215     {\r
216         NS_LOG(ERROR, "element is NULL");\r
217         return NS_ERROR;\r
218     }\r
219 \r
220     NSCacheSubData * subData = (NSCacheSubData*) element->data;\r
221 \r
222     if (OCNotifyListOfObservers(rHandle, (OCObservationId*)&subData->messageObId, 1, payload, OC_HIGH_QOS)\r
223             != OC_STACK_OK)\r
224     {\r
225         NS_LOG(ERROR, "fail to send topic updation");\r
226         OCRepPayloadDestroy(payload);\r
227         return NS_ERROR;\r
228 \r
229     }\r
230 \r
231     OCRepPayloadDestroy(payload);\r
232 \r
233     NS_LOG(DEBUG, "NSSendTopicUpdationToConsumer - OUT");\r
234     return NS_OK;\r
235 }\r
236 \r
237 bool NSIsTopicSubscribed(char * consumerId, char * topic)\r
238 {\r
239     //TODO: implement function\r
240     return true;\r
241 }\r
242 \r
243 void * NSTopicSchedule(void * ptr)\r
244 {\r
245     if (ptr == NULL)\r
246     {\r
247         NS_LOG(DEBUG, "Create NSTopicSchedule");\r
248     }\r
249 \r
250     while (NSIsRunning[TOPIC_SCHEDULER])\r
251     {\r
252         sem_wait(&NSSemaphore[TOPIC_SCHEDULER]);\r
253         pthread_mutex_lock(&NSMutex[TOPIC_SCHEDULER]);\r
254 \r
255         if (NSHeadMsg[TOPIC_SCHEDULER] != NULL)\r
256         {\r
257             NSTask *node = NSHeadMsg[TOPIC_SCHEDULER];\r
258             NSHeadMsg[TOPIC_SCHEDULER] = node->nextTask;\r
259 \r
260             switch (node->taskType)\r
261             {\r
262                 case TASK_SEND_TOPICS:\r
263                     NS_LOG(DEBUG, "CASE TASK_SEND_TOPICS : ");\r
264                     break;\r
265                 case TASK_SUBSCRIBE_TOPICS:\r
266                     NS_LOG(DEBUG, "CASE TASK_SUBSCRIBE_TOPICS : ");\r
267                     break;\r
268                 case TASK_REGISTER_TOPICS:\r
269                     NS_LOG(DEBUG, "CASE TASK_REGISTER_TOPICS : ");\r
270                     NSTopicList * topicList = (NSTopicList *) node->taskData;\r
271                     NSRegisterTopicList(topicList);\r
272                     NSSendTopicUpdation();\r
273                     // TODO : free NSTopic\r
274                     // NSFreeTopicList(topicList);\r
275                     break;\r
276                 default:\r
277                     break;\r
278             }\r
279 \r
280             OICFree(node);\r
281         }\r
282 \r
283         pthread_mutex_unlock(&NSMutex[TOPIC_SCHEDULER]);\r
284     }\r
285 \r
286     NS_LOG(DEBUG, "Destroy NSTopicSchedule");\r
287     return NULL;\r
288 }\r