Merge remote-tracking branch 'origin/routing-manager'
[platform/upstream/iotivity.git] / resource / csdk / stack / src / ocobserve.c
index 654078d..6749105 100644 (file)
 #include "ocobserve.h"
 #include "ocresourcehandler.h"
 #include "ocrandom.h"
-#include "ocmalloc.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "ocpayload.h"
 #include "ocserverrequest.h"
+#include "logger.h"
 
 #include "utlist.h"
 #include "pdu.h"
 
+
 // Module Name
-#define MOD_NAME PCF("ocobserve")
+#define MOD_NAME "ocobserve"
 
-#define TAG  PCF("OCStackObserve")
+#define TAG  "OCStackObserve"
 
 #define VERIFY_NON_NULL(arg) { if (!arg) {OC_LOG(FATAL, TAG, #arg " is NULL"); goto exit;} }
 
 static struct ResourceObserver * serverObsList = NULL;
-
 /**
  * Determine observe QOS based on the QOS of the request.
  * The qos passed as a parameter overrides what the client requested.
@@ -70,19 +73,19 @@ static OCQualityOfService DetermineObserverQoS(OCMethod method,
     {
         OC_LOG_V(INFO, TAG, "Current NON count for this observer is %d",
                 resourceObserver->lowQosCount);
-        #ifdef WITH_PRESENCE
+#ifdef WITH_PRESENCE
         if((resourceObserver->forceHighQos \
                 || resourceObserver->lowQosCount >= MAX_OBSERVER_NON_COUNT) \
                 && method != OC_REST_PRESENCE)
-        #else
+#else
         if(resourceObserver->forceHighQos \
                 || resourceObserver->lowQosCount >= MAX_OBSERVER_NON_COUNT)
-        #endif
+#endif
         {
             resourceObserver->lowQosCount = 0;
             // at some point we have to to send CON to check on the
             // availability of observer
-            OC_LOG(INFO, TAG, PCF("This time we are sending the  notification as High qos"));
+            OC_LOG(INFO, TAG, "This time we are sending the  notification as High qos");
             decidedQoS = OC_HIGH_QOS;
         }
         else
@@ -95,13 +98,13 @@ static OCQualityOfService DetermineObserverQoS(OCMethod method,
 
 #ifdef WITH_PRESENCE
 OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr, uint32_t maxAge,
-        OCResourceType *resourceType, OCQualityOfService qos)
+        OCPresenceTrigger trigger, OCResourceType *resourceType, OCQualityOfService qos)
 #else
 OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr, uint32_t maxAge,
         OCQualityOfService qos)
 #endif
 {
-    OC_LOG(INFO, TAG, PCF("Entering SendObserverNotification"));
+    OC_LOG(INFO, TAG, "Entering SendObserverNotification");
     if(!resPtr)
     {
         return OC_STACK_INVALID_PARAM;
@@ -111,7 +114,7 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr,
     ResourceObserver * resourceObserver = serverObsList;
     uint8_t numObs = 0;
     OCServerRequest * request = NULL;
-    OCEntityHandlerRequest ehRequest = {};
+    OCEntityHandlerRequest ehRequest = {0};
     OCEntityHandlerResult ehResult = OC_EH_ERROR;
     bool observeErrorFlag = false;
 
@@ -121,81 +124,92 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr,
         if (resourceObserver->resource == resPtr)
         {
             numObs++;
-            #ifdef WITH_PRESENCE
+#ifdef WITH_PRESENCE
             if(method != OC_REST_PRESENCE)
             {
-            #endif
+#endif
                 qos = DetermineObserverQoS(method, resourceObserver, qos);
 
-                result = AddServerRequest(&request, 0, 0, 0, 1, OC_REST_GET,
+                result = AddServerRequest(&request, 0, 0, 1, OC_REST_GET,
                         0, resPtr->sequenceNum, qos, resourceObserver->query,
                         NULL, NULL,
                         resourceObserver->token, resourceObserver->tokenLength,
-                        resourceObserver->resUri, 0,
-                        &(resourceObserver->addressInfo), resourceObserver->connectivityType);
+                        resourceObserver->resUri, 0, resourceObserver->acceptFormat,
+                        &resourceObserver->devAddr);
 
                 if(request)
                 {
                     request->observeResult = OC_STACK_OK;
                     if(result == OC_STACK_OK)
                     {
-                        result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
-                                    request->method, (OCResourceHandle) resPtr, request->query,
-                                    request->reqJSONPayload,
+                        result = FormOCEntityHandlerRequest(
+                                    &ehRequest,
+                                    (OCRequestHandle) request,
+                                    request->method,
+                                    &request->devAddr,
+                                    (OCResourceHandle) resPtr,
+                                    request->query,
+                                    PAYLOAD_TYPE_REPRESENTATION,
+                                    request->payload,
+                                    request->payloadSize,
                                     request->numRcvdVendorSpecificHeaderOptions,
                                     request->rcvdVendorSpecificHeaderOptions,
-                                    OC_OBSERVE_NO_OPTION, 0);
+                                    OC_OBSERVE_NO_OPTION,
+                                    0);
                         if(result == OC_STACK_OK)
                         {
-                            ehResult = resPtr->entityHandler(OC_REQUEST_FLAG, &ehRequest);
+                            ehResult = resPtr->entityHandler(OC_REQUEST_FLAG, &ehRequest,
+                                                resPtr->entityHandlerCallbackParam);
                             if(ehResult == OC_EH_ERROR)
                             {
                                 FindAndDeleteServerRequest(request);
                             }
                         }
+                        OCPayloadDestroy(ehRequest.payload);
                     }
                 }
-            #ifdef WITH_PRESENCE
+#ifdef WITH_PRESENCE
             }
             else
             {
-                OCEntityHandlerResponse ehResponse = {};
-                char presenceResBuf[MAX_RESPONSE_LENGTH] = {};
+                OCEntityHandlerResponse ehResponse = {0};
 
                 //This is effectively the implementation for the presence entity handler.
-                OC_LOG(DEBUG, TAG, PCF("This notification is for Presence"));
-
-                result = AddServerRequest(&request, 0, 0, 0, 1, OC_REST_GET,
+                OC_LOG(DEBUG, TAG, "This notification is for Presence");
+                result = AddServerRequest(&request, 0, 0, 1, OC_REST_GET,
                         0, resPtr->sequenceNum, qos, resourceObserver->query,
                         NULL, NULL,
                         resourceObserver->token, resourceObserver->tokenLength,
-                        resourceObserver->resUri, 0,
-                        &(resourceObserver->addressInfo), resourceObserver->connectivityType);
+                        resourceObserver->resUri, 0, resourceObserver->acceptFormat,
+                        &resourceObserver->devAddr);
 
                 if(result == OC_STACK_OK)
                 {
-                    // we create the payload here
-                    if(resourceType && resourceType->resourcetypename)
+                    OCPresencePayload* presenceResBuf = OCPresencePayloadCreate(
+                            resPtr->sequenceNum, maxAge, trigger,
+                            resourceType ? resourceType->resourcetypename : NULL);
+
+                    if(!presenceResBuf)
                     {
-                        snprintf((char *)presenceResBuf, sizeof(presenceResBuf), "%u:%u:%s",
-                                resPtr->sequenceNum, maxAge, resourceType->resourcetypename);
+                        return OC_STACK_NO_MEMORY;
                     }
-                    else
+
+                    if(result == OC_STACK_OK)
                     {
-                        snprintf((char *)presenceResBuf, sizeof(presenceResBuf), "%u:%u",
-                                resPtr->sequenceNum, maxAge);
+                        ehResponse.ehResult = OC_EH_OK;
+                        ehResponse.payload = (OCPayload*)presenceResBuf;
+                        ehResponse.persistentBufferFlag = 0;
+                        ehResponse.requestHandle = (OCRequestHandle) request;
+                        ehResponse.resourceHandle = (OCResourceHandle) resPtr;
+                        OICStrcpy(ehResponse.resourceUri, sizeof(ehResponse.resourceUri),
+                                resourceObserver->resUri);
+                        result = OCDoResponse(&ehResponse);
                     }
-                    ehResponse.ehResult = OC_EH_OK;
-                    ehResponse.payload = presenceResBuf;
-                    ehResponse.payloadSize = strlen((const char *)presenceResBuf) + 1;
-                    ehResponse.persistentBufferFlag = 0;
-                    ehResponse.requestHandle = (OCRequestHandle) request;
-                    ehResponse.resourceHandle = (OCResourceHandle) resPtr;
-                    strcpy((char *)ehResponse.resourceUri, (const char *)resourceObserver->resUri);
-                    result = OCDoResponse(&ehResponse);
+
+                    OCPresencePayloadDestroy(presenceResBuf);
                 }
             }
-            #endif
+#endif
 
             // Since we are in a loop, set an error flag to indicate at least one error occurred.
             if (result != OC_STACK_OK)
@@ -208,12 +222,12 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr,
 
     if (numObs == 0)
     {
-        OC_LOG(INFO, TAG, PCF("Resource has no observers"));
+        OC_LOG(INFO, TAG, "Resource has no observers");
         result = OC_STACK_NO_OBSERVERS;
     }
     else if (observeErrorFlag)
     {
-        OC_LOG(ERROR, TAG, PCF("Observer notification error"));
+        OC_LOG(ERROR, TAG, "Observer notification error");
         result = OC_STACK_ERROR;
     }
     return result;
@@ -221,10 +235,12 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr,
 
 OCStackResult SendListObserverNotification (OCResource * resource,
         OCObservationId  *obsIdList, uint8_t numberOfIds,
-        const char *notificationJSONPayload, uint32_t maxAge,
+        const OCRepPayload *payload,
+        uint32_t maxAge,
         OCQualityOfService qos)
 {
-    if(!resource || !obsIdList || !notificationJSONPayload)
+    (void)maxAge;
+    if(!resource || !obsIdList || !payload)
     {
         return OC_STACK_INVALID_PARAM;
     }
@@ -236,7 +252,7 @@ OCStackResult SendListObserverNotification (OCResource * resource,
     OCStackResult result = OC_STACK_ERROR;
     bool observeErrorFlag = false;
 
-    OC_LOG(INFO, TAG, PCF("Entering SendListObserverNotification"));
+    OC_LOG(INFO, TAG, "Entering SendListObserverNotification");
     while(numIds)
     {
         observer = GetObserverUsingId (*obsIdList);
@@ -248,28 +264,26 @@ OCStackResult SendListObserverNotification (OCResource * resource,
                 qos = DetermineObserverQoS(OC_REST_GET, observer, qos);
 
 
-                result = AddServerRequest(&request, 0, 0, 0, 1, OC_REST_GET,
+                result = AddServerRequest(&request, 0, 0, 1, OC_REST_GET,
                         0, resource->sequenceNum, qos, observer->query,
                         NULL, NULL, observer->token, observer->tokenLength,
-                        observer->resUri, 0,
-                        &(observer->addressInfo), observer->connectivityType);
+                        observer->resUri, 0, observer->acceptFormat,
+                        &observer->devAddr);
 
                 if(request)
                 {
                     request->observeResult = OC_STACK_OK;
                     if(result == OC_STACK_OK)
                     {
-                        OCEntityHandlerResponse ehResponse = {};
+                        OCEntityHandlerResponse ehResponse = {0};
                         ehResponse.ehResult = OC_EH_OK;
-                        ehResponse.payload = (char *) OCMalloc(MAX_RESPONSE_LENGTH + 1);
+                        ehResponse.payload = (OCPayload*)OCRepPayloadCreate();
                         if(!ehResponse.payload)
                         {
                             FindAndDeleteServerRequest(request);
                             continue;
                         }
-                        strncpy(ehResponse.payload, notificationJSONPayload, MAX_RESPONSE_LENGTH-1);
-                        ehResponse.payload[MAX_RESPONSE_LENGTH] = '\0';
-                        ehResponse.payloadSize = strlen(ehResponse.payload) + 1;
+                        memcpy(ehResponse.payload, payload, sizeof(*payload));
                         ehResponse.persistentBufferFlag = 0;
                         ehResponse.requestHandle = (OCRequestHandle) request;
                         ehResponse.resourceHandle = (OCResourceHandle) resource;
@@ -281,7 +295,7 @@ OCStackResult SendListObserverNotification (OCResource * resource,
                             // Increment only if OCDoResponse is successful
                             numSentNotification++;
 
-                            OCFree(ehResponse.payload);
+                            OICFree(ehResponse.payload);
                             FindAndDeleteServerRequest(request);
                         }
                         else
@@ -316,7 +330,7 @@ OCStackResult SendListObserverNotification (OCResource * resource,
     }
     else
     {
-        OC_LOG(ERROR, TAG, PCF("Observer notification error"));
+        OC_LOG(ERROR, TAG, "Observer notification error");
         return OC_STACK_ERROR;
     }
 }
@@ -325,7 +339,7 @@ OCStackResult GenerateObserverId (OCObservationId *observationId)
 {
     ResourceObserver *resObs = NULL;
 
-    OC_LOG(INFO, TAG, PCF("Entering GenerateObserverId"));
+    OC_LOG(INFO, TAG, "Entering GenerateObserverId");
     VERIFY_NON_NULL (observationId);
 
     do
@@ -335,7 +349,7 @@ OCStackResult GenerateObserverId (OCObservationId *observationId)
         resObs = GetObserverUsingId (*observationId);
     } while (NULL != resObs);
 
-    OC_LOG_V(INFO, TAG, "Generated bservation ID is %u", *observationId);
+    OC_LOG_V(INFO, TAG, "GeneratedObservation ID is %u", *observationId);
 
     return OC_STACK_OK;
 exit:
@@ -349,8 +363,8 @@ OCStackResult AddObserver (const char         *resUri,
                            uint8_t            tokenLength,
                            OCResource         *resHandle,
                            OCQualityOfService qos,
-                           const CAAddress_t  *addressInfo,
-                           CATransportType_t connectivityType)
+                           OCPayloadFormat    acceptFormat,
+                           const OCDevAddr    *devAddr)
 {
     // Check if resource exists and is observable.
     if (!resHandle)
@@ -368,44 +382,45 @@ OCStackResult AddObserver (const char         *resUri,
         return OC_STACK_INVALID_PARAM;
     }
 
-    obsNode = (ResourceObserver *) OCCalloc(1, sizeof(ResourceObserver));
+    obsNode = (ResourceObserver *) OICCalloc(1, sizeof(ResourceObserver));
     if (obsNode)
     {
         obsNode->observeId = obsId;
 
-        obsNode->resUri = (char *)OCMalloc(strlen(resUri)+1);
+        obsNode->resUri = OICStrdup(resUri);
         VERIFY_NON_NULL (obsNode->resUri);
-        memcpy (obsNode->resUri, resUri, strlen(resUri)+1);
 
         obsNode->qos = qos;
+        obsNode->acceptFormat = acceptFormat;
         if(query)
         {
-            obsNode->query = (char *)OCMalloc(strlen(query)+1);
+            obsNode->query = OICStrdup(query);
             VERIFY_NON_NULL (obsNode->query);
-            memcpy (obsNode->query, query, strlen(query)+1);
         }
         // If tokenLength is zero, the return value depends on the
         // particular library implementation (it may or may not be a null pointer).
         if(tokenLength)
         {
-            obsNode->token = (CAToken_t)OCMalloc(tokenLength);
+            obsNode->token = (CAToken_t)OICMalloc(tokenLength);
             VERIFY_NON_NULL (obsNode->token);
             memcpy(obsNode->token, token, tokenLength);
         }
         obsNode->tokenLength = tokenLength;
-        obsNode->addressInfo = *addressInfo;
-        obsNode->connectivityType = connectivityType;
+
+        obsNode->devAddr = *devAddr;
         obsNode->resource = resHandle;
+
         LL_APPEND (serverObsList, obsNode);
+
         return OC_STACK_OK;
     }
 
 exit:
     if (obsNode)
     {
-        OCFree(obsNode->resUri);
-        OCFree(obsNode->query);
-        OCFree(obsNode);
+        OICFree(obsNode->resUri);
+        OICFree(obsNode->query);
+        OICFree(obsNode);
     }
     return OC_STACK_NO_MEMORY;
 }
@@ -424,7 +439,7 @@ ResourceObserver* GetObserverUsingId (const OCObservationId observeId)
             }
         }
     }
-    OC_LOG(INFO, TAG, PCF("Observer node not found!!"));
+    OC_LOG(INFO, TAG, "Observer node not found!!");
     return NULL;
 }
 
@@ -434,10 +449,12 @@ ResourceObserver* GetObserverUsingToken (const CAToken_t token, uint8_t tokenLen
 
     if(token && *token)
     {
+        OC_LOG(INFO, TAG, "Looking for token");
+        OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength);
+        OC_LOG(INFO, TAG, "\tFound token:");
+
         LL_FOREACH (serverObsList, out)
         {
-            OC_LOG(INFO, TAG,PCF("comparing tokens"));
-            OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength);
             OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)out->token, tokenLength);
             if((memcmp(out->token, token, tokenLength) == 0))
             {
@@ -445,7 +462,12 @@ ResourceObserver* GetObserverUsingToken (const CAToken_t token, uint8_t tokenLen
             }
         }
     }
-    OC_LOG(INFO, TAG, PCF("Observer node not found!!"));
+    else
+    {
+        OC_LOG(ERROR, TAG, "Passed in NULL token");
+    }
+
+    OC_LOG(INFO, TAG, "Observer node not found!!");
     return NULL;
 }
 
@@ -461,13 +483,13 @@ OCStackResult DeleteObserverUsingToken (CAToken_t token, uint8_t tokenLength)
     obsNode = GetObserverUsingToken (token, tokenLength);
     if (obsNode)
     {
-        OC_LOG_V(INFO, TAG, PCF("deleting tokens"));
+        OC_LOG_V(INFO, TAG, "deleting observer id  %u with token", obsNode->observeId);
         OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)obsNode->token, tokenLength);
         LL_DELETE (serverObsList, obsNode);
-        OCFree(obsNode->resUri);
-        OCFree(obsNode->query);
-        OCFree(obsNode->token);
-        OCFree(obsNode);
+        OICFree(obsNode->resUri);
+        OICFree(obsNode->query);
+        OICFree(obsNode->token);
+        OICFree(obsNode);
     }
     // it is ok if we did not find the observer...
     return OC_STACK_OK;
@@ -501,21 +523,21 @@ CreateObserveHeaderOption (CAHeaderOption_t **caHdrOpt,
                            uint8_t numOptions,
                            uint8_t observeFlag)
 {
-    if(!caHdrOpt)
+    if(!caHdrOpt || !ocHdrOpt)
     {
         return OC_STACK_INVALID_PARAM;
     }
 
     CAHeaderOption_t *tmpHdrOpt = NULL;
 
-    tmpHdrOpt = (CAHeaderOption_t *) OCCalloc ((numOptions+1), sizeof(CAHeaderOption_t));
+    tmpHdrOpt = (CAHeaderOption_t *) OICCalloc ((numOptions+1), sizeof(CAHeaderOption_t));
     if (NULL == tmpHdrOpt)
     {
         return OC_STACK_NO_MEMORY;
     }
     tmpHdrOpt[0].protocolID = CA_COAP_ID;
     tmpHdrOpt[0].optionID = COAP_OPTION_OBSERVE;
-    tmpHdrOpt[0].optionLength = sizeof(uint32_t);
+    tmpHdrOpt[0].optionLength = sizeof(uint8_t);
     tmpHdrOpt[0].optionData[0] = observeFlag;
     for (uint8_t i = 0; i < numOptions; i++)
     {
@@ -543,13 +565,14 @@ GetObserveHeaderOption (uint32_t * observationOption,
     {
         return OC_STACK_INVALID_PARAM;
     }
-    *observationOption = OC_OBSERVE_NO_OPTION;
 
     if(!options || !numOptions)
     {
         return OC_STACK_INVALID_PARAM;
     }
 
+    *observationOption = OC_OBSERVE_NO_OPTION;
+
     for(uint8_t i = 0; i < *numOptions; i++)
     {
         if(options[i].protocolID == CA_COAP_ID &&
@@ -558,10 +581,7 @@ GetObserveHeaderOption (uint32_t * observationOption,
             *observationOption = options[i].optionData[0];
             for(uint8_t c = i; c < *numOptions-1; c++)
             {
-                options[i].protocolID = options[i+1].protocolID;
-                options[i].optionID = options[i+1].optionID;
-                options[i].optionLength = options[i+1].optionLength;
-                memcpy(options[i].optionData, options[i+1].optionData, options[i+1].optionLength);
+                options[i] = options[i+1];
             }
             (*numOptions)--;
             return OC_STACK_OK;