replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / stack / src / ocresource.c
index c511229..16579f8 100755 (executable)
 #include "oic_malloc.h"
 #include "oic_string.h"
 #include "logger.h"
-#include "cJSON.h"
 #include "ocpayload.h"
 #include "secureresourcemanager.h"
 #include "cacommon.h"
 #include "cainterface.h"
 #include "ocpayload.h"
-
+#include "oickeepaliveinternal.h"
+#include "platform_features.h"
+#include "payload_logging.h"
 #ifdef ROUTING_GATEWAY
 #include "routingmanager.h"
 #endif
 
-#ifdef RD_SERVER
-#include "rd_database.h"
-#endif
-
 /// Module Name
 #define TAG "OIC_RI_RESOURCE"
 
-#define VERIFY_SUCCESS(op, successCode) { if (op != successCode) \
+#define VERIFY_SUCCESS(op) { if (op != (OC_STACK_OK)) \
             {OIC_LOG_V(FATAL, TAG, "%s failed!!", #op); goto exit;} }
 
-#define VERIFY_NON_NULL(arg, logLevel, retVal) { if (!(arg)) { OIC_LOG((logLevel), \
-             TAG, #arg " is NULL"); return (retVal); } }
-
-#include "platform_features.h"
-
 extern OCResource *headResource;
-static OCPlatformInfo savedPlatformInfo = {0};
-static OCDeviceInfo savedDeviceInfo = {0};
 
 /**
  * Prepares a Payload for response.
@@ -118,7 +108,7 @@ static OCStackResult GetSecurePortInfo(OCDevAddr *endpoint, uint16_t *port)
 
 #ifdef TCP_ADAPTER
 /* This method will retrieve the tcp port */
-static OCStackResult GetTCPPortInfo(OCDevAddr *endpoint, uint16_t *port)
+static OCStackResult GetTCPPortInfo(OCDevAddr *endpoint, uint16_t *port, bool secured)
 {
     uint16_t p = 0;
 
@@ -126,11 +116,11 @@ static OCStackResult GetTCPPortInfo(OCDevAddr *endpoint, uint16_t *port)
     {
         if (endpoint->flags & OC_IP_USE_V4)
         {
-            p = caglobals.tcp.ipv4.port;
+            p = secured ? caglobals.tcp.ipv4s.port : caglobals.tcp.ipv4.port;
         }
         else if (endpoint->flags & OC_IP_USE_V6)
         {
-            p = caglobals.tcp.ipv6.port;
+            p = secured ? caglobals.tcp.ipv6s.port : caglobals.tcp.ipv6.port;
         }
     }
 
@@ -146,40 +136,54 @@ static OCStackResult GetTCPPortInfo(OCDevAddr *endpoint, uint16_t *port)
  * Resource and device filters in the SAME query are NOT validated
  * and resources will likely not clear filters.
  */
-static OCStackResult ExtractFiltersFromQuery(char *query, char **filterOne, char **filterTwo)
+OCStackResult ExtractFiltersFromQuery(const char *query, char **filterOne, char **filterTwo)
 {
-
+    if (!query)
+    {
+        OIC_LOG_V(ERROR, TAG, "Query is empty!");
+        return OC_STACK_INVALID_QUERY;
+    }
     char *key = NULL;
     char *value = NULL;
+    char *queryDup = NULL;
     char *restOfQuery = NULL;
+    char *keyValuePair = NULL;
     int numKeyValuePairsParsed = 0;
 
     *filterOne = NULL;
     *filterTwo = NULL;
 
-    OIC_LOG_V(INFO, TAG, "Extracting params from %s", query);
+    queryDup = OICStrdup(query);
+    if (NULL == queryDup)
+    {
+        OIC_LOG_V(ERROR, TAG, "Creating duplicate string failed!");
+        return OC_STACK_NO_MEMORY;
+    }
+
+    OIC_LOG_V(INFO, TAG, "Extracting params from %s", queryDup);
 
-    if (strnlen(query, MAX_QUERY_LENGTH) >= MAX_QUERY_LENGTH)
+    OCStackResult eCode = OC_STACK_INVALID_QUERY;
+    if (strnlen(queryDup, MAX_QUERY_LENGTH) >= MAX_QUERY_LENGTH)
     {
         OIC_LOG(ERROR, TAG, "Query exceeds maximum length.");
-        return OC_STACK_INVALID_QUERY;
+        goto exit;
     }
 
-    char *keyValuePair = strtok_r (query, OC_QUERY_SEPARATOR, &restOfQuery);
+    keyValuePair = strtok_r (queryDup, OC_QUERY_SEPARATOR, &restOfQuery);
 
     while(keyValuePair)
     {
         if (numKeyValuePairsParsed >= 2)
         {
             OIC_LOG(ERROR, TAG, "More than 2 queries params in URI.");
-            return OC_STACK_INVALID_QUERY;
+            goto exit;
         }
 
         key = strtok_r(keyValuePair, OC_KEY_VALUE_DELIMITER, &value);
 
         if (!key || !value)
         {
-            return OC_STACK_INVALID_QUERY;
+            goto exit;
         }
         else if (strncasecmp(key, OC_RSRVD_INTERFACE, sizeof(OC_RSRVD_INTERFACE) - 1) == 0)
         {
@@ -192,15 +196,45 @@ static OCStackResult ExtractFiltersFromQuery(char *query, char **filterOne, char
         else
         {
             OIC_LOG_V(ERROR, TAG, "Unsupported query key: %s", key);
-            return OC_STACK_INVALID_QUERY;
+            goto exit;
         }
         ++numKeyValuePairsParsed;
 
         keyValuePair = strtok_r(NULL, OC_QUERY_SEPARATOR, &restOfQuery);
     }
 
+    if (*filterOne)
+    {
+        *filterOne = OICStrdup(*filterOne);
+        if (NULL == *filterOne)
+        {
+            OIC_LOG_V(ERROR, TAG, "Creating duplicate string failed!");
+            eCode = OC_STACK_NO_MEMORY;
+            goto exit;
+        }
+    }
+
+    if (*filterTwo)
+    {
+        *filterTwo = OICStrdup(*filterTwo);
+        if (NULL == *filterTwo)
+        {
+            OIC_LOG_V(ERROR, TAG, "Creating duplicate string failed!");
+            OICFree(*filterOne);
+            eCode = OC_STACK_NO_MEMORY;
+            goto exit;
+        }
+    }
+
+    OICFree(queryDup);
     OIC_LOG_V(INFO, TAG, "Extracted params if: %s and rt: %s.", *filterOne, *filterTwo);
     return OC_STACK_OK;
+
+exit:
+    *filterOne = NULL;
+    *filterTwo = NULL;
+    OICFree(queryDup);
+    return eCode;
 }
 
 static OCVirtualResources GetTypeOfVirtualURI(const char *uriInRequest)
@@ -262,14 +296,14 @@ static OCStackResult getQueryParamsForFiltering (OCVirtualResources uri, char *q
     *filterOne = NULL;
     *filterTwo = NULL;
 
-    #ifdef WITH_PRESENCE
+#ifdef WITH_PRESENCE
     if (uri == OC_PRESENCE)
     {
         //Nothing needs to be done, except for pass a OC_PRESENCE query through as OC_STACK_OK.
         OIC_LOG(INFO, TAG, "OC_PRESENCE Request for virtual resource.");
         return OC_STACK_OK;
     }
-    #endif
+#endif
 
     OCStackResult result = OC_STACK_OK;
 
@@ -281,23 +315,57 @@ static OCStackResult getQueryParamsForFiltering (OCVirtualResources uri, char *q
     return result;
 }
 
-OCStackResult BuildResponseRepresentation(const OCResource *resourcePtr,
-                    OCRepPayload** payload)
+bool appendOCStringLL(OCRepPayload *device, OCStringLL *dmv)
 {
-    OCRepPayload *tempPayload = OCRepPayloadCreate();
+    int size = 0;
+    for (OCStringLL *ll = dmv; ll; ll = ll->next, size++);
+    size_t dim[MAX_REP_ARRAY_DEPTH] = {size, 0, 0};
+    char **dt = (char **)OICMalloc(sizeof(char *) * size);
+    int i = 0;
+    VERIFY_PARAM_NON_NULL(TAG, dt, "Data Model Version allocation failed.");
+    for (OCStringLL *ll = dmv; ll; ll = ll->next, i++)
+    {
+        dt[i] = OICStrdup(ll->value);
+        VERIFY_PARAM_NON_NULL(TAG, dt[i], "Data Model Version adding failed.");
+    }
+    if (!OCRepPayloadSetStringArrayAsOwner(device, OC_RSRVD_DATA_MODEL_VERSION, dt, dim))
+    {
+        goto exit;
+    }
+    return true;
 
+exit:
+    for (int i = 0; i < size; i++)
+    {
+        OICFree(dt[i]);
+    }
+    OICFree(dt);
+    return false;
+}
+
+static OCStackResult BuildDevicePlatformPayload(const OCResource *resourcePtr, OCRepPayload** payload, bool addDeviceId)
+{
     if (!resourcePtr)
     {
-        OCRepPayloadDestroy(tempPayload);
         return OC_STACK_INVALID_PARAM;
     }
 
-    if(!tempPayload)
+    OCRepPayload *tempPayload = OCRepPayloadCreate();
+    if (!tempPayload)
     {
         return OC_STACK_NO_MEMORY;
     }
 
-    OCRepPayloadSetUri(tempPayload, resourcePtr->uri);
+    if (addDeviceId)
+    {
+        const char *deviceId = OCGetServerInstanceIDString();
+        if (!deviceId)
+        {
+            OIC_LOG(ERROR, TAG, "Failed retrieving device id.");
+            return OC_STACK_ERROR;
+        }
+        OCRepPayloadSetPropString(tempPayload, OC_RSRVD_DEVICE_ID, deviceId);
+    }
 
     OCResourceType *resType = resourcePtr->rsrcType;
     while(resType)
@@ -316,8 +384,22 @@ OCStackResult BuildResponseRepresentation(const OCResource *resourcePtr,
     OCAttribute *resAttrib = resourcePtr->rsrcAttributes;
     while(resAttrib)
     {
-        OCRepPayloadSetPropString(tempPayload, resAttrib->attrName,
-                                resAttrib->attrValue);
+        if (resAttrib->attrName && resAttrib->attrValue)
+        {
+            if (0 == strcmp(OC_RSRVD_DATA_MODEL_VERSION, resAttrib->attrName))
+            {
+                char *dmv = OCCreateString((OCStringLL *)resAttrib->attrValue);
+                if (dmv)
+                {
+                    OCRepPayloadSetPropString(tempPayload, resAttrib->attrName, dmv);
+                    OICFree(dmv);
+                }
+            }
+            else
+            {
+                OCRepPayloadSetPropString(tempPayload, resAttrib->attrName, (char *)resAttrib->attrValue);
+            }
+        }
         resAttrib = resAttrib->next;
     }
 
@@ -333,6 +415,117 @@ OCStackResult BuildResponseRepresentation(const OCResource *resourcePtr,
     return OC_STACK_OK;
 }
 
+OCStackResult BuildResponseRepresentation(const OCResource *resourcePtr,
+                    OCRepPayload** payload, OCDevAddr *devAddr)
+{
+    if (!resourcePtr)
+    {
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    OCRepPayload *tempPayload = OCRepPayloadCreate();
+    if(!tempPayload)
+    {
+        return OC_STACK_NO_MEMORY;
+    }
+
+    OCRepPayloadSetPropString(tempPayload, OC_RSRVD_HREF, resourcePtr->uri);
+
+    uint8_t numElement = 0;
+    if (OC_STACK_OK == OCGetNumberOfResourceTypes((OCResource *)resourcePtr, &numElement))
+    {
+        size_t rtDim[MAX_REP_ARRAY_DEPTH] = {numElement, 0, 0};
+        char **rt = (char **)OICMalloc(sizeof(char *) * numElement);
+        if (!rt)
+        {
+            OIC_LOG(ERROR, TAG, "Resource type allocation failed.");
+            OCRepPayloadDestroy(tempPayload);
+            return OC_STACK_NO_MEMORY;
+        }
+        for (uint8_t i = 0; i < numElement; ++i)
+        {
+            const char *value = OCGetResourceTypeName((OCResource *)resourcePtr, i);
+            OIC_LOG_V(DEBUG, TAG, "value: %s", value);
+            rt[i] = OICStrdup(value);
+        }
+        OCRepPayloadSetStringArrayAsOwner(tempPayload, OC_RSRVD_RESOURCE_TYPE, rt, rtDim);
+    }
+
+    numElement = 0;
+    if (OC_STACK_OK == OCGetNumberOfResourceInterfaces((OCResource *)resourcePtr, &numElement))
+    {
+        size_t ifDim[MAX_REP_ARRAY_DEPTH] = {numElement, 0, 0};
+        char **itf = (char **)OICMalloc(sizeof(char *) * numElement);
+        if (!itf)
+        {
+            OIC_LOG(ERROR, TAG, "Resource interface allocation failed.");
+            OCRepPayloadDestroy(tempPayload);
+            return OC_STACK_NO_MEMORY;
+        }
+        for (uint8_t i = 0; i < numElement; ++i)
+        {
+            const char *value = OCGetResourceInterfaceName((OCResource *)resourcePtr, i);
+            OIC_LOG_V(DEBUG, TAG, "value: %s", value);
+            itf[i] = OICStrdup(value);
+        }
+        OCRepPayloadSetStringArrayAsOwner(tempPayload, OC_RSRVD_INTERFACE, itf, ifDim);
+    }
+
+    for (OCAttribute *resAttrib = resourcePtr->rsrcAttributes; resAttrib; resAttrib = resAttrib->next)
+    {
+        if (resAttrib->attrName && resAttrib->attrValue)
+        {
+            if (0 == strcmp(OC_RSRVD_DATA_MODEL_VERSION, resAttrib->attrName))
+            {
+                char *dmv = OCCreateString((OCStringLL *)resAttrib->attrValue);
+                if (dmv)
+                {
+                    OCRepPayloadSetPropString(tempPayload, resAttrib->attrName, dmv);
+                    OICFree(dmv);
+                }
+            }
+            else
+            {
+                OCRepPayloadSetPropString(tempPayload, resAttrib->attrName, (char *)resAttrib->attrValue);
+            }
+        }
+    }
+
+    if (devAddr)
+    {
+        OCResourceProperty p = OCGetResourceProperties((OCResourceHandle *)resourcePtr);
+        OCRepPayload *policy = OCRepPayloadCreate();
+        if (!policy)
+        {
+            OCPayloadDestroy((OCPayload *)tempPayload);
+            return OC_STACK_NO_MEMORY;
+        }
+        OCRepPayloadSetPropInt(policy, OC_RSRVD_BITMAP, ((p & OC_DISCOVERABLE) | (p & OC_OBSERVABLE)));
+        if (p & OC_SECURE)
+        {
+            OCRepPayloadSetPropBool(policy, OC_RSRVD_SECURE, p & OC_SECURE);
+            uint16_t securePort = 0;
+            if (GetSecurePortInfo(devAddr, &securePort) != OC_STACK_OK)
+            {
+                securePort = 0;
+            }
+            OCRepPayloadSetPropInt(policy, OC_RSRVD_HOSTING_PORT, securePort);
+        }
+        OCRepPayloadSetPropObjectAsOwner(tempPayload, OC_RSRVD_POLICY, policy);
+    }
+
+    if (!*payload)
+    {
+        *payload = tempPayload;
+    }
+    else
+    {
+        OCRepPayloadAppend(*payload, tempPayload);
+    }
+
+    return OC_STACK_OK;
+}
+
 OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr,
                         OCDiscoveryPayload *payload, OCDevAddr *devAddr)
 {
@@ -351,10 +544,8 @@ OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr,
 
 #ifdef TCP_ADAPTER
     uint16_t tcpPort = 0;
-    if (GetTCPPortInfo(devAddr, &tcpPort) != OC_STACK_OK)
-    {
-        tcpPort = 0;
-    }
+    GetTCPPortInfo(devAddr, &tcpPort, (resourcePtr->resourceProperties & OC_SECURE));
+
     OCDiscoveryPayloadAddResource(payload, resourcePtr, securePort, tcpPort);
 #else
     OCDiscoveryPayloadAddResource(payload, resourcePtr, securePort);
@@ -363,21 +554,6 @@ OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr,
     return OC_STACK_OK;
 }
 
-uint8_t IsCollectionResource (OCResource *resource)
-{
-    if(!resource)
-    {
-        return 0;
-    }
-
-    if(resource->rsrcChildResourcesHead != NULL)
-    {
-        return 1;
-    }
-
-    return 0;
-}
-
 OCResource *FindResourceByUri(const char* resourceUri)
 {
     if(!resourceUri)
@@ -398,7 +574,6 @@ OCResource *FindResourceByUri(const char* resourceUri)
     return NULL;
 }
 
-
 OCStackResult DetermineResourceHandling (const OCServerRequest *request,
                                          ResourceHandling *handling,
                                          OCResource **resource)
@@ -442,7 +617,7 @@ OCStackResult DetermineResourceHandling (const OCServerRequest *request,
             return OC_STACK_NO_RESOURCE;
         }
 
-        if (IsCollectionResource (resourcePtr))
+        if (resourcePtr && resourcePtr->rsrcChildResourcesHead != NULL)
         {
             // Collection resource
             if (resourcePtr->entityHandler != defaultResourceEHandler)
@@ -493,9 +668,6 @@ OCStackResult EntityHandlerCodeToOCStackCode(OCEntityHandlerResult ehResult)
         case OC_EH_FORBIDDEN:
             result = OC_STACK_FORBIDDEN_REQ;
             break;
-        case OC_EH_INTERNAL_SERVER_ERROR:
-            result = OC_STACK_INTERNAL_SERVER_ERROR;
-            break;
         case OC_EH_RESOURCE_CREATED:
             result = OC_STACK_RESOURCE_CREATED;
             break;
@@ -508,6 +680,24 @@ OCStackResult EntityHandlerCodeToOCStackCode(OCEntityHandlerResult ehResult)
         case OC_EH_RESOURCE_NOT_FOUND:
             result = OC_STACK_NO_RESOURCE;
             break;
+        case OC_EH_INTERNAL_SERVER_ERROR:
+            result = OC_STACK_INTERNAL_SERVER_ERROR;
+            break;
+        case OC_EH_NOT_IMPLEMENTED:
+            result = OC_STACK_NOT_IMPLEMENTED;
+            break;
+        case OC_EH_BAD_GATEWAY:
+            result = OC_STACK_BAD_GATEWAY;
+            break;
+        case OC_EH_SERVICE_UNAVAILABLE:
+            result = OC_STACK_SERVICE_UNAVAILABLE;
+            break;
+        case OC_EH_RETRANSMIT_TIMEOUT:
+            result = OC_STACK_GATEWAY_TIMEOUT;
+            break;
+        case OC_EH_PROXY_NOT_SUPPORTED:
+            result = OC_STACK_PROXY_NOT_SUPPORTED;
+            break;
         default:
             result = OC_STACK_ERROR;
     }
@@ -522,21 +712,24 @@ static bool resourceMatchesRTFilter(OCResource *resource, char *resourceTypeFilt
         return false;
     }
 
-    // Null or empty is analogous to no filter.
-    if (resourceTypeFilter == NULL || *resourceTypeFilter == 0)
+    // Null is analogous to no filter.
+    if (NULL == resourceTypeFilter)
     {
         return true;
     }
 
-    OCResourceType *resourceTypePtr = resource->rsrcType;
+    // Empty resourceType filter is analogous to error query
+    if (0 == strlen(resourceTypeFilter))
+    {
+        return false;
+    }
 
-    while (resourceTypePtr)
+    for (OCResourceType *rtPtr = resource->rsrcType; rtPtr; rtPtr = rtPtr->next)
     {
-        if (strcmp (resourceTypePtr->resourcetypename, resourceTypeFilter) == 0)
+        if (0 == strcmp(rtPtr->resourcetypename, resourceTypeFilter))
         {
             return true;
         }
-        resourceTypePtr = resourceTypePtr->next;
     }
 
     OIC_LOG_V(INFO, TAG, "%s does not contain rt=%s.", resource->uri, resourceTypeFilter);
@@ -550,23 +743,26 @@ static bool resourceMatchesIFFilter(OCResource *resource, char *interfaceFilter)
         return false;
     }
 
-    // Null or empty is analogous to no filter.
-    if (interfaceFilter == NULL || *interfaceFilter == 0)
+    // Null is analogous to no filter.
+    if (NULL == interfaceFilter)
     {
         return true;
     }
 
-    OCResourceInterface *interfacePtr = resource->rsrcInterface;
+    // Empty interface filter is analogous to error query
+    if (0 == strlen(interfaceFilter))
+    {
+        return false;
+    }
 
-    while (interfacePtr)
+    for (OCResourceInterface *ifPtr = resource->rsrcInterface; ifPtr; ifPtr = ifPtr->next)
     {
-        if ((strcmp (interfacePtr->name, interfaceFilter) == 0) &&
-            (strcmp (OC_RSRVD_INTERFACE_LL, interfaceFilter) == 0 ||
-             strcmp (OC_RSRVD_INTERFACE_DEFAULT, interfaceFilter) == 0))
+        if (0 == strcmp(ifPtr->name, interfaceFilter) ||
+            0 == strcmp(OC_RSRVD_INTERFACE_LL, interfaceFilter) ||
+            0 == strcmp(OC_RSRVD_INTERFACE_DEFAULT, interfaceFilter))
         {
             return true;
         }
-        interfacePtr = interfacePtr->next;
     }
 
     OIC_LOG_V(INFO, TAG, "%s does not contain if=%s.", resource->uri, interfaceFilter);
@@ -596,12 +792,12 @@ static bool includeThisResourceInResponse(OCResource *resource,
          */
         if (!(resourceTypeFilter && *resourceTypeFilter))
         {
-            OIC_LOG_V(INFO, TAG, "%s no query string for EXPLICIT_DISCOVERABLE \
+            OIC_LOG_V(INFO, TAG, "%s no query string for EXPLICIT_DISCOVERABLE\
                 resource", resource->uri);
             return false;
         }
     }
-    else if ( !(resource->resourceProperties & OC_ACTIVE) ||
+    else if (!(resource->resourceProperties & OC_ACTIVE) ||
          !(resource->resourceProperties & OC_DISCOVERABLE))
     {
         OIC_LOG_V(INFO, TAG, "%s not ACTIVE or DISCOVERABLE", resource->uri);
@@ -610,7 +806,6 @@ static bool includeThisResourceInResponse(OCResource *resource,
 
     return resourceMatchesIFFilter(resource, interfaceFilter) &&
            resourceMatchesRTFilter(resource, resourceTypeFilter);
-
 }
 
 OCStackResult SendNonPersistantDiscoveryResponse(OCServerRequest *request, OCResource *resource,
@@ -621,12 +816,138 @@ OCStackResult SendNonPersistantDiscoveryResponse(OCServerRequest *request, OCRes
     response.ehResult = ehResult;
     response.payload = discoveryPayload;
     response.persistentBufferFlag = 0;
-    response.requestHandle = (OCRequestHandle) request;
+    response.requestHandle = (OCRequestHandle) request->requestId;
     response.resourceHandle = (OCResourceHandle) resource;
 
     return OCDoResponse(&response);
 }
 
+static OCStackResult EHRequest(OCEntityHandlerRequest *ehRequest, OCPayloadType type,
+    OCServerRequest *request, OCResource *resource)
+{
+    return FormOCEntityHandlerRequest(ehRequest,
+                                     (OCRequestHandle)request->requestId,
+                                     request->method,
+                                     &request->devAddr,
+                                     (OCResourceHandle)resource,
+                                     request->query,
+                                     type,
+                                     request->payload,
+                                     request->payloadSize,
+                                     request->numRcvdVendorSpecificHeaderOptions,
+                                     request->rcvdVendorSpecificHeaderOptions,
+                                     (OCObserveAction)request->observationOption,
+                                     (OCObservationId)0,
+                                     request->coapID);
+}
+
+#ifdef RD_SERVER
+/**
+ * Find resource at the resource directory server. This resource is not local resource but a
+ * remote resource.
+ *
+ * @param resource The resource to check the matching resource URI.
+ * @param interfaceQuery The interface query parameter.
+ * @param resourceTypeQuery The resourceType query parameter.
+ * @param discPayload The payload that will be added with the resource information if found at RD.
+ *
+ * @return ::OC_STACK_OK if the resource is found else ::OC_STACK_NO_RESOURCE.
+ * In case if build is not with flag RD_SERVER, it returns ::OC_STACK_NO_RESOURCE.
+ */
+static OCStackResult findResourceAtRD(const OCResource* resource, const char *interfaceQuery,
+    const char *resourceTypeQuery, OCDiscoveryPayload *discPayload)
+{
+    if (strcmp(resource->uri, OC_RSRVD_RD_URI) == 0)
+    {
+        if (OC_STACK_OK == OCRDDatabaseCheckResources(interfaceQuery, resourceTypeQuery, discPayload))
+        {
+            return OC_STACK_OK;
+        }
+    }
+
+    return OC_STACK_NO_RESOURCE;
+}
+#endif
+
+/**
+ * Creates a discovery payload and add device id information. This information is included in all
+ * /oic/res response.
+ *
+ * @param payload  payload that will have memory alllocated and device id information added.
+ *
+ * @return ::OC_STACK_OK if successful in allocating memory and adding ID information.
+ * ::OC_STACK_NO_MEMORY if failed allocating the memory.
+ */
+static OCStackResult discoveryPayloadCreateAndAddDeviceId(OCPayload **payload)
+{
+    if (*payload)
+    {
+        OIC_LOG(DEBUG, TAG, "Payload is already allocated");
+        return OC_STACK_OK;
+    }
+
+    *payload = (OCPayload *) OCDiscoveryPayloadCreate();
+    VERIFY_PARAM_NON_NULL(TAG, *payload, "Failed adding device id to discovery payload.");
+
+    {
+        OCDiscoveryPayload *discPayload = (OCDiscoveryPayload *)*payload;
+        discPayload->sid = (char *)OICCalloc(1, UUID_STRING_SIZE);
+        VERIFY_PARAM_NON_NULL(TAG, discPayload->sid, "Failed adding device id to discovery payload.");
+
+        const char* uid = OCGetServerInstanceIDString();
+        if (uid)
+        {
+            memcpy(discPayload->sid, uid, UUID_STRING_SIZE);
+        }
+
+    }
+    return OC_STACK_OK;
+exit:
+    OCPayloadDestroy(*payload);
+    return OC_STACK_NO_MEMORY;
+}
+
+/**
+ * Add the common properties to the payload, they are only included in case of oic.if.baseline response.
+ *
+ * @param discPayload payload that will have the baseline information included.
+ *
+ * @return ::OC_STACK_OK if successful in adding all the information. ::OC_STACK_NO_MEMORY if failed
+ * allocating the memory for the baseline information.
+ */
+static OCStackResult addDiscoveryBaselineCommonProperties(OCDiscoveryPayload *discPayload)
+{
+    if (!discPayload)
+    {
+        OIC_LOG(ERROR, TAG, "Payload is not allocated");
+        return OC_STACK_ERROR;
+    }
+
+    OCGetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DEVICE_NAME, (void **)&discPayload->name);
+
+    discPayload->type = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
+    VERIFY_PARAM_NON_NULL(TAG, discPayload->type, "Failed adding rt to discovery payload.");
+    discPayload->type->value = OICStrdup(OC_RSRVD_RESOURCE_TYPE_RES);
+    VERIFY_PARAM_NON_NULL(TAG, discPayload->type, "Failed adding rt value to discovery payload.");
+
+    OCResourcePayloadAddStringLL(&discPayload->iface, OC_RSRVD_INTERFACE_LL);
+    OCResourcePayloadAddStringLL(&discPayload->iface, OC_RSRVD_INTERFACE_DEFAULT);
+    VERIFY_PARAM_NON_NULL(TAG, discPayload->iface, "Failed adding if to discovery payload.");
+
+    return OC_STACK_OK;
+
+exit:
+    return OC_STACK_NO_MEMORY;
+}
+
+static bool isUnicast(OCServerRequest *request)
+{
+    bool isMulticast = request->devAddr.flags &  OC_MULTICAST;
+    return (isMulticast == false &&
+           (request->devAddr.adapter != OC_ADAPTER_RFCOMM_BTEDR) &&
+           (request->devAddr.adapter != OC_ADAPTER_GATT_BTLE));
+}
+
 static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource* resource)
 {
     if (!request || !resource)
@@ -634,13 +955,32 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource
         return OC_STACK_INVALID_PARAM;
     }
 
-    OCStackResult discoveryResult = OC_STACK_ERROR;
     OCPayload* payload = NULL;
+    char *interfaceQuery = NULL;
+    char *resourceTypeQuery = NULL;
 
     OIC_LOG(INFO, TAG, "Entering HandleVirtualResource");
 
     OCVirtualResources virtualUriInRequest = GetTypeOfVirtualURI (request->resourceUrl);
 
+#ifdef TCP_ADAPTER
+    if (OC_KEEPALIVE_RESOURCE_URI == virtualUriInRequest)
+    {
+        // Received request for a keepalive
+        OIC_LOG(INFO, TAG, "Request is for KeepAlive Request");
+        return OCHandleKeepAliveRequest(request, resource);
+    }
+#endif
+
+    OCStackResult discoveryResult = OC_STACK_ERROR;
+    if (request->method == OC_REST_PUT || request->method == OC_REST_POST ||
+        request->method == OC_REST_DELETE)
+    {
+        OIC_LOG_V(ERROR, TAG, "Resource : %s not permitted for method: %d",
+            request->resourceUrl, request->method);
+        return OC_STACK_UNAUTHORIZED_REQ;
+    }
+
     // Step 1: Generate the response to discovery request
     if (virtualUriInRequest == OC_WELL_KNOWN_URI
 #ifdef MQ_BROKER
@@ -648,184 +988,68 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource
 #endif
             )
     {
-        if (request->method == OC_REST_PUT || request->method == OC_REST_POST || request->method == OC_REST_DELETE)
-        {
-            OIC_LOG_V(ERROR, TAG, "Resource : %s not permitted for method: %d", request->resourceUrl, request->method);
-            return OC_STACK_UNAUTHORIZED_REQ;
-        }
-
-        char *interfaceQuery = NULL;
-        char *resourceTypeQuery = NULL;
-
-        discoveryResult = getQueryParamsForFiltering (virtualUriInRequest, request->query,
+        discoveryResult = getQueryParamsForFiltering(virtualUriInRequest, request->query,
                 &interfaceQuery, &resourceTypeQuery);
-        bool interfaceQueryAllocated = false;
+        VERIFY_SUCCESS(discoveryResult);
+
         if (!interfaceQuery && !resourceTypeQuery)
         {
-            interfaceQueryAllocated = true;
+            // If no query is sent, default interface is used i.e. oic.if.ll.
             interfaceQuery = OICStrdup(OC_RSRVD_INTERFACE_LL);
         }
 
-        if (discoveryResult == OC_STACK_OK)
-        {
-            payload = (OCPayload *)OCDiscoveryPayloadCreate();
-
-            if (payload)
-            {
-                OCDiscoveryPayload *discPayload = (OCDiscoveryPayload *)payload;
-                bool foundResourceAtRD = false;
+        discoveryResult = discoveryPayloadCreateAndAddDeviceId(&payload);
+        VERIFY_PARAM_NON_NULL(TAG, payload, "Failed creating Discovery Payload.");
+        VERIFY_SUCCESS(discoveryResult);
 
-                if (!resourceTypeQuery && interfaceQuery && (0 == strcmp(interfaceQuery, OC_RSRVD_INTERFACE_LL)))
-                {
-                    OCResourceProperty prop = OC_DISCOVERABLE;
+        OCDiscoveryPayload *discPayload = (OCDiscoveryPayload *)payload;
+        if (interfaceQuery && 0 == strcmp(interfaceQuery, OC_RSRVD_INTERFACE_DEFAULT))
+        {
+            discoveryResult = addDiscoveryBaselineCommonProperties(discPayload);
+            VERIFY_SUCCESS(discoveryResult);
+        }
+        OCResourceProperty prop = OC_DISCOVERABLE;
 #ifdef MQ_BROKER
-                    if (OC_MQ_BROKER_URI == virtualUriInRequest)
-                    {
-                        prop = OC_MQ_BROKER;
-                    }
-#endif
-
-                    for (; resource && discoveryResult == OC_STACK_OK; resource = resource->next)
-                    {
-                        foundResourceAtRD = false;
-#ifdef RD_SERVER
-                        if (strcmp(resource->uri, OC_RSRVD_RD_URI) == 0)
-                        {
-                            if (OC_STACK_OK == OCRDDatabaseCheckResources(interfaceQuery, resourceTypeQuery, discPayload))
-                            {
-                                foundResourceAtRD = true;
-                                discoveryResult = OC_STACK_OK;
-                            }
-                        }
+        prop = (OC_MQ_BROKER_URI == virtualUriInRequest) ? OC_MQ_BROKER : prop;
 #endif
-                        if (!foundResourceAtRD && (resource->resourceProperties & prop))
-                        {
-                            discoveryResult = BuildVirtualResourceResponse(resource, discPayload, &request->devAddr);
-                        }
-                    }
-                }
-                else
-                {
-                    if (interfaceQuery && (0 != strcmp(interfaceQuery, OC_RSRVD_INTERFACE_LL)))
-                    {
-                        discPayload->uri = OICStrdup(OC_RSRVD_WELL_KNOWN_URI);
-                        VERIFY_NON_NULL(discPayload->uri, ERROR, OC_STACK_NO_MEMORY);
-                        if (savedDeviceInfo.deviceName)
-                        {
-                            discPayload->name = OICStrdup(savedDeviceInfo.deviceName);
-                            VERIFY_NON_NULL(discPayload->name, ERROR, OC_STACK_NO_MEMORY);
-                        }
-                        discPayload->type = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
-                        VERIFY_NON_NULL(discPayload->type, ERROR, OC_STACK_NO_MEMORY);
-                        discPayload->type->value = OICStrdup(OC_RSRVD_RESOURCE_TYPE_RES);
-                        VERIFY_NON_NULL(discPayload->type->value, ERROR, OC_STACK_NO_MEMORY);
-                        OCResourcePayloadAddStringLL(&discPayload->iface, OC_RSRVD_INTERFACE_LL);
-                        OCResourcePayloadAddStringLL(&discPayload->iface, OC_RSRVD_INTERFACE_DEFAULT);
-                        VERIFY_NON_NULL(discPayload->iface, ERROR, OC_STACK_NO_MEMORY);
-                    }
-                    for (;resource && discoveryResult == OC_STACK_OK; resource = resource->next)
-                    {
-#ifdef RD_SERVER
-                        if (strcmp(resource->uri, OC_RSRVD_RD_URI) == 0)
-                        {
-                            if (OC_STACK_OK == OCRDDatabaseCheckResources(interfaceQuery, resourceTypeQuery, discPayload))
-                            {
-                                foundResourceAtRD = true;
-                                discoveryResult = OC_STACK_OK;
-                            }
-                        }
-#endif
-                        if (!foundResourceAtRD && includeThisResourceInResponse(resource, interfaceQuery, resourceTypeQuery))
-                        {
-                            discoveryResult = BuildVirtualResourceResponse(resource, discPayload, &request->devAddr);
-                        }
-                    }
-                    // Set discoveryResult appropriately if no 'valid' resources are available
-                    if (discPayload->resources == NULL && !foundResourceAtRD)
-                    {
-                        discoveryResult = OC_STACK_NO_RESOURCE;
-                    }
-                }
-                if (discoveryResult == OC_STACK_OK && foundResourceAtRD == false)
+        for (; resource && discoveryResult == OC_STACK_OK; resource = resource->next)
+        {
+            // This case will handle when no resource type and it is oic.if.ll.
+            // Do not assume check if the query is ll
+            if (!resourceTypeQuery &&
+                (interfaceQuery && 0 == strcmp(interfaceQuery, OC_RSRVD_INTERFACE_LL)))
+            {
+                // Only include discoverable type
+                if (resource->resourceProperties & prop)
                 {
-                    discPayload->sid = (char *)OICCalloc(1, UUID_STRING_SIZE);
-                    VERIFY_NON_NULL(discPayload->sid, ERROR, OC_STACK_NO_MEMORY);
-
-                    const char* uid = OCGetServerInstanceIDString();
-                    if (uid)
-                    {
-                        memcpy(discPayload->sid, uid, UUID_STRING_SIZE);
-                    }
+                    discoveryResult = BuildVirtualResourceResponse(resource, discPayload, &request->devAddr);
                 }
             }
+            else if (includeThisResourceInResponse(resource, interfaceQuery, resourceTypeQuery))
+            {
+                discoveryResult = BuildVirtualResourceResponse(resource, discPayload, &request->devAddr);
+            }
             else
             {
-                discoveryResult = OC_STACK_NO_MEMORY;
+                discoveryResult = OC_STACK_OK;
             }
-
         }
-        else
+        if (discPayload->resources == NULL)
         {
-            OIC_LOG_V(ERROR, TAG, "Error (%d) parsing query.", discoveryResult);
-        }
-        if (interfaceQueryAllocated)
-        {
-            OICFree(interfaceQuery);
+            discoveryResult = OC_STACK_NO_RESOURCE;
         }
     }
     else if (virtualUriInRequest == OC_DEVICE_URI)
     {
-        if (request->method == OC_REST_PUT || request->method == OC_REST_POST || request->method == OC_REST_DELETE)
-        {
-            OIC_LOG_V(ERROR, TAG, "Resource : %s not permitted for method: %d", request->resourceUrl, request->method);
-            return OC_STACK_UNAUTHORIZED_REQ;
-        }
-
-        const char* deviceId = OCGetServerInstanceIDString();
-        if (!deviceId)
-        {
-            discoveryResult = OC_STACK_ERROR;
-        }
-        else
-        {
-            char *dataModelVersions = OCCreateString(savedDeviceInfo.dataModelVersions);
-            if (!dataModelVersions)
-            {
-                discoveryResult = OC_STACK_NO_MEMORY;
-            }
-            else
-            {
-                payload = (OCPayload*) OCDevicePayloadCreate(deviceId, savedDeviceInfo.deviceName,
-                    savedDeviceInfo.types, savedDeviceInfo.specVersion, dataModelVersions);
-                if (!payload)
-                {
-                     discoveryResult = OC_STACK_NO_MEMORY;
-                }
-                else
-                {
-                     discoveryResult = OC_STACK_OK;
-                }
-                OICFree(dataModelVersions);
-            }
-        }
+        OCResource *resourcePtr = FindResourceByUri(OC_RSRVD_DEVICE_URI);
+        VERIFY_PARAM_NON_NULL(TAG, resourcePtr, "Device URI not found.");
+        discoveryResult = BuildDevicePlatformPayload(resourcePtr, (OCRepPayload **)&payload, true);
     }
     else if (virtualUriInRequest == OC_PLATFORM_URI)
     {
-        if (request->method == OC_REST_PUT || request->method == OC_REST_POST || request->method == OC_REST_DELETE)
-        {
-            OIC_LOG_V(ERROR, TAG, "Resource : %s not permitted for method: %d", request->resourceUrl, request->method);
-            return OC_STACK_UNAUTHORIZED_REQ;
-        }
-
-        payload = (OCPayload*)OCPlatformPayloadCreate(&savedPlatformInfo);
-        if (!payload)
-        {
-            discoveryResult = OC_STACK_NO_MEMORY;
-        }
-        else
-        {
-            discoveryResult = OC_STACK_OK;
-        }
+        OCResource *resourcePtr = FindResourceByUri(OC_RSRVD_PLATFORM_URI);
+        VERIFY_PARAM_NON_NULL(TAG, resourcePtr, "Platform URI not found.");
+        discoveryResult = BuildDevicePlatformPayload(resourcePtr, (OCRepPayload **)&payload, false);
     }
 #ifdef ROUTING_GATEWAY
     else if (OC_GATEWAY_URI == virtualUriInRequest)
@@ -833,17 +1057,9 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource
         // Received request for a gateway
         OIC_LOG(INFO, TAG, "Request is for Gateway Virtual Request");
         discoveryResult = RMHandleGatewayRequest(request, resource);
-
-    }
-#endif
-#ifdef TCP_ADAPTER
-    else if (OC_KEEPALIVE_RESOURCE_URI == virtualUriInRequest)
-    {
-        // Received request for a keepalive
-        OIC_LOG(INFO, TAG, "Request is for KeepAlive Request");
-        discoveryResult = HandleKeepAliveRequest(request, resource);
     }
 #endif
+
     /**
      * Step 2: Send the discovery response
      *
@@ -882,26 +1098,23 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource
     if (OC_GATEWAY_URI != virtualUriInRequest)
 #endif
     {
-#if TCP_ADAPTER
-        // KeepAlive uses the HandleKeepAliveRequest to respond to the request.
-        if (OC_KEEPALIVE_RESOURCE_URI != virtualUriInRequest)
-#endif
+        OIC_LOG_PAYLOAD(DEBUG, payload);
+        if(discoveryResult == OC_STACK_OK)
         {
-            if(discoveryResult == OC_STACK_OK)
-            {
-                SendNonPersistantDiscoveryResponse(request, resource, payload, OC_EH_OK);
-            }
-            else if(((request->devAddr.flags &  OC_MULTICAST) == false) &&
-                (request->devAddr.adapter != OC_ADAPTER_RFCOMM_BTEDR) &&
-                (request->devAddr.adapter != OC_ADAPTER_GATT_BTLE))
+
+            SendNonPersistantDiscoveryResponse(request, resource, payload, OC_EH_OK);
+        }
+        else // Error handling
+        {
+            if (isUnicast(request))
             {
                 OIC_LOG_V(ERROR, TAG, "Sending a (%d) error to (%d) discovery request",
                     discoveryResult, virtualUriInRequest);
                 SendNonPersistantDiscoveryResponse(request, resource, NULL,
                     (discoveryResult == OC_STACK_NO_RESOURCE) ?
-                            OC_EH_RESOURCE_NOT_FOUND : OC_EH_ERROR);
+                        OC_EH_RESOURCE_NOT_FOUND : OC_EH_ERROR);
             }
-            else
+            else // Multicast
             {
                 // Ignoring the discovery request as per RFC 7252, Section #8.2
                 OIC_LOG(INFO, TAG, "Silently ignoring the request since no useful data to send.");
@@ -909,41 +1122,39 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource
                 // since it never remove and causes a big memory waste.
                 FindAndDeleteServerRequest(request);
             }
+            discoveryResult = OC_STACK_CONTINUE;
         }
     }
 
+exit:
+    if (interfaceQuery)
+    {
+        OICFree(interfaceQuery);
+    }
+
+    if (resourceTypeQuery)
+    {
+        OICFree(resourceTypeQuery);
+    }
     OCPayloadDestroy(payload);
 
-    return OC_STACK_OK;
+    // To ignore the message, OC_STACK_CONTINUE is sent
+    return discoveryResult;
 }
 
 static OCStackResult
-HandleDefaultDeviceEntityHandler (OCServerRequest *request)
+HandleDefaultDeviceEntityHandler(OCServerRequest *request)
 {
-    if(!request)
+    if (!request)
     {
         return OC_STACK_INVALID_PARAM;
     }
 
-    OCStackResult result = OC_STACK_OK;
     OCEntityHandlerResult ehResult = OC_EH_ERROR;
     OCEntityHandlerRequest ehRequest = {0};
-
     OIC_LOG(INFO, TAG, "Entering HandleResourceWithDefaultDeviceEntityHandler");
-    result = FormOCEntityHandlerRequest(&ehRequest,
-                                        (OCRequestHandle) request,
-                                        request->method,
-                                        &request->devAddr,
-                                        (OCResourceHandle) NULL, request->query,
-                                        PAYLOAD_TYPE_REPRESENTATION,
-                                        request->payload,
-                                        request->payloadSize,
-                                        request->numRcvdVendorSpecificHeaderOptions,
-                                        request->rcvdVendorSpecificHeaderOptions,
-                                        (OCObserveAction)request->observationOption,
-                                        (OCObservationId)0,
-                                        request->coapID);
-    VERIFY_SUCCESS(result, OC_STACK_OK);
+    OCStackResult result = EHRequest(&ehRequest, PAYLOAD_TYPE_REPRESENTATION, request, NULL);
+    VERIFY_SUCCESS(result);
 
     // At this point we know for sure that defaultDeviceHandler exists
     ehResult = defaultDeviceHandler(OC_REQUEST_FLAG, &ehRequest,
@@ -964,9 +1175,8 @@ exit:
 }
 
 static OCStackResult
-HandleResourceWithEntityHandler (OCServerRequest *request,
-                                 OCResource *resource,
-                                 uint8_t collectionResource)
+HandleResourceWithEntityHandler(OCServerRequest *request,
+                                OCResource *resource)
 {
     if(!request || ! resource)
     {
@@ -986,24 +1196,10 @@ HandleResourceWithEntityHandler (OCServerRequest *request,
     if (request && request->resourceUrl && SRMIsSecurityResourceURI(request->resourceUrl))
     {
         type = PAYLOAD_TYPE_SECURITY;
-
     }
 
-    result = FormOCEntityHandlerRequest(&ehRequest,
-                                        (OCRequestHandle)request,
-                                        request->method,
-                                        &request->devAddr,
-                                        (OCResourceHandle)resource,
-                                        request->query,
-                                        type,
-                                        request->payload,
-                                        request->payloadSize,
-                                        request->numRcvdVendorSpecificHeaderOptions,
-                                        request->rcvdVendorSpecificHeaderOptions,
-                                        (OCObserveAction)request->observationOption,
-                                        0,
-                                        request->coapID);
-    VERIFY_SUCCESS(result, OC_STACK_OK);
+    result = EHRequest(&ehRequest, type, request, resource);
+    VERIFY_SUCCESS(result);
 
     if(ehRequest.obsInfo.action == OC_OBSERVE_NO_OPTION)
     {
@@ -1033,7 +1229,7 @@ HandleResourceWithEntityHandler (OCServerRequest *request,
         }
 
         result = GenerateObserverId(&ehRequest.obsInfo.obsId);
-        VERIFY_SUCCESS(result, OC_STACK_OK);
+        VERIFY_SUCCESS(result);
 
         result = AddObserver ((const char*)(request->resourceUrl),
                 (const char *)(request->query),
@@ -1075,7 +1271,7 @@ HandleResourceWithEntityHandler (OCServerRequest *request,
         {
             // Stack does not contain this observation request
             // Either token is incorrect or observation list is corrupted
-            result = OC_STACK_ERROR;
+            result = OC_STACK_NO_RESOURCE;
             goto exit;
         }
         ehRequest.obsInfo.obsId = resObs->observeId;
@@ -1121,32 +1317,16 @@ exit:
     return result;
 }
 
-static OCStackResult
-HandleCollectionResourceDefaultEntityHandler (OCServerRequest *request,
-                                              OCResource *resource)
+static OCStackResult HandleCollectionResourceDefaultEntityHandler(OCServerRequest *request,
+                                                                  OCResource *resource)
 {
-    if(!request || !resource)
+    if (!request || !resource)
     {
         return OC_STACK_INVALID_PARAM;
     }
 
-    OCStackResult result = OC_STACK_ERROR;
     OCEntityHandlerRequest ehRequest = {0};
-
-    result = FormOCEntityHandlerRequest(&ehRequest,
-                                        (OCRequestHandle)request,
-                                        request->method,
-                                        &request->devAddr,
-                                        (OCResourceHandle)resource,
-                                        request->query,
-                                        PAYLOAD_TYPE_REPRESENTATION,
-                                        request->payload,
-                                        request->payloadSize,
-                                        request->numRcvdVendorSpecificHeaderOptions,
-                                        request->rcvdVendorSpecificHeaderOptions,
-                                        (OCObserveAction)request->observationOption,
-                                        (OCObservationId)0,
-                                        request->coapID);
+    OCStackResult result = EHRequest(&ehRequest, PAYLOAD_TYPE_REPRESENTATION, request, resource);
     if(result == OC_STACK_OK)
     {
         result = DefaultCollectionEntityHandler (OC_REQUEST_FLAG, &ehRequest);
@@ -1180,12 +1360,12 @@ ProcessRequest(ResourceHandling resHandling, OCResource *resource, OCServerReque
         }
         case OC_RESOURCE_NOT_COLLECTION_WITH_ENTITYHANDLER:
         {
-            ret = HandleResourceWithEntityHandler (request, resource, 0);
+            ret = HandleResourceWithEntityHandler (request, resource);
             break;
         }
         case OC_RESOURCE_COLLECTION_WITH_ENTITYHANDLER:
         {
-            ret = HandleResourceWithEntityHandler (request, resource, 1);
+            ret = HandleResourceWithEntityHandler (request, resource);
             break;
         }
         case OC_RESOURCE_COLLECTION_DEFAULT_ENTITYHANDLER:
@@ -1207,224 +1387,242 @@ ProcessRequest(ResourceHandling resHandling, OCResource *resource, OCServerReque
     return ret;
 }
 
-void DeletePlatformInfo()
+OCStackResult OCSetPlatformInfo(OCPlatformInfo info)
 {
-    OIC_LOG(INFO, TAG, "Deleting platform info.");
-
-    OICFree(savedPlatformInfo.platformID);
-    savedPlatformInfo.platformID = NULL;
-
-    OICFree(savedPlatformInfo.manufacturerName);
-    savedPlatformInfo.manufacturerName = NULL;
-
-    OICFree(savedPlatformInfo.manufacturerUrl);
-    savedPlatformInfo.manufacturerUrl = NULL;
-
-    OICFree(savedPlatformInfo.modelNumber);
-    savedPlatformInfo.modelNumber = NULL;
-
-    OICFree(savedPlatformInfo.dateOfManufacture);
-    savedPlatformInfo.dateOfManufacture = NULL;
-
-    OICFree(savedPlatformInfo.platformVersion);
-    savedPlatformInfo.platformVersion = NULL;
-
-    OICFree(savedPlatformInfo.operatingSystemVersion);
-    savedPlatformInfo.operatingSystemVersion = NULL;
-
-    OICFree(savedPlatformInfo.hardwareVersion);
-    savedPlatformInfo.hardwareVersion = NULL;
-
-    OICFree(savedPlatformInfo.firmwareVersion);
-    savedPlatformInfo.firmwareVersion = NULL;
-
-    OICFree(savedPlatformInfo.supportUrl);
-    savedPlatformInfo.supportUrl = NULL;
-
-    OICFree(savedPlatformInfo.systemTime);
-    savedPlatformInfo.systemTime = NULL;
-}
-
-static OCStackResult DeepCopyPlatFormInfo(OCPlatformInfo info)
-{
-    savedPlatformInfo.platformID = OICStrdup(info.platformID);
-    savedPlatformInfo.manufacturerName = OICStrdup(info.manufacturerName);
-    savedPlatformInfo.manufacturerUrl = OICStrdup(info.manufacturerUrl);
-    savedPlatformInfo.modelNumber = OICStrdup(info.modelNumber);
-    savedPlatformInfo.dateOfManufacture = OICStrdup(info.dateOfManufacture);
-    savedPlatformInfo.platformVersion = OICStrdup(info.platformVersion);
-    savedPlatformInfo.operatingSystemVersion = OICStrdup(info.operatingSystemVersion);
-    savedPlatformInfo.hardwareVersion = OICStrdup(info.hardwareVersion);
-    savedPlatformInfo.firmwareVersion = OICStrdup(info.firmwareVersion);
-    savedPlatformInfo.supportUrl = OICStrdup(info.supportUrl);
-    savedPlatformInfo.systemTime = OICStrdup(info.systemTime);
-
-    if ((!savedPlatformInfo.platformID && info.platformID)||
-        (!savedPlatformInfo.manufacturerName && info.manufacturerName)||
-        (!savedPlatformInfo.manufacturerUrl && info.manufacturerUrl)||
-        (!savedPlatformInfo.modelNumber && info.modelNumber)||
-        (!savedPlatformInfo.dateOfManufacture && info.dateOfManufacture)||
-        (!savedPlatformInfo.platformVersion && info.platformVersion)||
-        (!savedPlatformInfo.operatingSystemVersion && info.operatingSystemVersion)||
-        (!savedPlatformInfo.hardwareVersion && info.hardwareVersion)||
-        (!savedPlatformInfo.firmwareVersion && info.firmwareVersion)||
-        (!savedPlatformInfo.supportUrl && info.supportUrl)||
-        (!savedPlatformInfo.systemTime && info.systemTime))
-    {
-        DeletePlatformInfo();
-        return OC_STACK_INVALID_PARAM;
+    OCResource *resource = NULL;
+    if (!info.platformID || !info.manufacturerName)
+    {
+        OIC_LOG(ERROR, TAG, "No value specified.");
+        goto exit;
+    }
+    if (0 == strlen(info.platformID) || 0 == strlen(info.manufacturerName))
+    {
+        OIC_LOG(ERROR, TAG, "The passed value cannot be empty");
+        goto exit;
+    }
+    if ((info.manufacturerName && strlen(info.manufacturerName) > MAX_PLATFORM_NAME_LENGTH) ||
+        (info.manufacturerUrl && strlen(info.manufacturerUrl) > MAX_PLATFORM_URL_LENGTH) ||
+        (info.modelNumber && strlen(info.modelNumber) > MAX_PLATFORM_NAME_LENGTH) ||
+        (info.platformVersion && strlen(info.platformVersion) > MAX_PLATFORM_NAME_LENGTH) ||
+        (info.operatingSystemVersion && strlen(info.operatingSystemVersion) > MAX_PLATFORM_NAME_LENGTH) ||
+        (info.hardwareVersion && strlen(info.hardwareVersion) > MAX_PLATFORM_NAME_LENGTH) ||
+        (info.firmwareVersion && strlen(info.firmwareVersion) > MAX_PLATFORM_NAME_LENGTH) ||
+        (info.supportUrl && strlen(info.supportUrl) > MAX_PLATFORM_URL_LENGTH))
+    {
+        OIC_LOG(ERROR, TAG, "The passed value is bigger than permitted.");
+        goto exit;
     }
 
+    resource = FindResourceByUri(OC_RSRVD_PLATFORM_URI);
+    if (!resource)
+    {
+        OIC_LOG(ERROR, TAG, "Platform Resource does not exist.");
+        goto exit;
+    }
+    OIC_LOG(INFO, TAG, "Entering OCSetPlatformInfo");
+    VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_PLATFORM_ID, info.platformID));
+    VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_MFG_NAME, info.manufacturerName));
+    OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_MFG_URL, info.manufacturerUrl);
+    OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_MODEL_NUM, info.modelNumber);
+    OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_MFG_DATE, info.dateOfManufacture);
+    OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_PLATFORM_VERSION, info.platformVersion);
+    OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_OS_VERSION, info.operatingSystemVersion);
+    OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_HARDWARE_VERSION, info.hardwareVersion);
+    OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_FIRMWARE_VERSION, info.firmwareVersion);
+    OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_SUPPORT_URL, info.supportUrl);
+    OCSetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_SYSTEM_TIME, info.systemTime);
+    OIC_LOG(INFO, TAG, "Platform parameter initialized successfully.");
     return OC_STACK_OK;
 
+exit:
+    return OC_STACK_INVALID_PARAM;
 }
 
-OCStackResult SavePlatformInfo(OCPlatformInfo info)
+OCStackResult OCSetDeviceInfo(OCDeviceInfo info)
 {
-    DeletePlatformInfo();
+    OCStringLL *dataModelVersion = NULL;
+    OCResource *resource = FindResourceByUri(OC_RSRVD_DEVICE_URI);
+    if (!resource)
+    {
+        OIC_LOG(ERROR, TAG, "Device Resource does not exist.");
+        goto exit;
+    }
+    if (!info.deviceName || info.deviceName[0] == '\0')
+    {
+        OIC_LOG(ERROR, TAG, "Null or empty device name.");
+       return OC_STACK_INVALID_PARAM;
+    }
 
-    OCStackResult res = DeepCopyPlatFormInfo(info);
+    if (OCGetServerInstanceIDString() == NULL)
+    {
+        OIC_LOG(INFO, TAG, "Device ID generation failed");
+        goto exit;
+    }
 
-    if (res != OC_STACK_OK)
+    VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DEVICE_NAME, info.deviceName));
+    for (OCStringLL *temp = info.types; temp; temp = temp->next)
+    {
+        if (temp->value)
+        {
+            VERIFY_SUCCESS(OCBindResourceTypeToResource(resource, temp->value));
+        }
+    }
+    VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_SPEC_VERSION, info.specVersion ?
+        info.specVersion: OC_SPEC_VERSION));
+    if (info.dataModelVersions)
     {
-        OIC_LOG_V(ERROR, TAG, "Failed to save platform info. errno(%d)", res);
+        VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DATA_MODEL_VERSION, info.dataModelVersions));
     }
     else
     {
-        OIC_LOG(INFO, TAG, "Platform info saved.");
+        dataModelVersion = OCCreateOCStringLL(OC_DATA_MODEL_VERSION);
+        VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DATA_MODEL_VERSION, dataModelVersion));
+#ifdef __TIZENRT__
+        OCFreeOCStringLL(dataModelVersion);
+#endif
     }
+    OIC_LOG(INFO, TAG, "Device parameter initialized successfully.");
+    return OC_STACK_OK;
 
-    return res;
-}
-
-void DeleteDeviceInfo()
-{
-    OIC_LOG(INFO, TAG, "Deleting device info.");
-
-    OICFree(savedDeviceInfo.deviceName);
-    OCFreeOCStringLL(savedDeviceInfo.types);
-    OICFree(savedDeviceInfo.specVersion);
-    OCFreeOCStringLL(savedDeviceInfo.dataModelVersions);
-    savedDeviceInfo.deviceName = NULL;
-    savedDeviceInfo.specVersion = NULL;
-    savedDeviceInfo.dataModelVersions = NULL;
+exit:
+    if (dataModelVersion)
+    {
+        OCFreeOCStringLL(dataModelVersion);
+    }
+    return OC_STACK_ERROR;
 }
 
-static OCStackResult DeepCopyDeviceInfo(OCDeviceInfo info)
+OCStackResult OCGetAttribute(const OCResource *resource, const char *attribute, void **value)
 {
-    savedDeviceInfo.deviceName = OICStrdup(info.deviceName);
-
-    if(!savedDeviceInfo.deviceName && info.deviceName)
+    if (!resource || !attribute)
     {
-        DeleteDeviceInfo();
-        return OC_STACK_NO_MEMORY;
+        return OC_STACK_INVALID_PARAM;
     }
-
-    if (info.types)
+    if (0 == strlen(attribute))
     {
-        savedDeviceInfo.types = CloneOCStringLL(info.types);
-        OCStringLL *type = info.types;
-        bool found = false;
-        while (type)
-        {
-            if (type && type->value && 0 == strcmp(type->value, OC_RSRVD_RESOURCE_TYPE_DEVICE))
-            {
-                found = true;
-            }
-            type = type->next;
-        }
-        if (!found)
+        return OC_STACK_INVALID_PARAM;
+    }
+    for (OCAttribute *temp = resource->rsrcAttributes; temp; temp = temp->next)
+    {
+        if (0 == strcmp(attribute, temp->attrName))
         {
-            // Append the oic.wk.d at the start of rt link parameter value.
-            OCStringLL *dest = (OCStringLL*)OICCalloc (1, sizeof (OCStringLL));
-            if (!dest)
+            // A special case as this type return OCStringLL
+            if (0 == strcmp(OC_RSRVD_DATA_MODEL_VERSION, attribute))
             {
-                DeleteDeviceInfo();
-                return OC_STACK_NO_MEMORY;
+                *value = CloneOCStringLL((OCStringLL *)temp->attrValue);
+                return OC_STACK_OK;
             }
-            dest->value = OICStrdup (OC_RSRVD_RESOURCE_TYPE_DEVICE);
-            if (!dest->value)
+            else
             {
-                DeleteDeviceInfo();
-                return OC_STACK_NO_MEMORY;
+                *value = OICStrdup((char *)temp->attrValue);
+                return OC_STACK_OK;
             }
-            dest->next = savedDeviceInfo.types;
-            savedDeviceInfo.types = dest;
-        }
-        if(!savedDeviceInfo.types && info.types)
-        {
-            DeleteDeviceInfo();
-            return OC_STACK_NO_MEMORY;
         }
     }
+    return OC_STACK_NO_RESOURCE;
+}
 
-    if (info.specVersion)
+OCStackResult OCGetPropertyValue(OCPayloadType type, const char *prop, void **value)
+{
+    if (!prop || *value)
     {
-        savedDeviceInfo.specVersion = OICStrdup(info.specVersion);
-        if(!savedDeviceInfo.specVersion && info.specVersion)
-        {
-            DeleteDeviceInfo();
-            return OC_STACK_NO_MEMORY;
-        }
+        return OC_STACK_INVALID_PARAM;
     }
-    else
+    if (strlen(prop) == 0)
     {
-        savedDeviceInfo.specVersion = OICStrdup(OC_SPEC_VERSION);
-        if(!savedDeviceInfo.specVersion && OC_SPEC_VERSION)
+        return OC_STACK_INVALID_PARAM;
+    }
+    OCStackResult res =  OC_STACK_NO_RESOURCE;
+    if (PAYLOAD_TYPE_DEVICE == type || PAYLOAD_TYPE_PLATFORM == type)
+    {
+        const char *pathType = (type == PAYLOAD_TYPE_DEVICE) ? OC_RSRVD_DEVICE_URI : OC_RSRVD_PLATFORM_URI;
+        OCResource *resource = FindResourceByUri(pathType);
+        if (!resource)
         {
-            DeleteDeviceInfo();
-            return OC_STACK_NO_MEMORY;
+            return OC_STACK_NO_RESOURCE;
         }
+
+        res = OCGetAttribute(resource, prop, value);
     }
+    return res;
+}
 
-    if (info.dataModelVersions)
+OCStackResult OCSetAttribute(OCResource* resource, const char* attribute, const void* value)
+{
+    // See if the attribute already exists in the list.
+    OCAttribute *resAttrib;
+    for (resAttrib = resource->rsrcAttributes; resAttrib; resAttrib = resAttrib->next)
     {
-        savedDeviceInfo.dataModelVersions = CloneOCStringLL(info.dataModelVersions);
-        if(!savedDeviceInfo.dataModelVersions && info.dataModelVersions)
+        if (0 == strcmp(attribute, resAttrib->attrName))
         {
-            DeleteDeviceInfo();
-            return OC_STACK_NO_MEMORY;
+            // Found, free the old value.
+            if (0 == strcmp(OC_RSRVD_DATA_MODEL_VERSION, resAttrib->attrName))
+            {
+                OCFreeOCStringLL((OCStringLL *)resAttrib->attrValue);
+            }
+            else
+            {
+                OICFree((char *)resAttrib->attrValue);
+            }
+            break;
         }
     }
+
+    // If not already in the list, add it.
+    if (NULL == resAttrib)
+    {
+        resAttrib = (OCAttribute *)OICCalloc(1, sizeof(OCAttribute));
+        VERIFY_PARAM_NON_NULL(TAG, resAttrib, "Failed allocating OCAttribute");
+        resAttrib->attrName = OICStrdup(attribute);
+        VERIFY_PARAM_NON_NULL(TAG, resAttrib->attrName, "Failed allocating attribute name");
+        resAttrib->next = resource->rsrcAttributes;
+        resource->rsrcAttributes = resAttrib;
+    }
+
+    // Fill in the new value.
+    if (0 == strcmp(OC_RSRVD_DATA_MODEL_VERSION, attribute))
+    {
+        resAttrib->attrValue = CloneOCStringLL((OCStringLL *)value);
+    }
     else
     {
-        savedDeviceInfo.dataModelVersions = (OCStringLL *)OICCalloc(1,sizeof(OCStringLL));
-        if (!savedDeviceInfo.dataModelVersions)
-        {
-            return OC_STACK_NO_MEMORY;
-        }
-        savedDeviceInfo.dataModelVersions->value = OICStrdup(OC_DATA_MODEL_VERSION);
-        if(!savedDeviceInfo.dataModelVersions->value && OC_DATA_MODEL_VERSION)
-        {
-            DeleteDeviceInfo();
-            return OC_STACK_NO_MEMORY;
-        }
+        resAttrib->attrValue = OICStrdup((char *)value);
     }
+    VERIFY_PARAM_NON_NULL(TAG, resAttrib->attrValue, "Failed allocating attribute value");
 
     return OC_STACK_OK;
-}
-
-OCStackResult SaveDeviceInfo(OCDeviceInfo info)
-{
-    OCStackResult res = OC_STACK_OK;
 
-    DeleteDeviceInfo();
-
-    res = DeepCopyDeviceInfo(info);
+exit:
+    OCDeleteResourceAttributes(resAttrib);
+    return OC_STACK_NO_MEMORY;
 
-    VERIFY_SUCCESS(res, OC_STACK_OK);
+}
 
-    if (OCGetServerInstanceIDString() == NULL)
+OCStackResult OCSetPropertyValue(OCPayloadType type, const char *prop, const void *value)
+{
+    if (!prop || !value)
     {
-        OIC_LOG(INFO, TAG, "Device ID generation failed");
-        res =  OC_STACK_ERROR;
-        goto exit;
+        return OC_STACK_INVALID_PARAM;
+    }
+    if (strlen(prop) == 0)
+    {
+        return OC_STACK_INVALID_PARAM;
     }
 
-    OIC_LOG(INFO, TAG, "Device initialized successfully.");
-    return OC_STACK_OK;
+    OCStackResult res = OC_STACK_ERROR;
+    if (PAYLOAD_TYPE_DEVICE == type || PAYLOAD_TYPE_PLATFORM == type)
+    {
+        const char *pathType = (type == PAYLOAD_TYPE_DEVICE) ? OC_RSRVD_DEVICE_URI : OC_RSRVD_PLATFORM_URI;
+        OCResource *resource = FindResourceByUri(pathType);
+        if (!resource)
+        {
+            OIC_LOG(ERROR, TAG, "Resource does not exist.");
+        }
+        else
+        {
+            res = OCSetAttribute(resource, prop, value);
+        }
+    }
 
-exit:
-    DeleteDeviceInfo();
     return res;
 }