Infineon: Add cyw20829 platform, shared slot feature, json memory map, psoc6 xip
Based in 1.8.0 release of MCUBoot library
This commit adds CYW20829 Infineon platform support with following capabilities:
1. Overwrite and swap upgrade mode support
2. Multi-image with up to 4 images
3. Hardware security counter is supported for CYW20829 platform
Add XIP support for PSOC6 platform - place BOOT slot in external memory and execute it in place using SMIF in XIP mode
and some new features for Infineon devices.
1. Shared upgrade slot feature - use one shared area for upgrade slots of multiple images
2. Memory map defined using JSON file - define memory regions for bootloader and user app in conventional way using JSON file
diff --git a/boot/boot_serial/pkg.yml b/boot/boot_serial/pkg.yml
index f1431c7..19f9a32 100644
--- a/boot/boot_serial/pkg.yml
+++ b/boot/boot_serial/pkg.yml
@@ -28,7 +28,6 @@
pkg.deps:
- "@apache-mynewt-core/hw/hal"
- "@apache-mynewt-core/kernel/os"
- - "@apache-mynewt-core/encoding/tinycbor"
- "@apache-mynewt-core/encoding/base64"
- "@mcuboot/boot/mynewt/flash_map_backend"
- "@mcuboot/boot/mynewt/boot_uart"
diff --git a/boot/boot_serial/src/boot_serial.c b/boot/boot_serial/src/boot_serial.c
index d0f0eb0..914167e 100644
--- a/boot/boot_serial/src/boot_serial.c
+++ b/boot/boot_serial/src/boot_serial.c
@@ -25,6 +25,7 @@
#include "sysflash/sysflash.h"
#include "bootutil/bootutil_log.h"
+#include "cbor_encode.h"
#ifdef __ZEPHYR__
#include <power/reboot.h>
@@ -33,8 +34,6 @@
#include <drivers/flash.h>
#include <sys/crc.h>
#include <sys/base64.h>
-#include <tinycbor/cbor.h>
-#include <tinycbor/cbor_buf_reader.h>
#else
#include <bsp/bsp.h>
#include <hal/hal_system.h>
@@ -42,7 +41,6 @@
#include <os/os_cputime.h>
#include <crc/crc16.h>
#include <base64/base64.h>
-#include <tinycbor/cbor.h>
#endif /* __ZEPHYR__ */
#include <flash_map_backend/flash_map_backend.h>
@@ -56,16 +54,21 @@
#include "boot_serial/boot_serial.h"
#include "boot_serial_priv.h"
-#ifdef CONFIG_BOOT_ERASE_PROGRESSIVELY
+#ifdef MCUBOOT_ERASE_PROGRESSIVELY
#include "bootutil_priv.h"
#endif
#include "serial_recovery_cbor.h"
+#include "bootutil/boot_hooks.h"
-MCUBOOT_LOG_MODULE_DECLARE(mcuboot);
+BOOT_LOG_MODULE_DECLARE(mcuboot);
+
+#ifndef BOOT_IMAGE_NUMBER
+#define BOOT_IMAGE_NUMBER MCUBOOT_IMAGE_NUMBER
+#endif
#define BOOT_SERIAL_INPUT_MAX 512
-#define BOOT_SERIAL_OUT_MAX 128
+#define BOOT_SERIAL_OUT_MAX (128 * MCUBOOT_IMAGE_NUMBER)
#ifdef __ZEPHYR__
/* base64 lib encodes data to null-terminated string */
@@ -78,10 +81,6 @@
#define htons(x) sys_cpu_to_be16(x)
#endif
-#ifndef BOOT_IMAGE_NUMBER
-#define BOOT_IMAGE_NUMBER MCUBOOT_IMAGE_NUMBER
-#endif
-
#if (BOOT_IMAGE_NUMBER > 1)
#define IMAGES_ITER(x) for ((x) = 0; (x) < BOOT_IMAGE_NUMBER; ++(x))
#else
@@ -97,28 +96,28 @@
static char bs_obuf[BOOT_SERIAL_OUT_MAX];
-static int bs_cbor_writer(struct cbor_encoder_writer *, const char *data,
- int len);
static void boot_serial_output(void);
-static struct cbor_encoder_writer bs_writer = {
- .write = bs_cbor_writer
+static cbor_state_backups_t dummy_backups;
+static cbor_state_t cbor_state = {
+ .backups = &dummy_backups
};
-static CborEncoder bs_root;
-static CborEncoder bs_rsp;
-int
-bs_cbor_writer(struct cbor_encoder_writer *cew, const char *data, int len)
-{
- if (cew->bytes_written + len > sizeof(bs_obuf)) {
- return CborErrorOutOfMemory;
- }
-
- memcpy(&bs_obuf[cew->bytes_written], data, len);
- cew->bytes_written += len;
-
- return 0;
-}
+/**
+ * Function that processes MGMT_GROUP_ID_PERUSER mcumgr group and may be
+ * used to process any groups that have not been processed by generic boot
+ * serial implementation.
+ *
+ * @param[in] hdr -- the decoded header of mcumgr message;
+ * @param[in] buffer -- buffer with first mcumgr message;
+ * @param[in] len -- length of of data in buffer;
+ * @param[out] *cs -- object with encoded response.
+ *
+ * @return 0 on success; non-0 error code otherwise.
+ */
+extern int bs_peruser_system_specific(const struct nmgr_hdr *hdr,
+ const char *buffer,
+ int len, cbor_state_t *cs);
/*
* Convert version into string without use of snprintf().
@@ -172,17 +171,15 @@
static void
bs_list(char *buf, int len)
{
- CborEncoder images;
- CborEncoder image;
struct image_header hdr;
uint8_t tmpbuf[64];
- int slot, area_id;
+ uint32_t slot, area_id;
const struct flash_area *fap;
uint8_t image_index;
- cbor_encoder_create_map(&bs_root, &bs_rsp, CborIndefiniteLength);
- cbor_encode_text_stringz(&bs_rsp, "images");
- cbor_encoder_create_array(&bs_rsp, &images, CborIndefiniteLength);
+ map_start_encode(&cbor_state, 1);
+ tstrx_put(&cbor_state, "images");
+ list_start_encode(&cbor_state, 5);
image_index = 0;
IMAGES_ITER(image_index) {
for (slot = 0; slot < 2; slot++) {
@@ -191,34 +188,51 @@
continue;
}
- flash_area_read(fap, 0, &hdr, sizeof(hdr));
-
- if (hdr.ih_magic != IMAGE_MAGIC ||
- bootutil_img_validate(NULL, 0, &hdr, fap, tmpbuf, sizeof(tmpbuf),
- NULL, 0, NULL)) {
- flash_area_close(fap);
- continue;
+ int rc = BOOT_HOOK_CALL(boot_read_image_header_hook,
+ BOOT_HOOK_REGULAR, image_index, slot, &hdr);
+ if (rc == BOOT_HOOK_REGULAR)
+ {
+ flash_area_read(fap, 0, &hdr, sizeof(hdr));
}
+
+ fih_int fih_rc = FIH_FAILURE;
+
+ if (hdr.ih_magic == IMAGE_MAGIC)
+ {
+ BOOT_HOOK_CALL_FIH(boot_image_check_hook,
+ fih_int_encode(BOOT_HOOK_REGULAR),
+ fih_rc, image_index, slot);
+ if (fih_eq(fih_rc, BOOT_HOOK_REGULAR))
+ {
+ FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, &hdr, fap, tmpbuf, sizeof(tmpbuf),
+ NULL, 0, NULL);
+ }
+ }
+
flash_area_close(fap);
- cbor_encoder_create_map(&images, &image, CborIndefiniteLength);
+ if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
+ continue;
+ }
+
+ map_start_encode(&cbor_state, 20);
#if (BOOT_IMAGE_NUMBER > 1)
- cbor_encode_text_stringz(&image, "image");
- cbor_encode_int(&image, image_index);
+ tstrx_put(&cbor_state, "image");
+ uintx32_put(&cbor_state, image_index);
#endif
- cbor_encode_text_stringz(&image, "slot");
- cbor_encode_int(&image, slot);
- cbor_encode_text_stringz(&image, "version");
+ tstrx_put(&cbor_state, "slot");
+ uintx32_put(&cbor_state, slot);
+ tstrx_put(&cbor_state, "version");
bs_list_img_ver((char *)tmpbuf, sizeof(tmpbuf), &hdr.ih_ver);
- cbor_encode_text_stringz(&image, (char *)tmpbuf);
- cbor_encoder_close_container(&images, &image);
+ tstrx_put_term(&cbor_state, (char *)tmpbuf);
+ map_end_encode(&cbor_state, 20);
}
}
- cbor_encoder_close_container(&bs_rsp, &images);
- cbor_encoder_close_container(&bs_root, &bs_rsp);
+ list_end_encode(&cbor_state, 5);
+ map_end_encode(&cbor_state, 1);
boot_serial_output();
}
@@ -229,15 +243,15 @@
bs_upload(char *buf, int len)
{
const uint8_t *img_data = NULL;
- long long int off = UINT_MAX;
+ long long int off = UINT64_MAX;
size_t img_blen = 0;
uint8_t rem_bytes;
- long long int data_len = UINT_MAX;
+ long long int data_len = UINT64_MAX;
int img_num;
size_t slen;
const struct flash_area *fap = NULL;
int rc;
-#ifdef CONFIG_BOOT_ERASE_PROGRESSIVELY
+#ifdef MCUBOOT_ERASE_PROGRESSIVELY
static off_t off_last = -1;
struct flash_sector sector;
#endif
@@ -254,13 +268,16 @@
* }
*/
- Upload_t upload;
- if (!cbor_decode_Upload((const uint8_t *)buf, len, &upload)) {
+ struct Upload upload;
+ uint32_t decoded_len;
+ bool result = cbor_decode_Upload((const uint8_t *)buf, len, &upload, &decoded_len);
+
+ if (!result || (len != decoded_len)) {
goto out_invalid_data;
}
for (int i = 0; i < upload._Upload_members_count; i++) {
- _Member_t *member = &upload._Upload_members[i];
+ struct Member_ *member = &upload._Upload_members[i];
switch(member->_Member_choice) {
case _Member_image:
img_num = member->_Member_image;
@@ -283,14 +300,18 @@
}
}
- if (off == UINT_MAX || img_data == NULL) {
+ if (off == UINT64_MAX || img_data == NULL) {
/*
* Offset must be set in every block.
*/
goto out_invalid_data;
}
+#if !defined(MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD)
rc = flash_area_open(flash_area_id_from_multi_image_slot(img_num, 0), &fap);
+#else
+ rc = flash_area_open(flash_area_id_from_direct_image(img_num), &fap);
+#endif
if (rc) {
rc = MGMT_ERR_EINVAL;
goto out;
@@ -298,11 +319,11 @@
if (off == 0) {
curr_off = 0;
- if (data_len > fap->fa_size) {
+ if (data_len > flash_area_get_size(fap)) {
goto out_invalid_data;
}
-#ifndef CONFIG_BOOT_ERASE_PROGRESSIVELY
- rc = flash_area_erase(fap, 0, fap->fa_size);
+#ifndef MCUBOOT_ERASE_PROGRESSIVELY
+ rc = flash_area_erase(fap, 0, flash_area_get_size(fap));
if (rc) {
goto out_invalid_data;
}
@@ -326,16 +347,17 @@
rem_bytes = 0;
}
-#ifdef CONFIG_BOOT_ERASE_PROGRESSIVELY
+#ifdef MCUBOOT_ERASE_PROGRESSIVELY
rc = flash_area_sector_from_off(curr_off + img_blen, §or);
if (rc) {
BOOT_LOG_ERR("Unable to determine flash sector size");
goto out;
}
- if (off_last != sector.fs_off) {
- off_last = sector.fs_off;
- BOOT_LOG_INF("Erasing sector at offset 0x%x", sector.fs_off);
- rc = flash_area_erase(fap, sector.fs_off, sector.fs_size);
+ if (off_last != flash_sector_get_off(§or)) {
+ off_last = flash_sector_get_off(§or);
+ BOOT_LOG_INF("Erasing sector at offset 0x%x", flash_sector_get_off(§or));
+ rc = flash_area_erase(fap, flash_sector_get_off(§or),
+ flash_sector_get_size(§or));
if (rc) {
BOOT_LOG_ERR("Error %d while erasing sector", rc);
goto out;
@@ -372,8 +394,8 @@
if (rc == 0) {
curr_off += img_blen;
-#ifdef CONFIG_BOOT_ERASE_PROGRESSIVELY
if (curr_off == img_size) {
+#ifdef MCUBOOT_ERASE_PROGRESSIVELY
/* get the last sector offset */
rc = flash_area_sector_from_off(boot_status_off(fap), §or);
if (rc) {
@@ -383,16 +405,24 @@
}
/* Assure that sector for image trailer was erased. */
/* Check whether it was erased during previous upload. */
- if (off_last < sector.fs_off) {
- BOOT_LOG_INF("Erasing sector at offset 0x%x", sector.fs_off);
- rc = flash_area_erase(fap, sector.fs_off, sector.fs_size);
+ if (off_last < flash_sector_get_off(§or)) {
+ BOOT_LOG_INF("Erasing sector at offset 0x%x",
+ flash_sector_get_off(§or));
+ rc = flash_area_erase(fap, flash_sector_get_off(§or),
+ flash_sector_get_size(§or));
if (rc) {
BOOT_LOG_ERR("Error %d while erasing sector", rc);
goto out;
}
}
- }
#endif
+ rc = BOOT_HOOK_CALL(boot_serial_uploaded_hook, 0, img_num, fap,
+ img_size);
+ if (rc) {
+ BOOT_LOG_ERR("Error %d post upload hook", rc);
+ goto out;
+ }
+ }
} else {
out_invalid_data:
rc = MGMT_ERR_EINVAL;
@@ -400,14 +430,14 @@
out:
BOOT_LOG_INF("RX: 0x%x", rc);
- cbor_encoder_create_map(&bs_root, &bs_rsp, CborIndefiniteLength);
- cbor_encode_text_stringz(&bs_rsp, "rc");
- cbor_encode_int(&bs_rsp, rc);
+ map_start_encode(&cbor_state, 10);
+ tstrx_put(&cbor_state, "rc");
+ uintx32_put(&cbor_state, rc);
if (rc == 0) {
- cbor_encode_text_stringz(&bs_rsp, "off");
- cbor_encode_uint(&bs_rsp, curr_off);
+ tstrx_put(&cbor_state, "off");
+ uintx32_put(&cbor_state, curr_off);
}
- cbor_encoder_close_container(&bs_root, &bs_rsp);
+ map_end_encode(&cbor_state, 10);
boot_serial_output();
flash_area_close(fap);
@@ -419,10 +449,10 @@
static void
bs_empty_rsp(char *buf, int len)
{
- cbor_encoder_create_map(&bs_root, &bs_rsp, CborIndefiniteLength);
- cbor_encode_text_stringz(&bs_rsp, "rc");
- cbor_encode_int(&bs_rsp, 0);
- cbor_encoder_close_container(&bs_root, &bs_rsp);
+ map_start_encode(&cbor_state, 10);
+ tstrx_put(&cbor_state, "rc");
+ uintx32_put(&cbor_state, 0);
+ map_end_encode(&cbor_state, 10);
boot_serial_output();
}
@@ -436,7 +466,11 @@
bs_empty_rsp(buf, len);
#ifdef __ZEPHYR__
+#ifdef CONFIG_MULTITHREADING
k_sleep(K_MSEC(250));
+#else
+ k_busy_wait(250000);
+#endif
sys_reboot(SYS_REBOOT_COLD);
#else
os_cputime_delay_usecs(250000);
@@ -465,8 +499,9 @@
buf += sizeof(*hdr);
len -= sizeof(*hdr);
- bs_writer.bytes_written = 0;
- cbor_encoder_init(&bs_root, &bs_writer, 0);
+ cbor_state.payload_mut = (uint8_t *)bs_obuf;
+ cbor_state.payload_end = (const uint8_t *)bs_obuf
+ + sizeof(bs_obuf);
/*
* Limited support for commands.
@@ -494,6 +529,10 @@
default:
break;
}
+ } else if (MCUBOOT_PERUSER_MGMT_GROUP_ENABLED == 1) {
+ if (bs_peruser_system_specific(hdr, buf, len, &cbor_state) == 0) {
+ boot_serial_output();
+ }
}
}
@@ -509,7 +548,7 @@
char encoded_buf[BASE64_ENCODE_SIZE(BOOT_SERIAL_OUT_MAX)];
data = bs_obuf;
- len = bs_writer.bytes_written;
+ len = (uint32_t)cbor_state.payload_mut - (uint32_t)bs_obuf;
bs_hdr->nh_op++;
bs_hdr->nh_flags = 0;
@@ -624,6 +663,7 @@
off = 0;
while (1) {
+ MCUBOOT_CPU_IDLE();
rc = f->read(in_buf + off, sizeof(in_buf) - off, &full_line);
if (rc <= 0 && !full_line) {
continue;
diff --git a/boot/boot_serial/src/boot_serial_priv.h b/boot/boot_serial/src/boot_serial_priv.h
index 9275f3f..5e0211c 100644
--- a/boot/boot_serial/src/boot_serial_priv.h
+++ b/boot/boot_serial/src/boot_serial_priv.h
@@ -36,13 +36,17 @@
/*
* From newtmgr.h
*/
+#define MGMT_ERR_OK 0
+#define MGMT_ERR_EUNKNOWN 2
#define MGMT_ERR_EINVAL 3
+#define MGMT_ERR_ENOTSUP 8
#define NMGR_OP_READ 0
#define NMGR_OP_WRITE 2
#define MGMT_GROUP_ID_DEFAULT 0
#define MGMT_GROUP_ID_IMAGE 1
+#define MGMT_GROUP_ID_PERUSER 64
#define NMGR_ID_CONS_ECHO_CTRL 1
#define NMGR_ID_RESET 5
@@ -65,6 +69,19 @@
void boot_serial_input(char *buf, int len);
extern const struct boot_uart_funcs *boot_uf;
+/**
+ * @brief Selects direct image to upload according to the "image"
+ * parameter of the mcumgr update frame.
+ *
+ * @param[in] image_id the value of the "image" parameter of the
+ * mcumgr update frame to be translated.
+ *
+ * @return flash area ID for the image if defined;
+ * -EINVAL when flash area for given image number has not been
+ * defined.
+ */
+extern int flash_area_id_from_direct_image(int image_id);
+
#ifdef __cplusplus
}
#endif
diff --git a/boot/boot_serial/src/cbor_common.c b/boot/boot_serial/src/cbor_common.c
new file mode 100644
index 0000000..8a4cd9c
--- /dev/null
+++ b/boot/boot_serial/src/cbor_common.c
@@ -0,0 +1,125 @@
+/*
+ * This file has been copied from the cddl-gen submodule.
+ * Commit 9f77837f9950da1633d22abf6181a830521a6688
+ */
+
+/*
+ * Copyright (c) 2020 Nordic Semiconductor ASA
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "cbor_common.h"
+
+_Static_assert((sizeof(size_t) == sizeof(void *)),
+ "This code needs size_t to be the same length as pointers.");
+
+bool new_backup(cbor_state_t *state, uint32_t new_elem_count)
+{
+ if ((state->backups->current_backup + 1)
+ >= state->backups->num_backups) {
+ FAIL();
+ }
+
+ uint32_t i = ++(state->backups->current_backup);
+ memcpy(&state->backups->backup_list[i], state,
+ sizeof(cbor_state_t));
+
+ state->elem_count = new_elem_count;
+
+ return true;
+}
+
+
+bool restore_backup(cbor_state_t *state, uint32_t flags,
+ uint32_t max_elem_count)
+{
+ const uint8_t *payload = state->payload;
+ const uint32_t elem_count = state->elem_count;
+
+ if (state->backups->current_backup == 0) {
+ FAIL();
+ }
+
+ if (flags & FLAG_RESTORE) {
+ uint32_t i = state->backups->current_backup;
+
+ memcpy(state, &state->backups->backup_list[i],
+ sizeof(cbor_state_t));
+ }
+
+ if (flags & FLAG_DISCARD) {
+ state->backups->current_backup--;
+ }
+
+ if (elem_count > max_elem_count) {
+ cbor_print("elem_count: %d (expected max %d)\r\n",
+ elem_count, max_elem_count);
+ FAIL();
+ }
+
+ if (flags & FLAG_TRANSFER_PAYLOAD) {
+ state->payload = payload;
+ }
+
+ return true;
+}
+
+
+bool union_start_code(cbor_state_t *state)
+{
+ if (!new_backup(state, state->elem_count)) {
+ FAIL();
+ }
+ return true;
+}
+
+
+bool union_elem_code(cbor_state_t *state)
+{
+ if (!restore_backup(state, FLAG_RESTORE, state->elem_count)) {
+ FAIL();
+ }
+ return true;
+}
+
+bool union_end_code(cbor_state_t *state)
+{
+ if (!restore_backup(state, FLAG_DISCARD, state->elem_count)) {
+ FAIL();
+ }
+ return true;
+}
+
+bool entry_function(const uint8_t *payload, uint32_t payload_len,
+ const void *struct_ptr, uint32_t *payload_len_out,
+ cbor_encoder_t func, uint32_t elem_count, uint32_t num_backups)
+{
+ cbor_state_t state = {
+ .payload = payload,
+ .payload_end = payload + payload_len,
+ .elem_count = elem_count,
+ };
+
+ cbor_state_t state_backups[num_backups + 1];
+
+ cbor_state_backups_t backups = {
+ .backup_list = state_backups,
+ .current_backup = 0,
+ .num_backups = num_backups + 1,
+ };
+
+ state.backups = &backups;
+
+ bool result = func(&state, struct_ptr);
+
+ if (result && (payload_len_out != NULL)) {
+ *payload_len_out = MIN(payload_len,
+ (size_t)state.payload - (size_t)payload);
+ }
+ return result;
+}
diff --git a/boot/boot_serial/src/cbor_common.h b/boot/boot_serial/src/cbor_common.h
new file mode 100644
index 0000000..e652908
--- /dev/null
+++ b/boot/boot_serial/src/cbor_common.h
@@ -0,0 +1,145 @@
+/*
+ * This file has been copied from the cddl-gen submodule.
+ * Commit 9f77837f9950da1633d22abf6181a830521a6688
+ */
+
+/*
+ * Copyright (c) 2020 Nordic Semiconductor ASA
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef CBOR_COMMON_H__
+#define CBOR_COMMON_H__
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+
+/** Convenience type that allows pointing to strings directly inside the payload
+ * without the need to copy out.
+ */
+typedef struct
+{
+ const uint8_t *value;
+ uint32_t len;
+} cbor_string_type_t;
+
+#ifdef CDDL_CBOR_VERBOSE
+#include <sys/printk.h>
+#define cbor_trace() (printk("bytes left: %d, byte: 0x%x, elem_count: 0x%zx, %s:%d\n",\
+ (uint32_t)state->payload_end - (uint32_t)state->payload, *state->payload, state->elem_count,\
+ __FILE__, __LINE__))
+#define cbor_assert(expr, ...) \
+do { \
+ if (!(expr)) { \
+ printk("ASSERTION \n \"" #expr \
+ "\"\nfailed at %s:%d with message:\n ", \
+ __FILE__, __LINE__); \
+ printk(__VA_ARGS__);\
+ return false; \
+ } \
+} while(0)
+#define cbor_print(...) printk(__VA_ARGS__)
+#else
+#define cbor_trace() ((void)state)
+#define cbor_assert(...)
+#define cbor_print(...)
+#endif
+
+#ifndef MIN
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+
+struct cbor_state_backups_s;
+
+typedef struct cbor_state_backups_s cbor_state_backups_t;
+
+typedef struct{
+union {
+ uint8_t *payload_mut;
+ uint8_t const *payload; /**< The current place in the payload. Will be
+ updated when an element is correctly
+ processed. */
+};
+ uint8_t const *payload_bak; /**< Temporary backup of payload. */
+ uint32_t elem_count; /**< The current element is part of a LIST or a MAP,
+ and this keeps count of how many elements are
+ expected. This will be checked before processing
+ and decremented if the element is correctly
+ processed. */
+ uint8_t const *payload_end; /**< The end of the payload. This will be
+ checked against payload before
+ processing each element. */
+ cbor_state_backups_t *backups;
+} cbor_state_t;
+
+struct cbor_state_backups_s{
+ cbor_state_t *backup_list;
+ uint32_t current_backup;
+ uint32_t num_backups;
+};
+
+/** Function pointer type used with multi_decode.
+ *
+ * This type is compatible with all decoding functions here and in the generated
+ * code, except for multi_decode.
+ */
+typedef bool(cbor_encoder_t)(cbor_state_t *, const void *);
+typedef bool(cbor_decoder_t)(cbor_state_t *, void *);
+
+/** Enumeration representing the major types available in CBOR.
+ *
+ * The major type is represented in the 3 first bits of the header byte.
+ */
+typedef enum
+{
+ CBOR_MAJOR_TYPE_PINT = 0, ///! Positive Integer
+ CBOR_MAJOR_TYPE_NINT = 1, ///! Negative Integer
+ CBOR_MAJOR_TYPE_BSTR = 2, ///! Byte String
+ CBOR_MAJOR_TYPE_TSTR = 3, ///! Text String
+ CBOR_MAJOR_TYPE_LIST = 4, ///! List
+ CBOR_MAJOR_TYPE_MAP = 5, ///! Map
+ CBOR_MAJOR_TYPE_TAG = 6, ///! Semantic Tag
+ CBOR_MAJOR_TYPE_PRIM = 7, ///! Primitive Type
+} cbor_major_type_t;
+
+/** Shorthand macro to check if a result is within min/max constraints.
+ */
+#define PTR_VALUE_IN_RANGE(type, res, min, max) \
+ (((min == NULL) || (*(type *)res >= *(type *)min)) \
+ && ((max == NULL) || (*(type *)res <= *(type *)max)))
+
+#define FAIL() \
+do {\
+ cbor_trace(); \
+ return false; \
+} while(0)
+
+
+#define VALUE_IN_HEADER 23 /**! For values below this, the value is encoded
+ directly in the header. */
+
+#define BOOL_TO_PRIM 20 ///! In CBOR, false/true have the values 20/21
+
+#define FLAG_RESTORE 1UL
+#define FLAG_DISCARD 2UL
+#define FLAG_TRANSFER_PAYLOAD 4UL
+
+bool new_backup(cbor_state_t *state, uint32_t new_elem_count);
+
+bool restore_backup(cbor_state_t *state, uint32_t flags,
+ uint32_t max_elem_count);
+
+bool union_start_code(cbor_state_t *state);
+
+bool union_elem_code(cbor_state_t *state);
+
+bool union_end_code(cbor_state_t *state);
+
+bool entry_function(const uint8_t *payload, uint32_t payload_len,
+ const void *struct_ptr, uint32_t *payload_len_out,
+ cbor_encoder_t func, uint32_t elem_count, uint32_t num_backups);
+
+#endif /* CBOR_COMMON_H__ */
diff --git a/boot/boot_serial/src/cbor_decode.c b/boot/boot_serial/src/cbor_decode.c
index 9d27bbb..9707729 100644
--- a/boot/boot_serial/src/cbor_decode.c
+++ b/boot/boot_serial/src/cbor_decode.c
@@ -1,6 +1,6 @@
/*
- * This file has been copied from the cddl_gen submodule.
- * Commit 9d911cf0c7c9f13b5a9fdd5ed6c1012df21e5576
+ * This file has been copied from the cddl-gen submodule.
+ * Commit 9f77837f9950da1633d22abf6181a830521a6688
*/
/*
@@ -14,22 +14,8 @@
#include <stddef.h>
#include <string.h>
#include "cbor_decode.h"
+#include "cbor_common.h"
-/** Enumeration representing the major types available in CBOR.
- *
- * The major type is represented in the 3 first bits of the header byte.
- */
-typedef enum
-{
- CBOR_MAJOR_TYPE_PINT = 0, ///! Positive Integer
- CBOR_MAJOR_TYPE_NINT = 1, ///! Negative Integer
- CBOR_MAJOR_TYPE_BSTR = 2, ///! Byte String
- CBOR_MAJOR_TYPE_TSTR = 3, ///! Text String
- CBOR_MAJOR_TYPE_LIST = 4, ///! List
- CBOR_MAJOR_TYPE_MAP = 5, ///! Map
- CBOR_MAJOR_TYPE_TAG = 6, ///! Semantic Tag
- CBOR_MAJOR_TYPE_PRIM = 7, ///! Primitive Type
-} cbor_major_type_t;
/** Return value length from additional value.
*/
@@ -52,122 +38,126 @@
/** Extract the additional info, i.e. the last 5 bits of the header byte. */
#define ADDITIONAL(header_byte) ((header_byte) & 0x1F)
-/** Shorthand macro to check if a result is within min/max constraints.
- */
-#define PTR_VALUE_IN_RANGE(type, p_res, p_min, p_max) \
- (((p_min == NULL) || (*(type *)p_res >= *(type *)p_min)) \
- && ((p_max == NULL) || (*(type *)p_res <= *(type *)p_max)))
-
-#define FAIL() \
-do {\
- cbor_decode_trace(); \
- return false; \
-} while(0)
#define FAIL_AND_DECR_IF(expr) \
do {\
if (expr) { \
- (p_state->p_payload)--; \
+ (state->payload)--; \
FAIL(); \
} \
} while(0)
-#define VALUE_IN_HEADER 23 /**! For values below this, the value is encoded
- directly in the header. */
+#define FAIL_IF(expr) \
+do {\
+ if (expr) { \
+ FAIL(); \
+ } \
+} while(0)
-#define BOOL_TO_PRIM 20 ///! In CBOR, false/true have the values 20/21
+
+#define FAIL_RESTORE() \
+ state->payload = state->payload_bak; \
+ state->elem_count++; \
+ FAIL()
/** Get a single value.
*
- * @details @p pp_payload must point to the header byte. This function will
+ * @details @p ppayload must point to the header byte. This function will
* retrieve the value (either from within the additional info, or from
* the subsequent bytes) and return it in the result. The result can
* have arbitrary length.
*
* The function will also validate
* - Min/max constraints on the value.
- * - That @p pp_payload doesn't overrun past @p p_payload_end.
- * - That @p p_elem_count has not been exhausted.
+ * - That @p payload doesn't overrun past @p payload_end.
+ * - That @p elem_count has not been exhausted.
*
- * @p pp_payload and @p p_elem_count are updated if the function
+ * @p ppayload and @p elem_count are updated if the function
* succeeds. If not, they are left unchanged.
*
* CBOR values are always big-endian, so this function converts from
* big to little-endian if necessary (@ref CONFIG_BIG_ENDIAN).
*/
-static bool value_extract(cbor_decode_state_t * p_state,
- void * const p_result, size_t result_len)
+static bool value_extract(cbor_state_t *state,
+ void *const result, uint32_t result_len)
{
- cbor_decode_trace();
- cbor_decode_assert(result_len != 0, "0-length result not supported.\n");
+ cbor_trace();
+ cbor_assert(result_len != 0, "0-length result not supported.\n");
+ cbor_assert(result != NULL, NULL);
- FAIL_AND_DECR_IF(p_state->elem_count == 0);
- FAIL_AND_DECR_IF(p_state->p_payload >= p_state->p_payload_end);
+ FAIL_IF((state->elem_count == 0) \
+ || (state->payload >= state->payload_end));
- uint8_t *p_u8_result = (uint8_t *)p_result;
- uint8_t additional = ADDITIONAL(*p_state->p_payload);
+ uint8_t *u8_result = (uint8_t *)result;
+ uint8_t additional = ADDITIONAL(*state->payload);
- (p_state->p_payload)++;
+ state->payload_bak = state->payload;
+ (state->payload)++;
- memset(p_result, 0, result_len);
+ memset(result, 0, result_len);
if (additional <= VALUE_IN_HEADER) {
#ifdef CONFIG_BIG_ENDIAN
- p_u8_result[result_len - 1] = additional;
+ u8_result[result_len - 1] = additional;
#else
- p_u8_result[0] = additional;
+ u8_result[0] = additional;
#endif /* CONFIG_BIG_ENDIAN */
} else {
uint32_t len = additional_len(additional);
FAIL_AND_DECR_IF(len > result_len);
- FAIL_AND_DECR_IF((p_state->p_payload + len)
- > p_state->p_payload_end);
+ FAIL_AND_DECR_IF((state->payload + len)
+ > state->payload_end);
#ifdef CONFIG_BIG_ENDIAN
- memcpy(&p_u8_result[result_len - len], p_state->p_payload, len);
+ memcpy(&u8_result[result_len - len], state->payload, len);
#else
for (uint32_t i = 0; i < len; i++) {
- p_u8_result[i] = (p_state->p_payload)[len - i - 1];
+ u8_result[i] = (state->payload)[len - i - 1];
}
#endif /* CONFIG_BIG_ENDIAN */
- (p_state->p_payload) += len;
+ (state->payload) += len;
}
- (p_state->elem_count)--;
+ (state->elem_count)--;
return true;
}
-static bool int32_decode(cbor_decode_state_t * p_state,
- int32_t *p_result, void *p_min_value, void *p_max_value)
+static bool int32_decode(cbor_state_t *state, int32_t *result)
{
- uint8_t major_type = MAJOR_TYPE(*p_state->p_payload);
+ FAIL_IF(state->payload >= state->payload_end);
+ uint8_t major_type = MAJOR_TYPE(*state->payload);
+ uint32_t uint_result;
+ int32_t int_result;
- if (!value_extract(p_state, p_result, 4)) {
+ if (!value_extract(state, &uint_result, 4)) {
FAIL();
}
- if (*p_result < 0) {
+
+ cbor_print("uintval: %u\r\n", uint_result);
+ if (uint_result >= (1 << (8*sizeof(uint_result)-1))) {
/* Value is too large to fit in a signed integer. */
- FAIL();
+ FAIL_RESTORE();
}
if (major_type == CBOR_MAJOR_TYPE_NINT) {
- // Convert from CBOR's representation.
- *p_result = 1 - *p_result;
+ /* Convert from CBOR's representation. */
+ int_result = -1 - uint_result;
+ } else {
+ int_result = uint_result;
}
- if (!PTR_VALUE_IN_RANGE(int32_t, p_result, p_min_value, p_max_value)) {
- FAIL();
- }
- cbor_decode_print("val: %d\r\n", *p_result);
+
+ cbor_print("val: %d\r\n", int_result);
+ *result = int_result;
return true;
}
-bool intx32_decode(cbor_decode_state_t * p_state,
- int32_t *p_result, void *p_min_value, void *p_max_value)
+bool intx32_decode(cbor_state_t *state, int32_t *result)
{
- uint8_t major_type = MAJOR_TYPE(*p_state->p_payload);
+ FAIL_IF(state->payload >= state->payload_end);
+ uint8_t major_type = MAJOR_TYPE(*state->payload);
if (major_type != CBOR_MAJOR_TYPE_PINT
&& major_type != CBOR_MAJOR_TYPE_NINT) {
@@ -175,203 +165,384 @@
FAIL();
}
- if (!int32_decode(p_state,
- p_result, p_min_value,
- p_max_value)){
+ if (!int32_decode(state, result)) {
FAIL();
}
return true;
}
-
-static bool uint32_decode(cbor_decode_state_t * p_state,
- void *p_result, void *p_min_value, void *p_max_value)
+bool intx32_expect(cbor_state_t *state, int32_t result)
{
- if (!value_extract(p_state, p_result, 4)) {
+ int32_t value;
+
+ if (!intx32_decode(state, &value)) {
FAIL();
}
- if (!PTR_VALUE_IN_RANGE(uint32_t, p_result, p_min_value, p_max_value)) {
- FAIL();
+ if (value != result) {
+ cbor_print("%d != %d\r\n", value, result);
+ FAIL_RESTORE();
}
- cbor_decode_print("val: %u\r\n", *(uint32_t *)p_result);
return true;
}
-bool uintx32_decode(cbor_decode_state_t * p_state,
- uint32_t *p_result, void *p_min_value, void *p_max_value)
+static bool uint32_decode(cbor_state_t *state, uint32_t *result)
{
- uint8_t major_type = MAJOR_TYPE(*p_state->p_payload);
+ if (!value_extract(state, result, 4)) {
+ FAIL();
+ }
+
+ return true;
+}
+
+
+bool uintx32_decode(cbor_state_t *state, uint32_t *result)
+{
+ FAIL_IF(state->payload >= state->payload_end);
+ uint8_t major_type = MAJOR_TYPE(*state->payload);
if (major_type != CBOR_MAJOR_TYPE_PINT) {
/* Value to be read doesn't have the right type. */
FAIL();
}
- if (!uint32_decode(p_state, p_result, p_min_value, p_max_value)){
+ if (!uint32_decode(state, result)) {
FAIL();
}
return true;
}
-
-static bool size_decode(cbor_decode_state_t * p_state,
- size_t *p_result, size_t *p_min_value, size_t *p_max_value)
+bool uintx32_expect(cbor_state_t *state, uint32_t result)
{
- _Static_assert((sizeof(size_t) == sizeof(uint32_t)),
- "This code needs size_t to be 4 bytes long.");
- return uint32_decode(p_state,
- p_result, p_min_value, p_max_value);
+ uint32_t value;
+
+ if (!uintx32_decode(state, &value)) {
+ FAIL();
+ }
+ if (value != result) {
+ cbor_print("%u != %u\r\n", value, result);
+ FAIL_RESTORE();
+ }
+ return true;
+}
+
+bool uintx32_expect_union(cbor_state_t *state, uint32_t result)
+{
+ union_elem_code(state);
+ return uintx32_expect(state, result);
}
-bool strx_start_decode(cbor_decode_state_t * p_state,
- cbor_string_type_t *p_result, void *p_min_len, void *p_max_len)
+static bool strx_start_decode(cbor_state_t *state,
+ cbor_string_type_t *result, cbor_major_type_t exp_major_type)
{
- uint8_t major_type = MAJOR_TYPE(*p_state->p_payload);
- cbor_string_type_t *p_str_result = (cbor_string_type_t *)p_result;
+ FAIL_IF(state->payload >= state->payload_end);
+ uint8_t major_type = MAJOR_TYPE(*state->payload);
- if (major_type != CBOR_MAJOR_TYPE_BSTR
- && major_type != CBOR_MAJOR_TYPE_TSTR) {
- /* Value to be read doesn't have the right type. */
+ if (major_type != exp_major_type) {
FAIL();
}
- if (!size_decode(p_state,
- &p_str_result->len, (size_t *)p_min_len,
- (size_t *)p_max_len)) {
+
+ if (!uint32_decode(state, &result->len)) {
FAIL();
}
- p_str_result->value = p_state->p_payload;
+
+ if (result->len > (state->payload_end - state->payload)) {
+ cbor_print("error: 0x%x > 0x%x\r\n",
+ (uint32_t)result->len,
+ (uint32_t)(state->payload_end - state->payload));
+ FAIL_RESTORE();
+ }
+
+ result->value = state->payload;
+ return true;
+}
+
+bool bstrx_cbor_start_decode(cbor_state_t *state, cbor_string_type_t *result)
+{
+ if(!strx_start_decode(state, result, CBOR_MAJOR_TYPE_BSTR)) {
+ FAIL();
+ }
+
+ if (!new_backup(state, 0xFFFFFFFF)) {
+ FAIL_RESTORE();
+ }
+
+ /* Overflow is checked in strx_start_decode() */
+ state->payload_end = result->value + result->len;
+ return true;
+}
+
+bool bstrx_cbor_end_decode(cbor_state_t *state)
+{
+ if (state->payload != state->payload_end) {
+ FAIL();
+ }
+ if (!restore_backup(state,
+ FLAG_RESTORE | FLAG_DISCARD | FLAG_TRANSFER_PAYLOAD,
+ 0xFFFFFFFF)) {
+ FAIL();
+ }
+
return true;
}
-bool strx_decode(cbor_decode_state_t * p_state,
- cbor_string_type_t *p_result, void *p_min_len, void *p_max_len)
+bool strx_decode(cbor_state_t *state, cbor_string_type_t *result,
+ cbor_major_type_t exp_major_type)
{
- if (!strx_start_decode(p_state, p_result,
- p_min_len, p_max_len)) {
- return false;
+ if (!strx_start_decode(state, result, exp_major_type)) {
+ FAIL();
}
- (p_state->p_payload) += p_result->len;
+
+ /* Overflow is checked in strx_start_decode() */
+ (state->payload) += result->len;
return true;
}
-bool list_start_decode(cbor_decode_state_t * p_state,
- size_t *p_result, size_t min_num, size_t max_num)
+bool strx_expect(cbor_state_t *state, cbor_string_type_t *result,
+ cbor_major_type_t exp_major_type)
{
- uint8_t major_type = MAJOR_TYPE(*p_state->p_payload);
+ cbor_string_type_t tmp_result;
- *p_result = p_state->elem_count;
-
- if (major_type != CBOR_MAJOR_TYPE_LIST
- && major_type != CBOR_MAJOR_TYPE_MAP) {
+ if (!strx_decode(state, &tmp_result, exp_major_type)) {
FAIL();
}
- if (!uint32_decode(p_state,
- p_result, &min_num, &max_num)) {
- FAIL();
+ if ((tmp_result.len != result->len)
+ || memcmp(result->value, tmp_result.value, tmp_result.len)) {
+ FAIL_RESTORE();
}
- size_t tmp = *p_result;
- *p_result = p_state->elem_count;
- p_state->elem_count = major_type == CBOR_MAJOR_TYPE_MAP ? tmp * 2 : tmp;
return true;
}
-bool primx_decode(cbor_decode_state_t * p_state,
- uint8_t *p_result, void *p_min_result, void *p_max_result)
+bool bstrx_decode(cbor_state_t *state, cbor_string_type_t *result)
{
- uint8_t major_type = MAJOR_TYPE(*p_state->p_payload);
- uint32_t val;
+ return strx_decode(state, result, CBOR_MAJOR_TYPE_BSTR);
+}
+
+
+bool bstrx_expect(cbor_state_t *state, cbor_string_type_t *result)
+{
+ return strx_expect(state, result, CBOR_MAJOR_TYPE_BSTR);
+}
+
+
+bool tstrx_decode(cbor_state_t *state, cbor_string_type_t *result)
+{
+ return strx_decode(state, result, CBOR_MAJOR_TYPE_TSTR);
+}
+
+
+bool tstrx_expect(cbor_state_t *state, cbor_string_type_t *result)
+{
+ return strx_expect(state, result, CBOR_MAJOR_TYPE_TSTR);
+}
+
+
+static bool list_map_start_decode(cbor_state_t *state,
+ cbor_major_type_t exp_major_type)
+{
+ FAIL_IF(state->payload >= state->payload_end);
+ uint8_t major_type = MAJOR_TYPE(*state->payload);
+ uint32_t new_elem_count;
+
+ if (major_type != exp_major_type) {
+ FAIL();
+ }
+
+ if (!uint32_decode(state, &new_elem_count)) {
+ FAIL();
+ }
+
+ if (!new_backup(state, new_elem_count)) {
+ FAIL_RESTORE();
+ }
+
+ return true;
+}
+
+
+bool list_start_decode(cbor_state_t *state)
+{
+ return list_map_start_decode(state, CBOR_MAJOR_TYPE_LIST);
+}
+
+
+bool map_start_decode(cbor_state_t *state)
+{
+ bool ret = list_map_start_decode(state, CBOR_MAJOR_TYPE_MAP);
+
+ if (ret) {
+ state->elem_count *= 2;
+ }
+ return ret;
+}
+
+
+bool list_map_end_decode(cbor_state_t *state)
+{
+ if (!restore_backup(state,
+ FLAG_RESTORE | FLAG_DISCARD | FLAG_TRANSFER_PAYLOAD,
+ 0)) {
+ FAIL();
+ }
+
+ return true;
+}
+
+
+bool list_end_decode(cbor_state_t *state)
+{
+ return list_map_end_decode(state);
+}
+
+
+bool map_end_decode(cbor_state_t *state)
+{
+ return list_map_end_decode(state);
+}
+
+
+static bool primx_decode(cbor_state_t *state, uint32_t *result)
+{
+ FAIL_IF(state->payload >= state->payload_end);
+ uint8_t major_type = MAJOR_TYPE(*state->payload);
if (major_type != CBOR_MAJOR_TYPE_PRIM) {
/* Value to be read doesn't have the right type. */
FAIL();
}
- if (!uint32_decode(p_state,
- &val, p_min_result, p_max_result)) {
+ if (!uint32_decode(state, result)) {
FAIL();
}
- if (p_result != NULL) {
- *p_result = val;
+ if (*result > 0xFF) {
+ FAIL_RESTORE();
+ }
+ return true;
+}
+
+static bool primx_expect(cbor_state_t *state, uint32_t result)
+{
+ uint32_t value;
+
+ if (!primx_decode(state, &value)) {
+ FAIL();
+ }
+ if (value != result) {
+ FAIL_RESTORE();
}
return true;
}
-bool boolx_decode(cbor_decode_state_t * p_state,
- bool *p_result, void *p_min_result, void *p_max_result)
+bool nilx_expect(cbor_state_t *state, void *result)
{
- uint8_t min_result = *(uint8_t *)p_min_result + BOOL_TO_PRIM;
- uint8_t max_result = *(uint8_t *)p_max_result + BOOL_TO_PRIM;
-
- if (!primx_decode(p_state,
- (uint8_t *)p_result, &min_result, &max_result)) {
+ if (!primx_expect(state, 22)) {
FAIL();
}
- (*p_result) -= BOOL_TO_PRIM;
return true;
}
-bool double_decode(cbor_decode_state_t * p_state,
- double *p_result, void *p_min_result, void *p_max_result)
+bool boolx_decode(cbor_state_t *state, bool *result)
{
- uint8_t major_type = MAJOR_TYPE(*p_state->p_payload);
+ uint32_t tmp_result;
+
+ if (!primx_decode(state, &tmp_result)) {
+ FAIL();
+ }
+ (*result) = tmp_result - BOOL_TO_PRIM;
+
+ cbor_print("boolval: %u\r\n", *result);
+ return true;
+}
+
+
+bool boolx_expect(cbor_state_t *state, bool result)
+{
+ bool value;
+
+ if (!boolx_decode(state, &value)) {
+ FAIL();
+ }
+ if (value != result) {
+ FAIL_RESTORE();
+ }
+ return true;
+}
+
+
+bool double_decode(cbor_state_t *state, double *result)
+{
+ FAIL_IF(state->payload >= state->payload_end);
+ uint8_t major_type = MAJOR_TYPE(*state->payload);
if (major_type != CBOR_MAJOR_TYPE_PRIM) {
/* Value to be read doesn't have the right type. */
FAIL();
}
- if (!value_extract(p_state, p_result,
- sizeof(*p_result))) {
- FAIL();
- }
-
- if (!PTR_VALUE_IN_RANGE(double, p_result, p_min_result, p_max_result)) {
+ if (!value_extract(state, result,
+ sizeof(*result))) {
FAIL();
}
return true;
}
-bool any_decode(cbor_decode_state_t * p_state,
- void *p_result, void *p_min_result, void *p_max_result)
+bool double_expect(cbor_state_t *state, double *result)
{
- cbor_decode_assert(p_result == NULL,
+ double value;
+
+ if (!double_decode(state, &value)) {
+ FAIL();
+ }
+ if (value != *result) {
+ FAIL_RESTORE();
+ }
+ return true;
+}
+
+
+bool any_decode(cbor_state_t *state, void *result)
+{
+ cbor_assert(result == NULL,
"'any' type cannot be returned, only skipped.\n");
- uint8_t major_type = MAJOR_TYPE(*p_state->p_payload);
+ FAIL_IF(state->payload >= state->payload_end);
+ uint8_t major_type = MAJOR_TYPE(*state->payload);
uint32_t value;
- size_t num_decode;
- void *p_null_result = NULL;
- size_t temp_elem_count;
+ uint32_t num_decode;
+ void *null_result = NULL;
+ uint32_t temp_elem_count;
+ uint8_t const *payload_bak;
- if (!value_extract(p_state, &value, sizeof(value))) {
- /* Can happen because of p_elem_count (or p_payload_end) */
+ if (!value_extract(state, &value, sizeof(value))) {
+ /* Can happen because of elem_count (or payload_end) */
FAIL();
}
switch (major_type) {
case CBOR_MAJOR_TYPE_BSTR:
case CBOR_MAJOR_TYPE_TSTR:
- (p_state->p_payload) += value;
+ (state->payload) += value;
break;
case CBOR_MAJOR_TYPE_MAP:
value *= 2; /* Because all members have a key. */
/* Fallthrough */
case CBOR_MAJOR_TYPE_LIST:
- temp_elem_count = p_state->elem_count;
- p_state->elem_count = value;
- if (!multi_decode(value, value, &num_decode, any_decode,
- p_state,
- &p_null_result, NULL, NULL, 0)) {
- p_state->elem_count = temp_elem_count;
+ temp_elem_count = state->elem_count;
+ payload_bak = state->payload;
+ state->elem_count = value;
+ if (!multi_decode(value, value, &num_decode,
+ (void *)any_decode, state,
+ &null_result, 0)) {
+ state->elem_count = temp_elem_count;
+ state->payload = payload_bak;
FAIL();
}
- p_state->elem_count = temp_elem_count;
+ state->elem_count = temp_elem_count;
break;
default:
/* Do nothing */
@@ -382,36 +553,77 @@
}
-bool multi_decode(size_t min_decode,
- size_t max_decode,
- size_t *p_num_decode,
- decoder_t decoder,
- cbor_decode_state_t * p_state,
- void *p_result,
- void *p_min_result,
- void *p_max_result,
- size_t result_len)
+bool tag_decode(cbor_state_t *state, uint32_t *result)
{
- for (size_t i = 0; i < max_decode; i++) {
- uint8_t const *p_payload_bak = p_state->p_payload;
- size_t elem_count_bak = p_state->elem_count;
+ FAIL_IF(state->payload >= state->payload_end);
+ uint8_t major_type = MAJOR_TYPE(*state->payload);
- if (!decoder(p_state,
- (uint8_t *)p_result + i*result_len,
- p_min_result,
- p_max_result)) {
- *p_num_decode = i;
- p_state->p_payload = p_payload_bak;
- p_state->elem_count = elem_count_bak;
+ if (major_type != CBOR_MAJOR_TYPE_TAG) {
+ /* Value to be read doesn't have the right type. */
+ FAIL();
+ }
+ if (!uint32_decode(state, result)) {
+ FAIL();
+ }
+ state->elem_count++;
+ return true;
+}
+
+
+bool tag_expect(cbor_state_t *state, uint32_t result)
+{
+ uint32_t tag_val;
+
+ if (!tag_decode(state, &tag_val)) {
+ FAIL();
+ }
+ if (tag_val != result) {
+ FAIL_RESTORE();
+ }
+ return true;
+}
+
+
+bool multi_decode(uint32_t min_decode,
+ uint32_t max_decode,
+ uint32_t *num_decode,
+ cbor_decoder_t decoder,
+ cbor_state_t *state,
+ void *result,
+ uint32_t result_len)
+{
+ for (uint32_t i = 0; i < max_decode; i++) {
+ uint8_t const *payload_bak = state->payload;
+ uint32_t elem_count_bak = state->elem_count;
+
+ if (!decoder(state,
+ (uint8_t *)result + i*result_len)) {
+ *num_decode = i;
+ state->payload = payload_bak;
+ state->elem_count = elem_count_bak;
if (i < min_decode) {
FAIL();
} else {
- cbor_decode_print("Found %zu elements.\n", i);
+ cbor_print("Found %zu elements.\n", i);
}
return true;
}
}
- cbor_decode_print("Found %zu elements.\n", max_decode);
- *p_num_decode = max_decode;
+ cbor_print("Found %zu elements.\n", max_decode);
+ *num_decode = max_decode;
return true;
}
+
+
+bool present_decode(uint32_t *present,
+ cbor_decoder_t decoder,
+ cbor_state_t *state,
+ void *result)
+{
+ uint32_t num_decode;
+ bool retval = multi_decode(0, 1, &num_decode, decoder, state, result, 0);
+ if (retval) {
+ *present = num_decode;
+ }
+ return retval;
+}
diff --git a/boot/boot_serial/src/cbor_decode.h b/boot/boot_serial/src/cbor_decode.h
index cd466cd..5bdc800 100644
--- a/boot/boot_serial/src/cbor_decode.h
+++ b/boot/boot_serial/src/cbor_decode.h
@@ -1,6 +1,6 @@
/*
- * This file has been copied from the cddl_gen submodule.
- * Commit 9d911cf0c7c9f13b5a9fdd5ed6c1012df21e5576
+ * This file has been copied from the cddl-gen submodule.
+ * Commit 9f77837f9950da1633d22abf6181a830521a6688
*/
/*
@@ -9,35 +9,33 @@
* SPDX-License-Identifier: Apache-2.0
*/
-#ifndef CDDL_CBOR_H__
-#define CDDL_CBOR_H__
+#ifndef CBOR_DECODE_H__
+#define CBOR_DECODE_H__
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
+#include "cbor_common.h"
/** The cbor_decode library provides functions for decoding CBOR data elements.
*
* This library is primarily meant to be called from code generated by
- * $CDDL_GEN_BASE/scripts/cddl_gen.py
+ * $CDDL_GEN_BASE/cddl_gen/cddl_gen.py script, or its equivalent cddl_gen
+ * command line executable.
*
* Some details to notice about this library:
- * - Integers are all 32 bits (uint32_t and size_t). This means that CBOR's
- * 64 bit values are not supported. This applies to integer types, as well as
- * lengths for other types.
+ * - Integers are all 32 bits (uint32_t). This means that CBOR's 64 bit values
+ * are not supported, even when the code is running on a 64 bit architecture.
+ * This applies to integer types, as well as lengths for other types.
* - Strings are kept in the container type cbor_string_type_t, which is a
* pointer and a length.
* - When a function returns false, it only means that decoding that particular
* value failed. If a value is allowed to take multiple different values,
- * another decoding function can be called if the first fails. All functions
- * are designed to reset pp_payload and p_elem_count to their original values
- * if they return false.
+ * another decoding function can be called if the first fails.
* - There is some type casting going on under the hood to make the code
- * generator friendly. See especially the decoder_t type which is compatible
+ * generator friendly. See especially the processor_t type which is compatible
* with all functions except multi_decode, but the compiler doesn't "know"
* this because they are defined with different pointer types. It also means
* any usage of multi_decode must be made with care for function types.
- * - This library has no function for semantic tags.
- * - This library doesn't distinguish lists from maps.
*
*
* CBOR's format is described well on Wikipedia
@@ -54,7 +52,11 @@
*
* The available major types can be seen in @ref cbor_major_type_t.
*
- * PINT, NINT, TAG, and PRIM elements have no payload, only Value.
+ * For all types, Values 0-23 are encoded directly in the "Additional info",
+ * meaning that the "Value" field is 0 bytes long. If "Additional info" is 24,
+ * 25, 26, or 27, the "Value" field is 1, 2, 4, or 8 bytes long, respectively.
+ *
+ * Major types PINT, NINT, TAG, and PRIM elements have no payload, only Value.
* PINT: Interpret the Value as a positive integer.
* NINT: Interpret the Value as a positive integer, then multiply by -1 and
* subtract 1.
@@ -65,7 +67,7 @@
* 21: "true"
* 22: "null"
* 23: "undefined"
- * >256: Interpret as IEEE 754 float with given precision
+ * >=0x10000: Interpret as IEEE 754 float with given precision
*
* For BSTR, TSTR, LIST, and MAP, the Value describes the length of the payload.
* For BSTR and TSTR, the length is in bytes, for LIST, the length is in number
@@ -74,148 +76,105 @@
* For LIST and MAP, sub elements are regular CBOR elements with their own
* Header, Value and Payload. LISTs and MAPs can be recursively encoded.
*
- * For all types, Values 0-23 are encoded directly in the "Additional info",
- * meaning that the "Value" field is 0 bytes long. If "Additional info" is 24,
- * 25, 26, or 27, the "Value" field is 1, 2, 4, or 8 bytes long, respectively.
- *
* The additional info means slightly different things for different major
* types.
*/
-
-/** Convenience type that allows pointing to strings directly inside the payload
- * without the need to copy out.
- */
-typedef struct
-{
- const uint8_t *value;
- size_t len;
-} cbor_string_type_t;
-
-#ifdef CDDL_CBOR_VERBOSE
-#include <sys/printk.h>
-#define cbor_decode_trace() (printk("p_state->p_payload: 0x%x, "\
- "*p_state->p_payload: 0x%x, p_state->elem_count: 0x%zx, %s:%d\n",\
- (uint32_t)p_state->p_payload, *p_state->p_payload, p_state->elem_count,\
- __FILE__, __LINE__))
-#define cbor_decode_assert(expr, ...) \
-do { \
- if (!(expr)) { \
- printk("ASSERTION \n \"" #expr \
- "\"\nfailed at %s:%d with message:\n ", \
- __FILE__, __LINE__); \
- printk(__VA_ARGS__);\
- return false; \
- } \
-} while(0)
-#define cbor_decode_print(...) printk(__VA_ARGS__)
-#else
-#define cbor_decode_trace()
-#define cbor_decode_assert(...)
-#define cbor_decode_print(...)
-#endif
-
-typedef struct {
- uint8_t const *p_payload;
- uint8_t const *p_payload_end;
- size_t elem_count;
-} cbor_decode_state_t;
-
-/** Function pointer type used with multi_decode.
- *
- * This type is compatible with all decoding functions here and in the generated
- * code, except for multi_decode.
- */
-typedef bool(decoder_t)(cbor_decode_state_t *, void *, void *, void *);
-
/** Decode a PINT/NINT into a int32_t.
*
- * @param[inout] pp_payload The current place in the payload. Will be
- * updated if the element is correctly decoded.
- * @param[in] p_payload_end The end of the payload. This will be checked
- * against pp_payload before decoding.
- * @param[inout] p_elem_count The current element is part of a LIST or a MAP,
- * and this keeps count of how many elements are
- * expected. This will be checked before decoding
- * decremented if the element is correctly decoded.
- * @param[out] p_result Where to place the decoded value.
- * @param[in] p_min_value The minimum acceptable value. This is checked
- * after decoding, and if the decoded value is
- * outside the range, the decoding will fail.
- * A NULL value here means there is no restriction.
- * @param[in] p_max_value The maximum acceptable value. This is checked
- * after decoding, and if the decoded value is
- * outside the range, the decoding will fail.
- * A NULL value here means there is no restriction.
+ * @param[inout] state The current state of the decoding.
+ * @param[out] result Where to place the decoded value.
*
* @retval true If the value was decoded correctly.
* @retval false If the value has the wrong type, the payload overflowed, the
- * element count was exhausted, the value was not within the
- * acceptable range, or the value was larger than can fit in the
- * result variable.
+ * element count was exhausted, or the value was larger than can
+ * fit in the result variable.
*/
-bool intx32_decode(cbor_decode_state_t * p_state, int32_t *p_result, void *p_min_value, void *p_max_value);
+bool intx32_decode(cbor_state_t *state, int32_t *result);
-/** Decode a PINT into a uint32_t.
+/** Expect a PINT/NINT with a certain value. Uses intx32_decode internally.
*
- * @details See @ref intx32_decode for information about parameters and return
- * values.
+ * @param[inout] state The current state of the decoding.
+ * @param[in] result The expected value
+ *
+ * @retval true If the result was decoded correctly and has the expected value.
+ * @retval false If intx32_decode failed or the result doesn't have the
+ * expected value.
*/
-bool uintx32_decode(cbor_decode_state_t * p_state, uint32_t *p_result, void *p_min_value, void *p_max_value);
+bool intx32_expect(cbor_state_t *state, int32_t result);
-/** Decode a BSTR or TSTR, but leave pp_payload pointing at the payload.
- *
- * @details See @ref intx32_decode for information about parameters and return
- * values. For strings, the value refers to the length of the string.
- */
-bool strx_start_decode(cbor_decode_state_t * p_state, cbor_string_type_t *p_result, void *p_min_len, void *p_max_len);
+/** Decode a PINT. */
+bool uintx32_decode(cbor_state_t *state, uint32_t *result);
+bool uintx32_expect(cbor_state_t *state, uint32_t result);
+bool uintx32_expect_union(cbor_state_t *state, uint32_t result);
-/** Decode a BSTR or TSTR, and move pp_payload to after the payload.
+/** Decode and consume a BSTR header.
*
- * @details See @ref intx32_decode for information about parameters and return
- * values. For strings, the value refers to the length of the string.
+ * The rest of the string can be decoded as CBOR.
+ * A state backup is created to keep track of the element count.
+ *
+ * @retval true Header decoded correctly
+ * @retval false Header decoded incorrectly, or backup failed.
*/
-bool strx_decode(cbor_decode_state_t * p_state, cbor_string_type_t *p_result, void *p_min_len, void *p_max_len);
+bool bstrx_cbor_start_decode(cbor_state_t *state, cbor_string_type_t *result);
-/** Decode a LIST or MAP, but leave pp_payload pointing at the payload.
+/** Finalize decoding a CBOR-encoded bstr.
*
- * @details See @ref intx32_decode for information about parameters and return
- * values. For lists and maps, the value refers to the number of
- * elements.
+ * Restore element count from backup.
*/
-bool list_start_decode(cbor_decode_state_t * p_state, size_t *p_result, size_t min_num, size_t max_num);
+bool bstrx_cbor_end_decode(cbor_state_t *state);
-/** Decode a primitive value.
- *
- * @details See @ref intx32_decode for information about parameters and return
- * values.
- */
-bool primx_decode(cbor_decode_state_t * p_state, uint8_t *p_result, void *p_min_result, void *p_max_result);
+/** Decode and consume a BSTR */
+bool bstrx_decode(cbor_state_t *state, cbor_string_type_t *result);
+bool bstrx_expect(cbor_state_t *state, cbor_string_type_t *result);
-/** Decode a boolean primitive value.
- *
- * @details See @ref intx32_decode for information about parameters and return
- * values. The result is translated internally from the primitive
- * values for true/false (20/21) to 0/1.
- */
-bool boolx_decode(cbor_decode_state_t * p_state, bool *p_result, void *p_min_result, void *p_max_result);
+/** Decode and consume a TSTR */
+bool tstrx_decode(cbor_state_t *state, cbor_string_type_t *result);
+bool tstrx_expect(cbor_state_t *state, cbor_string_type_t *result);
-/** Decode a float
+/** Decode and consume a LIST header.
*
- * @warning This function has not been tested, and likely doesn't work.
+ * The contents of the list can be decoded via subsequent function calls.
+ * A state backup is created to keep track of the element count.
*
- * @details See @ref intx32_decode for information about parameters and return
- * values.
+ * @retval true Header decoded correctly
+ * @retval false Header decoded incorrectly, or backup failed.
*/
-bool float_decode(cbor_decode_state_t * p_state, double *p_result, void *p_min_result, void *p_max_result);
+bool list_start_decode(cbor_state_t *state);
-/** Skip a single element, regardless of type and value.
+/** Decode and consume a MAP header. */
+bool map_start_decode(cbor_state_t *state);
+
+/** Finalize decoding a LIST
*
- * @details See @ref intx32_decode for information about parameters and return
- * values. @p p_result, @p p_min_result, and @p p_max_result must be
- * NULL.
+ * Check that the list had the correct number of elements, and restore previous
+ * element count from backup.
+ *
+ * @retval true Everything ok.
+ * @retval false Element count not correct.
*/
-bool any_decode(cbor_decode_state_t * p_state, void *p_result, void *p_min_result, void *p_max_result);
+bool list_end_decode(cbor_state_t *state);
+
+/** Finalize decoding a MAP */
+bool map_end_decode(cbor_state_t *state);
+
+/** Decode a "nil" primitive value. */
+bool nilx_expect(cbor_state_t *state, void *result);
+
+/** Decode a boolean primitive value. */
+bool boolx_decode(cbor_state_t *state, bool *result);
+bool boolx_expect(cbor_state_t *state, bool result);
+
+/** Decode a float */
+bool float_decode(cbor_state_t *state, double *result);
+bool float_expect(cbor_state_t *state, double *result);
+
+/** Skip a single element, regardless of type and value. */
+bool any_decode(cbor_state_t *state, void *result);
+
+/** Decode a tag. */
+bool tag_decode(cbor_state_t *state, uint32_t *result);
+bool tag_expect(cbor_state_t *state, uint32_t result);
/** Decode 0 or more elements with the same type and constraints.
*
@@ -224,46 +183,52 @@
* with length 8, that could be done with:
*
* @code{c}
- * size_t elem_count = 5;
* uint32_t int_min = 0;
* uint32_t int_max = 100;
- * size_t bstr_size = 8;
+ * uint32_t bstr_size = 8;
* uint32_t ints[3];
* cbor_string_type_t bstrs[2];
+ * bool res;
*
- * list_start_decode(pp_payload, p_payload_end, &parent_elem_count,
- * &elem_count, NULL, NULL);
- * multi_decode(3, 3, &num_decode, uintx32_decode, pp_payload,
- * p_payload_end, ints, &int_min, &int_max, 4);
- * multi_decode(0, 2, &num_decode, strx_decode, pp_payload,
- * p_payload_end, bstrs, &bstr_size, &bstr_size,
+ * res = list_start_encode(state, 3, 5);
+ * // check res
+ * res = multi_encode(3, 3, &num_encode, uintx32_encode, state,
+ * ints, &int_min, &int_max, 4);
+ * // check res
+ * res = multi_encode(0, 2, &num_encode, strx_encode, state,
+ * bstrs, &bstr_size, &bstr_size,
* sizeof(cbor_string_type_t));
+ * // check res
+ * res = list_end_encode(state, 3, 5);
+ * // check res
* @endcode
*
- * See @ref intx32_decode for information about the undocumented
- * parameters.
- *
* @param[in] min_decode The minimum acceptable number of elements.
* @param[in] max_decode The maximum acceptable number of elements.
- * @param[out] p_num_decode The actual number of elements.
+ * @param[out] num_decode The actual number of elements.
* @param[in] decoder The decoder function to call under the hood. This
* function will be called with the provided arguments
* repeatedly until the function fails (returns false)
* or until it has been called @p max_decode times.
- * p_result is moved @p result_len bytes for each call
- * to @p decoder, i.e. @p p_result refers to an array
+ * result is moved @p result_len bytes for each call
+ * to @p decoder, i.e. @p result refers to an array
* of result variables.
- * @param[out] p_result Where to place the decoded values. Must be an array
+ * @param[out] result Where to place the decoded values. Must be an array
* of length at least @p max_decode.
* @param[in] result_len The length of the result variables. Must be the
- * length expected by the @p decoder.
+ * length matching the elements of @p result.
*
* @retval true If at least @p min_decode variables were correctly decoded.
* @retval false If @p decoder failed before having decoded @p min_decode
* values.
*/
-bool multi_decode(size_t min_decode, size_t max_decode, size_t *p_num_decode,
- decoder_t decoder, cbor_decode_state_t * p_state, void *p_result, void *p_min_result, void *p_max_result,
- size_t result_len);
+bool multi_decode(uint32_t min_decode, uint32_t max_decode, uint32_t *num_decode,
+ cbor_decoder_t decoder, cbor_state_t *state, void *result,
+ uint32_t result_len);
-#endif
+bool present_decode(uint32_t *present,
+ cbor_decoder_t decoder,
+ cbor_state_t *state,
+ void *result);
+
+#endif /* CBOR_DECODE_H__ */
diff --git a/boot/boot_serial/src/cbor_encode.c b/boot/boot_serial/src/cbor_encode.c
new file mode 100644
index 0000000..d12dc94
--- /dev/null
+++ b/boot/boot_serial/src/cbor_encode.c
@@ -0,0 +1,466 @@
+/*
+ * This file has been copied from the cddl-gen submodule.
+ * Commit 9f77837f9950da1633d22abf6181a830521a6688
+ */
+
+/*
+ * Copyright (c) 2020 Nordic Semiconductor ASA
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+#include "cbor_encode.h"
+#include "cbor_common.h"
+
+_Static_assert((sizeof(size_t) == sizeof(void *)),
+ "This code needs size_t to be the same length as pointers.");
+
+uint8_t get_additional(uint32_t len, uint8_t value0)
+{
+ switch(len) {
+ case 0: return value0;
+ case 1: return 24;
+ case 2: return 25;
+ case 3: return 25;
+ case 4: return 26;
+ case 5: return 26;
+ case 6: return 26;
+ case 7: return 26;
+ case 8: return 27;
+ }
+
+ cbor_assert(false, NULL);
+ return 0;
+}
+
+static bool encode_header_byte(cbor_state_t *state,
+ cbor_major_type_t major_type, uint8_t additional)
+{
+ if ((state->payload + 1) > state->payload_end) {
+ FAIL();
+ }
+
+ cbor_assert(additional < 32, NULL);
+
+ *(state->payload_mut++) = (major_type << 5) | (additional & 0x1F);
+ return true;
+}
+
+/** Encode a single value.
+ */
+static bool value_encode_len(cbor_state_t *state, cbor_major_type_t major_type,
+ const void *const input, uint32_t result_len)
+{
+ uint8_t *u8_result = (uint8_t *)input;
+
+ if ((state->payload + 1 + result_len) > state->payload_end) {
+ FAIL();
+ }
+
+ if (!encode_header_byte(state, major_type,
+ get_additional(result_len, u8_result[0]))) {
+ FAIL();
+ }
+ state->payload_mut--;
+ cbor_trace();
+ state->payload_mut++;
+
+#ifdef CONFIG_BIG_ENDIAN
+ memcpy(state->payload_mut, u8_result, result_len);
+ state->payload_mut += result_len;
+#else
+ for (; result_len > 0; result_len--) {
+ *(state->payload_mut++) = u8_result[result_len - 1];
+ }
+#endif
+
+ state->elem_count++;
+ return true;
+}
+
+
+static uint32_t get_result_len(const void *const input, uint32_t max_result_len)
+{
+ uint8_t *u8_result = (uint8_t *)input;
+ size_t i;
+
+ for (i = 0; i < max_result_len; i++) {
+#ifdef CONFIG_BIG_ENDIAN
+ size_t idx = i;
+#else
+ size_t idx = max_result_len - 1 - i;
+#endif
+ if (u8_result[idx] != 0) {
+ break;
+ }
+ }
+ max_result_len -= i;
+
+ /* According to specification result length can be encoded on 1, 2, 4
+ * or 8 bytes.
+ */
+ cbor_assert(max_result_len <= 8, "Up to 8 bytes can be used to encode length.\n");
+ size_t encode_byte_cnt = 1;
+
+ for (size_t i = 0; i <= 3; i++) {
+ if (max_result_len <= encode_byte_cnt) {
+ max_result_len = encode_byte_cnt;
+ break;
+ }
+
+ encode_byte_cnt *= 2;
+ }
+
+ if ((max_result_len == 1) && (u8_result[0] <= VALUE_IN_HEADER)) {
+ max_result_len = 0;
+ }
+
+ return max_result_len;
+}
+
+
+static bool value_encode(cbor_state_t *state, cbor_major_type_t major_type,
+ const void *const input, uint32_t max_result_len)
+{
+ cbor_assert(max_result_len != 0, "0-length result not supported.\n");
+ return value_encode_len(state, major_type, input,
+ get_result_len(input, max_result_len));
+}
+
+
+bool intx32_put(cbor_state_t *state, int32_t input)
+{
+ cbor_major_type_t major_type;
+
+ if (input < 0) {
+ major_type = CBOR_MAJOR_TYPE_NINT;
+ /* Convert from CBOR's representation. */
+ input = -1 - input;
+ } else {
+ major_type = CBOR_MAJOR_TYPE_PINT;
+ input = input;
+ }
+
+ if (!value_encode(state, major_type, &input, 4)) {
+ FAIL();
+ }
+
+ return true;
+}
+
+bool intx32_encode(cbor_state_t *state, const int32_t *input)
+{
+ return intx32_put(state, *input);
+}
+
+
+static bool uint32_encode(cbor_state_t *state, const uint32_t *input,
+ cbor_major_type_t major_type)
+{
+ if (!value_encode(state, major_type, input, 4)) {
+ FAIL();
+ }
+ return true;
+}
+
+
+bool uintx32_encode(cbor_state_t *state, const uint32_t *input)
+{
+ if (!uint32_encode(state, input, CBOR_MAJOR_TYPE_PINT)) {
+ FAIL();
+ }
+ return true;
+}
+
+
+bool uintx32_put(cbor_state_t *state, uint32_t input)
+{
+ if (!uint32_encode(state, &input, CBOR_MAJOR_TYPE_PINT)) {
+ FAIL();
+ }
+ return true;
+}
+
+
+static bool strx_start_encode(cbor_state_t *state,
+ const cbor_string_type_t *input, cbor_major_type_t major_type)
+{
+ if (input->value && ((get_result_len(&input->len, sizeof(input->len))
+ + 1 + input->len + (size_t)state->payload)
+ > (size_t)state->payload_end)) {
+ FAIL();
+ }
+ if (!uint32_encode(state, &input->len, major_type)) {
+ FAIL();
+ }
+
+ return true;
+}
+
+
+static bool primx_encode(cbor_state_t *state, uint32_t input)
+{
+ if (!uint32_encode(state, &input, CBOR_MAJOR_TYPE_PRIM)) {
+ FAIL();
+ }
+ return true;
+}
+
+
+static uint32_t remaining_str_len(cbor_state_t *state)
+{
+ uint32_t max_len = (size_t)state->payload_end - (size_t)state->payload;
+ uint32_t result_len = get_result_len(&max_len, sizeof(uint32_t));
+ return max_len - result_len - 1;
+}
+
+
+bool bstrx_cbor_start_encode(cbor_state_t *state, const cbor_string_type_t *result)
+{
+ if (!new_backup(state, 0)) {
+ FAIL();
+ }
+
+ uint32_t max_len = remaining_str_len(state);
+
+ /* Encode a dummy header */
+ if (!uint32_encode(state, &max_len,
+ CBOR_MAJOR_TYPE_BSTR)) {
+ FAIL();
+ }
+ return true;
+}
+
+
+bool bstrx_cbor_end_encode(cbor_state_t *state)
+{
+ const uint8_t *payload = state->payload;
+
+ if (!restore_backup(state, FLAG_RESTORE | FLAG_DISCARD, 0xFFFFFFFF)) {
+ FAIL();
+ }
+ cbor_string_type_t value;
+
+ value.value = state->payload_end - remaining_str_len(state);
+ value.len = (size_t)payload - (size_t)value.value;
+
+ /* Reencode header of list now that we know the number of elements. */
+ if (!bstrx_encode(state, &value)) {
+ FAIL();
+ }
+ return true;
+}
+
+
+static bool strx_encode(cbor_state_t *state,
+ const cbor_string_type_t *input, cbor_major_type_t major_type)
+{
+ if (!strx_start_encode(state, input, major_type)) {
+ FAIL();
+ }
+ if (input->len > (state->payload_end - state->payload)) {
+ FAIL();
+ }
+ if (state->payload_mut != input->value) {
+ memmove(state->payload_mut, input->value, input->len);
+ }
+ state->payload += input->len;
+ return true;
+}
+
+
+bool bstrx_encode(cbor_state_t *state, const cbor_string_type_t *input)
+{
+ return strx_encode(state, input, CBOR_MAJOR_TYPE_BSTR);
+}
+
+
+bool tstrx_encode(cbor_state_t *state, const cbor_string_type_t *input)
+{
+ return strx_encode(state, input, CBOR_MAJOR_TYPE_TSTR);
+}
+
+
+static bool list_map_start_encode(cbor_state_t *state, uint32_t max_num,
+ cbor_major_type_t major_type)
+{
+#ifdef CDDL_CBOR_CANONICAL
+ if (!new_backup(state, 0)) {
+ FAIL();
+ }
+
+ /* Encode dummy header with max number of elements. */
+ if (!uint32_encode(state, &max_num, major_type)) {
+ FAIL();
+ }
+ state->elem_count--; /* Because of dummy header. */
+#else
+ if (!encode_header_byte(state, major_type, 31)) {
+ FAIL();
+ }
+#endif
+ return true;
+}
+
+
+bool list_start_encode(cbor_state_t *state, uint32_t max_num)
+{
+ return list_map_start_encode(state, max_num, CBOR_MAJOR_TYPE_LIST);
+}
+
+
+bool map_start_encode(cbor_state_t *state, uint32_t max_num)
+{
+ return list_map_start_encode(state, max_num, CBOR_MAJOR_TYPE_MAP);
+}
+
+
+bool list_map_end_encode(cbor_state_t *state, uint32_t max_num,
+ cbor_major_type_t major_type)
+{
+#ifdef CDDL_CBOR_CANONICAL
+ uint32_t list_count = ((major_type == CBOR_MAJOR_TYPE_LIST) ?
+ state->elem_count
+ : (state->elem_count / 2));
+
+ const uint8_t *payload = state->payload;
+ uint32_t max_header_len = get_result_len(&max_num, 4);
+ uint32_t header_len = get_result_len(&list_count, 4);
+
+ if (!restore_backup(state, FLAG_RESTORE | FLAG_DISCARD, 0xFFFFFFFF)) {
+ FAIL();
+ }
+
+ cbor_print("list_count: %d\r\n", list_count);
+
+ /* Reencode header of list now that we know the number of elements. */
+ if (!(uint32_encode(state, &list_count, major_type))) {
+ FAIL();
+ }
+
+ if (max_header_len != header_len) {
+ const uint8_t *start = state->payload + max_header_len - header_len;
+ uint32_t body_size = payload - start;
+ memmove(state->payload_mut,
+ state->payload + max_header_len - header_len,
+ body_size);
+ /* Reset payload pointer to end of list */
+ state->payload += body_size;
+ } else {
+ /* Reset payload pointer to end of list */
+ state->payload = payload;
+ }
+#else
+ if (!encode_header_byte(state, CBOR_MAJOR_TYPE_PRIM, 31)) {
+ FAIL();
+ }
+#endif
+ return true;
+}
+
+
+bool list_end_encode(cbor_state_t *state, uint32_t max_num)
+{
+ return list_map_end_encode(state, max_num, CBOR_MAJOR_TYPE_LIST);
+}
+
+
+bool map_end_encode(cbor_state_t *state, uint32_t max_num)
+{
+ return list_map_end_encode(state, max_num, CBOR_MAJOR_TYPE_MAP);
+}
+
+
+bool nilx_put(cbor_state_t *state, const void *input)
+{
+ (void)input;
+ return primx_encode(state, 22);
+}
+
+
+bool boolx_encode(cbor_state_t *state, const bool *input)
+{
+ if (!primx_encode(state, *input + BOOL_TO_PRIM)) {
+ FAIL();
+ }
+ return true;
+}
+
+
+bool boolx_put(cbor_state_t *state, bool input)
+{
+ if (!primx_encode(state, input + BOOL_TO_PRIM)) {
+ FAIL();
+ }
+ return true;
+}
+
+
+bool double_encode(cbor_state_t *state, double *input)
+{
+ if (!value_encode(state, CBOR_MAJOR_TYPE_PRIM, input,
+ sizeof(*input))) {
+ FAIL();
+ }
+
+ return true;
+}
+
+
+bool double_put(cbor_state_t *state, double input)
+{
+ return double_encode(state, &input);
+}
+
+
+bool any_encode(cbor_state_t *state, void *input)
+{
+ return nilx_put(state, input);
+}
+
+
+bool tag_encode(cbor_state_t *state, uint32_t tag)
+{
+ if (!value_encode(state, CBOR_MAJOR_TYPE_TAG, &tag, sizeof(tag))) {
+ FAIL();
+ }
+ state->elem_count--;
+
+ return true;
+}
+
+
+bool multi_encode(uint32_t min_encode,
+ uint32_t max_encode,
+ const uint32_t *num_encode,
+ cbor_encoder_t encoder,
+ cbor_state_t *state,
+ const void *input,
+ uint32_t result_len)
+{
+ if (!PTR_VALUE_IN_RANGE(uint32_t, num_encode, NULL, &max_encode)) {
+ FAIL();
+ }
+ for (uint32_t i = 0; i < *num_encode; i++) {
+ if (!encoder(state, (const uint8_t *)input + i*result_len)) {
+ FAIL();
+ }
+ }
+ cbor_print("Found %zu elements.\n", *num_encode);
+ return true;
+}
+
+
+bool present_encode(const uint32_t *present,
+ cbor_encoder_t encoder,
+ cbor_state_t *state,
+ const void *input)
+{
+ uint32_t num_encode = *present;
+ bool retval = multi_encode(0, 1, &num_encode, encoder, state, input, 0);
+ return retval;
+}
diff --git a/boot/boot_serial/src/cbor_encode.h b/boot/boot_serial/src/cbor_encode.h
new file mode 100644
index 0000000..4c53d45
--- /dev/null
+++ b/boot/boot_serial/src/cbor_encode.h
@@ -0,0 +1,150 @@
+/*
+ * This file has been copied from the cddl-gen submodule.
+ * Commit 9f77837f9950da1633d22abf6181a830521a6688
+ */
+
+/*
+ * Copyright (c) 2020 Nordic Semiconductor ASA
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef CBOR_ENCODE_H__
+#define CBOR_ENCODE_H__
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include "cbor_common.h"
+
+
+/** Encode a PINT/NINT into a int32_t.
+ *
+ * @param[inout] state The current state of the decoding.
+ * @param[out] result Where to place the encoded value.
+ *
+ * @retval true Everything is ok.
+ * @retval false If the payload is exhausted.
+ */
+bool intx32_encode(cbor_state_t *state, const int32_t *input);
+bool intx32_put(cbor_state_t *state, int32_t result);
+
+/** Encode a PINT into a uint32_t. */
+bool uintx32_encode(cbor_state_t *state, const uint32_t *result);
+bool uintx32_put(cbor_state_t *state, uint32_t result);
+
+/** Encode a BSTR header.
+ *
+ * The rest of the string can be encoded as CBOR.
+ * A state backup is created to keep track of the element count.
+ *
+ * @retval true Header encoded correctly
+ * @retval false Header encoded incorrectly, or backup failed.
+ */
+bool bstrx_cbor_start_encode(cbor_state_t *state, const cbor_string_type_t *result);
+
+/** Finalize encoding a CBOR-encoded BSTR.
+ *
+ * Restore element count from backup.
+ */
+bool bstrx_cbor_end_encode(cbor_state_t *state);
+
+/** Encode a BSTR, */
+bool bstrx_encode(cbor_state_t *state, const cbor_string_type_t *result);
+
+/** Encode a TSTR. */
+bool tstrx_encode(cbor_state_t *state, const cbor_string_type_t *result);
+
+#define tstrx_put(state, string) \
+ tstrx_encode(state, &(cbor_string_type_t){.value = (const uint8_t *)string, .len = (sizeof(string) - 1)})
+
+#define tstrx_put_term(state, string) \
+ tstrx_encode(state, &(cbor_string_type_t){.value = (const uint8_t *)string, .len = strlen((const char *)string)})
+
+/** Encode a LIST header.
+ *
+ * The contents of the list can be decoded via subsequent function calls.
+ * A state backup is created to keep track of the element count.
+ */
+bool list_start_encode(cbor_state_t *state, uint32_t max_num);
+
+/** Encode a MAP header. */
+bool map_start_encode(cbor_state_t *state, uint32_t max_num);
+
+/** Encode end of a LIST. Do some checks and deallocate backup. */
+bool list_end_encode(cbor_state_t *state, uint32_t max_num);
+
+/** Encode end of a MAP. Do some checks and deallocate backup. */
+bool map_end_encode(cbor_state_t *state, uint32_t max_num);
+
+/** Encode a "nil" primitive value. result should be NULL. */
+bool nilx_put(cbor_state_t *state, const void *result);
+
+/** Encode a boolean primitive value. */
+bool boolx_encode(cbor_state_t *state, const bool *result);
+bool boolx_put(cbor_state_t *state, bool result);
+
+/** Encode a float */
+bool float_encode(cbor_state_t *state, double *result);
+bool float_put(cbor_state_t *state, double result);
+
+/** Dummy encode "any": Encode a "nil". input should be NULL. */
+bool any_encode(cbor_state_t *state, void *input);
+
+/** Encode a tag. */
+bool tag_encode(cbor_state_t *state, uint32_t tag);
+
+/** Encode 0 or more elements with the same type and constraints.
+ *
+ * @details This must not necessarily encode all elements in a list. E.g. if
+ * the list contains 3 INTS between 0 and 100 followed by 0 to 2 BSTRs
+ * with length 8, that could be done with:
+ *
+ * @code{c}
+ * uint32_t int_min = 0;
+ * uint32_t int_max = 100;
+ * uint32_t bstr_size = 8;
+ * uint32_t ints[3];
+ * cbor_string_type_t bstrs[2] = <initialize here>;
+ * bool res;
+ *
+ * res = list_start_encode(state, 5);
+ * // check res
+ * res = multi_encode(3, 3, &num_encode, uintx32_encode, state,
+ * ints, 4);
+ * // check res
+ * res = multi_encode(0, 2, &num_encode, strx_encode, state,
+ * bstrs, sizeof(cbor_string_type_t));
+ * // check res
+ * res = list_end_encode(state, 5);
+ * // check res
+ * @endcode
+ *
+ * @param[in] min_encode The minimum acceptable number of elements.
+ * @param[in] max_encode The maximum acceptable number of elements.
+ * @param[in] num_encode The actual number of elements.
+ * @param[in] encoder The encoder function to call under the hood. This
+ * function will be called with the provided arguments
+ * repeatedly until the function fails (returns false)
+ * or until it has been called @p max_encode times.
+ * result is moved @p result_len bytes for each call
+ * to @p encoder, i.e. @p result refers to an array
+ * of result variables.
+ * @param[in] input Source of the encoded values. Must be an array
+ * of length at least @p max_encode.
+ * @param[in] result_len The length of the result variables. Must be the
+ * length of the elements in result.
+ *
+ * @retval true If at least @p min_encode variables were correctly encoded.
+ * @retval false If @p encoder failed before having encoded @p min_encode
+ * values.
+ */
+bool multi_encode(uint32_t min_encode, uint32_t max_encode, const uint32_t *num_encode,
+ cbor_encoder_t encoder, cbor_state_t *state, const void *input,
+ uint32_t result_len);
+
+bool present_encode(const uint32_t *present,
+ cbor_encoder_t encoder,
+ cbor_state_t *state,
+ const void *input);
+
+#endif /* CBOR_ENCODE_H__ */
diff --git a/boot/boot_serial/src/regenerate_serial_recovery_cbor.sh b/boot/boot_serial/src/regenerate_serial_recovery_cbor.sh
index 79cb6e9..08d1220 100755
--- a/boot/boot_serial/src/regenerate_serial_recovery_cbor.sh
+++ b/boot/boot_serial/src/regenerate_serial_recovery_cbor.sh
@@ -1,19 +1,19 @@
#!/bin/bash
if [ "$1" == "--help" ] || [ "$1" == "" ]; then
- echo "Regenerate serial_recovery_cbor.c|h if the cddl_gen submodule is updated."
+ echo "Regenerate serial_recovery_cbor.c|h if the cddl-gen submodule is updated."
echo "Usage: $0 <copyright>"
- echo " e.g. $0 \"2020 Nordic Semiconductor ASA\""
+ echo " e.g. $0 \"2021 Nordic Semiconductor ASA\""
exit -1
fi
add_copy_notice() {
echo "$(printf '/*
- * This file has been %s from the cddl_gen submodule.
+ * This file has been %s from the cddl-gen submodule.
* Commit %s
*/
-' "$2" "$(git -C ../../../ext/cddl_gen rev-parse HEAD)"; cat $1;)" > $1
+' "$2" "$(git -C ../../../ext/cddl-gen rev-parse HEAD)"; cat $1;)" > $1
}
echo "Copying cbor_decode.c|h"
@@ -22,11 +22,15 @@
add_copy_notice $2 "copied"
}
-copy_with_copy_notice ../../../ext/cddl_gen/src/cbor_decode.c cbor_decode.c
-copy_with_copy_notice ../../../ext/cddl_gen/include/cbor_decode.h cbor_decode.h cbor_decode.h
+copy_with_copy_notice ../../../ext/cddl-gen/src/cbor_decode.c cbor_decode.c
+copy_with_copy_notice ../../../ext/cddl-gen/src/cbor_encode.c cbor_encode.c
+copy_with_copy_notice ../../../ext/cddl-gen/src/cbor_common.c cbor_common.c
+copy_with_copy_notice ../../../ext/cddl-gen/include/cbor_decode.h cbor_decode.h
+copy_with_copy_notice ../../../ext/cddl-gen/include/cbor_encode.h cbor_encode.h
+copy_with_copy_notice ../../../ext/cddl-gen/include/cbor_common.h cbor_common.h
echo "Generating serial_recovery_cbor.c|h"
-python3 ../../../ext/cddl_gen/scripts/cddl_gen.py -i serial_recovery.cddl -t Upload --oc serial_recovery_cbor.c --oh serial_recovery_cbor.h --time-header
+python3 ../../../ext/cddl-gen/cddl_gen/cddl_gen.py -c serial_recovery.cddl code -d -t Upload --oc serial_recovery_cbor.c --oh serial_recovery_cbor.h --time-header
add_copyright() {
echo "$(printf '/*
@@ -42,3 +46,4 @@
add_copyright serial_recovery_cbor.h "$1"
add_copy_notice serial_recovery_cbor.c "generated"
add_copy_notice serial_recovery_cbor.h "generated"
+add_copy_notice types_serial_recovery_cbor.h "generated"
diff --git a/boot/boot_serial/src/serial_recovery_cbor.c b/boot/boot_serial/src/serial_recovery_cbor.c
index 45634ef..2561b70 100644
--- a/boot/boot_serial/src/serial_recovery_cbor.c
+++ b/boot/boot_serial/src/serial_recovery_cbor.c
@@ -1,16 +1,18 @@
/*
- * This file has been generated from the cddl_gen submodule.
- * Commit 9d911cf0c7c9f13b5a9fdd5ed6c1012df21e5576
+ * This file has been generated from the cddl-gen submodule.
+ * Commit 9f77837f9950da1633d22abf6181a830521a6688
*/
/*
- * Copyright (c) 2020 Nordic Semiconductor ASA
+ * Copyright (c) 2021 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
-/* Generated with cddl_gen.py (https://github.com/oyvindronningstad/cddl_gen)
- * at: 2020-05-13 12:19:04
+/*
+ * Generated with cddl_gen.py (https://github.com/NordicSemiconductor/cddl-gen)
+ * at: 2021-08-02 17:09:42
+ * Generated with a default_max_qty of 3
*/
#include <stdint.h>
@@ -20,65 +22,73 @@
#include "cbor_decode.h"
#include "serial_recovery_cbor.h"
+#if DEFAULT_MAX_QTY != 3
+#error "The type file was generated with a different default_max_qty than this file"
+#endif
+
static bool decode_Member(
- cbor_decode_state_t *p_state, void * p_result, void * p_min_value,
- void * p_max_value)
+ cbor_state_t *state, struct Member_ *result)
{
- cbor_decode_print("decode_Member\n");
- uint8_t const * p_payload_bak;
- size_t elem_count_bak;
- _Member_t* p_type_result = (_Member_t*)p_result;
+ cbor_print("%s\n", __func__);
+ cbor_string_type_t tmp_str;
+ bool int_res;
- bool result = (((p_payload_bak = p_state->p_payload) && ((elem_count_bak = p_state->elem_count) || 1) && ((((strx_decode(p_state, &((*p_type_result)._Member_image_key), NULL, NULL))&& !memcmp("image", (*p_type_result)._Member_image_key.value, (*p_type_result)._Member_image_key.len)
- && (intx32_decode(p_state, &((*p_type_result)._Member_image), NULL, NULL))) && (((*p_type_result)._Member_choice = _Member_image) || 1))
- || ((p_state->p_payload = p_payload_bak) && ((p_state->elem_count = elem_count_bak) || 1) && (((strx_decode(p_state, &((*p_type_result)._Member_data_key), NULL, NULL))&& !memcmp("data", (*p_type_result)._Member_data_key.value, (*p_type_result)._Member_data_key.len)
- && (strx_decode(p_state, &((*p_type_result)._Member_data), NULL, NULL))) && (((*p_type_result)._Member_choice = _Member_data) || 1)))
- || ((p_state->p_payload = p_payload_bak) && ((p_state->elem_count = elem_count_bak) || 1) && (((strx_decode(p_state, &((*p_type_result)._Member_len_key), NULL, NULL))&& !memcmp("len", (*p_type_result)._Member_len_key.value, (*p_type_result)._Member_len_key.len)
- && (intx32_decode(p_state, &((*p_type_result)._Member_len), NULL, NULL))) && (((*p_type_result)._Member_choice = _Member_len) || 1)))
- || ((p_state->p_payload = p_payload_bak) && ((p_state->elem_count = elem_count_bak) || 1) && (((strx_decode(p_state, &((*p_type_result)._Member_off_key), NULL, NULL))&& !memcmp("off", (*p_type_result)._Member_off_key.value, (*p_type_result)._Member_off_key.len)
- && (intx32_decode(p_state, &((*p_type_result)._Member_off), NULL, NULL))) && (((*p_type_result)._Member_choice = _Member_off) || 1)))
- || ((p_state->p_payload = p_payload_bak) && ((p_state->elem_count = elem_count_bak) || 1) && (((strx_decode(p_state, &((*p_type_result)._Member_sha_key), NULL, NULL))&& !memcmp("sha", (*p_type_result)._Member_sha_key.value, (*p_type_result)._Member_sha_key.len)
- && (strx_decode(p_state, &((*p_type_result)._Member_sha), NULL, NULL))) && (((*p_type_result)._Member_choice = _Member_sha) || 1))))));
+ bool tmp_result = (((union_start_code(state) && (int_res = (((((tstrx_expect(state, ((tmp_str.value = (const uint8_t *)"image",
+ tmp_str.len = sizeof("image") - 1, &tmp_str)))))
+ && (intx32_decode(state, (&(*result)._Member_image)))) && (((*result)._Member_choice = _Member_image) || 1))
+ || (union_elem_code(state) && ((((tstrx_expect(state, ((tmp_str.value = (const uint8_t *)"data",
+ tmp_str.len = sizeof("data") - 1, &tmp_str)))))
+ && (bstrx_decode(state, (&(*result)._Member_data)))) && (((*result)._Member_choice = _Member_data) || 1)))
+ || (union_elem_code(state) && ((((tstrx_expect(state, ((tmp_str.value = (const uint8_t *)"len",
+ tmp_str.len = sizeof("len") - 1, &tmp_str)))))
+ && (intx32_decode(state, (&(*result)._Member_len)))) && (((*result)._Member_choice = _Member_len) || 1)))
+ || (union_elem_code(state) && ((((tstrx_expect(state, ((tmp_str.value = (const uint8_t *)"off",
+ tmp_str.len = sizeof("off") - 1, &tmp_str)))))
+ && (intx32_decode(state, (&(*result)._Member_off)))) && (((*result)._Member_choice = _Member_off) || 1)))
+ || (union_elem_code(state) && ((((tstrx_expect(state, ((tmp_str.value = (const uint8_t *)"sha",
+ tmp_str.len = sizeof("sha") - 1, &tmp_str)))))
+ && (bstrx_decode(state, (&(*result)._Member_sha)))) && (((*result)._Member_choice = _Member_sha) || 1)))), union_end_code(state), int_res))));
- if (!result)
- {
- cbor_decode_trace();
- }
+ if (!tmp_result)
+ cbor_trace();
- return result;
+ return tmp_result;
}
static bool decode_Upload(
- cbor_decode_state_t *p_state, void * p_result, void * p_min_value,
- void * p_max_value)
+ cbor_state_t *state, struct Upload *result)
{
- cbor_decode_print("decode_Upload\n");
- size_t temp_elem_counts[2];
- size_t *p_temp_elem_count = temp_elem_counts;
- Upload_t* p_type_result = (Upload_t*)p_result;
+ cbor_print("%s\n", __func__);
+ bool int_res;
- bool result = (((list_start_decode(p_state, &(*(p_temp_elem_count++)), 1, 5))
- && multi_decode(1, 5, &(*p_type_result)._Upload_members_count, (void*)decode_Member, p_state, &((*p_type_result)._Upload_members), NULL, NULL, sizeof(_Member_t))
- && ((p_state->elem_count = *(--p_temp_elem_count)) || 1)));
+ bool tmp_result = (((map_start_decode(state) && (int_res = (multi_decode(1, 5, &(*result)._Upload_members_count, (void *)decode_Member, state, (&(*result)._Upload_members), sizeof(struct Member_))), ((map_end_decode(state)) && int_res)))));
- if (!result)
- {
- cbor_decode_trace();
- }
+ if (!tmp_result)
+ cbor_trace();
- p_state->elem_count = temp_elem_counts[0];
- return result;
+ return tmp_result;
}
-bool cbor_decode_Upload(const uint8_t * p_payload, size_t payload_len, Upload_t * p_result)
-{
- cbor_decode_state_t state = {
- .p_payload = p_payload,
- .p_payload_end = p_payload + payload_len,
- .elem_count = 1
- };
- return decode_Upload(&state, p_result, NULL, NULL);
+__attribute__((unused)) static bool type_test_decode_Upload(
+ struct Upload *result)
+{
+ /* This function should not be called, it is present only to test that
+ * the types of the function and struct match, since this information
+ * is lost with the casts in the entry function.
+ */
+ return decode_Upload(NULL, result);
+}
+
+
+bool cbor_decode_Upload(
+ const uint8_t *payload, uint32_t payload_len,
+ struct Upload *result,
+ uint32_t *payload_len_out)
+{
+ return entry_function(payload, payload_len, (const void *)result,
+ payload_len_out, (void *)decode_Upload,
+ 1, 2);
}
diff --git a/boot/boot_serial/src/serial_recovery_cbor.h b/boot/boot_serial/src/serial_recovery_cbor.h
index aa14f5c..f167d9b 100644
--- a/boot/boot_serial/src/serial_recovery_cbor.h
+++ b/boot/boot_serial/src/serial_recovery_cbor.h
@@ -1,16 +1,18 @@
/*
- * This file has been generated from the cddl_gen submodule.
- * Commit 9d911cf0c7c9f13b5a9fdd5ed6c1012df21e5576
+ * This file has been generated from the cddl-gen submodule.
+ * Commit 9f77837f9950da1633d22abf6181a830521a6688
*/
/*
- * Copyright (c) 2020 Nordic Semiconductor ASA
+ * Copyright (c) 2021 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
-/* Generated with cddl_gen.py (https://github.com/oyvindronningstad/cddl_gen)
- * at: 2020-05-13 12:19:04
+/*
+ * Generated with cddl_gen.py (https://github.com/NordicSemiconductor/cddl-gen)
+ * at: 2021-08-02 17:09:42
+ * Generated with a default_max_qty of 3
*/
#ifndef SERIAL_RECOVERY_CBOR_H__
@@ -21,45 +23,17 @@
#include <stddef.h>
#include <string.h>
#include "cbor_decode.h"
+#include "types_serial_recovery_cbor.h"
+
+#if DEFAULT_MAX_QTY != 3
+#error "The type file was generated with a different default_max_qty than this file"
+#endif
-typedef struct {
- union {
- struct {
- cbor_string_type_t _Member_image_key;
- int32_t _Member_image;
- };
- struct {
- cbor_string_type_t _Member_data_key;
- cbor_string_type_t _Member_data;
- };
- struct {
- cbor_string_type_t _Member_len_key;
- int32_t _Member_len;
- };
- struct {
- cbor_string_type_t _Member_off_key;
- int32_t _Member_off;
- };
- struct {
- cbor_string_type_t _Member_sha_key;
- cbor_string_type_t _Member_sha;
- };
- };
- enum {
- _Member_image,
- _Member_data,
- _Member_len,
- _Member_off,
- _Member_sha,
- } _Member_choice;
-} _Member_t;
+bool cbor_decode_Upload(
+ const uint8_t *payload, uint32_t payload_len,
+ struct Upload *result,
+ uint32_t *payload_len_out);
-typedef struct {
- _Member_t _Upload_members[5];
- size_t _Upload_members_count;
-} Upload_t;
-bool cbor_decode_Upload(const uint8_t * p_payload, size_t payload_len, Upload_t * p_result);
-
-#endif // SERIAL_RECOVERY_CBOR_H__
+#endif /* SERIAL_RECOVERY_CBOR_H__ */
diff --git a/boot/boot_serial/src/types_serial_recovery_cbor.h b/boot/boot_serial/src/types_serial_recovery_cbor.h
new file mode 100644
index 0000000..8856017
--- /dev/null
+++ b/boot/boot_serial/src/types_serial_recovery_cbor.h
@@ -0,0 +1,56 @@
+/*
+ * This file has been generated from the cddl-gen submodule.
+ * Commit 9f77837f9950da1633d22abf6181a830521a6688
+ */
+
+/*
+ * Generated with cddl_gen.py (https://github.com/NordicSemiconductor/cddl-gen)
+ * at: 2021-08-02 17:09:42
+ * Generated with a default_max_qty of 3
+ */
+
+#ifndef TYPES_SERIAL_RECOVERY_CBOR_H__
+#define TYPES_SERIAL_RECOVERY_CBOR_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+#include "cbor_decode.h"
+
+#define DEFAULT_MAX_QTY 3
+
+struct Member_ {
+ union {
+ struct {
+ int32_t _Member_image;
+ };
+ struct {
+ cbor_string_type_t _Member_data;
+ };
+ struct {
+ int32_t _Member_len;
+ };
+ struct {
+ int32_t _Member_off;
+ };
+ struct {
+ cbor_string_type_t _Member_sha;
+ };
+ };
+ enum {
+ _Member_image,
+ _Member_data,
+ _Member_len,
+ _Member_off,
+ _Member_sha,
+ } _Member_choice;
+};
+
+struct Upload {
+ struct Member_ _Upload_members[5];
+ uint32_t _Upload_members_count;
+};
+
+
+#endif /* TYPES_SERIAL_RECOVERY_CBOR_H__ */
diff --git a/boot/boot_serial/test/src/testcases/boot_serial_upload_bigger_image.c b/boot/boot_serial/test/src/testcases/boot_serial_upload_bigger_image.c
index 53a7199..83ba50a 100644
--- a/boot/boot_serial/test/src/testcases/boot_serial_upload_bigger_image.c
+++ b/boot/boot_serial/test/src/testcases/boot_serial_upload_bigger_image.c
@@ -18,7 +18,6 @@
*/
#include <flash_map_backend/flash_map_backend.h>
-#include <tinycbor/cborconstants_p.h>
#include "boot_test.h"