From 8e5812d21832a1f40334f8aaa72ff977beb45d66 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Tue, 17 May 2022 12:00:05 +0200 Subject: [PATCH] suit/transport: move common code to new file --- sys/Makefile.dep | 1 + sys/include/suit.h | 7 + sys/shell/commands/Makefile | 2 +- sys/shell/commands/shell_commands.c | 4 +- sys/suit/transport/coap.c | 194 +++------------------------- sys/suit/transport/worker.c | 186 ++++++++++++++++++++++++++ 6 files changed, 216 insertions(+), 178 deletions(-) create mode 100644 sys/suit/transport/worker.c diff --git a/sys/Makefile.dep b/sys/Makefile.dep index ac747e24cb..1f46dc7690 100644 --- a/sys/Makefile.dep +++ b/sys/Makefile.dep @@ -846,6 +846,7 @@ endif ifneq (,$(filter suit_transport_%, $(USEMODULE))) USEMODULE += suit_transport + USEMODULE += suit_transport_worker endif ifneq (,$(filter suit_transport_coap, $(USEMODULE))) diff --git a/sys/include/suit.h b/sys/include/suit.h index 008b8c4db5..6a7a09078d 100644 --- a/sys/include/suit.h +++ b/sys/include/suit.h @@ -62,6 +62,13 @@ extern "C" { #define CONFIG_SUIT_COMPONENT_MAX_NAME_LEN (32U) #endif +/** + * @brief Maximum length of a SUIT resource URL + */ +#ifndef SUIT_URL_MAX +#define SUIT_URL_MAX 128 +#endif + /** * @brief Current SUIT serialization format version * diff --git a/sys/shell/commands/Makefile b/sys/shell/commands/Makefile index e3f4835565..673d1ca407 100644 --- a/sys/shell/commands/Makefile +++ b/sys/shell/commands/Makefile @@ -134,7 +134,7 @@ ifneq (,$(filter nimble_statconn,$(USEMODULE))) SRC += sc_nimble_statconn.c endif -ifneq (,$(filter suit_transport_coap,$(USEMODULE))) +ifneq (,$(filter suit_transport_worker,$(USEMODULE))) SRC += sc_suit.c endif diff --git a/sys/shell/commands/shell_commands.c b/sys/shell/commands/shell_commands.c index 53b09da120..fbdbdaab54 100644 --- a/sys/shell/commands/shell_commands.c +++ b/sys/shell/commands/shell_commands.c @@ -203,7 +203,7 @@ extern int _nimble_netif_handler(int argc, char **argv); extern int _nimble_statconn_handler(int argc, char **argv); #endif -#ifdef MODULE_SUIT_TRANSPORT_COAP +#ifdef MODULE_SUIT_TRANSPORT_WORKER extern int _suit_handler(int argc, char **argv); #endif @@ -382,7 +382,7 @@ const shell_command_t _shell_command_list[] = { #ifdef MODULE_NIMBLE_STATCONN { "statconn", "NimBLE netif statconn", _nimble_statconn_handler}, #endif -#ifdef MODULE_SUIT_TRANSPORT_COAP +#ifdef MODULE_SUIT_TRANSPORT_WORKER { "suit", "Trigger a SUIT firmware update", _suit_handler }, #endif #ifdef MODULE_CRYPTOAUTHLIB diff --git a/sys/suit/transport/coap.c b/sys/suit/transport/coap.c index 5015bdfa59..4be72700ab 100644 --- a/sys/suit/transport/coap.c +++ b/sys/suit/transport/coap.c @@ -22,163 +22,16 @@ * @} */ -#include -#include -#include - -#include "msg.h" #include "log.h" +#include "suit.h" #include "net/nanocoap.h" -#include "net/nanocoap_sock.h" -#include "thread.h" -#include "periph/pm.h" -#include "ztimer.h" - -#ifdef MODULE_SUIT_TRANSPORT_COAP #include "suit/transport/coap.h" -#include "net/sock/util.h" -#endif -#ifdef MODULE_SUIT_TRANSPORT_VFS -#include "vfs_util.h" -#endif +#include "kernel_defines.h" #ifdef MODULE_RIOTBOOT_SLOT #include "riotboot/slot.h" #endif -#ifdef MODULE_SUIT -#include "suit.h" -#include "suit/handlers.h" -#include "suit/storage.h" -#endif - -#if defined(MODULE_PROGRESS_BAR) -#include "progress_bar.h" -#endif - -#define ENABLE_DEBUG 0 -#include "debug.h" - -#ifndef SUIT_COAP_STACKSIZE -/* allocate stack needed to do manifest validation */ -#define SUIT_COAP_STACKSIZE (3 * THREAD_STACKSIZE_LARGE) -#endif - -#ifndef SUIT_COAP_PRIO -#define SUIT_COAP_PRIO THREAD_PRIORITY_MAIN - 1 -#endif - -#ifndef SUIT_URL_MAX -#define SUIT_URL_MAX 128 -#endif - -#ifndef SUIT_MANIFEST_BUFSIZE -#define SUIT_MANIFEST_BUFSIZE 640 -#endif - -#define SUIT_MSG_TRIGGER 0x12345 - -static char _stack[SUIT_COAP_STACKSIZE]; -static char _url[SUIT_URL_MAX]; -static uint8_t _manifest_buf[SUIT_MANIFEST_BUFSIZE]; - -static kernel_pid_t _suit_coap_pid; - -static void _suit_handle_url(const char *url, coap_blksize_t blksize) -{ - ssize_t size; - LOG_INFO("suit_coap: downloading \"%s\"\n", url); - - if (0) {} -#ifdef MODULE_SUIT_TRANSPORT_COAP - else if (strncmp(url, "coap://", 7) == 0) { - size = nanocoap_get_blockwise_url_to_buf(url, blksize, - _manifest_buf, - sizeof(_manifest_buf)); - } -#endif -#ifdef MODULE_SUIT_TRANSPORT_VFS - else if (strncmp(url, "file:/", 6) == 0) { - size = vfs_file_to_buffer(&url[6], _manifest_buf, sizeof(_manifest_buf)); - } -#endif - else { - LOG_WARNING("suit_coap: unsupported URL scheme!\n)"); - return; - } - - if (size >= 0) { - LOG_INFO("suit_coap: got manifest with size %u\n", (unsigned)size); - -#ifdef MODULE_SUIT - suit_manifest_t manifest; - memset(&manifest, 0, sizeof(manifest)); - - manifest.urlbuf = _url; - manifest.urlbuf_len = SUIT_URL_MAX; - - int res; - if ((res = suit_parse(&manifest, _manifest_buf, size)) != SUIT_OK) { - LOG_INFO("suit_parse() failed. res=%i\n", res); - return; - } - -#endif -#ifdef MODULE_SUIT_STORAGE_FLASHWRITE - if (res == 0) { - const riotboot_hdr_t *hdr = riotboot_slot_get_hdr( - riotboot_slot_other()); - riotboot_hdr_print(hdr); - ztimer_sleep(ZTIMER_MSEC, 1 * MS_PER_SEC); - - if (riotboot_hdr_validate(hdr) == 0) { - LOG_INFO("suit_coap: rebooting...\n"); - pm_reboot(); - } - else { - LOG_INFO("suit_coap: update failed, hdr invalid\n "); - } - } -#endif - } - else { - LOG_INFO("suit_coap: error getting manifest\n"); - } -} - -static void *_suit_coap_thread(void *arg) -{ - (void)arg; - - LOG_INFO("suit_coap: started.\n"); - msg_t msg_queue[4]; - msg_init_queue(msg_queue, 4); - - _suit_coap_pid = thread_getpid(); - - msg_t m; - while (true) { - msg_receive(&m); - DEBUG("suit_coap: got msg with type %" PRIu32 "\n", m.content.value); - switch (m.content.value) { - case SUIT_MSG_TRIGGER: - LOG_INFO("suit_coap: trigger received\n"); - _suit_handle_url(_url, CONFIG_SUIT_COAP_BLOCKSIZE); - break; - default: - LOG_WARNING("suit_coap: warning: unhandled msg\n"); - } - } - return NULL; -} - -void suit_coap_run(void) -{ - thread_create(_stack, SUIT_COAP_STACKSIZE, SUIT_COAP_PRIO, - THREAD_CREATE_STACKTEST, - _suit_coap_thread, NULL, "suit_coap"); -} - static ssize_t _version_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, void *context) { @@ -187,25 +40,6 @@ static ssize_t _version_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, COAP_FORMAT_TEXT, (uint8_t *)"NONE", 4); } -#ifdef MODULE_RIOTBOOT_SLOT -static ssize_t _slot_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, - void *context) -{ - /* context is passed either as NULL or 0x1 for /active or /inactive */ - char c = '0'; - - if (context) { - c += riotboot_slot_other(); - } - else { - c += riotboot_slot_current(); - } - - return coap_reply_simple(pkt, COAP_CODE_205, buf, len, - COAP_FORMAT_TEXT, (uint8_t *)&c, 1); -} -#endif - static ssize_t _trigger_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, void *context) { @@ -230,21 +64,31 @@ static ssize_t _trigger_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, COAP_FORMAT_NONE, NULL, 0); } -void suit_coap_trigger(const uint8_t *url, size_t len) +#ifdef MODULE_RIOTBOOT_SLOT +static ssize_t _slot_handler(coap_pkt_t *pkt, uint8_t *buf, size_t len, + void *context) { - memcpy(_url, url, len); - _url[len] = '\0'; - msg_t m = { .content.value = SUIT_MSG_TRIGGER }; - msg_send(&m, _suit_coap_pid); + /* context is passed either as NULL or 0x1 for /active or /inactive */ + char c = '0'; + + if (context) { + c += riotboot_slot_other(); + } + else { + c += riotboot_slot_current(); + } + + return coap_reply_simple(pkt, COAP_CODE_205, buf, len, + COAP_FORMAT_TEXT, (uint8_t *)&c, 1); } +#endif static const coap_resource_t _subtree[] = { #ifdef MODULE_RIOTBOOT_SLOT { "/suit/slot/active", COAP_METHOD_GET, _slot_handler, NULL }, { "/suit/slot/inactive", COAP_METHOD_GET, _slot_handler, (void *)0x1 }, #endif - { "/suit/trigger", COAP_METHOD_PUT | COAP_METHOD_POST, _trigger_handler, - NULL }, + { "/suit/trigger", COAP_METHOD_PUT | COAP_METHOD_POST, _trigger_handler, NULL }, { "/suit/version", COAP_METHOD_GET, _version_handler, NULL }, }; diff --git a/sys/suit/transport/worker.c b/sys/suit/transport/worker.c new file mode 100644 index 0000000000..7b54c095e8 --- /dev/null +++ b/sys/suit/transport/worker.c @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2019 Freie Universität Berlin + * 2019 Inria + * 2019 Kaspar Schleiser + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup sys_suit + * @{ + * + * @file + * @brief SUIT transport worker thread + * + * @author Koen Zandberg + * @author Kaspar Schleiser + * @author Francisco Molina + * @author Alexandre Abadie + * @} + */ + +#include +#include +#include +#include + +#include "msg.h" +#include "log.h" +#include "thread.h" +#include "time_units.h" +#include "periph/pm.h" +#include "ztimer.h" + +#ifdef MODULE_SUIT_TRANSPORT_COAP +#include "net/nanocoap_sock.h" +#include "suit/transport/coap.h" +#include "net/sock/util.h" +#endif +#ifdef MODULE_SUIT_TRANSPORT_VFS +#include "vfs_util.h" +#endif + +#ifdef MODULE_RIOTBOOT_SLOT +#include "riotboot/slot.h" +#endif + +#ifdef MODULE_SUIT +#include "suit.h" +#include "suit/handlers.h" +#include "suit/storage.h" +#endif + +#if defined(MODULE_PROGRESS_BAR) +#include "progress_bar.h" +#endif + +#define ENABLE_DEBUG 0 +#include "debug.h" + +#ifndef SUIT_WORKER_STACKSIZE +/* allocate stack needed to do manifest validation */ +#define SUIT_WORKER_STACKSIZE (3 * THREAD_STACKSIZE_LARGE) +#endif + +#ifndef SUIT_COAP_WORKER_PRIO +#define SUIT_COAP_WORKER_PRIO THREAD_PRIORITY_MAIN - 1 +#endif + +#ifndef SUIT_MANIFEST_BUFSIZE +#define SUIT_MANIFEST_BUFSIZE 640 +#endif + +#define SUIT_MSG_TRIGGER 0x12345 + +static char _stack[SUIT_WORKER_STACKSIZE]; +static char _url[SUIT_URL_MAX]; +static uint8_t _manifest_buf[SUIT_MANIFEST_BUFSIZE]; + +static kernel_pid_t _suit_worker_pid; + +static void _suit_handle_url(const char *url) +{ + ssize_t size; + LOG_INFO("suit_worker: downloading \"%s\"\n", url); + + if (0) {} +#ifdef MODULE_SUIT_TRANSPORT_COAP + else if (strncmp(url, "coap://", 7) == 0) { + size = nanocoap_get_blockwise_url_to_buf(url, + CONFIG_SUIT_COAP_BLOCKSIZE, + _manifest_buf, + sizeof(_manifest_buf)); + } +#endif +#ifdef MODULE_SUIT_TRANSPORT_VFS + else if (strncmp(url, "file://", 7) == 0) { + size = vfs_file_to_buffer(&url[7], _manifest_buf, sizeof(_manifest_buf)); + } +#endif + else { + LOG_WARNING("suit_worker: unsupported URL scheme!\n)"); + return; + } + + if (size >= 0) { + LOG_INFO("suit_worker: got manifest with size %u\n", (unsigned)size); + +#ifdef MODULE_SUIT + suit_manifest_t manifest; + memset(&manifest, 0, sizeof(manifest)); + + manifest.urlbuf = _url; + manifest.urlbuf_len = SUIT_URL_MAX; + + int res; + if ((res = suit_parse(&manifest, _manifest_buf, size)) != SUIT_OK) { + LOG_INFO("suit_worker: suit_parse() failed. res=%i\n", res); + return; + } + +#endif +#ifdef MODULE_SUIT_STORAGE_FLASHWRITE + if (res == 0) { + const riotboot_hdr_t *hdr = riotboot_slot_get_hdr( + riotboot_slot_other()); + riotboot_hdr_print(hdr); + ztimer_sleep(ZTIMER_MSEC, 1 * MS_PER_SEC); + + if (riotboot_hdr_validate(hdr) == 0) { + LOG_INFO("suit_worker: rebooting...\n"); + pm_reboot(); + } + else { + LOG_INFO("suit_worker: update failed, hdr invalid\n "); + } + } +#endif + } + else { + LOG_INFO("suit_worker: error getting manifest\n"); + } +} + +static void *_suit_worker_thread(void *arg) +{ + (void)arg; + + LOG_INFO("suit_worker: started.\n"); + msg_t msg_queue[4]; + msg_init_queue(msg_queue, 4); + + _suit_worker_pid = thread_getpid(); + + msg_t m; + while (true) { + msg_receive(&m); + DEBUG("suit_worker: got msg with type %" PRIu32 "\n", m.content.value); + switch (m.content.value) { + case SUIT_MSG_TRIGGER: + LOG_INFO("suit_worker: trigger received\n"); + _suit_handle_url(_url); + break; + default: + LOG_WARNING("suit_worker: warning: unhandled msg\n"); + } + } + return NULL; +} + +void suit_coap_run(void) +{ + thread_create(_stack, SUIT_WORKER_STACKSIZE, SUIT_COAP_WORKER_PRIO, + THREAD_CREATE_STACKTEST, + _suit_worker_thread, NULL, "suit worker"); +} + +void suit_coap_trigger(const uint8_t *url, size_t len) +{ + memcpy(_url, url, len); + _url[len] = '\0'; + msg_t m = { .content.value = SUIT_MSG_TRIGGER }; + msg_send(&m, _suit_worker_pid); +}