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