net: lwm2m: response to peer with correct error code when write fail

Update the firmware update_result accordingly by checking return
value of the firmware data write callback registered by application.
Also, set response code according.

Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
This commit is contained in:
Robert Chou 2017-11-02 18:36:24 +08:00 committed by Jukka Rissanen
parent d36b3251fa
commit 3ad6719fbf
3 changed files with 51 additions and 39 deletions

View file

@ -2674,6 +2674,8 @@ error:
msg->code = COAP_RESPONSE_CODE_NOT_ALLOWED;
} else if (r == -EEXIST) {
msg->code = COAP_RESPONSE_CODE_BAD_REQUEST;
} else if (r == -EFAULT) {
msg->code = COAP_RESPONSE_CODE_INCOMPLETE;
} else if (r == -EFBIG) {
msg->code = COAP_RESPONSE_CODE_REQUEST_TOO_LARGE;
} else {

View file

@ -177,7 +177,7 @@ static int package_write_cb(u16_t obj_inst_id,
bool last_block, size_t total_size)
{
u8_t state;
int ret = 0;
int ret;
state = lwm2m_firmware_get_update_state();
if (state == STATE_IDLE) {
@ -196,19 +196,25 @@ static int package_write_cb(u16_t obj_inst_id,
return -EPERM;
}
if (write_cb) {
ret = write_cb(obj_inst_id, data, data_len,
last_block, total_size);
if (ret < 0) {
SYS_LOG_ERR("Failed to store firmware: %d", ret);
lwm2m_firmware_set_update_result(
RESULT_INTEGRITY_FAILED);
return ret;
ret = write_cb ? write_cb(obj_inst_id, data, data_len,
last_block, total_size) : 0;
if (ret >= 0) {
if (last_block) {
lwm2m_firmware_set_update_state(STATE_DOWNLOADED);
}
}
if (last_block) {
lwm2m_firmware_set_update_state(STATE_DOWNLOADED);
return 0;
} else if (ret == -ENOMEM) {
lwm2m_firmware_set_update_result(RESULT_OUT_OF_MEM);
} else if (ret == -ENOSPC) {
lwm2m_firmware_set_update_result(RESULT_NO_STORAGE);
/* Response 4.13 (RFC7959, section 2.9.3) */
/* TODO: should include size1 option to indicate max size */
ret = -EFBIG;
} else if (ret == -EFAULT) {
lwm2m_firmware_set_update_result(RESULT_INTEGRITY_FAILED);
} else {
lwm2m_firmware_set_update_result(RESULT_UPDATE_FAILED);
}
return ret;

View file

@ -216,7 +216,7 @@ do_firmware_transfer_reply_cb(const struct coap_packet *response,
const struct sockaddr *from)
{
int ret;
size_t transfer_offset = 0;
bool last_block;
u8_t token[8];
u8_t tkl;
u16_t payload_len, payload_offset, len;
@ -239,7 +239,7 @@ do_firmware_transfer_reply_cb(const struct coap_packet *response,
ret = transfer_empty_ack(coap_header_get_id(check_response));
if (ret < 0) {
SYS_LOG_ERR("Error transmitting ACK");
return ret;
goto error;
}
}
@ -249,8 +249,8 @@ do_firmware_transfer_reply_cb(const struct coap_packet *response,
SYS_LOG_ERR("Unexpected response from server: %d.%d",
COAP_RESPONSE_CODE_CLASS(resp_code),
COAP_RESPONSE_CODE_DETAIL(resp_code));
lwm2m_firmware_set_update_result(RESULT_CONNECTION_LOST);
return -ENOENT;
ret = -ENOMSG;
goto error;
}
/* save main firmware block context */
@ -260,8 +260,8 @@ do_firmware_transfer_reply_cb(const struct coap_packet *response,
ret = coap_update_from_block(check_response, &firmware_block_ctx);
if (ret < 0) {
SYS_LOG_ERR("Error from block update: %d", ret);
lwm2m_firmware_set_update_result(RESULT_INTEGRITY_FAILED);
return ret;
ret = -EFAULT;
goto error;
}
/* test for duplicate transfer */
@ -274,8 +274,8 @@ do_firmware_transfer_reply_cb(const struct coap_packet *response,
return 0;
}
/* Reach last block if transfer_offset equals to 0 */
transfer_offset = coap_next_block(check_response, &firmware_block_ctx);
/* Reach last block if ret equals to 0 */
last_block = !coap_next_block(check_response, &firmware_block_ctx);
/* Process incoming data */
payload_frag = coap_packet_get_payload(check_response, &payload_offset,
@ -288,7 +288,7 @@ do_firmware_transfer_reply_cb(const struct coap_packet *response,
/* look up firmware package resource */
ret = lwm2m_engine_get_resource("5/0/0", &res);
if (ret < 0) {
return ret;
goto error;
}
/* get buffer data */
@ -314,33 +314,22 @@ do_firmware_transfer_reply_cb(const struct coap_packet *response,
write_buf);
/* check for end of packet */
if (!payload_frag && payload_offset == 0xffff) {
lwm2m_firmware_set_update_result(
RESULT_INTEGRITY_FAILED);
return -EINVAL;
/* malformed packet */
ret = -EFAULT;
goto error;
}
ret = write_cb(0, write_buf, len,
!payload_frag &&
transfer_offset == 0,
!payload_frag && last_block,
firmware_block_ctx.total_size);
if (ret == -ENOMEM) {
lwm2m_firmware_set_update_result(
RESULT_OUT_OF_MEM);
return ret;
} else if (ret == -ENOSPC) {
lwm2m_firmware_set_update_result(
RESULT_NO_STORAGE);
return ret;
} else if (ret < 0) {
lwm2m_firmware_set_update_result(
RESULT_INTEGRITY_FAILED);
return ret;
if (ret < 0) {
goto error;
}
}
}
}
if (transfer_offset > 0) {
if (!last_block) {
/* More block(s) to come, setup next transfer */
ret = transfer_request(&firmware_block_ctx, token, tkl,
do_firmware_transfer_reply_cb);
@ -349,6 +338,21 @@ do_firmware_transfer_reply_cb(const struct coap_packet *response,
lwm2m_firmware_set_update_state(STATE_DOWNLOADED);
}
return 0;
error:
if (ret == -ENOMEM) {
lwm2m_firmware_set_update_result(RESULT_OUT_OF_MEM);
} else if (ret == -ENOSPC) {
lwm2m_firmware_set_update_result(RESULT_NO_STORAGE);
} else if (ret == -EFAULT) {
lwm2m_firmware_set_update_result(RESULT_INTEGRITY_FAILED);
} else if (ret == -ENOMSG) {
lwm2m_firmware_set_update_result(RESULT_CONNECTION_LOST);
} else {
lwm2m_firmware_set_update_result(RESULT_UPDATE_FAILED);
}
return ret;
}