add deregister of observe and delete subscription list from observeid
[platform/upstream/iotivity.git] / service / notification / src / provider / NSProviderListener.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 "NSProviderListener.h"\r
22 \r
23 OCEntityHandlerResult NSEntityHandlerNotificationCb(OCEntityHandlerFlag flag,\r
24         OCEntityHandlerRequest *entityHandlerRequest, void* callback)\r
25 {\r
26     NS_LOG(DEBUG, "NSEntityHandlerNotificationCb - IN");\r
27 \r
28     OCEntityHandlerResult ehResult = OC_EH_OK;\r
29     OCEntityHandlerResponse response =\r
30     { 0, 0, OC_EH_ERROR, 0, 0,\r
31     { },\r
32     { 0 }, false };\r
33 \r
34     (void)callback;\r
35 \r
36     // Validate pointer\r
37     if (!entityHandlerRequest)\r
38     {\r
39         NS_LOG(ERROR, "Invalid request pointer");\r
40         return OC_EH_ERROR;\r
41     }\r
42 \r
43     // Initialize certain response fields\r
44     response.numSendVendorSpecificHeaderOptions = 0;\r
45     memset(response.sendVendorSpecificHeaderOptions, 0,\r
46             sizeof response.sendVendorSpecificHeaderOptions);\r
47     memset(response.resourceUri, 0, sizeof response.resourceUri);\r
48     OCRepPayload* payload = NULL;\r
49 \r
50     if (flag & OC_REQUEST_FLAG)\r
51     {\r
52         NS_LOG(DEBUG, "Flag includes OC_REQUEST_FLAG");\r
53 \r
54         if (OC_REST_GET == entityHandlerRequest->method)\r
55         {\r
56             NS_LOG(DEBUG, "NSEntityHandlerNotificationCb - OC_REST_GET");\r
57 \r
58             NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_SEND_POLICY,\r
59                     NSCopyOCEntityHandlerRequest(entityHandlerRequest));\r
60             ehResult = OC_EH_OK;\r
61 \r
62         }\r
63         else if (OC_REST_PUT == entityHandlerRequest->method)\r
64         {\r
65             NS_LOG(DEBUG, "NSEntityHandlerNotificationCb - OC_REST_PUT");\r
66             ehResult = OC_EH_OK;\r
67         }\r
68         else if (OC_REST_POST == entityHandlerRequest->method)\r
69         {\r
70             NS_LOG(DEBUG, "NSEntityHandlerNotificationCb - OC_REST_POST");\r
71             ehResult = OC_EH_OK;\r
72         }\r
73         else if (OC_REST_DELETE == entityHandlerRequest->method)\r
74         {\r
75             NS_LOG(DEBUG, "NSEntityHandlerNotificationCb - OC_REST_DELETE");\r
76             ehResult = OC_EH_OK;\r
77         }\r
78         else\r
79         {\r
80             NS_LOG_V (DEBUG, "Received unsupported method %d from client",\r
81                     entityHandlerRequest->method);\r
82             ehResult = OC_EH_OK;\r
83         }\r
84 \r
85         // If the result isn't an error or forbidden, send response\r
86         if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))\r
87         {\r
88             // Format the response.  Note this requires some info about the request\r
89             response.requestHandle = entityHandlerRequest->requestHandle;\r
90             response.resourceHandle = entityHandlerRequest->resource;\r
91             response.ehResult = ehResult;\r
92             //response.payload = reinterpret_cast<OCPayload*>(payload);\r
93             response.payload = (OCPayload*) payload;\r
94             // Indicate that response is NOT in a persistent buffer\r
95             response.persistentBufferFlag = 0;\r
96 \r
97             // Handle vendor specific options\r
98             if (entityHandlerRequest->rcvdVendorSpecificHeaderOptions\r
99                     && entityHandlerRequest->numRcvdVendorSpecificHeaderOptions)\r
100             {\r
101                 NS_LOG (DEBUG, "Received vendor specific options");\r
102                 uint8_t i = 0;\r
103                 OCHeaderOption * rcvdOptions = entityHandlerRequest->rcvdVendorSpecificHeaderOptions;\r
104                 for (i = 0; i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions; i++)\r
105                 {\r
106                     if (((OCHeaderOption) rcvdOptions[i]).protocolID == OC_COAP_ID)\r
107                     {\r
108                         OIC_LOG_V(DEBUG, LISTENER_TAG, "Received option with OC_COAP_ID and ID %u with",\r
109                                 ((OCHeaderOption)rcvdOptions[i]).optionID );\r
110 \r
111                         OIC_LOG_BUFFER(DEBUG, LISTENER_TAG, ((OCHeaderOption)rcvdOptions[i]).optionData,\r
112                                 MAX_HEADER_OPTION_DATA_LENGTH);\r
113                     }\r
114                 }\r
115                 OCHeaderOption * sendOptions = response.sendVendorSpecificHeaderOptions;\r
116                 uint8_t option2[] =\r
117                 { 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 };\r
118                 uint8_t option3[] =\r
119                 { 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 };\r
120                 sendOptions[0].protocolID = OC_COAP_ID;\r
121                 sendOptions[0].optionID = 2248;\r
122                 memcpy(sendOptions[0].optionData, option2, sizeof(option2));\r
123                 sendOptions[0].optionLength = 10;\r
124                 sendOptions[1].protocolID = OC_COAP_ID;\r
125                 sendOptions[1].optionID = 2600;\r
126                 memcpy(sendOptions[1].optionData, option3, sizeof(option3));\r
127                 sendOptions[1].optionLength = 10;\r
128                 response.numSendVendorSpecificHeaderOptions = 2;\r
129             }\r
130         }\r
131     }\r
132 \r
133     OCPayloadDestroy(response.payload);\r
134     NS_LOG(DEBUG, "NSEntityHandlerNotificationCb - OUT");\r
135     return ehResult;\r
136 }\r
137 \r
138 OCEntityHandlerResult NSEntityHandlerMessageCb(OCEntityHandlerFlag flag,\r
139         OCEntityHandlerRequest *entityHandlerRequest, void* callback)\r
140 {\r
141     NS_LOG(DEBUG, "NSEntityHandlerMessageCb - IN");\r
142 \r
143     OCEntityHandlerResult ehResult = OC_EH_OK;\r
144     OCEntityHandlerResponse response =\r
145     { 0, 0, OC_EH_ERROR, 0, 0,\r
146     { },\r
147     { 0 }, false };\r
148 \r
149     (void)callback;\r
150 \r
151     // Validate pointer\r
152     if (!entityHandlerRequest)\r
153     {\r
154         NS_LOG (ERROR,"Invalid request pointer");\r
155         return OC_EH_ERROR;\r
156     }\r
157 \r
158     // Initialize certain response fields\r
159     response.numSendVendorSpecificHeaderOptions = 0;\r
160     memset(response.sendVendorSpecificHeaderOptions, 0,\r
161             sizeof response.sendVendorSpecificHeaderOptions);\r
162     memset(response.resourceUri, 0, sizeof response.resourceUri);\r
163     OCRepPayload* payload = NULL;\r
164 \r
165     if (flag & OC_REQUEST_FLAG)\r
166     {\r
167         NS_LOG(DEBUG, "Flag includes OC_REQUEST_FLAG");\r
168 \r
169         if (OC_REST_GET == entityHandlerRequest->method)\r
170         {\r
171             NS_LOG(DEBUG, "NSEntityHandlerMessageCb - OC_REST_GET");\r
172             ehResult = OC_EH_OK;\r
173         }\r
174         else if (OC_REST_PUT == entityHandlerRequest->method)\r
175         {\r
176             NS_LOG(DEBUG, "NSEntityHandlerMessageCb - OC_REST_PUT");\r
177             ehResult = OC_EH_OK;\r
178         }\r
179         else if (OC_REST_POST == entityHandlerRequest->method)\r
180         {\r
181             NS_LOG(DEBUG, "NSEntityHandlerMessageCb - OC_REST_POST");\r
182             ehResult = OC_EH_OK;\r
183         }\r
184         else if (OC_REST_DELETE == entityHandlerRequest->method)\r
185         {\r
186             NS_LOG(DEBUG, "NSEntityHandlerMessageCb - OC_REST_DELETE");\r
187             ehResult = OC_EH_OK;\r
188         }\r
189         else\r
190         {\r
191             NS_LOG_V(DEBUG, "Received unsupported method %d from client",\r
192                     entityHandlerRequest->method);\r
193             ehResult = OC_EH_OK;\r
194         }\r
195 \r
196         // If the result isn't an error or forbidden, send response\r
197         if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))\r
198         {\r
199             // Format the response.  Note this requires some info about the request\r
200             response.requestHandle = entityHandlerRequest->requestHandle;\r
201             response.resourceHandle = entityHandlerRequest->resource;\r
202             response.ehResult = ehResult;\r
203             //response.payload = reinterpret_cast<OCPayload*>(payload);\r
204             response.payload = (OCPayload*) payload;\r
205             // Indicate that response is NOT in a persistent buffer\r
206             response.persistentBufferFlag = 0;\r
207 \r
208             // Handle vendor specific options\r
209             if (entityHandlerRequest->rcvdVendorSpecificHeaderOptions\r
210                     && entityHandlerRequest->numRcvdVendorSpecificHeaderOptions)\r
211             {\r
212                 NS_LOG(DEBUG, "Received vendor specific options");\r
213                 uint8_t i = 0;\r
214                 OCHeaderOption * rcvdOptions = entityHandlerRequest->rcvdVendorSpecificHeaderOptions;\r
215                 for (i = 0; i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions; i++)\r
216                 {\r
217                     if (((OCHeaderOption) rcvdOptions[i]).protocolID == OC_COAP_ID)\r
218                     {\r
219                         OIC_LOG_V(DEBUG, LISTENER_TAG, "Received option with OC_COAP_ID and ID %u with",\r
220                                 ((OCHeaderOption)rcvdOptions[i]).optionID );\r
221 \r
222                         OIC_LOG_BUFFER(DEBUG, LISTENER_TAG, ((OCHeaderOption)rcvdOptions[i]).optionData,\r
223                                 MAX_HEADER_OPTION_DATA_LENGTH);\r
224                     }\r
225                 }\r
226                 OCHeaderOption * sendOptions = response.sendVendorSpecificHeaderOptions;\r
227                 uint8_t option2[] =\r
228                 { 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 };\r
229                 uint8_t option3[] =\r
230                 { 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 };\r
231                 sendOptions[0].protocolID = OC_COAP_ID;\r
232                 sendOptions[0].optionID = 2248;\r
233                 memcpy(sendOptions[0].optionData, option2, sizeof(option2));\r
234                 sendOptions[0].optionLength = 10;\r
235                 sendOptions[1].protocolID = OC_COAP_ID;\r
236                 sendOptions[1].optionID = 2600;\r
237                 memcpy(sendOptions[1].optionData, option3, sizeof(option3));\r
238                 sendOptions[1].optionLength = 10;\r
239                 response.numSendVendorSpecificHeaderOptions = 2;\r
240             }\r
241         }\r
242     }\r
243 \r
244     if (flag & OC_OBSERVE_FLAG)\r
245     {\r
246         NS_LOG(DEBUG, "NSEntityHandlerMessageCb - OC_OBSERVE_FLAG");\r
247 \r
248         OCObserveAction ocObAction = entityHandlerRequest->obsInfo.action;\r
249 \r
250         if (ocObAction == OC_OBSERVE_REGISTER)\r
251         {\r
252             NS_LOG(DEBUG, "NSEntityHandlerMessageCb - OC_OBSERVE_REGISTER");\r
253             NS_LOG_V(DEBUG, "NSEntityHandlerMessageCb\n"\r
254                     "Register message observerID : %d\n", entityHandlerRequest->obsInfo.obsId);\r
255             NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_RECV_SUBSCRIPTION,\r
256                     NSCopyOCEntityHandlerRequest(entityHandlerRequest));\r
257         }\r
258         else if(ocObAction == OC_OBSERVE_DEREGISTER)\r
259         {\r
260             NS_LOG(DEBUG, "NSEntityHandlerMessageCb - OC_OBSERVE_DEREGISTER");\r
261             NS_LOG_V(DEBUG, "NSEntityHandlerMessageCb\n - "\r
262                     "Deregister Message observerID : %d\n", entityHandlerRequest->obsInfo.obsId);\r
263             NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_RECV_UNSUBSCRIPTION,\r
264                     NSCopyOCEntityHandlerRequest(entityHandlerRequest));\r
265         }\r
266     }\r
267 \r
268     OCPayloadDestroy(response.payload);\r
269     NS_LOG(DEBUG, "NSEntityHandlerMessageCb - OUT");\r
270     return ehResult;\r
271 }\r
272 \r
273 OCEntityHandlerResult NSEntityHandlerSyncCb(OCEntityHandlerFlag flag,\r
274         OCEntityHandlerRequest *entityHandlerRequest, void* callback)\r
275 {\r
276     NS_LOG(DEBUG, "NSEntityHandlerSyncCb - IN");\r
277     OCEntityHandlerResult ehResult = OC_EH_OK;\r
278     OCEntityHandlerResponse response =\r
279     { 0, 0, OC_EH_ERROR, 0, 0,\r
280     { },\r
281     { 0 }, false };\r
282 \r
283     (void)callback;\r
284 \r
285     // Validate pointer\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     // Initialize certain response fields\r
293     response.numSendVendorSpecificHeaderOptions = 0;\r
294     memset(response.sendVendorSpecificHeaderOptions, 0,\r
295             sizeof response.sendVendorSpecificHeaderOptions);\r
296     memset(response.resourceUri, 0, sizeof response.resourceUri);\r
297     OCRepPayload* payload = NULL;\r
298 \r
299     if (flag & OC_REQUEST_FLAG)\r
300     {\r
301         NS_LOG(DEBUG, "Flag includes OC_REQUEST_FLAG");\r
302 \r
303         if (OC_REST_GET == entityHandlerRequest->method)\r
304         {\r
305             NS_LOG(DEBUG, "NSEntityHandlerSyncCb - OC_REST_GET");\r
306             ehResult = OC_EH_OK;\r
307         }\r
308         else if (OC_REST_PUT == entityHandlerRequest->method)\r
309         {\r
310             NS_LOG(DEBUG, "NSEntityHandlerSyncCb - OC_REST_PUT");\r
311             ehResult = OC_EH_OK;\r
312         }\r
313         else if (OC_REST_POST == entityHandlerRequest->method)\r
314         {\r
315             /** Receive sync data from consumer which read or dismiss notification message.\r
316                            And broadcast the sync data to all subscribers including provider app\r
317                            to synchronize the notification message status. */\r
318 \r
319             NS_LOG(DEBUG, "NSEntityHandlerSyncCb - OC_REST_POST");\r
320 \r
321             NSPushQueue(NOTIFICATION_SCHEDULER, TASK_RECV_READ,\r
322                     NSGetSyncInfo(entityHandlerRequest->payload));\r
323             ehResult = OC_EH_OK;\r
324         }\r
325         else if (OC_REST_DELETE == entityHandlerRequest->method)\r
326         {\r
327             NS_LOG(DEBUG, "Received OC_REST_DELETE from client");\r
328             ehResult = OC_EH_OK;\r
329         }\r
330         else\r
331         {\r
332             NS_LOG_V(DEBUG, "Received unsupported method %d from client",\r
333                     entityHandlerRequest->method);\r
334             ehResult = OC_EH_OK;\r
335         }\r
336 \r
337         // If the result isn't an error or forbidden, send response\r
338         if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))\r
339         {\r
340             // Format the response.  Note this requires some info about the request\r
341             response.requestHandle = entityHandlerRequest->requestHandle;\r
342             response.resourceHandle = entityHandlerRequest->resource;\r
343             response.ehResult = ehResult;\r
344             //response.payload = reinterpret_cast<OCPayload*>(payload);\r
345             response.payload = (OCPayload*) payload;\r
346             // Indicate that response is NOT in a persistent buffer\r
347             response.persistentBufferFlag = 0;\r
348 \r
349             // Handle vendor specific options\r
350             if (entityHandlerRequest->rcvdVendorSpecificHeaderOptions\r
351                     && entityHandlerRequest->numRcvdVendorSpecificHeaderOptions)\r
352             {\r
353                 NS_LOG(DEBUG, "Received vendor specific options");\r
354                 uint8_t i = 0;\r
355                 OCHeaderOption * rcvdOptions = entityHandlerRequest->rcvdVendorSpecificHeaderOptions;\r
356                 for (i = 0; i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions; i++)\r
357                 {\r
358                     if (((OCHeaderOption) rcvdOptions[i]).protocolID == OC_COAP_ID)\r
359                     {\r
360                         OIC_LOG_V(DEBUG, LISTENER_TAG, "Received option with OC_COAP_ID and ID %u with",\r
361                                 ((OCHeaderOption)rcvdOptions[i]).optionID );\r
362 \r
363                         OIC_LOG_BUFFER(DEBUG, LISTENER_TAG, ((OCHeaderOption)rcvdOptions[i]).optionData,\r
364                                 MAX_HEADER_OPTION_DATA_LENGTH);\r
365                     }\r
366                 }\r
367                 OCHeaderOption * sendOptions = response.sendVendorSpecificHeaderOptions;\r
368                 uint8_t option2[] =\r
369                 { 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 };\r
370                 uint8_t option3[] =\r
371                 { 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 };\r
372                 sendOptions[0].protocolID = OC_COAP_ID;\r
373                 sendOptions[0].optionID = 2248;\r
374                 memcpy(sendOptions[0].optionData, option2, sizeof(option2));\r
375                 sendOptions[0].optionLength = 10;\r
376                 sendOptions[1].protocolID = OC_COAP_ID;\r
377                 sendOptions[1].optionID = 2600;\r
378                 memcpy(sendOptions[1].optionData, option3, sizeof(option3));\r
379                 sendOptions[1].optionLength = 10;\r
380                 response.numSendVendorSpecificHeaderOptions = 2;\r
381             }\r
382         }\r
383     }\r
384 \r
385     if (flag & OC_OBSERVE_FLAG)\r
386     {\r
387         /** Requested by consumers to synchronize notification message status.\r
388             Store the observer IDs to storage or cache */\r
389 \r
390         NS_LOG(DEBUG, "NSEntityHandlerSyncCb - OC_OBSERVE_FLAG");\r
391 \r
392 \r
393         OCObserveAction ocObAction = entityHandlerRequest->obsInfo.action;\r
394 \r
395         if (ocObAction == OC_OBSERVE_REGISTER)\r
396         {\r
397             NS_LOG(DEBUG, "NSEntityHandlerSyncCb - OC_OBSERVE_REGISTER");\r
398             NS_LOG_V(DEBUG, "NSEntityHandlerSyncCb\n - "\r
399                     "Register Sync observerID : %d\n", entityHandlerRequest->obsInfo.obsId);\r
400             NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_SYNC_SUBSCRIPTION,\r
401                     NSCopyOCEntityHandlerRequest(entityHandlerRequest));\r
402         }\r
403         else if(ocObAction == OC_OBSERVE_DEREGISTER)\r
404         {\r
405             NS_LOG(DEBUG, "NSEntityHandlerSyncCb - OC_OBSERVE_DEREGISTER");\r
406             NS_LOG_V(DEBUG, "NSEntityHandlerSyncCb\n - "\r
407                     "Deregister Sync observerID : %d\n", entityHandlerRequest->obsInfo.obsId);\r
408             NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_RECV_UNSUBSCRIPTION,\r
409                     NSCopyOCEntityHandlerRequest(entityHandlerRequest));\r
410         }\r
411     }\r
412 \r
413     OCPayloadDestroy(response.payload);\r
414     NS_LOG(DEBUG, "NSEntityHandlerSyncCb - OUT");\r
415     return ehResult;\r
416 }\r
417 \r
418 void NSProviderConnectionStateListener(const CAEndpoint_t * info, bool connected)\r
419 {\r
420 \r
421     NS_LOG(DEBUG, "NSProviderConnectionStateListener - IN");\r
422 \r
423     if (connected)\r
424     {\r
425         NS_LOG(DEBUG, "CONNECTED");\r
426 \r
427         // Set Connection State\r
428         NSSetProviderConnectionState(CONNECTED);\r
429 \r
430         // Start Presence\r
431         NSPushQueue(DISCOVERY_SCHEDULER, TASK_START_PRESENCE, NULL);\r
432 \r
433         if(info->adapter == CA_ADAPTER_TCP)\r
434         {\r
435             NS_LOG_V(DEBUG, "TCP Connected remote address: %s:%d", info->addr, info->port);\r
436         }\r
437     }\r
438     else\r
439     {\r
440 \r
441         NS_LOG(DEBUG, "DISCONNECTED");\r
442 \r
443         // Set Connection State\r
444         NSSetProviderConnectionState(DISCONNECTED);\r
445 \r
446         if(info->adapter == CA_ADAPTER_TCP)\r
447         {\r
448             NS_LOG_V(DEBUG, "TCP Disconnected remote address: %s:%d", info->addr, info->port);\r
449         }\r
450     }\r
451 \r
452     NS_LOG(DEBUG, "NSProviderConnectionStateListener - OUT");\r
453 }\r
454 \r
455 void NSProviderAdapterStateListener(CATransportAdapter_t adapter, bool enabled)\r
456 {\r
457     (void)adapter;\r
458 \r
459     NS_LOG(DEBUG, "NSProviderAdapterStateListener - IN");\r
460 \r
461     if (enabled)\r
462     {\r
463         NS_LOG(DEBUG, "CONNECTED");\r
464 \r
465         // Set Connection State\r
466         NSSetProviderConnectionState(CONNECTED);\r
467 \r
468         // Start Presence\r
469         NSPushQueue(DISCOVERY_SCHEDULER, TASK_START_PRESENCE, NULL);\r
470     }\r
471     else\r
472     {\r
473 \r
474         NS_LOG(DEBUG, "DISCONNECTED");\r
475 \r
476         // Set Connection State\r
477         NSSetProviderConnectionState(DISCONNECTED);\r
478     }\r
479 \r
480     NS_LOG(DEBUG, "NSProviderAdapterStateListener - OUT");\r
481 }\r
482 \r