Add context param to DP
[platform/upstream/iotivity.git] / resource / csdk / stack / src / ocstack.c
1 //******************************************************************
2 //
3 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21
22 //-----------------------------------------------------------------------------
23 // Includes
24 //-----------------------------------------------------------------------------
25
26 // Defining _POSIX_C_SOURCE macro with 200112L (or greater) as value
27 // causes header files to expose definitions
28 // corresponding to the POSIX.1-2001 base
29 // specification (excluding the XSI extension).
30 // For POSIX.1-2001 base specification,
31 // Refer http://pubs.opengroup.org/onlinepubs/009695399/
32 #define _POSIX_C_SOURCE 200112L
33 #ifndef __STDC_FORMAT_MACROS
34 #define __STDC_FORMAT_MACROS
35 #endif
36 #ifndef __STDC_LIMIT_MACROS
37 #define __STDC_LIMIT_MACROS
38 #endif
39 #include <inttypes.h>
40 #include <string.h>
41 #include <ctype.h>
42
43 #include "ocstack.h"
44 #include "ocstackinternal.h"
45 #include "ocresourcehandler.h"
46 #include "occlientcb.h"
47 #include "ocobserve.h"
48 #include "ocrandom.h"
49 #include "oic_malloc.h"
50 #include "oic_string.h"
51 #include "logger.h"
52 #include "ocserverrequest.h"
53 #include "secureresourcemanager.h"
54 #include "doxmresource.h"
55 #include "cacommon.h"
56 #include "cainterface.h"
57 #include "ocpayload.h"
58 #include "ocpayloadcbor.h"
59
60 #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
61 #include "routingutility.h"
62 #ifdef ROUTING_GATEWAY
63 #include "routingmanager.h"
64 #endif
65 #endif
66
67 #ifdef TCP_ADAPTER
68 #include "oickeepalive.h"
69 #endif
70
71 //#ifdef DIRECT_PAIRING
72 #include "directpairing.h"
73 //#endif
74
75 #ifdef WITH_ARDUINO
76 #include "Time.h"
77 #else
78 #include <sys/time.h>
79 #endif
80 #include "coap_time.h"
81 #include "utlist.h"
82 #include "pdu.h"
83
84 #ifndef ARDUINO
85 #include <arpa/inet.h>
86 #endif
87
88 #ifndef UINT32_MAX
89 #define UINT32_MAX   (0xFFFFFFFFUL)
90 #endif
91
92 //-----------------------------------------------------------------------------
93 // Typedefs
94 //-----------------------------------------------------------------------------
95 typedef enum
96 {
97     OC_STACK_UNINITIALIZED = 0,
98     OC_STACK_INITIALIZED,
99     OC_STACK_UNINIT_IN_PROGRESS
100 } OCStackState;
101
102 #ifdef WITH_PRESENCE
103 typedef enum
104 {
105     OC_PRESENCE_UNINITIALIZED = 0,
106     OC_PRESENCE_INITIALIZED
107 } OCPresenceState;
108 #endif
109
110 //-----------------------------------------------------------------------------
111 // Private variables
112 //-----------------------------------------------------------------------------
113 static OCStackState stackState = OC_STACK_UNINITIALIZED;
114
115 OCResource *headResource = NULL;
116 static OCResource *tailResource = NULL;
117 static OCResourceHandle platformResource = {0};
118 static OCResourceHandle deviceResource = {0};
119 #ifdef WITH_PRESENCE
120 static OCPresenceState presenceState = OC_PRESENCE_UNINITIALIZED;
121 static PresenceResource presenceResource;
122 static uint8_t PresenceTimeOutSize = 0;
123 static uint32_t PresenceTimeOut[] = {50, 75, 85, 95, 100};
124 #endif
125
126 static OCMode myStackMode;
127 #ifdef RA_ADAPTER
128 //TODO: revisit this design
129 static bool gRASetInfo = false;
130 #endif
131 OCDeviceEntityHandler defaultDeviceHandler;
132 void* defaultDeviceHandlerCallbackParameter = NULL;
133 static const char COAP_TCP[] = "coap+tcp:";
134 static const char CORESPEC[] = "core";
135
136 //-----------------------------------------------------------------------------
137 // Macros
138 //-----------------------------------------------------------------------------
139 #define TAG  "OIC_RI_STACK"
140 #define VERIFY_SUCCESS(op, successCode) { if ((op) != (successCode)) \
141             {OIC_LOG_V(FATAL, TAG, "%s failed!!", #op); goto exit;} }
142 #define VERIFY_NON_NULL(arg, logLevel, retVal) { if (!(arg)) { OIC_LOG((logLevel), \
143              TAG, #arg " is NULL"); return (retVal); } }
144 #define VERIFY_NON_NULL_NR(arg, logLevel) { if (!(arg)) { OIC_LOG((logLevel), \
145              TAG, #arg " is NULL"); return; } }
146 #define VERIFY_NON_NULL_V(arg) { if (!arg) {OIC_LOG(FATAL, TAG, #arg " is NULL");\
147     goto exit;} }
148
149 //TODO: we should allow the server to define this
150 #define MAX_OBSERVE_AGE (0x2FFFFUL)
151
152 #define MILLISECONDS_PER_SECOND   (1000)
153
154 //-----------------------------------------------------------------------------
155 // Private internal function prototypes
156 //-----------------------------------------------------------------------------
157
158 /**
159  * Generate handle of OCDoResource invocation for callback management.
160  *
161  * @return Generated OCDoResource handle.
162  */
163 static OCDoHandle GenerateInvocationHandle();
164
165 /**
166  * Initialize resource data structures, variables, etc.
167  *
168  * @return ::OC_STACK_OK on success, some other value upon failure.
169  */
170 static OCStackResult initResources();
171
172 /**
173  * Add a resource to the end of the linked list of resources.
174  *
175  * @param resource Resource to be added
176  */
177 static void insertResource(OCResource *resource);
178
179 /**
180  * Find a resource in the linked list of resources.
181  *
182  * @param resource Resource to be found.
183  * @return Pointer to resource that was found in the linked list or NULL if the resource was not
184  *         found.
185  */
186 static OCResource *findResource(OCResource *resource);
187
188 /**
189  * Insert a resource type into a resource's resource type linked list.
190  * If resource type already exists, it will not be inserted and the
191  * resourceType will be free'd.
192  * resourceType->next should be null to avoid memory leaks.
193  * Function returns silently for null args.
194  *
195  * @param resource Resource where resource type is to be inserted.
196  * @param resourceType Resource type to be inserted.
197  */
198 static void insertResourceType(OCResource *resource,
199         OCResourceType *resourceType);
200
201 /**
202  * Get a resource type at the specified index within a resource.
203  *
204  * @param handle Handle of resource.
205  * @param index Index of resource type.
206  *
207  * @return Pointer to resource type if found, NULL otherwise.
208  */
209 static OCResourceType *findResourceTypeAtIndex(OCResourceHandle handle,
210         uint8_t index);
211
212 /**
213  * Insert a resource interface into a resource's resource interface linked list.
214  * If resource interface already exists, it will not be inserted and the
215  * resourceInterface will be free'd.
216  * resourceInterface->next should be null to avoid memory leaks.
217  *
218  * @param resource Resource where resource interface is to be inserted.
219  * @param resourceInterface Resource interface to be inserted.
220  */
221 static void insertResourceInterface(OCResource *resource,
222         OCResourceInterface *resourceInterface);
223
224 /**
225  * Get a resource interface at the specified index within a resource.
226  *
227  * @param handle Handle of resource.
228  * @param index Index of resource interface.
229  *
230  * @return Pointer to resource interface if found, NULL otherwise.
231  */
232 static OCResourceInterface *findResourceInterfaceAtIndex(
233         OCResourceHandle handle, uint8_t index);
234
235 /**
236  * Delete all of the dynamically allocated elements that were created for the resource type.
237  *
238  * @param resourceType Specified resource type.
239  */
240 static void deleteResourceType(OCResourceType *resourceType);
241
242 /**
243  * Delete all of the dynamically allocated elements that were created for the resource interface.
244  *
245  * @param resourceInterface Specified resource interface.
246  */
247 static void deleteResourceInterface(OCResourceInterface *resourceInterface);
248
249 /**
250  * Delete all of the dynamically allocated elements that were created for the resource.
251  *
252  * @param resource Specified resource.
253  */
254 static void deleteResourceElements(OCResource *resource);
255
256 /**
257  * Delete resource specified by handle.  Deletes resource and all resourcetype and resourceinterface
258  * linked lists.
259  *
260  * @param handle Handle of resource to be deleted.
261  *
262  * @return ::OC_STACK_OK on success, some other value upon failure.
263  */
264 static OCStackResult deleteResource(OCResource *resource);
265
266 /**
267  * Delete all of the resources in the resource list.
268  */
269 static void deleteAllResources();
270
271 /**
272  * Increment resource sequence number.  Handles rollover.
273  *
274  * @param resPtr Pointer to resource.
275  */
276 static void incrementSequenceNumber(OCResource * resPtr);
277
278 /*
279  * Attempts to initialize every network interface that the CA Layer might have compiled in.
280  *
281  * Note: At least one interface must succeed to initialize. If all calls to @ref CASelectNetwork
282  * return something other than @ref CA_STATUS_OK, then this function fails.
283  *
284  * @return ::CA_STATUS_OK on success, some other value upon failure.
285  */
286 static CAResult_t OCSelectNetwork();
287
288 /**
289  * Get the CoAP ticks after the specified number of milli-seconds.
290  *
291  * @param afterMilliSeconds Milli-seconds.
292  * @return
293  *     CoAP ticks
294  */
295 static uint32_t GetTicks(uint32_t afterMilliSeconds);
296
297 /**
298  * Convert CAResult_t to OCStackResult.
299  *
300  * @param caResult CAResult_t code.
301  * @return ::OC_STACK_OK on success, some other value upon failure.
302  */
303 static OCStackResult CAResultToOCStackResult(CAResult_t caResult);
304
305 /**
306  * Convert CAResponseResult_t to OCStackResult.
307  *
308  * @param caCode CAResponseResult_t code.
309  * @return ::OC_STACK_OK on success, some other value upon failure.
310  */
311 static OCStackResult CAResponseToOCStackResult(CAResponseResult_t caCode);
312
313 /**
314  * Convert OCStackResult to CAResponseResult_t.
315  *
316  * @param caCode OCStackResult code.
317  * @param method OCMethod method the return code replies to.
318  * @return ::CA_CONTENT on OK, some other value upon failure.
319  */
320 static CAResponseResult_t OCToCAStackResult(OCStackResult ocCode, OCMethod method);
321
322 /**
323  * Convert OCTransportFlags_t to CATransportModifiers_t.
324  *
325  * @param ocConType OCTransportFlags_t input.
326  * @return CATransportFlags
327  */
328 static CATransportFlags_t OCToCATransportFlags(OCTransportFlags ocConType);
329
330 /**
331  * Convert CATransportFlags_t to OCTransportModifiers_t.
332  *
333  * @param caConType CATransportFlags_t input.
334  * @return OCTransportFlags
335  */
336 static OCTransportFlags CAToOCTransportFlags(CATransportFlags_t caConType);
337
338 /**
339  * Handle response from presence request.
340  *
341  * @param endPoint CA remote endpoint.
342  * @param responseInfo CA response info.
343  * @return ::OC_STACK_OK on success, some other value upon failure.
344  */
345 static OCStackResult HandlePresenceResponse(const CAEndpoint_t *endPoint,
346         const CAResponseInfo_t *responseInfo);
347
348 /**
349  * This function will be called back by CA layer when a response is received.
350  *
351  * @param endPoint CA remote endpoint.
352  * @param responseInfo CA response info.
353  */
354 static void HandleCAResponses(const CAEndpoint_t* endPoint,
355         const CAResponseInfo_t* responseInfo);
356
357 /**
358  * This function will be called back by CA layer when a request is received.
359  *
360  * @param endPoint CA remote endpoint.
361  * @param requestInfo CA request info.
362  */
363 static void HandleCARequests(const CAEndpoint_t* endPoint,
364         const CARequestInfo_t* requestInfo);
365
366 /**
367  * Extract query from a URI.
368  *
369  * @param uri Full URI with query.
370  * @param query Pointer to string that will contain query.
371  * @param newURI Pointer to string that will contain URI.
372  * @return ::OC_STACK_OK on success, some other value upon failure.
373  */
374 static OCStackResult getQueryFromUri(const char * uri, char** resourceType, char ** newURI);
375
376 /**
377  * Finds a resource type in an OCResourceType link-list.
378  *
379  * @param resourceTypeList The link-list to be searched through.
380  * @param resourceTypeName The key to search for.
381  *
382  * @return Resource type that matches the key (ie. resourceTypeName) or
383  *      NULL if there is either an invalid parameter or this function was unable to find the key.
384  */
385 static OCResourceType *findResourceType(OCResourceType * resourceTypeList,
386         const char * resourceTypeName);
387
388 /**
389  * Reset presence TTL for a ClientCB struct. ttlLevel will be set to 0.
390  * TTL will be set to maxAge.
391  *
392  * @param cbNode Callback Node for which presence ttl is to be reset.
393  * @param maxAge New value of ttl in seconds.
394
395  * @return ::OC_STACK_OK on success, some other value upon failure.
396  */
397 static OCStackResult ResetPresenceTTL(ClientCB *cbNode, uint32_t maxAgeSeconds);
398
399 /**
400  * Ensure the accept header option is set appropriatly before sending the requests and routing
401  * header option is updated with destination.
402  *
403  * @param object CA remote endpoint.
404  * @param requestInfo CA request info.
405  *
406  * @return ::OC_STACK_OK on success, some other value upon failure.
407  */
408 static OCStackResult OCSendRequest(const CAEndpoint_t *object, CARequestInfo_t *requestInfo);
409
410 //-----------------------------------------------------------------------------
411 // Internal functions
412 //-----------------------------------------------------------------------------
413
414 uint32_t GetTicks(uint32_t afterMilliSeconds)
415 {
416     coap_tick_t now;
417     coap_ticks(&now);
418
419     // Guard against overflow of uint32_t
420     if (afterMilliSeconds <= ((UINT32_MAX - (uint32_t)now) * MILLISECONDS_PER_SECOND) /
421                              COAP_TICKS_PER_SECOND)
422     {
423         return now + (afterMilliSeconds * COAP_TICKS_PER_SECOND)/MILLISECONDS_PER_SECOND;
424     }
425     else
426     {
427         return UINT32_MAX;
428     }
429 }
430
431 void CopyEndpointToDevAddr(const CAEndpoint_t *in, OCDevAddr *out)
432 {
433     VERIFY_NON_NULL_NR(in, FATAL);
434     VERIFY_NON_NULL_NR(out, FATAL);
435
436     out->adapter = (OCTransportAdapter)in->adapter;
437     out->flags = CAToOCTransportFlags(in->flags);
438     OICStrcpy(out->addr, sizeof(out->addr), in->addr);
439     out->port = in->port;
440     out->interface = in->interface;
441 #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
442     memcpy(out->routeData, in->routeData, sizeof(out->routeData));
443 #endif
444 }
445
446 void CopyDevAddrToEndpoint(const OCDevAddr *in, CAEndpoint_t *out)
447 {
448     VERIFY_NON_NULL_NR(in, FATAL);
449     VERIFY_NON_NULL_NR(out, FATAL);
450
451     out->adapter = (CATransportAdapter_t)in->adapter;
452     out->flags = OCToCATransportFlags(in->flags);
453     OICStrcpy(out->addr, sizeof(out->addr), in->addr);
454 #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
455     memcpy(out->routeData, in->routeData, sizeof(out->routeData));
456 #endif
457     out->port = in->port;
458     out->interface = in->interface;
459 }
460
461 void FixUpClientResponse(OCClientResponse *cr)
462 {
463     VERIFY_NON_NULL_NR(cr, FATAL);
464
465     cr->addr = &cr->devAddr;
466     cr->connType = (OCConnectivityType)
467         ((cr->devAddr.adapter << CT_ADAPTER_SHIFT) | (cr->devAddr.flags & CT_MASK_FLAGS));
468 }
469
470 static OCStackResult OCSendRequest(const CAEndpoint_t *object, CARequestInfo_t *requestInfo)
471 {
472     VERIFY_NON_NULL(object, FATAL, OC_STACK_INVALID_PARAM);
473     VERIFY_NON_NULL(requestInfo, FATAL, OC_STACK_INVALID_PARAM);
474
475 #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
476     OCStackResult rmResult = RMAddInfo(object->routeData, requestInfo, true, NULL);
477     if (OC_STACK_OK != rmResult)
478     {
479         OIC_LOG(ERROR, TAG, "Add destination option failed");
480         return rmResult;
481     }
482 #endif
483
484     // OC stack prefer CBOR encoded payloads.
485     requestInfo->info.acceptFormat = CA_FORMAT_APPLICATION_CBOR;
486     CAResult_t result = CASendRequest(object, requestInfo);
487     if(CA_STATUS_OK != result)
488     {
489         OIC_LOG_V(ERROR, TAG, "CASendRequest failed with CA error %u", result);
490         return CAResultToOCResult(result);
491     }
492     return OC_STACK_OK;
493 }
494 //-----------------------------------------------------------------------------
495 // Internal API function
496 //-----------------------------------------------------------------------------
497
498 // This internal function is called to update the stack with the status of
499 // observers and communication failures
500 OCStackResult OCStackFeedBack(CAToken_t token, uint8_t tokenLength, uint8_t status)
501 {
502     OCStackResult result = OC_STACK_ERROR;
503     ResourceObserver * observer = NULL;
504     OCEntityHandlerRequest ehRequest = {0};
505
506     switch(status)
507     {
508     case OC_OBSERVER_NOT_INTERESTED:
509         OIC_LOG(DEBUG, TAG, "observer not interested in our notifications");
510         observer = GetObserverUsingToken (token, tokenLength);
511         if(observer)
512         {
513             result = FormOCEntityHandlerRequest(&ehRequest,
514                                                 (OCRequestHandle)NULL,
515                                                 OC_REST_NOMETHOD,
516                                                 &observer->devAddr,
517                                                 (OCResourceHandle)NULL,
518                                                 NULL, PAYLOAD_TYPE_REPRESENTATION,
519                                                 NULL, 0, 0, NULL,
520                                                 OC_OBSERVE_DEREGISTER,
521                                                 observer->observeId);
522             if(result != OC_STACK_OK)
523             {
524                 return result;
525             }
526             observer->resource->entityHandler(OC_OBSERVE_FLAG, &ehRequest,
527                             observer->resource->entityHandlerCallbackParam);
528         }
529
530         result = DeleteObserverUsingToken (token, tokenLength);
531         if(result == OC_STACK_OK)
532         {
533             OIC_LOG(DEBUG, TAG, "Removed observer successfully");
534         }
535         else
536         {
537             result = OC_STACK_OK;
538             OIC_LOG(DEBUG, TAG, "Observer Removal failed");
539         }
540         break;
541
542     case OC_OBSERVER_STILL_INTERESTED:
543         OIC_LOG(DEBUG, TAG, "observer still interested, reset the failedCount");
544         observer = GetObserverUsingToken (token, tokenLength);
545         if(observer)
546         {
547             observer->forceHighQos = 0;
548             observer->failedCommCount = 0;
549             result = OC_STACK_OK;
550         }
551         else
552         {
553             result = OC_STACK_OBSERVER_NOT_FOUND;
554         }
555         break;
556
557     case OC_OBSERVER_FAILED_COMM:
558         OIC_LOG(DEBUG, TAG, "observer is unreachable");
559         observer = GetObserverUsingToken (token, tokenLength);
560         if(observer)
561         {
562             if(observer->failedCommCount >= MAX_OBSERVER_FAILED_COMM)
563             {
564                 result = FormOCEntityHandlerRequest(&ehRequest,
565                                                     (OCRequestHandle)NULL,
566                                                     OC_REST_NOMETHOD,
567                                                     &observer->devAddr,
568                                                     (OCResourceHandle)NULL,
569                                                     NULL, PAYLOAD_TYPE_REPRESENTATION,
570                                                     NULL, 0, 0, NULL,
571                                                     OC_OBSERVE_DEREGISTER,
572                                                     observer->observeId);
573                 if(result != OC_STACK_OK)
574                 {
575                     return OC_STACK_ERROR;
576                 }
577                 observer->resource->entityHandler(OC_OBSERVE_FLAG, &ehRequest,
578                                     observer->resource->entityHandlerCallbackParam);
579
580                 result = DeleteObserverUsingToken (token, tokenLength);
581                 if(result == OC_STACK_OK)
582                 {
583                     OIC_LOG(DEBUG, TAG, "Removed observer successfully");
584                 }
585                 else
586                 {
587                     result = OC_STACK_OK;
588                     OIC_LOG(DEBUG, TAG, "Observer Removal failed");
589                 }
590             }
591             else
592             {
593                 observer->failedCommCount++;
594                 result = OC_STACK_CONTINUE;
595             }
596             observer->forceHighQos = 1;
597             OIC_LOG_V(DEBUG, TAG, "Failed count for this observer is %d",observer->failedCommCount);
598         }
599         break;
600     default:
601         OIC_LOG(ERROR, TAG, "Unknown status");
602         result = OC_STACK_ERROR;
603         break;
604         }
605     return result;
606 }
607
608 static OCStackResult CAResultToOCStackResult(CAResult_t caResult)
609 {
610     OCStackResult ret = OC_STACK_ERROR;
611
612     switch(caResult)
613     {
614         case CA_ADAPTER_NOT_ENABLED:
615         case CA_SERVER_NOT_STARTED:
616             ret = OC_STACK_ADAPTER_NOT_ENABLED;
617             break;
618         case CA_MEMORY_ALLOC_FAILED:
619             ret = OC_STACK_NO_MEMORY;
620             break;
621         case CA_STATUS_INVALID_PARAM:
622             ret = OC_STACK_INVALID_PARAM;
623             break;
624         default:
625             break;
626     }
627     return ret;
628 }
629
630 OCStackResult CAResponseToOCStackResult(CAResponseResult_t caCode)
631 {
632     OCStackResult ret = OC_STACK_ERROR;
633
634     switch(caCode)
635     {
636         case CA_CREATED:
637             ret = OC_STACK_RESOURCE_CREATED;
638             break;
639         case CA_DELETED:
640             ret = OC_STACK_RESOURCE_DELETED;
641             break;
642         case CA_CHANGED:
643         case CA_CONTENT:
644         case CA_VALID:
645             ret = OC_STACK_OK;
646             break;
647         case CA_BAD_REQ:
648             ret = OC_STACK_INVALID_QUERY;
649             break;
650         case CA_UNAUTHORIZED_REQ:
651             ret = OC_STACK_UNAUTHORIZED_REQ;
652             break;
653         case CA_BAD_OPT:
654             ret = OC_STACK_INVALID_OPTION;
655             break;
656         case CA_NOT_FOUND:
657             ret = OC_STACK_NO_RESOURCE;
658             break;
659         case CA_RETRANSMIT_TIMEOUT:
660             ret = OC_STACK_COMM_ERROR;
661             break;
662         case CA_REQUEST_ENTITY_TOO_LARGE:
663             ret = OC_STACK_TOO_LARGE_REQ;
664             break;
665         default:
666             break;
667     }
668     return ret;
669 }
670
671 CAResponseResult_t OCToCAStackResult(OCStackResult ocCode, OCMethod method)
672 {
673     CAResponseResult_t ret = CA_INTERNAL_SERVER_ERROR;
674
675     switch(ocCode)
676     {
677         case OC_STACK_OK:
678            switch (method)
679            {
680                case OC_REST_PUT:
681                case OC_REST_POST:
682                    // This Response Code is like HTTP 204 "No Content" but only used in
683                    // response to POST and PUT requests.
684                    ret = CA_CHANGED;
685                    break;
686                case OC_REST_GET:
687                    // This Response Code is like HTTP 200 "OK" but only used in response to
688                    // GET requests.
689                    ret = CA_CONTENT;
690                    break;
691                default:
692                    // This should not happen but,
693                    // give it a value just in case but output an error
694                    ret = CA_CONTENT;
695                    OIC_LOG_V(ERROR, TAG, "Unexpected OC_STACK_OK return code for method [%d].", method);
696             }
697             break;
698         case OC_STACK_RESOURCE_CREATED:
699             ret = CA_CREATED;
700             break;
701         case OC_STACK_RESOURCE_DELETED:
702             ret = CA_DELETED;
703             break;
704         case OC_STACK_INVALID_QUERY:
705             ret = CA_BAD_REQ;
706             break;
707         case OC_STACK_INVALID_OPTION:
708             ret = CA_BAD_OPT;
709             break;
710         case OC_STACK_NO_RESOURCE:
711             ret = CA_NOT_FOUND;
712             break;
713         case OC_STACK_COMM_ERROR:
714             ret = CA_RETRANSMIT_TIMEOUT;
715             break;
716         case OC_STACK_UNAUTHORIZED_REQ:
717             ret = CA_UNAUTHORIZED_REQ;
718             break;
719         default:
720             break;
721     }
722     return ret;
723 }
724
725 CATransportFlags_t OCToCATransportFlags(OCTransportFlags ocFlags)
726 {
727     CATransportFlags_t caFlags = (CATransportFlags_t)ocFlags;
728
729     // supply default behavior.
730     if ((caFlags & (CA_IPV6|CA_IPV4)) == 0)
731     {
732         caFlags = (CATransportFlags_t)(caFlags|CA_IPV6|CA_IPV4);
733     }
734     if ((caFlags & OC_MASK_SCOPE) == 0)
735     {
736         caFlags = (CATransportFlags_t)(caFlags|OC_SCOPE_LINK);
737     }
738     return caFlags;
739 }
740
741 OCTransportFlags CAToOCTransportFlags(CATransportFlags_t caFlags)
742 {
743     return (OCTransportFlags)caFlags;
744 }
745
746 static OCStackResult ResetPresenceTTL(ClientCB *cbNode, uint32_t maxAgeSeconds)
747 {
748     uint32_t lowerBound  = 0;
749     uint32_t higherBound = 0;
750
751     if (!cbNode || !cbNode->presence || !cbNode->presence->timeOut)
752     {
753         return OC_STACK_INVALID_PARAM;
754     }
755
756     OIC_LOG_V(INFO, TAG, "Update presence TTL, time is %u", GetTicks(0));
757
758     cbNode->presence->TTL = maxAgeSeconds;
759
760     for (int index = 0; index < PresenceTimeOutSize; index++)
761     {
762         // Guard against overflow
763         if (cbNode->presence->TTL < (UINT32_MAX/(MILLISECONDS_PER_SECOND*PresenceTimeOut[index]))
764                                      * 100)
765         {
766             lowerBound = GetTicks((PresenceTimeOut[index] *
767                                   cbNode->presence->TTL *
768                                   MILLISECONDS_PER_SECOND)/100);
769         }
770         else
771         {
772             lowerBound = GetTicks(UINT32_MAX);
773         }
774
775         if (cbNode->presence->TTL < (UINT32_MAX/(MILLISECONDS_PER_SECOND*PresenceTimeOut[index+1]))
776                                      * 100)
777         {
778             higherBound = GetTicks((PresenceTimeOut[index + 1] *
779                                    cbNode->presence->TTL *
780                                    MILLISECONDS_PER_SECOND)/100);
781         }
782         else
783         {
784             higherBound = GetTicks(UINT32_MAX);
785         }
786
787         cbNode->presence->timeOut[index] = OCGetRandomRange(lowerBound, higherBound);
788
789         OIC_LOG_V(DEBUG, TAG, "lowerBound timeout  %d", lowerBound);
790         OIC_LOG_V(DEBUG, TAG, "higherBound timeout %d", higherBound);
791         OIC_LOG_V(DEBUG, TAG, "timeOut entry  %d", cbNode->presence->timeOut[index]);
792     }
793
794     cbNode->presence->TTLlevel = 0;
795
796     OIC_LOG_V(DEBUG, TAG, "this TTL level %d", cbNode->presence->TTLlevel);
797     return OC_STACK_OK;
798 }
799
800 const char *convertTriggerEnumToString(OCPresenceTrigger trigger)
801 {
802     if (trigger == OC_PRESENCE_TRIGGER_CREATE)
803     {
804         return OC_RSRVD_TRIGGER_CREATE;
805     }
806     else if (trigger == OC_PRESENCE_TRIGGER_CHANGE)
807     {
808         return OC_RSRVD_TRIGGER_CHANGE;
809     }
810     else
811     {
812         return OC_RSRVD_TRIGGER_DELETE;
813     }
814 }
815
816 OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr)
817 {
818     if(!triggerStr)
819     {
820         return OC_PRESENCE_TRIGGER_CREATE;
821     }
822     else if(strcmp(triggerStr, OC_RSRVD_TRIGGER_CREATE) == 0)
823     {
824         return OC_PRESENCE_TRIGGER_CREATE;
825     }
826     else if(strcmp(triggerStr, OC_RSRVD_TRIGGER_CHANGE) == 0)
827     {
828         return OC_PRESENCE_TRIGGER_CHANGE;
829     }
830     else
831     {
832         return OC_PRESENCE_TRIGGER_DELETE;
833     }
834 }
835
836 /**
837  * The cononical presence allows constructed URIs to be string compared.
838  *
839  * requestUri must be a char array of size CA_MAX_URI_LENGTH
840  */
841 static int FormCanonicalPresenceUri(const CAEndpoint_t *endpoint, char *resourceUri,
842         char *presenceUri)
843 {
844     VERIFY_NON_NULL(endpoint   , FATAL, OC_STACK_INVALID_PARAM);
845     VERIFY_NON_NULL(resourceUri, FATAL, OC_STACK_INVALID_PARAM);
846     VERIFY_NON_NULL(presenceUri, FATAL, OC_STACK_INVALID_PARAM);
847
848     CAEndpoint_t *ep = (CAEndpoint_t *)endpoint;
849
850     if (ep->adapter == CA_ADAPTER_IP)
851     {
852         if ((ep->flags & CA_IPV6) && !(ep->flags & CA_IPV4))
853         {
854             if ('\0' == ep->addr[0])  // multicast
855             {
856                 return snprintf(presenceUri, CA_MAX_URI_LENGTH, OC_RSRVD_PRESENCE_URI);
857             }
858             else
859             {
860                 return snprintf(presenceUri, CA_MAX_URI_LENGTH, "coap://[%s]:%u%s",
861                         ep->addr, ep->port, OC_RSRVD_PRESENCE_URI);
862             }
863         }
864         else
865         {
866             if ('\0' == ep->addr[0])  // multicast
867             {
868                 OICStrcpy(ep->addr, sizeof(ep->addr), OC_MULTICAST_IP);
869                 ep->port = OC_MULTICAST_PORT;
870             }
871             return snprintf(presenceUri, CA_MAX_URI_LENGTH, "coap://%s:%u%s",
872                     ep->addr, ep->port, OC_RSRVD_PRESENCE_URI);
873         }
874     }
875
876     // might work for other adapters (untested, but better than nothing)
877     return snprintf(presenceUri, CA_MAX_URI_LENGTH, "coap://%s%s", ep->addr,
878                     OC_RSRVD_PRESENCE_URI);
879 }
880
881
882 OCStackResult HandlePresenceResponse(const CAEndpoint_t *endpoint,
883                             const CAResponseInfo_t *responseInfo)
884 {
885     VERIFY_NON_NULL(endpoint, FATAL, OC_STACK_INVALID_PARAM);
886     VERIFY_NON_NULL(responseInfo, FATAL, OC_STACK_INVALID_PARAM);
887
888     OCStackApplicationResult cbResult = OC_STACK_DELETE_TRANSACTION;
889     ClientCB * cbNode = NULL;
890     char *resourceTypeName = NULL;
891     OCClientResponse response = {.devAddr = {.adapter = OC_DEFAULT_ADAPTER}};
892     OCStackResult result = OC_STACK_ERROR;
893     uint32_t maxAge = 0;
894     int uriLen;
895     char presenceUri[CA_MAX_URI_LENGTH];
896
897     int presenceSubscribe = 0;
898     int multicastPresenceSubscribe = 0;
899
900     if (responseInfo->result != CA_CONTENT)
901     {
902         OIC_LOG_V(ERROR, TAG, "HandlePresenceResponse failed %d", responseInfo->result);
903         return OC_STACK_ERROR;
904     }
905
906     // check for unicast presence
907     uriLen = FormCanonicalPresenceUri(endpoint, OC_RSRVD_PRESENCE_URI, presenceUri);
908     if (uriLen < 0 || (size_t)uriLen >= sizeof (presenceUri))
909     {
910         return OC_STACK_INVALID_URI;
911     }
912
913     cbNode = GetClientCB(NULL, 0, NULL, presenceUri);
914     if (cbNode)
915     {
916         presenceSubscribe = 1;
917     }
918     else
919     {
920         // check for multiicast presence
921         CAEndpoint_t ep = { .adapter = endpoint->adapter,
922                             .flags = endpoint->flags };
923
924         uriLen = FormCanonicalPresenceUri(&ep, OC_RSRVD_PRESENCE_URI, presenceUri);
925
926         cbNode = GetClientCB(NULL, 0, NULL, presenceUri);
927         if (cbNode)
928         {
929             multicastPresenceSubscribe = 1;
930         }
931     }
932
933     if (!presenceSubscribe && !multicastPresenceSubscribe)
934     {
935         OIC_LOG(ERROR, TAG, "Received a presence notification, but no callback, ignoring");
936         goto exit;
937     }
938
939     response.payload = NULL;
940     response.result = OC_STACK_OK;
941
942     CopyEndpointToDevAddr(endpoint, &response.devAddr);
943     FixUpClientResponse(&response);
944
945     if (responseInfo->info.payload)
946     {
947         result = OCParsePayload(&response.payload,
948                 PAYLOAD_TYPE_PRESENCE,
949                 responseInfo->info.payload,
950                 responseInfo->info.payloadSize);
951
952         if(result != OC_STACK_OK)
953         {
954             OIC_LOG(ERROR, TAG, "Presence parse failed");
955             goto exit;
956         }
957         if(!response.payload || response.payload->type != PAYLOAD_TYPE_PRESENCE)
958         {
959             OIC_LOG(ERROR, TAG, "Presence payload was wrong type");
960             result = OC_STACK_ERROR;
961             goto exit;
962         }
963         response.sequenceNumber = ((OCPresencePayload*)response.payload)->sequenceNumber;
964         resourceTypeName = ((OCPresencePayload*)response.payload)->resourceType;
965         maxAge = ((OCPresencePayload*)response.payload)->maxAge;
966     }
967
968     if (presenceSubscribe)
969     {
970         if(cbNode->sequenceNumber == response.sequenceNumber)
971         {
972             OIC_LOG(INFO, TAG, "No presence change");
973             ResetPresenceTTL(cbNode, maxAge);
974             OIC_LOG_V(INFO, TAG, "ResetPresenceTTL - TTLlevel:%d\n", cbNode->presence->TTLlevel);
975             goto exit;
976         }
977
978         if(maxAge == 0)
979         {
980             OIC_LOG(INFO, TAG, "Stopping presence");
981             response.result = OC_STACK_PRESENCE_STOPPED;
982             if(cbNode->presence)
983             {
984                 OICFree(cbNode->presence->timeOut);
985                 OICFree(cbNode->presence);
986                 cbNode->presence = NULL;
987             }
988         }
989         else
990         {
991             if(!cbNode->presence)
992             {
993                 cbNode->presence = (OCPresence *)OICMalloc(sizeof (OCPresence));
994
995                 if(!(cbNode->presence))
996                 {
997                     OIC_LOG(ERROR, TAG, "Could not allocate memory for cbNode->presence");
998                     result = OC_STACK_NO_MEMORY;
999                     goto exit;
1000                 }
1001
1002                 VERIFY_NON_NULL_V(cbNode->presence);
1003                 cbNode->presence->timeOut = NULL;
1004                 cbNode->presence->timeOut = (uint32_t *)
1005                         OICMalloc(PresenceTimeOutSize * sizeof(uint32_t));
1006                 if(!(cbNode->presence->timeOut)){
1007                     OIC_LOG(ERROR, TAG,
1008                                   "Could not allocate memory for cbNode->presence->timeOut");
1009                     OICFree(cbNode->presence);
1010                     result = OC_STACK_NO_MEMORY;
1011                     goto exit;
1012                 }
1013             }
1014
1015             ResetPresenceTTL(cbNode, maxAge);
1016
1017             cbNode->sequenceNumber = response.sequenceNumber;
1018
1019             // Ensure that a filter is actually applied.
1020             if( resourceTypeName && cbNode->filterResourceType)
1021             {
1022                 if(!findResourceType(cbNode->filterResourceType, resourceTypeName))
1023                 {
1024                     goto exit;
1025                 }
1026             }
1027         }
1028     }
1029     else
1030     {
1031         // This is the multicast case
1032         OCMulticastNode* mcNode = NULL;
1033         mcNode = GetMCPresenceNode(presenceUri);
1034
1035         if(mcNode != NULL)
1036         {
1037             if(mcNode->nonce == response.sequenceNumber)
1038             {
1039                 OIC_LOG(INFO, TAG, "No presence change (Multicast)");
1040                 goto exit;
1041             }
1042             mcNode->nonce = response.sequenceNumber;
1043
1044             if(maxAge == 0)
1045             {
1046                 OIC_LOG(INFO, TAG, "Stopping presence");
1047                 response.result = OC_STACK_PRESENCE_STOPPED;
1048             }
1049         }
1050         else
1051         {
1052             char* uri = OICStrdup(presenceUri);
1053             if (!uri)
1054             {
1055                 OIC_LOG(INFO, TAG,
1056                     "No Memory for URI to store in the presence node");
1057                 result = OC_STACK_NO_MEMORY;
1058                 goto exit;
1059             }
1060
1061             result = AddMCPresenceNode(&mcNode, uri, response.sequenceNumber);
1062             if(result == OC_STACK_NO_MEMORY)
1063             {
1064                 OIC_LOG(INFO, TAG,
1065                     "No Memory for Multicast Presence Node");
1066                 OICFree(uri);
1067                 goto exit;
1068             }
1069             // presence node now owns uri
1070         }
1071
1072         // Ensure that a filter is actually applied.
1073         if(resourceTypeName && cbNode->filterResourceType)
1074         {
1075             if(!findResourceType(cbNode->filterResourceType, resourceTypeName))
1076             {
1077                 goto exit;
1078             }
1079         }
1080     }
1081
1082     cbResult = cbNode->callBack(cbNode->context, cbNode->handle, &response);
1083
1084     if (cbResult == OC_STACK_DELETE_TRANSACTION)
1085     {
1086         FindAndDeleteClientCB(cbNode);
1087     }
1088
1089 exit:
1090     OCPayloadDestroy(response.payload);
1091     return result;
1092 }
1093
1094 void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* responseInfo)
1095 {
1096     OIC_LOG(DEBUG, TAG, "Enter OCHandleResponse");
1097
1098     if(responseInfo->info.resourceUri &&
1099         strcmp(responseInfo->info.resourceUri, OC_RSRVD_PRESENCE_URI) == 0)
1100     {
1101         HandlePresenceResponse(endPoint, responseInfo);
1102         return;
1103     }
1104
1105     ClientCB *cbNode = GetClientCB(responseInfo->info.token,
1106             responseInfo->info.tokenLength, NULL, NULL);
1107
1108     ResourceObserver * observer = GetObserverUsingToken (responseInfo->info.token,
1109             responseInfo->info.tokenLength);
1110
1111     if(cbNode)
1112     {
1113         OIC_LOG(INFO, TAG, "There is a cbNode associated with the response token");
1114         if(responseInfo->result == CA_EMPTY)
1115         {
1116             OIC_LOG(INFO, TAG, "Receiving A ACK/RESET for this token");
1117             // We do not have a case for the client to receive a RESET
1118             if(responseInfo->info.type == CA_MSG_ACKNOWLEDGE)
1119             {
1120                 //This is the case of receiving an ACK on a request to a slow resource!
1121                 OIC_LOG(INFO, TAG, "This is a pure ACK");
1122                 //TODO: should we inform the client
1123                 //      app that at least the request was received at the server?
1124             }
1125         }
1126         else if(responseInfo->result == CA_RETRANSMIT_TIMEOUT)
1127         {
1128             OIC_LOG(INFO, TAG, "Receiving A Timeout for this token");
1129             OIC_LOG(INFO, TAG, "Calling into application address space");
1130
1131             OCClientResponse response =
1132                 {.devAddr = {.adapter = OC_DEFAULT_ADAPTER}};
1133             CopyEndpointToDevAddr(endPoint, &response.devAddr);
1134             FixUpClientResponse(&response);
1135             response.resourceUri = responseInfo->info.resourceUri;
1136             memcpy(response.identity.id, responseInfo->info.identity.id,
1137                                                 sizeof (response.identity.id));
1138             response.identity.id_length = responseInfo->info.identity.id_length;
1139
1140             response.result = CAResponseToOCStackResult(responseInfo->result);
1141             cbNode->callBack(cbNode->context,
1142                     cbNode->handle, &response);
1143             FindAndDeleteClientCB(cbNode);
1144         }
1145         else
1146         {
1147             OIC_LOG(INFO, TAG, "This is a regular response, A client call back is found");
1148             OIC_LOG(INFO, TAG, "Calling into application address space");
1149
1150             OCClientResponse response =
1151                 {.devAddr = {.adapter = OC_DEFAULT_ADAPTER}};
1152             response.sequenceNumber = OC_OBSERVE_NO_OPTION;
1153             CopyEndpointToDevAddr(endPoint, &response.devAddr);
1154             FixUpClientResponse(&response);
1155             response.resourceUri = responseInfo->info.resourceUri;
1156             memcpy(response.identity.id, responseInfo->info.identity.id,
1157                                                 sizeof (response.identity.id));
1158             response.identity.id_length = responseInfo->info.identity.id_length;
1159
1160             response.result = CAResponseToOCStackResult(responseInfo->result);
1161
1162             if(responseInfo->info.payload &&
1163                responseInfo->info.payloadSize)
1164             {
1165                 OCPayloadType type = PAYLOAD_TYPE_INVALID;
1166                 // check the security resource
1167                 if (SRMIsSecurityResourceURI(cbNode->requestUri))
1168                 {
1169                     type = PAYLOAD_TYPE_SECURITY;
1170                 }
1171                 else if (cbNode->method == OC_REST_DISCOVER)
1172                 {
1173                     if (strncmp(OC_RSRVD_WELL_KNOWN_URI,cbNode->requestUri,
1174                                 sizeof(OC_RSRVD_WELL_KNOWN_URI) - 1) == 0)
1175                     {
1176                         type = PAYLOAD_TYPE_DISCOVERY;
1177                     }
1178                     else if (strcmp(cbNode->requestUri, OC_RSRVD_DEVICE_URI) == 0)
1179                     {
1180                         type = PAYLOAD_TYPE_DEVICE;
1181                     }
1182                     else if (strcmp(cbNode->requestUri, OC_RSRVD_PLATFORM_URI) == 0)
1183                     {
1184                         type = PAYLOAD_TYPE_PLATFORM;
1185                     }
1186 #ifdef ROUTING_GATEWAY
1187                     else if (strcmp(cbNode->requestUri, OC_RSRVD_GATEWAY_URI) == 0)
1188                     {
1189                         type = PAYLOAD_TYPE_REPRESENTATION;
1190                     }
1191 #endif
1192                     else if (strcmp(cbNode->requestUri, OC_RSRVD_RD_URI) == 0)
1193                     {
1194                         type = PAYLOAD_TYPE_RD;
1195                     }
1196 #ifdef TCP_ADAPTER
1197                     else if (strcmp(cbNode->requestUri, KEEPALIVE_RESOURCE_URI) == 0)
1198                     {
1199                         type = PAYLOAD_TYPE_REPRESENTATION;
1200                     }
1201 #endif
1202                     else
1203                     {
1204                         OIC_LOG_V(ERROR, TAG, "Unknown Payload type in Discovery: %d %s",
1205                                 cbNode->method, cbNode->requestUri);
1206                         return;
1207                     }
1208                 }
1209                 else if (cbNode->method == OC_REST_GET ||
1210                          cbNode->method == OC_REST_PUT ||
1211                          cbNode->method == OC_REST_POST ||
1212                          cbNode->method == OC_REST_OBSERVE ||
1213                          cbNode->method == OC_REST_OBSERVE_ALL ||
1214                          cbNode->method == OC_REST_DELETE)
1215                 {
1216                     char targetUri[MAX_URI_LENGTH];
1217                     snprintf(targetUri, MAX_URI_LENGTH, "%s?rt=%s", OC_RSRVD_RD_URI,
1218                             OC_RSRVD_RESOURCE_TYPE_RDPUBLISH);
1219                     if (strcmp(targetUri, cbNode->requestUri) == 0)
1220                     {
1221                         type = PAYLOAD_TYPE_RD;
1222                     }
1223                     else if (strcmp(OC_RSRVD_PLATFORM_URI, cbNode->requestUri) == 0)
1224                     {
1225                         type = PAYLOAD_TYPE_PLATFORM;
1226                     }
1227                     else if (strcmp(OC_RSRVD_DEVICE_URI, cbNode->requestUri) == 0)
1228                     {
1229                         type = PAYLOAD_TYPE_DEVICE;
1230                     }
1231                     if (type == PAYLOAD_TYPE_INVALID)
1232                     {
1233                         OIC_LOG_V(INFO, TAG, "Assuming PAYLOAD_TYPE_REPRESENTATION: %d %s",
1234                                 cbNode->method, cbNode->requestUri);
1235                         type = PAYLOAD_TYPE_REPRESENTATION;
1236                     }
1237                 }
1238                 else
1239                 {
1240                     OIC_LOG_V(ERROR, TAG, "Unknown Payload type: %d %s",
1241                             cbNode->method, cbNode->requestUri);
1242                     return;
1243                 }
1244
1245                 if(OC_STACK_OK != OCParsePayload(&response.payload,
1246                             type,
1247                             responseInfo->info.payload,
1248                             responseInfo->info.payloadSize))
1249                 {
1250                     OIC_LOG(ERROR, TAG, "Error converting payload");
1251                     OCPayloadDestroy(response.payload);
1252                     return;
1253                 }
1254             }
1255
1256             response.numRcvdVendorSpecificHeaderOptions = 0;
1257             if(responseInfo->info.numOptions > 0)
1258             {
1259                 int start = 0;
1260                 //First option always with option ID is COAP_OPTION_OBSERVE if it is available.
1261                 if(responseInfo->info.options[0].optionID == COAP_OPTION_OBSERVE)
1262                 {
1263                     size_t i;
1264                     uint32_t observationOption;
1265                     uint8_t* optionData = (uint8_t*)responseInfo->info.options[0].optionData;
1266                     for (observationOption=0, i=0;
1267                             i<sizeof(uint32_t) && i<responseInfo->info.options[0].optionLength;
1268                             i++)
1269                     {
1270                         observationOption =
1271                             (observationOption << 8) | optionData[i];
1272                     }
1273                     response.sequenceNumber = observationOption;
1274
1275                     response.numRcvdVendorSpecificHeaderOptions = responseInfo->info.numOptions - 1;
1276                     start = 1;
1277                 }
1278                 else
1279                 {
1280                     response.numRcvdVendorSpecificHeaderOptions = responseInfo->info.numOptions;
1281                 }
1282
1283                 if(response.numRcvdVendorSpecificHeaderOptions > MAX_HEADER_OPTIONS)
1284                 {
1285                     OIC_LOG(ERROR, TAG, "#header options are more than MAX_HEADER_OPTIONS");
1286                     OCPayloadDestroy(response.payload);
1287                     return;
1288                 }
1289
1290                 for (uint8_t i = start; i < responseInfo->info.numOptions; i++)
1291                 {
1292                     memcpy (&(response.rcvdVendorSpecificHeaderOptions[i-start]),
1293                             &(responseInfo->info.options[i]), sizeof(OCHeaderOption));
1294                 }
1295             }
1296
1297             if (cbNode->method == OC_REST_OBSERVE &&
1298                 response.sequenceNumber > OC_OFFSET_SEQUENCE_NUMBER &&
1299                 response.sequenceNumber <= cbNode->sequenceNumber)
1300             {
1301                 OIC_LOG_V(INFO, TAG, "Received stale notification. Number :%d",
1302                                                  response.sequenceNumber);
1303             }
1304             else
1305             {
1306                 OCStackApplicationResult appFeedback = cbNode->callBack(cbNode->context,
1307                                                                         cbNode->handle,
1308                                                                         &response);
1309                 cbNode->sequenceNumber = response.sequenceNumber;
1310
1311                 if (appFeedback == OC_STACK_DELETE_TRANSACTION)
1312                 {
1313                     FindAndDeleteClientCB(cbNode);
1314                 }
1315                 else
1316                 {
1317                     // To keep discovery callbacks active.
1318                     cbNode->TTL = GetTicks(MAX_CB_TIMEOUT_SECONDS *
1319                                             MILLISECONDS_PER_SECOND);
1320                 }
1321             }
1322
1323             //Need to send ACK when the response is CON
1324             if(responseInfo->info.type == CA_MSG_CONFIRM)
1325             {
1326                 SendDirectStackResponse(endPoint, responseInfo->info.messageId, CA_EMPTY,
1327                         CA_MSG_ACKNOWLEDGE, 0, NULL, NULL, 0, NULL);
1328             }
1329
1330             OCPayloadDestroy(response.payload);
1331         }
1332         return;
1333     }
1334
1335     if(observer)
1336     {
1337         OIC_LOG(INFO, TAG, "There is an observer associated with the response token");
1338         if(responseInfo->result == CA_EMPTY)
1339         {
1340             OIC_LOG(INFO, TAG, "Receiving A ACK/RESET for this token");
1341             if(responseInfo->info.type == CA_MSG_RESET)
1342             {
1343                 OIC_LOG(INFO, TAG, "This is a RESET");
1344                 OCStackFeedBack(responseInfo->info.token, responseInfo->info.tokenLength,
1345                         OC_OBSERVER_NOT_INTERESTED);
1346             }
1347             else if(responseInfo->info.type == CA_MSG_ACKNOWLEDGE)
1348             {
1349                 OIC_LOG(INFO, TAG, "This is a pure ACK");
1350                 OCStackFeedBack(responseInfo->info.token, responseInfo->info.tokenLength,
1351                         OC_OBSERVER_STILL_INTERESTED);
1352             }
1353         }
1354         else if(responseInfo->result == CA_RETRANSMIT_TIMEOUT)
1355         {
1356             OIC_LOG(INFO, TAG, "Receiving Time Out for an observer");
1357             OCStackFeedBack(responseInfo->info.token, responseInfo->info.tokenLength,
1358                     OC_OBSERVER_FAILED_COMM);
1359         }
1360         return;
1361     }
1362
1363     if(!cbNode && !observer)
1364     {
1365         if(myStackMode == OC_CLIENT || myStackMode == OC_CLIENT_SERVER
1366            || myStackMode == OC_GATEWAY)
1367         {
1368             OIC_LOG(INFO, TAG, "This is a client, but no cbNode was found for token");
1369             if(responseInfo->result == CA_EMPTY)
1370             {
1371                 OIC_LOG(INFO, TAG, "Receiving CA_EMPTY in the ocstack");
1372             }
1373             else
1374             {
1375                 OIC_LOG(INFO, TAG, "Received a message without callbacks. Sending RESET");
1376                 SendDirectStackResponse(endPoint, responseInfo->info.messageId, CA_EMPTY,
1377                                         CA_MSG_RESET, 0, NULL, NULL, 0, NULL);
1378             }
1379         }
1380
1381         if(myStackMode == OC_SERVER || myStackMode == OC_CLIENT_SERVER
1382            || myStackMode == OC_GATEWAY)
1383         {
1384             OIC_LOG(INFO, TAG, "This is a server, but no observer was found for token");
1385             if (responseInfo->info.type == CA_MSG_ACKNOWLEDGE)
1386             {
1387                 OIC_LOG_V(INFO, TAG, "Received ACK at server for messageId : %d",
1388                                             responseInfo->info.messageId);
1389             }
1390             if (responseInfo->info.type == CA_MSG_RESET)
1391             {
1392                 OIC_LOG_V(INFO, TAG, "Received RESET at server for messageId : %d",
1393                                             responseInfo->info.messageId);
1394             }
1395         }
1396
1397         return;
1398     }
1399
1400     OIC_LOG(INFO, TAG, "Exit OCHandleResponse");
1401 }
1402
1403 void HandleCAResponses(const CAEndpoint_t* endPoint, const CAResponseInfo_t* responseInfo)
1404 {
1405     VERIFY_NON_NULL_NR(endPoint, FATAL);
1406     VERIFY_NON_NULL_NR(responseInfo, FATAL);
1407
1408     OIC_LOG(INFO, TAG, "Enter HandleCAResponses");
1409
1410 #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
1411 #ifdef ROUTING_GATEWAY
1412     bool needRIHandling = false;
1413     /*
1414      * Routing manager is going to update either of endpoint or response or both.
1415      * This typecasting is done to avoid unnecessary duplication of Endpoint and responseInfo
1416      * RM can update "routeData" option in endPoint so that future RI requests can be sent to proper
1417      * destination.
1418      */
1419     OCStackResult ret = RMHandleResponse((CAResponseInfo_t *)responseInfo, (CAEndpoint_t *)endPoint,
1420                                          &needRIHandling);
1421     if(ret != OC_STACK_OK || !needRIHandling)
1422     {
1423         OIC_LOG_V(INFO, TAG, "Routing status![%d]. Not forwarding to RI", ret);
1424         return;
1425     }
1426 #endif
1427
1428     /*
1429      * Put source in sender endpoint so that the next packet from application can be routed to
1430      * proper destination and remove "RM" coap header option before passing request / response to
1431      * RI as this option will make no sense to either RI or application.
1432      */
1433     RMUpdateInfo((CAHeaderOption_t **) &(responseInfo->info.options),
1434                  (uint8_t *) &(responseInfo->info.numOptions),
1435                  (CAEndpoint_t *) endPoint);
1436 #endif
1437
1438     OCHandleResponse(endPoint, responseInfo);
1439
1440     OIC_LOG(INFO, TAG, "Exit HandleCAResponses");
1441 }
1442
1443 /*
1444  * This function handles error response from CA
1445  * code shall be added to handle the errors
1446  */
1447 void HandleCAErrorResponse(const CAEndpoint_t *endPoint, const CAErrorInfo_t *errorInfo)
1448 {
1449     OIC_LOG(INFO, TAG, "Enter HandleCAErrorResponse");
1450
1451     if (NULL == endPoint)
1452     {
1453         OIC_LOG(ERROR, TAG, "endPoint is NULL");
1454         return;
1455     }
1456
1457     if (NULL == errorInfo)
1458     {
1459         OIC_LOG(ERROR, TAG, "errorInfo is NULL");
1460         return;
1461     }
1462
1463     ClientCB *cbNode = GetClientCB(errorInfo->info.token,
1464                                    errorInfo->info.tokenLength, NULL, NULL);
1465     if (cbNode)
1466     {
1467         OCClientResponse response = { .devAddr = { .adapter = OC_DEFAULT_ADAPTER } };
1468         CopyEndpointToDevAddr(endPoint, &response.devAddr);
1469         FixUpClientResponse(&response);
1470         response.resourceUri = errorInfo->info.resourceUri;
1471         memcpy(response.identity.id, errorInfo->info.identity.id,
1472                sizeof (response.identity.id));
1473         response.identity.id_length = errorInfo->info.identity.id_length;
1474         response.result = CAResultToOCStackResult(errorInfo->result);
1475
1476         cbNode->callBack(cbNode->context, cbNode->handle, &response);
1477         FindAndDeleteClientCB(cbNode);
1478     }
1479
1480     OIC_LOG(INFO, TAG, "Exit HandleCAErrorResponse");
1481 }
1482
1483 /*
1484  * This function sends out Direct Stack Responses. These are responses that are not coming
1485  * from the application entity handler. These responses have no payload and are usually ACKs,
1486  * RESETs or some error conditions that were caught by the stack.
1487  */
1488 OCStackResult SendDirectStackResponse(const CAEndpoint_t* endPoint, const uint16_t coapID,
1489         const CAResponseResult_t responseResult, const CAMessageType_t type,
1490         const uint8_t numOptions, const CAHeaderOption_t *options,
1491         CAToken_t token, uint8_t tokenLength, const char *resourceUri)
1492 {
1493     OIC_LOG(DEBUG, TAG, "Entering SendDirectStackResponse");
1494     CAResponseInfo_t respInfo = {
1495         .result = responseResult
1496     };
1497     respInfo.info.messageId = coapID;
1498     respInfo.info.numOptions = numOptions;
1499
1500     if (respInfo.info.numOptions)
1501     {
1502         respInfo.info.options =
1503             (CAHeaderOption_t *)OICCalloc(respInfo.info.numOptions, sizeof(CAHeaderOption_t));
1504         memcpy (respInfo.info.options, options,
1505                 sizeof(CAHeaderOption_t) * respInfo.info.numOptions);
1506
1507     }
1508
1509     respInfo.info.payload = NULL;
1510     respInfo.info.token = token;
1511     respInfo.info.tokenLength = tokenLength;
1512     respInfo.info.type = type;
1513     respInfo.info.resourceUri = OICStrdup (resourceUri);
1514     respInfo.info.acceptFormat = CA_FORMAT_UNDEFINED;
1515
1516 #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
1517     // Add the destination to route option from the endpoint->routeData.
1518     bool doPost = false;
1519     OCStackResult result = RMAddInfo(endPoint->routeData, &respInfo, false, &doPost);
1520     if(OC_STACK_OK != result)
1521     {
1522         OIC_LOG_V(ERROR, TAG, "Add routing option failed [%d]", result);
1523         return result;
1524     }
1525     if (doPost)
1526     {
1527         OIC_LOG(DEBUG, TAG, "Sending a POST message for EMPTY ACK in Client Mode");
1528         CARequestInfo_t reqInfo = {.method = CA_POST };
1529         /* The following initialization is not done in a single initializer block as in
1530          * arduino, .c file is compiled as .cpp and moves it from C99 to C++11.  The latter
1531          * does not have designated initalizers. This is a work-around for now.
1532          */
1533         reqInfo.info.type = CA_MSG_NONCONFIRM;
1534         reqInfo.info.messageId = coapID;
1535         reqInfo.info.tokenLength = tokenLength;
1536         reqInfo.info.token = token;
1537         reqInfo.info.numOptions = respInfo.info.numOptions;
1538         reqInfo.info.payload = NULL;
1539         reqInfo.info.resourceUri = OICStrdup (OC_RSRVD_GATEWAY_URI);
1540         if (reqInfo.info.numOptions)
1541         {
1542             reqInfo.info.options =
1543                 (CAHeaderOption_t *)OICCalloc(reqInfo.info.numOptions, sizeof(CAHeaderOption_t));
1544             if (NULL == reqInfo.info.options)
1545             {
1546                 OIC_LOG(ERROR, TAG, "Calloc failed");
1547                 return OC_STACK_NO_MEMORY;
1548             }
1549             memcpy (reqInfo.info.options, respInfo.info.options,
1550                     sizeof(CAHeaderOption_t) * reqInfo.info.numOptions);
1551
1552         }
1553         CAResult_t caResult = CASendRequest(endPoint, &reqInfo);
1554         OICFree (reqInfo.info.resourceUri);
1555         OICFree (reqInfo.info.options);
1556         OICFree (respInfo.info.resourceUri);
1557         OICFree (respInfo.info.options);
1558         if (CA_STATUS_OK != caResult)
1559         {
1560             OIC_LOG(ERROR, TAG, "CASendRequest error");
1561             return CAResultToOCResult(caResult);
1562         }
1563     }
1564     else
1565 #endif
1566     {
1567         CAResult_t caResult = CASendResponse(endPoint, &respInfo);
1568
1569         // resourceUri in the info field is cloned in the CA layer and
1570         // thus ownership is still here.
1571         OICFree (respInfo.info.resourceUri);
1572         OICFree (respInfo.info.options);
1573         if(CA_STATUS_OK != caResult)
1574         {
1575             OIC_LOG(ERROR, TAG, "CASendResponse error");
1576             return CAResultToOCResult(caResult);
1577         }
1578     }
1579     OIC_LOG(DEBUG, TAG, "Exit SendDirectStackResponse");
1580     return OC_STACK_OK;
1581 }
1582
1583 OCStackResult HandleStackRequests(OCServerProtocolRequest * protocolRequest)
1584 {
1585     OIC_LOG(INFO, TAG, "Entering HandleStackRequests (OCStack Layer)");
1586     OCStackResult result = OC_STACK_ERROR;
1587     if(!protocolRequest)
1588     {
1589         OIC_LOG(ERROR, TAG, "protocolRequest is NULL");
1590         return OC_STACK_INVALID_PARAM;
1591     }
1592
1593     OCServerRequest * request = GetServerRequestUsingToken(protocolRequest->requestToken,
1594             protocolRequest->tokenLength);
1595     if(!request)
1596     {
1597         OIC_LOG(INFO, TAG, "This is a new Server Request");
1598         result = AddServerRequest(&request, protocolRequest->coapID,
1599                 protocolRequest->delayedResNeeded, 0, protocolRequest->method,
1600                 protocolRequest->numRcvdVendorSpecificHeaderOptions,
1601                 protocolRequest->observationOption, protocolRequest->qos,
1602                 protocolRequest->query, protocolRequest->rcvdVendorSpecificHeaderOptions,
1603                 protocolRequest->payload, protocolRequest->requestToken,
1604                 protocolRequest->tokenLength, protocolRequest->resourceUrl,
1605                 protocolRequest->reqTotalSize, protocolRequest->acceptFormat,
1606                 &protocolRequest->devAddr);
1607         if (OC_STACK_OK != result)
1608         {
1609             OIC_LOG(ERROR, TAG, "Error adding server request");
1610             return result;
1611         }
1612
1613         if(!request)
1614         {
1615             OIC_LOG(ERROR, TAG, "Out of Memory");
1616             return OC_STACK_NO_MEMORY;
1617         }
1618
1619         if(!protocolRequest->reqMorePacket)
1620         {
1621             request->requestComplete = 1;
1622         }
1623     }
1624     else
1625     {
1626         OIC_LOG(INFO, TAG, "This is either a repeated or blocked Server Request");
1627     }
1628
1629     if(request->requestComplete)
1630     {
1631         OIC_LOG(INFO, TAG, "This Server Request is complete");
1632         ResourceHandling resHandling = OC_RESOURCE_VIRTUAL;
1633         OCResource *resource = NULL;
1634         result = DetermineResourceHandling (request, &resHandling, &resource);
1635         if (result == OC_STACK_OK)
1636         {
1637             result = ProcessRequest(resHandling, resource, request);
1638         }
1639     }
1640     else
1641     {
1642         OIC_LOG(INFO, TAG, "This Server Request is incomplete");
1643         result = OC_STACK_CONTINUE;
1644     }
1645     return result;
1646 }
1647
1648 void OCHandleRequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* requestInfo)
1649 {
1650     OIC_LOG(DEBUG, TAG, "Enter OCHandleRequests");
1651
1652 #ifdef TCP_ADAPTER
1653     if (requestInfo->info.resourceUri &&
1654             strcmp(requestInfo->info.resourceUri, KEEPALIVE_RESOURCE_URI) == 0)
1655     {
1656         HandleKeepAliveRequest(endPoint, requestInfo);
1657         return;
1658     }
1659 #endif
1660
1661     OCStackResult requestResult = OC_STACK_ERROR;
1662
1663     if(myStackMode == OC_CLIENT)
1664     {
1665         //TODO: should the client be responding to requests?
1666         return;
1667     }
1668
1669     OCServerProtocolRequest serverRequest = {0};
1670
1671     OIC_LOG_V(INFO, TAG, "Endpoint URI : %s", requestInfo->info.resourceUri);
1672
1673     char * uriWithoutQuery = NULL;
1674     char * query  = NULL;
1675
1676     requestResult = getQueryFromUri(requestInfo->info.resourceUri, &query, &uriWithoutQuery);
1677
1678     if (requestResult != OC_STACK_OK || !uriWithoutQuery)
1679     {
1680         OIC_LOG_V(ERROR, TAG, "getQueryFromUri() failed with OC error code %d\n", requestResult);
1681         return;
1682     }
1683     OIC_LOG_V(INFO, TAG, "URI without query: %s", uriWithoutQuery);
1684     OIC_LOG_V(INFO, TAG, "Query : %s", query);
1685
1686     if(strlen(uriWithoutQuery) < MAX_URI_LENGTH)
1687     {
1688         OICStrcpy(serverRequest.resourceUrl, sizeof(serverRequest.resourceUrl), uriWithoutQuery);
1689         OICFree(uriWithoutQuery);
1690     }
1691     else
1692     {
1693         OIC_LOG(ERROR, TAG, "URI length exceeds MAX_URI_LENGTH.");
1694         OICFree(uriWithoutQuery);
1695         OICFree(query);
1696         return;
1697     }
1698
1699     if(query)
1700     {
1701         if(strlen(query) < MAX_QUERY_LENGTH)
1702         {
1703             OICStrcpy(serverRequest.query, sizeof(serverRequest.query), query);
1704             OICFree(query);
1705         }
1706         else
1707         {
1708             OIC_LOG(ERROR, TAG, "Query length exceeds MAX_QUERY_LENGTH.");
1709             OICFree(query);
1710             return;
1711         }
1712     }
1713
1714     if ((requestInfo->info.payload) && (0 < requestInfo->info.payloadSize))
1715     {
1716         serverRequest.reqTotalSize = requestInfo->info.payloadSize;
1717         serverRequest.payload = (uint8_t *) OICMalloc(requestInfo->info.payloadSize);
1718         if (!serverRequest.payload)
1719         {
1720             OIC_LOG(ERROR, TAG, "Allocation for payload failed.");
1721             return;
1722         }
1723         memcpy (serverRequest.payload, requestInfo->info.payload,
1724                 requestInfo->info.payloadSize);
1725     }
1726     else
1727     {
1728         serverRequest.reqTotalSize = 0;
1729     }
1730
1731     switch (requestInfo->method)
1732     {
1733         case CA_GET:
1734             serverRequest.method = OC_REST_GET;
1735             break;
1736         case CA_PUT:
1737             serverRequest.method = OC_REST_PUT;
1738             break;
1739         case CA_POST:
1740             serverRequest.method = OC_REST_POST;
1741             break;
1742         case CA_DELETE:
1743             serverRequest.method = OC_REST_DELETE;
1744             break;
1745         default:
1746             OIC_LOG_V(ERROR, TAG, "Received CA method %d not supported", requestInfo->method);
1747             SendDirectStackResponse(endPoint, requestInfo->info.messageId, CA_BAD_REQ,
1748                         requestInfo->info.type, requestInfo->info.numOptions,
1749                         requestInfo->info.options, requestInfo->info.token,
1750                         requestInfo->info.tokenLength, requestInfo->info.resourceUri);
1751             OICFree(serverRequest.payload);
1752             return;
1753     }
1754
1755     OIC_LOG_BUFFER(INFO, TAG, (const uint8_t *)requestInfo->info.token,
1756             requestInfo->info.tokenLength);
1757
1758     serverRequest.tokenLength = requestInfo->info.tokenLength;
1759     if (serverRequest.tokenLength) {
1760         // Non empty token
1761         serverRequest.requestToken = (CAToken_t)OICMalloc(requestInfo->info.tokenLength);
1762
1763         if (!serverRequest.requestToken)
1764         {
1765             OIC_LOG(FATAL, TAG, "Allocation for token failed.");
1766             SendDirectStackResponse(endPoint, requestInfo->info.messageId, CA_INTERNAL_SERVER_ERROR,
1767                     requestInfo->info.type, requestInfo->info.numOptions,
1768                     requestInfo->info.options, requestInfo->info.token,
1769                     requestInfo->info.tokenLength, requestInfo->info.resourceUri);
1770             OICFree(serverRequest.payload);
1771             return;
1772         }
1773         memcpy(serverRequest.requestToken, requestInfo->info.token, requestInfo->info.tokenLength);
1774     }
1775
1776     switch (requestInfo->info.acceptFormat)
1777     {
1778         case CA_FORMAT_APPLICATION_CBOR:
1779             serverRequest.acceptFormat = OC_FORMAT_CBOR;
1780             break;
1781         case CA_FORMAT_UNDEFINED:
1782             serverRequest.acceptFormat = OC_FORMAT_UNDEFINED;
1783             break;
1784         default:
1785             serverRequest.acceptFormat = OC_FORMAT_UNSUPPORTED;
1786     }
1787
1788     if (requestInfo->info.type == CA_MSG_CONFIRM)
1789     {
1790         serverRequest.qos = OC_HIGH_QOS;
1791     }
1792     else
1793     {
1794         serverRequest.qos = OC_LOW_QOS;
1795     }
1796     // CA does not need the following field
1797     // Are we sure CA does not need them? how is it responding to multicast
1798     serverRequest.delayedResNeeded = 0;
1799
1800     serverRequest.coapID = requestInfo->info.messageId;
1801
1802     CopyEndpointToDevAddr(endPoint, &serverRequest.devAddr);
1803
1804     // copy vendor specific header options
1805     uint8_t tempNum = (requestInfo->info.numOptions);
1806
1807     // Assume no observation requested and it is a pure GET.
1808     // If obs registration/de-registration requested it'll be fetched from the
1809     // options in GetObserveHeaderOption()
1810     serverRequest.observationOption = OC_OBSERVE_NO_OPTION;
1811
1812     GetObserveHeaderOption(&serverRequest.observationOption, requestInfo->info.options, &tempNum);
1813     if (requestInfo->info.numOptions > MAX_HEADER_OPTIONS)
1814     {
1815         OIC_LOG(ERROR, TAG,
1816                 "The request info numOptions is greater than MAX_HEADER_OPTIONS");
1817         SendDirectStackResponse(endPoint, requestInfo->info.messageId, CA_BAD_OPT,
1818                 requestInfo->info.type, requestInfo->info.numOptions,
1819                 requestInfo->info.options, requestInfo->info.token,
1820                 requestInfo->info.tokenLength, requestInfo->info.resourceUri);
1821         OICFree(serverRequest.payload);
1822         OICFree(serverRequest.requestToken);
1823         return;
1824     }
1825     serverRequest.numRcvdVendorSpecificHeaderOptions = tempNum;
1826     if (serverRequest.numRcvdVendorSpecificHeaderOptions)
1827     {
1828         memcpy (&(serverRequest.rcvdVendorSpecificHeaderOptions), requestInfo->info.options,
1829             sizeof(CAHeaderOption_t)*tempNum);
1830     }
1831
1832     requestResult = HandleStackRequests (&serverRequest);
1833
1834     // Send ACK to client as precursor to slow response
1835     if (requestResult == OC_STACK_SLOW_RESOURCE)
1836     {
1837         if (requestInfo->info.type == CA_MSG_CONFIRM)
1838         {
1839             SendDirectStackResponse(endPoint, requestInfo->info.messageId, CA_EMPTY,
1840                                     CA_MSG_ACKNOWLEDGE,0, NULL, NULL, 0, NULL);
1841         }
1842     }
1843     else if(requestResult != OC_STACK_OK)
1844     {
1845         OIC_LOG_V(ERROR, TAG, "HandleStackRequests failed. error: %d", requestResult);
1846
1847         CAResponseResult_t stackResponse =
1848             OCToCAStackResult(requestResult, serverRequest.method);
1849
1850         SendDirectStackResponse(endPoint, requestInfo->info.messageId, stackResponse,
1851                 requestInfo->info.type, requestInfo->info.numOptions,
1852                 requestInfo->info.options, requestInfo->info.token,
1853                 requestInfo->info.tokenLength, requestInfo->info.resourceUri);
1854     }
1855     // requestToken is fed to HandleStackRequests, which then goes to AddServerRequest.
1856     // The token is copied in there, and is thus still owned by this function.
1857     OICFree(serverRequest.payload);
1858     OICFree(serverRequest.requestToken);
1859     OIC_LOG(INFO, TAG, "Exit OCHandleRequests");
1860 }
1861
1862 //This function will be called back by CA layer when a request is received
1863 void HandleCARequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* requestInfo)
1864 {
1865     OIC_LOG(INFO, TAG, "Enter HandleCARequests");
1866     if(!endPoint)
1867     {
1868         OIC_LOG(ERROR, TAG, "endPoint is NULL");
1869         return;
1870     }
1871
1872     if(!requestInfo)
1873     {
1874         OIC_LOG(ERROR, TAG, "requestInfo is NULL");
1875         return;
1876     }
1877
1878 #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
1879 #ifdef ROUTING_GATEWAY
1880     bool needRIHandling = false;
1881     bool isEmptyMsg = false;
1882     /*
1883      * Routing manager is going to update either of endpoint or request or both.
1884      * This typecasting is done to avoid unnecessary duplication of Endpoint and requestInfo
1885      * RM can update "routeData" option in endPoint so that future RI requests can be sent to proper
1886      * destination. It can also remove "RM" coap header option before passing request / response to
1887      * RI as this option will make no sense to either RI or application.
1888      */
1889     OCStackResult ret = RMHandleRequest((CARequestInfo_t *)requestInfo, (CAEndpoint_t *)endPoint,
1890                                         &needRIHandling, &isEmptyMsg);
1891     if(OC_STACK_OK != ret || !needRIHandling)
1892     {
1893         OIC_LOG_V(INFO, TAG, "Routing status![%d]. Not forwarding to RI", ret);
1894         return;
1895     }
1896 #endif
1897
1898     /*
1899      * Put source in sender endpoint so that the next packet from application can be routed to
1900      * proper destination and remove RM header option.
1901      */
1902     RMUpdateInfo((CAHeaderOption_t **) &(requestInfo->info.options),
1903                  (uint8_t *) &(requestInfo->info.numOptions),
1904                  (CAEndpoint_t *) endPoint);
1905
1906 #ifdef ROUTING_GATEWAY
1907     if (isEmptyMsg)
1908     {
1909         /*
1910          * In Gateways, the MSGType in route option is used to check if the actual
1911          * response is EMPTY message(4 bytes CoAP Header).  In case of Client, the
1912          * EMPTY response is sent in the form of POST request which need to be changed
1913          * to a EMPTY response by RM.  This translation is done in this part of the code.
1914          */
1915         OIC_LOG(INFO, TAG, "This is a Empty response from the Client");
1916         CAResponseInfo_t respInfo = {.result = CA_EMPTY,
1917                                      .info.messageId = requestInfo->info.messageId,
1918                                      .info.type = CA_MSG_ACKNOWLEDGE};
1919         OCHandleResponse(endPoint, &respInfo);
1920     }
1921     else
1922 #endif
1923 #endif
1924     {
1925         // Normal handling of the packet
1926         OCHandleRequests(endPoint, requestInfo);
1927     }
1928     OIC_LOG(INFO, TAG, "Exit HandleCARequests");
1929 }
1930
1931 bool validatePlatformInfo(OCPlatformInfo info)
1932 {
1933
1934     if (!info.platformID)
1935     {
1936         OIC_LOG(ERROR, TAG, "No platform ID found.");
1937         return false;
1938     }
1939
1940     if (info.manufacturerName)
1941     {
1942         size_t lenManufacturerName = strlen(info.manufacturerName);
1943
1944         if(lenManufacturerName == 0 || lenManufacturerName > MAX_MANUFACTURER_NAME_LENGTH)
1945         {
1946             OIC_LOG(ERROR, TAG, "Manufacturer name fails length requirements.");
1947             return false;
1948         }
1949     }
1950     else
1951     {
1952         OIC_LOG(ERROR, TAG, "No manufacturer name present");
1953         return false;
1954     }
1955
1956     if (info.manufacturerUrl)
1957     {
1958         if(strlen(info.manufacturerUrl) > MAX_MANUFACTURER_URL_LENGTH)
1959         {
1960             OIC_LOG(ERROR, TAG, "Manufacturer url fails length requirements.");
1961             return false;
1962         }
1963     }
1964     return true;
1965 }
1966
1967 //-----------------------------------------------------------------------------
1968 // Public APIs
1969 //-----------------------------------------------------------------------------
1970 #ifdef RA_ADAPTER
1971 OCStackResult OCSetRAInfo(const OCRAInfo_t *raInfo)
1972 {
1973     if (!raInfo           ||
1974         !raInfo->username ||
1975         !raInfo->hostname ||
1976         !raInfo->xmpp_domain)
1977     {
1978
1979         return OC_STACK_INVALID_PARAM;
1980     }
1981     OCStackResult result = CAResultToOCResult(CASetRAInfo((const CARAInfo_t *) raInfo));
1982     gRASetInfo = (result == OC_STACK_OK)? true : false;
1983
1984     return result;
1985 }
1986 #endif
1987
1988 OCStackResult OCInit(const char *ipAddr, uint16_t port, OCMode mode)
1989 {
1990     (void) ipAddr;
1991     (void) port;
1992     return OCInit1(mode, OC_DEFAULT_FLAGS, OC_DEFAULT_FLAGS);
1993 }
1994
1995 OCStackResult OCInit1(OCMode mode, OCTransportFlags serverFlags, OCTransportFlags clientFlags)
1996 {
1997     if(stackState == OC_STACK_INITIALIZED)
1998     {
1999         OIC_LOG(INFO, TAG, "Subsequent calls to OCInit() without calling \
2000                 OCStop() between them are ignored.");
2001         return OC_STACK_OK;
2002     }
2003
2004 #ifndef ROUTING_GATEWAY
2005     if (OC_GATEWAY == mode)
2006     {
2007         OIC_LOG(ERROR, TAG, "Routing Manager not supported");
2008         return OC_STACK_INVALID_PARAM;
2009     }
2010 #endif
2011
2012 #ifdef RA_ADAPTER
2013     if(!gRASetInfo)
2014     {
2015         OIC_LOG(ERROR, TAG, "Need to call OCSetRAInfo before calling OCInit");
2016         return OC_STACK_ERROR;
2017     }
2018 #endif
2019
2020     OCStackResult result = OC_STACK_ERROR;
2021     OIC_LOG(INFO, TAG, "Entering OCInit");
2022
2023     // Validate mode
2024     if (!((mode == OC_CLIENT) || (mode == OC_SERVER) || (mode == OC_CLIENT_SERVER)
2025         || (mode == OC_GATEWAY)))
2026     {
2027         OIC_LOG(ERROR, TAG, "Invalid mode");
2028         return OC_STACK_ERROR;
2029     }
2030     myStackMode = mode;
2031
2032     if (mode == OC_CLIENT || mode == OC_CLIENT_SERVER || mode == OC_GATEWAY)
2033     {
2034         caglobals.client = true;
2035     }
2036     if (mode == OC_SERVER || mode == OC_CLIENT_SERVER || mode == OC_GATEWAY)
2037     {
2038         caglobals.server = true;
2039     }
2040
2041     caglobals.serverFlags = (CATransportFlags_t)serverFlags;
2042     if (!(caglobals.serverFlags & CA_IPFAMILY_MASK))
2043     {
2044         caglobals.serverFlags = (CATransportFlags_t)(caglobals.serverFlags|CA_IPV4|CA_IPV6);
2045     }
2046     caglobals.clientFlags = (CATransportFlags_t)clientFlags;
2047     if (!(caglobals.clientFlags & CA_IPFAMILY_MASK))
2048     {
2049         caglobals.clientFlags = (CATransportFlags_t)(caglobals.clientFlags|CA_IPV4|CA_IPV6);
2050     }
2051
2052     defaultDeviceHandler = NULL;
2053     defaultDeviceHandlerCallbackParameter = NULL;
2054
2055     result = CAResultToOCResult(CAInitialize());
2056     VERIFY_SUCCESS(result, OC_STACK_OK);
2057
2058     result = CAResultToOCResult(OCSelectNetwork());
2059     VERIFY_SUCCESS(result, OC_STACK_OK);
2060
2061     switch (myStackMode)
2062     {
2063         case OC_CLIENT:
2064             CARegisterHandler(HandleCARequests, HandleCAResponses, HandleCAErrorResponse);
2065             result = CAResultToOCResult(CAStartDiscoveryServer());
2066             OIC_LOG(INFO, TAG, "Client mode: CAStartDiscoveryServer");
2067             break;
2068         case OC_SERVER:
2069             SRMRegisterHandler(HandleCARequests, HandleCAResponses, HandleCAErrorResponse);
2070             result = CAResultToOCResult(CAStartListeningServer());
2071             OIC_LOG(INFO, TAG, "Server mode: CAStartListeningServer");
2072             break;
2073         case OC_CLIENT_SERVER:
2074         case OC_GATEWAY:
2075             SRMRegisterHandler(HandleCARequests, HandleCAResponses, HandleCAErrorResponse);
2076             result = CAResultToOCResult(CAStartListeningServer());
2077             if(result == OC_STACK_OK)
2078             {
2079                 result = CAResultToOCResult(CAStartDiscoveryServer());
2080             }
2081             break;
2082     }
2083     VERIFY_SUCCESS(result, OC_STACK_OK);
2084
2085 #ifdef TCP_ADAPTER
2086     CARegisterKeepAliveHandler(HandleKeepAliveConnCB);
2087 #endif
2088
2089 #ifdef WITH_PRESENCE
2090     PresenceTimeOutSize = sizeof (PresenceTimeOut) / sizeof (PresenceTimeOut[0]) - 1;
2091 #endif // WITH_PRESENCE
2092
2093     //Update Stack state to initialized
2094     stackState = OC_STACK_INITIALIZED;
2095
2096     // Initialize resource
2097     if(myStackMode != OC_CLIENT)
2098     {
2099         result = initResources();
2100     }
2101
2102     // Initialize the SRM Policy Engine
2103     if(result == OC_STACK_OK)
2104     {
2105         result = SRMInitPolicyEngine();
2106         // TODO after BeachHead delivery: consolidate into single SRMInit()
2107     }
2108 #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
2109     RMSetStackMode(mode);
2110 #ifdef ROUTING_GATEWAY
2111     if (OC_GATEWAY == myStackMode)
2112     {
2113         result = RMInitialize();
2114     }
2115 #endif
2116 #endif
2117
2118 #ifdef TCP_ADAPTER
2119     if (result == OC_STACK_OK)
2120     {
2121         result = InitializeKeepAlive(myStackMode);
2122     }
2123 #endif
2124
2125 exit:
2126     if(result != OC_STACK_OK)
2127     {
2128         OIC_LOG(ERROR, TAG, "Stack initialization error");
2129         deleteAllResources();
2130         CATerminate();
2131         stackState = OC_STACK_UNINITIALIZED;
2132     }
2133     return result;
2134 }
2135
2136 OCStackResult OCStop()
2137 {
2138     OIC_LOG(INFO, TAG, "Entering OCStop");
2139
2140     if (stackState == OC_STACK_UNINIT_IN_PROGRESS)
2141     {
2142         OIC_LOG(DEBUG, TAG, "Stack already stopping, exiting");
2143         return OC_STACK_OK;
2144     }
2145     else if (stackState != OC_STACK_INITIALIZED)
2146     {
2147         OIC_LOG(ERROR, TAG, "Stack not initialized");
2148         return OC_STACK_ERROR;
2149     }
2150
2151     stackState = OC_STACK_UNINIT_IN_PROGRESS;
2152
2153 #ifdef WITH_PRESENCE
2154     // Ensure that the TTL associated with ANY and ALL presence notifications originating from
2155     // here send with the code "OC_STACK_PRESENCE_STOPPED" result.
2156     presenceResource.presenceTTL = 0;
2157 #endif // WITH_PRESENCE
2158
2159 #ifdef ROUTING_GATEWAY
2160     if (OC_GATEWAY == myStackMode)
2161     {
2162         RMTerminate();
2163     }
2164 #endif
2165
2166 #ifdef TCP_ADAPTER
2167     TerminateKeepAlive(myStackMode);
2168 #endif
2169
2170     // Free memory dynamically allocated for resources
2171     deleteAllResources();
2172     DeleteDeviceInfo();
2173     DeletePlatformInfo();
2174     CATerminate();
2175     // Remove all observers
2176     DeleteObserverList();
2177     // Remove all the client callbacks
2178     DeleteClientCBList();
2179
2180     // De-init the SRM Policy Engine
2181     // TODO after BeachHead delivery: consolidate into single SRMDeInit()
2182     SRMDeInitPolicyEngine();
2183
2184
2185     stackState = OC_STACK_UNINITIALIZED;
2186     return OC_STACK_OK;
2187 }
2188
2189 OCStackResult OCStartMulticastServer()
2190 {
2191     if(stackState != OC_STACK_INITIALIZED)
2192     {
2193         OIC_LOG(ERROR, TAG, "OCStack is not initalized. Cannot start multicast server.");
2194         return OC_STACK_ERROR;
2195     }
2196     CAResult_t ret = CAStartListeningServer();
2197     if (CA_STATUS_OK != ret)
2198     {
2199         OIC_LOG_V(ERROR, TAG, "Failed starting listening server: %d", ret);
2200         return OC_STACK_ERROR;
2201     }
2202     return OC_STACK_OK;
2203 }
2204
2205 OCStackResult OCStopMulticastServer()
2206 {
2207     CAResult_t ret = CAStopListeningServer();
2208     if (CA_STATUS_OK != ret)
2209     {
2210         OIC_LOG_V(ERROR, TAG, "Failed stopping listening server: %d", ret);
2211         return OC_STACK_ERROR;
2212     }
2213     return OC_STACK_OK;
2214 }
2215
2216 CAMessageType_t qualityOfServiceToMessageType(OCQualityOfService qos)
2217 {
2218     switch (qos)
2219     {
2220         case OC_HIGH_QOS:
2221             return CA_MSG_CONFIRM;
2222         case OC_LOW_QOS:
2223         case OC_MEDIUM_QOS:
2224         case OC_NA_QOS:
2225         default:
2226             return CA_MSG_NONCONFIRM;
2227     }
2228 }
2229
2230 /**
2231  *  A request uri consists of the following components in order:
2232  *                              example
2233  *  optionally one of
2234  *      CoAP over UDP prefix    "coap://"
2235  *      CoAP over TCP prefix    "coap+tcp://"
2236  *  optionally one of
2237  *      IPv6 address            "[1234::5678]"
2238  *      IPv4 address            "192.168.1.1"
2239  *  optional port               ":5683"
2240  *  resource uri                "/oc/core..."
2241  *
2242  *  for PRESENCE requests, extract resource type.
2243  */
2244 static OCStackResult ParseRequestUri(const char *fullUri,
2245                                         OCTransportAdapter adapter,
2246                                         OCTransportFlags flags,
2247                                         OCDevAddr **devAddr,
2248                                         char **resourceUri,
2249                                         char **resourceType)
2250 {
2251     VERIFY_NON_NULL(fullUri, FATAL, OC_STACK_INVALID_CALLBACK);
2252
2253     OCStackResult result = OC_STACK_OK;
2254     OCDevAddr *da = NULL;
2255     char *colon = NULL;
2256     char *end;
2257
2258     // provide defaults for all returned values
2259     if (devAddr)
2260     {
2261         *devAddr = NULL;
2262     }
2263     if (resourceUri)
2264     {
2265         *resourceUri = NULL;
2266     }
2267     if (resourceType)
2268     {
2269         *resourceType = NULL;
2270     }
2271
2272     // delimit url prefix, if any
2273     const char *start = fullUri;
2274     char *slash2 = strstr(start, "//");
2275     if (slash2)
2276     {
2277         start = slash2 + 2;
2278     }
2279     char *slash = strchr(start, '/');
2280     if (!slash)
2281     {
2282         return OC_STACK_INVALID_URI;
2283     }
2284
2285     // process url scheme
2286     size_t prefixLen = slash2 - fullUri;
2287     bool istcp = false;
2288     if (prefixLen)
2289     {
2290         if ((prefixLen == sizeof(COAP_TCP) - 1) && (!strncmp(fullUri, COAP_TCP, prefixLen)))
2291         {
2292             istcp = true;
2293         }
2294     }
2295
2296     // TODO: this logic should come in with unit tests exercising the various strings
2297     // processs url prefix, if any
2298     size_t urlLen = slash - start;
2299     // port
2300     uint16_t port = 0;
2301     size_t len = 0;
2302     if (urlLen && devAddr)
2303     {   // construct OCDevAddr
2304         if (start[0] == '[')
2305         {   // ipv6 address
2306             char *close = strchr(++start, ']');
2307             if (!close || close > slash)
2308             {
2309                 return OC_STACK_INVALID_URI;
2310             }
2311             end = close;
2312             if (close[1] == ':')
2313             {
2314                 colon = close + 1;
2315             }
2316
2317             if (istcp)
2318             {
2319                 adapter = (OCTransportAdapter)(adapter | OC_ADAPTER_TCP);
2320             }
2321             else
2322             {
2323                 adapter = (OCTransportAdapter)(adapter | OC_ADAPTER_IP);
2324             }
2325             flags = (OCTransportFlags)(flags | OC_IP_USE_V6);
2326         }
2327         else
2328         {
2329             char *dot = strchr(start, '.');
2330             if (dot && dot < slash)
2331             {   // ipv4 address
2332                 colon = strchr(start, ':');
2333                 end = (colon && colon < slash) ? colon : slash;
2334
2335                 if (istcp)
2336                 {
2337                     // coap over tcp
2338                     adapter = (OCTransportAdapter)(adapter | OC_ADAPTER_TCP);
2339                 }
2340                 else
2341                 {
2342                     adapter = (OCTransportAdapter)(adapter | OC_ADAPTER_IP);
2343                 }
2344                 flags = (OCTransportFlags)(flags | OC_IP_USE_V4);
2345             }
2346             else
2347             {   // MAC address
2348                 end = slash;
2349             }
2350         }
2351         len = end - start;
2352         if (len >= sizeof(da->addr))
2353         {
2354             return OC_STACK_INVALID_URI;
2355         }
2356         // collect port, if any
2357         if (colon && colon < slash)
2358         {
2359             for (colon++; colon < slash; colon++)
2360             {
2361                 char c = colon[0];
2362                 if (c < '0' || c > '9')
2363                 {
2364                     return OC_STACK_INVALID_URI;
2365                 }
2366                 port = 10 * port + c - '0';
2367             }
2368         }
2369
2370         len = end - start;
2371         if (len >= sizeof(da->addr))
2372         {
2373             return OC_STACK_INVALID_URI;
2374         }
2375
2376         da = (OCDevAddr *)OICCalloc(sizeof (OCDevAddr), 1);
2377         if (!da)
2378         {
2379             return OC_STACK_NO_MEMORY;
2380         }
2381         OICStrcpyPartial(da->addr, sizeof(da->addr), start, len);
2382         da->port = port;
2383         da->adapter = adapter;
2384         da->flags = flags;
2385         if (!strncmp(fullUri, "coaps:", 6))
2386         {
2387             da->flags = (OCTransportFlags)(da->flags|CA_SECURE);
2388         }
2389         *devAddr = da;
2390     }
2391
2392     // process resource uri, if any
2393     if (slash)
2394     {   // request uri and query
2395         size_t ulen = strlen(slash); // resource uri length
2396         size_t tlen = 0;      // resource type length
2397         char *type = NULL;
2398
2399         static const char strPresence[] = "/oic/ad?rt=";
2400         static const size_t lenPresence = sizeof(strPresence) - 1;
2401         if (!strncmp(slash, strPresence, lenPresence))
2402         {
2403             type = slash + lenPresence;
2404             tlen = ulen - lenPresence;
2405         }
2406         // resource uri
2407         if (resourceUri)
2408         {
2409             *resourceUri = (char *)OICMalloc(ulen + 1);
2410             if (!*resourceUri)
2411             {
2412                 result = OC_STACK_NO_MEMORY;
2413                 goto error;
2414             }
2415             strcpy(*resourceUri, slash);
2416         }
2417         // resource type
2418         if (type && resourceType)
2419         {
2420             *resourceType = (char *)OICMalloc(tlen + 1);
2421             if (!*resourceType)
2422             {
2423                 result = OC_STACK_NO_MEMORY;
2424                 goto error;
2425             }
2426
2427             OICStrcpy(*resourceType, (tlen+1), type);
2428         }
2429     }
2430
2431     return OC_STACK_OK;
2432
2433 error:
2434     // free all returned values
2435     if (devAddr)
2436     {
2437         OICFree(*devAddr);
2438     }
2439     if (resourceUri)
2440     {
2441         OICFree(*resourceUri);
2442     }
2443     if (resourceType)
2444     {
2445         OICFree(*resourceType);
2446     }
2447     return result;
2448 }
2449
2450 static OCStackResult OCPreparePresence(CAEndpoint_t *endpoint,
2451                                         char *resourceUri, char **requestUri)
2452 {
2453     char uri[CA_MAX_URI_LENGTH];
2454
2455     FormCanonicalPresenceUri(endpoint, resourceUri, uri);
2456
2457     *requestUri = OICStrdup(uri);
2458     if (!*requestUri)
2459     {
2460         return OC_STACK_NO_MEMORY;
2461     }
2462
2463     return OC_STACK_OK;
2464 }
2465
2466 /**
2467  * Discover or Perform requests on a specified resource
2468  */
2469 OCStackResult OCDoResource(OCDoHandle *handle,
2470                             OCMethod method,
2471                             const char *requestUri,
2472                             const OCDevAddr *destination,
2473                             OCPayload* payload,
2474                             OCConnectivityType connectivityType,
2475                             OCQualityOfService qos,
2476                             OCCallbackData *cbData,
2477                             OCHeaderOption *options,
2478                             uint8_t numOptions)
2479 {
2480     OIC_LOG(INFO, TAG, "Entering OCDoResource");
2481
2482     // Validate input parameters
2483     VERIFY_NON_NULL(cbData, FATAL, OC_STACK_INVALID_CALLBACK);
2484     VERIFY_NON_NULL(cbData->cb, FATAL, OC_STACK_INVALID_CALLBACK);
2485     VERIFY_NON_NULL(requestUri , FATAL, OC_STACK_INVALID_URI);
2486
2487     OCStackResult result = OC_STACK_ERROR;
2488     CAResult_t caResult;
2489     CAToken_t token = NULL;
2490     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
2491     ClientCB *clientCB = NULL;
2492     OCDoHandle resHandle = NULL;
2493     CAEndpoint_t endpoint = {.adapter = CA_DEFAULT_ADAPTER};
2494     OCDevAddr tmpDevAddr = { OC_DEFAULT_ADAPTER };
2495     uint32_t ttl = 0;
2496     OCTransportAdapter adapter;
2497     OCTransportFlags flags;
2498     // the request contents are put here
2499     CARequestInfo_t requestInfo = {.method = CA_GET};
2500     // requestUri  will be parsed into the following three variables
2501     OCDevAddr *devAddr = NULL;
2502     char *resourceUri = NULL;
2503     char *resourceType = NULL;
2504
2505     /*
2506      * Support original behavior with address on resourceUri argument.
2507      */
2508     adapter = (OCTransportAdapter)(connectivityType >> CT_ADAPTER_SHIFT);
2509     flags = (OCTransportFlags)(connectivityType & CT_MASK_FLAGS);
2510
2511     result = ParseRequestUri(requestUri, adapter, flags, &devAddr, &resourceUri, &resourceType);
2512
2513     if (result != OC_STACK_OK)
2514     {
2515         OIC_LOG_V(DEBUG, TAG, "Unable to parse uri: %s", requestUri);
2516         goto exit;
2517     }
2518
2519     switch (method)
2520     {
2521     case OC_REST_GET:
2522     case OC_REST_OBSERVE:
2523     case OC_REST_OBSERVE_ALL:
2524     case OC_REST_CANCEL_OBSERVE:
2525         requestInfo.method = CA_GET;
2526         break;
2527     case OC_REST_PUT:
2528         requestInfo.method = CA_PUT;
2529         break;
2530     case OC_REST_POST:
2531         requestInfo.method = CA_POST;
2532         break;
2533     case OC_REST_DELETE:
2534         requestInfo.method = CA_DELETE;
2535         break;
2536     case OC_REST_DISCOVER:
2537         qos = OC_LOW_QOS;
2538         if (destination || devAddr)
2539         {
2540             requestInfo.isMulticast = false;
2541         }
2542         else
2543         {
2544             tmpDevAddr.adapter = adapter;
2545             tmpDevAddr.flags = flags;
2546             destination = &tmpDevAddr;
2547             requestInfo.isMulticast = true;
2548         }
2549         // CA_DISCOVER will become GET and isMulticast
2550         requestInfo.method = CA_GET;
2551         break;
2552 #ifdef WITH_PRESENCE
2553     case OC_REST_PRESENCE:
2554         // Replacing method type with GET because "presence"
2555         // is a stack layer only implementation.
2556         requestInfo.method = CA_GET;
2557         break;
2558 #endif
2559     default:
2560         result = OC_STACK_INVALID_METHOD;
2561         goto exit;
2562     }
2563
2564     if (!devAddr && !destination)
2565     {
2566         OIC_LOG(DEBUG, TAG, "no devAddr and no destination");
2567         result = OC_STACK_INVALID_PARAM;
2568         goto exit;
2569     }
2570
2571     /* If not original behavior, use destination argument */
2572     if (destination && !devAddr)
2573     {
2574         devAddr = (OCDevAddr *)OICMalloc(sizeof (OCDevAddr));
2575         if (!devAddr)
2576         {
2577             result = OC_STACK_NO_MEMORY;
2578             goto exit;
2579         }
2580         *devAddr = *destination;
2581     }
2582
2583     resHandle = GenerateInvocationHandle();
2584     if (!resHandle)
2585     {
2586         result = OC_STACK_NO_MEMORY;
2587         goto exit;
2588     }
2589
2590     caResult = CAGenerateToken(&token, tokenLength);
2591     if (caResult != CA_STATUS_OK)
2592     {
2593         OIC_LOG(ERROR, TAG, "CAGenerateToken error");
2594         result= OC_STACK_ERROR;
2595         goto exit;
2596     }
2597
2598     // fill in request data
2599     requestInfo.info.type = qualityOfServiceToMessageType(qos);
2600     requestInfo.info.token = token;
2601     requestInfo.info.tokenLength = tokenLength;
2602     requestInfo.info.resourceUri = resourceUri;
2603
2604     if ((method == OC_REST_OBSERVE) || (method == OC_REST_OBSERVE_ALL))
2605     {
2606         result = CreateObserveHeaderOption (&(requestInfo.info.options),
2607                                     options, numOptions, OC_OBSERVE_REGISTER);
2608         if (result != OC_STACK_OK)
2609         {
2610             goto exit;
2611         }
2612         requestInfo.info.numOptions = numOptions + 1;
2613     }
2614     else
2615     {
2616         requestInfo.info.numOptions = numOptions;
2617         requestInfo.info.options =
2618             (CAHeaderOption_t*) OICCalloc(numOptions, sizeof(CAHeaderOption_t));
2619         memcpy(requestInfo.info.options, (CAHeaderOption_t*)options,
2620                numOptions * sizeof(CAHeaderOption_t));
2621     }
2622
2623     CopyDevAddrToEndpoint(devAddr, &endpoint);
2624
2625     if(payload)
2626     {
2627         if((result =
2628             OCConvertPayload(payload, &requestInfo.info.payload, &requestInfo.info.payloadSize))
2629                 != OC_STACK_OK)
2630         {
2631             OIC_LOG(ERROR, TAG, "Failed to create CBOR Payload");
2632             goto exit;
2633         }
2634         requestInfo.info.payloadFormat = CA_FORMAT_APPLICATION_CBOR;
2635     }
2636     else
2637     {
2638         requestInfo.info.payload = NULL;
2639         requestInfo.info.payloadSize = 0;
2640         requestInfo.info.payloadFormat = CA_FORMAT_UNDEFINED;
2641     }
2642
2643     if (result != OC_STACK_OK)
2644     {
2645         OIC_LOG(ERROR, TAG, "CACreateEndpoint error");
2646         goto exit;
2647     }
2648
2649     // prepare for response
2650 #ifdef WITH_PRESENCE
2651     if (method == OC_REST_PRESENCE)
2652     {
2653         char *presenceUri = NULL;
2654         result = OCPreparePresence(&endpoint, resourceUri, &presenceUri);
2655         if (OC_STACK_OK != result)
2656         {
2657             goto exit;
2658         }
2659
2660         // Assign full presence uri as coap://ip:port/oic/ad to add to callback list.
2661         // Presence notification will form a canonical uri to
2662         // look for callbacks into the application.
2663         resourceUri = presenceUri;
2664     }
2665 #endif
2666
2667     ttl = GetTicks(MAX_CB_TIMEOUT_SECONDS * MILLISECONDS_PER_SECOND);
2668     result = AddClientCB(&clientCB, cbData, token, tokenLength, &resHandle,
2669                             method, devAddr, resourceUri, resourceType, ttl);
2670     if (OC_STACK_OK != result)
2671     {
2672         goto exit;
2673     }
2674
2675     devAddr = NULL;       // Client CB list entry now owns it
2676     resourceUri = NULL;   // Client CB list entry now owns it
2677     resourceType = NULL;  // Client CB list entry now owns it
2678
2679     // send request
2680     result = OCSendRequest(&endpoint, &requestInfo);
2681     if (OC_STACK_OK != result)
2682     {
2683         goto exit;
2684     }
2685
2686     if (handle)
2687     {
2688         *handle = resHandle;
2689     }
2690
2691 exit:
2692     if (result != OC_STACK_OK)
2693     {
2694         OIC_LOG(ERROR, TAG, "OCDoResource error");
2695         FindAndDeleteClientCB(clientCB);
2696         CADestroyToken(token);
2697         if (handle)
2698         {
2699             *handle = NULL;
2700         }
2701         OICFree(resHandle);
2702     }
2703
2704     // This is the owner of the payload object, so we free it
2705     OCPayloadDestroy(payload);
2706     OICFree(requestInfo.info.payload);
2707     OICFree(devAddr);
2708     OICFree(resourceUri);
2709     OICFree(resourceType);
2710     OICFree(requestInfo.info.options);
2711     return result;
2712 }
2713
2714 OCStackResult OCCancel(OCDoHandle handle, OCQualityOfService qos, OCHeaderOption * options,
2715         uint8_t numOptions)
2716 {
2717     /*
2718      * This ftn is implemented one of two ways in the case of observation:
2719      *
2720      * 1. qos == OC_NON_CONFIRMABLE. When observe is unobserved..
2721      *      Remove the callback associated on client side.
2722      *      When the next notification comes in from server,
2723      *      reply with RESET message to server.
2724      *      Keep in mind that the server will react to RESET only
2725      *      if the last notification was sent as CON
2726      *
2727      * 2. qos == OC_CONFIRMABLE. When OCCancel is called,
2728      *      and it is associated with an observe request
2729      *      (i.e. ClientCB->method == OC_REST_OBSERVE || OC_REST_OBSERVE_ALL),
2730      *      Send CON Observe request to server with
2731      *      observe flag = OC_RESOURCE_OBSERVE_DEREGISTER.
2732      *      Remove the callback associated on client side.
2733      */
2734     OCStackResult ret = OC_STACK_OK;
2735     CAEndpoint_t endpoint = {.adapter = CA_DEFAULT_ADAPTER};
2736     CARequestInfo_t requestInfo = {.method = CA_GET};
2737
2738     if(!handle)
2739     {
2740         return OC_STACK_INVALID_PARAM;
2741     }
2742
2743     ClientCB *clientCB = GetClientCB(NULL, 0, handle, NULL);
2744     if (!clientCB)
2745     {
2746         OIC_LOG(ERROR, TAG, "Callback not found. Called OCCancel on same resource twice?");
2747         return OC_STACK_ERROR;
2748     }
2749
2750     switch (clientCB->method)
2751     {
2752         case OC_REST_OBSERVE:
2753         case OC_REST_OBSERVE_ALL:
2754
2755             OIC_LOG_V(INFO, TAG, "Canceling observation for resource %s", clientCB->requestUri);
2756
2757             CopyDevAddrToEndpoint(clientCB->devAddr, &endpoint);
2758
2759             if ((endpoint.adapter & CA_ADAPTER_IP) && qos != OC_HIGH_QOS)
2760             {
2761                 FindAndDeleteClientCB(clientCB);
2762                 break;
2763             }
2764
2765             OIC_LOG(INFO, TAG, "Cancelling observation as CONFIRMABLE");
2766
2767             requestInfo.info.type = qualityOfServiceToMessageType(qos);
2768             requestInfo.info.token = clientCB->token;
2769             requestInfo.info.tokenLength = clientCB->tokenLength;
2770
2771             if (CreateObserveHeaderOption (&(requestInfo.info.options),
2772                     options, numOptions, OC_OBSERVE_DEREGISTER) != OC_STACK_OK)
2773             {
2774                 return OC_STACK_ERROR;
2775             }
2776             requestInfo.info.numOptions = numOptions + 1;
2777             requestInfo.info.resourceUri = OICStrdup (clientCB->requestUri);
2778
2779
2780             ret = OCSendRequest(&endpoint, &requestInfo);
2781
2782             if (requestInfo.info.options)
2783             {
2784                 OICFree (requestInfo.info.options);
2785             }
2786             if (requestInfo.info.resourceUri)
2787             {
2788                 OICFree (requestInfo.info.resourceUri);
2789             }
2790
2791             break;
2792
2793         case OC_REST_DISCOVER:
2794             OIC_LOG_V(INFO, TAG, "Cancelling discovery callback for resource %s",
2795                                            clientCB->requestUri);
2796             FindAndDeleteClientCB(clientCB);
2797             break;
2798
2799 #ifdef WITH_PRESENCE
2800         case OC_REST_PRESENCE:
2801             FindAndDeleteClientCB(clientCB);
2802             break;
2803 #endif
2804
2805         default:
2806             ret = OC_STACK_INVALID_METHOD;
2807             break;
2808     }
2809
2810     return ret;
2811 }
2812
2813 /**
2814  * @brief   Register Persistent storage callback.
2815  * @param   persistentStorageHandler [IN] Pointers to open, read, write, close & unlink handlers.
2816  * @return
2817  *     OC_STACK_OK    - No errors; Success
2818  *     OC_STACK_INVALID_PARAM - Invalid parameter
2819  */
2820 OCStackResult OCRegisterPersistentStorageHandler(OCPersistentStorage* persistentStorageHandler)
2821 {
2822     OIC_LOG(INFO, TAG, "RegisterPersistentStorageHandler !!");
2823     if(!persistentStorageHandler)
2824     {
2825         OIC_LOG(ERROR, TAG, "The persistent storage handler is invalid");
2826         return OC_STACK_INVALID_PARAM;
2827     }
2828     else
2829     {
2830         if( !persistentStorageHandler->open ||
2831                 !persistentStorageHandler->close ||
2832                 !persistentStorageHandler->read ||
2833                 !persistentStorageHandler->unlink ||
2834                 !persistentStorageHandler->write)
2835         {
2836             OIC_LOG(ERROR, TAG, "The persistent storage handler is invalid");
2837             return OC_STACK_INVALID_PARAM;
2838         }
2839     }
2840     return SRMRegisterPersistentStorageHandler(persistentStorageHandler);
2841 }
2842
2843 #ifdef WITH_PRESENCE
2844
2845 OCStackResult OCProcessPresence()
2846 {
2847     OCStackResult result = OC_STACK_OK;
2848
2849     // the following line floods the log with messages that are irrelevant
2850     // to most purposes.  Uncomment as needed.
2851     //OIC_LOG(INFO, TAG, "Entering RequestPresence");
2852     ClientCB* cbNode = NULL;
2853     OCClientResponse clientResponse;
2854     OCStackApplicationResult cbResult = OC_STACK_DELETE_TRANSACTION;
2855
2856     LL_FOREACH(cbList, cbNode)
2857     {
2858         if (OC_REST_PRESENCE != cbNode->method || !cbNode->presence)
2859         {
2860             continue;
2861         }
2862
2863         uint32_t now = GetTicks(0);
2864         OIC_LOG_V(DEBUG, TAG, "this TTL level %d",
2865                                                 cbNode->presence->TTLlevel);
2866         OIC_LOG_V(DEBUG, TAG, "current ticks %d", now);
2867
2868         if (cbNode->presence->TTLlevel > PresenceTimeOutSize)
2869         {
2870             goto exit;
2871         }
2872
2873         if (cbNode->presence->TTLlevel < PresenceTimeOutSize)
2874         {
2875             OIC_LOG_V(DEBUG, TAG, "timeout ticks %d",
2876                     cbNode->presence->timeOut[cbNode->presence->TTLlevel]);
2877         }
2878         if (cbNode->presence->TTLlevel >= PresenceTimeOutSize)
2879         {
2880             OIC_LOG(DEBUG, TAG, "No more timeout ticks");
2881
2882             clientResponse.sequenceNumber = 0;
2883             clientResponse.result = OC_STACK_PRESENCE_TIMEOUT;
2884             clientResponse.devAddr = *cbNode->devAddr;
2885             FixUpClientResponse(&clientResponse);
2886             clientResponse.payload = NULL;
2887
2888             // Increment the TTLLevel (going to a next state), so we don't keep
2889             // sending presence notification to client.
2890             cbNode->presence->TTLlevel++;
2891             OIC_LOG_V(DEBUG, TAG, "moving to TTL level %d",
2892                                         cbNode->presence->TTLlevel);
2893
2894             cbResult = cbNode->callBack(cbNode->context, cbNode->handle, &clientResponse);
2895             if (cbResult == OC_STACK_DELETE_TRANSACTION)
2896             {
2897                 FindAndDeleteClientCB(cbNode);
2898             }
2899         }
2900
2901         if (now < cbNode->presence->timeOut[cbNode->presence->TTLlevel])
2902         {
2903             continue;
2904         }
2905
2906         CAEndpoint_t endpoint = {.adapter = CA_DEFAULT_ADAPTER};
2907         CAInfo_t requestData = {.type = CA_MSG_CONFIRM};
2908         CARequestInfo_t requestInfo = {.method = CA_GET};
2909
2910         OIC_LOG(DEBUG, TAG, "time to test server presence");
2911
2912         CopyDevAddrToEndpoint(cbNode->devAddr, &endpoint);
2913
2914         requestData.type = CA_MSG_NONCONFIRM;
2915         requestData.token = cbNode->token;
2916         requestData.tokenLength = cbNode->tokenLength;
2917         requestData.resourceUri = OC_RSRVD_PRESENCE_URI;
2918         requestInfo.method = CA_GET;
2919         requestInfo.info = requestData;
2920
2921         result = OCSendRequest(&endpoint, &requestInfo);
2922         if (OC_STACK_OK != result)
2923         {
2924             goto exit;
2925         }
2926
2927         cbNode->presence->TTLlevel++;
2928         OIC_LOG_V(DEBUG, TAG, "moving to TTL level %d", cbNode->presence->TTLlevel);
2929     }
2930 exit:
2931     if (result != OC_STACK_OK)
2932     {
2933         OIC_LOG(ERROR, TAG, "OCProcessPresence error");
2934     }
2935
2936     return result;
2937 }
2938 #endif // WITH_PRESENCE
2939
2940 OCStackResult OCProcess()
2941 {
2942 #ifdef WITH_PRESENCE
2943     OCProcessPresence();
2944 #endif
2945     CAHandleRequestResponse();
2946
2947 #ifdef ROUTING_GATEWAY
2948     RMProcess();
2949 #endif
2950
2951 #ifdef TCP_ADAPTER
2952     ProcessKeepAlive();
2953 #endif
2954     return OC_STACK_OK;
2955 }
2956
2957 #ifdef WITH_PRESENCE
2958 OCStackResult OCStartPresence(const uint32_t ttl)
2959 {
2960     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
2961     OCChangeResourceProperty(
2962             &(((OCResource *)presenceResource.handle)->resourceProperties),
2963             OC_ACTIVE, 1);
2964
2965     if (OC_MAX_PRESENCE_TTL_SECONDS < ttl)
2966     {
2967         presenceResource.presenceTTL = OC_MAX_PRESENCE_TTL_SECONDS;
2968         OIC_LOG(INFO, TAG, "Setting Presence TTL to max value");
2969     }
2970     else if (0 == ttl)
2971     {
2972         presenceResource.presenceTTL = OC_DEFAULT_PRESENCE_TTL_SECONDS;
2973         OIC_LOG(INFO, TAG, "Setting Presence TTL to default value");
2974     }
2975     else
2976     {
2977         presenceResource.presenceTTL = ttl;
2978     }
2979     OIC_LOG_V(DEBUG, TAG, "Presence TTL is %" PRIu32 " seconds", presenceResource.presenceTTL);
2980
2981     if (OC_PRESENCE_UNINITIALIZED == presenceState)
2982     {
2983         presenceState = OC_PRESENCE_INITIALIZED;
2984
2985         OCDevAddr devAddr = { OC_DEFAULT_ADAPTER };
2986
2987         CAToken_t caToken = NULL;
2988         CAResult_t caResult = CAGenerateToken(&caToken, tokenLength);
2989         if (caResult != CA_STATUS_OK)
2990         {
2991             OIC_LOG(ERROR, TAG, "CAGenerateToken error");
2992             CADestroyToken(caToken);
2993             return OC_STACK_ERROR;
2994         }
2995
2996         AddObserver(OC_RSRVD_PRESENCE_URI, NULL, 0, caToken, tokenLength,
2997                 (OCResource *)presenceResource.handle, OC_LOW_QOS, OC_FORMAT_UNDEFINED, &devAddr);
2998         CADestroyToken(caToken);
2999     }
3000
3001     // Each time OCStartPresence is called
3002     // a different random 32-bit integer number is used
3003     ((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
3004
3005     return SendPresenceNotification(((OCResource *)presenceResource.handle)->rsrcType,
3006             OC_PRESENCE_TRIGGER_CREATE);
3007 }
3008
3009 OCStackResult OCStopPresence()
3010 {
3011     OCStackResult result = OC_STACK_ERROR;
3012
3013     if(presenceResource.handle)
3014     {
3015         ((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
3016
3017     // make resource inactive
3018     result = OCChangeResourceProperty(
3019             &(((OCResource *) presenceResource.handle)->resourceProperties),
3020             OC_ACTIVE, 0);
3021     }
3022
3023     if(result != OC_STACK_OK)
3024     {
3025         OIC_LOG(ERROR, TAG,
3026                       "Changing the presence resource properties to ACTIVE not successful");
3027         return result;
3028     }
3029
3030     return SendStopNotification();
3031 }
3032 #endif
3033
3034 OCStackResult OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandler entityHandler,
3035                                             void* callbackParameter)
3036 {
3037     defaultDeviceHandler = entityHandler;
3038     defaultDeviceHandlerCallbackParameter = callbackParameter;
3039
3040     return OC_STACK_OK;
3041 }
3042
3043 OCStackResult OCSetPlatformInfo(OCPlatformInfo platformInfo)
3044 {
3045     OIC_LOG(INFO, TAG, "Entering OCSetPlatformInfo");
3046
3047     if(myStackMode ==  OC_SERVER || myStackMode == OC_CLIENT_SERVER || myStackMode == OC_GATEWAY)
3048     {
3049         if (validatePlatformInfo(platformInfo))
3050         {
3051             return SavePlatformInfo(platformInfo);
3052         }
3053         else
3054         {
3055             return OC_STACK_INVALID_PARAM;
3056         }
3057     }
3058     else
3059     {
3060         return OC_STACK_ERROR;
3061     }
3062 }
3063
3064 OCStackResult OCSetDeviceInfo(OCDeviceInfo deviceInfo)
3065 {
3066     OIC_LOG(INFO, TAG, "Entering OCSetDeviceInfo");
3067
3068     if (!deviceInfo.deviceName || deviceInfo.deviceName[0] == '\0')
3069     {
3070         OIC_LOG(ERROR, TAG, "Null or empty device name.");
3071         return OC_STACK_INVALID_PARAM;
3072     }
3073
3074     if (deviceInfo.types)
3075     {
3076         OCStringLL *type =  deviceInfo.types;
3077         OCResource *resource = findResource((OCResource *) deviceResource);
3078         if (!resource)
3079         {
3080             return OC_STACK_INVALID_PARAM;
3081         }
3082         deleteResourceType(resource->rsrcType);
3083         resource->rsrcType = NULL;
3084
3085         while (type)
3086         {
3087             OCBindResourceTypeToResource(deviceResource, type->value);
3088             type = type->next;
3089         }
3090     }
3091     return SaveDeviceInfo(deviceInfo);
3092 }
3093
3094 OCStackResult OCCreateResource(OCResourceHandle *handle,
3095         const char *resourceTypeName,
3096         const char *resourceInterfaceName,
3097         const char *uri, OCEntityHandler entityHandler,
3098         void* callbackParam,
3099         uint8_t resourceProperties)
3100 {
3101
3102     OCResource *pointer = NULL;
3103     OCStackResult result = OC_STACK_ERROR;
3104
3105     OIC_LOG(INFO, TAG, "Entering OCCreateResource");
3106
3107     if(myStackMode == OC_CLIENT)
3108     {
3109         return OC_STACK_INVALID_PARAM;
3110     }
3111     // Validate parameters
3112     if(!uri || uri[0]=='\0' || strlen(uri)>=MAX_URI_LENGTH )
3113     {
3114         OIC_LOG(ERROR, TAG, "URI is empty or too long");
3115         return OC_STACK_INVALID_URI;
3116     }
3117     // Is it presented during resource discovery?
3118     if (!handle || !resourceTypeName || resourceTypeName[0] == '\0' )
3119     {
3120         OIC_LOG(ERROR, TAG, "Input parameter is NULL");
3121         return OC_STACK_INVALID_PARAM;
3122     }
3123
3124     if(!resourceInterfaceName || strlen(resourceInterfaceName) == 0)
3125     {
3126         resourceInterfaceName = OC_RSRVD_INTERFACE_DEFAULT;
3127     }
3128
3129     // Make sure resourceProperties bitmask has allowed properties specified
3130     if (resourceProperties
3131             > (OC_ACTIVE | OC_DISCOVERABLE | OC_OBSERVABLE | OC_SLOW | OC_SECURE |
3132                OC_EXPLICIT_DISCOVERABLE))
3133     {
3134         OIC_LOG(ERROR, TAG, "Invalid property");
3135         return OC_STACK_INVALID_PARAM;
3136     }
3137
3138     // If the headResource is NULL, then no resources have been created...
3139     pointer = headResource;
3140     if (pointer)
3141     {
3142         // At least one resources is in the resource list, so we need to search for
3143         // repeated URLs, which are not allowed.  If a repeat is found, exit with an error
3144         while (pointer)
3145         {
3146             if (strncmp(uri, pointer->uri, MAX_URI_LENGTH) == 0)
3147             {
3148                 OIC_LOG_V(ERROR, TAG, "Resource %s already exists", uri);
3149                 return OC_STACK_INVALID_PARAM;
3150             }
3151             pointer = pointer->next;
3152         }
3153     }
3154     // Create the pointer and insert it into the resource list
3155     pointer = (OCResource *) OICCalloc(1, sizeof(OCResource));
3156     if (!pointer)
3157     {
3158         result = OC_STACK_NO_MEMORY;
3159         goto exit;
3160     }
3161     pointer->sequenceNum = OC_OFFSET_SEQUENCE_NUMBER;
3162
3163     insertResource(pointer);
3164
3165     // Set the uri
3166     pointer->uri = OICStrdup(uri);
3167     if (!pointer->uri)
3168     {
3169         result = OC_STACK_NO_MEMORY;
3170         goto exit;
3171     }
3172
3173     // Set properties.  Set OC_ACTIVE
3174     pointer->resourceProperties = (OCResourceProperty) (resourceProperties
3175             | OC_ACTIVE);
3176
3177     // Add the resourcetype to the resource
3178     result = BindResourceTypeToResource(pointer, resourceTypeName);
3179     if (result != OC_STACK_OK)
3180     {
3181         OIC_LOG(ERROR, TAG, "Error adding resourcetype");
3182         goto exit;
3183     }
3184
3185     // Add the resourceinterface to the resource
3186     result = BindResourceInterfaceToResource(pointer, resourceInterfaceName);
3187     if (result != OC_STACK_OK)
3188     {
3189         OIC_LOG(ERROR, TAG, "Error adding resourceinterface");
3190         goto exit;
3191     }
3192
3193     // If an entity handler has been passed, attach it to the newly created
3194     // resource.  Otherwise, set the default entity handler.
3195     if (entityHandler)
3196     {
3197         pointer->entityHandler = entityHandler;
3198         pointer->entityHandlerCallbackParam = callbackParam;
3199     }
3200     else
3201     {
3202         pointer->entityHandler = defaultResourceEHandler;
3203         pointer->entityHandlerCallbackParam = NULL;
3204     }
3205
3206     // Initialize a pointer indicating child resources in case of collection
3207     pointer->rsrcChildResourcesHead = NULL;
3208
3209     *handle = pointer;
3210     result = OC_STACK_OK;
3211
3212 #ifdef WITH_PRESENCE
3213     if (presenceResource.handle)
3214     {
3215         ((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
3216         SendPresenceNotification(pointer->rsrcType, OC_PRESENCE_TRIGGER_CREATE);
3217     }
3218 #endif
3219 exit:
3220     if (result != OC_STACK_OK)
3221     {
3222         // Deep delete of resource and other dynamic elements that it contains
3223         deleteResource(pointer);
3224     }
3225     return result;
3226 }
3227
3228 OCStackResult OCBindResource(
3229         OCResourceHandle collectionHandle, OCResourceHandle resourceHandle)
3230 {
3231     OCResource *resource = NULL;
3232     OCChildResource *tempChildResource = NULL;
3233     OCChildResource *newChildResource = NULL;
3234
3235     OIC_LOG(INFO, TAG, "Entering OCBindResource");
3236
3237     // Validate parameters
3238     VERIFY_NON_NULL(collectionHandle, ERROR, OC_STACK_ERROR);
3239     VERIFY_NON_NULL(resourceHandle, ERROR, OC_STACK_ERROR);
3240     // Container cannot contain itself
3241     if (collectionHandle == resourceHandle)
3242     {
3243         OIC_LOG(ERROR, TAG, "Added handle equals collection handle");
3244         return OC_STACK_INVALID_PARAM;
3245     }
3246
3247     // Use the handle to find the resource in the resource linked list
3248     resource = findResource((OCResource *) collectionHandle);
3249     if (!resource)
3250     {
3251         OIC_LOG(ERROR, TAG, "Collection handle not found");
3252         return OC_STACK_INVALID_PARAM;
3253     }
3254
3255     // Look for an open slot to add add the child resource.
3256     // If found, add it and return success
3257
3258     tempChildResource = resource->rsrcChildResourcesHead;
3259
3260     while(resource->rsrcChildResourcesHead && tempChildResource->next)
3261     {
3262         // TODO: what if one of child resource was deregistered without unbinding?
3263         tempChildResource = tempChildResource->next;
3264     }
3265
3266     // Do memory allocation for child resource
3267     newChildResource = (OCChildResource *) OICCalloc(1, sizeof(OCChildResource));
3268     if(!newChildResource)
3269     {
3270         OIC_LOG(ERROR, TAG, "Adding new child resource is failed due to memory allocation failure");
3271         return OC_STACK_ERROR;
3272     }
3273
3274     newChildResource->rsrcResource = (OCResource *) resourceHandle;
3275     newChildResource->next = NULL;
3276
3277     if(!resource->rsrcChildResourcesHead)
3278     {
3279         resource->rsrcChildResourcesHead = newChildResource;
3280     }
3281     else {
3282         tempChildResource->next = newChildResource;
3283     }
3284
3285     OIC_LOG(INFO, TAG, "resource bound");
3286
3287 #ifdef WITH_PRESENCE
3288     if (presenceResource.handle)
3289     {
3290         ((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
3291         SendPresenceNotification(((OCResource *) resourceHandle)->rsrcType,
3292                 OC_PRESENCE_TRIGGER_CHANGE);
3293     }
3294 #endif
3295
3296     return OC_STACK_OK;
3297 }
3298
3299 OCStackResult OCUnBindResource(
3300         OCResourceHandle collectionHandle, OCResourceHandle resourceHandle)
3301 {
3302     OCResource *resource = NULL;
3303     OCChildResource *tempChildResource = NULL;
3304     OCChildResource *tempLastChildResource = NULL;
3305
3306     OIC_LOG(INFO, TAG, "Entering OCUnBindResource");
3307
3308     // Validate parameters
3309     VERIFY_NON_NULL(collectionHandle, ERROR, OC_STACK_ERROR);
3310     VERIFY_NON_NULL(resourceHandle, ERROR, OC_STACK_ERROR);
3311     // Container cannot contain itself
3312     if (collectionHandle == resourceHandle)
3313     {
3314         OIC_LOG(ERROR, TAG, "removing handle equals collection handle");
3315         return OC_STACK_INVALID_PARAM;
3316     }
3317
3318     // Use the handle to find the resource in the resource linked list
3319     resource = findResource((OCResource *) collectionHandle);
3320     if (!resource)
3321     {
3322         OIC_LOG(ERROR, TAG, "Collection handle not found");
3323         return OC_STACK_INVALID_PARAM;
3324     }
3325
3326     // Look for an open slot to add add the child resource.
3327     // If found, add it and return success
3328     if(!resource->rsrcChildResourcesHead)
3329     {
3330         OIC_LOG(INFO, TAG, "resource not found in collection");
3331
3332         // Unable to add resourceHandle, so return error
3333         return OC_STACK_ERROR;
3334
3335     }
3336
3337     tempChildResource = resource->rsrcChildResourcesHead;
3338
3339     while (tempChildResource)
3340     {
3341         if(tempChildResource->rsrcResource == resourceHandle)
3342         {
3343             // if resource going to be unbinded is the head one.
3344             if( tempChildResource == resource->rsrcChildResourcesHead )
3345             {
3346                 OCChildResource *temp = resource->rsrcChildResourcesHead->next;
3347                 OICFree(resource->rsrcChildResourcesHead);
3348                 resource->rsrcChildResourcesHead = temp;
3349                 temp = NULL;
3350             }
3351             else
3352             {
3353                 OCChildResource *temp = tempChildResource->next;
3354                 OICFree(tempChildResource);
3355                 tempLastChildResource->next = temp;
3356                 temp = NULL;
3357             }
3358
3359             OIC_LOG(INFO, TAG, "resource unbound");
3360
3361             // Send notification when resource is unbounded successfully.
3362 #ifdef WITH_PRESENCE
3363             if (presenceResource.handle)
3364             {
3365                 ((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
3366                 SendPresenceNotification(((OCResource *) resourceHandle)->rsrcType,
3367                         OC_PRESENCE_TRIGGER_CHANGE);
3368             }
3369 #endif
3370             tempChildResource = NULL;
3371             tempLastChildResource = NULL;
3372
3373             return OC_STACK_OK;
3374
3375         }
3376
3377         tempLastChildResource = tempChildResource;
3378         tempChildResource = tempChildResource->next;
3379     }
3380
3381     OIC_LOG(INFO, TAG, "resource not found in collection");
3382
3383     tempChildResource = NULL;
3384     tempLastChildResource = NULL;
3385
3386     // Unable to add resourceHandle, so return error
3387     return OC_STACK_ERROR;
3388 }
3389
3390 static bool ValidateResourceTypeInterface(const char *resourceItemName)
3391 {
3392     if (!resourceItemName)
3393     {
3394         return false;
3395     }
3396     // Per RFC 6690 only registered values must follow the first rule below.
3397     // At this point in time the only values registered begin with "core", and
3398     // all other values are specified as opaque strings where multiple values
3399     // are separated by a space.
3400     if (strncmp(resourceItemName, CORESPEC, sizeof(CORESPEC) - 1) == 0)
3401     {
3402         for(size_t index = sizeof(CORESPEC) - 1;  resourceItemName[index]; ++index)
3403         {
3404             if (resourceItemName[index] != '.'
3405                 && resourceItemName[index] != '-'
3406                 && (resourceItemName[index] < 'a' || resourceItemName[index] > 'z')
3407                 && (resourceItemName[index] < '0' || resourceItemName[index] > '9'))
3408             {
3409                 return false;
3410             }
3411         }
3412     }
3413     else
3414     {
3415         for (size_t index = 0; resourceItemName[index]; ++index)
3416         {
3417             if (resourceItemName[index] == ' '
3418                 || resourceItemName[index] == '\t'
3419                 || resourceItemName[index] == '\r'
3420                 || resourceItemName[index] == '\n')
3421             {
3422                 return false;
3423             }
3424         }
3425     }
3426
3427     return true;
3428 }
3429
3430 OCStackResult BindResourceTypeToResource(OCResource* resource,
3431                                             const char *resourceTypeName)
3432 {
3433     OCResourceType *pointer = NULL;
3434     char *str = NULL;
3435     OCStackResult result = OC_STACK_ERROR;
3436
3437     VERIFY_NON_NULL(resourceTypeName, ERROR, OC_STACK_INVALID_PARAM);
3438
3439     if (!ValidateResourceTypeInterface(resourceTypeName))
3440     {
3441         OIC_LOG(ERROR, TAG, "resource type illegal (see RFC 6690)");
3442         return OC_STACK_INVALID_PARAM;
3443     }
3444
3445     pointer = (OCResourceType *) OICCalloc(1, sizeof(OCResourceType));
3446     if (!pointer)
3447     {
3448         result = OC_STACK_NO_MEMORY;
3449         goto exit;
3450     }
3451
3452     str = OICStrdup(resourceTypeName);
3453     if (!str)
3454     {
3455         result = OC_STACK_NO_MEMORY;
3456         goto exit;
3457     }
3458     pointer->resourcetypename = str;
3459     pointer->next = NULL;
3460
3461     insertResourceType(resource, pointer);
3462     result = OC_STACK_OK;
3463
3464 exit:
3465     if (result != OC_STACK_OK)
3466     {
3467         OICFree(pointer);
3468         OICFree(str);
3469     }
3470
3471     return result;
3472 }
3473
3474 OCStackResult BindResourceInterfaceToResource(OCResource* resource,
3475         const char *resourceInterfaceName)
3476 {
3477     OCResourceInterface *pointer = NULL;
3478     char *str = NULL;
3479     OCStackResult result = OC_STACK_ERROR;
3480
3481     VERIFY_NON_NULL(resourceInterfaceName, ERROR, OC_STACK_INVALID_PARAM);
3482
3483     if (!ValidateResourceTypeInterface(resourceInterfaceName))
3484     {
3485         OIC_LOG(ERROR, TAG, "resource /interface illegal (see RFC 6690)");
3486         return OC_STACK_INVALID_PARAM;
3487     }
3488
3489     OIC_LOG_V(INFO, TAG, "Binding %s interface to %s", resourceInterfaceName, resource->uri);
3490
3491     pointer = (OCResourceInterface *) OICCalloc(1, sizeof(OCResourceInterface));
3492     if (!pointer)
3493     {
3494         result = OC_STACK_NO_MEMORY;
3495         goto exit;
3496     }
3497
3498     str = OICStrdup(resourceInterfaceName);
3499     if (!str)
3500     {
3501         result = OC_STACK_NO_MEMORY;
3502         goto exit;
3503     }
3504     pointer->name = str;
3505
3506     // Bind the resourceinterface to the resource
3507     insertResourceInterface(resource, pointer);
3508
3509     result = OC_STACK_OK;
3510
3511     exit:
3512     if (result != OC_STACK_OK)
3513     {
3514         OICFree(pointer);
3515         OICFree(str);
3516     }
3517
3518     return result;
3519 }
3520
3521 OCStackResult OCBindResourceTypeToResource(OCResourceHandle handle,
3522         const char *resourceTypeName)
3523 {
3524
3525     OCStackResult result = OC_STACK_ERROR;
3526     OCResource *resource = NULL;
3527
3528     resource = findResource((OCResource *) handle);
3529     if (!resource)
3530     {
3531         OIC_LOG(ERROR, TAG, "Resource not found");
3532         return OC_STACK_ERROR;
3533     }
3534
3535     result = BindResourceTypeToResource(resource, resourceTypeName);
3536
3537 #ifdef WITH_PRESENCE
3538     if(presenceResource.handle)
3539     {
3540         ((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
3541         SendPresenceNotification(resource->rsrcType, OC_PRESENCE_TRIGGER_CHANGE);
3542     }
3543 #endif
3544
3545     return result;
3546 }
3547
3548 OCStackResult OCBindResourceInterfaceToResource(OCResourceHandle handle,
3549         const char *resourceInterfaceName)
3550 {
3551
3552     OCStackResult result = OC_STACK_ERROR;
3553     OCResource *resource = NULL;
3554
3555     resource = findResource((OCResource *) handle);
3556     if (!resource)
3557     {
3558         OIC_LOG(ERROR, TAG, "Resource not found");
3559         return OC_STACK_ERROR;
3560     }
3561
3562     result = BindResourceInterfaceToResource(resource, resourceInterfaceName);
3563
3564 #ifdef WITH_PRESENCE
3565     if (presenceResource.handle)
3566     {
3567         ((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
3568         SendPresenceNotification(resource->rsrcType, OC_PRESENCE_TRIGGER_CHANGE);
3569     }
3570 #endif
3571
3572     return result;
3573 }
3574
3575 OCStackResult OCGetNumberOfResources(uint8_t *numResources)
3576 {
3577     OCResource *pointer = headResource;
3578
3579     VERIFY_NON_NULL(numResources, ERROR, OC_STACK_INVALID_PARAM);
3580     *numResources = 0;
3581     while (pointer)
3582     {
3583         *numResources = *numResources + 1;
3584         pointer = pointer->next;
3585     }
3586     return OC_STACK_OK;
3587 }
3588
3589 OCResourceHandle OCGetResourceHandle(uint8_t index)
3590 {
3591     OCResource *pointer = headResource;
3592
3593     for( uint8_t i = 0; i < index && pointer; ++i)
3594     {
3595         pointer = pointer->next;
3596     }
3597     return (OCResourceHandle) pointer;
3598 }
3599
3600 OCStackResult OCDeleteResource(OCResourceHandle handle)
3601 {
3602     if (!handle)
3603     {
3604         OIC_LOG(ERROR, TAG, "Invalid handle for deletion");
3605         return OC_STACK_INVALID_PARAM;
3606     }
3607
3608     OCResource *resource = findResource((OCResource *) handle);
3609     if (resource == NULL)
3610     {
3611         OIC_LOG(ERROR, TAG, "Resource not found");
3612         return OC_STACK_NO_RESOURCE;
3613     }
3614
3615     if (deleteResource((OCResource *) handle) != OC_STACK_OK)
3616     {
3617         OIC_LOG(ERROR, TAG, "Error deleting resource");
3618         return OC_STACK_ERROR;
3619     }
3620
3621     return OC_STACK_OK;
3622 }
3623
3624 const char *OCGetResourceUri(OCResourceHandle handle)
3625 {
3626     OCResource *resource = NULL;
3627
3628     resource = findResource((OCResource *) handle);
3629     if (resource)
3630     {
3631         return resource->uri;
3632     }
3633     return (const char *) NULL;
3634 }
3635
3636 OCResourceProperty OCGetResourceProperties(OCResourceHandle handle)
3637 {
3638     OCResource *resource = NULL;
3639
3640     resource = findResource((OCResource *) handle);
3641     if (resource)
3642     {
3643         return resource->resourceProperties;
3644     }
3645     return (OCResourceProperty)-1;
3646 }
3647
3648 OCStackResult OCGetNumberOfResourceTypes(OCResourceHandle handle,
3649         uint8_t *numResourceTypes)
3650 {
3651     OCResource *resource = NULL;
3652     OCResourceType *pointer = NULL;
3653
3654     VERIFY_NON_NULL(numResourceTypes, ERROR, OC_STACK_INVALID_PARAM);
3655     VERIFY_NON_NULL(handle, ERROR, OC_STACK_INVALID_PARAM);
3656
3657     *numResourceTypes = 0;
3658
3659     resource = findResource((OCResource *) handle);
3660     if (resource)
3661     {
3662         pointer = resource->rsrcType;
3663         while (pointer)
3664         {
3665             *numResourceTypes = *numResourceTypes + 1;
3666             pointer = pointer->next;
3667         }
3668     }
3669     return OC_STACK_OK;
3670 }
3671
3672 const char *OCGetResourceTypeName(OCResourceHandle handle, uint8_t index)
3673 {
3674     OCResourceType *resourceType = NULL;
3675
3676     resourceType = findResourceTypeAtIndex(handle, index);
3677     if (resourceType)
3678     {
3679         return resourceType->resourcetypename;
3680     }
3681     return (const char *) NULL;
3682 }
3683
3684 OCStackResult OCGetNumberOfResourceInterfaces(OCResourceHandle handle,
3685         uint8_t *numResourceInterfaces)
3686 {
3687     OCResourceInterface *pointer = NULL;
3688     OCResource *resource = NULL;
3689
3690     VERIFY_NON_NULL(handle, ERROR, OC_STACK_INVALID_PARAM);
3691     VERIFY_NON_NULL(numResourceInterfaces, ERROR, OC_STACK_INVALID_PARAM);
3692
3693     *numResourceInterfaces = 0;
3694     resource = findResource((OCResource *) handle);
3695     if (resource)
3696     {
3697         pointer = resource->rsrcInterface;
3698         while (pointer)
3699         {
3700             *numResourceInterfaces = *numResourceInterfaces + 1;
3701             pointer = pointer->next;
3702         }
3703     }
3704     return OC_STACK_OK;
3705 }
3706
3707 const char *OCGetResourceInterfaceName(OCResourceHandle handle, uint8_t index)
3708 {
3709     OCResourceInterface *resourceInterface = NULL;
3710
3711     resourceInterface = findResourceInterfaceAtIndex(handle, index);
3712     if (resourceInterface)
3713     {
3714         return resourceInterface->name;
3715     }
3716     return (const char *) NULL;
3717 }
3718
3719 OCResourceHandle OCGetResourceHandleFromCollection(OCResourceHandle collectionHandle,
3720         uint8_t index)
3721 {
3722     OCResource *resource = NULL;
3723     OCChildResource *tempChildResource = NULL;
3724     uint8_t num = 0;
3725
3726     resource = findResource((OCResource *) collectionHandle);
3727     if (!resource)
3728     {
3729         return NULL;
3730     }
3731
3732     tempChildResource = resource->rsrcChildResourcesHead;
3733
3734     while(tempChildResource)
3735     {
3736         if( num == index )
3737         {
3738             return tempChildResource->rsrcResource;
3739         }
3740         num++;
3741         tempChildResource = tempChildResource->next;
3742     }
3743
3744     // In this case, the number of resource handles in the collection exceeds the index
3745     tempChildResource = NULL;
3746     return NULL;
3747 }
3748
3749 OCStackResult OCBindResourceHandler(OCResourceHandle handle,
3750         OCEntityHandler entityHandler,
3751         void* callbackParam)
3752 {
3753     OCResource *resource = NULL;
3754
3755     // Validate parameters
3756     VERIFY_NON_NULL(handle, ERROR, OC_STACK_INVALID_PARAM);
3757
3758     // Use the handle to find the resource in the resource linked list
3759     resource = findResource((OCResource *)handle);
3760     if (!resource)
3761     {
3762         OIC_LOG(ERROR, TAG, "Resource not found");
3763         return OC_STACK_ERROR;
3764     }
3765
3766     // Bind the handler
3767     resource->entityHandler = entityHandler;
3768     resource->entityHandlerCallbackParam = callbackParam;
3769
3770 #ifdef WITH_PRESENCE
3771     if (presenceResource.handle)
3772     {
3773         ((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
3774         SendPresenceNotification(resource->rsrcType, OC_PRESENCE_TRIGGER_CHANGE);
3775     }
3776 #endif
3777
3778     return OC_STACK_OK;
3779 }
3780
3781 OCEntityHandler OCGetResourceHandler(OCResourceHandle handle)
3782 {
3783     OCResource *resource = NULL;
3784
3785     resource = findResource((OCResource *)handle);
3786     if (!resource)
3787     {
3788         OIC_LOG(ERROR, TAG, "Resource not found");
3789         return NULL;
3790     }
3791
3792     // Bind the handler
3793     return resource->entityHandler;
3794 }
3795
3796 void incrementSequenceNumber(OCResource * resPtr)
3797 {
3798     // Increment the sequence number
3799     resPtr->sequenceNum += 1;
3800     if (resPtr->sequenceNum == MAX_SEQUENCE_NUMBER)
3801     {
3802         resPtr->sequenceNum = OC_OFFSET_SEQUENCE_NUMBER+1;
3803     }
3804     return;
3805 }
3806
3807 #ifdef WITH_PRESENCE
3808 OCStackResult SendPresenceNotification(OCResourceType *resourceType,
3809         OCPresenceTrigger trigger)
3810 {
3811     OCResource *resPtr = NULL;
3812     OCStackResult result = OC_STACK_ERROR;
3813     OCMethod method = OC_REST_PRESENCE;
3814     uint32_t maxAge = 0;
3815     resPtr = findResource((OCResource *) presenceResource.handle);
3816     if(NULL == resPtr)
3817     {
3818         return OC_STACK_NO_RESOURCE;
3819     }
3820
3821     if((((OCResource *) presenceResource.handle)->resourceProperties) & OC_ACTIVE)
3822     {
3823         maxAge = presenceResource.presenceTTL;
3824
3825         result = SendAllObserverNotification(method, resPtr, maxAge,
3826                 trigger, resourceType, OC_LOW_QOS);
3827     }
3828
3829     return result;
3830 }
3831
3832 OCStackResult SendStopNotification()
3833 {
3834     OCResource *resPtr = NULL;
3835     OCStackResult result = OC_STACK_ERROR;
3836     OCMethod method = OC_REST_PRESENCE;
3837     resPtr = findResource((OCResource *) presenceResource.handle);
3838     if(NULL == resPtr)
3839     {
3840         return OC_STACK_NO_RESOURCE;
3841     }
3842
3843     // maxAge is 0. ResourceType is NULL.
3844     result = SendAllObserverNotification(method, resPtr, 0, OC_PRESENCE_TRIGGER_DELETE,
3845             NULL, OC_LOW_QOS);
3846
3847     return result;
3848 }
3849
3850 #endif // WITH_PRESENCE
3851 OCStackResult OCNotifyAllObservers(OCResourceHandle handle, OCQualityOfService qos)
3852 {
3853     OCResource *resPtr = NULL;
3854     OCStackResult result = OC_STACK_ERROR;
3855     OCMethod method = OC_REST_NOMETHOD;
3856     uint32_t maxAge = 0;
3857
3858     OIC_LOG(INFO, TAG, "Notifying all observers");
3859 #ifdef WITH_PRESENCE
3860     if(handle == presenceResource.handle)
3861     {
3862         return OC_STACK_OK;
3863     }
3864 #endif // WITH_PRESENCE
3865     VERIFY_NON_NULL(handle, ERROR, OC_STACK_ERROR);
3866
3867     // Verify that the resource exists
3868     resPtr = findResource ((OCResource *) handle);
3869     if (NULL == resPtr)
3870     {
3871         return OC_STACK_NO_RESOURCE;
3872     }
3873     else
3874     {
3875         //only increment in the case of regular observing (not presence)
3876         incrementSequenceNumber(resPtr);
3877         method = OC_REST_OBSERVE;
3878         maxAge = MAX_OBSERVE_AGE;
3879 #ifdef WITH_PRESENCE
3880         result = SendAllObserverNotification (method, resPtr, maxAge,
3881                 OC_PRESENCE_TRIGGER_DELETE, NULL, qos);
3882 #else
3883         result = SendAllObserverNotification (method, resPtr, maxAge, qos);
3884 #endif
3885         return result;
3886     }
3887 }
3888
3889 OCStackResult
3890 OCNotifyListOfObservers (OCResourceHandle handle,
3891                          OCObservationId  *obsIdList,
3892                          uint8_t          numberOfIds,
3893                          const OCRepPayload       *payload,
3894                          OCQualityOfService qos)
3895 {
3896     OIC_LOG(INFO, TAG, "Entering OCNotifyListOfObservers");
3897
3898     OCResource *resPtr = NULL;
3899     //TODO: we should allow the server to define this
3900     uint32_t maxAge = MAX_OBSERVE_AGE;
3901
3902     VERIFY_NON_NULL(handle, ERROR, OC_STACK_ERROR);
3903     VERIFY_NON_NULL(obsIdList, ERROR, OC_STACK_ERROR);
3904     VERIFY_NON_NULL(payload, ERROR, OC_STACK_ERROR);
3905
3906     resPtr = findResource ((OCResource *) handle);
3907     if (NULL == resPtr || myStackMode == OC_CLIENT)
3908     {
3909         return OC_STACK_NO_RESOURCE;
3910     }
3911     else
3912     {
3913         incrementSequenceNumber(resPtr);
3914     }
3915     return (SendListObserverNotification(resPtr, obsIdList, numberOfIds,
3916             payload, maxAge, qos));
3917 }
3918
3919 OCStackResult OCDoResponse(OCEntityHandlerResponse *ehResponse)
3920 {
3921     OCStackResult result = OC_STACK_ERROR;
3922     OCServerRequest *serverRequest = NULL;
3923
3924     OIC_LOG(INFO, TAG, "Entering OCDoResponse");
3925
3926     // Validate input parameters
3927     VERIFY_NON_NULL(ehResponse, ERROR, OC_STACK_INVALID_PARAM);
3928     VERIFY_NON_NULL(ehResponse->requestHandle, ERROR, OC_STACK_INVALID_PARAM);
3929
3930     // Normal response
3931     // Get pointer to request info
3932     serverRequest = GetServerRequestUsingHandle((OCServerRequest *)ehResponse->requestHandle);
3933     if(serverRequest)
3934     {
3935         // response handler in ocserverrequest.c. Usually HandleSingleResponse.
3936         result = serverRequest->ehResponseHandler(ehResponse);
3937     }
3938
3939     return result;
3940 }
3941
3942 //#ifdef DIRECT_PAIRING
3943 const OCDPDev_t* OCDiscoverDirectPairingDevices(unsigned short waittime)
3944 {
3945     OIC_LOG(INFO, TAG, "Start OCDiscoverDirectPairingDevices");
3946     if(OC_STACK_OK != DPDeviceDiscovery(waittime))
3947     {
3948         OIC_LOG(ERROR, TAG, "Fail to discover Direct-Pairing device");
3949         return NULL;
3950     }
3951
3952     return (const OCDPDev_t*)DPGetDiscoveredDevices();
3953 }
3954
3955 const OCDPDev_t* OCGetDirectPairedDevices()
3956 {
3957     return (const OCDPDev_t*)DPGetPairedDevices();
3958 }
3959
3960 OCStackResult OCDoDirectPairing(void *ctx, OCDPDev_t* peer, OCPrm_t pmSel, char *pinNumber,
3961                                                      OCDirectPairingCB resultCallback)
3962 {
3963     OIC_LOG(INFO, TAG, "Start OCDoDirectPairing");
3964     if(NULL ==  peer || NULL == pinNumber)
3965     {
3966         OIC_LOG(ERROR, TAG, "Invalid parameters");
3967         return OC_STACK_INVALID_PARAM;
3968     }
3969     if (NULL == resultCallback)
3970     {
3971         OIC_LOG(ERROR, TAG, "Invalid callback");
3972         return OC_STACK_INVALID_CALLBACK;
3973     }
3974
3975     return DPDirectPairing(ctx, (OCDirectPairingDev_t*)peer, (OicSecPrm_t)pmSel,
3976                                            pinNumber, (OCDirectPairingResultCB)resultCallback);
3977 }
3978 //#endif // DIRECT_PAIRING
3979
3980 //-----------------------------------------------------------------------------
3981 // Private internal function definitions
3982 //-----------------------------------------------------------------------------
3983 static OCDoHandle GenerateInvocationHandle()
3984 {
3985     OCDoHandle handle = NULL;
3986     // Generate token here, it will be deleted when the transaction is deleted
3987     handle = (OCDoHandle) OICMalloc(sizeof(uint8_t[CA_MAX_TOKEN_LEN]));
3988     if (handle)
3989     {
3990         OCFillRandomMem((uint8_t*)handle, sizeof(uint8_t[CA_MAX_TOKEN_LEN]));
3991     }
3992
3993     return handle;
3994 }
3995
3996 #ifdef WITH_PRESENCE
3997 OCStackResult OCChangeResourceProperty(OCResourceProperty * inputProperty,
3998         OCResourceProperty resourceProperties, uint8_t enable)
3999 {
4000     if (!inputProperty)
4001     {
4002         return OC_STACK_INVALID_PARAM;
4003     }
4004     if (resourceProperties
4005             > (OC_ACTIVE | OC_DISCOVERABLE | OC_OBSERVABLE | OC_SLOW))
4006     {
4007         OIC_LOG(ERROR, TAG, "Invalid property");
4008         return OC_STACK_INVALID_PARAM;
4009     }
4010     if(!enable)
4011     {
4012         *inputProperty = (OCResourceProperty) (*inputProperty & ~(resourceProperties));
4013     }
4014     else
4015     {
4016         *inputProperty = (OCResourceProperty) (*inputProperty | resourceProperties);
4017     }
4018     return OC_STACK_OK;
4019 }
4020 #endif
4021
4022 OCStackResult initResources()
4023 {
4024     OCStackResult result = OC_STACK_OK;
4025
4026     headResource = NULL;
4027     tailResource = NULL;
4028     // Init Virtual Resources
4029 #ifdef WITH_PRESENCE
4030     presenceResource.presenceTTL = OC_DEFAULT_PRESENCE_TTL_SECONDS;
4031
4032     result = OCCreateResource(&presenceResource.handle,
4033             OC_RSRVD_RESOURCE_TYPE_PRESENCE,
4034             "core.r",
4035             OC_RSRVD_PRESENCE_URI,
4036             NULL,
4037             NULL,
4038             OC_OBSERVABLE);
4039     //make resource inactive
4040     result = OCChangeResourceProperty(
4041             &(((OCResource *) presenceResource.handle)->resourceProperties),
4042             OC_ACTIVE, 0);
4043 #endif
4044 #ifndef WITH_ARDUINO
4045     if (result == OC_STACK_OK)
4046     {
4047         result = SRMInitSecureResources();
4048     }
4049 #endif
4050
4051     if(result == OC_STACK_OK)
4052     {
4053         result = OCCreateResource(&deviceResource,
4054                                   OC_RSRVD_RESOURCE_TYPE_DEVICE,
4055                                   OC_RSRVD_INTERFACE_DEFAULT,
4056                                   OC_RSRVD_DEVICE_URI,
4057                                   NULL,
4058                                   NULL,
4059                                   OC_DISCOVERABLE);
4060         if(result == OC_STACK_OK)
4061         {
4062             result = BindResourceInterfaceToResource((OCResource *)deviceResource,
4063                                                      OC_RSRVD_INTERFACE_READ);
4064         }
4065     }
4066
4067     if(result == OC_STACK_OK)
4068     {
4069         result = OCCreateResource(&platformResource,
4070                                   OC_RSRVD_RESOURCE_TYPE_PLATFORM,
4071                                   OC_RSRVD_INTERFACE_DEFAULT,
4072                                   OC_RSRVD_PLATFORM_URI,
4073                                   NULL,
4074                                   NULL,
4075                                   OC_DISCOVERABLE);
4076         if(result == OC_STACK_OK)
4077         {
4078             result = BindResourceInterfaceToResource((OCResource *)platformResource,
4079                                                      OC_RSRVD_INTERFACE_READ);
4080         }
4081     }
4082
4083     return result;
4084 }
4085
4086 void insertResource(OCResource *resource)
4087 {
4088     if (!headResource)
4089     {
4090         headResource = resource;
4091         tailResource = resource;
4092     }
4093     else
4094     {
4095         tailResource->next = resource;
4096         tailResource = resource;
4097     }
4098     resource->next = NULL;
4099 }
4100
4101 OCResource *findResource(OCResource *resource)
4102 {
4103     OCResource *pointer = headResource;
4104
4105     while (pointer)
4106     {
4107         if (pointer == resource)
4108         {
4109             return resource;
4110         }
4111         pointer = pointer->next;
4112     }
4113     return NULL;
4114 }
4115
4116 void deleteAllResources()
4117 {
4118     OCResource *pointer = headResource;
4119     OCResource *temp = NULL;
4120
4121     while (pointer)
4122     {
4123         temp = pointer->next;
4124 #ifdef WITH_PRESENCE
4125         if (pointer != (OCResource *) presenceResource.handle)
4126         {
4127 #endif // WITH_PRESENCE
4128             deleteResource(pointer);
4129 #ifdef WITH_PRESENCE
4130         }
4131 #endif // WITH_PRESENCE
4132         pointer = temp;
4133     }
4134
4135     SRMDeInitSecureResources();
4136
4137 #ifdef WITH_PRESENCE
4138     // Ensure that the last resource to be deleted is the presence resource. This allows for all
4139     // presence notification attributed to their deletion to be processed.
4140     deleteResource((OCResource *) presenceResource.handle);
4141 #endif // WITH_PRESENCE
4142 }
4143
4144 OCStackResult deleteResource(OCResource *resource)
4145 {
4146     OCResource *prev = NULL;
4147     OCResource *temp = NULL;
4148     if(!resource)
4149     {
4150         OIC_LOG(DEBUG,TAG,"resource is NULL");
4151         return OC_STACK_INVALID_PARAM;
4152     }
4153
4154     OIC_LOG_V (INFO, TAG, "Deleting resource %s", resource->uri);
4155
4156     temp = headResource;
4157     while (temp)
4158     {
4159         if (temp == resource)
4160         {
4161             // Invalidate all Resource Properties.
4162             resource->resourceProperties = (OCResourceProperty) 0;
4163 #ifdef WITH_PRESENCE
4164             if(resource != (OCResource *) presenceResource.handle)
4165             {
4166 #endif // WITH_PRESENCE
4167                 OCNotifyAllObservers((OCResourceHandle)resource, OC_HIGH_QOS);
4168 #ifdef WITH_PRESENCE
4169             }
4170
4171             if(presenceResource.handle)
4172             {
4173                 ((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
4174                 SendPresenceNotification(resource->rsrcType, OC_PRESENCE_TRIGGER_DELETE);
4175             }
4176 #endif
4177             // Only resource in list.
4178             if (temp == headResource && temp == tailResource)
4179             {
4180                 headResource = NULL;
4181                 tailResource = NULL;
4182             }
4183             // Deleting head.
4184             else if (temp == headResource)
4185             {
4186                 headResource = temp->next;
4187             }
4188             // Deleting tail.
4189             else if (temp == tailResource)
4190             {
4191                 tailResource = prev;
4192                 tailResource->next = NULL;
4193             }
4194             else
4195             {
4196                 prev->next = temp->next;
4197             }
4198
4199             deleteResourceElements(temp);
4200             OICFree(temp);
4201             return OC_STACK_OK;
4202         }
4203         else
4204         {
4205             prev = temp;
4206             temp = temp->next;
4207         }
4208     }
4209
4210     return OC_STACK_ERROR;
4211 }
4212
4213 void deleteResourceElements(OCResource *resource)
4214 {
4215     if (!resource)
4216     {
4217         return;
4218     }
4219
4220     OICFree(resource->uri);
4221     deleteResourceType(resource->rsrcType);
4222     deleteResourceInterface(resource->rsrcInterface);
4223 }
4224
4225 void deleteResourceType(OCResourceType *resourceType)
4226 {
4227     OCResourceType *pointer = resourceType;
4228     OCResourceType *next = NULL;
4229
4230     while (pointer)
4231     {
4232         next = pointer->next;
4233         OICFree(pointer->resourcetypename);
4234         OICFree(pointer);
4235         pointer = next;
4236     }
4237 }
4238
4239 void deleteResourceInterface(OCResourceInterface *resourceInterface)
4240 {
4241     OCResourceInterface *pointer = resourceInterface;
4242     OCResourceInterface *next = NULL;
4243
4244     while (pointer)
4245     {
4246         next = pointer->next;
4247         OICFree(pointer->name);
4248         OICFree(pointer);
4249         pointer = next;
4250     }
4251 }
4252
4253 void insertResourceType(OCResource *resource, OCResourceType *resourceType)
4254 {
4255     OCResourceType *pointer = NULL;
4256     OCResourceType *previous = NULL;
4257     if (!resource || !resourceType)
4258     {
4259         return;
4260     }
4261     // resource type list is empty.
4262     else if (!resource->rsrcType)
4263     {
4264         resource->rsrcType = resourceType;
4265     }
4266     else
4267     {
4268         pointer = resource->rsrcType;
4269
4270         while (pointer)
4271         {
4272             if (!strcmp(resourceType->resourcetypename, pointer->resourcetypename))
4273             {
4274                 OIC_LOG_V(INFO, TAG, "Type %s already exists", resourceType->resourcetypename);
4275                 OICFree(resourceType->resourcetypename);
4276                 OICFree(resourceType);
4277                 return;
4278             }
4279             previous = pointer;
4280             pointer = pointer->next;
4281         }
4282
4283         if (previous)
4284         {
4285             previous->next = resourceType;
4286         }
4287     }
4288     resourceType->next = NULL;
4289
4290     OIC_LOG_V(INFO, TAG, "Added type %s to %s", resourceType->resourcetypename, resource->uri);
4291 }
4292
4293 OCResourceType *findResourceTypeAtIndex(OCResourceHandle handle, uint8_t index)
4294 {
4295     OCResource *resource = NULL;
4296     OCResourceType *pointer = NULL;
4297
4298     // Find the specified resource
4299     resource = findResource((OCResource *) handle);
4300     if (!resource)
4301     {
4302         return NULL;
4303     }
4304
4305     // Make sure a resource has a resourcetype
4306     if (!resource->rsrcType)
4307     {
4308         return NULL;
4309     }
4310
4311     // Iterate through the list
4312     pointer = resource->rsrcType;
4313     for(uint8_t i = 0; i< index && pointer; ++i)
4314     {
4315         pointer = pointer->next;
4316     }
4317     return pointer;
4318 }
4319
4320 OCResourceType *findResourceType(OCResourceType * resourceTypeList, const char * resourceTypeName)
4321 {
4322     if(resourceTypeList && resourceTypeName)
4323     {
4324         OCResourceType * rtPointer = resourceTypeList;
4325         while(resourceTypeName && rtPointer)
4326         {
4327             if(rtPointer->resourcetypename &&
4328                     strcmp(resourceTypeName, (const char *)
4329                     (rtPointer->resourcetypename)) == 0)
4330             {
4331                 break;
4332             }
4333             rtPointer = rtPointer->next;
4334         }
4335         return rtPointer;
4336     }
4337     return NULL;
4338 }
4339
4340 /*
4341  * Insert a new interface into interface linked list only if not already present.
4342  * If alredy present, 2nd arg is free'd.
4343  * Default interface will always be first if present.
4344  */
4345 void insertResourceInterface(OCResource *resource, OCResourceInterface *newInterface)
4346 {
4347     OCResourceInterface *pointer = NULL;
4348     OCResourceInterface *previous = NULL;
4349
4350     newInterface->next = NULL;
4351
4352     OCResourceInterface **firstInterface = &(resource->rsrcInterface);
4353
4354     if (!*firstInterface)
4355     {
4356         // If first interface is not oic.if.baseline, by default add it as first interface type.
4357         if (0 == strcmp(newInterface->name, OC_RSRVD_INTERFACE_DEFAULT))
4358         {
4359             *firstInterface = newInterface;
4360         }
4361         else
4362         {
4363             OCStackResult result = BindResourceInterfaceToResource(resource, OC_RSRVD_INTERFACE_DEFAULT);
4364             if (result != OC_STACK_OK)
4365             {
4366                 OICFree(newInterface->name);
4367                 OICFree(newInterface);
4368                 return;
4369             }
4370             if (*firstInterface)
4371             {
4372                 (*firstInterface)->next = newInterface;
4373             }
4374         }
4375     }
4376     // If once add oic.if.baseline, later too below code take care of freeing memory.
4377     else if (strcmp(newInterface->name, OC_RSRVD_INTERFACE_DEFAULT) == 0)
4378     {
4379         if (strcmp((*firstInterface)->name, OC_RSRVD_INTERFACE_DEFAULT) == 0)
4380         {
4381             OICFree(newInterface->name);
4382             OICFree(newInterface);
4383             return;
4384         }
4385         // This code will not hit anymore, keeping
4386         else
4387         {
4388             newInterface->next = *firstInterface;
4389             *firstInterface = newInterface;
4390         }
4391     }
4392     else
4393     {
4394         pointer = *firstInterface;
4395         while (pointer)
4396         {
4397             if (strcmp(newInterface->name, pointer->name) == 0)
4398             {
4399                 OICFree(newInterface->name);
4400                 OICFree(newInterface);
4401                 return;
4402             }
4403             previous = pointer;
4404             pointer = pointer->next;
4405         }
4406         previous->next = newInterface;
4407     }
4408 }
4409
4410 OCResourceInterface *findResourceInterfaceAtIndex(OCResourceHandle handle,
4411         uint8_t index)
4412 {
4413     OCResource *resource = NULL;
4414     OCResourceInterface *pointer = NULL;
4415
4416     // Find the specified resource
4417     resource = findResource((OCResource *) handle);
4418     if (!resource)
4419     {
4420         return NULL;
4421     }
4422
4423     // Make sure a resource has a resourceinterface
4424     if (!resource->rsrcInterface)
4425     {
4426         return NULL;
4427     }
4428
4429     // Iterate through the list
4430     pointer = resource->rsrcInterface;
4431
4432     for (uint8_t i = 0; i < index && pointer; ++i)
4433     {
4434         pointer = pointer->next;
4435     }
4436     return pointer;
4437 }
4438
4439 /*
4440  * This function splits the uri using the '?' delimiter.
4441  * "uriWithoutQuery" is the block of characters between the beginning
4442  * till the delimiter or '\0' which ever comes first.
4443  * "query" is whatever is to the right of the delimiter if present.
4444  * No delimiter sets the query to NULL.
4445  * If either are present, they will be malloc'ed into the params 2, 3.
4446  * The first param, *uri is left untouched.
4447
4448  * NOTE: This function does not account for whitespace at the end of the uri NOR
4449  *       malformed uri's with '??'. Whitespace at the end will be assumed to be
4450  *       part of the query.
4451  */
4452 OCStackResult getQueryFromUri(const char * uri, char** query, char ** uriWithoutQuery)
4453 {
4454     if(!uri)
4455     {
4456         return OC_STACK_INVALID_URI;
4457     }
4458     if(!query || !uriWithoutQuery)
4459     {
4460         return OC_STACK_INVALID_PARAM;
4461     }
4462
4463     *query           = NULL;
4464     *uriWithoutQuery = NULL;
4465
4466     size_t uriWithoutQueryLen = 0;
4467     size_t queryLen = 0;
4468     size_t uriLen = strlen(uri);
4469
4470     char *pointerToDelimiter = strstr(uri, "?");
4471
4472     uriWithoutQueryLen = pointerToDelimiter == NULL ? uriLen : (size_t)(pointerToDelimiter - uri);
4473     queryLen = pointerToDelimiter == NULL ? 0 : uriLen - uriWithoutQueryLen - 1;
4474
4475     if (uriWithoutQueryLen)
4476     {
4477         *uriWithoutQuery =  (char *) OICCalloc(uriWithoutQueryLen + 1, 1);
4478         if (!*uriWithoutQuery)
4479         {
4480             goto exit;
4481         }
4482         OICStrcpy(*uriWithoutQuery, uriWithoutQueryLen +1, uri);
4483     }
4484     if (queryLen)
4485     {
4486         *query = (char *) OICCalloc(queryLen + 1, 1);
4487         if (!*query)
4488         {
4489             OICFree(*uriWithoutQuery);
4490             *uriWithoutQuery = NULL;
4491             goto exit;
4492         }
4493         OICStrcpy(*query, queryLen + 1, pointerToDelimiter + 1);
4494     }
4495
4496     return OC_STACK_OK;
4497
4498     exit:
4499         return OC_STACK_NO_MEMORY;
4500 }
4501
4502 static const OicUuid_t* OCGetServerInstanceID(void)
4503 {
4504     static bool generated = false;
4505     static OicUuid_t sid;
4506     if (generated)
4507     {
4508         return &sid;
4509     }
4510
4511     if (OC_STACK_OK != GetDoxmDeviceID(&sid))
4512     {
4513         OIC_LOG(FATAL, TAG, "Generate UUID for Server Instance failed!");
4514         return NULL;
4515     }
4516     generated = true;
4517     return &sid;
4518 }
4519
4520 const char* OCGetServerInstanceIDString(void)
4521 {
4522     static bool generated = false;
4523     static char sidStr[UUID_STRING_SIZE];
4524
4525     if(generated)
4526     {
4527         return sidStr;
4528     }
4529
4530     const OicUuid_t *sid = OCGetServerInstanceID();
4531     if(OCConvertUuidToString(sid->id, sidStr) != RAND_UUID_OK)
4532     {
4533         OIC_LOG(FATAL, TAG, "Generate UUID String for Server Instance failed!");
4534         return NULL;
4535     }
4536
4537     generated = true;
4538     return sidStr;
4539 }
4540
4541 CAResult_t OCSelectNetwork()
4542 {
4543     CAResult_t retResult = CA_STATUS_FAILED;
4544     CAResult_t caResult = CA_STATUS_OK;
4545
4546     CATransportAdapter_t connTypes[] = {
4547             CA_ADAPTER_IP,
4548             CA_ADAPTER_RFCOMM_BTEDR,
4549             CA_ADAPTER_GATT_BTLE,
4550             CA_ADAPTER_NFC
4551 #ifdef RA_ADAPTER
4552             ,CA_ADAPTER_REMOTE_ACCESS
4553 #endif
4554
4555 #ifdef TCP_ADAPTER
4556             ,CA_ADAPTER_TCP
4557 #endif
4558         };
4559     int numConnTypes = sizeof(connTypes)/sizeof(connTypes[0]);
4560
4561     for(int i = 0; i<numConnTypes; i++)
4562     {
4563         // Ignore CA_NOT_SUPPORTED error. The CA Layer may have not compiled in the interface.
4564         if(caResult == CA_STATUS_OK || caResult == CA_NOT_SUPPORTED)
4565         {
4566            caResult = CASelectNetwork(connTypes[i]);
4567            if(caResult == CA_STATUS_OK)
4568            {
4569                retResult = CA_STATUS_OK;
4570            }
4571         }
4572     }
4573
4574     if(retResult != CA_STATUS_OK)
4575     {
4576         return caResult; // Returns error of appropriate transport that failed fatally.
4577     }
4578
4579     return retResult;
4580 }
4581
4582 OCStackResult CAResultToOCResult(CAResult_t caResult)
4583 {
4584     switch (caResult)
4585     {
4586         case CA_STATUS_OK:
4587             return OC_STACK_OK;
4588         case CA_STATUS_INVALID_PARAM:
4589             return OC_STACK_INVALID_PARAM;
4590         case CA_ADAPTER_NOT_ENABLED:
4591             return OC_STACK_ADAPTER_NOT_ENABLED;
4592         case CA_SERVER_STARTED_ALREADY:
4593             return OC_STACK_OK;
4594         case CA_SERVER_NOT_STARTED:
4595             return OC_STACK_ERROR;
4596         case CA_DESTINATION_NOT_REACHABLE:
4597             return OC_STACK_COMM_ERROR;
4598         case CA_SOCKET_OPERATION_FAILED:
4599             return OC_STACK_COMM_ERROR;
4600         case CA_SEND_FAILED:
4601             return OC_STACK_COMM_ERROR;
4602         case CA_RECEIVE_FAILED:
4603             return OC_STACK_COMM_ERROR;
4604         case CA_MEMORY_ALLOC_FAILED:
4605             return OC_STACK_NO_MEMORY;
4606         case CA_REQUEST_TIMEOUT:
4607             return OC_STACK_TIMEOUT;
4608         case CA_DESTINATION_DISCONNECTED:
4609             return OC_STACK_COMM_ERROR;
4610         case CA_STATUS_FAILED:
4611             return OC_STACK_ERROR;
4612         case CA_NOT_SUPPORTED:
4613             return OC_STACK_NOTIMPL;
4614         default:
4615             return OC_STACK_ERROR;
4616     }
4617 }