Retrieve on /oic/res?rt=oic.d.xxx should return as per oic.if.ll
[platform/upstream/iotivity.git] / resource / csdk / stack / src / ocresource.c
old mode 100644 (file)
new mode 100755 (executable)
index 063e7da..5349740
 // For POSIX.1-2001 base specification,
 // Refer http://pubs.opengroup.org/onlinepubs/009695399/
 #define _POSIX_C_SOURCE 200112L
-#include "ocresource.h"
+
+#ifdef WITH_ARDUINO
 #include <string.h>
+#else
+#include <strings.h>
+#endif
+
+#include "ocresource.h"
 #include "ocresourcehandler.h"
 #include "ocobserve.h"
 #include "occollection.h"
 #include "oic_string.h"
 #include "logger.h"
 #include "cJSON.h"
-
+#include "ocpayload.h"
+#include "secureresourcemanager.h"
 #include "cacommon.h"
 #include "cainterface.h"
+#include "rdpayload.h"
+#include "ocpayload.h"
+
+#ifdef WITH_RD
+#include "rd_server.h"
+#endif
 
+#ifdef ROUTING_GATEWAY
+#include "routingmanager.h"
+#endif
 
 /// Module Name
-#define TAG PCF("ocresource")
+#define TAG "OIC_RI_RESOURCE"
+
 #define VERIFY_SUCCESS(op, successCode) { if (op != successCode) \
-            {OC_LOG_V(FATAL, TAG, "%s failed!!", #op); goto exit;} }
+            {OIC_LOG_V(FATAL, TAG, "%s failed!!", #op); goto exit;} }
 
-#define VERIFY_NON_NULL(arg, logLevel, retVal) { if (!(arg)) { OC_LOG((logLevel), \
-             TAG, PCF(#arg " is NULL")); return (retVal); } }
+#define VERIFY_NON_NULL(arg, logLevel, retVal) { if (!(arg)) { OIC_LOG((logLevel), \
+             TAG, #arg " is NULL"); return (retVal); } }
 
 extern OCResource *headResource;
-static OCPlatformInfo savedPlatformInfo = {};
-static OCDeviceInfo savedDeviceInfo = {};
+static OCPlatformInfo savedPlatformInfo = {0};
+static OCDeviceInfo savedDeviceInfo = {0};
 
-static const char * VIRTUAL_RSRCS[] =
-{
-    "/oic/res",
-    "/oic/d",
-    "/oic/p",
-    "/oic/res/types/d",
-    #ifdef WITH_PRESENCE
-    "/oic/ad"
-    #endif
-};
+/**
+ * Prepares a Payload for response.
+ */
+static OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr,
+                                                  OCDiscoveryPayload* payload,
+                                                  OCDevAddr *endpoint,
+                                                  bool rdResponse);
 
 //-----------------------------------------------------------------------------
 // Default resource entity handler function
@@ -77,178 +91,48 @@ OCEntityHandlerResult defaultResourceEHandler(OCEntityHandlerFlag flag,
 }
 
 /* This method will retrieve the port at which the secure resource is hosted */
-static OCStackResult GetSecurePortInfo(CATransportAdapter_t connType, uint16_t *port)
+static OCStackResult GetSecurePortInfo(OCDevAddr *endpoint, uint16_t *port)
 {
-    CAEndpoint_t* info = NULL;
-    uint32_t size = 0;
-    OCStackResult ret = OC_STACK_ERROR;
+    uint16_t p = 0;
 
-    CAResult_t caResult = CAGetNetworkInformation(&info, &size);
-    if ((caResult == CA_STATUS_OK) && info && size)
+    if (endpoint->adapter == OC_ADAPTER_IP)
     {
-        while (size--)
+        if (endpoint->flags & OC_IP_USE_V6)
         {
-            if ((info[size].flags & CA_SECURE) && info[size].adapter == connType)
-            {
-                if (info[size].adapter == CA_ADAPTER_IP)
-                {
-                    *port = info[size].port;
-                    ret = OC_STACK_OK;
-                    break;
-                }
-            }
+            p = caglobals.ip.u6s.port;
+        }
+        else if (endpoint->flags & OC_IP_USE_V4)
+        {
+            p = caglobals.ip.u4s.port;
         }
     }
 
-    OICFree(info);
-    return ret;
-}
-
-/*
- * Encodes platform info into json and returns a string on the heap.
- * Caller responsible for freeing the string.
- */
-static char* GetJSONStringFromPlatformInfo(OCPlatformInfo info)
-{
-    cJSON *rootObj = cJSON_CreateObject();
-
-    if (!rootObj)
-    {
-        return NULL;
-    }
-
-    cJSON *repObj = NULL;
-    char *jsonEncodedInfo = NULL;
-
-    cJSON_AddItemToObject (rootObj, OC_RSRVD_HREF,
-            cJSON_CreateString(GetVirtualResourceUri(OC_PLATFORM_URI)));
-
-    cJSON_AddItemToObject (rootObj, OC_RSRVD_REPRESENTATION, repObj = cJSON_CreateObject());
-
-    if (!repObj)
-    {
-        return NULL;
-    }
-    if (info.platformID)
-    {
-        cJSON_AddItemToObject (repObj, OC_RSRVD_PLATFORM_ID,
-                cJSON_CreateString(info.platformID));
-    }
-
-    if (info.manufacturerName)
-    {
-        cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_NAME,
-                cJSON_CreateString(info.manufacturerName));
-    }
-
-    if (info.manufacturerUrl)
-    {
-        cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_URL,
-                cJSON_CreateString(info.manufacturerUrl));
-    }
-
-    if (info.modelNumber)
-    {
-        cJSON_AddItemToObject (repObj, OC_RSRVD_MODEL_NUM,
-                cJSON_CreateString(info.modelNumber));
-    }
-
-    if (info.dateOfManufacture)
-    {
-        cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_DATE,
-                cJSON_CreateString(info.dateOfManufacture));
-    }
-
-    if (info.platformVersion)
-    {
-        cJSON_AddItemToObject (repObj, OC_RSRVD_PLATFORM_VERSION,
-                cJSON_CreateString(info.platformVersion));
-    }
-
-    if (info.operatingSystemVersion)
-    {
-        cJSON_AddItemToObject (repObj, OC_RSRVD_OS_VERSION,
-                cJSON_CreateString(info.operatingSystemVersion));
-    }
-
-    if (info.hardwareVersion)
-    {
-        cJSON_AddItemToObject (repObj, OC_RSRVD_HARDWARE_VERSION,
-                cJSON_CreateString(info.hardwareVersion));
-    }
-
-    if (info.firmwareVersion)
-    {
-        cJSON_AddItemToObject (repObj, OC_RSRVD_FIRMWARE_VERSION,
-                cJSON_CreateString(info.firmwareVersion));
-    }
-
-    if (info.supportUrl)
-    {
-        cJSON_AddItemToObject (repObj, OC_RSRVD_SUPPORT_URL,
-                cJSON_CreateString(info.supportUrl));
-    }
-
-    if (info.systemTime)
-    {
-        cJSON_AddItemToObject (repObj, OC_RSRVD_SYSTEM_TIME,
-                cJSON_CreateString(info.systemTime));
-    }
-
-    jsonEncodedInfo = cJSON_PrintUnformatted (rootObj);
-
-    cJSON_Delete(rootObj);
-
-    return jsonEncodedInfo;
+    *port = p;
+    return OC_STACK_OK;
 }
 
-/*
- * Encodes device info into json and returns a string on the heap.
- * Caller responsible for freeing the string.
- */
-static char* GetJSONStringFromDeviceInfo(OCDeviceInfo info)
+#ifdef TCP_ADAPTER
+/* This method will retrieve the tcp port */
+static OCStackResult GetTCPPortInfo(OCDevAddr *endpoint, uint16_t *port)
 {
-    cJSON *rootObj = cJSON_CreateObject();
+    uint16_t p = 0;
 
-    if (!rootObj)
+    if (endpoint->adapter == OC_ADAPTER_IP)
     {
-        return NULL;
-    }
-
-    cJSON *repObj = NULL;
-    char *jsonEncodedInfo = NULL;
-
-    cJSON_AddItemToObject (rootObj, OC_RSRVD_HREF,
-            cJSON_CreateString(GetVirtualResourceUri(OC_DEVICE_URI)));
-
-    cJSON_AddItemToObject (rootObj, OC_RSRVD_REPRESENTATION, repObj = cJSON_CreateObject());
-
-    if (!repObj)
-    {
-        return NULL;
-    }
-
-    cJSON_AddItemToObject (repObj, OC_RSRVD_DEVICE_ID,
-                    cJSON_CreateString(OCGetServerInstanceIDString()));
-
-    if (info.deviceName)
-    {
-        cJSON_AddItemToObject (repObj, OC_RSRVD_DEVICE_NAME,
-                        cJSON_CreateString(info.deviceName));
+        if (endpoint->flags & OC_IP_USE_V4)
+        {
+            p = caglobals.tcp.ipv4.port;
+        }
+        else if (endpoint->flags & OC_IP_USE_V6)
+        {
+            p = caglobals.tcp.ipv6.port;
+        }
     }
 
-    cJSON_AddItemToObject (repObj, OC_RSRVD_SPEC_VERSION,
-                        cJSON_CreateString(OC_SPEC_VERSION));
-
-    cJSON_AddItemToObject (repObj, OC_RSRVD_DATA_MODEL_VERSION,
-                        cJSON_CreateString(OC_DATA_MODEL_VERSION));
-
-    jsonEncodedInfo = cJSON_PrintUnformatted (rootObj);
-
-    cJSON_Delete(rootObj);
-
-    return jsonEncodedInfo;
+    *port = p;
+    return OC_STACK_OK;
 }
+#endif
 
 /*
  * Function will extract 0, 1 or 2 filters from query.
@@ -268,7 +152,7 @@ static OCStackResult ExtractFiltersFromQuery(char *query, char **filterOne, char
     *filterOne = NULL;
     *filterTwo = NULL;
 
-    OC_LOG_V(INFO, TAG, PCF("Received query %s for param extraction"), query);
+    OIC_LOG_V(INFO, TAG, "Extracting params from %s", query);
 
     char *keyValuePair = strtok_r (query, OC_QUERY_SEPARATOR, &restOfQuery);
 
@@ -276,7 +160,7 @@ static OCStackResult ExtractFiltersFromQuery(char *query, char **filterOne, char
     {
         if (numKeyValuePairsParsed >= 2)
         {
-            OC_LOG(ERROR, TAG, PCF("More than 2 queries params in URI."));
+            OIC_LOG(ERROR, TAG, "More than 2 queries params in URI.");
             return OC_STACK_INVALID_QUERY;
         }
 
@@ -286,17 +170,17 @@ static OCStackResult ExtractFiltersFromQuery(char *query, char **filterOne, char
         {
             return OC_STACK_INVALID_QUERY;
         }
-        else if (strcmp (key, OC_RSRVD_INTERFACE) == 0)
+        else if (strncasecmp(key, OC_RSRVD_INTERFACE, sizeof(OC_RSRVD_INTERFACE) - 1) == 0)
         {
             *filterOne = value;     // if
         }
-        else if (strcmp (key, OC_RSRVD_RESOURCE_TYPE) == 0)
+        else if (strncasecmp(key, OC_RSRVD_RESOURCE_TYPE, sizeof(OC_RSRVD_INTERFACE) - 1) == 0)
         {
             *filterTwo = value;     // rt
         }
         else
         {
-            OC_LOG_V(ERROR, TAG, "Unsupported query key: %s", key);
+            OIC_LOG_V(ERROR, TAG, "Unsupported query key: %s", key);
             return OC_STACK_INVALID_QUERY;
         }
         ++numKeyValuePairsParsed;
@@ -304,31 +188,41 @@ static OCStackResult ExtractFiltersFromQuery(char *query, char **filterOne, char
         keyValuePair = strtok_r(NULL, OC_QUERY_SEPARATOR, &restOfQuery);
     }
 
-    OC_LOG_V(INFO, TAG, "Extracted params %s and %s.", *filterOne, *filterTwo);
+    OIC_LOG_V(INFO, TAG, "Extracted params if: %s and rt: %s.", *filterOne, *filterTwo);
     return OC_STACK_OK;
 }
 
-static OCVirtualResources GetTypeOfVirtualURI(char *uriInRequest)
+static OCVirtualResources GetTypeOfVirtualURI(const char *uriInRequest)
 {
-    if (strcmp (uriInRequest, GetVirtualResourceUri(OC_WELL_KNOWN_URI)) == 0)
+    if (strcmp(uriInRequest, OC_RSRVD_WELL_KNOWN_URI) == 0)
     {
         return OC_WELL_KNOWN_URI;
     }
-    else if (strcmp (uriInRequest, GetVirtualResourceUri(OC_DEVICE_URI)) == 0)
+    else if (strcmp(uriInRequest, OC_RSRVD_DEVICE_URI) == 0)
     {
         return OC_DEVICE_URI;
     }
-    else if (strcmp (uriInRequest, GetVirtualResourceUri(OC_PLATFORM_URI)) == 0)
+    else if (strcmp(uriInRequest, OC_RSRVD_PLATFORM_URI) == 0)
     {
         return OC_PLATFORM_URI;
     }
-
-    #ifdef WITH_PRESENCE
-    else
+    else if (strcmp(uriInRequest, OC_RSRVD_RESOURCE_TYPES_URI) == 0)
+    {
+        return OC_RESOURCE_TYPES_URI;
+    }
+#ifdef ROUTING_GATEWAY
+    else if (0 == strcmp(uriInRequest, OC_RSRVD_GATEWAY_URI))
+    {
+        return OC_GATEWAY_URI;
+    }
+#endif
+#ifdef WITH_PRESENCE
+    else if (strcmp(uriInRequest, OC_RSRVD_PRESENCE_URI) == 0)
     {
         return OC_PRESENCE;
     }
-    #endif
+#endif //WITH_PRESENCE
+    return OC_UNKNOWN_URI;
 }
 
 static OCStackResult getQueryParamsForFiltering (OCVirtualResources uri, char *query,
@@ -346,7 +240,7 @@ static OCStackResult getQueryParamsForFiltering (OCVirtualResources uri, char *q
     if (uri == OC_PRESENCE)
     {
         //Nothing needs to be done, except for pass a OC_PRESENCE query through as OC_STACK_OK.
-        OC_LOG(INFO, TAG, PCF("OC_PRESENCE Request for virtual resource."));
+        OIC_LOG(INFO, TAG, "OC_PRESENCE Request for virtual resource.");
         return OC_STACK_OK;
     }
     #endif
@@ -361,187 +255,91 @@ static OCStackResult getQueryParamsForFiltering (OCVirtualResources uri, char *q
     return result;
 }
 
-OCStackResult copyStringIfEnoughSpace(char* dest, const char *src, uint16_t *remaining)
+OCStackResult BuildResponseRepresentation(const OCResource *resourcePtr,
+                    OCRepPayload** payload)
 {
-    if (!dest || !src || !remaining)
-    {
-        return OC_STACK_INVALID_PARAM;
-    }
-
-    size_t srcLen = strlen(src);
+    OCRepPayload *tempPayload = OCRepPayloadCreate();
 
-    if (srcLen < *remaining)
-    {
-        OICStrcpy(dest, *remaining, src);
-        *remaining = *remaining - srcLen;
-        return OC_STACK_OK;
-    }
-    else
+    if (!resourcePtr)
     {
-        return OC_STACK_ERROR;
+        OCRepPayloadDestroy(tempPayload);
+        return OC_STACK_INVALID_PARAM;
     }
-}
 
-OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr, char *out,
-                        uint16_t *remaining, CATransportAdapter_t adapter )
-{
-    if(!resourcePtr || !out  || !remaining)
+    if(!tempPayload)
     {
-        return OC_STACK_INVALID_PARAM;
+        return OC_STACK_NO_MEMORY;
     }
 
-    OCResourceType *resourceTypePtr = NULL;
-    OCResourceInterface *interfacePtr = NULL;
-    cJSON *resObj = NULL;
-    cJSON *policyObj = NULL;
-    cJSON *rtArray = NULL;
-    char *jsonStr = NULL;
-    OCStackResult ret = OC_STACK_OK;
-
-    OC_LOG_V(INFO, TAG, PCF("Encoding resource %s"), resourcePtr->uri);
-
-    resObj = cJSON_CreateObject();
+    OCRepPayloadSetUri(tempPayload, resourcePtr->uri);
 
-    if (resourcePtr)
+    OCResourceType *resType = resourcePtr->rsrcType;
+    while(resType)
     {
-        // URI
-        cJSON_AddItemToObject (resObj, OC_RSRVD_HREF, cJSON_CreateString(resourcePtr->uri));
-
-        // resource types
-        cJSON_AddItemToObject (resObj, OC_RSRVD_RESOURCE_TYPE, rtArray = cJSON_CreateArray());
-        resourceTypePtr = resourcePtr->rsrcType;
-        while (resourceTypePtr)
-        {
-            cJSON_AddItemToArray (rtArray,
-                                  cJSON_CreateString(resourceTypePtr->resourcetypename));
-            resourceTypePtr = resourceTypePtr->next;
-        }
-        // interfaces
-        cJSON_AddItemToObject (resObj, OC_RSRVD_INTERFACE, rtArray = cJSON_CreateArray());
-        interfacePtr = resourcePtr->rsrcInterface;
-        while (interfacePtr)
-        {
-            cJSON_AddItemToArray (rtArray, cJSON_CreateString(interfacePtr->name));
-            interfacePtr = interfacePtr->next;
-        }
-
-        // Policy
-        cJSON_AddItemToObject (resObj, OC_RSRVD_POLICY, policyObj = cJSON_CreateObject());
-
-        if (policyObj)
-        {
-            cJSON_AddNumberToObject (policyObj, OC_RSRVD_BITMAP,
-                             resourcePtr->resourceProperties & (OC_OBSERVABLE|OC_DISCOVERABLE));
-            // Set secure flag for secure resources
-            if (resourcePtr->resourceProperties & OC_SECURE)
-            {
-                cJSON_AddNumberToObject(policyObj, OC_RSRVD_SECURE, OC_RESOURCE_SECURE);
-                //Set the IP port also as secure resources are hosted on a different port
-                uint16_t port = 0;
-                if (GetSecurePortInfo(adapter, &port) == OC_STACK_OK)
-                {
-                    cJSON_AddNumberToObject(policyObj, OC_RSRVD_HOSTING_PORT, port);
-                }
-            }
-        }
-        else
-        {
-            cJSON_Delete(resObj);
-            return OC_STACK_NO_MEMORY;
-        }
+        OCRepPayloadAddResourceType(tempPayload, resType->resourcetypename);
+        resType = resType->next;
     }
-    jsonStr = cJSON_PrintUnformatted (resObj);
 
-    if(!jsonStr)
+    OCResourceInterface *resInterface = resourcePtr->rsrcInterface;
+    while(resInterface)
     {
-        cJSON_Delete(resObj);
-        return OC_STACK_NO_MEMORY;
+        OCRepPayloadAddInterface(tempPayload, resInterface->name);
+        resInterface = resInterface->next;
     }
 
-    ret = copyStringIfEnoughSpace(out, jsonStr, remaining);
-
-    cJSON_Delete (resObj);
-    OICFree (jsonStr);
-
-    return ret;
-}
-
-OCStackResult BuildVirtualResourceResponseForDevice(char *out, uint16_t *remaining)
-{
-    if(!out || !remaining)
+    OCAttribute *resAttrib = resourcePtr->rsrcAttributes;
+    while(resAttrib)
     {
-        return OC_STACK_INVALID_PARAM;
+        OCRepPayloadSetPropString(tempPayload, resAttrib->attrName,
+                                resAttrib->attrValue);
+        resAttrib = resAttrib->next;
     }
 
-    OCStackResult ret = OC_STACK_ERROR;
-    char *jsonStr = NULL;
-
-    jsonStr = GetJSONStringFromDeviceInfo(savedDeviceInfo);
-
-    if(jsonStr)
+    if(!*payload)
     {
-        ret = copyStringIfEnoughSpace(out, jsonStr, remaining);
-        OICFree(jsonStr);
+        *payload = tempPayload;
     }
     else
     {
-        OC_LOG(ERROR, TAG, PCF("Error encoding save device info."));
-        ret = OC_STACK_ERROR;
+        OCRepPayloadAppend(*payload, tempPayload);
     }
-    return ret;
+
+    return OC_STACK_OK;
 }
 
-OCStackResult BuildVirtualResourceResponseForPlatform(char *out, uint16_t *remaining)
+OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr,
+                        OCDiscoveryPayload *payload, OCDevAddr *devAddr, bool rdResponse)
 {
-    if(!out || !remaining)
+    if (!resourcePtr || !payload)
     {
         return OC_STACK_INVALID_PARAM;
     }
-
-    OCStackResult ret = OC_STACK_ERROR;
-    char *jsonStr = NULL;
-
-    jsonStr = GetJSONStringFromPlatformInfo(savedPlatformInfo);
-
-    if(jsonStr)
-    {
-        ret = copyStringIfEnoughSpace(out, jsonStr, remaining);
-        OICFree(jsonStr);
-    }
-    else
+    uint16_t securePort = 0;
+    if (resourcePtr->resourceProperties & OC_SECURE)
     {
-        OC_LOG(ERROR, TAG, PCF("Error encoding save platform info."));
-        ret = OC_STACK_ERROR;
+       if (GetSecurePortInfo(devAddr, &securePort) != OC_STACK_OK)
+       {
+           securePort = 0;
+       }
     }
 
-    return ret;
-}
-
-const char * GetVirtualResourceUri( OCVirtualResources resource)
-{
-    if (resource < OC_MAX_VIRTUAL_RESOURCES)
+    if (rdResponse)
     {
-        return VIRTUAL_RSRCS[resource];
+        securePort = devAddr->port;
     }
 
-    return NULL;
-}
-
-bool IsVirtualResource(const char* resourceUri)
-{
-    if(!resourceUri)
+    uint16_t tcpPort = 0;
+#ifdef TCP_ADAPTER
+    if (GetTCPPortInfo(devAddr, &tcpPort) != OC_STACK_OK)
     {
-        return false;
+        tcpPort = 0;
     }
+    OCDiscoveryPayloadAddResource(payload, resourcePtr, securePort, tcpPort);
+#else
+    OCDiscoveryPayloadAddResource(payload, resourcePtr, securePort);
+#endif
 
-    for (int i = 0; i < OC_MAX_VIRTUAL_RESOURCES; i++)
-    {
-        if (strcmp(resourceUri, GetVirtualResourceUri((OCVirtualResources)i)) == 0)
-        {
-            return true;
-        }
-    }
-    return false;
+    return OC_STACK_OK;
 }
 
 uint8_t IsCollectionResource (OCResource *resource)
@@ -551,13 +349,11 @@ uint8_t IsCollectionResource (OCResource *resource)
         return 0;
     }
 
-    for (int i = 0; i < MAX_CONTAINED_RESOURCES; i++)
+    if(resource->rsrcChildResourcesHead != NULL)
     {
-        if (resource->rsrcResources[i])
-        {
-            return 1;
-        }
+        return 1;
     }
+
     return 0;
 }
 
@@ -577,7 +373,7 @@ OCResource *FindResourceByUri(const char* resourceUri)
         }
         pointer = pointer->next;
     }
-    OC_LOG(INFO, TAG, PCF("Resource not found"));
+    OIC_LOG_V(INFO, TAG, "Resource %s not found", resourceUri);
     return NULL;
 }
 
@@ -591,13 +387,12 @@ OCStackResult DetermineResourceHandling (const OCServerRequest *request,
         return OC_STACK_INVALID_PARAM;
     }
 
-    OC_LOG(INFO, TAG, PCF("Entering DetermineResourceHandling"));
-
-    const OCDevAddr *devAddr = &request->devAddr;
+    OIC_LOG_V(INFO, TAG, "DetermineResourceHandling for %s", request->resourceUrl);
 
     // Check if virtual resource
-    if (IsVirtualResource((const char*)request->resourceUrl))
+    if (GetTypeOfVirtualURI(request->resourceUrl) != OC_UNKNOWN_URI)
     {
+        OIC_LOG_V (INFO, TAG, "%s is virtual", request->resourceUrl);
         *handling = OC_RESOURCE_VIRTUAL;
         *resource = headResource;
         return OC_STACK_OK;
@@ -610,8 +405,7 @@ OCStackResult DetermineResourceHandling (const OCServerRequest *request,
     }
     else
     {
-        OCResource *resourcePtr = NULL;
-        resourcePtr = FindResourceByUri((const char*)request->resourceUrl);
+        OCResource *resourcePtr = FindResourceByUri((const char*)request->resourceUrl);
         *resource = resourcePtr;
         if (!resourcePtr)
         {
@@ -627,13 +421,6 @@ OCStackResult DetermineResourceHandling (const OCServerRequest *request,
             return OC_STACK_NO_RESOURCE;
         }
 
-        // secure resource will entertain only authorized requests
-        if ((resourcePtr->resourceProperties & OC_SECURE) && ((devAddr->flags & OC_FLAG_SECURE) == 0))
-        {
-            OC_LOG(ERROR, TAG, PCF("Un-authorized request. Ignoring"));
-            return OC_STACK_RESOURCE_ERROR;
-        }
-
         if (IsCollectionResource (resourcePtr))
         {
             // Collection resource
@@ -723,7 +510,7 @@ static bool resourceMatchesRTFilter(OCResource *resource, char *resourceTypeFilt
         resourceTypePtr = resourceTypePtr->next;
     }
 
-    OC_LOG_V(INFO, TAG, PCF("%s does not contain rt=%s."), resource->uri, resourceTypeFilter);
+    OIC_LOG_V(INFO, TAG, "%s does not contain rt=%s.", resource->uri, resourceTypeFilter);
     return false;
 }
 
@@ -744,14 +531,16 @@ static bool resourceMatchesIFFilter(OCResource *resource, char *interfaceFilter)
 
     while (interfacePtr)
     {
-        if (strcmp (interfacePtr->name, interfaceFilter) == 0)
+        if ((strcmp (interfacePtr->name, interfaceFilter) == 0) &&
+            (strcmp (OC_RSRVD_INTERFACE_LL, interfaceFilter) == 0 ||
+             strcmp (OC_RSRVD_INTERFACE_DEFAULT, interfaceFilter) == 0))
         {
             return true;
         }
         interfacePtr = interfacePtr->next;
     }
 
-    OC_LOG_V(INFO, TAG, PCF("%s does not contain if=%s."), resource->uri, interfaceFilter);
+    OIC_LOG_V(INFO, TAG, "%s does not contain if=%s.", resource->uri, interfaceFilter);
     return false;
 }
 
@@ -761,19 +550,32 @@ static bool resourceMatchesIFFilter(OCResource *resource, char *interfaceFilter)
  * Function will return true if all non null AND non empty filters passed in find a match.
  */
 static bool includeThisResourceInResponse(OCResource *resource,
-                                                 char *interfaceFilter,
-                                                 char *resourceTypeFilter)
+                                          char *interfaceFilter,
+                                          char *resourceTypeFilter)
 {
     if (!resource)
     {
-        OC_LOG(ERROR, TAG, PCF("Invalid resource"));
+        OIC_LOG(ERROR, TAG, "Invalid resource");
         return false;
     }
 
-    if ( !(resource->resourceProperties & OC_ACTIVE) ||
+    if (resource->resourceProperties & OC_EXPLICIT_DISCOVERABLE)
+    {
+        /*
+         * At least one valid filter should be available to
+         * include the resource in discovery response
+         */
+        if (!(resourceTypeFilter && *resourceTypeFilter))
+        {
+            OIC_LOG_V(INFO, TAG, "%s no query string for EXPLICIT_DISCOVERABLE \
+                resource", resource->uri);
+            return false;
+        }
+    }
+    else if ( !(resource->resourceProperties & OC_ACTIVE) ||
          !(resource->resourceProperties & OC_DISCOVERABLE))
     {
-        OC_LOG_V(INFO, TAG, PCF("%s not ACTIVE or DISCOVERABLE"), resource->uri);
+        OIC_LOG_V(INFO, TAG, "%s not ACTIVE or DISCOVERABLE", resource->uri);
         return false;
     }
 
@@ -783,13 +585,12 @@ static bool includeThisResourceInResponse(OCResource *resource,
 }
 
 OCStackResult SendNonPersistantDiscoveryResponse(OCServerRequest *request, OCResource *resource,
-                                char *discoveryPayload)
+                                OCPayload *discoveryPayload, OCEntityHandlerResult ehResult)
 {
-    OCEntityHandlerResponse response = {};
+    OCEntityHandlerResponse response = {0};
 
-    response.ehResult = OC_EH_OK;
+    response.ehResult = ehResult;
     response.payload = discoveryPayload;
-    response.payloadSize = strlen((const char *)discoveryPayload) + 1;
     response.persistentBufferFlag = 0;
     response.requestHandle = (OCRequestHandle) request;
     response.resourceHandle = (OCResourceHandle) resource;
@@ -797,35 +598,101 @@ OCStackResult SendNonPersistantDiscoveryResponse(OCServerRequest *request, OCRes
     return OCDoResponse(&response);
 }
 
-static OCStackResult appendDeviceIDAndOpenLinksArray (char *out, uint16_t *remaining)
+#ifdef WITH_RD
+static OCStackResult checkResourceExistsAtRD(const char *interfaceType, const char *resourceType,
+     OCResource **payload, OCDevAddr *devAddr)
 {
-    if (!out || !remaining)
+    OCResourceCollectionPayload *repPayload;
+    if (!payload)
     {
-        return OC_STACK_INVALID_PARAM;
+        return OC_STACK_ERROR;
     }
+    if (OCRDCheckPublishedResource(interfaceType, resourceType, &repPayload, devAddr) == OC_STACK_OK)
+    {
+        if (!repPayload)
+        {
+            return OC_STACK_ERROR;
+        }
+        OCResource *ptr = ((OCResource *) OICCalloc(1, sizeof(OCResource)));
+        if (!ptr)
+        {
+           return OC_STACK_NO_MEMORY;
+        }
 
-    const char *deviceID = OCGetServerInstanceIDString();
+        ptr->uri = OICStrdup(repPayload->setLinks->href);
+        if (!ptr->uri)
+        {
+           return OC_STACK_NO_MEMORY;
+        }
+        OCStringLL *rt = repPayload->setLinks->rt;
+        while (rt)
+        {
+            OCResourceType *temp = (OCResourceType *) OICCalloc(1, sizeof(OCResourceType));
+            if(!temp)
+            {
+                OICFree(ptr->uri);
+                return OC_STACK_NO_MEMORY;
+            }
+            temp->next = NULL;
+            temp->resourcetypename = OICStrdup(rt->value);
+            if (!ptr->rsrcType)
+            {
+                ptr->rsrcType = temp;
+            }
+            else
+            {
+                OCResourceType *type = ptr->rsrcType;
+                while (type->next)
+                {
+                    type = type->next;
+                }
+                type->next = temp;
+            }
+            rt = rt->next;
+        }
 
-    char deviceIDJSONField[MAX_RESPONSE_LENGTH] = {};
+        OCStringLL *itf = repPayload->setLinks->itf;
+        while (itf)
+        {
+            OCResourceInterface *temp = (OCResourceInterface *) OICCalloc(1, sizeof(OCResourceInterface));
+            if (!temp)
+            {
+                OICFree(ptr->uri);
 
-    // Format is : {"di":"UUID","links":[
-    sprintf (deviceIDJSONField, "{\"%s\":\"%s\"%s\"%s\":[", OC_RSRVD_DEVICE_ID, deviceID,
-                            OC_JSON_SEPARATOR_STR, OC_RSRVD_LINKS);
+                return OC_STACK_NO_MEMORY;
+            }
+            temp->next = NULL;
+            temp->name = OICStrdup(itf->value);
+            if (!ptr->rsrcInterface)
+            {
+                ptr->rsrcInterface = temp;
+            }
+            else
+            {
+                OCResourceInterface *type = ptr->rsrcInterface;
+                while (type->next)
+                {
+                    type = type->next;
+                }
+                type->next = temp;
+            }
+            itf = itf->next;
+        }
 
-    uint16_t lenDeviceIDJSON = strlen(deviceIDJSONField);
+        ptr->resourceProperties = (OCResourceProperty) repPayload->tags->bitmap;
 
-    if (lenDeviceIDJSON > *remaining)
-    {
-        return OC_STACK_ERROR;
+        OCFreeCollectionResource(repPayload);
+        *payload = ptr;
+        return OC_STACK_OK;
     }
     else
     {
-        OICStrcat(out, *remaining, deviceIDJSONField);
-        *remaining -= lenDeviceIDJSON;
+        OIC_LOG_V(ERROR, TAG, "The resource type or interface type doe not exist \
+                             on the resource directory");
     }
-
-    return OC_STACK_OK;
+    return OC_STACK_ERROR;
 }
+#endif
 
 static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource* resource)
 {
@@ -835,128 +702,257 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource
     }
 
     OCStackResult discoveryResult = OC_STACK_ERROR;
-    char *filterOne = NULL;
-    char *filterTwo = NULL;
-    uint16_t remaining  = 0;
 
-    char discoveryBuffer[MAX_RESPONSE_LENGTH] = {};
+    bool bMulticast    = false;     // Was the discovery request a multicast request?
+    OCPayload* payload = NULL;
 
-    OC_LOG(INFO, TAG, PCF("Entering HandleVirtualResource"));
+    OIC_LOG(INFO, TAG, "Entering HandleVirtualResource");
 
     OCVirtualResources virtualUriInRequest = GetTypeOfVirtualURI (request->resourceUrl);
 
-    remaining = MAX_RESPONSE_LENGTH - sizeof ('\0');
-
+    // Step 1: Generate the response to discovery request
     if (virtualUriInRequest == OC_WELL_KNOWN_URI)
     {
-        discoveryResult = getQueryParamsForFiltering (virtualUriInRequest, request->query,
-                                            &filterOne, &filterTwo);
-        if (discoveryResult != OC_STACK_OK)
+        if (request->method == OC_REST_PUT || request->method == OC_REST_POST || request->method == OC_REST_DELETE)
         {
-            OC_LOG_V(ERROR, TAG, "Error (%d) validating query.\n", discoveryResult);
-            return discoveryResult;
+            OIC_LOG_V(ERROR, TAG, "Resource : %s not permitted for method: %d", request->resourceUrl, request->method);
+            return OC_STACK_UNAUTHORIZED_REQ;
         }
-        char *ptrIntoBuffer = discoveryBuffer;
 
-        discoveryResult = appendDeviceIDAndOpenLinksArray(ptrIntoBuffer, &remaining);
+        char *interfaceQuery = NULL;
+        char *resourceTypeQuery = NULL;
 
-        while(resource && discoveryResult == OC_STACK_OK)
+        discoveryResult = getQueryParamsForFiltering (virtualUriInRequest, request->query,
+                &interfaceQuery, &resourceTypeQuery);
+        bool interfaceQueryAllocated = false;
+        if (!interfaceQuery && !resourceTypeQuery)
         {
-            if(includeThisResourceInResponse(resource, filterOne, filterTwo))
-            {
-                ptrIntoBuffer += strlen(ptrIntoBuffer);
+            interfaceQueryAllocated = true;
+            interfaceQuery = OICStrdup(OC_RSRVD_INTERFACE_LL);
+        }
 
-                discoveryResult = BuildVirtualResourceResponse(resource, ptrIntoBuffer,
-                                        &remaining, (CATransportAdapter_t)request->devAddr.adapter);
+        if (discoveryResult == OC_STACK_OK)
+        {
+            payload = (OCPayload *)OCDiscoveryPayloadCreate();
 
-                if (discoveryResult != OC_STACK_OK)
+            if (payload)
+            {
+                OCDiscoveryPayload *discPayload = (OCDiscoveryPayload *)payload;
+                discPayload->sid = (char *)OICCalloc(1, UUID_STRING_SIZE);
+                VERIFY_NON_NULL(discPayload->sid, ERROR, OC_STACK_NO_MEMORY);
+
+                const char* uid = OCGetServerInstanceIDString();
+                if (uid)
                 {
-                    OC_LOG_V(INFO, TAG, "Error (%d) encoding %s", discoveryResult, resource->uri);
-                    break;
+                    memcpy(discPayload->sid, uid, UUID_STRING_SIZE);
                 }
 
-                ptrIntoBuffer += strlen(ptrIntoBuffer);
-                if (remaining > sizeof(OC_JSON_SEPARATOR))
+                if (!resourceTypeQuery && interfaceQuery && (0 == strcmp(interfaceQuery, OC_RSRVD_INTERFACE_LL)))
                 {
-                    *ptrIntoBuffer = OC_JSON_SEPARATOR;
-                    ++ptrIntoBuffer;
-                    --remaining;
+                    for (; resource && discoveryResult == OC_STACK_OK; resource = resource->next)
+                    {
+                        bool result = false;
+                        if (resource->resourceProperties & OC_DISCOVERABLE)
+                        {
+                            result = true;
+                        }
+
+                        if (result)
+                        {
+                            discoveryResult = BuildVirtualResourceResponse(resource,
+                            discPayload, &request->devAddr, false);
+                        }
+                    }
                 }
                 else
                 {
-                    OC_LOG(INFO, TAG, PCF("Out of space in buffer"));
-                    break;
+                    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 = OICStrdup(OC_RSRVD_RESOURCE_TYPE_RES);
+                        VERIFY_NON_NULL(discPayload->type, ERROR, OC_STACK_NO_MEMORY);
+                        OCResourcePayloadAddStringLL(&discPayload->interface, OC_RSRVD_INTERFACE_LL);
+                        OCResourcePayloadAddStringLL(&discPayload->interface, OC_RSRVD_INTERFACE_DEFAULT);
+                        VERIFY_NON_NULL(discPayload->interface, ERROR, OC_STACK_NO_MEMORY);
+                    }
+                    bool foundResourceAtRD = false;
+                    for (;resource && discoveryResult == OC_STACK_OK; resource = resource->next)
+                    {
+#ifdef WITH_RD
+                        if (strcmp(resource->uri, OC_RSRVD_RD_URI) == 0)
+                        {
+                            OCResource *resource1 = NULL;
+                            OCDevAddr devAddr;
+                            discoveryResult = checkResourceExistsAtRD(interfaceQuery,
+                                resourceTypeQuery, &resource1, &devAddr);
+                            if (discoveryResult != OC_STACK_OK)
+                            {
+                                 break;
+                            }
+                            discoveryResult = BuildVirtualResourceResponse(resource1,
+                                discPayload, &devAddr, true);
+                            if (payload)
+                            {
+                                discPayload->baseURI = OICStrdup(devAddr.addr);
+                            }
+                            OICFree(resource1->uri);
+                            for (OCResourceType *rsrcRt = resource1->rsrcType, *rsrcRtNext = NULL; rsrcRt; )
+                            {
+                                rsrcRtNext = rsrcRt->next;
+                                OICFree(rsrcRt->resourcetypename);
+                                OICFree(rsrcRt);
+                                rsrcRt = rsrcRtNext;
+                            }
+
+                            for (OCResourceInterface *rsrcPtr = resource1->rsrcInterface, *rsrcNext = NULL; rsrcPtr; )
+                            {
+                                rsrcNext = rsrcPtr->next;
+                                OICFree(rsrcPtr->name);
+                                OICFree(rsrcPtr);
+                                rsrcPtr = rsrcNext;
+                            }
+                            foundResourceAtRD = true;
+                        }
+#endif
+                        if (!foundResourceAtRD && includeThisResourceInResponse(resource, interfaceQuery, resourceTypeQuery))
+                        {
+                            discoveryResult = BuildVirtualResourceResponse(resource,
+                                discPayload, &request->devAddr, false);
+                        }
+                    }
+                    // Set discoveryResult appropriately if no 'valid' resources are available
+                    if (discPayload->resources == NULL && !foundResourceAtRD)
+                    {
+                        discoveryResult = OC_STACK_NO_RESOURCE;
+                    }
                 }
-
             }
-            resource = resource->next;
+            else
+            {
+                discoveryResult = OC_STACK_NO_MEMORY;
+            }
         }
-
-        size_t lenDiscoveryBuff = strlen (discoveryBuffer);
-
-        // Traling separator replaced with closing of "links" array.
-        // discoveryBuffer guaranteed to be null terminated as "remaining"
-        // accounts for '\0' when initialized.
-        if (lenDiscoveryBuff > 0 && discoveryBuffer[lenDiscoveryBuff - 1] == OC_JSON_SEPARATOR)
+        else
         {
-            discoveryBuffer[lenDiscoveryBuff - 1] = ']';
+            OIC_LOG_V(ERROR, TAG, "Error (%d) parsing query.", discoveryResult);
         }
-        else
+        if (interfaceQueryAllocated)
         {
-            // If No trailing separator then close links array anyway.
-            discoveryBuffer[lenDiscoveryBuff] = ']';
+            OICFree(interfaceQuery);
+        }
+    }
+    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;
         }
-        --remaining;
-        ptrIntoBuffer += strlen(ptrIntoBuffer);
 
-        // Close array element brace.
-        if (remaining > sizeof ('}'))
+        const char* deviceId = OCGetServerInstanceIDString();
+        if (!deviceId)
         {
-            *ptrIntoBuffer = '}';
-            --remaining;
+            discoveryResult = OC_STACK_ERROR;
         }
         else
         {
-            discoveryResult = OC_STACK_ERROR;
+            payload = (OCPayload*) OCDevicePayloadCreate(deviceId, savedDeviceInfo.deviceName,
+                savedDeviceInfo.types, savedDeviceInfo.specVersion, savedDeviceInfo.dataModelVersion);
+            if (!payload)
+            {
+                discoveryResult = OC_STACK_NO_MEMORY;
+            }
+            else
+            {
+                discoveryResult = OC_STACK_OK;
+            }
         }
     }
-
-    else if (virtualUriInRequest == OC_DEVICE_URI)
+    else if (virtualUriInRequest == OC_PLATFORM_URI)
     {
-        discoveryResult = BuildVirtualResourceResponseForDevice(discoveryBuffer, &remaining);
+        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;
+        }
     }
-    else if (virtualUriInRequest == OC_PLATFORM_URI)
+#ifdef ROUTING_GATEWAY
+    else if (OC_GATEWAY_URI == virtualUriInRequest)
     {
-        discoveryResult = BuildVirtualResourceResponseForPlatform(discoveryBuffer, &remaining);
+        // Received request for a gateway
+        OIC_LOG(INFO, TAG, "Request is for Gateway Virtual Request");
+        discoveryResult = RMHandleGatewayRequest(request, resource);
+
     }
+#endif
 
-    #ifdef WITH_PRESENCE
-    else
+    /**
+     * Step 2: Send the discovery response
+     *
+     * Iotivity should respond to discovery requests in below manner:
+     * 1)If query filter matching fails and discovery request is multicast,
+     *   it should NOT send any response.
+     * 2)If query filter matching fails and discovery request is unicast,
+     *   it should send an error(RESOURCE_NOT_FOUND - 404) response.
+     * 3)If Server does not have any 'DISCOVERABLE' resources and discovery
+     *   request is multicast, it should NOT send any response.
+     * 4)If Server does not have any 'DISCOVERABLE' resources and discovery
+     *   request is unicast, it should send an error(RESOURCE_NOT_FOUND - 404) response.
+     */
+
+#ifdef WITH_PRESENCE
+    if ((virtualUriInRequest == OC_PRESENCE) &&
+        (resource->resourceProperties & OC_ACTIVE))
     {
-        if(resource->resourceProperties & OC_ACTIVE)
-        {
-            discoveryResult = SendPresenceNotification(resource->rsrcType,
-                                                OC_PRESENCE_TRIGGER_CHANGE);
-        }
+        // Presence uses observer notification api to respond via SendPresenceNotification.
+        SendPresenceNotification(resource->rsrcType, OC_PRESENCE_TRIGGER_CHANGE);
     }
+    else
     #endif
-
-    // Presence uses observer notification api to respond via SendPresenceNotification.
-    if (virtualUriInRequest != OC_PRESENCE)
+#ifdef ROUTING_GATEWAY
+    // Gateway uses the RMHandleGatewayRequest to respond to the request.
+    if (OC_GATEWAY_URI != virtualUriInRequest)
+#endif
     {
         if(discoveryResult == OC_STACK_OK)
         {
-            discoveryResult = SendNonPersistantDiscoveryResponse(request, resource,
-                                                        discoveryBuffer);
+            SendNonPersistantDiscoveryResponse(request, resource, payload, OC_EH_OK);
+        }
+        else if(bMulticast == false && (request->devAddr.adapter != OC_ADAPTER_RFCOMM_BTEDR) &&
+               (request->devAddr.adapter != OC_ADAPTER_GATT_BTLE))
+        {
+            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);
         }
         else
         {
-            OC_LOG_V(ERROR, TAG, "Error (%d) building (%d)  discovery response. "\
-                        "Not responding to request.", discoveryResult, virtualUriInRequest);
+            // Ignoring the discovery request as per RFC 7252, Section #8.2
+            OIC_LOG(INFO, TAG, "Silently ignoring the request since device does not have \
+                any useful data to send");
         }
     }
 
-    return discoveryResult;
+    OCPayloadDestroy(payload);
+
+    return OC_STACK_OK;
 }
 
 static OCStackResult
@@ -969,14 +965,21 @@ HandleDefaultDeviceEntityHandler (OCServerRequest *request)
 
     OCStackResult result = OC_STACK_OK;
     OCEntityHandlerResult ehResult = OC_EH_ERROR;
-    OCEntityHandlerRequest ehRequest = {};
-
-    OC_LOG(INFO, TAG, PCF("Entering HandleResourceWithDefaultDeviceEntityHandler"));
-    result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
-            request->method, (OCResourceHandle) NULL, request->query,
-            request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
-            request->rcvdVendorSpecificHeaderOptions,
-            (OCObserveAction)request->observationOption, (OCObservationId)0);
+    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);
     VERIFY_SUCCESS(result, OC_STACK_OK);
 
     // At this point we know for sure that defaultDeviceHandler exists
@@ -984,7 +987,7 @@ HandleDefaultDeviceEntityHandler (OCServerRequest *request)
                                   (char*) request->resourceUrl, defaultDeviceHandlerCallbackParameter);
     if(ehResult == OC_EH_SLOW)
     {
-        OC_LOG(INFO, TAG, PCF("This is a slow resource"));
+        OIC_LOG(INFO, TAG, "This is a slow resource");
         request->slowFlag = 1;
     }
     else if(ehResult == OC_EH_ERROR)
@@ -993,6 +996,7 @@ HandleDefaultDeviceEntityHandler (OCServerRequest *request)
     }
     result = EntityHandlerCodeToOCStackCode(ehResult);
 exit:
+    OCPayloadDestroy(ehRequest.payload);
     return result;
 }
 
@@ -1011,25 +1015,63 @@ HandleResourceWithEntityHandler (OCServerRequest *request,
     OCEntityHandlerFlag ehFlag = OC_REQUEST_FLAG;
     ResourceObserver *resObs = NULL;
 
-    OCEntityHandlerRequest ehRequest = {};
+    OCEntityHandlerRequest ehRequest = {0};
 
-    OC_LOG(INFO, TAG, PCF("Entering HandleResourceWithEntityHandler"));
+    OIC_LOG(INFO, TAG, "Entering HandleResourceWithEntityHandler");
+    OCPayloadType type = PAYLOAD_TYPE_REPRESENTATION;
+    // check the security resource
+    if (request && request->resourceUrl && SRMIsSecurityResourceURI(request->resourceUrl))
+    {
+        type = PAYLOAD_TYPE_SECURITY;
+
+    }
+
+    if (request && strcmp(request->resourceUrl, OC_RSRVD_RD_URI) == 0)
+    {
+        type = PAYLOAD_TYPE_RD;
+    }
 
-    result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
-            request->method, (OCResourceHandle) resource, request->query,
-            request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
-            request->rcvdVendorSpecificHeaderOptions,
-            (OCObserveAction)request->observationOption, 0);
+    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);
     VERIFY_SUCCESS(result, OC_STACK_OK);
 
     if(ehRequest.obsInfo.action == OC_OBSERVE_NO_OPTION)
     {
-        OC_LOG(INFO, TAG, PCF("No observation requested"));
+        OIC_LOG(INFO, TAG, "No observation requested");
         ehFlag = OC_REQUEST_FLAG;
     }
     else if(ehRequest.obsInfo.action == OC_OBSERVE_REGISTER && !collectionResource)
     {
-        OC_LOG(INFO, TAG, PCF("Observation registration requested"));
+        OIC_LOG(INFO, TAG, "Observation registration requested");
+
+        ResourceObserver *obs = GetObserverUsingToken (request->requestToken,
+                                    request->tokenLength);
+
+        if (obs)
+        {
+            OIC_LOG (INFO, TAG, "Observer with this token already present");
+            OIC_LOG (INFO, TAG, "Possibly re-transmitted CON OBS request");
+            OIC_LOG (INFO, TAG, "Not adding observer. Not responding to client");
+            OIC_LOG (INFO, TAG, "The first request for this token is already ACKED.");
+
+            // server requests are usually free'd when the response is sent out
+            // for the request in ocserverrequest.c : HandleSingleResponse()
+            // Since we are making an early return and not responding, the server request
+            // needs to be deleted.
+            FindAndDeleteServerRequest (request);
+            return OC_STACK_OK;
+        }
 
         result = GenerateObserverId(&ehRequest.obsInfo.obsId);
         VERIFY_SUCCESS(result, OC_STACK_OK);
@@ -1037,31 +1079,31 @@ HandleResourceWithEntityHandler (OCServerRequest *request,
         result = AddObserver ((const char*)(request->resourceUrl),
                 (const char *)(request->query),
                 ehRequest.obsInfo.obsId, request->requestToken, request->tokenLength,
-                resource, request->qos,
+                resource, request->qos, request->acceptFormat,
                 &request->devAddr);
 
         if(result == OC_STACK_OK)
         {
-            OC_LOG(INFO, TAG, PCF("Added observer successfully"));
+            OIC_LOG(INFO, TAG, "Added observer successfully");
             request->observeResult = OC_STACK_OK;
             ehFlag = (OCEntityHandlerFlag)(OC_REQUEST_FLAG | OC_OBSERVE_FLAG);
         }
         else
         {
-            result = OC_STACK_OK;
-
             // The error in observeResult for the request will be used when responding to this
             // request by omitting the observation option/sequence number.
             request->observeResult = OC_STACK_ERROR;
-            OC_LOG(ERROR, TAG, PCF("Observer Addition failed"));
+            OIC_LOG(ERROR, TAG, "Observer Addition failed");
             ehFlag = OC_REQUEST_FLAG;
+            FindAndDeleteServerRequest(request);
+            goto exit;
         }
 
     }
     else if(ehRequest.obsInfo.action == OC_OBSERVE_DEREGISTER &&
             !collectionResource)
     {
-        OC_LOG(INFO, TAG, PCF("Deregistering observation requested"));
+        OIC_LOG(INFO, TAG, "Deregistering observation requested");
 
         resObs = GetObserverUsingToken (request->requestToken, request->tokenLength);
 
@@ -1079,14 +1121,15 @@ HandleResourceWithEntityHandler (OCServerRequest *request,
 
         if(result == OC_STACK_OK)
         {
-            OC_LOG(INFO, TAG, PCF("Removed observer successfully"));
+            OIC_LOG(INFO, TAG, "Removed observer successfully");
             request->observeResult = OC_STACK_OK;
         }
         else
         {
-            result = OC_STACK_OK;
             request->observeResult = OC_STACK_ERROR;
-            OC_LOG(ERROR, TAG, PCF("Observer Removal failed"));
+            OIC_LOG(ERROR, TAG, "Observer Removal failed");
+            FindAndDeleteServerRequest(request);
+            goto exit;
         }
     }
     else
@@ -1098,7 +1141,7 @@ HandleResourceWithEntityHandler (OCServerRequest *request,
     ehResult = resource->entityHandler(ehFlag, &ehRequest, resource->entityHandlerCallbackParam);
     if(ehResult == OC_EH_SLOW)
     {
-        OC_LOG(INFO, TAG, PCF("This is a slow resource"));
+        OIC_LOG(INFO, TAG, "This is a slow resource");
         request->slowFlag = 1;
     }
     else if(ehResult == OC_EH_ERROR)
@@ -1107,6 +1150,7 @@ HandleResourceWithEntityHandler (OCServerRequest *request,
     }
     result = EntityHandlerCodeToOCStackCode(ehResult);
 exit:
+    OCPayloadDestroy(ehRequest.payload);
     return result;
 }
 
@@ -1120,19 +1164,28 @@ HandleCollectionResourceDefaultEntityHandler (OCServerRequest *request,
     }
 
     OCStackResult result = OC_STACK_ERROR;
-    OCEntityHandlerRequest ehRequest = {};
-
-    result = FormOCEntityHandlerRequest(&ehRequest, (OCRequestHandle) request,
-            request->method, (OCResourceHandle) resource, request->query,
-            request->reqJSONPayload, request->numRcvdVendorSpecificHeaderOptions,
-            request->rcvdVendorSpecificHeaderOptions,
-            (OCObserveAction)request->observationOption, (OCObservationId) 0);
-    if(result != OC_STACK_OK)
-    {
-        return result;
-    }
-
-    return (DefaultCollectionEntityHandler (OC_REQUEST_FLAG, &ehRequest));
+    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);
+    if(result == OC_STACK_OK)
+    {
+        result = DefaultCollectionEntityHandler (OC_REQUEST_FLAG, &ehRequest);
+    }
+
+    OCPayloadDestroy(ehRequest.payload);
+    return result;
 }
 
 OCStackResult
@@ -1154,7 +1207,7 @@ ProcessRequest(ResourceHandling resHandling, OCResource *resource, OCServerReque
         }
         case OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER:
         {
-            OC_LOG(INFO, TAG, PCF("OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER"));
+            OIC_LOG(INFO, TAG, "OC_RESOURCE_NOT_COLLECTION_DEFAULT_ENTITYHANDLER");
             return OC_STACK_ERROR;
         }
         case OC_RESOURCE_NOT_COLLECTION_WITH_ENTITYHANDLER:
@@ -1179,7 +1232,7 @@ ProcessRequest(ResourceHandling resHandling, OCResource *resource, OCServerReque
         }
         default:
         {
-            OC_LOG(INFO, TAG, PCF("Invalid Resource Determination"));
+            OIC_LOG(INFO, TAG, "Invalid Resource Determination");
             return OC_STACK_ERROR;
         }
     }
@@ -1188,7 +1241,7 @@ ProcessRequest(ResourceHandling resHandling, OCResource *resource, OCServerReque
 
 void DeletePlatformInfo()
 {
-    OC_LOG(INFO, TAG, PCF("Deleting platform info."));
+    OIC_LOG(INFO, TAG, "Deleting platform info.");
 
     OICFree(savedPlatformInfo.platformID);
     savedPlatformInfo.platformID = NULL;
@@ -1266,11 +1319,11 @@ OCStackResult SavePlatformInfo(OCPlatformInfo info)
 
     if (res != OC_STACK_OK)
     {
-        OC_LOG_V(ERROR, TAG, PCF("Failed to save platform info. errno(%d)"), res);
+        OIC_LOG_V(ERROR, TAG, "Failed to save platform info. errno(%d)", res);
     }
     else
     {
-        OC_LOG(ERROR, TAG, PCF("Platform info saved."));
+        OIC_LOG(INFO, TAG, "Platform info saved.");
     }
 
     return res;
@@ -1278,10 +1331,15 @@ OCStackResult SavePlatformInfo(OCPlatformInfo info)
 
 void DeleteDeviceInfo()
 {
-    OC_LOG(INFO, TAG, PCF("Deleting device info."));
+    OIC_LOG(INFO, TAG, "Deleting device info.");
 
     OICFree(savedDeviceInfo.deviceName);
+    OCFreeOCStringLL(savedDeviceInfo.types);
+    OICFree(savedDeviceInfo.specVersion);
+    OICFree(savedDeviceInfo.dataModelVersion);
     savedDeviceInfo.deviceName = NULL;
+    savedDeviceInfo.specVersion = NULL;
+    savedDeviceInfo.dataModelVersion = NULL;
 }
 
 static OCStackResult DeepCopyDeviceInfo(OCDeviceInfo info)
@@ -1294,6 +1352,54 @@ static OCStackResult DeepCopyDeviceInfo(OCDeviceInfo info)
         return OC_STACK_NO_MEMORY;
     }
 
+    if (info.types)
+    {
+        savedDeviceInfo.types = CloneOCStringLL(info.types);
+        if(!savedDeviceInfo.types && info.types)
+        {
+            DeleteDeviceInfo();
+            return OC_STACK_NO_MEMORY;
+        }
+    }
+
+    if (info.specVersion)
+    {
+        savedDeviceInfo.specVersion = OICStrdup(info.specVersion);
+        if(!savedDeviceInfo.specVersion && info.specVersion)
+        {
+            DeleteDeviceInfo();
+            return OC_STACK_NO_MEMORY;
+        }
+    }
+    else
+    {
+        savedDeviceInfo.specVersion = OICStrdup(OC_SPEC_VERSION);
+        if(!savedDeviceInfo.specVersion && OC_SPEC_VERSION)
+        {
+            DeleteDeviceInfo();
+            return OC_STACK_NO_MEMORY;
+        }
+    }
+
+    if (info.dataModelVersion)
+    {
+        savedDeviceInfo.dataModelVersion = OICStrdup(info.dataModelVersion);
+        if(!savedDeviceInfo.dataModelVersion && info.dataModelVersion)
+        {
+            DeleteDeviceInfo();
+            return OC_STACK_NO_MEMORY;
+        }
+    }
+    else
+    {
+        savedDeviceInfo.dataModelVersion = OICStrdup(OC_DATA_MODEL_VERSION);
+        if(!savedDeviceInfo.dataModelVersion && OC_DATA_MODEL_VERSION)
+        {
+            DeleteDeviceInfo();
+            return OC_STACK_NO_MEMORY;
+        }
+    }
+
     return OC_STACK_OK;
 }
 
@@ -1307,18 +1413,17 @@ OCStackResult SaveDeviceInfo(OCDeviceInfo info)
 
     VERIFY_SUCCESS(res, OC_STACK_OK);
 
-    if(OCGetServerInstanceID() == NULL)
+    if (OCGetServerInstanceIDString() == NULL)
     {
-        OC_LOG(INFO, TAG, PCF("Device ID generation failed"));
+        OIC_LOG(INFO, TAG, "Device ID generation failed");
         res =  OC_STACK_ERROR;
         goto exit;
     }
 
-    OC_LOG(INFO, TAG, PCF("Device initialized successfully."));
+    OIC_LOG(INFO, TAG, "Device initialized successfully.");
     return OC_STACK_OK;
 
-    exit:
-        DeleteDeviceInfo();
-        return res;
-
+exit:
+    DeleteDeviceInfo();
+    return res;
 }