lib: updatehub: Add download block check
The current CoAP implementation not perform any checks including duplicated packets. This add block sequency verification and a timer to ensures that slow networks works apropriately. Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
This commit is contained in:
parent
092b962350
commit
3add3d7b60
5 changed files with 151 additions and 17 deletions
|
@ -9,4 +9,5 @@ zephyr_library()
|
|||
zephyr_library_sources_ifdef(CONFIG_UPDATEHUB updatehub.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_UPDATEHUB updatehub_device.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_UPDATEHUB updatehub_firmware.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_UPDATEHUB updatehub_timer.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_UPDATEHUB_SHELL shell.c)
|
||||
|
|
|
@ -86,6 +86,14 @@ config UPDATEHUB_DTLS
|
|||
Enables DTLS communication between the UpdateHub
|
||||
client and the server
|
||||
|
||||
config UPDATEHUB_COAP_CONN_TIMEOUT
|
||||
int "CoAP connection timeout in seconds"
|
||||
default 10
|
||||
range 1 360
|
||||
depends on UPDATEHUB
|
||||
help
|
||||
Set the CoAP connection timeout value.
|
||||
|
||||
config UPDATEHUB_COAP_MAX_RETRY
|
||||
int "Maximum retries attempts to download a packet"
|
||||
default 10
|
||||
|
|
|
@ -26,6 +26,7 @@ LOG_MODULE_REGISTER(updatehub, CONFIG_UPDATEHUB_LOG_LEVEL);
|
|||
#include "updatehub_priv.h"
|
||||
#include "updatehub_firmware.h"
|
||||
#include "updatehub_device.h"
|
||||
#include "updatehub_timer.h"
|
||||
|
||||
#if defined(CONFIG_UPDATEHUB_DTLS)
|
||||
#define CA_CERTIFICATE_TAG 1
|
||||
|
@ -363,6 +364,29 @@ static bool install_update_cb_sha256(void)
|
|||
return true;
|
||||
}
|
||||
|
||||
static int install_update_cb_check_blk_num(struct coap_packet *resp)
|
||||
{
|
||||
int blk_num;
|
||||
int blk2_opt;
|
||||
|
||||
blk2_opt = coap_get_option_int(resp, COAP_OPTION_BLOCK2);
|
||||
|
||||
if ((resp->max_len - resp->offset) <= 0 || (blk2_opt < 0)) {
|
||||
LOG_DBG("Invalid data received or block number is < 0");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
blk_num = GET_BLOCK_NUM(blk2_opt);
|
||||
|
||||
if (blk_num == updatehub_blk_get(UPDATEHUB_BLK_INDEX)) {
|
||||
updatehub_blk_inc(UPDATEHUB_BLK_INDEX);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
static void install_update_cb(void)
|
||||
{
|
||||
struct coap_packet response_packet;
|
||||
|
@ -390,6 +414,15 @@ static void install_update_cb(void)
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
if (install_update_cb_check_blk_num(&response_packet) < 0) {
|
||||
ctx.code_status = UPDATEHUB_DOWNLOAD_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
updatehub_tmr_stop();
|
||||
updatehub_blk_set(UPDATEHUB_BLK_ATTEMPT, 0);
|
||||
updatehub_blk_set(UPDATEHUB_BLK_TX_AVAILABLE, 1);
|
||||
|
||||
ctx.downloaded_size = ctx.downloaded_size +
|
||||
(response_packet.max_len - response_packet.offset);
|
||||
|
||||
|
@ -438,9 +471,6 @@ cleanup:
|
|||
|
||||
static enum updatehub_response install_update(void)
|
||||
{
|
||||
int verification_download = 0;
|
||||
int attempts_download = 0;
|
||||
|
||||
if (boot_erase_img_bank(FLASH_AREA_ID(image_1)) != 0) {
|
||||
LOG_ERR("Failed to init flash and erase second slot");
|
||||
ctx.code_status = UPDATEHUB_FLASH_INIT_ERROR;
|
||||
|
@ -469,31 +499,43 @@ static enum updatehub_response install_update(void)
|
|||
flash_img_init(&ctx.flash_ctx);
|
||||
|
||||
ctx.downloaded_size = 0;
|
||||
updatehub_blk_set(UPDATEHUB_BLK_ATTEMPT, 0);
|
||||
updatehub_blk_set(UPDATEHUB_BLK_INDEX, 0);
|
||||
updatehub_blk_set(UPDATEHUB_BLK_TX_AVAILABLE, 1);
|
||||
|
||||
while (ctx.downloaded_size != ctx.block.total_size) {
|
||||
verification_download = ctx.downloaded_size;
|
||||
|
||||
if (updatehub_blk_get(UPDATEHUB_BLK_TX_AVAILABLE)) {
|
||||
if (send_request(COAP_TYPE_CON, COAP_METHOD_GET,
|
||||
UPDATEHUB_DOWNLOAD) < 0) {
|
||||
ctx.code_status = UPDATEHUB_NETWORKING_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
updatehub_blk_set(UPDATEHUB_BLK_TX_AVAILABLE, 0);
|
||||
updatehub_blk_inc(UPDATEHUB_BLK_ATTEMPT);
|
||||
updatehub_tmr_start();
|
||||
}
|
||||
|
||||
install_update_cb();
|
||||
|
||||
if (ctx.code_status != UPDATEHUB_OK) {
|
||||
if (ctx.code_status == UPDATEHUB_OK) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ctx.code_status != UPDATEHUB_DOWNLOAD_ERROR &&
|
||||
ctx.code_status != UPDATEHUB_NETWORKING_ERROR) {
|
||||
LOG_DBG("status: %d", ctx.code_status);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (verification_download == ctx.downloaded_size) {
|
||||
if (attempts_download ==
|
||||
if (updatehub_blk_get(UPDATEHUB_BLK_ATTEMPT) ==
|
||||
CONFIG_UPDATEHUB_COAP_MAX_RETRY) {
|
||||
updatehub_tmr_stop();
|
||||
|
||||
LOG_ERR("Could not get the packet");
|
||||
ctx.code_status = UPDATEHUB_DOWNLOAD_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
attempts_download++;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
@ -719,6 +761,9 @@ enum updatehub_response updatehub_probe(void)
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
LOG_DBG("metadata size: %d", strlen(metadata));
|
||||
LOG_HEXDUMP_DBG(metadata, MAX_DOWNLOAD_DATA, "metadata");
|
||||
|
||||
memcpy(metadata_copy, metadata, strlen(metadata));
|
||||
if (json_obj_parse(metadata, strlen(metadata),
|
||||
recv_probe_sh_array_descr,
|
||||
|
@ -747,6 +792,7 @@ enum updatehub_response updatehub_probe(void)
|
|||
metadata_any_boards.objects[1].objects.sha256sum,
|
||||
SHA256_HEX_DIGEST_SIZE);
|
||||
update_info.image_size = metadata_any_boards.objects[1].objects.size;
|
||||
LOG_DBG("metadata_any: %s", update_info.sha256sum_image);
|
||||
} else {
|
||||
if (!is_compatible_hardware(&metadata_some_boards)) {
|
||||
LOG_ERR("Incompatible hardware");
|
||||
|
@ -769,6 +815,7 @@ enum updatehub_response updatehub_probe(void)
|
|||
SHA256_HEX_DIGEST_SIZE);
|
||||
update_info.image_size =
|
||||
metadata_some_boards.objects[1].objects.size;
|
||||
LOG_DBG("metadata_some: %s", update_info.sha256sum_image);
|
||||
}
|
||||
|
||||
ctx.code_status = UPDATEHUB_HAS_UPDATE;
|
||||
|
|
53
lib/updatehub/updatehub_timer.c
Normal file
53
lib/updatehub/updatehub_timer.c
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2020 O.S.Systems
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <logging/log.h>
|
||||
LOG_MODULE_DECLARE(updatehub, CONFIG_UPDATEHUB_LOG_LEVEL);
|
||||
|
||||
#include <zephyr.h>
|
||||
#include "updatehub_timer.h"
|
||||
|
||||
static int blk_vars[UPDATEHUB_BLK_MAX_VARS];
|
||||
|
||||
static void timer_expire(struct k_timer *timer)
|
||||
{
|
||||
LOG_DBG("tmr_expire");
|
||||
blk_vars[UPDATEHUB_BLK_TX_AVAILABLE] = 1;
|
||||
}
|
||||
|
||||
K_TIMER_DEFINE(uhu_packet_down_tmr, timer_expire, NULL);
|
||||
|
||||
int updatehub_blk_get(enum updatehub_blk_vars var)
|
||||
{
|
||||
LOG_DBG("blk_get[%d] = %d", var, blk_vars[var]);
|
||||
return blk_vars[var];
|
||||
}
|
||||
|
||||
void updatehub_blk_inc(enum updatehub_blk_vars var)
|
||||
{
|
||||
blk_vars[var]++;
|
||||
LOG_DBG("blk_inc[%d] = %d", var, blk_vars[var]);
|
||||
}
|
||||
|
||||
void updatehub_blk_set(enum updatehub_blk_vars var, int val)
|
||||
{
|
||||
LOG_DBG("blk_set[%d] = %d", var, val);
|
||||
blk_vars[var] = val;
|
||||
}
|
||||
|
||||
void updatehub_tmr_start(void)
|
||||
{
|
||||
LOG_DBG("tmr_start");
|
||||
k_timer_start(&uhu_packet_down_tmr,
|
||||
K_SECONDS(CONFIG_UPDATEHUB_COAP_CONN_TIMEOUT),
|
||||
K_NO_WAIT);
|
||||
}
|
||||
|
||||
void updatehub_tmr_stop(void)
|
||||
{
|
||||
LOG_DBG("tmr_stop");
|
||||
k_timer_stop(&uhu_packet_down_tmr);
|
||||
}
|
25
lib/updatehub/updatehub_timer.h
Normal file
25
lib/updatehub/updatehub_timer.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2020 O.S.Systems
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __UPDATEHUB_TIMER_H__
|
||||
#define __UPDATEHUB_TIMER_H__
|
||||
|
||||
enum updatehub_blk_vars {
|
||||
UPDATEHUB_BLK_ATTEMPT,
|
||||
UPDATEHUB_BLK_INDEX,
|
||||
UPDATEHUB_BLK_TX_AVAILABLE,
|
||||
|
||||
UPDATEHUB_BLK_MAX_VARS,
|
||||
};
|
||||
|
||||
int updatehub_blk_get(enum updatehub_blk_vars var);
|
||||
void updatehub_blk_inc(enum updatehub_blk_vars var);
|
||||
void updatehub_blk_set(enum updatehub_blk_vars var, int val);
|
||||
|
||||
void updatehub_tmr_start(void);
|
||||
void updatehub_tmr_stop(void);
|
||||
|
||||
#endif /* __UPDATEHUB_TIMER_H__ */
|
Loading…
Add table
Add a link
Reference in a new issue