#include "caremotehandler.h"
#include "cablockwisetransfer.h"
#include "oic_malloc.h"
-#include "camutex.h"
+#include "oic_string.h"
+#include "octhread.h"
#include "logger.h"
+#include "oic_time.h"
-#define TAG "CA_BWT"
+#define TAG "OIC_CA_BWT"
#define BLOCKWISE_OPTION_BUFFER (sizeof(unsigned int))
#define BLOCK_NUMBER_IDX 4
#define BLOCK_SIZE(arg) (1 << ((arg) + 4))
+#define BLOCK_DATA_TIMEOUT_SECONDS (60 * 1) // 1 minutes.
+static const uint64_t USECS_PER_SEC = 1000000;
+
// 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)
{
// 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)
{
CAResult_t CAInitializeBlockWiseTransfer(CASendThreadFunc sendThreadFunc,
CAReceiveThreadFunc receivedThreadFunc)
{
- OIC_LOG(DEBUG, TAG, "initialize");
+ OIC_LOG(DEBUG, TAG, "CAInitializeBlockWiseTransfer");
// set block-wise transfer context
if (!g_context.sendThreadFunc)
CAResult_t res = CAInitBlockWiseMutexVariables();
if (CA_STATUS_OK != res)
{
+ u_arraylist_free(&g_context.dataList);
+ g_context.dataList = NULL;
OIC_LOG(ERROR, TAG, "init has failed");
}
CAResult_t CATerminateBlockWiseTransfer()
{
- OIC_LOG(DEBUG, TAG, "terminate");
+ OIC_LOG(DEBUG, TAG, "CATerminateBlockWiseTransfer");
if (g_context.dataList)
{
+ CARemoveAllBlockDataFromList();
u_arraylist_free(&g_context.dataList);
}
CAResult_t CAInitBlockWiseMutexVariables()
{
- OIC_LOG(DEBUG, TAG, "IN");
-
if (!g_context.blockDataListMutex)
{
- g_context.blockDataListMutex = ca_mutex_new();
+ g_context.blockDataListMutex = oc_mutex_new();
if (!g_context.blockDataListMutex)
{
- OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+ OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
return CA_STATUS_FAILED;
}
}
if (!g_context.blockDataSenderMutex)
{
- g_context.blockDataSenderMutex = ca_mutex_new();
+ g_context.blockDataSenderMutex = oc_mutex_new();
if (!g_context.blockDataSenderMutex)
{
- OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+ OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
CATerminateBlockWiseMutexVariables();
return CA_STATUS_FAILED;
}
void CATerminateBlockWiseMutexVariables()
{
- OIC_LOG(DEBUG, TAG, "IN");
-
if (g_context.blockDataListMutex)
{
- ca_mutex_free(g_context.blockDataListMutex);
+ oc_mutex_free(g_context.blockDataListMutex);
g_context.blockDataListMutex = NULL;
}
if (g_context.blockDataSenderMutex)
{
- ca_mutex_free(g_context.blockDataSenderMutex);
+ oc_mutex_free(g_context.blockDataSenderMutex);
g_context.blockDataSenderMutex = NULL;
}
}
VERIFY_NON_NULL(sendData, TAG, "sendData");
// check if message type is CA_MSG_RESET
- if (sendData->responseInfo)
+ if (sendData->requestInfo)
+ {
+ if (CA_MSG_RESET == sendData->requestInfo->info.type)
+ {
+ OIC_LOG(DEBUG, TAG, "reset message can't be sent to the block");
+ return CA_NOT_SUPPORTED;
+ }
+
+ /*
+ * Other uses of the Block options in conjunction with multicast
+ * messages are for further study.
+ */
+ if (sendData->requestInfo->isMulticast)
+ {
+ OIC_LOG(DEBUG, TAG, "multicast message can't be sent to the block");
+ return CA_NOT_SUPPORTED;
+ }
+ }
+ else if (sendData->responseInfo)
{
if (CA_MSG_RESET == sendData->responseInfo->info.type)
{
OIC_LOG(DEBUG, TAG, "reset message can't be sent to the block");
return CA_NOT_SUPPORTED;
}
+ if (sendData->responseInfo->isMulticast)
+ {
+ OIC_LOG(DEBUG, TAG, "multicast message can't be sent to the block");
+ return CA_NOT_SUPPORTED;
+ }
}
// #1. check if it is already included in block data list
// #4. send block message
OIC_LOG(DEBUG, TAG, "send first block msg");
res = CAAddSendThreadQueue(currData->sentData,
- (const CABlockDataID_t *)&currData->blockDataId);
+ (const CABlockDataID_t *) &currData->blockDataId);
if (CA_STATUS_OK != res)
{
OIC_LOG(ERROR, TAG, "add has failed");
if (g_context.sendThreadFunc)
{
- ca_mutex_lock(g_context.blockDataSenderMutex);
+ oc_mutex_lock(g_context.blockDataSenderMutex);
g_context.sendThreadFunc(cloneData);
- ca_mutex_unlock(g_context.blockDataSenderMutex);
+ oc_mutex_unlock(g_context.blockDataSenderMutex);
}
else
{
{
OIC_LOG(DEBUG, TAG, "CAReceiveBlockWiseData");
VERIFY_NON_NULL(pdu, TAG, "pdu");
- VERIFY_NON_NULL(pdu->hdr, TAG, "pdu->hdr");
+ VERIFY_NON_NULL(pdu->transport_hdr, TAG, "pdu->transport_hdr");
VERIFY_NON_NULL(endpoint, TAG, "endpoint");
VERIFY_NON_NULL(receivedData, TAG, "receivedData");
// check if received message type is CA_MSG_RESET
- if (CA_EMPTY == pdu->hdr->coap_hdr_udp_t.code)
+ if (CA_EMPTY == pdu->transport_hdr->udp.code)
{
OIC_LOG(DEBUG, TAG, "code is CA_EMPTY..");
- // get token from block-wise transfer list when CA_EMPTY(RST/ACK) is received
- CAResult_t res = CAGetTokenFromBlockDataList(pdu, endpoint, receivedData->responseInfo);
- if (CA_STATUS_OK != res)
+ if (!receivedData->responseInfo->info.token)
{
- OIC_LOG(ERROR, TAG, "fail to get token");
- return res;
+ // get token from block-wise transfer list when CA_EMPTY(RST/ACK) is received
+ CAResult_t res = CAGetTokenFromBlockDataList(pdu, endpoint,
+ receivedData->responseInfo);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "fail to get token");
+ return res;
+ }
}
CABlockDataID_t* blockDataID = CACreateBlockDatablockId(
receivedData->responseInfo->info.token,
receivedData->responseInfo->info.tokenLength,
endpoint->port);
- if(NULL == blockDataID || NULL == blockDataID->id || blockDataID->idLength < 1)
+ if (NULL == blockDataID || blockDataID->idLength < 1)
{
+ // 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;
+ }
+
OIC_LOG(ERROR, TAG, "blockId is null");
CADestroyBlockID(blockDataID);
return CA_STATUS_FAILED;
}
+ // If we didn't send the last block message and received EMPTY message,
+ // we have to remain the block data from list.
+ CABlockData_t *data = CAGetBlockDataFromBlockDataList(blockDataID);
+ if (data && (data->block1.m || data->block2.m))
+ {
+ OIC_LOG(DEBUG, TAG, "this is normal EMPTY message for blockwise-transfer.");
+ CADestroyBlockID(blockDataID);
+ return CA_STATUS_OK;
+ }
+
CARemoveBlockDataFromList(blockDataID);
CADestroyBlockID(blockDataID);
return CA_NOT_SUPPORTED;
}
// check if block option is set and get block data
- coap_block_t block = {0, 0, 0};
+ coap_block_t block = { 0, 0, 0 };
// get block1 option
int isBlock1 = coap_get_block(pdu, COAP_OPTION_BLOCK1, &block);
}
}
- // check if there is error code
+ // if there is no block option in pdu, check if there is error code.
if (!isBlock1 && !isBlock2)
{
- uint32_t code = CA_RESPONSE_CODE(pdu->hdr->coap_hdr_udp_t.code);
- if (CA_REQUEST_ENTITY_INCOMPLETE == code)
+ CABlockDataID_t* blockDataID = CACreateBlockDatablockId(
+ (CAToken_t)pdu->transport_hdr->udp.token,
+ pdu->transport_hdr->udp.token_length,
+ endpoint->port);
+ if (NULL == blockDataID || blockDataID->idLength < 1)
{
- CABlockDataID_t* blockDataID = CACreateBlockDatablockId(
- (CAToken_t)pdu->hdr->coap_hdr_udp_t.token,
- pdu->hdr->coap_hdr_udp_t.token_length,
- endpoint->port);
+ OIC_LOG(ERROR, TAG, "blockId is null");
+ CADestroyBlockID(blockDataID);
+ return CA_STATUS_FAILED;
+ }
- if(NULL == blockDataID || NULL == blockDataID->id || blockDataID->idLength < 1)
+ uint32_t code = CA_RESPONSE_CODE(pdu->transport_hdr->udp.code);
+ if (CA_REQUEST_ENTITY_INCOMPLETE == code)
+ {
+ CABlockData_t *data = CAGetBlockDataFromBlockDataList(blockDataID);
+ if (!data)
{
- OIC_LOG(ERROR, TAG, "blockId is null");
+ OIC_LOG(ERROR, TAG, "getting has failed");
CADestroyBlockID(blockDataID);
return CA_STATUS_FAILED;
}
- CABlockData_t *data = CAGetBlockDataFromBlockDataList(blockDataID);
- if (!data)
+ coap_block_t *block = CAGetBlockOption(blockDataID, data->type);
+ if (!block)
{
- OIC_LOG(ERROR, TAG, "getting has failed");
+ OIC_LOG(ERROR, TAG, "block is null");
CADestroyBlockID(blockDataID);
return CA_STATUS_FAILED;
}
+ CAResult_t res = CA_STATUS_OK;
if (COAP_OPTION_BLOCK2 == data->type)
{
- coap_block_t *block2 = CAGetBlockOption(blockDataID, COAP_OPTION_BLOCK2);
- if (!block2)
- {
- OIC_LOG(ERROR, TAG, "block is null");
- CADestroyBlockID(blockDataID);
- return CA_STATUS_FAILED;
- }
-
- CAResult_t res = CASetNextBlockOption2(pdu, endpoint, receivedData, *block2,
- dataLen);
+ res = CASetNextBlockOption2(pdu, endpoint, receivedData, *block, dataLen);
if (CA_STATUS_OK != res)
{
OIC_LOG(ERROR, TAG, "setting has failed");
CADestroyBlockID(blockDataID);
- return res;
+ return CA_STATUS_FAILED;
}
}
else if (COAP_OPTION_BLOCK1 == data->type)
{
- coap_block_t *block1 = CAGetBlockOption(blockDataID, COAP_OPTION_BLOCK1);
- if (!block1)
- {
- OIC_LOG(ERROR, TAG, "block is null");
- CADestroyBlockID(blockDataID);
- return CA_STATUS_FAILED;
- }
-
- CAResult_t res = CASetNextBlockOption1(pdu, endpoint, receivedData, *block1,
- dataLen);
+ res = CASetNextBlockOption1(pdu, endpoint, receivedData, *block, dataLen);
if (CA_STATUS_OK != res)
{
OIC_LOG(ERROR, TAG, "setting has failed");
return res;
}
}
+ CADestroyBlockID(blockDataID);
}
else
{
// and sent data remain in block data list, remove block data
if (receivedData->responseInfo)
{
- CABlockDataID_t* blockDataID = CACreateBlockDatablockId(
- (CAToken_t)pdu->hdr->coap_hdr_udp_t.token,
- pdu->hdr->coap_hdr_udp_t.token_length,
- endpoint->port);
- if(NULL == blockDataID || NULL == blockDataID->id || blockDataID->idLength < 1)
- {
- OIC_LOG(ERROR, TAG, "blockId is null");
- CADestroyBlockID(blockDataID);
- return CA_STATUS_FAILED;
- }
-
CARemoveBlockDataFromList(blockDataID);
- CADestroyBlockID(blockDataID);
}
+ CADestroyBlockID(blockDataID);
return CA_NOT_SUPPORTED;
}
}
-
return CA_STATUS_OK;
}
}
break;
- case CA_OPTION2_CON:
+ case CA_OPTION2_REQUEST:
// add data to send thread
data = CAGetDataSetFromBlockDataList(blockID);
if (!data)
return CA_STATUS_FAILED;
}
- if (data->requestInfo)
- {
- data->requestInfo->info.messageId = pdu->hdr->coap_hdr_udp_t.id;
- }
-
if (data->responseInfo)
{
- data->responseInfo->info.messageId = pdu->hdr->coap_hdr_udp_t.id;
- }
+ data->responseInfo->info.type =
+ (pdu->transport_hdr->udp.type == CA_MSG_CONFIRM) ?
+ CA_MSG_ACKNOWLEDGE : CA_MSG_NONCONFIRM;
+ data->responseInfo->info.messageId = pdu->transport_hdr->udp.id;
- res = CAAddSendThreadQueue(data, blockID);
- if (CA_STATUS_OK != res)
- {
- OIC_LOG(ERROR, TAG, "add has failed");
- return res;
+ res = CAAddSendThreadQueue(data, blockID);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "add has failed");
+ return res;
+ }
}
-
break;
- case CA_OPTION1_ACK:
- case CA_OPTION2_ACK:
- case CA_SENT_PREVIOUS_NON_MSG:
- res = CASendBlockMessage(pdu, CA_MSG_CONFIRM, blockWiseStatus,
- blockID);
+ case CA_OPTION1_RESPONSE:
+ case CA_OPTION2_RESPONSE:
+ case CA_OPTION1_REQUEST_BLOCK:
+ res = CASendBlockMessage(pdu, pdu->transport_hdr->udp.type, blockID);
if (CA_STATUS_OK != res)
{
OIC_LOG(ERROR, TAG, "send has failed");
}
break;
- case CA_OPTION1_NO_ACK_LAST_BLOCK:
+ case CA_OPTION1_REQUEST_LAST_BLOCK:
// process last block and send upper layer
res = CAReceiveLastBlock(blockID, receivedData);
if (CA_STATUS_OK != res)
OIC_LOG(ERROR, TAG, "receive has failed");
return res;
}
-
- if (CA_MSG_NONCONFIRM == pdu->hdr->coap_hdr_udp_t.type)
- {
- // remove data from list
- res = CARemoveBlockDataFromList(blockID);
- if (CA_STATUS_OK != res)
- {
- OIC_LOG(ERROR, TAG, "remove has failed");
- return res;
- }
- }
- break;
-
- case CA_OPTION1_NO_ACK_BLOCK:
- if (CA_MSG_CONFIRM == pdu->hdr->coap_hdr_udp_t.type)
- {
- // add data to send thread
- res = CASendBlockMessage(pdu, CA_MSG_ACKNOWLEDGE, blockWiseStatus,
- blockID);
- if (CA_STATUS_OK != res)
- {
- OIC_LOG(ERROR, TAG, "send has failed");
- return res;
- }
- }
break;
case CA_BLOCK_INCOMPLETE:
- if (CA_MSG_CONFIRM == pdu->hdr->coap_hdr_udp_t.type ||
- CA_MSG_ACKNOWLEDGE == pdu->hdr->coap_hdr_udp_t.type)
+ // add data to send thread
+ res = CASendErrorMessage(pdu, blockWiseStatus, CA_REQUEST_ENTITY_INCOMPLETE, blockID);
+ if (CA_STATUS_OK != res)
{
- // add data to send thread
- res = CASendErrorMessage(pdu, blockWiseStatus,
- CA_REQUEST_ENTITY_INCOMPLETE,
- blockID);
- if (CA_STATUS_OK != res)
- {
- OIC_LOG(ERROR, TAG, "send has failed");
- return res;
- }
+ OIC_LOG(ERROR, TAG, "send has failed");
+ return res;
}
break;
case CA_BLOCK_TOO_LARGE:
- if (CA_MSG_ACKNOWLEDGE == pdu->hdr->coap_hdr_udp_t.type)
+ if (receivedData->requestInfo)
{
- res = CASendBlockMessage(pdu, CA_MSG_CONFIRM, blockWiseStatus,
+ res = CASendErrorMessage(pdu, blockWiseStatus, CA_REQUEST_ENTITY_TOO_LARGE,
blockID);
if (CA_STATUS_OK != res)
{
return res;
}
}
- else if (CA_MSG_CONFIRM == pdu->hdr->coap_hdr_udp_t.type)
+ else if (receivedData->responseInfo)
{
- res = CASendErrorMessage(pdu, blockWiseStatus,
- CA_REQUEST_ENTITY_TOO_LARGE,
- blockID);
+ res = CASendBlockMessage(pdu, pdu->transport_hdr->udp.type, blockID);
if (CA_STATUS_OK != res)
{
OIC_LOG(ERROR, TAG, "send has failed");
return CA_STATUS_OK;
}
+static CAResult_t CASendDirectEmptyResponse(const CAEndpoint_t *endpoint, uint16_t messageId)
+{
+ OIC_LOG(DEBUG, TAG, "Entering CASendDirectEmptyResponse");
+ CAResponseInfo_t respInfo = {
+ .result = CA_EMPTY
+ };
+ respInfo.info.type = CA_MSG_ACKNOWLEDGE;
+ respInfo.info.messageId = messageId;
+ respInfo.info.dataType = CA_RESPONSE_DATA;
+
+ CAResult_t caResult = CASendResponse(endpoint, &respInfo);
+
+ OIC_LOG(DEBUG, TAG, "Exit CASendDirectEmptyResponse");
+ return caResult;
+}
+
CAResult_t CASendBlockMessage(const coap_pdu_t *pdu, CAMessageType_t msgType,
- uint8_t status, const CABlockDataID_t *blockID)
+ const CABlockDataID_t *blockID)
{
VERIFY_NON_NULL(pdu, TAG, "pdu");
- VERIFY_NON_NULL(pdu->hdr, TAG, "pdu->hdr");
+ VERIFY_NON_NULL(pdu->transport_hdr, TAG, "pdu->transport_hdr");
VERIFY_NON_NULL(blockID, TAG, "blockID");
CAData_t *data = CAGetDataSetFromBlockDataList(blockID);
return CA_STATUS_FAILED;
}
- if (CA_MSG_CONFIRM == msgType)
+ CAMessageType_t sentMsgType = CA_MSG_NONCONFIRM;
+ switch (msgType)
{
- OIC_LOG(DEBUG, TAG, "need new msgID");
- if (data->requestInfo)
- {
- data->requestInfo->info.messageId = 0;
- }
+ case CA_MSG_CONFIRM:
+ sentMsgType = CA_MSG_ACKNOWLEDGE;
+ break;
+ case CA_MSG_ACKNOWLEDGE:
+ sentMsgType = CA_MSG_CONFIRM;
+ break;
+ default:
+ sentMsgType = CA_MSG_NONCONFIRM;
+ break;
+ }
+ uint32_t code = pdu->transport_hdr->udp.code;
+ if (CA_GET == code || CA_POST == code || CA_PUT == code || CA_DELETE == code)
+ {
if (data->responseInfo)
{
- data->responseInfo->info.messageId = 0;
+ OIC_LOG(DEBUG, TAG, "set response info");
+ data->responseInfo->info.messageId = pdu->transport_hdr->udp.id;
+ data->responseInfo->info.type = sentMsgType;
+ data->responseInfo->result = CA_CONTINUE;
}
}
- else if (CA_MSG_ACKNOWLEDGE == msgType)
+ else
{
- if (data->responseInfo)
+ if (data->requestInfo)
{
- OIC_LOG(DEBUG, TAG, "set ACK message");
- data->responseInfo->info.messageId = pdu->hdr->coap_hdr_udp_t.id;
- data->responseInfo->info.type = CA_MSG_ACKNOWLEDGE;
- if (CA_OPTION1_NO_ACK_LAST_BLOCK == status)
- {
- data->responseInfo->result = CA_CHANGED;
- }
- else if (CA_OPTION1_NO_ACK_BLOCK == status)
+ // if the received response message type is CON, send empty message.
+ // and then, send next block request message with new messagId.
+ if (msgType == CA_MSG_CONFIRM)
{
- data->responseInfo->result = CA_CONTINUE;
+ CASendDirectEmptyResponse(data->remoteEndpoint,
+ data->requestInfo->info.messageId);
+ sentMsgType = CA_MSG_CONFIRM;
}
+
+ OIC_LOG(DEBUG, TAG, "need new msgID");
+ data->requestInfo->info.messageId = 0;
+ data->requestInfo->info.type = sentMsgType;
+ }
+ else if (data->responseInfo)
+ {
+ data->responseInfo->info.messageId = pdu->transport_hdr->udp.id;
+ data->responseInfo->info.type = sentMsgType;
}
}
}
CAResult_t CASendErrorMessage(const coap_pdu_t *pdu, uint8_t status,
- CAResponseResult_t responseResult,
- const CABlockDataID_t *blockID)
+ CAResponseResult_t responseResult, const CABlockDataID_t *blockID)
{
VERIFY_NON_NULL(pdu, TAG, "pdu");
- VERIFY_NON_NULL(pdu->hdr, TAG, "pdu->hdr");
+ VERIFY_NON_NULL(pdu->transport_hdr, TAG, "pdu->transport_hdr");
VERIFY_NON_NULL(blockID, TAG, "blockID");
// create error responseInfo
return CA_STATUS_FAILED;
}
- CAData_t *cloneData = NULL;
- if (data->sentData && data->sentData->responseInfo)
+ if (!data->sentData)
+ {
+ OIC_LOG(ERROR, TAG, "data has no sent-data");
+ return CA_STATUS_FAILED;
+ }
+
+ CAData_t *cloneData = CACloneCAData(data->sentData);
+ if (!cloneData)
+ {
+ OIC_LOG(ERROR, TAG, "clone has failed");
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+
+ CAMessageType_t sentMsgType = CA_MSG_NONCONFIRM;
+ switch (pdu->transport_hdr->udp.type)
+ {
+ case CA_MSG_CONFIRM:
+ sentMsgType = CA_MSG_ACKNOWLEDGE;
+ break;
+ case CA_MSG_ACKNOWLEDGE:
+ sentMsgType = CA_MSG_CONFIRM;
+ break;
+ default:
+ sentMsgType = CA_MSG_NONCONFIRM;
+ }
+
+ if (cloneData->responseInfo)
{
- data->sentData->responseInfo->info.messageId = pdu->hdr->coap_hdr_udp_t.id;
- data->sentData->responseInfo->info.type = CA_MSG_ACKNOWLEDGE;
- data->sentData->responseInfo->result = responseResult;
- cloneData = CACloneCAData(data->sentData);
- if (!cloneData)
+ cloneData->responseInfo->info.messageId = pdu->transport_hdr->udp.id;
+ cloneData->responseInfo->info.type = sentMsgType;
+ cloneData->responseInfo->result = responseResult;
+ }
+ else
+ {
+ CAInfo_t responseData = { .tokenLength = pdu->transport_hdr->udp.token_length };
+ responseData.token = (CAToken_t) OICMalloc(responseData.tokenLength);
+ if (!responseData.token)
{
- OIC_LOG(ERROR, TAG, "clone has failed");
+ OIC_LOG(ERROR, TAG, "out of memory");
+ CADestroyDataSet(cloneData);
return CA_MEMORY_ALLOC_FAILED;
}
- OIC_LOG(DEBUG, TAG, "set ACK message");
- }
- else if (data->sentData)
- {
- cloneData = CACreateNewDataSet(pdu, data->sentData->remoteEndpoint);
- if(!cloneData)
+ memcpy(responseData.token, pdu->transport_hdr->udp.token, responseData.tokenLength);
+
+ cloneData->responseInfo = (CAResponseInfo_t*) OICCalloc(1, sizeof(CAResponseInfo_t));
+ if (!cloneData->responseInfo)
{
- OIC_LOG(ERROR, TAG, PCF("CACreateNewDataSet failed"));
+ OIC_LOG(ERROR, TAG, "out of memory");
+ CADestroyDataSet(cloneData);
+ OICFree(responseData.token);
return CA_MEMORY_ALLOC_FAILED;
}
- cloneData->responseInfo->info.type = CA_MSG_CONFIRM;
+ cloneData->responseInfo->info = responseData;
+ cloneData->responseInfo->info.type = sentMsgType;
cloneData->responseInfo->result = responseResult;
- OIC_LOG(DEBUG, TAG, "set CON message");
}
- else
+
+ OIC_LOG(DEBUG, TAG, "set response message to send error code");
+
+ // if there is a requestInfo, remove it to send response message
+ if (cloneData->requestInfo)
{
- OIC_LOG(ERROR, TAG, "data has no sent-data");
- return CA_MEMORY_ALLOC_FAILED;
+ CADestroyRequestInfoInternal(cloneData->requestInfo);
+ cloneData->requestInfo = NULL;
}
// add data to send thread
if (g_context.sendThreadFunc)
{
- ca_mutex_lock(g_context.blockDataSenderMutex);
+ oc_mutex_lock(g_context.blockDataSenderMutex);
g_context.sendThreadFunc(cloneData);
- ca_mutex_unlock(g_context.blockDataSenderMutex);
+ oc_mutex_unlock(g_context.blockDataSenderMutex);
}
else
{
return CA_STATUS_OK;
}
-CAResult_t CAReceiveLastBlock(const CABlockDataID_t *blockID,
- const CAData_t *receivedData)
+CAResult_t CAReceiveLastBlock(const CABlockDataID_t *blockID, const CAData_t *receivedData)
{
VERIFY_NON_NULL(blockID, TAG, "blockID");
VERIFY_NON_NULL(receivedData, TAG, "receivedData");
// update payload
size_t fullPayloadLen = 0;
- CAPayload_t fullPayload = CAGetPayloadFromBlockDataList(blockID,
- &fullPayloadLen);
+ CAPayload_t fullPayload = CAGetPayloadFromBlockDataList(blockID, &fullPayloadLen);
if (fullPayload)
{
CAResult_t res = CAUpdatePayloadToCAData(cloneData, fullPayload, fullPayloadLen);
return CA_STATUS_OK;
}
+static CABlockData_t* CACheckTheExistOfBlockData(const CABlockDataID_t* blockDataID,
+ coap_pdu_t *pdu, const CAEndpoint_t *endpoint,
+ uint8_t blockType)
+{
+ // Get BlockData data. If does not exist, create a new data
+ CABlockData_t *data = CAGetBlockDataFromBlockDataList(blockDataID);
+ if (!data)
+ {
+ OIC_LOG(DEBUG, TAG, "block data doesn't exist in list. create new one");
+
+ CAData_t *cadata = CACreateNewDataSet(pdu, endpoint);
+ if (!cadata)
+ {
+ OIC_LOG(ERROR, TAG, "data is null");
+ return NULL;
+ }
+
+ data = CACreateNewBlockData(cadata);
+ if (!data)
+ {
+ OIC_LOG(ERROR, TAG, "failed to create a new block data");
+ CADestroyDataSet(cadata);
+ return NULL;
+ }
+ CADestroyDataSet(cadata);
+ }
+
+ // update BLOCK OPTION type
+ CAResult_t res = CAUpdateBlockOptionType(blockDataID, blockType);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "update has failed");
+ return NULL;
+ }
+
+ return data;
+}
+
// TODO make pdu const after libcoap is updated to support that.
CAResult_t CASetNextBlockOption1(coap_pdu_t *pdu, const CAEndpoint_t *endpoint,
const CAData_t *receivedData, coap_block_t block,
{
OIC_LOG(INFO, TAG, "CASetNextBlockOption1");
VERIFY_NON_NULL(pdu, TAG, "pdu");
- VERIFY_NON_NULL(pdu->hdr, TAG, "pdu->hdr");
+ VERIFY_NON_NULL(pdu->transport_hdr, TAG, "pdu->transport_hdr");
VERIFY_NON_NULL(endpoint, TAG, "endpoint");
VERIFY_NON_NULL(receivedData, TAG, "receivedData");
OIC_LOG_V(INFO, TAG, "num:%d, M:%d, sze:%d", block.num, block.m, block.szx);
CABlockDataID_t* blockDataID = CACreateBlockDatablockId(
- (CAToken_t)pdu->hdr->coap_hdr_udp_t.token,
- pdu->hdr->coap_hdr_udp_t.token_length,
+ (CAToken_t)pdu->transport_hdr->udp.token,
+ pdu->transport_hdr->udp.token_length,
endpoint->port);
-
- if(NULL == blockDataID || NULL == blockDataID->id || blockDataID->idLength < 1)
+ if (NULL == blockDataID || blockDataID->idLength < 1)
{
OIC_LOG(ERROR, TAG, "blockId is null");
CADestroyBlockID(blockDataID);
return CA_STATUS_FAILED;
}
- // BlockData data is created if it not existed
- if (!CAIsBlockDataInList(blockDataID))
- {
- OIC_LOG(DEBUG, TAG, "no message in list");
-
- CAData_t *data = CACreateNewDataSet(pdu, endpoint);
- if (!data)
- {
- OIC_LOG(ERROR, TAG, "data is null");
- CADestroyBlockID(blockDataID);
- return CA_STATUS_FAILED;
- }
-
- CABlockData_t *currData = CACreateNewBlockData(data);
- if (!currData)
- {
- OIC_LOG(ERROR, TAG, "currData is null");
- CADestroyDataSet(data);
- CADestroyBlockID(blockDataID);
- return CA_STATUS_FAILED;
- }
- CADestroyDataSet(data);
- }
-
- // update BLOCK OPTION1 type
- CAResult_t res = CAUpdateBlockOptionType(blockDataID,
- COAP_OPTION_BLOCK1);
- if (CA_STATUS_OK != res)
- {
- OIC_LOG(ERROR, TAG, "update has failed");
- CARemoveBlockDataFromList(blockDataID);
- CADestroyBlockID(blockDataID);
- return res;
- }
-
- CABlockData_t *data = CAGetBlockDataFromBlockDataList(blockDataID);
+ CAResult_t res = CA_STATUS_OK;
+ CABlockData_t *data = CACheckTheExistOfBlockData(blockDataID, pdu, endpoint,
+ COAP_OPTION_BLOCK1);
if (!data)
{
- OIC_LOG(ERROR, TAG, "getting has failed");
- CADestroyBlockID(blockDataID);
- return CA_STATUS_FAILED;
+ OIC_LOG(ERROR, TAG, "Failed to create or get block data");
+ res = CA_STATUS_FAILED;
+ goto exit;
}
uint8_t blockWiseStatus = CA_BLOCK_UNKNOWN;
- // received type from remote device
- if (CA_MSG_ACKNOWLEDGE == pdu->hdr->coap_hdr_udp_t.type)
- {
- uint32_t code = CA_RESPONSE_CODE(pdu->hdr->coap_hdr_udp_t.code);
- if (0 == block.m &&
- (CA_REQUEST_ENTITY_INCOMPLETE != code && CA_REQUEST_ENTITY_TOO_LARGE != code))
- {
- OIC_LOG(INFO, TAG, "Data has sent");
- // initialize block number for response message
- data->block1.num = 0;
- CADestroyBlockID(blockDataID);
- return CA_STATUS_OK;
- }
-
- blockWiseStatus = CA_OPTION1_ACK;
- res = CAUpdateBlockOptionItems(data, pdu, &block, COAP_OPTION_BLOCK1, blockWiseStatus);
- if (CA_STATUS_OK != res)
- {
- OIC_LOG(ERROR, TAG, "update has failed");
- CADestroyBlockID(blockDataID);
- return res;
- }
-
- res = CAUpdateBlockData(data, block, COAP_OPTION_BLOCK1);
- if (CA_STATUS_OK != res)
- {
- OIC_LOG(ERROR, TAG, "update has failed");
- CARemoveBlockDataFromList(blockDataID);
- CADestroyBlockID(blockDataID);
- return res;
- }
- }
- else // CON or NON message
+ uint32_t code = pdu->transport_hdr->udp.code;
+ if (CA_GET == code || CA_POST == code || CA_PUT == code || CA_DELETE == code)
{
+ // received message type is request
OIC_LOG_V(INFO, TAG, "num:%d, M:%d", block.num, block.m);
// check the size option
- bool isSizeOption = CAIsPayloadLengthInPduWithBlockSizeOption(pdu,
- COAP_OPTION_SIZE1,
+ bool isSizeOption = CAIsPayloadLengthInPduWithBlockSizeOption(pdu, COAP_OPTION_SIZE1,
&(data->payloadLength));
- // check if received payload is exact
- if (CA_MSG_CONFIRM == pdu->hdr->coap_hdr_udp_t.type)
- {
- blockWiseStatus = CACheckBlockErrorType(data, &block, receivedData,
- COAP_OPTION_BLOCK1, dataLen);
- }
+ blockWiseStatus = CACheckBlockErrorType(data, &block, receivedData,
+ COAP_OPTION_BLOCK1, dataLen);
if (CA_BLOCK_RECEIVED_ALREADY != blockWiseStatus)
{
if (CA_STATUS_OK != res)
{
OIC_LOG(ERROR, TAG, "update has failed");
- CARemoveBlockDataFromList(blockDataID);
- CADestroyBlockID(blockDataID);
- return res;
+ goto exit;
}
- 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");
- CARemoveBlockDataFromList(blockDataID);
- CADestroyBlockID(blockDataID);
- return res;
+ goto exit;
}
// update block data
if (CA_STATUS_OK != res)
{
OIC_LOG(ERROR, TAG, "update has failed");
- CARemoveBlockDataFromList(blockDataID);
- CADestroyBlockID(blockDataID);
- return res;
+ goto exit;
}
}
// check the blcok-wise transfer status for next step
if (CA_BLOCK_UNKNOWN == blockWiseStatus || CA_BLOCK_RECEIVED_ALREADY == blockWiseStatus)
{
- if (0 == block.m) // Last block is received
+ OIC_LOG_V(DEBUG, TAG, "M bit is %d", block.m);
+
+ blockWiseStatus = (0 == block.m) ?
+ CA_OPTION1_REQUEST_LAST_BLOCK : CA_OPTION1_REQUEST_BLOCK;
+ }
+ }
+ else
+ {
+ // received message type is response
+ uint32_t code = CA_RESPONSE_CODE(pdu->transport_hdr->udp.code);
+ if (0 == block.m && (CA_REQUEST_ENTITY_INCOMPLETE != code
+ && CA_REQUEST_ENTITY_TOO_LARGE != code))
+ {
+ int isBlock2 = coap_get_block(pdu, COAP_OPTION_BLOCK2, &block);
+ if (isBlock2)
{
- OIC_LOG(DEBUG, TAG, "M bit is 0");
- blockWiseStatus = CA_OPTION1_NO_ACK_LAST_BLOCK;
+ OIC_LOG(INFO, TAG, "received data is combining block1 and block2");
+ // initialize block number for response message
+ data->block1.num = 0;
+ CADestroyBlockID(blockDataID);
+ return CA_STATUS_OK;
}
else
{
- OIC_LOG(DEBUG, TAG, "M bit is 1");
- blockWiseStatus = CA_OPTION1_NO_ACK_BLOCK;
+ OIC_LOG(INFO, TAG, "received data is not bulk data");
+ CAReceiveLastBlock(blockDataID, receivedData);
+ res = CA_STATUS_OK;
+ goto exit;
}
}
+
+ blockWiseStatus = CA_OPTION1_RESPONSE;
+ res = CAUpdateBlockOptionItems(data, pdu, &block, COAP_OPTION_BLOCK1, blockWiseStatus);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "update has failed");
+ CADestroyBlockID(blockDataID);
+ return res;
+ }
+
+ res = CAUpdateBlockData(data, block, COAP_OPTION_BLOCK1);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "update has failed");
+ goto exit;
+ }
}
res = CAProcessNextStep(pdu, receivedData, blockWiseStatus, blockDataID);
if (CA_STATUS_OK != res)
{
OIC_LOG(ERROR, TAG, "setting has failed");
- CARemoveBlockDataFromList(blockDataID);
+ goto exit;
}
CADestroyBlockID(blockDataID);
return res;
+
+exit:
+ CARemoveBlockDataFromList(blockDataID);
+ CADestroyBlockID(blockDataID);
+ return res;
}
// TODO make pdu const after libcoap is updated to support that.
OIC_LOG_V(INFO, TAG, "num:%d, M:%d, sze:%d", block.num, block.m, block.szx);
VERIFY_NON_NULL(pdu, TAG, "pdu");
- VERIFY_NON_NULL(pdu->hdr, TAG, "pdu->hdr");
+ VERIFY_NON_NULL(pdu->transport_hdr, TAG, "pdu->transport_hdr");
VERIFY_NON_NULL(endpoint, TAG, "endpoint");
VERIFY_NON_NULL(receivedData, TAG, "receivedData");
CABlockDataID_t* blockDataID = CACreateBlockDatablockId(
- (CAToken_t)pdu->hdr->coap_hdr_udp_t.token,
- pdu->hdr->coap_hdr_udp_t.token_length,
+ (CAToken_t)pdu->transport_hdr->udp.token,
+ pdu->transport_hdr->udp.token_length,
endpoint->port);
-
- if(NULL == blockDataID || NULL == blockDataID->id || blockDataID->idLength < 1)
+ if (NULL == blockDataID || blockDataID->idLength < 1)
{
OIC_LOG(ERROR, TAG, "blockId is null");
CADestroyBlockID(blockDataID);
return CA_STATUS_FAILED;
}
- // BlockData data is created if it not existed
- if (!CAIsBlockDataInList(blockDataID))
- {
- OIC_LOG(DEBUG, TAG, "no msg in list.");
-
- CAData_t *data = CACreateNewDataSet(pdu, endpoint);
- if (!data)
- {
- OIC_LOG(ERROR, TAG, "data is null");
- CADestroyBlockID(blockDataID);
- return CA_STATUS_FAILED;
- }
-
- CABlockData_t *currData = CACreateNewBlockData(data);
- if (!currData)
- {
- OIC_LOG(ERROR, TAG, "data is null");
- CADestroyDataSet(data);
- CADestroyBlockID(blockDataID);
- return CA_STATUS_FAILED;
- }
- CADestroyDataSet(data);
- }
-
- // set Block Option Type
- CAResult_t res = CAUpdateBlockOptionType(blockDataID,
- COAP_OPTION_BLOCK2);
- if (CA_STATUS_OK != res)
- {
- OIC_LOG(ERROR, TAG, "update has failed");
- CARemoveBlockDataFromList(blockDataID);
- CADestroyBlockID(blockDataID);
- return res;
- }
-
- CABlockData_t *data = CAGetBlockDataFromBlockDataList(blockDataID);
+ CAResult_t res = CA_STATUS_OK;
+ CABlockData_t *data = CACheckTheExistOfBlockData(blockDataID, pdu, endpoint,
+ COAP_OPTION_BLOCK2);
if (!data)
{
- OIC_LOG(ERROR, TAG, "getting has failed");
- CARemoveBlockDataFromList(blockDataID);
- CADestroyBlockID(blockDataID);
- return CA_STATUS_FAILED;
+ OIC_LOG(ERROR, TAG, "Failed to create or get block data");
+ res = CA_STATUS_FAILED;
+ goto exit;
}
uint8_t blockWiseStatus = CA_BLOCK_UNKNOWN;
- if (0 == block.num && CA_GET == pdu->hdr->coap_hdr_udp_t.code && 0 == block.m)
+ if (0 == block.num && CA_GET == pdu->transport_hdr->udp.code && 0 == block.m)
{
OIC_LOG(INFO, TAG, "first block number");
if (CA_STATUS_OK != res)
{
OIC_LOG(ERROR, TAG, "update has failed");
- CARemoveBlockDataFromList(blockDataID);
- CADestroyBlockID(blockDataID);
- return res;
+ goto exit;
}
// first block data have to notify to Application
if (CA_STATUS_OK != res)
{
OIC_LOG(ERROR, TAG, "update has failed");
- CARemoveBlockDataFromList(blockDataID);
- CADestroyBlockID(blockDataID);
- return res;
+ goto exit;
}
blockWiseStatus = CA_OPTION2_FIRST_BLOCK;
}
else
{
- // received type from remote device
- if (CA_MSG_ACKNOWLEDGE == pdu->hdr->coap_hdr_udp_t.type ||
- (CA_MSG_NONCONFIRM == pdu->hdr->coap_hdr_udp_t.type &&
- NULL != receivedData->responseInfo))
+ uint32_t code = pdu->transport_hdr->udp.code;
+ if (CA_GET == code || CA_POST == code || CA_PUT == code || CA_DELETE == code)
{
- OIC_LOG(DEBUG, TAG, "received ACK or NON");
+ // received message type is request
+ OIC_LOG_V(INFO, TAG, "num:%d, M:%d", block.num, block.m);
+
+ blockWiseStatus = CA_OPTION2_REQUEST;
+
+ res = CAUpdateBlockOptionItems(data, pdu, &block, COAP_OPTION_BLOCK2, blockWiseStatus);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "update has failed");
+ goto exit;
+ }
+
+ res = CAUpdateBlockData(data, block, COAP_OPTION_BLOCK2);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "update has failed");
+ goto exit;
+ }
+ }
+ else
+ {
+ // received message type is response
+ OIC_LOG(DEBUG, TAG, "received response message with block option2");
// check the size option
bool isSizeOption = CAIsPayloadLengthInPduWithBlockSizeOption(pdu,
COAP_OPTION_SIZE2,
&(data->payloadLength));
- // check if received payload is exact
- if (CA_MSG_ACKNOWLEDGE == pdu->hdr->coap_hdr_udp_t.type)
+ uint32_t code = CA_RESPONSE_CODE(pdu->transport_hdr->udp.code);
+ if (CA_REQUEST_ENTITY_INCOMPLETE != code && CA_REQUEST_ENTITY_TOO_LARGE != code)
{
+ // check if received payload is exact
blockWiseStatus = CACheckBlockErrorType(data, &block, receivedData,
COAP_OPTION_BLOCK2, dataLen);
}
if (CA_STATUS_OK != res)
{
OIC_LOG(ERROR, TAG, "update has failed");
- CARemoveBlockDataFromList(blockDataID);
- CADestroyBlockID(blockDataID);
- return res;
+ goto exit;
}
}
CA_BLOCK_RECEIVED_ALREADY == blockWiseStatus)
{
OIC_LOG(DEBUG, TAG, "M bit is 1");
-
- if (CA_MSG_ACKNOWLEDGE == pdu->hdr->coap_hdr_udp_t.type)
- {
- blockWiseStatus = CA_OPTION2_ACK;
- }
- else
- {
- blockWiseStatus = CA_OPTION2_NON;
- }
+ blockWiseStatus = CA_OPTION2_RESPONSE;
}
res = CAUpdateBlockOptionItems(data, pdu, &block, COAP_OPTION_BLOCK2,
if (CA_STATUS_OK != res)
{
OIC_LOG(ERROR, TAG, "update has failed");
- CARemoveBlockDataFromList(blockDataID);
- CADestroyBlockID(blockDataID);
- return res;
+ goto exit;
}
res = CAUpdateBlockData(data, block, COAP_OPTION_BLOCK2);
if (CA_STATUS_OK != res)
{
OIC_LOG(ERROR, TAG, "update has failed");
- CARemoveBlockDataFromList(blockDataID);
- CADestroyBlockID(blockDataID);
- return res;
+ goto exit;
}
}
}
- else // CON message and so on.
- {
- OIC_LOG_V(INFO, TAG, "num:%d, M:%d", block.num, block.m);
-
- blockWiseStatus = CA_OPTION2_CON;
-
- res = CAUpdateBlockOptionItems(data, pdu, &block, COAP_OPTION_BLOCK2, blockWiseStatus);
- if (CA_STATUS_OK != res)
- {
- OIC_LOG(ERROR, TAG, "update has failed");
- CARemoveBlockDataFromList(blockDataID);
- CADestroyBlockID(blockDataID);
- return res;
- }
-
- res = CAUpdateBlockData(data, block, COAP_OPTION_BLOCK2);
- if (CA_STATUS_OK != res)
- {
- OIC_LOG(ERROR, TAG, "update has failed");
- CARemoveBlockDataFromList(blockDataID);
- CADestroyBlockID(blockDataID);
- return res;
- }
- }
}
res = CAProcessNextStep(pdu, receivedData, blockWiseStatus, blockDataID);
if (CA_STATUS_OK != res)
{
OIC_LOG(ERROR, TAG, "setting has failed");
- CARemoveBlockDataFromList(blockDataID);
- CADestroyBlockID(blockDataID);
- return res;
+ goto exit;
}
CADestroyBlockID(blockDataID);
return CA_STATUS_OK;
+
+exit:
+ CARemoveBlockDataFromList(blockDataID);
+ CADestroyBlockID(blockDataID);
+ return res;
}
CAResult_t CAUpdateBlockOptionItems(CABlockData_t *currData, const coap_pdu_t *pdu,
// update block data
CAResult_t res = CA_STATUS_OK;
- uint32_t code = CA_RESPONSE_CODE(pdu->hdr->coap_hdr_udp_t.code);
+ uint32_t code = CA_RESPONSE_CODE(pdu->transport_hdr->udp.code);
if (CA_REQUEST_ENTITY_INCOMPLETE == code || CA_REQUEST_ENTITY_TOO_LARGE == code)
{
// update block option items
switch (status)
{
- case CA_OPTION1_ACK:
+ case CA_OPTION1_RESPONSE:
if (currData->block1.num > block->num)
{
OIC_LOG(ERROR, TAG, "received incorrect block num");
}
block->num++;
break;
- case CA_OPTION2_NON:
- block->num++;
- block->m = 0;
- break;
- case CA_OPTION2_CON:
+ case CA_OPTION2_REQUEST:
block->m = 0;
break;
- case CA_OPTION2_ACK:
+ case CA_OPTION2_RESPONSE:
if (currData->block2.num > block->num)
{
OIC_LOG(ERROR, TAG, "received incorrect block num");
if (CA_BLOCK_INCOMPLETE != status && CA_BLOCK_TOO_LARGE != status)
{
// negotiate block size
- res = CANegotiateBlockSize(currData, block, pdu->hdr->coap_hdr_udp_t.type, blockType);
+ res = CANegotiateBlockSize(currData, block, pdu, blockType);
if (CA_STATUS_OK != res)
{
OIC_LOG(ERROR, TAG, "negotiation has failed");
return res;
}
-CAResult_t CAGetMoreBitFromBlock(size_t payloadLen, coap_block_t *block)
+CAResult_t CASetMoreBitFromBlock(size_t payloadLen, coap_block_t *block)
{
VERIFY_NON_NULL(block, TAG, "block");
- if ((size_t)((block->num + 1) << (block->szx + BLOCK_NUMBER_IDX))
- < payloadLen)
+ if ((size_t) ((block->num + 1) << (block->szx + BLOCK_NUMBER_IDX)) < payloadLen)
{
OIC_LOG(DEBUG, TAG, "Set the M-bit(1)");
block->m = 1;
}
CAResult_t CANegotiateBlockSize(CABlockData_t *currData, coap_block_t *block,
- CAMessageType_t msgType, uint16_t blockType)
+ const coap_pdu_t *pdu, uint16_t blockType)
{
OIC_LOG(DEBUG, TAG, "IN-NegotiateBlockSize");
VERIFY_NON_NULL(currData, TAG, "currData");
VERIFY_NON_NULL(block, TAG, "block");
+ VERIFY_NON_NULL(pdu, TAG, "pdu");
+ VERIFY_NON_NULL(pdu->transport_hdr, TAG, "pdu->transport_hdr");
+
+ bool isReqMsg = false;
+ uint32_t code = pdu->transport_hdr->udp.code;
+ if (CA_GET == code || CA_POST == code || CA_PUT == code || CA_DELETE == code)
+ {
+ isReqMsg = true;
+ }
// #1. check the block option type
if (COAP_OPTION_BLOCK2 == blockType)
{
// #2. check the message type
- if (CA_MSG_ACKNOWLEDGE == msgType)
+ if (!isReqMsg)
{
if (block->szx > currData->block2.szx)
{
}
else if (COAP_OPTION_BLOCK1 == blockType)
{
- if (CA_MSG_ACKNOWLEDGE == msgType)
+ if (!isReqMsg)
{
if (block->szx < currData->block1.szx)
{
CAResult_t CAUpdateMessageId(coap_pdu_t *pdu, const CABlockDataID_t *blockID)
{
VERIFY_NON_NULL(pdu, TAG, "pdu");
+ VERIFY_NON_NULL(pdu->transport_hdr, TAG, "pdu->transport_hdr");
VERIFY_NON_NULL(blockID, TAG, "blockID");
- // if CON message is sent, update messageId in block-wise transfer list
- if (CA_MSG_CONFIRM == pdu->hdr->coap_hdr_udp_t.type)
+ // if message is sent, update messageId in block-wise transfer list
+ CAData_t * cadata = CAGetDataSetFromBlockDataList(blockID);
+ if (!cadata)
{
- CAData_t * cadata = CAGetDataSetFromBlockDataList(blockID);
- if (!cadata)
- {
- OIC_LOG(ERROR, TAG, "CAData is unavailable");
- return CA_STATUS_FAILED;
- }
+ OIC_LOG(ERROR, TAG, "CAData is unavailable");
+ return CA_STATUS_FAILED;
+ }
- if (cadata->requestInfo)
- {
- cadata->requestInfo->info.messageId = pdu->hdr->coap_hdr_udp_t.id;
- }
+ if (cadata->requestInfo)
+ {
+ cadata->requestInfo->info.messageId = pdu->transport_hdr->udp.id;
}
return CA_STATUS_OK;
}
CAResult_t CAAddBlockOption(coap_pdu_t **pdu, const CAInfo_t *info,
- const CAEndpoint_t *endpoint)
+ const CAEndpoint_t *endpoint, coap_list_t **options)
{
OIC_LOG(DEBUG, TAG, "IN-AddBlockOption");
VERIFY_NON_NULL(pdu, TAG, "pdu");
VERIFY_NON_NULL((*pdu), TAG, "(*pdu)");
- VERIFY_NON_NULL((*pdu)->hdr, TAG, "(*pdu)->hdr");
+ VERIFY_NON_NULL((*pdu)->transport_hdr, TAG, "(*pdu)->transport_hdr");
VERIFY_NON_NULL(info, TAG, "info");
VERIFY_NON_NULL(endpoint, TAG, "endpoint");
+ VERIFY_NON_NULL(options, TAG, "options");
+ CAResult_t res = CA_STATUS_OK;
size_t dataLength = 0;
if (info->payload)
{
dataLength = info->payloadSize;
- OIC_LOG_V(DEBUG, TAG, "dataLength - %d", dataLength);
- }
-
- OIC_LOG_V(DEBUG, TAG, "previous payload - %s", (*pdu)->data);
-
- uint32_t code = CA_RESPONSE_CODE((*pdu)->hdr->coap_hdr_udp_t.code);
- if (CA_REQUEST_ENTITY_INCOMPLETE == code)
- {
- OIC_LOG(INFO, TAG, "don't use option");
- return CA_STATUS_OK;
+ OIC_LOG_V(DEBUG, TAG, "dataLength - %zu", dataLength);
}
CABlockDataID_t* blockDataID = CACreateBlockDatablockId(
- (CAToken_t)(*pdu)->hdr->coap_hdr_udp_t.token,
- (*pdu)->hdr->coap_hdr_udp_t.token_length,
+ (CAToken_t)(*pdu)->transport_hdr->udp.token,
+ (*pdu)->transport_hdr->udp.token_length,
endpoint->port);
-
- if(NULL == blockDataID || NULL == blockDataID->id || blockDataID->idLength < 1)
+ if (NULL == blockDataID || blockDataID->idLength < 1)
{
OIC_LOG(ERROR, TAG, "blockId is null");
- CADestroyBlockID(blockDataID);
- return CA_STATUS_FAILED;
+ res = CA_STATUS_FAILED;
+ goto exit;
+ }
+
+ uint32_t repCode = CA_RESPONSE_CODE((*pdu)->transport_hdr->udp.code);
+ if (CA_REQUEST_ENTITY_INCOMPLETE == repCode)
+ {
+ OIC_LOG(INFO, TAG, "don't use option");
+ res = CA_STATUS_OK;
+ goto exit;
}
uint8_t blockType = CAGetBlockOptionType(blockDataID);
if (COAP_OPTION_BLOCK2 == blockType)
{
- CAResult_t res = CAAddBlockOption2(pdu, info, dataLength,
- blockDataID);
+ res = CAAddBlockOption2(pdu, info, dataLength, blockDataID, options);
if (CA_STATUS_OK != res)
{
OIC_LOG(ERROR, TAG, "add has failed");
- CADestroyBlockID(blockDataID);
- return res;
+ goto exit;
}
}
else if (COAP_OPTION_BLOCK1 == blockType)
{
- CAResult_t res = CAAddBlockOption1(pdu, info, dataLength,
- blockDataID);
+ res = CAAddBlockOption1(pdu, info, dataLength, blockDataID, options);
if (CA_STATUS_OK != res)
{
OIC_LOG(ERROR, TAG, "add has failed");
- CADestroyBlockID(blockDataID);
- return res;
+ goto exit;
}
}
else
{
OIC_LOG(DEBUG, TAG, "no BLOCK option");
+
+ // in case it is not large data, add option list to pdu.
+ if (*options)
+ {
+ for (coap_list_t *opt = *options; opt; opt = opt->next)
+ {
+ OIC_LOG_V(DEBUG, TAG, "[%s] opt will be added.",
+ COAP_OPTION_DATA(*(coap_option *) opt->data));
+ OIC_LOG_V(DEBUG, TAG, "[%d] pdu length", (*pdu)->length);
+
+ if (0 == 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)))
+ {
+ OIC_LOG(ERROR, TAG, "coap_add_option has failed");
+ res = CA_STATUS_FAILED;
+ goto exit;
+ }
+ }
+ }
+ OIC_LOG_V(DEBUG, TAG, "[%d] pdu length after option", (*pdu)->length);
+
// if response data is so large. it have to send as block transfer
if (!coap_add_data(*pdu, dataLength, (const unsigned char *) info->payload))
{
- OIC_LOG(INFO, TAG, "it have to use block");
+ OIC_LOG(INFO, TAG, "it has to use block");
+ res = CA_STATUS_FAILED;
+ goto exit;
}
else
{
OIC_LOG(INFO, TAG, "not Blockwise Transfer");
- CADestroyBlockID(blockDataID);
- return CA_STATUS_OK;
}
}
- CAResult_t res = CAUpdateMessageId(*pdu, blockDataID);
- if (CA_STATUS_OK != res)
+ uint32_t code = (*pdu)->transport_hdr->udp.code;
+ if (CA_GET == code || CA_POST == code || CA_PUT == code || CA_DELETE == code)
{
- OIC_LOG(ERROR, TAG, "fail to update CON message id ");
- CADestroyBlockID(blockDataID);
- return res;
+ // if received message type is RESET from remote device,
+ // we have to use the updated message id of request message to find token.
+ CABlockData_t *blockData = CAGetBlockDataFromBlockDataList(blockDataID);
+ if (blockData)
+ {
+ res = CAUpdateMessageId(*pdu, blockDataID);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "fail to update message id");
+ goto exit;
+ }
+ }
}
+ CAResetBlockDataTTL(blockDataID);
+exit:
CADestroyBlockID(blockDataID);
OIC_LOG(DEBUG, TAG, "OUT-AddBlockOption");
- return CA_STATUS_OK;
+ return res;
}
CAResult_t CAAddBlockOption2(coap_pdu_t **pdu, const CAInfo_t *info, size_t dataLength,
- const CABlockDataID_t *blockID)
+ const CABlockDataID_t *blockID, coap_list_t **options)
{
OIC_LOG(DEBUG, TAG, "IN-AddBlockOption2");
VERIFY_NON_NULL(pdu, TAG, "pdu");
VERIFY_NON_NULL((*pdu), TAG, "(*pdu)");
- VERIFY_NON_NULL((*pdu)->hdr, TAG, "(*pdu)->hdr");
+ VERIFY_NON_NULL((*pdu)->transport_hdr, TAG, "(*pdu)->transport_hdr");
VERIFY_NON_NULL(info, TAG, "info");
VERIFY_NON_NULL(blockID, TAG, "blockID");
+ 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");
return CA_STATUS_FAILED;
}
- 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))
+ CAResult_t res = CA_STATUS_OK;
+ uint32_t code = (*pdu)->transport_hdr->udp.code;
+ if (CA_GET != code && CA_POST != code && CA_PUT != code && CA_DELETE != code)
{
- int32_t res = coap_write_block_opt(block2, COAP_OPTION_BLOCK2, *pdu, dataLength);
- switch (res)
+ CASetMoreBitFromBlock(dataLength, block2);
+
+ // if block number is 0, add size2 option
+ if (0 == block2->num)
{
- 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");
+ res = CAAddBlockSizeOption(*pdu, COAP_OPTION_SIZE2, dataLength, options);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "add has failed");
+ goto exit;
+ }
+ }
+
+ res = CAAddBlockOptionImpl(block2, COAP_OPTION_BLOCK2, options);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "add has failed");
+ goto exit;
}
- CALogBlockInfo(block2);
if (block1->num)
{
OIC_LOG(DEBUG, TAG, "combining block1 and block2");
- CAResult_t res = CAAddBlockOptionImpl(*pdu, block1, COAP_OPTION_BLOCK1);
+ res = CAAddBlockOptionImpl(block1, COAP_OPTION_BLOCK1, options);
if (CA_STATUS_OK != res)
{
OIC_LOG(ERROR, TAG, "add has failed");
- CARemoveBlockDataFromList(blockID);
- return res;
+ goto exit;
}
// initialize block number
block1->num = 0;
}
- // if block number is 0, add size2 option
- if (0 == block2->num)
+ res = CAAddOptionToPDU(*pdu, options);
+ if (CA_STATUS_OK != res)
{
- res = CAAddBlockSizeOption(*pdu, COAP_OPTION_SIZE2, dataLength);
- if (CA_STATUS_OK != res)
- {
- OIC_LOG(ERROR, TAG, "add has failed");
- CARemoveBlockDataFromList(blockID);
- return res;
- }
+ OIC_LOG(ERROR, TAG, "add has failed");
+ goto exit;
}
if (!coap_add_block(*pdu, dataLength, (const unsigned char *) info->payload,
return CA_STATUS_FAILED;
}
+ CALogBlockInfo(block2);
+
if (!block2->m)
{
// if sent message is last response block message, remove data
CARemoveBlockDataFromList(blockID);
}
- else
- {
- if (CA_MSG_NONCONFIRM == (*pdu)->hdr->coap_hdr_udp_t.type)
- {
- OIC_LOG(DEBUG, TAG, "NON, send next block..");
- // update block data
- block2->num++;
- CAResult_t res = CAProcessNextStep(*pdu, NULL,
- CA_SENT_PREVIOUS_NON_MSG,
- blockID);
- if (CA_STATUS_OK != res)
- {
- OIC_LOG(ERROR, TAG, "failed to process next step");
- CARemoveBlockDataFromList(blockID);
- return res;
- }
- }
- }
}
else
{
- OIC_LOG(DEBUG, TAG, "option2, not ACK msg");
- CAResult_t res = CAAddBlockOptionImpl(*pdu, block2, COAP_OPTION_BLOCK2);
+ OIC_LOG(DEBUG, TAG, "option2, not response msg");
+ res = CAAddBlockOptionImpl(block2, COAP_OPTION_BLOCK2, options);
if (CA_STATUS_OK != res)
{
OIC_LOG(ERROR, TAG, "add has failed");
- CARemoveBlockDataFromList(blockID);
- return res;
+ goto exit;
+ }
+
+ res = CAAddOptionToPDU(*pdu, options);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "add has failed");
+ goto exit;
}
+ CALogBlockInfo(block2);
}
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;
+exit:
+ CARemoveBlockDataFromList(blockID);
+ return res;
}
CAResult_t CAAddBlockOption1(coap_pdu_t **pdu, const CAInfo_t *info, size_t dataLength,
- const CABlockDataID_t *blockID)
+ const CABlockDataID_t *blockID, coap_list_t **options)
{
OIC_LOG(DEBUG, TAG, "IN-AddBlockOption1");
VERIFY_NON_NULL(pdu, TAG, "pdu");
VERIFY_NON_NULL((*pdu), TAG, "(*pdu)");
- VERIFY_NON_NULL((*pdu)->hdr, TAG, "(*pdu)->hdr");
+ VERIFY_NON_NULL((*pdu)->transport_hdr, TAG, "(*pdu)->transport_hdr");
VERIFY_NON_NULL(info, TAG, "info");
VERIFY_NON_NULL(blockID, TAG, "blockID");
+ VERIFY_NON_NULL(options, TAG, "options");
// get set block data from CABlock list-set.
coap_block_t *block1 = CAGetBlockOption(blockID, COAP_OPTION_BLOCK1);
return CA_STATUS_FAILED;
}
- CALogBlockInfo(block1);
+ CAResult_t res = CA_STATUS_OK;
+ uint32_t code = (*pdu)->transport_hdr->udp.code;
+ if (CA_GET == code || CA_POST == code || CA_PUT == code || CA_DELETE == code)
+ {
+ CASetMoreBitFromBlock(dataLength, block1);
+
+ // if block number is 0, add size1 option
+ if (0 == block1->num)
+ {
+ res = CAAddBlockSizeOption(*pdu, COAP_OPTION_SIZE1, dataLength, options);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "add has failed");
+ goto exit;
+ }
+ }
+
+ // add block option to option list.
+ res = CAAddBlockOptionImpl(block1, COAP_OPTION_BLOCK1, options);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "add has failed");
+ goto exit;
+ }
- 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);
+ // add option list to pdu.
+ res = CAAddOptionToPDU(*pdu, options);
if (CA_STATUS_OK != res)
{
OIC_LOG(ERROR, TAG, "add has failed");
- CARemoveBlockDataFromList(blockID);
- return res;
+ goto exit;
}
- // reset block-list after write block
- if (0 == block1->m)
+ // add the payload data as the block size.
+ if (!coap_add_block(*pdu, dataLength, (const unsigned char *) info->payload, block1->num,
+ block1->szx))
{
- // remove data from list
- CAResult_t res = CARemoveBlockDataFromList(blockID);
- if (CA_STATUS_OK != res)
- {
- OIC_LOG(ERROR, TAG, "remove has failed");
- return res;
- }
+ OIC_LOG(ERROR, TAG, "Data length is smaller than the start index");
+ return CA_STATUS_FAILED;
}
}
else
{
- CAGetMoreBitFromBlock(dataLength, block1);
- CAResult_t res = CAAddBlockOptionImpl(*pdu, block1, COAP_OPTION_BLOCK1);
+ OIC_LOG(DEBUG, TAG, "received response message with block option1");
+
+ // add block option to option list.
+ res = CAAddBlockOptionImpl(block1, COAP_OPTION_BLOCK1, options);
if (CA_STATUS_OK != res)
{
OIC_LOG(ERROR, TAG, "add has failed");
- CARemoveBlockDataFromList(blockID);
- return res;
+ goto exit;
}
- CALogBlockInfo(block1);
- // if block number is 0, add size1 option
- if (0 == block1->num)
+ // add option list to pdu.
+ res = CAAddOptionToPDU(*pdu, options);
+ if (CA_STATUS_OK != res)
{
- res = CAAddBlockSizeOption(*pdu, COAP_OPTION_SIZE1, dataLength);
- if (CA_STATUS_OK != res)
- {
- OIC_LOG(ERROR, TAG, "add has failed");
- CARemoveBlockDataFromList(blockID);
- return res;
- }
+ OIC_LOG(ERROR, TAG, "add has failed");
+ goto exit;
}
- if (!coap_add_block(*pdu, dataLength, (const unsigned char *) info->payload,
- block1->num, block1->szx))
+ // add the payload data as the block size.
+ if (!coap_add_data(*pdu, dataLength, (const unsigned char *) info->payload))
{
- OIC_LOG(ERROR, TAG, "Data length is smaller than the start index");
+ OIC_LOG(ERROR, TAG, "failed to add payload");
return CA_STATUS_FAILED;
}
- // check the message type and if message type is NON, next block message will be sent
- if (CA_MSG_NONCONFIRM == (*pdu)->hdr->coap_hdr_udp_t.type)
+ // if it is last block message, remove block data from list.
+ if (0 == block1->m)
{
- if (block1->m)
- {
- OIC_LOG(DEBUG, TAG, "NON, send next block..");
- // update block data
- block1->num++;
- CAResult_t res = CAProcessNextStep(*pdu, NULL,
- CA_SENT_PREVIOUS_NON_MSG,
- blockID);
- if (CA_STATUS_OK != res)
- {
- OIC_LOG(ERROR, TAG, "failed to process next step");
- CARemoveBlockDataFromList(blockID);
- return res;
- }
- }
- else
+ // remove data from list
+ res = CARemoveBlockDataFromList(blockID);
+ if (CA_STATUS_OK != res)
{
- CARemoveBlockDataFromList(blockID);
+ OIC_LOG(ERROR, TAG, "remove has failed");
+ return res;
}
}
}
+ CALogBlockInfo(block1);
+
OIC_LOG(DEBUG, TAG, "OUT-AddBlockOption1");
return CA_STATUS_OK;
+
+exit:
+ CARemoveBlockDataFromList(blockID);
+ return res;
}
-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");
+
+ unsigned char buf[BLOCKWISE_OPTION_BUFFER] = { 0 };
+ unsigned int optionLength = coap_encode_var_bytes(buf,
+ ((block->num << BLOCK_NUMBER_IDX)
+ | (block->m << BLOCK_M_BIT_IDX)
+ | block->szx));
- coap_option *option = (coap_option *) OICMalloc(sizeof(coap_option));
- if (!option)
+ int ret = coap_insert(options,
+ CACreateNewOptionNode(blockType, optionLength, (char *) buf),
+ CAOrderOpts);
+ if (ret <= 0)
{
- OIC_LOG(ERROR, TAG, "out of memory");
- return CA_MEMORY_ALLOC_FAILED;
+ return CA_STATUS_INVALID_PARAM;
}
- unsigned char buf[BLOCKWISE_OPTION_BUFFER] = { 0 };
- option->key = blockType;
- option->length = coap_encode_var_bytes(buf,
- ((block->num << BLOCK_NUMBER_IDX)
- | (block->m << BLOCK_M_BIT_IDX) | block->szx));
- if (!coap_add_option(pdu, option->key, option->length, buf, coap_udp))
- {
- OIC_LOG(ERROR, TAG, "coap_add_option has failed");
- OICFree(option);
- return CA_STATUS_FAILED;
+ 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)
+ {
+ for (coap_list_t *opt = *options; opt; opt = opt->next)
+ {
+ OIC_LOG_V(DEBUG, TAG, "[%s] opt will be added.",
+ COAP_OPTION_DATA(*(coap_option *) opt->data));
+
+ OIC_LOG_V(DEBUG, TAG, "[%d] pdu length", pdu->length);
+ 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));
+ if (!ret)
+ {
+ return CA_STATUS_FAILED;
+ }
+ }
}
- OICFree(option);
+ OIC_LOG_V(DEBUG, TAG, "[%d] pdu length after option", pdu->length);
- OIC_LOG(DEBUG, TAG, "OUT-AddBlockOptionImpl");
return CA_STATUS_OK;
}
-CAResult_t CAAddBlockSizeOption(coap_pdu_t *pdu, uint16_t sizeType, size_t dataLength)
+CAResult_t CAAddBlockSizeOption(coap_pdu_t *pdu, uint16_t sizeType, size_t dataLength,
+ coap_list_t **options)
{
OIC_LOG(DEBUG, TAG, "IN-CAAddBlockSizeOption");
VERIFY_NON_NULL(pdu, TAG, "pdu");
+ VERIFY_NON_NULL(options, TAG, "options");
if (sizeType != COAP_OPTION_SIZE1 && sizeType != COAP_OPTION_SIZE2)
{
unsigned char value[BLOCKWISE_OPTION_BUFFER] = { 0 };
unsigned int optionLength = coap_encode_var_bytes(value, dataLength);
- if (!coap_add_option(pdu, sizeType, optionLength, value, coap_udp))
+ int ret = coap_insert(options,
+ CACreateNewOptionNode(sizeType, optionLength, (char *) value),
+ CAOrderOpts);
+ if (ret <= 0)
{
- OIC_LOG(ERROR, TAG, "failed to add size option");
- return CA_STATUS_FAILED;
+ return CA_STATUS_INVALID_PARAM;
}
OIC_LOG(DEBUG, TAG, "OUT-CAAddBlockSizeOption");
*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;
if (COAP_OPTION_BLOCK1 == blockType)
{
size_t prePayloadLen = currData->receivedPayloadLen;
- if (prePayloadLen != (size_t)BLOCK_SIZE(receivedBlock->szx)
- * receivedBlock->num)
+ if (prePayloadLen != (size_t) BLOCK_SIZE(receivedBlock->szx) * receivedBlock->num)
{
if (receivedBlock->num > currData->block1.num + 1)
{
OIC_LOG(ERROR, TAG, "it didn't order");
return CA_BLOCK_INCOMPLETE;
}
- return CA_BLOCK_RECEIVED_ALREADY;
+ else
+ {
+ OIC_LOG(ERROR, TAG, "already received this block");
+ return CA_BLOCK_RECEIVED_ALREADY;
+ }
}
}
// #3. check if error check logic is required
size_t optionLen = dataLen - blockPayloadLen;
- if (receivedBlock->m && blockPayloadLen !=
- (size_t)BLOCK_SIZE(receivedBlock->szx))
+ if (receivedBlock->m && blockPayloadLen != (size_t) BLOCK_SIZE(receivedBlock->szx))
{
// 413 Error handling of too large entity
if (COAP_MAX_PDU_SIZE < BLOCK_SIZE(receivedBlock->szx) + optionLen)
if (COAP_MAX_PDU_SIZE >= BLOCK_SIZE(size) + optionLen)
{
OIC_LOG_V(ERROR, TAG, "replace sze with %d", size);
- if (COAP_OPTION_BLOCK2 == blockType)
- {
- currData->block2.szx = size;
- }
- else
- {
- currData->block1.szx = size;
- }
+ currData->block2.szx = size;
+ currData->block1.szx = size;
break;
}
}
// 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);
}
CAData_t* CACreateNewDataSet(const coap_pdu_t *pdu, const CAEndpoint_t *endpoint)
{
VERIFY_NON_NULL_RET(pdu, TAG, "pdu", NULL);
- VERIFY_NON_NULL_RET(pdu->hdr, TAG, "pdu->hdr", NULL);
+ VERIFY_NON_NULL_RET(pdu->transport_hdr, TAG, "pdu->transport_hdr", NULL);
VERIFY_NON_NULL_RET(endpoint, TAG, "endpoint", NULL);
- CAInfo_t responseData = { .tokenLength = pdu->hdr->coap_hdr_udp_t.token_length };
- responseData.token = (CAToken_t) OICMalloc(responseData.tokenLength);
- if (!responseData.token)
+ CARequestInfo_t* requestInfo = NULL;
+ CAResponseInfo_t* responseInfo = NULL;
+
+ uint32_t code = pdu->transport_hdr->udp.code;
+ if (CA_GET == code || CA_POST == code || CA_PUT == code || CA_DELETE == code)
{
- OIC_LOG(ERROR, TAG, "out of memory");
- return NULL;
- }
- memcpy(responseData.token, pdu->hdr->coap_hdr_udp_t.token, responseData.tokenLength);
+ CAInfo_t responseData = { .tokenLength = pdu->transport_hdr->udp.token_length };
+ responseData.token = (CAToken_t) OICMalloc(responseData.tokenLength);
+ if (!responseData.token)
+ {
+ OIC_LOG(ERROR, TAG, "out of memory");
+ return NULL;
+ }
+ memcpy(responseData.token, pdu->transport_hdr->udp.token, responseData.tokenLength);
- CAResponseInfo_t* responseInfo = (CAResponseInfo_t*) OICCalloc(1, sizeof(CAResponseInfo_t));
- if (!responseInfo)
+ responseInfo = (CAResponseInfo_t*) OICCalloc(1, sizeof(CAResponseInfo_t));
+ if (!responseInfo)
+ {
+ OIC_LOG(ERROR, TAG, "out of memory");
+ OICFree(responseData.token);
+ return NULL;
+ }
+ responseInfo->info = responseData;
+ }
+ else
{
- OIC_LOG(ERROR, TAG, "out of memory");
- OICFree(responseData.token);
- return NULL;
+ CAInfo_t requestData = { .tokenLength = pdu->transport_hdr->udp.token_length };
+ requestData.token = (CAToken_t) OICMalloc(requestData.tokenLength);
+ if (!requestData.token)
+ {
+ OIC_LOG(ERROR, TAG, "out of memory");
+ return NULL;
+ }
+ memcpy(requestData.token, pdu->transport_hdr->udp.token, requestData.tokenLength);
+
+ requestInfo = (CARequestInfo_t*) OICCalloc(1, sizeof(CARequestInfo_t));
+ if (!requestInfo)
+ {
+ OIC_LOG(ERROR, TAG, "out of memory");
+ OICFree(requestData.token);
+ return NULL;
+ }
+ requestInfo->info = requestData;
+
+ // get resource uri information from received response message
+ // to send next request message to remote device
+ CAResponseInfo_t* resInfo = (CAResponseInfo_t*)OICCalloc(1, sizeof(*resInfo));
+ if (!resInfo)
+ {
+ OIC_LOG(ERROR, TAG, "memory allocation failed");
+ OICFree(requestData.token);
+ OICFree(requestInfo);
+ return NULL;
+ }
+
+ CAGetResponseInfoFromPDU(pdu, resInfo, endpoint);
+ requestInfo->method = CA_GET;
+ requestInfo->info.messageId = CAGetMessageIdFromPduBinaryData(pdu->transport_hdr,
+ pdu->length);
+ requestInfo->info.resourceUri = OICStrdup(resInfo->info.resourceUri);
+
+ // after copying the resource uri, destroy response info.
+ CADestroyResponseInfoInternal(resInfo);
}
- responseInfo->info = responseData;
CAData_t *data = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
if (!data)
{
OIC_LOG(ERROR, TAG, "out of memory");
- OICFree(responseInfo);
+ if (NULL != requestInfo)
+ {
+ OICFree(requestInfo->info.resourceUri);
+ OICFree(requestInfo->info.token);
+ OICFree(requestInfo);
+ }
+ if (NULL != responseInfo)
+ {
+ OICFree(responseInfo->info.token);
+ OICFree(responseInfo);
+ }
return NULL;
}
- data->requestInfo = NULL;
+ data->requestInfo = requestInfo;
data->responseInfo = responseInfo;
data->remoteEndpoint = CACloneEndpoint(endpoint);
data->type = SEND_TYPE_UNICAST;
{
clone->requestInfo = CACloneRequestInfo(data->requestInfo);
}
-
- if (data->responseInfo)
+ else if (data->responseInfo)
{
clone->responseInfo = CACloneResponseInfo(data->responseInfo);
}
switch (data->dataType)
{
case CA_REQUEST_DATA:
+ if (!data->requestInfo)
+ {
+ OIC_LOG(ERROR, TAG, "request info is null");
+ return CA_STATUS_FAILED;
+ }
// allocate payload field
newPayload = OICRealloc(data->requestInfo->info.payload, payloadLen);
if (!newPayload)
break;
case CA_RESPONSE_DATA:
+ if (!data->responseInfo)
+ {
+ OIC_LOG(ERROR, TAG, "response info is null");
+ return CA_STATUS_FAILED;
+ }
// allocate payload field
newPayload = OICRealloc(data->responseInfo->info.payload, payloadLen);
if (!newPayload)
return data->requestInfo->info.payload;
}
}
- else
+ else if (data->responseInfo)
{
if (data->responseInfo->info.payload)
{
break;
default:
OIC_LOG_V(ERROR, TAG, "there is no Error Code of BWT[%d]", responseResult);
+ return CA_STATUS_FAILED;
}
OIC_LOG(DEBUG, TAG, "OUT-HandleBlockErrorRes");
return CA_STATUS_OK;
}
-CAResult_t CAUpdateBlockOptionType(const CABlockDataID_t *blockID,
- uint8_t blockType)
+CAResult_t CAUpdateBlockOptionType(const CABlockDataID_t *blockID, uint8_t blockType)
{
OIC_LOG(DEBUG, TAG, "IN-UpdateBlockOptionType");
VERIFY_NON_NULL(blockID, TAG, "blockID");
- ca_mutex_lock(g_context.blockDataListMutex);
+ oc_mutex_lock(g_context.blockDataListMutex);
size_t len = u_arraylist_length(g_context.dataList);
for (size_t i = 0; i < len; i++)
if (CABlockidMatches(currData, blockID))
{
currData->type = blockType;
- ca_mutex_unlock(g_context.blockDataListMutex);
+ oc_mutex_unlock(g_context.blockDataListMutex);
OIC_LOG(DEBUG, TAG, "OUT-UpdateBlockOptionType");
return CA_STATUS_OK;
}
}
- ca_mutex_unlock(g_context.blockDataListMutex);
+ oc_mutex_unlock(g_context.blockDataListMutex);
OIC_LOG(DEBUG, TAG, "OUT-UpdateBlockOptionType");
return CA_STATUS_FAILED;
OIC_LOG(DEBUG, TAG, "IN-GetBlockOptionType");
VERIFY_NON_NULL_RET(blockID, TAG, "blockID", 0);
- ca_mutex_lock(g_context.blockDataListMutex);
+ oc_mutex_lock(g_context.blockDataListMutex);
size_t len = u_arraylist_length(g_context.dataList);
for (size_t i = 0; i < len; i++)
CABlockData_t *currData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
if (CABlockidMatches(currData, blockID))
{
- ca_mutex_unlock(g_context.blockDataListMutex);
+ oc_mutex_unlock(g_context.blockDataListMutex);
OIC_LOG(DEBUG, TAG, "OUT-GetBlockOptionType");
return currData->type;
}
}
- ca_mutex_unlock(g_context.blockDataListMutex);
+ oc_mutex_unlock(g_context.blockDataListMutex);
OIC_LOG(DEBUG, TAG, "OUT-GetBlockOptionType");
return 0;
{
VERIFY_NON_NULL_RET(blockID, TAG, "blockID", NULL);
- ca_mutex_lock(g_context.blockDataListMutex);
+ oc_mutex_lock(g_context.blockDataListMutex);
size_t len = u_arraylist_length(g_context.dataList);
for (size_t i = 0; i < len; i++)
CABlockData_t *currData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
if (CABlockidMatches(currData, blockID))
{
- ca_mutex_unlock(g_context.blockDataListMutex);
+ oc_mutex_unlock(g_context.blockDataListMutex);
return currData->sentData;
}
}
- ca_mutex_unlock(g_context.blockDataListMutex);
+ oc_mutex_unlock(g_context.blockDataListMutex);
+
+ return NULL;
+}
+
+CABlockData_t *CAUpdateDataSetFromBlockDataList(const CABlockDataID_t *blockID,
+ const CAData_t *sendData)
+{
+ VERIFY_NON_NULL_RET(blockID, TAG, "blockID", NULL);
+ VERIFY_NON_NULL_RET(sendData, TAG, "sendData", NULL);
+
+ oc_mutex_lock(g_context.blockDataListMutex);
+
+ size_t len = u_arraylist_length(g_context.dataList);
+ for (size_t i = 0; i < len; i++)
+ {
+ CABlockData_t *currData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
+ if (CABlockidMatches(currData, blockID))
+ {
+ CADestroyDataSet(currData->sentData);
+ currData->sentData = CACloneCAData(sendData);
+ oc_mutex_unlock(g_context.blockDataListMutex);
+ return currData;
+ }
+ }
+ oc_mutex_unlock(g_context.blockDataListMutex);
return NULL;
}
VERIFY_NON_NULL(endpoint, TAG, "endpoint");
VERIFY_NON_NULL(responseInfo, TAG, "responseInfo");
- ca_mutex_lock(g_context.blockDataListMutex);
+ oc_mutex_lock(g_context.blockDataListMutex);
size_t len = u_arraylist_length(g_context.dataList);
for (size_t i = 0; i < len; i++)
if (NULL != currData->sentData && NULL != currData->sentData->requestInfo)
{
- if (pdu->hdr->coap_hdr_udp_t.id == currData->sentData->requestInfo->info.messageId &&
+ if (pdu->transport_hdr->udp.id == currData->sentData->requestInfo->info.messageId &&
endpoint->adapter == currData->sentData->remoteEndpoint->adapter)
{
if (NULL != currData->sentData->requestInfo->info.token)
if (NULL == responseInfo->info.token)
{
OIC_LOG(ERROR, TAG, "out of memory");
- ca_mutex_unlock(g_context.blockDataListMutex);
+ oc_mutex_unlock(g_context.blockDataListMutex);
return CA_MEMORY_ALLOC_FAILED;
}
memcpy(responseInfo->info.token, currData->sentData->requestInfo->info.token,
responseInfo->info.tokenLength);
- ca_mutex_unlock(g_context.blockDataListMutex);
+ oc_mutex_unlock(g_context.blockDataListMutex);
OIC_LOG(DEBUG, TAG, "OUT-CAGetTokenFromBlockDataList");
return CA_STATUS_OK;
}
}
}
- ca_mutex_unlock(g_context.blockDataListMutex);
+ oc_mutex_unlock(g_context.blockDataListMutex);
OIC_LOG(DEBUG, TAG, "OUT-CAGetTokenFromBlockDataList");
- return CA_STATUS_OK;
+ return CA_STATUS_FAILED;
}
CAResult_t CACheckBlockDataValidation(const CAData_t *sendData, CABlockData_t **blockData)
VERIFY_NON_NULL(sendData, TAG, "sendData");
VERIFY_NON_NULL(blockData, TAG, "blockData");
- ca_mutex_lock(g_context.blockDataListMutex);
-
- size_t len = u_arraylist_length(g_context.dataList);
- for (size_t i = 0; i < len; i++)
+ if (sendData->responseInfo)
{
- CABlockData_t *currData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
-
- if (!currData)
- {
- continue;
- }
-
- if (sendData->requestInfo) // sendData is requestMessage
+ CABlockDataID_t* blockDataID = CACreateBlockDatablockId(
+ (CAToken_t)sendData->responseInfo->info.token,
+ sendData->responseInfo->info.tokenLength,
+ sendData->remoteEndpoint->port);
+ if (NULL == blockDataID || blockDataID->idLength < 1)
{
- OIC_LOG(DEBUG, TAG, "Send request");
- if (NULL != currData->blockDataId
- && NULL != currData->blockDataId->id
- && currData->blockDataId->idLength > 0
- && NULL != sendData->requestInfo->info.token)
- {
- CABlockDataID_t* blockDataID = CACreateBlockDatablockId(
- (CAToken_t)sendData->requestInfo->info.token,
- sendData->requestInfo->info.tokenLength,
- sendData->remoteEndpoint->port);
-
- if(NULL == blockDataID || NULL == blockDataID->id || blockDataID->idLength < 1)
- {
- OIC_LOG(ERROR, TAG, "blockId is null");
- CADestroyBlockID(blockDataID);
- return CA_STATUS_FAILED;
- }
-
- if (CABlockidMatches(currData, blockDataID))
- {
- OIC_LOG(ERROR, TAG, "already sent");
- CADestroyBlockID(blockDataID);
- continue;
- }
- CADestroyBlockID(blockDataID);
- }
+ OIC_LOG(ERROR, TAG, "blockId is null");
+ CADestroyBlockID(blockDataID);
+ return CA_STATUS_FAILED;
}
- else if (sendData->responseInfo) // sendData is responseMessage
- {
- OIC_LOG(DEBUG, TAG, "Send response");
- if (NULL != currData->blockDataId
- && NULL != currData->blockDataId->id
- && currData->blockDataId->idLength > 0
- && NULL != sendData->responseInfo->info.token)
- {
- CABlockDataID_t* blockDataID = CACreateBlockDatablockId(
- (CAToken_t)sendData->responseInfo->info.token,
- sendData->responseInfo->info.tokenLength,
- sendData->remoteEndpoint->port);
-
- if(NULL == blockDataID || NULL == blockDataID->id || blockDataID->idLength < 1)
- {
- OIC_LOG(ERROR, TAG, "blockId is null");
- CADestroyBlockID(blockDataID);
- return CA_STATUS_FAILED;
- }
- if (CABlockidMatches(currData, blockDataID))
- {
- // set sendData
- if (NULL != currData->sentData)
- {
- OIC_LOG(DEBUG, TAG, "init block number");
- CADestroyDataSet(currData->sentData);
- }
- currData->sentData = CACloneCAData(sendData);
- *blockData = currData;
- CADestroyBlockID(blockDataID);
- ca_mutex_unlock(g_context.blockDataListMutex);
- return CA_STATUS_OK;
- }
- CADestroyBlockID(blockDataID);
- }
- }
- else
+ CABlockData_t *updatedData = CAUpdateDataSetFromBlockDataList(blockDataID, sendData);
+ if (updatedData)
{
- OIC_LOG(ERROR, TAG, "no CAInfo data");
- continue;
+ OIC_LOG(DEBUG, TAG, "Send response about the received block request.");
+ *blockData = updatedData;
+ CADestroyBlockID(blockDataID);
+ return CA_STATUS_OK;
}
+ CADestroyBlockID(blockDataID);
}
- ca_mutex_unlock(g_context.blockDataListMutex);
return CA_STATUS_FAILED;
}
{
VERIFY_NON_NULL_RET(blockID, TAG, "blockID", NULL);
- ca_mutex_lock(g_context.blockDataListMutex);
+ oc_mutex_lock(g_context.blockDataListMutex);
size_t len = u_arraylist_length(g_context.dataList);
for (size_t i = 0; i < len; i++)
CABlockData_t *currData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
if (CABlockidMatches(currData, blockID))
{
- ca_mutex_unlock(g_context.blockDataListMutex);
+ oc_mutex_unlock(g_context.blockDataListMutex);
return currData;
}
}
- ca_mutex_unlock(g_context.blockDataListMutex);
+ oc_mutex_unlock(g_context.blockDataListMutex);
return NULL;
}
-coap_block_t *CAGetBlockOption(const CABlockDataID_t *blockID,
- uint16_t blockType)
+coap_block_t *CAGetBlockOption(const CABlockDataID_t *blockID, uint16_t blockType)
{
OIC_LOG(DEBUG, TAG, "IN-GetBlockOption");
VERIFY_NON_NULL_RET(blockID, TAG, "blockID", NULL);
- ca_mutex_lock(g_context.blockDataListMutex);
+ oc_mutex_lock(g_context.blockDataListMutex);
size_t len = u_arraylist_length(g_context.dataList);
for (size_t i = 0; i < len; i++)
CABlockData_t *currData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
if (CABlockidMatches(currData, blockID))
{
- ca_mutex_unlock(g_context.blockDataListMutex);
+ oc_mutex_unlock(g_context.blockDataListMutex);
OIC_LOG(DEBUG, TAG, "OUT-GetBlockOption");
if (COAP_OPTION_BLOCK2 == blockType)
{
return &currData->block2;
}
- else
+ else if (COAP_OPTION_BLOCK1 == blockType)
{
return &currData->block1;
}
}
}
- ca_mutex_unlock(g_context.blockDataListMutex);
+ oc_mutex_unlock(g_context.blockDataListMutex);
OIC_LOG(DEBUG, TAG, "OUT-GetBlockOption");
return NULL;
VERIFY_NON_NULL_RET(blockID, TAG, "blockID", NULL);
VERIFY_NON_NULL_RET(fullPayloadLen, TAG, "fullPayloadLen", NULL);
- ca_mutex_lock(g_context.blockDataListMutex);
+ oc_mutex_lock(g_context.blockDataListMutex);
size_t len = u_arraylist_length(g_context.dataList);
for (size_t i = 0; i < len; i++)
CABlockData_t *currData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
if (CABlockidMatches(currData, blockID))
{
- ca_mutex_unlock(g_context.blockDataListMutex);
+ oc_mutex_unlock(g_context.blockDataListMutex);
*fullPayloadLen = currData->receivedPayloadLen;
OIC_LOG(DEBUG, TAG, "OUT-GetFullPayload");
return currData->payload;
}
}
- ca_mutex_unlock(g_context.blockDataListMutex);
+ oc_mutex_unlock(g_context.blockDataListMutex);
OIC_LOG(DEBUG, TAG, "OUT-GetFullPayload");
return NULL;
data->block1.szx = CA_DEFAULT_BLOCK_SIZE;
data->block2.szx = CA_DEFAULT_BLOCK_SIZE;
data->sentData = CACloneCAData(sendData);
- if(!data->sentData)
+ if (!data->sentData)
{
OIC_LOG(ERROR, TAG, PCF("memory alloc has failed"));
OICFree(data);
tokenLength = data->sentData->requestInfo->info.tokenLength;
token = data->sentData->requestInfo->info.token;
}
- else if(data->sentData->responseInfo)
+ else if (data->sentData->responseInfo)
{
tokenLength = data->sentData->responseInfo->info.tokenLength;
token = data->sentData->responseInfo->info.token;
}
- CABlockDataID_t* blockDataID = CACreateBlockDatablockId(
- token, tokenLength,
- data->sentData->remoteEndpoint->port);
- if (NULL == blockDataID || NULL == blockDataID->id || blockDataID->idLength < 1)
+ if (!data->sentData->remoteEndpoint)
+ {
+ OIC_LOG(ERROR, TAG, "remoteEndpoint is null");
+ CADestroyDataSet(data->sentData);
+ OICFree(data);
+ return NULL;
+ }
+
+ CABlockDataID_t* blockDataID = CACreateBlockDatablockId(token, tokenLength,
+ data->sentData->remoteEndpoint->port);
+ if (NULL == blockDataID || blockDataID->idLength < 1)
{
OIC_LOG(ERROR, TAG, "blockId is null");
CADestroyBlockID(blockDataID);
return NULL;
}
data->blockDataId = blockDataID;
+ uint64_t now = OICGetCurrentTime(TIME_IN_US);
+ data->ttl = now + (BLOCK_DATA_TIMEOUT_SECONDS * USECS_PER_SEC);
- ca_mutex_lock(g_context.blockDataListMutex);
+ oc_mutex_lock(g_context.blockDataListMutex);
bool res = u_arraylist_add(g_context.dataList, (void *) data);
if (!res)
CADestroyBlockID(data->blockDataId);
CADestroyDataSet(data->sentData);
OICFree(data);
- ca_mutex_unlock(g_context.blockDataListMutex);
+ oc_mutex_unlock(g_context.blockDataListMutex);
return NULL;
}
- ca_mutex_unlock(g_context.blockDataListMutex);
+ oc_mutex_unlock(g_context.blockDataListMutex);
OIC_LOG(DEBUG, TAG, "OUT-CreateBlockData");
return data;
CAResult_t CARemoveBlockDataFromList(const CABlockDataID_t *blockID)
{
- OIC_LOG(DEBUG, TAG, "CARemoveBlockData");
+ OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
VERIFY_NON_NULL(blockID, TAG, "blockID");
- ca_mutex_lock(g_context.blockDataListMutex);
+ oc_mutex_lock(g_context.blockDataListMutex);
size_t len = u_arraylist_length(g_context.dataList);
for (size_t i = 0; i < len; i++)
if (!removedData)
{
OIC_LOG(ERROR, TAG, "data is NULL");
- ca_mutex_unlock(g_context.blockDataListMutex);
+ oc_mutex_unlock(g_context.blockDataListMutex);
return CA_STATUS_FAILED;
}
+ OIC_LOG(DEBUG, TAG, "Removed BlockID is ");
+ OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *) removedData->blockDataId->id,
+ removedData->blockDataId->idLength);
+
// destroy memory
- if (currData->sentData)
- {
- CADestroyDataSet(currData->sentData);
- }
- CADestroyBlockID(currData->blockDataId);
- OICFree(currData->payload);
- OICFree(currData);
- ca_mutex_unlock(g_context.blockDataListMutex);
+ CADestroyDataSet(removedData->sentData);
+ CADestroyBlockID(removedData->blockDataId);
+ OICFree(removedData->payload);
+ OICFree(removedData);
+ oc_mutex_unlock(g_context.blockDataListMutex);
return CA_STATUS_OK;
}
}
- ca_mutex_unlock(g_context.blockDataListMutex);
-
+ oc_mutex_unlock(g_context.blockDataListMutex);
+ OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
return CA_STATUS_OK;
}
-bool CAIsBlockDataInList(const CABlockDataID_t *blockID)
+CAResult_t CARemoveAllBlockDataFromList()
{
- OIC_LOG(DEBUG, TAG, "IN-IsBlockDataInList");
- VERIFY_NON_NULL_RET(blockID, TAG, "blockID", false);
+ OIC_LOG(DEBUG, TAG, "CARemoveAllBlockDataFromList");
- ca_mutex_lock(g_context.blockDataListMutex);
+ oc_mutex_lock(g_context.blockDataListMutex);
size_t len = u_arraylist_length(g_context.dataList);
- for (size_t i = 0; i < len; i++)
+ for (size_t i = len; i > 0; i--)
{
- CABlockData_t *currData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
- if (CABlockidMatches(currData, blockID))
+ CABlockData_t *removedData = u_arraylist_remove(g_context.dataList, i - 1);
+ if (removedData)
{
- OIC_LOG(DEBUG, TAG, "found block data");
- ca_mutex_unlock(g_context.blockDataListMutex);
- return true;
+ // destroy memory
+ if (removedData->sentData)
+ {
+ CADestroyDataSet(removedData->sentData);
+ }
+ CADestroyBlockID(removedData->blockDataId);
+ OICFree(removedData->payload);
+ OICFree(removedData);
}
}
- ca_mutex_unlock(g_context.blockDataListMutex);
+ oc_mutex_unlock(g_context.blockDataListMutex);
- OIC_LOG(DEBUG, TAG, "OUT-IsBlockDataInList");
- return false;
+ return CA_STATUS_OK;
}
void CADestroyDataSet(CAData_t* data)
{
VERIFY_NON_NULL_VOID(data, TAG, "data");
- CAFreeEndpoint(data->remoteEndpoint);
- CADestroyRequestInfoInternal(data->requestInfo);
- CADestroyResponseInfoInternal(data->responseInfo);
+ if (data->remoteEndpoint)
+ {
+ CAFreeEndpoint(data->remoteEndpoint);
+ data->remoteEndpoint = NULL;
+ }
+ if (data->requestInfo)
+ {
+ CADestroyRequestInfoInternal(data->requestInfo);
+ data->requestInfo = NULL;
+ }
+ if (data->responseInfo)
+ {
+ CADestroyResponseInfoInternal(data->responseInfo);
+ data->responseInfo = NULL;
+ }
OICFree(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);
+ char port[PORT_LENGTH] = { 0, };
+ port[0] = (char) ((portNumber >> 8) & 0xFF);
+ port[1] = (char) (portNumber & 0xFF);
CABlockDataID_t* blockDataID = (CABlockDataID_t *) OICMalloc(sizeof(CABlockDataID_t));
if (!blockDataID)
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 ");
OIC_LOG_V(DEBUG, TAG, "block option-szx : %d", block->szx);
}
+
+CAResult_t CARemoveBlockDataFromListWithSeed(const CAToken_t token, uint8_t tokenLength,
+ uint16_t portNumber)
+{
+ CABlockDataID_t* blockDataID = CACreateBlockDatablockId(token, tokenLength, portNumber);
+ if (NULL == blockDataID || blockDataID->idLength < 1)
+ {
+ OIC_LOG(ERROR, TAG, "blockId is null");
+ CADestroyBlockID(blockDataID);
+ return CA_STATUS_FAILED;
+ }
+
+ CAResult_t res = CARemoveBlockDataFromList(blockDataID);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "CARemoveBlockDataFromList failed");
+ }
+
+ CADestroyBlockID(blockDataID);
+ return res;
+}
+
+void CAResetBlockDataTTL(const CABlockDataID_t *blockID)
+{
+ OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
+ oc_mutex_lock(g_context.blockDataListMutex);
+ size_t len = u_arraylist_length(g_context.dataList);
+ for (size_t i = 0; i < len; i++)
+ {
+ CABlockData_t *blockData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
+ if (CABlockidMatches(blockData, blockID))
+ {
+ uint64_t now = OICGetCurrentTime(TIME_IN_US);
+ blockData->ttl = now + (BLOCK_DATA_TIMEOUT_SECONDS * USECS_PER_SEC);
+ oc_mutex_unlock(g_context.blockDataListMutex);
+ OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+ return;
+ }
+ }
+ oc_mutex_unlock(g_context.blockDataListMutex);
+ OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+}
+
+void CACheckAndDeleteTimedOutBlockData()
+{
+ OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
+ uint64_t now = OICGetCurrentTime(TIME_IN_US);
+
+ oc_mutex_lock(g_context.blockDataListMutex);
+ for (size_t i = 0; i < u_arraylist_length(g_context.dataList); i++)
+ {
+ CABlockData_t *blockData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
+ if (blockData && blockData->ttl < now)
+ {
+ OIC_LOG(INFO, TAG, "Deleting timed-out BlockData");
+ OIC_LOG(DEBUG, TAG, "BlockID is ");
+ OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *) blockData->blockDataId->id,
+ blockData->blockDataId->idLength);
+
+ blockData = (CABlockData_t *) u_arraylist_remove(g_context.dataList, i);
+ if (blockData)
+ {
+ // destroy memory
+ CADestroyDataSet(blockData->sentData);
+ CADestroyBlockID(blockData->blockDataId);
+ OICFree(blockData->payload);
+ OICFree(blockData);
+ }
+ }
+ }
+ oc_mutex_unlock(g_context.blockDataListMutex);
+ OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+}