boot_serial: Update cddl-gen
Update and rename submodule.
Regenerate code and copy updated files.
Update regeneration script.
Signed-off-by: Øyvind Rønningstad <oyvind.ronningstad@nordicsemi.no>
diff --git a/.gitmodules b/.gitmodules
index 1e4e333..adcdcb8 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -19,6 +19,6 @@
[submodule "boot/cypress/libs/cy-mbedtls-acceleration"]
path = boot/cypress/libs/cy-mbedtls-acceleration
url = https://github.com/cypresssemiconductorco/cy-mbedtls-acceleration.git
-[submodule "boot/boot_serial/src/cddl_gen"]
- path = ext/cddl_gen
- url = https://github.com/oyvindronningstad/cddl_gen.git
+[submodule "ext/cddl-gen"]
+ path = ext/cddl-gen
+ url = https://github.com/NordicSemiconductor/cddl-gen.git
diff --git a/boot/boot_serial/src/boot_serial.c b/boot/boot_serial/src/boot_serial.c
index 5501126..5fa794a 100644
--- a/boot/boot_serial/src/boot_serial.c
+++ b/boot/boot_serial/src/boot_serial.c
@@ -27,7 +27,7 @@
#include "bootutil/bootutil_log.h"
#ifdef __ZEPHYR__
-#include <sys/reboot.h>
+#include <power/reboot.h>
#include <sys/byteorder.h>
#include <sys/__assert.h>
#include <drivers/flash.h>
@@ -254,13 +254,16 @@
* }
*/
- Upload_t upload;
- if (!cbor_decode_Upload((const uint8_t *)buf, len, &upload)) {
+ struct Upload upload;
+ size_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;
diff --git a/boot/boot_serial/src/cbor_common.c b/boot/boot_serial/src/cbor_common.c
new file mode 100644
index 0000000..79469d5
--- /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 8f9358a0b4b0e9b0cd579f0988056ef0b60760e4
+ */
+
+/*
+ * 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..ce73dd6
--- /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 8f9358a0b4b0e9b0cd579f0988056ef0b60760e4
+ */
+
+/*
+ * 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..74c4cd7 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 8f9358a0b4b0e9b0cd579f0988056ef0b60760e4
*/
/*
@@ -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,124 @@
/** 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);
+ 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);
+ uint8_t major_type = MAJOR_TYPE(*state->payload);
if (major_type != CBOR_MAJOR_TYPE_PINT
&& major_type != CBOR_MAJOR_TYPE_NINT) {
@@ -175,203 +163,376 @@
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)
+{
+ 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;
+ 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 ((state->payload + result->len) > state->payload_end) {
+ cbor_print("error: 0x%x > 0x%x\r\n",
+ (uint32_t)(state->payload + result->len),
+ (uint32_t)state->payload_end);
+ 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();
+ }
+
+ 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;
+
+ (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)
+{
+ uint32_t new_elem_count;
+ uint8_t major_type = MAJOR_TYPE(*state->payload);
+
+ 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)
+{
+ 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)
+{
+ 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);
+ 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 +543,76 @@
}
-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;
+ 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..b0cfaa1 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 8f9358a0b4b0e9b0cd579f0988056ef0b60760e4
*/
/*
@@ -9,11 +9,12 @@
* 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.
*
@@ -21,23 +22,19 @@
* $CDDL_GEN_BASE/scripts/cddl_gen.py
*
* 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 +51,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 +66,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 +75,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 +182,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/regenerate_serial_recovery_cbor.sh b/boot/boot_serial/src/regenerate_serial_recovery_cbor.sh
index 79cb6e9..b371e0a 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/scripts/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..4277a7d 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 8f9358a0b4b0e9b0cd579f0988056ef0b60760e4
*/
/*
- * 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-05-10 09:40:43
+ * 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..bccc443 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 8f9358a0b4b0e9b0cd579f0988056ef0b60760e4
*/
/*
- * 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-05-10 09:40:43
+ * 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..01505eb
--- /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 8f9358a0b4b0e9b0cd579f0988056ef0b60760e4
+ */
+
+/*
+ * Generated with cddl_gen.py (https://github.com/NordicSemiconductor/cddl-gen)
+ * at: 2021-05-10 09:40:43
+ * 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/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt
index 3c8b93d..29cff0a 100644
--- a/boot/zephyr/CMakeLists.txt
+++ b/boot/zephyr/CMakeLists.txt
@@ -239,6 +239,7 @@
zephyr_sources(${BOOT_DIR}/boot_serial/src/boot_serial.c)
zephyr_sources(${BOOT_DIR}/boot_serial/src/serial_recovery_cbor.c)
zephyr_sources(${BOOT_DIR}/boot_serial/src/cbor_decode.c)
+ zephyr_sources(${BOOT_DIR}/boot_serial/src/cbor_common.c)
zephyr_include_directories(${BOOT_DIR}/bootutil/include)
zephyr_include_directories(${BOOT_DIR}/boot_serial/include)
diff --git a/ext/cddl-gen b/ext/cddl-gen
new file mode 160000
index 0000000..8f9358a
--- /dev/null
+++ b/ext/cddl-gen
@@ -0,0 +1 @@
+Subproject commit 8f9358a0b4b0e9b0cd579f0988056ef0b60760e4
diff --git a/ext/cddl_gen b/ext/cddl_gen
deleted file mode 160000
index 9d911cf..0000000
--- a/ext/cddl_gen
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 9d911cf0c7c9f13b5a9fdd5ed6c1012df21e5576