Update snapshot(2017-12-20)
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / tcp_adapter / catcpserver.c
index 8551650..7741e68 100644 (file)
@@ -75,6 +75,8 @@
  */
 #define MAX_CONNECTION_COUNTS   500
 
+#define COAP_TCP_MAX_BUFFER_CHUNK_SIZE 65530 //64kb - 6 (coap+tcp max header size)
+
 /**
  * Thread pool.
  */
@@ -386,6 +388,7 @@ void CACleanData(CATCPSessionInfo_t *svritem)
         svritem->tlsLen = 0;
 #endif
         svritem->totalLen = 0;
+        svritem->bufLen = 0;
         svritem->protocol = UNKNOWN;
     }
 }
@@ -426,6 +429,7 @@ CAResult_t CAConstructCoAP(CATCPSessionInfo_t *svritem, unsigned char **data,
         // copy 1 byte to parse coap header length
         memcpy(svritem->data, inBuffer, 1);
         svritem->len = 1;
+        svritem->bufLen = COAP_MAX_HEADER_SIZE;
         inBuffer++;
         inLen--;
     }
@@ -470,28 +474,41 @@ CAResult_t CAConstructCoAP(CATCPSessionInfo_t *svritem, unsigned char **data,
 
         //calculate CoAP message length
         svritem->totalLen = CAGetTotalLengthFromHeader(svritem->data);
-
-        // allocate required memory
-        unsigned char *buffer = OICRealloc(svritem->data, svritem->totalLen);
-        if (NULL == buffer)
-        {
-            OIC_LOG(ERROR, TAG, "OICRealloc - out of memory");
-            return CA_MEMORY_ALLOC_FAILED;
-        }
-        svritem->data = buffer;
     }
 
     // PAYLOAD
     if (inLen > 0)
     {
-        // read required bytes to have full CoAP payload
+        // Calculate length of data to be copied.
         copyLen = svritem->totalLen - svritem->len;
         if (inLen < copyLen)
         {
             copyLen = inLen;
         }
 
-        //read required bytes to have full CoAP header
+        // Is buffer not big enough for remaining data ?
+        if (svritem->len + copyLen > svritem->bufLen)
+        {
+            // Resize buffer to accommodate enough space
+            size_t extLen = svritem->totalLen - svritem->bufLen;
+            if (extLen > COAP_TCP_MAX_BUFFER_CHUNK_SIZE)
+            {
+                extLen = COAP_TCP_MAX_BUFFER_CHUNK_SIZE;
+            }
+
+            // Allocate required memory
+            unsigned char *buffer = OICRealloc(svritem->data, svritem->bufLen + extLen);
+            if (NULL == buffer)
+            {
+                OIC_LOG(ERROR, TAG, "OICRealloc - out of memory");
+                return CA_MEMORY_ALLOC_FAILED;
+            }
+
+            svritem->data = buffer;
+            svritem->bufLen += extLen;
+        }
+
+        // Read required bytes to have full CoAP payload
         memcpy(svritem->data + svritem->len, inBuffer, copyLen);
         svritem->len += copyLen;
         inBuffer += copyLen;