code cleanup.
[platform/upstream/iotivity.git] / service / notification / src / provider / NSProviderSubscription.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 "NSProviderSubscription.h"\r
22 \r
23 NSResult NSInitSubscriptionList()\r
24 {\r
25     NS_LOG(DEBUG, "NSInitSubscriptionList - IN");\r
26 \r
27     consumerSubList = NSStorageCreate();\r
28     consumerSubList->cacheType = NS_PROVIDER_CACHE_SUBSCRIBER;\r
29 \r
30     NS_LOG(DEBUG, "NSInitSubscriptionList - OUT");\r
31     return NS_OK;\r
32 }\r
33 \r
34 NSResult NSSetSubscriptionAccessPolicy(NSAccessPolicy access)\r
35 {\r
36     NS_LOG(DEBUG, "NSSetSubscriptionAcceptPolicy - IN");\r
37 \r
38     if (access == NS_ACCESS_ALLOW)\r
39     {\r
40         NS_LOG(DEBUG, "Place Provider as a subscription accepter");\r
41     }\r
42     else if (access == NS_ACCESS_DENY)\r
43     {\r
44         NS_LOG(DEBUG, "Place Consumer as a subscription accepter");\r
45     }\r
46 \r
47     NSSubscriptionAccess = access;\r
48 \r
49     NS_LOG(DEBUG, "NSSetSubscriptionAcceptPolicy - OUT");\r
50     return NS_OK;\r
51 }\r
52 \r
53 int NSGetSubscriptionAccepter()\r
54 {\r
55     return NSSubscriptionAccess;\r
56 }\r
57 \r
58 NSResult NSSendAccessPolicyResponse(OCEntityHandlerRequest *entityHandlerRequest)\r
59 {\r
60     NS_LOG(DEBUG, "NSSendAccessPolicyResponse - IN");\r
61 \r
62     // put notification resource\r
63     OCResourceHandle notificationResourceHandle = NULL;\r
64     if (NSPutNotificationResource(NSGetSubscriptionAccepter(), &notificationResourceHandle)\r
65             != NS_OK)\r
66     {\r
67         NS_LOG(ERROR, "Fail to put notification resource");\r
68         return NS_ERROR;\r
69     }\r
70 \r
71     // make response for the Get Request\r
72     OCEntityHandlerResponse response;\r
73     response.numSendVendorSpecificHeaderOptions = 0;\r
74     memset(response.sendVendorSpecificHeaderOptions, 0,\r
75             sizeof response.sendVendorSpecificHeaderOptions);\r
76     memset(response.resourceUri, 0, sizeof response.resourceUri);\r
77 \r
78     OCRepPayload* payload = OCRepPayloadCreate();\r
79     if (!payload)\r
80     {\r
81         NS_LOG(ERROR, "payload is NULL");\r
82         return NS_ERROR;\r
83     }\r
84 \r
85     NS_LOG_V(DEBUG, "NS Provider ID: %s", NSGetProviderInfo()->providerId);\r
86 \r
87     OCRepPayloadSetUri(payload, NS_ROOT_URI);\r
88     OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, NSGetProviderInfo()->providerId);\r
89     OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_POLICY, NSGetSubscriptionAccepter());\r
90     OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_MESSAGE, NS_COLLECTION_MESSAGE_URI);\r
91     OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_SYNC, NS_COLLECTION_SYNC_URI);\r
92 \r
93     response.requestHandle = entityHandlerRequest->requestHandle;\r
94     response.resourceHandle = entityHandlerRequest->resource;\r
95     response.persistentBufferFlag = 0;\r
96     response.ehResult = OC_EH_OK;\r
97     response.payload = (OCPayload *) payload;\r
98 \r
99     // Send Response\r
100     if (OCDoResponse(&response) != OC_STACK_OK)\r
101     {\r
102         NS_LOG(ERROR, "Fail to AccessPolicy send response");\r
103         return NS_ERROR;\r
104     }\r
105     OCRepPayloadDestroy(payload);\r
106     NSFreeOCEntityHandlerRequest(entityHandlerRequest);\r
107 \r
108     NS_LOG(DEBUG, "NSSendAccessPolicyResponse - OUT");\r
109     return NS_OK;\r
110 }\r
111 \r
112 void NSHandleSubscription(OCEntityHandlerRequest *entityHandlerRequest, NSResourceType resourceType)\r
113 {\r
114     NS_LOG(DEBUG, "NSHandleSubscription - IN");\r
115 \r
116     char * id = NSGetValueFromQuery(OICStrdup(entityHandlerRequest->query), NS_QUERY_CONSUMER_ID);\r
117 \r
118     if(!id)\r
119     {\r
120         NSFreeOCEntityHandlerRequest(entityHandlerRequest);\r
121         NS_LOG(ERROR, "Invalid ConsumerID");\r
122         return;\r
123     }\r
124 \r
125     NS_LOG_V(DEBUG, "consumerId = %s", id);\r
126     if (resourceType == NS_RESOURCE_MESSAGE)\r
127     {\r
128         NS_LOG(DEBUG, "resourceType == NS_RESOURCE_MESSAGE");\r
129         NSCacheElement * element = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement));\r
130         NSCacheSubData * subData = (NSCacheSubData *) OICMalloc(sizeof(NSCacheSubData));\r
131 \r
132         OICStrcpy(subData->id, UUID_STRING_SIZE, id);\r
133         NS_LOG_V(DEBUG, "SubList ID = [%s]", subData->id);\r
134 \r
135         NS_LOG_V(DEBUG, "Consumer Address: %s", entityHandlerRequest->devAddr.addr);\r
136         if(NSIsRemoteServerAddress(entityHandlerRequest->devAddr.addr))\r
137         {\r
138             NS_LOG(DEBUG, "Requested by remote server");\r
139             subData->remote_messageObId = entityHandlerRequest->obsInfo.obsId;\r
140             subData->messageObId = 0;\r
141             NS_LOG_V(DEBUG, "SubList message observation ID = [%d]", subData->remote_messageObId);\r
142         }\r
143         else\r
144         {\r
145             NS_LOG(DEBUG, "Requested by local consumer");\r
146             subData->messageObId = entityHandlerRequest->obsInfo.obsId;\r
147             subData->remote_messageObId = 0;\r
148             NS_LOG_V(DEBUG, "SubList message observation ID = [%d]", subData->messageObId);\r
149         }\r
150         subData->isWhite = false;\r
151         subData->remote_syncObId = 0;\r
152         subData->syncObId = 0;\r
153 \r
154         element->data = (void*) subData;\r
155         element->next = NULL;\r
156 \r
157         if (NSStorageWrite(consumerSubList, element) != NS_OK)\r
158         {\r
159             NS_LOG(DEBUG, "fail to write cache");\r
160         }\r
161 \r
162         if (NSGetSubscriptionAccepter() == NS_ACCESS_ALLOW)\r
163         {\r
164             NS_LOG(DEBUG, "NSGetSubscriptionAccepter == NS_ACCEPTER_PROVIDER");\r
165             NSAskAcceptanceToUser(entityHandlerRequest);\r
166         }\r
167         else if (NSGetSubscriptionAccepter() == NS_ACCESS_DENY)\r
168         {\r
169             NS_LOG(DEBUG, "NSGetSubscriptionAccepter == NS_ACCEPTER_CONSUMER");\r
170             NSSendSubscriptionResponse(entityHandlerRequest, true);\r
171         }\r
172     }\r
173     else if (resourceType == NS_RESOURCE_SYNC)\r
174     {\r
175         NS_LOG(DEBUG, "resourceType == NS_RESOURCE_SYNC");\r
176         NSCacheElement * element = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement));\r
177         NSCacheSubData * subData = (NSCacheSubData *) OICMalloc(sizeof(NSCacheSubData));\r
178 \r
179         OICStrcpy(subData->id, UUID_STRING_SIZE, id);\r
180         NS_LOG_V(DEBUG, "SubList ID = [%s]", subData->id);\r
181 \r
182         NS_LOG_V(DEBUG, "Consumer Address: %s", entityHandlerRequest->devAddr.addr);\r
183         if(NSIsRemoteServerAddress(entityHandlerRequest->devAddr.addr))\r
184         {\r
185             NS_LOG(DEBUG, "Requested by remote server");\r
186             subData->remote_syncObId = entityHandlerRequest->obsInfo.obsId;\r
187             subData->syncObId = 0;\r
188             NS_LOG_V(DEBUG, "SubList sync observation ID = [%d]", subData->remote_syncObId);\r
189         }\r
190         else\r
191         {\r
192             NS_LOG(DEBUG, "Requested by local consumer");\r
193             subData->syncObId = entityHandlerRequest->obsInfo.obsId;\r
194             subData->remote_syncObId = 0;\r
195             NS_LOG_V(DEBUG, "SubList sync observation ID = [%d]", subData->syncObId);\r
196         }\r
197 \r
198         subData->isWhite = false;\r
199         subData->messageObId = 0;\r
200         subData->remote_messageObId = 0;\r
201 \r
202         element->data = (void*) subData;\r
203         element->next = NULL;\r
204 \r
205         if (NSStorageWrite(consumerSubList, element) != NS_OK)\r
206         {\r
207             NS_LOG(ERROR, "Fail to write cache");\r
208         }\r
209 \r
210         NSFreeOCEntityHandlerRequest(entityHandlerRequest);\r
211     }\r
212 \r
213     NS_LOG(DEBUG, "NSHandleSubscription - OUT");\r
214 }\r
215 \r
216 void NSHandleUnsubscription(OCEntityHandlerRequest *entityHandlerRequest)\r
217 {\r
218     NS_LOG(DEBUG, "NSHandleUnsubscription - IN");\r
219 \r
220     NSProviderDeleteSubDataFromObId(consumerSubList, entityHandlerRequest->obsInfo.obsId);\r
221 \r
222     NSFreeOCEntityHandlerRequest(entityHandlerRequest);\r
223 \r
224     NS_LOG(DEBUG, "NSHandleUnsubscription - OUT");\r
225 }\r
226 \r
227 void NSAskAcceptanceToUser(OCEntityHandlerRequest *entityHandlerRequest)\r
228 {\r
229     NS_LOG(DEBUG, "NSAskAcceptanceToUser - IN");\r
230 \r
231     NSPushQueue(CALLBACK_RESPONSE_SCHEDULER, TASK_CB_SUBSCRIPTION, entityHandlerRequest);\r
232 \r
233     NS_LOG(DEBUG, "NSAskAcceptanceToUser - OUT");\r
234 }\r
235 \r
236 NSResult NSSendResponse(const char * id, bool accepted)\r
237 {\r
238     NS_LOG(DEBUG, "NSSendResponse - IN");\r
239 \r
240     OCRepPayload* payload = OCRepPayloadCreate();\r
241     if (!payload)\r
242     {\r
243         NS_LOG(ERROR, "fail to create playload");\r
244         return NS_ERROR;\r
245     }\r
246 \r
247     OCResourceHandle rHandle = NULL;\r
248     if (NSPutMessageResource(NULL, &rHandle) != NS_OK)\r
249     {\r
250         NS_LOG(ERROR, "Fail to put notification resource");\r
251         return NS_ERROR;\r
252     }\r
253 \r
254     OCRepPayloadSetUri(payload, NS_COLLECTION_MESSAGE_URI);\r
255     OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, 1);\r
256     OCRepPayloadSetPropBool(payload, NS_ATTRIBUTE_ACCPETANCE, accepted);\r
257     OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, NSGetProviderInfo()->providerId);\r
258 \r
259     NSCacheElement * element = NSStorageRead(consumerSubList, id);\r
260 \r
261     if(element == NULL)\r
262     {\r
263         NS_LOG(ERROR, "element is NULL");\r
264         return NS_ERROR;\r
265     }\r
266     NSCacheSubData * subData = (NSCacheSubData*) element->data;\r
267 \r
268     if (OCNotifyListOfObservers(rHandle, (OCObservationId*)&subData->messageObId, 1, payload, OC_HIGH_QOS)\r
269             != OC_STACK_OK)\r
270     {\r
271         NS_LOG(ERROR, "fail to send Acceptance");\r
272         OCRepPayloadDestroy(payload);\r
273         return NS_ERROR;\r
274 \r
275     }\r
276     OCRepPayloadDestroy(payload);\r
277 \r
278     NS_LOG(DEBUG, "NSSendResponse - OUT");\r
279     return NS_OK;\r
280 }\r
281 \r
282 NSResult NSSendSubscriptionResponse(OCEntityHandlerRequest *entityHandlerRequest, bool accepted)\r
283 {\r
284     NS_LOG(DEBUG, "NSSendSubscriptionResponse - IN");\r
285 \r
286     if (!entityHandlerRequest)\r
287     {\r
288         NS_LOG(ERROR, "Invalid request pointer");\r
289         return OC_EH_ERROR;\r
290     }\r
291 \r
292     char * id = NSGetValueFromQuery(OICStrdup(entityHandlerRequest->query), NS_QUERY_CONSUMER_ID);\r
293 \r
294     if(!id)\r
295     {\r
296         NSFreeOCEntityHandlerRequest(entityHandlerRequest);\r
297         NS_LOG(ERROR, "Invalid ConsumerID");\r
298         return NS_ERROR;\r
299     }\r
300 \r
301     if (accepted)\r
302     {\r
303         NS_LOG(DEBUG, "accepted is true");\r
304         NSCacheElement * element = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement));\r
305         NSCacheSubData * subData = (NSCacheSubData *) OICMalloc(sizeof(NSCacheSubData));\r
306 \r
307         OICStrcpy(subData->id, UUID_STRING_SIZE, id);\r
308 \r
309         subData->isWhite = true;\r
310         subData->messageObId = entityHandlerRequest->obsInfo.obsId;\r
311 \r
312         element->data = (void*) subData;\r
313         element->next = NULL;\r
314 \r
315         if (NSStorageWrite(consumerSubList, element) != NS_OK)\r
316         {\r
317             NS_LOG(ERROR, "fail to write consumer white list");\r
318         }\r
319     }\r
320 \r
321     NSSendResponse(id, accepted);\r
322 \r
323     NSFreeOCEntityHandlerRequest(entityHandlerRequest);\r
324 \r
325     NS_LOG(DEBUG, "NSSendSubscriptionResponse - OUT");\r
326     return NS_OK;\r
327 }\r
328 \r
329 void * NSSubScriptionSchedule(void *ptr)\r
330 {\r
331     if (ptr == NULL)\r
332     {\r
333         NS_LOG(DEBUG, "Create NSSubScriptionSchedule");\r
334     }\r
335 \r
336     while (NSIsRunning[SUBSCRIPTION_SCHEDULER])\r
337     {\r
338         sem_wait(&NSSemaphore[SUBSCRIPTION_SCHEDULER]);\r
339         pthread_mutex_lock(&NSMutex[SUBSCRIPTION_SCHEDULER]);\r
340 \r
341         if (NSHeadMsg[SUBSCRIPTION_SCHEDULER] != NULL)\r
342         {\r
343             NSTask *node = NSHeadMsg[SUBSCRIPTION_SCHEDULER];\r
344             NSHeadMsg[SUBSCRIPTION_SCHEDULER] = node->nextTask;\r
345 \r
346             switch (node->taskType)\r
347             {\r
348                 case TASK_SEND_POLICY:\r
349                     NS_LOG(DEBUG, "CASE TASK_SEND_POLICY : ");\r
350                     NSSendAccessPolicyResponse((OCEntityHandlerRequest*) node->taskData);\r
351                     break;\r
352 \r
353                 case TASK_RECV_SUBSCRIPTION:\r
354                     NS_LOG(DEBUG, "CASE TASK_RECV_SUBSCRIPTION : ");\r
355                     NSHandleSubscription((OCEntityHandlerRequest*) node->taskData,\r
356                             NS_RESOURCE_MESSAGE);\r
357                     break;\r
358 \r
359                 case TASK_RECV_UNSUBSCRIPTION:\r
360                     NS_LOG(DEBUG, "CASE TASK_RECV_UNSUBSCRIPTION : ");\r
361                     NSHandleUnsubscription((OCEntityHandlerRequest*) node->taskData);\r
362                     break;\r
363 \r
364                 case TASK_SEND_ALLOW:\r
365                 {\r
366                     NS_LOG(DEBUG, "CASE TASK_SEND_ALLOW : ");\r
367                     NSConsumer * consumer = (NSConsumer *) node->taskData;\r
368 \r
369                     NSCacheUpdateSubScriptionState(consumerSubList, consumer->consumerId, true);\r
370                     NSSendResponse(consumer->consumerId, true);\r
371                     NSFreeConsumer(consumer);\r
372                     break;\r
373                 }\r
374                 case TASK_SEND_DENY:\r
375                 {\r
376                     NS_LOG(DEBUG, "CASE TASK_SEND_DENY : ");\r
377                     NSConsumer * consumer = (NSConsumer *) node->taskData;\r
378 \r
379                     NSCacheUpdateSubScriptionState(consumerSubList, consumer->consumerId, false);\r
380                     NSSendResponse(consumer->consumerId, false);\r
381                     NSFreeConsumer(consumer);\r
382 \r
383                     break;\r
384                 }\r
385                 case TASK_SYNC_SUBSCRIPTION:\r
386                     NS_LOG(DEBUG, "CASE TASK_SYNC_SUBSCRIPTION : ");\r
387                     NSHandleSubscription((OCEntityHandlerRequest*) node->taskData,\r
388                             NS_RESOURCE_SYNC);\r
389                     break;\r
390                 default:\r
391                     break;\r
392 \r
393             }\r
394             OICFree(node);\r
395         }\r
396 \r
397         pthread_mutex_unlock(&NSMutex[SUBSCRIPTION_SCHEDULER]);\r
398 \r
399     }\r
400     NS_LOG(INFO, "Destroy NSSubScriptionSchedule");\r
401     return NULL;\r
402 }\r