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