Commit 65051869 authored by Kishen Maloor's avatar Kishen Maloor

coap:fix bug in client blockwise transfer flow

Signed-off-by: Kishen Maloor's avatarKishen Maloor <kishen.maloor@intel.com>
parent 21fe3cb6
......@@ -206,6 +206,35 @@ oc_blockwise_scrub_buffers(bool all)
}
#ifdef OC_CLIENT
static oc_blockwise_state_t *
oc_blockwise_find_buffer_by_token(oc_list_t list, uint8_t *token,
uint8_t token_len)
{
oc_blockwise_state_t *buffer = oc_list_head(list);
while (buffer) {
if (token_len > 0 && buffer->role == OC_BLOCKWISE_CLIENT &&
buffer->token_len == token_len &&
memcmp(buffer->token, token, token_len) == 0)
break;
buffer = buffer->next;
}
return buffer;
}
oc_blockwise_state_t *
oc_blockwise_find_request_buffer_by_token(uint8_t *token, uint8_t token_len)
{
return oc_blockwise_find_buffer_by_token(oc_blockwise_requests, token,
token_len);
}
oc_blockwise_state_t *
oc_blockwise_find_response_buffer_by_token(uint8_t *token, uint8_t token_len)
{
return oc_blockwise_find_buffer_by_token(oc_blockwise_responses, token,
token_len);
}
static oc_blockwise_state_t *
oc_blockwise_find_buffer_by_mid(oc_list_t list, uint16_t mid)
{
......@@ -328,8 +357,9 @@ oc_blockwise_handle_block(oc_blockwise_state_t *buffer,
{
if (incoming_block_offset >= (unsigned)OC_MAX_APP_DATA_SIZE ||
incoming_block_size > (OC_MAX_APP_DATA_SIZE - incoming_block_offset) ||
incoming_block_offset > buffer->next_block_offset)
incoming_block_offset > buffer->next_block_offset) {
return false;
}
if (buffer->next_block_offset == incoming_block_offset) {
memcpy(&buffer->buffer[buffer->next_block_offset], incoming_block,
......
......@@ -1343,6 +1343,7 @@ oc_ri_invoke_client_cb(void *response, oc_client_cb_t *cb,
} else {
if (pkt->type == COAP_TYPE_ACK && pkt->code == 0) {
separate = true;
cb->separate = 1;
} else if (!cb->discovery) {
oc_response_handler_t handler =
(oc_response_handler_t)cb->handler.response;
......
......@@ -52,6 +52,8 @@ typedef struct oc_blockwise_state_s
#endif /* !OC_DYNAMIC_ALLOCATION */
oc_string_t uri_query;
#ifdef OC_CLIENT
uint8_t token[COAP_TOKEN_LEN];
uint8_t token_len;
uint16_t mid;
void *client_cb;
#endif /* OC_CLIENT */
......@@ -76,6 +78,12 @@ oc_blockwise_state_t *oc_blockwise_find_request_buffer_by_mid(uint16_t mid);
oc_blockwise_state_t *oc_blockwise_find_response_buffer_by_mid(uint16_t mid);
oc_blockwise_state_t *oc_blockwise_find_request_buffer_by_token(
uint8_t *token, uint8_t token_len);
oc_blockwise_state_t *oc_blockwise_find_response_buffer_by_token(
uint8_t *token, uint8_t token_len);
oc_blockwise_state_t *oc_blockwise_find_request_buffer_by_client_cb(
oc_endpoint_t *endpoint, void *client_cb);
......
......@@ -85,6 +85,7 @@ typedef struct oc_client_cb_t
bool multicast;
bool stop_multicast_receive;
uint8_t ref_count;
uint8_t separate;
} oc_client_cb_t;
#ifdef OC_BLOCK_WISE
......
......@@ -150,6 +150,10 @@ coap_receive(oc_message_t *msg)
oc_blockwise_state_t *request_buffer = NULL, *response_buffer = NULL;
#endif /* OC_BLOCK_WISE */
#ifdef OC_CLIENT
oc_client_cb_t *client_cb = 0;
#endif /* OC_CLIENT */
#ifdef OC_TCP
if (msg->endpoint.flags & TCP) {
coap_status_code =
......@@ -544,7 +548,6 @@ coap_receive(oc_message_t *msg)
uint16_t response_mid = coap_get_mid();
bool error_response = false;
#endif /* OC_BLOCK_WISE */
oc_client_cb_t *client_cb = 0;
if (message->type != COAP_TYPE_RST) {
client_cb =
oc_ri_find_client_cb_by_token(message->token, message->token_len);
......@@ -574,6 +577,10 @@ coap_receive(oc_message_t *msg)
&msg->endpoint, client_cb);
} else {
request_buffer = oc_blockwise_find_request_buffer_by_mid(message->mid);
if (!request_buffer) {
request_buffer = oc_blockwise_find_request_buffer_by_token(
message->token, message->token_len);
}
}
if (!error_response && request_buffer &&
(block1 || message->code == REQUEST_ENTITY_TOO_LARGE_4_13)) {
......@@ -654,6 +661,10 @@ coap_receive(oc_message_t *msg)
} else {
response_buffer =
oc_blockwise_find_response_buffer_by_mid(message->mid);
if (!response_buffer) {
response_buffer = oc_blockwise_find_response_buffer_by_token(
message->token, message->token_len);
}
}
if (!error_response && response_buffer) {
OC_DBG("got response buffer for uri %s",
......@@ -709,11 +720,12 @@ coap_receive(oc_message_t *msg)
* signal from the server. In this case, the client_cb continues
* to live until the response arrives (or it times out).
*/
if (!oc_ri_is_client_cb_valid(client_cb)) {
if (client_cb->separate == 0) {
if (response_buffer) {
response_buffer->ref_count = 0;
}
}
client_cb->separate = 0;
goto send_message;
#else /* OC_BLOCK_WISE */
oc_ri_invoke_client_cb(message, client_cb, &msg->endpoint);
......@@ -765,6 +777,16 @@ send_message:
i += sizeof(r);
}
response->token_len = (uint8_t)i;
if (request_buffer) {
memcpy(request_buffer->token, response->token,
response->token_len);
request_buffer->token_len = response->token_len;
}
if (response_buffer) {
memcpy(response_buffer->token, response->token,
response->token_len);
response_buffer->token_len = response->token_len;
}
} else {
coap_set_token(response, message->token, message->token_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