Update snapshot(2017-12-06)
[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 bool NSProviderIsSyncAttributes(OCRepPayload * payload);\r
24 bool NSProviderIsTopicAttributes(OCRepPayload * payload);\r
25 OCStackResult NSProviderSendResponse(OCEntityHandlerRequest * entityHandlerRequest,\r
26         OCRepPayload * payload, char * reqInterface, OCEntityHandlerResult ehResult,\r
27         NSInterfaceType interfaceType, NSResourceType resourceType);\r
28 \r
29 OCEntityHandlerResult NSEntityHandlerNotificationCb(OCEntityHandlerFlag flag,\r
30         OCEntityHandlerRequest *entityHandlerRequest, void* callback)\r
31 {\r
32     NS_LOG(DEBUG, "NSEntityHandlerNotificationCb - IN");\r
33 \r
34     OCEntityHandlerResult ehResult = OC_EH_ERROR;\r
35 \r
36     (void)callback;\r
37 \r
38     if (!entityHandlerRequest)\r
39     {\r
40         NS_LOG(ERROR, "Invalid request pointer");\r
41         return ehResult;\r
42     }\r
43 \r
44     if (flag & OC_REQUEST_FLAG)\r
45     {\r
46         NS_LOG(DEBUG, "Flag includes OC_REQUEST_FLAG");\r
47 \r
48         if (OC_REST_GET == entityHandlerRequest->method)\r
49         {\r
50             NS_LOG(DEBUG, "NSEntityHandlerNotificationCb - OC_REST_GET");\r
51 \r
52             char * copyQuery = OICStrdup(entityHandlerRequest->query);\r
53             char * reqInterface = NSGetValueFromQuery(copyQuery, NS_QUERY_INTERFACE);\r
54 \r
55             if (reqInterface && strcmp(reqInterface, NS_INTERFACE_BASELINE) != 0\r
56                     && strcmp(reqInterface, NS_INTERFACE_READ) != 0)\r
57             {\r
58                 NS_LOG(ERROR, "Invalid interface");\r
59                 NSOICFree(copyQuery);\r
60                 return ehResult;\r
61             }\r
62 \r
63             NSOICFree(copyQuery);\r
64             NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_SEND_POLICY,\r
65                     NSCopyOCEntityHandlerRequest(entityHandlerRequest));\r
66 \r
67             ehResult = OC_EH_OK;\r
68         }\r
69         else\r
70         {\r
71             NS_LOG_V (DEBUG, "Received method %d from client", entityHandlerRequest->method);\r
72         }\r
73     }\r
74 \r
75     NS_LOG(DEBUG, "NSEntityHandlerNotificationCb - OUT");\r
76     return ehResult;\r
77 }\r
78 \r
79 OCEntityHandlerResult NSEntityHandlerMessageCb(OCEntityHandlerFlag flag,\r
80         OCEntityHandlerRequest *entityHandlerRequest, void* callback)\r
81 {\r
82     NS_LOG(DEBUG, "NSEntityHandlerMessageCb - IN");\r
83 \r
84     OCEntityHandlerResult ehResult = OC_EH_ERROR;\r
85     char * reqInterface = NULL;\r
86     OCRepPayload * payload = NULL;\r
87 \r
88     (void)callback;\r
89 \r
90     if (!entityHandlerRequest)\r
91     {\r
92         NS_LOG (ERROR,"Invalid request pointer");\r
93         return ehResult;\r
94     }\r
95 \r
96     if (flag & OC_REQUEST_FLAG)\r
97     {\r
98         NS_LOG(DEBUG, "Flag includes OC_REQUEST_FLAG");\r
99         NS_LOG_V(DEBUG, "Received method %d from client", entityHandlerRequest->method);\r
100 \r
101         if (OC_REST_GET == entityHandlerRequest->method)\r
102         {\r
103             NS_LOG(DEBUG, "NSEntityHandlerMessageCb - OC_REST_GET");\r
104 \r
105             char * copyQuery = OICStrdup(entityHandlerRequest->query);\r
106             reqInterface = OICStrdup(NSGetValueFromQuery(copyQuery, NS_QUERY_INTERFACE));\r
107             NSOICFree(copyQuery);\r
108 \r
109             if (reqInterface && strcmp(reqInterface, NS_INTERFACE_BASELINE) != 0\r
110                     && strcmp(reqInterface, NS_INTERFACE_READ) != 0)\r
111             {\r
112                 NS_LOG(ERROR, "Invalid interface");\r
113                 return ehResult;\r
114             }\r
115             ehResult = OC_EH_OK;\r
116         }\r
117         else\r
118         {\r
119             NS_LOG_V (DEBUG, "Received method %d from client", entityHandlerRequest->method);\r
120         }\r
121     }\r
122 \r
123     if (flag & OC_OBSERVE_FLAG)\r
124     {\r
125         NS_LOG(DEBUG, "NSEntityHandlerMessageCb - OC_OBSERVE_FLAG");\r
126 \r
127         OCObserveAction ocObAction = entityHandlerRequest->obsInfo.action;\r
128 \r
129         if (ocObAction == OC_OBSERVE_REGISTER)\r
130         {\r
131             NS_LOG(DEBUG, "NSEntityHandlerMessageCb - OC_OBSERVE_REGISTER");\r
132             NS_LOG_V(DEBUG, "NSEntityHandlerMessageCb\n"\r
133                     "Register message observerID : %d\n", entityHandlerRequest->obsInfo.obsId);\r
134 \r
135             NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_RECV_SUBSCRIPTION,\r
136                     NSCopyOCEntityHandlerRequest(entityHandlerRequest));\r
137             ehResult = OC_EH_OK;\r
138         }\r
139         else if (ocObAction == OC_OBSERVE_DEREGISTER)\r
140         {\r
141             NS_LOG(DEBUG, "NSEntityHandlerMessageCb - OC_OBSERVE_DEREGISTER");\r
142             NS_LOG_V(DEBUG, "NSEntityHandlerMessageCb\n - "\r
143                     "Deregister Message observerID : %d\n", entityHandlerRequest->obsInfo.obsId);\r
144             NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_RECV_UNSUBSCRIPTION,\r
145                     NSCopyOCEntityHandlerRequest(entityHandlerRequest));\r
146             ehResult = OC_EH_OK;\r
147         }\r
148     }\r
149 \r
150     ehResult = NSProviderSendResponse(entityHandlerRequest, payload, reqInterface, ehResult,\r
151             NS_INTERFACE_TYPE_READ, NS_RESOURCE_MESSAGE);\r
152     NSOICFree(reqInterface);\r
153     NS_LOG(DEBUG, "NSEntityHandlerMessageCb - OUT");\r
154     return ehResult;\r
155 }\r
156 \r
157 OCEntityHandlerResult NSEntityHandlerSyncCb(OCEntityHandlerFlag flag,\r
158         OCEntityHandlerRequest *entityHandlerRequest, void* callback)\r
159 {\r
160     NS_LOG(DEBUG, "NSEntityHandlerSyncCb - IN");\r
161     OCEntityHandlerResult ehResult = OC_EH_ERROR;\r
162     char * reqInterface = NULL;\r
163     OCRepPayload * payload = NULL;\r
164 \r
165     (void)callback;\r
166 \r
167     if (!entityHandlerRequest)\r
168     {\r
169         NS_LOG(ERROR, "Invalid request pointer");\r
170         return ehResult;\r
171     }\r
172 \r
173     if (flag & OC_REQUEST_FLAG)\r
174     {\r
175         NS_LOG(DEBUG, "Flag includes OC_REQUEST_FLAG");\r
176 \r
177         if (OC_REST_GET == entityHandlerRequest->method)\r
178         {\r
179 \r
180             char * copyQuery = OICStrdup(entityHandlerRequest->query);\r
181             reqInterface = OICStrdup(NSGetValueFromQuery(copyQuery, NS_QUERY_INTERFACE));\r
182             NSOICFree(copyQuery);\r
183 \r
184             if (reqInterface && strcmp(reqInterface, NS_INTERFACE_BASELINE) != 0\r
185                     && strcmp(reqInterface, NS_INTERFACE_READWRITE) != 0)\r
186             {\r
187                 NS_LOG(ERROR, "Invalid interface");\r
188                 return ehResult;\r
189             }\r
190 \r
191             ehResult = OC_EH_OK;\r
192         }\r
193         else if (OC_REST_POST == entityHandlerRequest->method)\r
194         {\r
195             /** Receive sync data from consumer which read or dismiss notification message.\r
196                 And broadcast the sync data to all subscribers including provider app\r
197                 to synchronize the notification message status. */\r
198 \r
199             NS_LOG(DEBUG, "NSEntityHandlerSyncCb - OC_REST_POST");\r
200 \r
201             if (NSProviderIsSyncAttributes((OCRepPayload *)entityHandlerRequest->payload))\r
202             {\r
203                 NSPushQueue(NOTIFICATION_SCHEDULER, TASK_RECV_READ,\r
204                                     NSGetSyncInfo(entityHandlerRequest->payload));\r
205                 ehResult = OC_EH_OK;\r
206             }\r
207         }\r
208         else\r
209         {\r
210             NS_LOG_V(DEBUG, "Received method %d from client", entityHandlerRequest->method);\r
211         }\r
212     }\r
213 \r
214     if (flag & OC_OBSERVE_FLAG)\r
215     {\r
216         /** Requested by consumers to synchronize notification message status.\r
217             Store the observer IDs to storage or cache */\r
218 \r
219         NS_LOG(DEBUG, "NSEntityHandlerSyncCb - OC_OBSERVE_FLAG");\r
220 \r
221         OCObserveAction ocObAction = entityHandlerRequest->obsInfo.action;\r
222 \r
223         if (ocObAction == OC_OBSERVE_REGISTER)\r
224         {\r
225             NS_LOG(DEBUG, "NSEntityHandlerSyncCb - OC_OBSERVE_REGISTER");\r
226             NS_LOG_V(DEBUG, "NSEntityHandlerSyncCb\n - "\r
227                     "Register Sync observerID : %d\n", entityHandlerRequest->obsInfo.obsId);\r
228             NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_SYNC_SUBSCRIPTION,\r
229                     NSCopyOCEntityHandlerRequest(entityHandlerRequest));\r
230         }\r
231         else if (ocObAction == OC_OBSERVE_DEREGISTER)\r
232         {\r
233             NS_LOG(DEBUG, "NSEntityHandlerSyncCb - OC_OBSERVE_DEREGISTER");\r
234             NS_LOG_V(DEBUG, "NSEntityHandlerSyncCb\n - "\r
235                     "Deregister Sync observerID : %d\n", entityHandlerRequest->obsInfo.obsId);\r
236             NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_RECV_UNSUBSCRIPTION,\r
237                     NSCopyOCEntityHandlerRequest(entityHandlerRequest));\r
238         }\r
239     }\r
240 \r
241     NS_LOG(DEBUG, "NSEntityHandlerSyncCb - OUT");\r
242 \r
243     ehResult = NSProviderSendResponse(entityHandlerRequest, payload, reqInterface, ehResult,\r
244             NS_INTERFACE_TYPE_READ, NS_RESOURCE_MESSAGE);\r
245     NSOICFree(reqInterface);\r
246 \r
247     return ehResult;\r
248 }\r
249 \r
250 OCEntityHandlerResult NSEntityHandlerTopicCb(OCEntityHandlerFlag flag,\r
251         OCEntityHandlerRequest *entityHandlerRequest, void* callback)\r
252 {\r
253     NS_LOG(DEBUG, "NSEntityHandlerTopicCb - IN");\r
254     OCEntityHandlerResult ehResult = OC_EH_ERROR;\r
255     char * reqInterface = NULL;\r
256     OCRepPayload * payload = NULL;\r
257 \r
258     (void)callback;\r
259 \r
260     if (!entityHandlerRequest)\r
261     {\r
262         NS_LOG(ERROR, "Invalid request pointer");\r
263         return ehResult;\r
264     }\r
265 \r
266     if (flag & OC_REQUEST_FLAG)\r
267     {\r
268         NS_LOG(DEBUG, "Flag includes OC_REQUEST_FLAG");\r
269 \r
270         if (OC_REST_GET == entityHandlerRequest->method)\r
271         {\r
272             NS_LOG(DEBUG, "NSEntityHandlerTopicCb - OC_REST_GET");\r
273 \r
274             char * copyReq = OICStrdup(entityHandlerRequest->query);\r
275             reqInterface = OICStrdup(NSGetValueFromQuery(copyReq, NS_QUERY_INTERFACE));\r
276             NSOICFree(copyReq);\r
277 \r
278             if (reqInterface && strcmp(reqInterface, NS_INTERFACE_BASELINE) != 0\r
279                     && strcmp(reqInterface, NS_INTERFACE_READWRITE) != 0)\r
280             {\r
281                 NS_LOG(ERROR, "Invalid interface");\r
282                 return ehResult;\r
283             }\r
284             // send consumer's interesting topic list if consumer id exists\r
285             // otherwise send  registered topic list\r
286             NSPushQueue(TOPIC_SCHEDULER, TASK_SEND_TOPICS,\r
287                     NSCopyOCEntityHandlerRequest(entityHandlerRequest));\r
288 \r
289             ehResult = OC_EH_OK;\r
290         }\r
291         else if (OC_REST_POST == entityHandlerRequest->method)\r
292         {\r
293             // Receive interesting topic list from consumers\r
294             // Send topic notice message(id = TOPIC) to the consumer\r
295             // which requests to post.\r
296             NS_LOG(DEBUG, "NSEntityHandlerTopicCb - OC_REST_POST");\r
297             // Accepter is provider. our service is not support sendtopiclist from OC_REST_POST\r
298             // Accepter is consumer. our service is support sendtopiclist from OC_REST_POST\r
299             if (NSGetPolicy() == false &&\r
300                     NSProviderIsTopicAttributes(OCRepPayloadClone((OCRepPayload *)\r
301                             entityHandlerRequest->payload)))\r
302             {\r
303                 NSPushQueue(TOPIC_SCHEDULER, TASK_POST_TOPIC,\r
304                         NSCopyOCEntityHandlerRequest(entityHandlerRequest));\r
305                 ehResult = OC_EH_OK;\r
306             }\r
307         }\r
308         else\r
309         {\r
310             NS_LOG_V(DEBUG, "Received unsupported method %d from client",\r
311                     entityHandlerRequest->method);\r
312             ehResult = OC_EH_ERROR;\r
313         }\r
314     }\r
315 \r
316     NS_LOG(DEBUG, "NSEntityHandlerTopicCb - OUT");\r
317     ehResult = NSProviderSendResponse(entityHandlerRequest, payload, reqInterface, ehResult,\r
318             NS_INTERFACE_TYPE_READWRITE, NS_RESOURCE_TOPIC);\r
319     NSOICFree(reqInterface);\r
320     return ehResult;\r
321 }\r
322 \r
323 #ifdef WITH_MQ\r
324 OCStackApplicationResult NSProviderMQListener(void * ctx, OCDoHandle handle,\r
325         OCClientResponse * clientResponse)\r
326 {\r
327     (void) ctx;\r
328     (void) handle;\r
329 \r
330     NS_LOG_V(DEBUG, "clientResponse->sequenceNumber = %d", clientResponse->sequenceNumber);\r
331 \r
332     if (clientResponse->sequenceNumber == OC_OBSERVE_REGISTER)\r
333     {\r
334         NS_LOG(DEBUG, "MQ OC_OBSERVE_RIGSTER");\r
335         NSSetMQServerInfo(clientResponse->resourceUri, &(clientResponse->devAddr));\r
336     }\r
337 \r
338     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);\r
339     NS_VERIFY_STACK_SUCCESS(NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);\r
340     NS_VERIFY_NOT_NULL(clientResponse->payload, OC_STACK_KEEP_TRANSACTION);\r
341 \r
342     NS_LOG(DEBUG, "income observe response of MQ notification");\r
343     NS_LOG_V(INFO_PRIVATE, "MQ OBS response income : %s:%d",\r
344             clientResponse->devAddr.addr, clientResponse->devAddr.port);\r
345     NS_LOG_V(DEBUG, "MQ OBS response result : %d",\r
346             clientResponse->result);\r
347     NS_LOG_V(DEBUG, "MQ OBS response sequenceNum : %d",\r
348             clientResponse->sequenceNumber);\r
349     NS_LOG_V(DEBUG, "MQ OBS response resource uri : %s",\r
350             clientResponse->resourceUri);\r
351     NS_LOG_V(DEBUG, "MQ OBS response Transport Type : %d",\r
352                     clientResponse->devAddr.adapter);\r
353 \r
354     OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;\r
355     NS_VERIFY_NOT_NULL(payload, OC_STACK_KEEP_TRANSACTION);\r
356 \r
357     NSMessageType type = -1;\r
358     bool getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_TYPE, (int64_t *) &type);\r
359     NS_LOG_V (DEBUG, "message sync type : %d", (int) type);\r
360 \r
361     if (!getResult && (type == NS_MESSAGE_READ || type == NS_MESSAGE_DELETED))\r
362     {\r
363         char * pId = NULL;\r
364         getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, &pId);\r
365         NS_LOG_V (INFO_PRIVATE, "provider id: %s", pId);\r
366 \r
367         if (getResult && strcmp(pId, NSGetProviderInfo()->providerId) == 0)\r
368         {\r
369             NSSyncInfo * syncInfo = (NSSyncInfo *)OICMalloc(sizeof(NSSyncInfo));\r
370             syncInfo->state = (type == NS_MESSAGE_READ) ? NS_SYNC_READ : NS_SYNC_DELETED;\r
371             OICStrcpy(syncInfo->providerId, NS_UUID_STRING_SIZE, pId);\r
372             NSOICFree(pId);\r
373             NSPushQueue(NOTIFICATION_SCHEDULER, TASK_RECV_READ, (void*) syncInfo);\r
374         }\r
375     }\r
376 \r
377     return OC_STACK_KEEP_TRANSACTION;\r
378 }\r
379 \r
380 OCStackApplicationResult NSProviderGetMQResponseCB(void * ctx, OCDoHandle handle,\r
381         OCClientResponse * clientResponse)\r
382 {\r
383     NS_LOG(DEBUG, "NSProviderGetMQResponseCB - IN");\r
384 \r
385     (void) handle;\r
386 \r
387     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);\r
388     NS_VERIFY_STACK_SUCCESS(NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);\r
389     NS_VERIFY_NOT_NULL(clientResponse->payload, OC_STACK_KEEP_TRANSACTION);\r
390 \r
391     NS_LOG(DEBUG, "income get response of MQ broker");\r
392     NS_LOG_V(INFO_PRIVATE, "MQ GET response income : %s:%d",\r
393             clientResponse->devAddr.addr, clientResponse->devAddr.port);\r
394     NS_LOG_V(DEBUG, "MQ GET response result : %d",\r
395             clientResponse->result);\r
396     NS_LOG_V(DEBUG, "MQ GET response sequenceNum : %d",\r
397             clientResponse->sequenceNumber);\r
398     NS_LOG_V(DEBUG, "MQ GET response resource uri : %s",\r
399             clientResponse->resourceUri);\r
400     NS_LOG_V(DEBUG, "MQ GET response Transport Type : %d",\r
401                     clientResponse->devAddr.adapter);\r
402 \r
403     char ** topicList = NULL;\r
404     size_t dimensions[MAX_REP_ARRAY_DEPTH] = {0};\r
405     OCRepPayloadGetStringArray((OCRepPayload *) clientResponse->payload,\r
406                                NS_ATTIRBUTE_MQ_TOPICLIST, & topicList, dimensions);\r
407 \r
408     char * interestTopicName = (char *) ctx;\r
409 \r
410     NS_LOG_V(DEBUG, "interestTopicName = %s", interestTopicName);\r
411     for (size_t i = 0; i < dimensions[0]; ++i)\r
412     {\r
413         NS_LOG_V(DEBUG, "found MQ topic : %s", topicList[i]);\r
414         if (!strcmp(topicList[i], interestTopicName))\r
415         {\r
416             NS_LOG(DEBUG, "subscribe to MQ notification");\r
417 \r
418             OCCallbackData cbdata = { NULL, NULL, NULL };\r
419             cbdata.cb = NSProviderMQListener;\r
420             cbdata.context = NULL;\r
421             cbdata.cd = NULL;\r
422 \r
423             OCStackResult ret = OCDoResource(NULL, OC_REST_OBSERVE, topicList[i],\r
424                     clientResponse->addr, NULL, CT_DEFAULT, OC_HIGH_QOS, &cbdata, NULL, 0);\r
425 \r
426             if (!NSOCResultToSuccess(ret))\r
427             {\r
428                 NS_LOG(DEBUG, "fail to subscribe to MQ notification");\r
429                 continue;\r
430             }\r
431         }\r
432     }\r
433 \r
434     // Free topic list\r
435     size_t count = calcDimTotal(dimensions);\r
436     for (size_t k = 0; k < count; k++)\r
437     {\r
438         OICFree(topicList[k]);\r
439     }\r
440     OICFree(topicList);\r
441 \r
442     NS_LOG(DEBUG, "NSProviderGetMQResponseCB - OUT");\r
443     return OC_STACK_KEEP_TRANSACTION;\r
444 }\r
445 \r
446 OCStackApplicationResult NSProviderPublishMQResponseCB(void *ctx, OCDoHandle handle,\r
447         OCClientResponse *clientResponse)\r
448 {\r
449     (void) ctx;\r
450     (void) handle;\r
451     NS_LOG(DEBUG, "Publish Topic callback received");\r
452 \r
453     OCStackApplicationResult res = OC_STACK_ERROR;\r
454 \r
455     NS_LOG_V(DEBUG, "Publish Topic response received code: (%d)", clientResponse->result);\r
456 \r
457     if (clientResponse->payload != NULL &&\r
458         clientResponse->payload->type == PAYLOAD_TYPE_REPRESENTATION)\r
459     {\r
460         NS_LOG(DEBUG, "PAYLOAD_TYPE_REPRESENTATION received");\r
461 \r
462         OCRepPayloadValue *val = ((OCRepPayload *)clientResponse->payload)->values;\r
463         while (val)\r
464         {\r
465             if( val->type == OCREP_PROP_INT)\r
466             {\r
467                 NS_LOG_V(DEBUG, "Key: %s, Value: %lld, int", val->name, val->i);\r
468             }\r
469             else if( val->type == OCREP_PROP_STRING)\r
470             {\r
471                 NS_LOG_V(DEBUG, "Key: %s, Value: %s, string", val->name, val->str);\r
472             }\r
473             else\r
474             {\r
475                 NS_LOG_V(DEBUG, "Un supported val Type.(0x%d)", val->type);\r
476             }\r
477 \r
478             val = val->next;\r
479         }\r
480 \r
481         res = OC_STACK_KEEP_TRANSACTION;\r
482     }\r
483 \r
484     return res;\r
485 }\r
486 #endif\r
487 \r
488 void NSProviderConnectionStateListener(const CAEndpoint_t * info, bool connected)\r
489 {\r
490     NS_LOG(DEBUG, "NSProviderConnectionStateListener - IN");\r
491 \r
492     if (connected)\r
493     {\r
494         NS_LOG(DEBUG, "CONNECTED");\r
495 \r
496         // Set Connection State\r
497         NSSetProviderConnectionState(CONNECTED);\r
498 \r
499         // Start Presence\r
500         NSPushQueue(DISCOVERY_SCHEDULER, TASK_START_PRESENCE, NULL);\r
501 \r
502         if (info->adapter == CA_ADAPTER_TCP)\r
503         {\r
504             NS_LOG_V(INFO_PRIVATE, "TCP Connected remote address: %s:%d", info->addr, info->port);\r
505         }\r
506     }\r
507     else\r
508     {\r
509         NS_LOG(DEBUG, "DISCONNECTED");\r
510 \r
511         // Set Connection State\r
512         NSSetProviderConnectionState(DISCONNECTED);\r
513 \r
514         if (info->adapter == CA_ADAPTER_TCP)\r
515         {\r
516             NS_LOG_V(INFO_PRIVATE, "TCP Disconnected remote address: %s:%d", info->addr, info->port);\r
517         }\r
518     }\r
519 \r
520     NS_LOG(DEBUG, "NSProviderConnectionStateListener - OUT");\r
521 }\r
522 \r
523 void NSProviderAdapterStateListener(CATransportAdapter_t adapter, bool enabled)\r
524 {\r
525     (void)adapter;\r
526 \r
527     NS_LOG(DEBUG, "NSProviderAdapterStateListener - IN");\r
528 \r
529     if (enabled)\r
530     {\r
531         NS_LOG(DEBUG, "CONNECTED");\r
532 \r
533         // Set Connection State\r
534         NSSetProviderConnectionState(CONNECTED);\r
535 \r
536         // Start Presence\r
537         NSPushQueue(DISCOVERY_SCHEDULER, TASK_START_PRESENCE, NULL);\r
538     }\r
539     else\r
540     {\r
541 \r
542         NS_LOG(DEBUG, "DISCONNECTED");\r
543 \r
544         // Set Connection State\r
545         NSSetProviderConnectionState(DISCONNECTED);\r
546     }\r
547 \r
548     NS_LOG(DEBUG, "NSProviderAdapterStateListener - OUT");\r
549 }\r
550 \r
551 bool NSProviderCompareSyncAttributes(const char * name)\r
552 {\r
553     if (!strcmp(name, NS_ATTRIBUTE_MESSAGE_ID) ||\r
554         !strcmp(name, NS_ATTRIBUTE_PROVIDER_ID) ||\r
555         !strcmp(name, NS_ATTRIBUTE_STATE))\r
556     {\r
557         return true;\r
558     }\r
559 \r
560     return false;\r
561 }\r
562 \r
563 bool NSProviderIsSyncAttributes(OCRepPayload * payload)\r
564 {\r
565     NS_LOG(DEBUG, "get extra info");\r
566     OCRepPayloadValue * curr = payload->values;\r
567 \r
568     while (curr)\r
569     {\r
570         if (!NSProviderCompareSyncAttributes(curr->name))\r
571         {\r
572             return false;\r
573         }\r
574 \r
575         curr = curr->next;\r
576     }\r
577 \r
578     return true;\r
579 }\r
580 \r
581 bool NSProviderCompareTopicAttributes(const char * name)\r
582 {\r
583     if (!strcmp(name, NS_ATTRIBUTE_TOPIC_LIST) ||\r
584         !strcmp(name, NS_ATTRIBUTE_CONSUMER_ID))\r
585     {\r
586         return true;\r
587     }\r
588 \r
589     return false;\r
590 }\r
591 \r
592 bool NSProviderCompareSubTopicAttributes(const char * name)\r
593 {\r
594     if (!strcmp(name, NS_ATTRIBUTE_TOPIC_NAME) ||\r
595         !strcmp(name, NS_ATTRIBUTE_TOPIC_SELECTION))\r
596     {\r
597         return true;\r
598     }\r
599 \r
600     return false;\r
601 }\r
602 \r
603 bool NSProviderIsTopicAttributes(OCRepPayload * payload)\r
604 {\r
605     NS_LOG(DEBUG, "get extra info");\r
606     OCRepPayloadValue * curr = payload->values;\r
607 \r
608     while (curr)\r
609     {\r
610         if (!NSProviderCompareTopicAttributes(curr->name))\r
611         {\r
612             OCRepPayloadDestroy(payload);\r
613             return false;\r
614         }\r
615 \r
616         if (!strcmp(curr->name, NS_ATTRIBUTE_TOPIC_LIST))\r
617         {\r
618             OCRepPayload ** topicListPayload = NULL;\r
619             OCRepPayloadValue * payloadValue = NULL;\r
620             payloadValue = NSPayloadFindValue(payload, NS_ATTRIBUTE_TOPIC_LIST);\r
621             size_t dimensionSize = calcDimTotal(payloadValue->arr.dimensions);\r
622             size_t dimensions[3] = { dimensionSize, 0, 0 };\r
623 \r
624             if (!dimensionSize)\r
625             {\r
626                 OCRepPayloadDestroy(payload);\r
627                 return false;\r
628             }\r
629 \r
630             OCRepPayloadGetPropObjectArray(payload, NS_ATTRIBUTE_TOPIC_LIST, &topicListPayload,\r
631                     dimensions);\r
632 \r
633             for (int i = 0; i < (int) dimensionSize; i++)\r
634             {\r
635                 OCRepPayloadValue * subCurr = topicListPayload[i]->values;\r
636 \r
637                 while (subCurr)\r
638                 {\r
639                     if (!NSProviderCompareSubTopicAttributes(subCurr->name))\r
640                     {\r
641                         for(int j = i; j < (int) dimensionSize; ++j)\r
642                         {\r
643                             OCRepPayloadDestroy(topicListPayload[j]);\r
644                         }\r
645 \r
646                         NSOICFree(topicListPayload);\r
647                         OCRepPayloadDestroy(payload);\r
648                         return false;\r
649                     }\r
650                     subCurr = subCurr->next;\r
651                 }\r
652                 OCRepPayloadDestroy(topicListPayload[i]);\r
653             }\r
654             NSOICFree(topicListPayload);\r
655         }\r
656         curr = curr->next;\r
657     }\r
658 \r
659     OCRepPayloadDestroy(payload);\r
660     return true;\r
661 }\r
662 \r
663 OCStackResult NSProviderSendResponse(OCEntityHandlerRequest * entityHandlerRequest,\r
664         OCRepPayload * payload, char * reqInterface, OCEntityHandlerResult ehResult,\r
665         NSInterfaceType interfaceType, NSResourceType resourceType)\r
666 {\r
667     if (reqInterface && strcmp(reqInterface, NS_INTERFACE_BASELINE) == 0)\r
668     {\r
669         payload = OCRepPayloadCreate();\r
670 \r
671         if (!payload)\r
672         {\r
673             NS_LOG(ERROR, "payload is NULL");\r
674             return ehResult;\r
675         }\r
676 \r
677         OCResourcePayloadAddStringLL(&payload->interfaces, NS_INTERFACE_BASELINE);\r
678         interfaceType == NS_INTERFACE_TYPE_READ ?\r
679                 OCResourcePayloadAddStringLL(&payload->interfaces, NS_INTERFACE_READ)\r
680                 : OCResourcePayloadAddStringLL(&payload->interfaces, NS_INTERFACE_READWRITE);\r
681 \r
682         char * rtStr = NULL;\r
683         switch (resourceType)\r
684         {\r
685             case NS_RESOURCE_MESSAGE:\r
686                 rtStr = NS_COLLECTION_MESSAGE_TYPE;\r
687                 break;\r
688             case NS_RESOURCE_SYNC:\r
689                 rtStr = NS_COLLECTION_SYNC_TYPE;\r
690                 break;\r
691             case NS_RESOURCE_TOPIC:\r
692                 rtStr = NS_COLLECTION_TOPIC_TYPE;\r
693                 break;\r
694             default:\r
695                 NS_LOG(ERROR, "sendResponseError");\r
696                 return ehResult;\r
697         }\r
698 \r
699         OCResourcePayloadAddStringLL(&payload->types, rtStr);\r
700     }\r
701 \r
702     if (resourceType == NS_RESOURCE_TOPIC && entityHandlerRequest->method == OC_REST_GET)\r
703     {\r
704         OCRepPayloadDestroy(payload);\r
705         return ehResult;\r
706     }\r
707 \r
708     OCEntityHandlerResponse response;\r
709     response.numSendVendorSpecificHeaderOptions = 0;\r
710     memset(response.sendVendorSpecificHeaderOptions, 0,\r
711             sizeof response.sendVendorSpecificHeaderOptions);\r
712     memset(response.resourceUri, 0, sizeof response.resourceUri);\r
713 \r
714     response.requestHandle = entityHandlerRequest->requestHandle;\r
715     response.resourceHandle = entityHandlerRequest->resource;\r
716     response.persistentBufferFlag = 0;\r
717     response.ehResult = ehResult;\r
718     response.payload = (OCPayload *) payload;\r
719 \r
720     if (OCDoResponse(&response) != OC_STACK_OK)\r
721     {\r
722         NS_LOG(ERROR, "Fail to AccessPolicy send response");\r
723         ehResult = OC_STACK_ERROR;\r
724     }\r
725 \r
726     OCRepPayloadDestroy(payload);\r
727     return ehResult;\r
728 }\r