Commit a6aa8c26 authored by Todd Malsbary's avatar Todd Malsbary Committed by Uze Choi

[IOT-1940] Include Uri-Path in blockwise requests.

This is correctly done for unicast requests but not for multicast
requests.

Bug: https://jira.iotivity.org/browse/IOT-1940
Change-Id: I9fa2d498ec4bec0cece2a75c51be2a64e05ce5f5
Signed-off-by: default avatarTodd Malsbary <todd.malsbary@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/19263Tested-by: default avatarjenkins-iotivity <jenkins@iotivity.org>
Reviewed-by: default avatarDan Mihai <Daniel.Mihai@microsoft.com>
Reviewed-by: default avatarZiran Sun <ziran.sun@samsung.com>
Reviewed-by: default avatarAshok Babu Channa <ashok.channa@samsung.com>
parent de259a21
......@@ -72,6 +72,12 @@ typedef struct
/** sender mutex for synchronization. **/
oc_mutex blockDataSenderMutex;
/** array list tracking multicast requests. **/
u_arraylist_t *multicastDataList;
/** mulitcast data list mutex for synchronization. **/
oc_mutex multicastDataListMutex;
} CABlockWiseContext_t;
/**
......@@ -116,6 +122,16 @@ typedef enum
CA_BLOCK_RECEIVED_ALREADY
} CABlockState_t;
/**
* Multicast request.
*/
typedef struct
{
CAToken_t token; /**< Token for CA */
uint8_t tokenLength; /**< token length */
CAURI_t resourceUri; /**< Resource URI information **/
} CABlockMulticastData_t;
/**
* Initializes the block-wise transfer context.
* @param[in] CASendThreadFunc function point to add data in send queue thread.
......@@ -577,6 +593,37 @@ CAResult_t CARemoveAllBlockDataFromList();
CAResult_t CARemoveBlockDataFromListWithSeed(const CAToken_t token, uint8_t tokenLength,
const char* addr, uint16_t portNumber);
/**
* Create the mulitcast data from given data and add the data in multicast list.
* @param[in] sendData data to be added to a list.
* @return created CABlockMulticastData_t structure,
* or NULL pointer will be returned if there is error case.
*/
CABlockMulticastData_t *CACreateNewBlockMulticastData(const CAData_t *sendData);
/**
* Get the block multicast data from list.
* @param[in] token token of the message.
* @param[in] tokenLength token length of the message.
* @return CABlockMulticastData_t structure.
*/
CABlockMulticastData_t *CAGetBlockMulticastDataFromListWithSeed(const CAToken_t token,
uint8_t tokenLength);
/**
* Remove all block multicast data in list.
* @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
*/
CAResult_t CARemoveAllBlockMulticastDataFromList();
/**
* Find the block data with seed info and remove it.
* @param[in] token token of the message.
* @param[in] tokenLength token length of the message.
* @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
*/
CAResult_t CARemoveBlockMulticastDataFromListWithSeed(const CAToken_t token, uint8_t tokenLength);
#ifdef __cplusplus
} /* extern "C" */
#endif
......
......@@ -57,7 +57,8 @@
// context for block-wise transfer
static CABlockWiseContext_t g_context = { .sendThreadFunc = NULL,
.receivedThreadFunc = NULL,
.dataList = NULL };
.dataList = NULL,
.multicastDataList = NULL };
static bool CACheckPayloadLength(const CAData_t *sendData)
{
......@@ -97,11 +98,18 @@ CAResult_t CAInitializeBlockWiseTransfer(CASendThreadFunc sendThreadFunc,
g_context.dataList = u_arraylist_create();
}
if (!g_context.multicastDataList)
{
g_context.multicastDataList = u_arraylist_create();
}
CAResult_t res = CAInitBlockWiseMutexVariables();
if (CA_STATUS_OK != res)
{
u_arraylist_free(&g_context.dataList);
g_context.dataList = NULL;
u_arraylist_free(&g_context.multicastDataList);
g_context.multicastDataList = NULL;
OIC_LOG(ERROR, TAG, "init has failed");
}
......@@ -118,6 +126,12 @@ CAResult_t CATerminateBlockWiseTransfer()
u_arraylist_free(&g_context.dataList);
}
if (g_context.multicastDataList)
{
CARemoveAllBlockMulticastDataFromList();
u_arraylist_free(&g_context.multicastDataList);
}
CATerminateBlockWiseMutexVariables();
return CA_STATUS_OK;
......@@ -146,6 +160,16 @@ CAResult_t CAInitBlockWiseMutexVariables()
}
}
if (!g_context.multicastDataListMutex)
{
g_context.multicastDataListMutex = oc_mutex_new();
if (!g_context.multicastDataListMutex)
{
OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
return CA_STATUS_FAILED;
}
}
return CA_STATUS_OK;
}
......@@ -162,6 +186,12 @@ void CATerminateBlockWiseMutexVariables()
oc_mutex_free(g_context.blockDataSenderMutex);
g_context.blockDataSenderMutex = NULL;
}
if (g_context.multicastDataListMutex)
{
oc_mutex_free(g_context.multicastDataListMutex);
g_context.multicastDataListMutex = NULL;
}
}
CAResult_t CASendBlockWiseData(const CAData_t *sendData)
......@@ -183,6 +213,18 @@ CAResult_t CASendBlockWiseData(const CAData_t *sendData)
*/
if (sendData->requestInfo->isMulticast)
{
CABlockMulticastData_t *currData = CAGetBlockMulticastDataFromListWithSeed(
sendData->requestInfo->info.token, sendData->requestInfo->info.tokenLength);
if (!currData)
{
currData = CACreateNewBlockMulticastData(sendData);
if (!currData)
{
OIC_LOG(ERROR, TAG, "memory alloc has failed");
return CA_MEMORY_ALLOC_FAILED;
}
}
OIC_LOG(DEBUG, TAG, "multicast message can't be sent to the block");
return CA_NOT_SUPPORTED;
}
......@@ -844,6 +886,23 @@ static CABlockData_t* CACheckTheExistOfBlockData(const CABlockDataID_t* blockDat
return NULL;
}
// Responses are not required to carry the Uri-Path but requests are
if (cadata->requestInfo && !cadata->requestInfo->info.resourceUri)
{
CABlockMulticastData_t *currData = CAGetBlockMulticastDataFromListWithSeed(
(CAToken_t) blockDataID->id, blockDataID->idLength);
if (currData)
{
cadata->requestInfo->info.resourceUri = OICStrdup(currData->resourceUri);
if (!cadata->requestInfo->info.resourceUri)
{
OIC_LOG(ERROR, TAG, "failed to allocate resource URI");
CADestroyDataSet(cadata);
return NULL;
}
}
}
data = CACreateNewBlockData(cadata);
if (!data)
{
......@@ -2798,3 +2857,145 @@ CAResult_t CARemoveBlockDataFromListWithSeed(const CAToken_t token, uint8_t toke
CADestroyBlockID(blockDataID);
return res;
}
CABlockMulticastData_t *CACreateNewBlockMulticastData(const CAData_t *sendData)
{
OIC_LOG(DEBUG, TAG, "IN-CACreateNewBlockMulticastData");
VERIFY_NON_NULL_RET(sendData, TAG, "sendData", NULL);
if (!sendData->requestInfo || !sendData->requestInfo->isMulticast)
{
return NULL;
}
CABlockMulticastData_t *data =
(CABlockMulticastData_t *) OICCalloc(1, sizeof(CABlockMulticastData_t));
if (!data)
{
OIC_LOG(ERROR, TAG, "memory alloc has failed");
return NULL;
}
uint8_t tokenLength = sendData->requestInfo->info.tokenLength;
CAToken_t token = (char *) OICMalloc(tokenLength * sizeof(char));
if (!token)
{
OIC_LOG(ERROR, TAG, "memory alloc has failed");
OICFree(data);
return NULL;
}
memcpy(token, sendData->requestInfo->info.token, tokenLength);
data->token = token;
data->tokenLength = tokenLength;
if (sendData->requestInfo->info.resourceUri)
{
char *resourceUri = OICStrdup(sendData->requestInfo->info.resourceUri);
if (!resourceUri)
{
OIC_LOG(ERROR, TAG, "memory alloc has failed");
OICFree(data->token);
OICFree(data);
return NULL;
}
data->resourceUri = resourceUri;
}
oc_mutex_lock(g_context.multicastDataListMutex);
bool res = u_arraylist_add(g_context.multicastDataList, (void *) data);
if (!res)
{
OIC_LOG(ERROR, TAG, "add has failed");
OICFree(data->resourceUri);
OICFree(data->token);
OICFree(data);
oc_mutex_unlock(g_context.multicastDataListMutex);
return NULL;
}
oc_mutex_unlock(g_context.multicastDataListMutex);
OIC_LOG(DEBUG, TAG, "OUT-CACreateNewBlockMulticastData");
return data;
}
CABlockMulticastData_t *CAGetBlockMulticastDataFromListWithSeed(const CAToken_t token,
uint8_t tokenLength)
{
VERIFY_NON_NULL_RET(token, TAG, "token", NULL);
oc_mutex_lock(g_context.multicastDataListMutex);
size_t len = u_arraylist_length(g_context.multicastDataList);
for (size_t i = 0; i < len; i++)
{
CABlockMulticastData_t *currData =
(CABlockMulticastData_t *) u_arraylist_get(g_context.multicastDataList, i);
if ((tokenLength >= currData->tokenLength)
&& !memcmp(token, currData->token, currData->tokenLength))
{
oc_mutex_unlock(g_context.multicastDataListMutex);
return currData;
}
}
oc_mutex_unlock(g_context.multicastDataListMutex);
return NULL;
}
CAResult_t CARemoveAllBlockMulticastDataFromList()
{
OIC_LOG(DEBUG, TAG, "CARemoveAllBlockMulticastDataFromList");
oc_mutex_lock(g_context.multicastDataListMutex);
size_t len = u_arraylist_length(g_context.multicastDataList);
for (size_t i = len; i > 0; i--)
{
CABlockMulticastData_t *removedData =
u_arraylist_remove(g_context.multicastDataList, i - 1);
if (removedData)
{
// destroy memory
OICFree(removedData->resourceUri);
OICFree(removedData->token);
OICFree(removedData);
}
}
oc_mutex_unlock(g_context.multicastDataListMutex);
return CA_STATUS_OK;
}
CAResult_t CARemoveBlockMulticastDataFromListWithSeed(const CAToken_t token, uint8_t tokenLength)
{
oc_mutex_lock(g_context.multicastDataListMutex);
size_t len = u_arraylist_length(g_context.multicastDataList);
for (size_t i = 0; i < len; i++)
{
CABlockMulticastData_t *currData =
(CABlockMulticastData_t *) u_arraylist_get(g_context.multicastDataList, i);
if ((tokenLength >= currData->tokenLength)
&& !memcmp(token, currData->token, currData->tokenLength))
{
CABlockMulticastData_t *removedData =
u_arraylist_remove(g_context.multicastDataList, i);
if (!removedData)
{
OIC_LOG(ERROR, TAG, "data is NULL");
oc_mutex_unlock(g_context.multicastDataListMutex);
return CA_STATUS_FAILED;
}
// destroy memory
OICFree(removedData->resourceUri);
OICFree(removedData->token);
OICFree(removedData);
oc_mutex_unlock(g_context.multicastDataListMutex);
return CA_STATUS_OK;
}
}
oc_mutex_unlock(g_context.multicastDataListMutex);
return CA_STATUS_OK;
}
......@@ -43,6 +43,7 @@
#include "oic_string.h"
#include "ocrandom.h"
#include "cacommonutil.h"
#include "cablockwisetransfer.h"
#define TAG "OIC_CA_PRTCL_MSG"
......@@ -1139,14 +1140,15 @@ CAResult_t CAGenerateTokenInternal(CAToken_t *token, uint8_t tokenLength)
return CA_STATUS_INVALID_PARAM;
}
// memory allocation
char *temp = (char *) OICCalloc(tokenLength, sizeof(char));
// memory allocation, token is stored as a Pascal-style string
char *temp = (char *) OICCalloc(tokenLength + 1, sizeof(char));
if (NULL == temp)
{
OIC_LOG(ERROR, TAG, "Out of memory");
return CA_MEMORY_ALLOC_FAILED;
}
*temp++ = tokenLength;
if (!OCGetRandomBytes((uint8_t *)temp, tokenLength))
{
OIC_LOG(ERROR, TAG, "Failed to generate random token");
......@@ -1164,7 +1166,14 @@ CAResult_t CAGenerateTokenInternal(CAToken_t *token, uint8_t tokenLength)
void CADestroyTokenInternal(CAToken_t token)
{
OICFree(token);
if (token)
{
char *temp = token - 1;
#ifdef WITH_BWT
CARemoveBlockMulticastDataFromListWithSeed(token, *temp);
#endif
OICFree(temp);
}
}
uint32_t CAGetOptionData(uint16_t key, const uint8_t *data, uint32_t len,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment