CTT1.2.2: changed requestHandle value to a request ID
[platform/upstream/iotivity.git] / resource / csdk / stack / src / ocstack.c
index dcfa88d..bd495ca 100644 (file)
@@ -297,23 +297,6 @@ static void incrementSequenceNumber(OCResource * resPtr);
 static CAResult_t OCSelectNetwork();
 
 /**
- * Get the CoAP ticks after the specified number of milli-seconds.
- *
- * @param afterMilliSeconds Milli-seconds.
- * @return
- *     CoAP ticks
- */
-static uint32_t GetTicks(uint32_t afterMilliSeconds);
-
-/**
- * Convert CAResult_t to OCStackResult.
- *
- * @param caResult CAResult_t code.
- * @return ::OC_STACK_OK on success, some other value upon failure.
- */
-static OCStackResult CAResultToOCStackResult(CAResult_t caResult);
-
-/**
  * Convert CAResponseResult_t to OCStackResult.
  *
  * @param caCode CAResponseResult_t code.
@@ -457,16 +440,16 @@ bool checkProxyUri(OCHeaderOption *options, uint8_t numOptions)
     return false;
 }
 
-uint32_t GetTicks(uint32_t afterMilliSeconds)
+uint32_t GetTicks(uint32_t milliSeconds)
 {
     coap_tick_t now;
     coap_ticks(&now);
 
     // Guard against overflow of uint32_t
-    if (afterMilliSeconds <= ((UINT32_MAX - (uint32_t)now) * MILLISECONDS_PER_SECOND) /
+    if (milliSeconds <= ((UINT32_MAX - (uint32_t)now) * MILLISECONDS_PER_SECOND) /
                              COAP_TICKS_PER_SECOND)
     {
-        return now + (afterMilliSeconds * COAP_TICKS_PER_SECOND)/MILLISECONDS_PER_SECOND;
+        return now + (milliSeconds * COAP_TICKS_PER_SECOND)/MILLISECONDS_PER_SECOND;
     }
     else
     {
@@ -565,7 +548,7 @@ OCStackResult OCStackFeedBack(CAToken_t token, uint8_t tokenLength, uint8_t stat
         if(observer)
         {
             result = FormOCEntityHandlerRequest(&ehRequest,
-                                                (OCRequestHandle)NULL,
+                                                0,
                                                 OC_REST_NOMETHOD,
                                                 &observer->devAddr,
                                                 (OCResourceHandle)NULL,
@@ -617,7 +600,7 @@ OCStackResult OCStackFeedBack(CAToken_t token, uint8_t tokenLength, uint8_t stat
             if(observer->failedCommCount >= MAX_OBSERVER_FAILED_COMM)
             {
                 result = FormOCEntityHandlerRequest(&ehRequest,
-                                                    (OCRequestHandle)NULL,
+                                                    0,
                                                     OC_REST_NOMETHOD,
                                                     &observer->devAddr,
                                                     (OCResourceHandle)NULL,
@@ -647,10 +630,11 @@ OCStackResult OCStackFeedBack(CAToken_t token, uint8_t tokenLength, uint8_t stat
             else
             {
                 observer->failedCommCount++;
+                observer->forceHighQos = 1;
+                OIC_LOG_V(DEBUG, TAG, "Failed count for this observer is %d",
+                          observer->failedCommCount);
                 result = OC_STACK_CONTINUE;
             }
-            observer->forceHighQos = 1;
-            OIC_LOG_V(DEBUG, TAG, "Failed count for this observer is %d",observer->failedCommCount);
         }
         break;
     default:
@@ -661,28 +645,6 @@ OCStackResult OCStackFeedBack(CAToken_t token, uint8_t tokenLength, uint8_t stat
     return result;
 }
 
-static OCStackResult CAResultToOCStackResult(CAResult_t caResult)
-{
-    OCStackResult ret = OC_STACK_ERROR;
-
-    switch(caResult)
-    {
-        case CA_ADAPTER_NOT_ENABLED:
-        case CA_SERVER_NOT_STARTED:
-            ret = OC_STACK_ADAPTER_NOT_ENABLED;
-            break;
-        case CA_MEMORY_ALLOC_FAILED:
-            ret = OC_STACK_NO_MEMORY;
-            break;
-        case CA_STATUS_INVALID_PARAM:
-            ret = OC_STACK_INVALID_PARAM;
-            break;
-        default:
-            break;
-    }
-    return ret;
-}
-
 OCStackResult CAResponseToOCStackResult(CAResponseResult_t caCode)
 {
     OCStackResult ret = OC_STACK_ERROR;
@@ -906,22 +868,9 @@ OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr)
     }
 }
 
-/**
- * Encode an address string to match RFC 6874.
- *
- * @param outputAddress    a char array to be written with the encoded string.
- *
- * @param outputSize       size of outputAddress buffer.
- *
- * @param inputAddress     a char array of size <= CA_MAX_URI_LENGTH
- *                         containing a valid IPv6 address string.
- *
- * @return                 OC_STACK_OK if encoding succeeded.
- *                         Else an error occured.
- */
- OCStackResult encodeAddressForRFC6874(char *outputAddress,
-                                       size_t outputSize,
-                                       const char *inputAddress)
+OCStackResult OCEncodeAddressForRFC6874(char *outputAddress,
+                                        size_t outputSize,
+                                        const char *inputAddress)
 {
     VERIFY_NON_NULL(inputAddress,  FATAL, OC_STACK_INVALID_PARAM);
     VERIFY_NON_NULL(outputAddress, FATAL, OC_STACK_INVALID_PARAM);
@@ -934,7 +883,7 @@ OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr)
     if (inputSize > outputSize)
     {
         OIC_LOG_V(ERROR, TAG,
-                  "encodeAddressForRFC6874 failed: "
+                  "OCEncodeAddressForRFC6874 failed: "
                   "outputSize (%zu) < inputSize (%zu)",
                   outputSize, inputSize);
 
@@ -962,21 +911,21 @@ OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr)
     // If no string follows the first '%', then the input was invalid.
     if (scopeIdPart[0] == '\0')
     {
-        OIC_LOG(ERROR, TAG, "encodeAddressForRFC6874 failed: Invalid input string: no scope ID!");
+        OIC_LOG(ERROR, TAG, "OCEncodeAddressForRFC6874 failed: Invalid input string: no scope ID!");
         return OC_STACK_ERROR;
     }
 
     // Check to see if the string is already encoded
     if ((scopeIdPart[0] == '2') && (scopeIdPart[1] == '5'))
     {
-        OIC_LOG(ERROR, TAG, "encodeAddressForRFC6874 failed: Input string is already encoded");
+        OIC_LOG(ERROR, TAG, "OCEncodeAddressForRFC6874 failed: Input string is already encoded");
         return OC_STACK_ERROR;
     }
 
     // Fail if we don't have room for encoded string's two additional chars
     if (outputSize < (inputSize + 2))
     {
-        OIC_LOG(ERROR, TAG, "encodeAddressForRFC6874 failed: encoded output will not fit!");
+        OIC_LOG(ERROR, TAG, "OCEncodeAddressForRFC6874 failed: encoded output will not fit!");
         return OC_STACK_ERROR;
     }
 
@@ -988,6 +937,41 @@ OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr)
     return OC_STACK_OK;
 }
 
+OCStackResult OCDecodeAddressForRFC6874(char *outputAddress,
+                                        size_t outputSize,
+                                        const char *inputAddress,
+                                        const char *end)
+{
+    VERIFY_NON_NULL(inputAddress,  FATAL, OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL(outputAddress, FATAL, OC_STACK_INVALID_PARAM);
+
+    if (NULL == end)
+    {
+        end = inputAddress + strlen(inputAddress);
+    }
+    size_t inputLength = end - inputAddress;
+
+    const char *percent = strchr(inputAddress, '%');
+    if (!percent || (percent > end))
+    {
+        OICStrcpyPartial(outputAddress, outputSize, inputAddress, inputLength);
+    }
+    else
+    {
+        if (percent[1] != '2' || percent[2] != '5')
+        {
+            return OC_STACK_INVALID_URI;
+        }
+
+        int addrlen = percent - inputAddress + 1;
+        OICStrcpyPartial(outputAddress, outputSize, inputAddress, addrlen);
+        OICStrcpyPartial(outputAddress + addrlen, outputSize - addrlen,
+                         percent + 3, end - percent - 3);
+    }
+
+    return OC_STACK_OK;
+}
+
 /**
  * The cononical presence allows constructed URIs to be string compared.
  *
@@ -1018,9 +1002,9 @@ static int FormCanonicalPresenceUri(const CAEndpoint_t *endpoint,
             {
                 char addressEncoded[CA_MAX_URI_LENGTH] = {0};
 
-                OCStackResult result = encodeAddressForRFC6874(addressEncoded,
-                                                               sizeof(addressEncoded),
-                                                               ep->addr);
+                OCStackResult result = OCEncodeAddressForRFC6874(addressEncoded,
+                                                                 sizeof(addressEncoded),
+                                                                 ep->addr);
 
                 if (OC_STACK_OK != result)
                 {
@@ -1311,12 +1295,13 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp
 #endif
                     else if (strcmp(cbNode->requestUri, OC_RSRVD_DEVICE_URI) == 0)
                     {
-                        type = PAYLOAD_TYPE_DEVICE;
+                        type = PAYLOAD_TYPE_REPRESENTATION;
                     }
                     else if (strcmp(cbNode->requestUri, OC_RSRVD_PLATFORM_URI) == 0)
                     {
-                        type = PAYLOAD_TYPE_PLATFORM;
+                        type = PAYLOAD_TYPE_REPRESENTATION;
                     }
+
 #ifdef ROUTING_GATEWAY
                     else if (strcmp(cbNode->requestUri, OC_RSRVD_GATEWAY_URI) == 0)
                     {
@@ -1325,7 +1310,7 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp
 #endif
                     else if (strcmp(cbNode->requestUri, OC_RSRVD_RD_URI) == 0)
                     {
-                        type = PAYLOAD_TYPE_REPRESENTATION ;
+                        type = PAYLOAD_TYPE_REPRESENTATION;
                     }
 #ifdef TCP_ADAPTER
                     else if (strcmp(cbNode->requestUri, KEEPALIVE_RESOURCE_URI) == 0)
@@ -1349,13 +1334,13 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp
                 {
                     if (cbNode->requestUri)
                     {
-                        if (strcmp(OC_RSRVD_PLATFORM_URI, cbNode->requestUri) == 0)
+                        if (0 == strcmp(OC_RSRVD_PLATFORM_URI, cbNode->requestUri))
                         {
-                            type = PAYLOAD_TYPE_PLATFORM;
+                            type = PAYLOAD_TYPE_REPRESENTATION;
                         }
-                        else if (strcmp(OC_RSRVD_DEVICE_URI, cbNode->requestUri) == 0)
+                        else if (0 == strcmp(OC_RSRVD_DEVICE_URI, cbNode->requestUri))
                         {
-                            type = PAYLOAD_TYPE_DEVICE;
+                            type = PAYLOAD_TYPE_REPRESENTATION;
                         }
                         if (type == PAYLOAD_TYPE_INVALID)
                         {
@@ -1587,19 +1572,10 @@ void HandleCAResponses(const CAEndpoint_t* endPoint, const CAResponseInfo_t* res
  */
 void HandleCAErrorResponse(const CAEndpoint_t *endPoint, const CAErrorInfo_t *errorInfo)
 {
-    OIC_LOG(INFO, TAG, "Enter HandleCAErrorResponse");
-
-    if (NULL == endPoint)
-    {
-        OIC_LOG(ERROR, TAG, "endPoint is NULL");
-        return;
-    }
+    VERIFY_NON_NULL_NR(endPoint, FATAL);
+    VERIFY_NON_NULL_NR(errorInfo, FATAL);
 
-    if (NULL == errorInfo)
-    {
-        OIC_LOG(ERROR, TAG, "errorInfo is NULL");
-        return;
-    }
+    OIC_LOG(INFO, TAG, "Enter HandleCAErrorResponse");
 
     ClientCB *cbNode = GetClientCB(errorInfo->info.token,
                                    errorInfo->info.tokenLength, NULL, NULL);
@@ -1612,11 +1588,24 @@ void HandleCAErrorResponse(const CAEndpoint_t *endPoint, const CAErrorInfo_t *er
         memcpy(response.identity.id, errorInfo->info.identity.id,
                sizeof (response.identity.id));
         response.identity.id_length = errorInfo->info.identity.id_length;
-        response.result = CAResultToOCStackResult(errorInfo->result);
+        response.result = CAResultToOCResult(errorInfo->result);
 
         cbNode->callBack(cbNode->context, cbNode->handle, &response);
     }
 
+    ResourceObserver *observer = GetObserverUsingToken(errorInfo->info.token,
+                                                       errorInfo->info.tokenLength);
+    if (observer)
+    {
+        OIC_LOG(INFO, TAG, "Receiving communication error for an observer");
+        OCStackResult result = CAResultToOCResult(errorInfo->result);
+        if (OC_STACK_COMM_ERROR == result)
+        {
+            OCStackFeedBack(errorInfo->info.token, errorInfo->info.tokenLength,
+                            OC_OBSERVER_FAILED_COMM);
+        }
+    }
+
     OIC_LOG(INFO, TAG, "Exit HandleCAErrorResponse");
 }
 
@@ -1662,6 +1651,8 @@ OCStackResult SendDirectStackResponse(const CAEndpoint_t* endPoint, const uint16
     if(OC_STACK_OK != result)
     {
         OIC_LOG_V(ERROR, TAG, "Add routing option failed [%d]", result);
+        OICFree (respInfo.info.resourceUri);
+        OICFree (respInfo.info.options);
         return result;
     }
     if (doPost)
@@ -1686,6 +1677,9 @@ OCStackResult SendDirectStackResponse(const CAEndpoint_t* endPoint, const uint16
             if (NULL == reqInfo.info.options)
             {
                 OIC_LOG(ERROR, TAG, "Calloc failed");
+                OICFree (reqInfo.info.resourceUri);
+                OICFree (respInfo.info.resourceUri);
+                OICFree (respInfo.info.options);
                 return OC_STACK_NO_MEMORY;
             }
             memcpy (reqInfo.info.options, respInfo.info.options,
@@ -2071,42 +2065,6 @@ void HandleCARequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* reque
     OIC_LOG(INFO, TAG, "Exit HandleCARequests");
 }
 
-bool validatePlatformInfo(OCPlatformInfo info)
-{
-
-    if (!info.platformID)
-    {
-        OIC_LOG(ERROR, TAG, "No platform ID found.");
-        return false;
-    }
-
-    if (info.manufacturerName)
-    {
-        size_t lenManufacturerName = strlen(info.manufacturerName);
-
-        if(lenManufacturerName == 0 || lenManufacturerName > MAX_MANUFACTURER_NAME_LENGTH)
-        {
-            OIC_LOG(ERROR, TAG, "Manufacturer name fails length requirements.");
-            return false;
-        }
-    }
-    else
-    {
-        OIC_LOG(ERROR, TAG, "No manufacturer name present");
-        return false;
-    }
-
-    if (info.manufacturerUrl)
-    {
-        if(strlen(info.manufacturerUrl) > MAX_MANUFACTURER_URL_LENGTH)
-        {
-            OIC_LOG(ERROR, TAG, "Manufacturer url fails length requirements.");
-            return false;
-        }
-    }
-    return true;
-}
-
 //-----------------------------------------------------------------------------
 // Public APIs
 //-----------------------------------------------------------------------------
@@ -2320,8 +2278,6 @@ OCStackResult OCStop()
 
     // Free memory dynamically allocated for resources
     deleteAllResources();
-    DeleteDeviceInfo();
-    DeletePlatformInfo();
     CATerminate();
     TerminateScheduleResourceList();
     // Remove all observers
@@ -2533,7 +2489,15 @@ static OCStackResult ParseRequestUri(const char *fullUri,
         {
             return OC_STACK_NO_MEMORY;
         }
-        OICStrcpyPartial(da->addr, sizeof(da->addr), start, len);
+
+        // Decode address per RFC 6874.
+        result = OCDecodeAddressForRFC6874(da->addr, sizeof(da->addr), start, end);
+        if (result != OC_STACK_OK)
+        {
+             OICFree(*devAddr);
+             return result;
+        }
+
         da->port = port;
         da->adapter = adapter;
         da->flags = flags;
@@ -3216,55 +3180,6 @@ OCStackResult OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandler entityHandle
     return OC_STACK_OK;
 }
 
-OCStackResult OCSetPlatformInfo(OCPlatformInfo platformInfo)
-{
-    OIC_LOG(INFO, TAG, "Entering OCSetPlatformInfo");
-
-    if(myStackMode ==  OC_SERVER || myStackMode == OC_CLIENT_SERVER || myStackMode == OC_GATEWAY)
-    {
-        if (validatePlatformInfo(platformInfo))
-        {
-            return SavePlatformInfo(platformInfo);
-        }
-        else
-        {
-            return OC_STACK_INVALID_PARAM;
-        }
-    }
-    else
-    {
-        return OC_STACK_ERROR;
-    }
-}
-
-OCStackResult OCSetDeviceInfo(OCDeviceInfo deviceInfo)
-{
-    OIC_LOG(INFO, TAG, "Entering OCSetDeviceInfo");
-
-    if (!deviceInfo.deviceName || deviceInfo.deviceName[0] == '\0')
-    {
-        OIC_LOG(ERROR, TAG, "Null or empty device name.");
-        return OC_STACK_INVALID_PARAM;
-    }
-
-    if (deviceInfo.types)
-    {
-        OCStringLL *type =  deviceInfo.types;
-        OCResource *resource = findResource((OCResource *) deviceResource);
-        if (!resource)
-        {
-            return OC_STACK_INVALID_PARAM;
-        }
-
-        while (type)
-        {
-            OCBindResourceTypeToResource(deviceResource, type->value);
-            type = type->next;
-        }
-    }
-    return SaveDeviceInfo(deviceInfo);
-}
-
 OCStackResult OCCreateResource(OCResourceHandle *handle,
         const char *resourceTypeName,
         const char *resourceInterfaceName,
@@ -4115,7 +4030,7 @@ OCStackResult OCDoResponse(OCEntityHandlerResponse *ehResponse)
 
     // Normal response
     // Get pointer to request info
-    serverRequest = GetServerRequestUsingHandle((OCServerRequest *)ehResponse->requestHandle);
+    serverRequest = GetServerRequestUsingHandle(ehResponse->requestHandle);
     if(serverRequest)
     {
         // response handler in ocserverrequest.c. Usually HandleSingleResponse.
@@ -4413,6 +4328,7 @@ void deleteResourceElements(OCResource *resource)
     OICFree(resource->uri);
     deleteResourceType(resource->rsrcType);
     deleteResourceInterface(resource->rsrcInterface);
+    OCDeleteResourceAttributes(resource->rsrcAttributes);
 }
 
 void deleteResourceType(OCResourceType *resourceType)
@@ -4443,6 +4359,25 @@ void deleteResourceInterface(OCResourceInterface *resourceInterface)
     }
 }
 
+void OCDeleteResourceAttributes(OCAttribute *rsrcAttributes)
+{
+    OCAttribute *next = NULL;
+    for (OCAttribute *pointer = rsrcAttributes; pointer; pointer = next)
+    {
+        next = pointer->next;
+        if (pointer->attrName && 0 == strcmp(OC_RSRVD_DATA_MODEL_VERSION, pointer->attrName))
+        {
+            OCFreeOCStringLL((OCStringLL *)pointer->attrValue);
+        }
+        else
+        {
+            OICFree(pointer->attrValue);
+        }
+        OICFree(pointer->attrName);
+        OICFree(pointer);
+    }
+}
+
 void insertResourceType(OCResource *resource, OCResourceType *resourceType)
 {
     OCResourceType *pointer = NULL;
@@ -4721,13 +4656,13 @@ const char* OCGetServerInstanceIDString(void)
     static bool generated = false;
     static char sidStr[UUID_STRING_SIZE];
 
-    if(generated)
+    if (generated)
     {
         return sidStr;
     }
 
     const OicUuid_t *sid = OCGetServerInstanceID();
-    if(OCConvertUuidToString(sid->id, sidStr) != RAND_UUID_OK)
+    if (sid && OCConvertUuidToString(sid->id, sidStr) != RAND_UUID_OK)
     {
         OIC_LOG(FATAL, TAG, "Generate UUID String for Server Instance failed!");
         return NULL;
@@ -4889,7 +4824,7 @@ OCStackResult OCUpdateResourceInsWithResponse(const char *requestUri,
                 {
                     OCRepPayload *rdPayload = (OCRepPayload *) response->payload;
                     OCRepPayload **links = NULL;
-                    size_t dimensions[MAX_REP_ARRAY_DEPTH];
+                    size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
                     if (OCRepPayloadGetPropObjectArray(rdPayload, OC_RSRVD_LINKS,
                                                        &links, dimensions))
                     {