Update snapshot(2018-01-04)
[platform/upstream/iotivity.git] / resource / csdk / stack / src / ocserverrequest.c
index d46f889..91d7e1c 100644 (file)
@@ -22,6 +22,7 @@
 #include "ocstack.h"
 #include "ocserverrequest.h"
 #include "ocresourcehandler.h"
+#include "ocobserve.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
 #include "ocpayload.h"
@@ -35,8 +36,8 @@
 #include "cacommon.h"
 #include "cainterface.h"
 
-#include "utlist.h"
-#include "pdu.h"
+#include <coap/utlist.h>
+#include <coap/pdu.h>
 
 // Module Name
 #define VERIFY_NON_NULL(arg) { if (!arg) {OIC_LOG(FATAL, TAG, #arg " is NULL"); goto exit;} }
@@ -101,6 +102,7 @@ static void DeleteServerRequest(OCServerRequest * serverRequest)
     {
         LL_DELETE(serverRequestList, serverRequest);
         OICFree(serverRequest->requestToken);
+        OICFree(serverRequest->rcvdVendorSpecificHeaderOptions);
         OICFree(serverRequest);
         serverRequest = NULL;
         OIC_LOG(INFO, TAG, "Server Request Removed!!");
@@ -201,16 +203,20 @@ OCServerRequest * GetServerRequestUsingToken (const CAToken_t token, uint8_t tok
     OIC_LOG(INFO, TAG,"Get server request with token");
     OIC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength);
 
-    OIC_LOG(INFO, TAG,"Found token");
+    OIC_LOG(INFO, TAG, "Found token");
     LL_FOREACH (serverRequestList, out)
     {
-        OIC_LOG_BUFFER(INFO, TAG, (const uint8_t *)out->requestToken, tokenLength);
-        if(memcmp(out->requestToken, token, tokenLength) == 0)
+        if(out)
         {
-            return out;
+            OIC_LOG_BUFFER(INFO, TAG, (const uint8_t *)out->requestToken, out->tokenLength);
+            if((tokenLength == out->tokenLength) &&
+                memcmp(out->requestToken, token, tokenLength) == 0)
+            {
+                return out;
+            }
         }
     }
-    OIC_LOG(ERROR, TAG, "Server Request not found!!");
+    OIC_LOG(INFO, TAG, "Server Request not found!!");
     return NULL;
 }
 
@@ -221,12 +227,12 @@ OCServerRequest * GetServerRequestUsingToken (const CAToken_t token, uint8_t tok
  * @return
  *     OCServerRequest*
  */
-OCServerRequest * GetServerRequestUsingHandle (const OCServerRequest * handle)
+OCServerRequest * GetServerRequestUsingHandle (const OCRequestHandle handle)
 {
     OCServerRequest * out = NULL;
     LL_FOREACH (serverRequestList, out)
     {
-        if(out == handle)
+        if(out->requestId == handle)
         {
             return out;
         }
@@ -243,7 +249,7 @@ OCServerRequest * GetServerRequestUsingHandle (const OCServerRequest * handle)
  * @return
  *     OCServerResponse*
  */
-OCServerResponse * GetServerResponseUsingHandle (const OCServerRequest * handle)
+OCServerResponse * GetServerResponseUsingHandle (const OCRequestHandle handle)
 {
     OCServerResponse * out = NULL;
     LL_FOREACH (serverResponseList, out)
@@ -253,7 +259,7 @@ OCServerResponse * GetServerResponseUsingHandle (const OCServerRequest * handle)
             return out;
         }
     }
-    OIC_LOG(ERROR, TAG, "Server Response not found!!");
+    OIC_LOG(INFO, TAG, "Server Response not found!!");
     return NULL;
 }
 
@@ -292,6 +298,7 @@ OCStackResult AddServerRequest (OCServerRequest ** request, uint16_t coapID,
     serverRequest->acceptFormat = acceptFormat;
     serverRequest->ehResponseHandler = HandleSingleResponse;
     serverRequest->numResponses = 1;
+    serverRequest->requestId = OCGetRandom();
 
     if(query)
     {
@@ -300,12 +307,16 @@ OCStackResult AddServerRequest (OCServerRequest ** request, uint16_t coapID,
 
     if(rcvdVendorSpecificHeaderOptions)
     {
+        serverRequest->rcvdVendorSpecificHeaderOptions =
+                    (OCHeaderOption *) OICCalloc(numRcvdVendorSpecificHeaderOptions, sizeof(OCHeaderOption));
+        VERIFY_NON_NULL(serverRequest->rcvdVendorSpecificHeaderOptions);
+
         memcpy(serverRequest->rcvdVendorSpecificHeaderOptions, rcvdVendorSpecificHeaderOptions,
-            MAX_HEADER_OPTIONS * sizeof(OCHeaderOption));
+            numRcvdVendorSpecificHeaderOptions * sizeof(OCHeaderOption));
     }
     if(payload && reqTotalSize)
     {
-       // destination is at least 1 greater than the source, so a NULL always exists in the
+        // destination is at least 1 greater than the source, so a NULL always exists in the
         // last character
         memcpy(serverRequest->payload, payload, reqTotalSize);
         serverRequest->payloadSize = reqTotalSize;
@@ -314,15 +325,14 @@ OCStackResult AddServerRequest (OCServerRequest ** request, uint16_t coapID,
     serverRequest->requestComplete = 0;
     if(requestToken)
     {
-        // If tokenLength is zero, the return value depends on the
-        // particular library implementation (it may or may not be a null pointer).
+         // If tokenLength is zero, the return value depends on the
+         // particular library implementation (it may or may not be a null pointer).
         if (tokenLength)
         {
             serverRequest->requestToken = (CAToken_t) OICMalloc(tokenLength);
             VERIFY_NON_NULL(serverRequest->requestToken);
             memcpy(serverRequest->requestToken, requestToken, tokenLength);
         }
-
     }
     serverRequest->tokenLength = tokenLength;
 
@@ -342,6 +352,8 @@ OCStackResult AddServerRequest (OCServerRequest ** request, uint16_t coapID,
 exit:
     if (serverRequest)
     {
+        OICFree(serverRequest->requestToken);
+        OICFree(serverRequest->rcvdVendorSpecificHeaderOptions);
         OICFree(serverRequest);
         serverRequest = NULL;
     }
@@ -441,7 +453,9 @@ CAResponseResult_t ConvertEHResultToCAResult (OCEntityHandlerResult result, OCMe
         case OC_EH_SLOW: // 2.05
             caResult = CA_CONTENT;
             break;
-        case OC_EH_OK: // 2.04/2.05
+        case OC_EH_OK:
+        case OC_EH_CHANGED: // 2.04
+        case OC_EH_CONTENT: // 2.05
             if (method == OC_REST_POST || method == OC_REST_PUT)
             {
                 caResult = CA_CHANGED;
@@ -454,9 +468,6 @@ CAResponseResult_t ConvertEHResultToCAResult (OCEntityHandlerResult result, OCMe
         case OC_EH_VALID: // 2.03
             caResult = CA_VALID;
             break;
-        case OC_EH_CHANGED: // 2.04
-            caResult = CA_CHANGED;
-            break;
         // Unsuccessful Client Request
         case OC_EH_UNAUTHORIZED_REQ: // 4.01
             caResult = CA_UNAUTHORIZED_REQ;
@@ -479,9 +490,21 @@ CAResponseResult_t ConvertEHResultToCAResult (OCEntityHandlerResult result, OCMe
         case OC_EH_INTERNAL_SERVER_ERROR: // 5.00
             caResult = CA_INTERNAL_SERVER_ERROR;
             break;
+        case OC_EH_NOT_IMPLEMENTED: // 5.01
+            caResult = CA_NOT_IMPLEMENTED;
+            break;
+        case OC_EH_BAD_GATEWAY: // 5.02
+            caResult = CA_BAD_GATEWAY;
+            break;
+        case OC_EH_SERVICE_UNAVAILABLE: // 5.03
+            caResult = CA_SERVICE_UNAVAILABLE;
+            break;
         case OC_EH_RETRANSMIT_TIMEOUT: // 5.04
             caResult = CA_RETRANSMIT_TIMEOUT;
             break;
+        case OC_EH_PROXY_NOT_SUPPORTED: // 5.05
+            caResult = CA_PROXY_NOT_SUPPORTED;
+            break;
         default:
             caResult = CA_BAD_REQ;
             break;
@@ -511,13 +534,19 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse)
         return OC_STACK_ERROR;
     }
 
-    OCServerRequest *serverRequest = (OCServerRequest *)ehResponse->requestHandle;
+    OCServerRequest *serverRequest = GetServerRequestUsingHandle(ehResponse->requestHandle);
+    if (NULL == serverRequest)
+    {
+        OIC_LOG(ERROR, TAG, "No serverRequest matching with ehResponse");
+        return OC_STACK_ERROR;
+    }
 
     CopyDevAddrToEndpoint(&serverRequest->devAddr, &responseEndpoint);
 
     responseInfo.info.messageId = serverRequest->coapID;
     responseInfo.info.resourceUri = serverRequest->resourceUrl;
     responseInfo.result = ConvertEHResultToCAResult(ehResponse->ehResult, serverRequest->method);
+    responseInfo.info.dataType = CA_RESPONSE_DATA;
 
     if(serverRequest->notificationFlag && serverRequest->qos == OC_HIGH_QOS)
     {
@@ -556,8 +585,8 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse)
     memcpy(responseInfo.info.token, serverRequest->requestToken, serverRequest->tokenLength);
     responseInfo.info.tokenLength = serverRequest->tokenLength;
 
-    // De-register observe option should not be included in the response header
-    if((serverRequest->observeResult == OC_STACK_OK) && (serverRequest->observationOption != OC_OBSERVE_DEREGISTER))
+    if((serverRequest->observeResult == OC_STACK_OK)&&
+       (serverRequest->observationOption != MAX_SEQUENCE_NUMBER + 1))
     {
         responseInfo.info.numOptions = ehResponse->numSendVendorSpecificHeaderOptions + 1;
     }
@@ -620,11 +649,13 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse)
     // Put the JSON prefix and suffix around the payload
     if(ehResponse->payload)
     {
+#ifdef WITH_PRESENCE
         if (ehResponse->payload->type == PAYLOAD_TYPE_PRESENCE)
         {
             responseInfo.isMulticast = true;
         }
         else
+#endif
         {
             responseInfo.isMulticast = false;
         }
@@ -642,7 +673,7 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse)
                     OICFree(responseInfo.info.options);
                     return result;
                 }
-                //Add CONTENT_FORMAT OPT if payload exist
+                // Add CONTENT_FORMAT OPT if payload exist
                 if (responseInfo.info.payloadSize > 0)
                 {
                     responseInfo.info.payloadFormat = CA_FORMAT_APPLICATION_CBOR;
@@ -741,10 +772,8 @@ OCStackResult HandleAggregateResponse(OCEntityHandlerResponse * ehResponse)
 
     OIC_LOG(INFO, TAG, "Inside HandleAggregateResponse");
 
-    OCServerRequest *serverRequest = GetServerRequestUsingHandle((OCServerRequest *)
-                                                                 ehResponse->requestHandle);
-    OCServerResponse *serverResponse = GetServerResponseUsingHandle((OCServerRequest *)
-                                                                    ehResponse->requestHandle);
+    OCServerRequest *serverRequest = GetServerRequestUsingHandle(ehResponse->requestHandle);
+    OCServerResponse *serverResponse = GetServerResponseUsingHandle(ehResponse->requestHandle);
 
     OCStackResult stackRet = OC_STACK_ERROR;
     if(serverRequest)
@@ -768,7 +797,7 @@ OCStackResult HandleAggregateResponse(OCEntityHandlerResponse * ehResponse)
             goto exit;
         }
 
-        OCRepPayload *newPayload = OCRepPayloadClone((OCRepPayload *)ehResponse->payload);
+        OCRepPayload *newPayload = OCRepPayloadBatchClone((OCRepPayload *)ehResponse->payload);
 
         if(!serverResponse->payload)
         {
@@ -786,6 +815,7 @@ OCStackResult HandleAggregateResponse(OCEntityHandlerResponse * ehResponse)
         {
             OIC_LOG(INFO, TAG, "This is the last response fragment");
             ehResponse->payload = serverResponse->payload;
+            ehResponse->ehResult = OC_EH_OK;
             stackRet = HandleSingleResponse(ehResponse);
             //Delete the request and response
             FindAndDeleteServerRequest(serverRequest);
@@ -798,5 +828,6 @@ OCStackResult HandleAggregateResponse(OCEntityHandlerResponse * ehResponse)
         }
     }
 exit:
+
     return stackRet;
 }