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