Merge branch 'master' into simulator
[platform/upstream/iotivity.git] / resource / csdk / stack / src / ocobserve.c
index 09a902f..f587d74 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 "utlist.h"
 #include "pdu.h"
 
+
 // Module Name
 #define MOD_NAME PCF("ocobserve")
 
@@ -39,7 +42,6 @@
 #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.
@@ -95,7 +97,7 @@ 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)
@@ -127,32 +129,41 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr,
             #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->token, resourceObserver->tokenLength,
                         resourceObserver->resUri, 0,
-                        &(resourceObserver->addressInfo), resourceObserver->connectivityType);
+                        &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,
+                                    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
@@ -160,37 +171,40 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr,
             else
             {
                 OCEntityHandlerResponse ehResponse = {};
-                char presenceResBuf[MAX_RESPONSE_LENGTH] = {};
+
                 //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,
+                result = AddServerRequest(&request, 0, 0, 1, OC_REST_GET,
                         0, resPtr->sequenceNum, qos, resourceObserver->query,
                         NULL, NULL,
-                        &resourceObserver->token, resourceObserver->tokenLength,
+                        resourceObserver->token, resourceObserver->tokenLength,
                         resourceObserver->resUri, 0,
-                        &(resourceObserver->addressInfo), resourceObserver->connectivityType);
+                        &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
@@ -219,16 +233,17 @@ 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)
+    if(!resource || !obsIdList || !payload)
     {
         return OC_STACK_INVALID_PARAM;
     }
 
     uint8_t numIds = numberOfIds;
-    ResourceObserver *observation = NULL;
+    ResourceObserver *observer = NULL;
     uint8_t numSentNotification = 0;
     OCServerRequest * request = NULL;
     OCStackResult result = OC_STACK_ERROR;
@@ -237,21 +252,20 @@ OCStackResult SendListObserverNotification (OCResource * resource,
     OC_LOG(INFO, TAG, PCF("Entering SendListObserverNotification"));
     while(numIds)
     {
-        OC_LOG_V(INFO, TAG, "Need to notify observation id %d", *obsIdList);
-        observation = GetObserverUsingId (*obsIdList);
-        if(observation)
+        observer = GetObserverUsingId (*obsIdList);
+        if(observer)
         {
-            // Found observation - verify if it matches the resource handle
-            if (observation->resource == resource)
+            // Found observer - verify if it matches the resource handle
+            if (observer->resource == resource)
             {
-                qos = DetermineObserverQoS(OC_REST_GET, observation, qos);
+                qos = DetermineObserverQoS(OC_REST_GET, observer, qos);
 
 
-                result = AddServerRequest(&request, 0, 0, 0, 1, OC_REST_GET,
-                        0, resource->sequenceNum, qos, observation->query,
-                        NULL, NULL, &observation->token, observation->tokenLength,
-                        observation->resUri, 0,
-                        &(observation->addressInfo), observation->connectivityType);
+                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->devAddr);
 
                 if(request)
                 {
@@ -260,26 +274,31 @@ OCStackResult SendListObserverNotification (OCResource * resource,
                     {
                         OCEntityHandlerResponse ehResponse = {};
                         ehResponse.ehResult = OC_EH_OK;
-                        ehResponse.payload = (char *) OCMalloc(MAX_RESPONSE_LENGTH);
+                        ehResponse.payload = (OCPayload*)OCRepPayloadCreate();
                         if(!ehResponse.payload)
                         {
                             FindAndDeleteServerRequest(request);
                             continue;
                         }
-                        strncpy(ehResponse.payload, notificationJSONPayload, MAX_RESPONSE_LENGTH-1);
-                        ehResponse.payloadSize = strlen(ehResponse.payload) + 1;
+                        memcpy(ehResponse.payload, payload, sizeof(*payload));
                         ehResponse.persistentBufferFlag = 0;
                         ehResponse.requestHandle = (OCRequestHandle) request;
                         ehResponse.resourceHandle = (OCResourceHandle) resource;
                         result = OCDoResponse(&ehResponse);
                         if(result == OC_STACK_OK)
                         {
-                            // Increment sent notifications only if OCDoResponse is successful
+                            OC_LOG_V(INFO, TAG, "Observer id %d notified.", *obsIdList);
+
+                            // Increment only if OCDoResponse is successful
                             numSentNotification++;
 
-                            OCFree(ehResponse.payload);
+                            OICFree(ehResponse.payload);
                             FindAndDeleteServerRequest(request);
                         }
+                        else
+                        {
+                            OC_LOG_V(INFO, TAG, "Error notifying observer id %d.", *obsIdList);
+                        }
                     }
                     else
                     {
@@ -327,7 +346,7 @@ OCStackResult GenerateObserverId (OCObservationId *observationId)
         resObs = GetObserverUsingId (*observationId);
     } while (NULL != resObs);
 
-    OC_LOG_V(INFO, TAG, "Observation ID is %u", *observationId);
+    OC_LOG_V(INFO, TAG, "Generated bservation ID is %u", *observationId);
 
     return OC_STACK_OK;
 exit:
@@ -337,12 +356,11 @@ exit:
 OCStackResult AddObserver (const char         *resUri,
                            const char         *query,
                            OCObservationId    obsId,
-                           CAToken_t          *token,
+                           CAToken_t          token,
                            uint8_t            tokenLength,
                            OCResource         *resHandle,
                            OCQualityOfService qos,
-                           const CAAddress_t  *addressInfo,
-                           CAConnectivityType_t connectivityType)
+                           const OCDevAddr    *devAddr)
 {
     // Check if resource exists and is observable.
     if (!resHandle)
@@ -360,44 +378,44 @@ 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;
         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);
+            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;
 }
@@ -420,28 +438,35 @@ ResourceObserver* GetObserverUsingId (const OCObservationId observeId)
     return NULL;
 }
 
-ResourceObserver* GetObserverUsingToken (const CAToken_t token, uint8_t tokenLength)
+ResourceObserver* GetObserverUsingToken (const CAToken_t token, uint8_t tokenLength)
 {
     ResourceObserver *out = NULL;
 
     if(token && *token)
     {
+        OC_LOG(INFO, TAG,PCF("Looking for token"));
+        OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength);
+        OC_LOG(INFO, TAG,PCF("\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))
+            if((memcmp(out->token, token, tokenLength) == 0))
             {
                 return out;
             }
         }
     }
+    else
+    {
+        OC_LOG(ERROR, TAG,PCF("Passed in NULL token"));
+    }
+
     OC_LOG(INFO, TAG, PCF("Observer node not found!!"));
     return NULL;
 }
 
-OCStackResult DeleteObserverUsingToken (CAToken_t token, uint8_t tokenLength)
+OCStackResult DeleteObserverUsingToken (CAToken_t token, uint8_t tokenLength)
 {
     if(!token || !*token)
     {
@@ -453,13 +478,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;
@@ -473,7 +498,7 @@ void DeleteObserverList()
     {
         if(out)
         {
-            DeleteObserverUsingToken (&(out->token), out->tokenLength);
+            DeleteObserverUsingToken ((out->token), out->tokenLength);
         }
     }
     serverObsList = NULL;
@@ -500,7 +525,7 @@ CreateObserveHeaderOption (CAHeaderOption_t **caHdrOpt,
 
     CAHeaderOption_t *tmpHdrOpt = NULL;
 
-    tmpHdrOpt = (CAHeaderOption_t *) OCMalloc ((numOptions+1)*sizeof(CAHeaderOption_t));
+    tmpHdrOpt = (CAHeaderOption_t *) OICCalloc ((numOptions+1), sizeof(CAHeaderOption_t));
     if (NULL == tmpHdrOpt)
     {
         return OC_STACK_NO_MEMORY;
@@ -550,10 +575,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;