Merge branch 'master' into cloud-interface
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / cablockwisetransfer.c
index dd3e1b5..140456a 100644 (file)
@@ -43,7 +43,7 @@
 #include "camutex.h"
 #include "logger.h"
 
-#define TAG "CA_BWT"
+#define TAG "OIC_CA_BWT"
 
 #define BLOCKWISE_OPTION_BUFFER    (sizeof(unsigned int))
 #define BLOCK_NUMBER_IDX           4
@@ -53,7 +53,9 @@
 #define BLOCK_SIZE(arg) (1 << ((arg) + 4))
 
 // context for block-wise transfer
-static CABlockWiseContext_t g_context = { 0 };
+static CABlockWiseContext_t g_context = { .sendThreadFunc = NULL,
+                                          .receivedThreadFunc = NULL,
+                                          .dataList = NULL };
 
 static bool CACheckPayloadLength(const CAData_t *sendData)
 {
@@ -62,7 +64,7 @@ static bool CACheckPayloadLength(const CAData_t *sendData)
 
     // check if message has to be transfered to a block
     size_t maxBlockSize = BLOCK_SIZE(CA_DEFAULT_BLOCK_SIZE);
-    OIC_LOG_V(DEBUG, TAG, "payloadLen=%d, maxBlockSize=%d", payloadLen, maxBlockSize);
+    OIC_LOG_V(DEBUG, TAG, "payloadLen=%zu, maxBlockSize=%zu", payloadLen, maxBlockSize);
 
     if (payloadLen <= maxBlockSize)
     {
@@ -309,9 +311,18 @@ CAResult_t CAReceiveBlockWiseData(coap_pdu_t *pdu, const CAEndpoint_t *endpoint,
                 endpoint->port);
         if(NULL == blockDataID || NULL == blockDataID->id || blockDataID->idLength < 1)
         {
-            OIC_LOG(ERROR, TAG, "blockId is null");
-            CADestroyBlockID(blockDataID);
-            return CA_STATUS_FAILED;
+            // if retransmission is timeout, callback msg will be send without token.
+            if (NULL == blockDataID && !receivedData->responseInfo->info.token)
+            {
+                OIC_LOG(INFO, TAG, "retransmission was stopped");
+                return CA_REQUEST_TIMEOUT;
+            }
+            else
+            {
+                OIC_LOG(ERROR, TAG, "blockId is null");
+                CADestroyBlockID(blockDataID);
+                return CA_STATUS_FAILED;
+            }
         }
 
         CARemoveBlockDataFromList(blockDataID);
@@ -914,7 +925,8 @@ CAResult_t CASetNextBlockOption1(coap_pdu_t *pdu, const CAEndpoint_t *endpoint,
                 return res;
             }
 
-            res = CAUpdateBlockOptionItems(data, pdu, &block, COAP_OPTION_BLOCK1, blockWiseStatus);
+            res = CAUpdateBlockOptionItems(data, pdu, &block, COAP_OPTION_BLOCK1,
+                                           blockWiseStatus);
             if (CA_STATUS_OK != res)
             {
                 OIC_LOG(ERROR, TAG, "update has failed");
@@ -1011,8 +1023,7 @@ CAResult_t CASetNextBlockOption2(coap_pdu_t *pdu, const CAEndpoint_t *endpoint,
     }
 
     // set Block Option Type
-    CAResult_t res = CAUpdateBlockOptionType(blockDataID,
-                                             COAP_OPTION_BLOCK2);
+    CAResult_t res = CAUpdateBlockOptionType(blockDataID, COAP_OPTION_BLOCK2);
     if (CA_STATUS_OK != res)
     {
         OIC_LOG(ERROR, TAG, "update has failed");
@@ -1408,7 +1419,7 @@ CAResult_t CAAddBlockOption(coap_pdu_t **pdu, const CAInfo_t *info,
     if (info->payload)
     {
         dataLength = info->payloadSize;
-        OIC_LOG_V(DEBUG, TAG, "dataLength - %d", dataLength);
+        OIC_LOG_V(DEBUG, TAG, "dataLength - %zu", dataLength);
     }
 
     OIC_LOG_V(DEBUG, TAG, "previous payload - %s", (*pdu)->data);
@@ -1516,10 +1527,8 @@ CAResult_t CAAddBlockOption2(coap_pdu_t **pdu, const CAInfo_t *info, size_t data
     VERIFY_NON_NULL(options, TAG, "options");
 
     // get set block data from CABlock list-set.
-    coap_block_t *block1 = CAGetBlockOption(blockID,
-                                            COAP_OPTION_BLOCK1);
-    coap_block_t *block2 = CAGetBlockOption(blockID,
-                                            COAP_OPTION_BLOCK2);
+    coap_block_t *block1 = CAGetBlockOption(blockID, COAP_OPTION_BLOCK1);
+    coap_block_t *block2 = CAGetBlockOption(blockID, COAP_OPTION_BLOCK2);
     if (!block1 || !block2)
     {
         OIC_LOG(ERROR, TAG, "getting has failed");
@@ -1528,34 +1537,17 @@ CAResult_t CAAddBlockOption2(coap_pdu_t **pdu, const CAInfo_t *info, size_t data
 
     CALogBlockInfo(block2);
 
-    uint8_t code = 0;
     if (CA_MSG_ACKNOWLEDGE == (*pdu)->hdr->coap_hdr_udp_t.type ||
             (CA_MSG_NONCONFIRM == (*pdu)->hdr->coap_hdr_udp_t.type &&
                     CA_GET != (*pdu)->hdr->coap_hdr_udp_t.code))
     {
-        int32_t res = coap_write_block_opt(block2, COAP_OPTION_BLOCK2, *pdu, dataLength);
-        switch (res)
-        {
-            case -2: /* illegal block */
-                code = COAP_RESPONSE_CODE(CA_BAD_REQ);
-                OIC_LOG(ERROR, TAG, "write block option : -2");
-                goto error;
-            case -1: /* should really not happen */
-                OIC_LOG(ERROR, TAG, "write block option : -1");
-                break;
-            case -3: /* cannot handle request */
-                code = COAP_RESPONSE_CODE(CA_INTERNAL_SERVER_ERROR);
-                OIC_LOG(ERROR, TAG, "write block option : -3");
-                goto error;
-            default:
-                OIC_LOG(INFO, TAG, "success write block option");
-        }
+        CAGetMoreBitFromBlock(dataLength, block2);
         CALogBlockInfo(block2);
 
         // if block number is 0, add size2 option
         if (0 == block2->num)
         {
-            res = CAAddBlockSizeOption(*pdu, COAP_OPTION_SIZE2, dataLength, options);
+            CAResult_t res = CAAddBlockSizeOption(*pdu, COAP_OPTION_SIZE2, dataLength, options);
             if (CA_STATUS_OK != res)
             {
                 OIC_LOG(ERROR, TAG, "add has failed");
@@ -1564,10 +1556,18 @@ CAResult_t CAAddBlockOption2(coap_pdu_t **pdu, const CAInfo_t *info, size_t data
             }
         }
 
+        CAResult_t res = CAAddBlockOptionImpl(block2, COAP_OPTION_BLOCK2, options);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "add has failed");
+            CARemoveBlockDataFromList(blockID);
+            return res;
+        }
+
         if (block1->num)
         {
             OIC_LOG(DEBUG, TAG, "combining block1 and block2");
-            CAResult_t res = CAAddBlockOptionImpl(*pdu, block1, COAP_OPTION_BLOCK1, options);
+            res = CAAddBlockOptionImpl(block1, COAP_OPTION_BLOCK1, options);
             if (CA_STATUS_OK != res)
             {
                 OIC_LOG(ERROR, TAG, "add has failed");
@@ -1578,6 +1578,14 @@ CAResult_t CAAddBlockOption2(coap_pdu_t **pdu, const CAInfo_t *info, size_t data
             block1->num = 0;
         }
 
+        res = CAAddOptionToPDU(*pdu, options);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "add has failed");
+            CARemoveBlockDataFromList(blockID);
+            return res;
+        }
+
         if (!coap_add_block(*pdu, dataLength, (const unsigned char *) info->payload,
                             block2->num, block2->szx))
         {
@@ -1612,7 +1620,15 @@ CAResult_t CAAddBlockOption2(coap_pdu_t **pdu, const CAInfo_t *info, size_t data
     else
     {
         OIC_LOG(DEBUG, TAG, "option2, not ACK msg");
-        CAResult_t res = CAAddBlockOptionImpl(*pdu, block2, COAP_OPTION_BLOCK2, options);
+        CAResult_t res = CAAddBlockOptionImpl(block2, COAP_OPTION_BLOCK2, options);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "add has failed");
+            CARemoveBlockDataFromList(blockID);
+            return res;
+        }
+
+        res = CAAddOptionToPDU(*pdu, options);
         if (CA_STATUS_OK != res)
         {
             OIC_LOG(ERROR, TAG, "add has failed");
@@ -1622,17 +1638,6 @@ CAResult_t CAAddBlockOption2(coap_pdu_t **pdu, const CAInfo_t *info, size_t data
     }
 
     return CA_STATUS_OK;
-
-error:
-    OIC_LOG_V(ERROR, TAG, "error : %d", code);
-
-    char* phrase = coap_response_phrase(code);
-    if(phrase)
-    {
-        coap_add_data(*pdu, strlen(phrase),
-                      (unsigned char *) phrase);
-    }
-    return CA_STATUS_FAILED;
 }
 
 CAResult_t CAAddBlockOption1(coap_pdu_t **pdu, const CAInfo_t *info, size_t dataLength,
@@ -1659,7 +1664,15 @@ CAResult_t CAAddBlockOption1(coap_pdu_t **pdu, const CAInfo_t *info, size_t data
     if (CA_MSG_ACKNOWLEDGE == (*pdu)->hdr->coap_hdr_udp_t.type)
     {
         OIC_LOG(DEBUG, TAG, "option1 and ACK msg..");
-        CAResult_t res = CAAddBlockOptionImpl(*pdu, block1, COAP_OPTION_BLOCK1, options);
+        CAResult_t res = CAAddBlockOptionImpl(block1, COAP_OPTION_BLOCK1, options);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "add has failed");
+            CARemoveBlockDataFromList(blockID);
+            return res;
+        }
+
+        res = CAAddOptionToPDU(*pdu, options);
         if (CA_STATUS_OK != res)
         {
             OIC_LOG(ERROR, TAG, "add has failed");
@@ -1702,13 +1715,22 @@ CAResult_t CAAddBlockOption1(coap_pdu_t **pdu, const CAInfo_t *info, size_t data
             }
         }
 
-        res = CAAddBlockOptionImpl(*pdu, block1, COAP_OPTION_BLOCK1, options);
+        res = CAAddBlockOptionImpl(block1, COAP_OPTION_BLOCK1, options);
         if (CA_STATUS_OK != res)
         {
             OIC_LOG(ERROR, TAG, "add has failed");
             CARemoveBlockDataFromList(blockID);
             return res;
         }
+
+        res = CAAddOptionToPDU(*pdu, options);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "add has failed");
+            CARemoveBlockDataFromList(blockID);
+            return res;
+        }
+
         CALogBlockInfo(block1);
 
         if (!coap_add_block(*pdu, dataLength, (const unsigned char *) info->payload,
@@ -1748,11 +1770,10 @@ CAResult_t CAAddBlockOption1(coap_pdu_t **pdu, const CAInfo_t *info, size_t data
     return CA_STATUS_OK;
 }
 
-CAResult_t CAAddBlockOptionImpl(coap_pdu_t *pdu, coap_block_t *block, uint8_t blockType,
+CAResult_t CAAddBlockOptionImpl(coap_block_t *block, uint8_t blockType,
                                 coap_list_t **options)
 {
     OIC_LOG(DEBUG, TAG, "IN-AddBlockOptionImpl");
-    VERIFY_NON_NULL(pdu, TAG, "pdu");
     VERIFY_NON_NULL(block, TAG, "block");
     VERIFY_NON_NULL(options, TAG, "options");
 
@@ -1770,6 +1791,12 @@ CAResult_t CAAddBlockOptionImpl(coap_pdu_t *pdu, coap_block_t *block, uint8_t bl
         return CA_STATUS_INVALID_PARAM;
     }
 
+    OIC_LOG(DEBUG, TAG, "OUT-AddBlockOptionImpl");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAAddOptionToPDU(coap_pdu_t *pdu, coap_list_t **options)
+{
     // after adding the block option to option list, add option list to pdu.
     if (*options)
     {
@@ -1779,15 +1806,18 @@ CAResult_t CAAddBlockOptionImpl(coap_pdu_t *pdu, coap_block_t *block, uint8_t bl
                       COAP_OPTION_DATA(*(coap_option *) opt->data));
 
             OIC_LOG_V(DEBUG, TAG, "[%d] pdu length", pdu->length);
-            coap_add_option(pdu, COAP_OPTION_KEY(*(coap_option *) opt->data),
-                            COAP_OPTION_LENGTH(*(coap_option *) opt->data),
-                            COAP_OPTION_DATA(*(coap_option *) opt->data), coap_udp);
+            int ret = coap_add_option(pdu, COAP_OPTION_KEY(*(coap_option *) opt->data),
+                                      COAP_OPTION_LENGTH(*(coap_option *) opt->data),
+                                      COAP_OPTION_DATA(*(coap_option *) opt->data), coap_udp);
+            if (!ret)
+            {
+                return CA_STATUS_FAILED;
+            }
         }
     }
 
     OIC_LOG_V(DEBUG, TAG, "[%d] pdu length after option", pdu->length);
 
-    OIC_LOG(DEBUG, TAG, "OUT-AddBlockOptionImpl");
     return CA_STATUS_OK;
 }
 
@@ -1843,7 +1873,7 @@ bool CAIsPayloadLengthInPduWithBlockSizeOption(coap_pdu_t *pdu,
         *totalPayloadLen = coap_decode_var_bytes(COAP_OPT_VALUE(option),
                                                  COAP_OPT_LENGTH(option));
 
-        OIC_LOG_V(DEBUG, TAG, "the total payload length to be received is [%d]bytes",
+        OIC_LOG_V(DEBUG, TAG, "the total payload length to be received is [%zu]bytes",
                   *totalPayloadLen);
 
         return true;
@@ -2031,7 +2061,7 @@ CAResult_t CAUpdatePayloadData(CABlockData_t *currData, const CAData_t *received
         // update received payload length
         currData->receivedPayloadLen += blockPayloadLen;
 
-        OIC_LOG_V(DEBUG, TAG, "updated payload: %s, len: %d", currData->payload,
+        OIC_LOG_V(DEBUG, TAG, "updated payload: %s, len: %zu", currData->payload,
                   currData->receivedPayloadLen);
     }
 
@@ -2658,8 +2688,6 @@ void CADestroyDataSet(CAData_t* data)
 CABlockDataID_t* CACreateBlockDatablockId(const CAToken_t token, uint8_t tokenLength,
                                           uint16_t portNumber)
 {
-    VERIFY_NON_NULL_RET(token, TAG, "token", NULL);
-
     char port[PORT_LENGTH] = {0,};
     port[0] = (char)((portNumber>>8) & 0xFF);
     port[1] = (char)(portNumber & 0xFF);
@@ -2679,7 +2707,11 @@ CABlockDataID_t* CACreateBlockDatablockId(const CAToken_t token, uint8_t tokenLe
         return NULL;
     }
 
-    memcpy(blockDataID->id, token, tokenLength);
+    if (token)
+    {
+        memcpy(blockDataID->id, token, tokenLength);
+    }
+
     memcpy(blockDataID->id + tokenLength, port, sizeof(port));
 
     OIC_LOG(DEBUG, TAG, "BlockID is ");