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
index ff15208..5349740 100755 (executable)
@@ -111,6 +111,29 @@ static OCStackResult GetSecurePortInfo(OCDevAddr *endpoint, uint16_t *port)
     return OC_STACK_OK;
 }
 
+#ifdef TCP_ADAPTER
+/* This method will retrieve the tcp port */
+static OCStackResult GetTCPPortInfo(OCDevAddr *endpoint, uint16_t *port)
+{
+    uint16_t p = 0;
+
+    if (endpoint->adapter == OC_ADAPTER_IP)
+    {
+        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;
+        }
+    }
+
+    *port = p;
+    return OC_STACK_OK;
+}
+#endif
+
 /*
  * Function will extract 0, 1 or 2 filters from query.
  * More than 2 filters or unsupported filters will result in error.
@@ -291,21 +314,31 @@ OCStackResult BuildVirtualResourceResponse(const OCResource *resourcePtr,
     {
         return OC_STACK_INVALID_PARAM;
     }
-    uint16_t port = 0;
+    uint16_t securePort = 0;
     if (resourcePtr->resourceProperties & OC_SECURE)
     {
-       if (GetSecurePortInfo(devAddr, &port) != OC_STACK_OK)
+       if (GetSecurePortInfo(devAddr, &securePort) != OC_STACK_OK)
        {
-           port = 0;
+           securePort = 0;
        }
     }
 
     if (rdResponse)
     {
-        port = devAddr->port;
+        securePort = devAddr->port;
     }
 
-    OCDiscoveryPayloadAddResource(payload, resourcePtr, port);
+    uint16_t tcpPort = 0;
+#ifdef TCP_ADAPTER
+    if (GetTCPPortInfo(devAddr, &tcpPort) != OC_STACK_OK)
+    {
+        tcpPort = 0;
+    }
+    OCDiscoveryPayloadAddResource(payload, resourcePtr, securePort, tcpPort);
+#else
+    OCDiscoveryPayloadAddResource(payload, resourcePtr, securePort);
+#endif
+
     return OC_STACK_OK;
 }
 
@@ -498,7 +531,9 @@ 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;
         }
@@ -515,8 +550,8 @@ 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)
     {
@@ -524,14 +559,13 @@ static bool includeThisResourceInResponse(OCResource *resource,
         return false;
     }
 
-    if ( resource->resourceProperties & OC_EXPLICIT_DISCOVERABLE)
+    if (resource->resourceProperties & OC_EXPLICIT_DISCOVERABLE)
     {
         /*
          * At least one valid filter should be available to
          * include the resource in discovery response
          */
-        if (!((interfaceFilter && *interfaceFilter ) ||
-              (resourceTypeFilter && *resourceTypeFilter)))
+        if (!(resourceTypeFilter && *resourceTypeFilter))
         {
             OIC_LOG_V(INFO, TAG, "%s no query string for EXPLICIT_DISCOVERABLE \
                 resource", resource->uri);
@@ -679,11 +713,23 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource
     // Step 1: Generate the response to discovery request
     if (virtualUriInRequest == OC_WELL_KNOWN_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;
+        }
+
         char *interfaceQuery = NULL;
         char *resourceTypeQuery = NULL;
 
         discoveryResult = getQueryParamsForFiltering (virtualUriInRequest, request->query,
                 &interfaceQuery, &resourceTypeQuery);
+        bool interfaceQueryAllocated = false;
+        if (!interfaceQuery && !resourceTypeQuery)
+        {
+            interfaceQueryAllocated = true;
+            interfaceQuery = OICStrdup(OC_RSRVD_INTERFACE_LL);
+        }
 
         if (discoveryResult == OC_STACK_OK)
         {
@@ -691,20 +737,50 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource
 
             if (payload)
             {
-                ((OCDiscoveryPayload*)payload)->sid = (char *)OICCalloc(1, UUID_STRING_SIZE);
-                VERIFY_NON_NULL(((OCDiscoveryPayload*)payload)->sid, ERROR, OC_STACK_NO_MEMORY);
-                memcpy(((OCDiscoveryPayload*)payload)->sid, OCGetServerInstanceIDString(), UUID_STRING_SIZE);
+                OCDiscoveryPayload *discPayload = (OCDiscoveryPayload *)payload;
+                discPayload->sid = (char *)OICCalloc(1, UUID_STRING_SIZE);
+                VERIFY_NON_NULL(discPayload->sid, ERROR, OC_STACK_NO_MEMORY);
 
-                if (interfaceQuery && 0 == strcmp(OC_RSRVD_INTERFACE_LL, interfaceQuery))
+                const char* uid = OCGetServerInstanceIDString();
+                if (uid)
+                {
+                    memcpy(discPayload->sid, uid, UUID_STRING_SIZE);
+                }
+
+                if (!resourceTypeQuery && interfaceQuery && (0 == strcmp(interfaceQuery, OC_RSRVD_INTERFACE_LL)))
                 {
                     for (; resource && discoveryResult == OC_STACK_OK; resource = resource->next)
                     {
-                        discoveryResult = BuildVirtualResourceResponse(resource,
-                                (OCDiscoveryPayload *)payload, &request->devAddr, false);
+                        bool result = false;
+                        if (resource->resourceProperties & OC_DISCOVERABLE)
+                        {
+                            result = true;
+                        }
+
+                        if (result)
+                        {
+                            discoveryResult = BuildVirtualResourceResponse(resource,
+                            discPayload, &request->devAddr, false);
+                        }
                     }
                 }
                 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 = 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)
                     {
@@ -720,10 +796,10 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource
                                  break;
                             }
                             discoveryResult = BuildVirtualResourceResponse(resource1,
-                                (OCDiscoveryPayload*)payload, &devAddr, true);
+                                discPayload, &devAddr, true);
                             if (payload)
                             {
-                                ((OCDiscoveryPayload*)payload)->baseURI = OICStrdup(devAddr.addr);
+                                discPayload->baseURI = OICStrdup(devAddr.addr);
                             }
                             OICFree(resource1->uri);
                             for (OCResourceType *rsrcRt = resource1->rsrcType, *rsrcRtNext = NULL; rsrcRt; )
@@ -747,11 +823,11 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource
                         if (!foundResourceAtRD && includeThisResourceInResponse(resource, interfaceQuery, resourceTypeQuery))
                         {
                             discoveryResult = BuildVirtualResourceResponse(resource,
-                                (OCDiscoveryPayload*)payload, &request->devAddr, false);
+                                discPayload, &request->devAddr, false);
                         }
                     }
                     // Set discoveryResult appropriately if no 'valid' resources are available
-                    if (((OCDiscoveryPayload*)payload)->resources == NULL && !foundResourceAtRD)
+                    if (discPayload->resources == NULL && !foundResourceAtRD)
                     {
                         discoveryResult = OC_STACK_NO_RESOURCE;
                     }
@@ -766,9 +842,19 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource
         {
             OIC_LOG_V(ERROR, TAG, "Error (%d) parsing query.", discoveryResult);
         }
+        if (interfaceQueryAllocated)
+        {
+            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;
+        }
+
         const char* deviceId = OCGetServerInstanceIDString();
         if (!deviceId)
         {
@@ -777,7 +863,7 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource
         else
         {
             payload = (OCPayload*) OCDevicePayloadCreate(deviceId, savedDeviceInfo.deviceName,
-                savedDeviceInfo.types, OC_SPEC_VERSION, OC_DATA_MODEL_VERSION);
+                savedDeviceInfo.types, savedDeviceInfo.specVersion, savedDeviceInfo.dataModelVersion);
             if (!payload)
             {
                 discoveryResult = OC_STACK_NO_MEMORY;
@@ -790,6 +876,12 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource
     }
     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)
         {
@@ -998,13 +1090,13 @@ HandleResourceWithEntityHandler (OCServerRequest *request,
         }
         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;
             OIC_LOG(ERROR, TAG, "Observer Addition failed");
             ehFlag = OC_REQUEST_FLAG;
+            FindAndDeleteServerRequest(request);
+            goto exit;
         }
 
     }
@@ -1034,9 +1126,10 @@ HandleResourceWithEntityHandler (OCServerRequest *request,
         }
         else
         {
-            result = OC_STACK_OK;
             request->observeResult = OC_STACK_ERROR;
             OIC_LOG(ERROR, TAG, "Observer Removal failed");
+            FindAndDeleteServerRequest(request);
+            goto exit;
         }
     }
     else
@@ -1242,8 +1335,11 @@ void DeleteDeviceInfo()
 
     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)
@@ -1265,6 +1361,45 @@ static OCStackResult DeepCopyDeviceInfo(OCDeviceInfo info)
             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;
 }