Initial commit
Initial commit.
This commit is contained in:
24
bootloader/mcuboot/boot/zcbor/add_zcbor_copy_version.sh
Normal file
24
bootloader/mcuboot/boot/zcbor/add_zcbor_copy_version.sh
Normal file
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ "$1" == "--help" ]; then
|
||||
echo "Add header if the zcbor files are updated."
|
||||
exit -1
|
||||
fi
|
||||
|
||||
add_copy_notice() {
|
||||
echo "$(printf '/*
|
||||
* This file has been %s from the zcbor library.
|
||||
* Commit %s
|
||||
*/
|
||||
|
||||
' "$2" "$(zcbor --version)"; cat $1;)" > $1
|
||||
}
|
||||
|
||||
add_copy_notice src/zcbor_decode.c "copied"
|
||||
add_copy_notice src/zcbor_encode.c "copied"
|
||||
add_copy_notice src/zcbor_common.c "copied"
|
||||
add_copy_notice include/zcbor_decode.h "copied"
|
||||
add_copy_notice include/zcbor_encode.h "copied"
|
||||
add_copy_notice include/zcbor_common.h "copied"
|
||||
add_copy_notice include/zcbor_print.h "copied"
|
||||
add_copy_notice include/zcbor_tags.h "copied"
|
||||
514
bootloader/mcuboot/boot/zcbor/include/zcbor_common.h
Normal file
514
bootloader/mcuboot/boot/zcbor/include/zcbor_common.h
Normal file
@@ -0,0 +1,514 @@
|
||||
/*
|
||||
* This file has been copied from the zcbor library.
|
||||
* Commit zcbor 0.8.1
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2020 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZCBOR_COMMON_H__
|
||||
#define ZCBOR_COMMON_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include "zcbor_tags.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ZCBOR_STRINGIFY_PRE(x) #x
|
||||
#define ZCBOR_STRINGIFY(s) ZCBOR_STRINGIFY_PRE(s)
|
||||
|
||||
#define ZCBOR_VERSION_MAJOR 0
|
||||
#define ZCBOR_VERSION_MINOR 8
|
||||
#define ZCBOR_VERSION_BUGFIX 1
|
||||
|
||||
/** The version string with dots and not prefix. */
|
||||
#define ZCBOR_VERSION_STR ZCBOR_STRINGIFY(ZCBOR_VERSION_MAJOR) \
|
||||
"." ZCBOR_STRINGIFY(ZCBOR_VERSION_MINOR) \
|
||||
"." ZCBOR_STRINGIFY(ZCBOR_VERSION_BUGFIX)
|
||||
|
||||
/** Monotonically increasing integer representing the version. */
|
||||
#define ZCBOR_VERSION ((ZCBOR_VERSION_MAJOR << 24) \
|
||||
+ (ZCBOR_VERSION_MINOR << 16) \
|
||||
+ (ZCBOR_VERSION_BUGFIX << 8))
|
||||
|
||||
/** Convenience type that allows pointing to strings directly inside the payload
|
||||
* without the need to copy out.
|
||||
*/
|
||||
struct zcbor_string {
|
||||
const uint8_t *value;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
|
||||
/** Type representing a string fragment.
|
||||
*
|
||||
* Don't modify any member variables, or subsequent calls may fail.
|
||||
**/
|
||||
struct zcbor_string_fragment {
|
||||
struct zcbor_string fragment; ///! Location and length of the fragment.
|
||||
size_t offset; ///! The offset in the full string at which this fragment belongs.
|
||||
size_t total_len; ///! The total length of the string this fragment is a part of.
|
||||
};
|
||||
|
||||
|
||||
/** Size to use in struct zcbor_string_fragment when the real size is unknown. */
|
||||
#define ZCBOR_STRING_FRAGMENT_UNKNOWN_LENGTH SIZE_MAX
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a, b) (((a) < (b)) ? (b) : (a))
|
||||
#endif
|
||||
|
||||
#ifndef ZCBOR_ARRAY_SIZE
|
||||
#define ZCBOR_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
#endif
|
||||
|
||||
/* Endian-dependent offset of smaller integer in a bigger one. */
|
||||
#ifdef ZCBOR_BIG_ENDIAN
|
||||
#define ZCBOR_ECPY_OFFS(dst_len, src_len) ((dst_len) - (src_len))
|
||||
#else
|
||||
#define ZCBOR_ECPY_OFFS(dst_len, src_len) (0)
|
||||
#endif /* ZCBOR_BIG_ENDIAN */
|
||||
|
||||
#if SIZE_MAX <= UINT64_MAX
|
||||
/** The ZCBOR_SUPPORTS_SIZE_T will be defined if processing of size_t type variables directly
|
||||
* with zcbor_size_ functions is supported.
|
||||
**/
|
||||
#define ZCBOR_SUPPORTS_SIZE_T
|
||||
#else
|
||||
#warning "zcbor: Unsupported size_t encoding size"
|
||||
#endif
|
||||
|
||||
struct zcbor_state_constant;
|
||||
|
||||
/** The zcbor_state_t structure is used for both encoding and decoding. */
|
||||
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. */
|
||||
size_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. */
|
||||
bool payload_moved; /**< Is set to true while the state is stored as a backup
|
||||
if @ref zcbor_update_state is called, since that function
|
||||
updates the payload_end of all backed-up states. */
|
||||
|
||||
/* This is the "decode state", the part of zcbor_state_t that is only used by zcbor_decode.c. */
|
||||
struct {
|
||||
bool indefinite_length_array; /**< Is set to true if the decoder is currently
|
||||
decoding the contents of an indefinite-
|
||||
length array. */
|
||||
bool counting_map_elems; /**< Is set to true while the number of elements of the
|
||||
current map are being counted. */
|
||||
#ifdef ZCBOR_MAP_SMART_SEARCH
|
||||
uint8_t *map_search_elem_state; /**< Optional flags to use when searching unordered
|
||||
maps. If this is not NULL and map_elem_count
|
||||
is non-zero, this consists of one flag per element
|
||||
in the current map. The n-th bit can be set to 0
|
||||
to indicate that the n-th element in the
|
||||
map should not be searched. These are manipulated
|
||||
via zcbor_elem_processed() or
|
||||
zcbor_unordered_map_search(), and should not be
|
||||
manipulated directly. */
|
||||
#else
|
||||
size_t map_elems_processed; /**< The number of elements of an unordered map
|
||||
that have been processed. */
|
||||
#endif
|
||||
size_t map_elem_count; /**< Number of elements in the current unordered map.
|
||||
This also serves as the number of bits (not bytes)
|
||||
in the map_search_elem_state array (when applicable). */
|
||||
} decode_state;
|
||||
struct zcbor_state_constant *constant_state; /**< The part of the state that is
|
||||
not backed up and duplicated. */
|
||||
} zcbor_state_t;
|
||||
|
||||
struct zcbor_state_constant {
|
||||
zcbor_state_t *backup_list;
|
||||
size_t current_backup;
|
||||
size_t num_backups;
|
||||
int error;
|
||||
#ifdef ZCBOR_STOP_ON_ERROR
|
||||
bool stop_on_error;
|
||||
#endif
|
||||
bool manually_process_elem; /**< Whether an (unordered map) element should be automatically
|
||||
marked as processed when found via @ref zcbor_search_map_key. */
|
||||
#ifdef ZCBOR_MAP_SMART_SEARCH
|
||||
uint8_t *map_search_elem_state_end; /**< The end of the @ref map_search_elem_state buffer. */
|
||||
#endif
|
||||
};
|
||||
|
||||
/** Function pointer type used with zcbor_multi_decode.
|
||||
*
|
||||
* This type is compatible with all decoding functions here and in the generated
|
||||
* code, except for zcbor_multi_decode.
|
||||
*/
|
||||
typedef bool(zcbor_encoder_t)(zcbor_state_t *, const void *);
|
||||
typedef bool(zcbor_decoder_t)(zcbor_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
|
||||
{
|
||||
ZCBOR_MAJOR_TYPE_PINT = 0, ///! Positive Integer
|
||||
ZCBOR_MAJOR_TYPE_NINT = 1, ///! Negative Integer
|
||||
ZCBOR_MAJOR_TYPE_BSTR = 2, ///! Byte String
|
||||
ZCBOR_MAJOR_TYPE_TSTR = 3, ///! Text String
|
||||
ZCBOR_MAJOR_TYPE_LIST = 4, ///! List
|
||||
ZCBOR_MAJOR_TYPE_MAP = 5, ///! Map
|
||||
ZCBOR_MAJOR_TYPE_TAG = 6, ///! Semantic Tag
|
||||
ZCBOR_MAJOR_TYPE_SIMPLE = 7, ///! Simple values and floats
|
||||
} zcbor_major_type_t;
|
||||
|
||||
/** Extract the major type, i.e. the first 3 bits of the header byte. */
|
||||
#define ZCBOR_MAJOR_TYPE(header_byte) ((zcbor_major_type_t)(((header_byte) >> 5) & 0x7))
|
||||
|
||||
/** Extract the additional info, i.e. the last 5 bits of the header byte. */
|
||||
#define ZCBOR_ADDITIONAL(header_byte) ((header_byte) & 0x1F)
|
||||
|
||||
/** Convenience macro for failing out of a decoding/encoding function.
|
||||
*/
|
||||
#define ZCBOR_FAIL() \
|
||||
do {\
|
||||
zcbor_log("ZCBOR_FAIL "); \
|
||||
zcbor_trace_file(state); \
|
||||
return false; \
|
||||
} while(0)
|
||||
|
||||
#define ZCBOR_FAIL_IF(expr) \
|
||||
do {\
|
||||
if (expr) { \
|
||||
zcbor_log("ZCBOR_FAIL_IF(" #expr ") "); \
|
||||
ZCBOR_FAIL(); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define ZCBOR_ERR(err) \
|
||||
do { \
|
||||
zcbor_log("ZCBOR_ERR(%d) ", err); \
|
||||
zcbor_error(state, err); \
|
||||
ZCBOR_FAIL(); \
|
||||
} while(0)
|
||||
|
||||
#define ZCBOR_ERR_IF(expr, err) \
|
||||
do {\
|
||||
if (expr) { \
|
||||
zcbor_log("ZCBOR_ERR_IF(" #expr ", %d) ", err); \
|
||||
ZCBOR_ERR(err); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define ZCBOR_CHECK_PAYLOAD() \
|
||||
ZCBOR_ERR_IF(state->payload >= state->payload_end, ZCBOR_ERR_NO_PAYLOAD)
|
||||
|
||||
#ifdef ZCBOR_STOP_ON_ERROR
|
||||
#define ZCBOR_CHECK_ERROR() \
|
||||
do { \
|
||||
if (!zcbor_check_error(state)) { \
|
||||
ZCBOR_FAIL(); \
|
||||
} \
|
||||
} while(0)
|
||||
#else
|
||||
#define ZCBOR_CHECK_ERROR()
|
||||
#endif
|
||||
|
||||
#define ZCBOR_VALUE_IN_HEADER 23 ///! Values below this are encoded directly in the header.
|
||||
#define ZCBOR_VALUE_IS_1_BYTE 24 ///! The next 1 byte contains the value.
|
||||
#define ZCBOR_VALUE_IS_2_BYTES 25 ///! The next 2 bytes contain the value.
|
||||
#define ZCBOR_VALUE_IS_4_BYTES 26 ///! The next 4 bytes contain the value.
|
||||
#define ZCBOR_VALUE_IS_8_BYTES 27 ///! The next 8 bytes contain the value.
|
||||
#define ZCBOR_VALUE_IS_INDEFINITE_LENGTH 31 ///! The list or map has indefinite length, and will instead be terminated by a 0xFF token.
|
||||
|
||||
#define ZCBOR_BOOL_TO_SIMPLE ((uint8_t)20) ///! In CBOR, false/true have the values 20/21
|
||||
|
||||
#define ZCBOR_FLAG_RESTORE 1UL ///! Restore from the backup. Overwrite the current state with the state from the backup.
|
||||
#define ZCBOR_FLAG_CONSUME 2UL ///! Consume the backup. Remove the backup from the stack of backups.
|
||||
#define ZCBOR_FLAG_KEEP_PAYLOAD 4UL ///! Keep the pre-restore payload after restoring.
|
||||
#define ZCBOR_FLAG_KEEP_DECODE_STATE 8UL ///! Keep the pre-restore decode state (everything only used for decoding)
|
||||
|
||||
#define ZCBOR_SUCCESS 0
|
||||
#define ZCBOR_ERR_NO_BACKUP_MEM 1
|
||||
#define ZCBOR_ERR_NO_BACKUP_ACTIVE 2
|
||||
#define ZCBOR_ERR_LOW_ELEM_COUNT 3
|
||||
#define ZCBOR_ERR_HIGH_ELEM_COUNT 4
|
||||
#define ZCBOR_ERR_INT_SIZE 5
|
||||
#define ZCBOR_ERR_FLOAT_SIZE 6
|
||||
#define ZCBOR_ERR_ADDITIONAL_INVAL 7 ///! > 27
|
||||
#define ZCBOR_ERR_NO_PAYLOAD 8
|
||||
#define ZCBOR_ERR_PAYLOAD_NOT_CONSUMED 9
|
||||
#define ZCBOR_ERR_WRONG_TYPE 10
|
||||
#define ZCBOR_ERR_WRONG_VALUE 11
|
||||
#define ZCBOR_ERR_WRONG_RANGE 12
|
||||
#define ZCBOR_ERR_ITERATIONS 13
|
||||
#define ZCBOR_ERR_ASSERTION 14
|
||||
#define ZCBOR_ERR_PAYLOAD_OUTDATED 15 ///! Because of a call to @ref zcbor_update_state
|
||||
#define ZCBOR_ERR_ELEM_NOT_FOUND 16
|
||||
#define ZCBOR_ERR_MAP_MISALIGNED 17
|
||||
#define ZCBOR_ERR_ELEMS_NOT_PROCESSED 18
|
||||
#define ZCBOR_ERR_NOT_AT_END 19
|
||||
#define ZCBOR_ERR_MAP_FLAGS_NOT_AVAILABLE 20
|
||||
#define ZCBOR_ERR_INVALID_VALUE_ENCODING 21 ///! When ZCBOR_CANONICAL is defined, and the incoming data is not encoded with minimal length.
|
||||
#define ZCBOR_ERR_UNKNOWN 31
|
||||
|
||||
/** The largest possible elem_count. */
|
||||
#define ZCBOR_MAX_ELEM_COUNT SIZE_MAX
|
||||
|
||||
/** Initial value for elem_count for when it just needs to be large. */
|
||||
#define ZCBOR_LARGE_ELEM_COUNT (ZCBOR_MAX_ELEM_COUNT - 15)
|
||||
|
||||
|
||||
/** Take a backup of the current state. Overwrite the current elem_count. */
|
||||
bool zcbor_new_backup(zcbor_state_t *state, size_t new_elem_count);
|
||||
|
||||
/** Consult the most recent backup. In doing so, check whether elem_count is
|
||||
* less than or equal to max_elem_count.
|
||||
* Also, take action based on the flags (See ZCBOR_FLAG_*).
|
||||
*/
|
||||
bool zcbor_process_backup(zcbor_state_t *state, uint32_t flags, size_t max_elem_count);
|
||||
|
||||
/** Convenience function for starting encoding/decoding of a union.
|
||||
*
|
||||
* That is, for attempting to encode, or especially decode, multiple options.
|
||||
* Makes a new backup.
|
||||
*/
|
||||
bool zcbor_union_start_code(zcbor_state_t *state);
|
||||
|
||||
/** Convenience function before encoding/decoding one element of a union.
|
||||
*
|
||||
* Call this before attempting each option.
|
||||
* Restores the backup, without consuming it.
|
||||
*/
|
||||
bool zcbor_union_elem_code(zcbor_state_t *state);
|
||||
|
||||
/** Convenience function before encoding/decoding one element of a union.
|
||||
*
|
||||
* Consumes the backup without restoring it.
|
||||
*/
|
||||
bool zcbor_union_end_code(zcbor_state_t *state);
|
||||
|
||||
/** Initialize a state with backups.
|
||||
* As long as n_states is more than 1, one of the states in the array is used
|
||||
* as a struct zcbor_state_constant object.
|
||||
* If there is no struct zcbor_state_constant (n_states == 1), error codes are
|
||||
* not available.
|
||||
* This means that you get a state with (n_states - 2) backups.
|
||||
* payload, payload_len, elem_count, and elem_state are used to initialize the first state.
|
||||
* The elem_state is only needed for unordered maps, when ZCBOR_MAP_SMART_SEARCH is enabled.
|
||||
* It is ignored otherwise.
|
||||
*/
|
||||
void zcbor_new_state(zcbor_state_t *state_array, size_t n_states,
|
||||
const uint8_t *payload, size_t payload_len, size_t elem_count,
|
||||
uint8_t *elem_state, size_t elem_state_bytes);
|
||||
|
||||
/** Do boilerplate entry function procedure.
|
||||
* Initialize states, call function, and check the result.
|
||||
*/
|
||||
int zcbor_entry_function(const uint8_t *payload, size_t payload_len,
|
||||
void *result, size_t *payload_len_out, zcbor_state_t *state, zcbor_decoder_t func,
|
||||
size_t n_states, size_t elem_count);
|
||||
|
||||
#ifdef ZCBOR_STOP_ON_ERROR
|
||||
/** Check stored error and fail if present, but only if stop_on_error is true.
|
||||
*
|
||||
* @retval true No error found
|
||||
* @retval false An error was found
|
||||
*/
|
||||
static inline bool zcbor_check_error(const zcbor_state_t *state)
|
||||
{
|
||||
struct zcbor_state_constant *cs = state->constant_state;
|
||||
return !(cs && cs->stop_on_error && cs->error);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Return the current error state, replacing it with SUCCESS. */
|
||||
static inline int zcbor_pop_error(zcbor_state_t *state)
|
||||
{
|
||||
if (!state->constant_state) {
|
||||
return ZCBOR_SUCCESS;
|
||||
}
|
||||
int err = state->constant_state->error;
|
||||
|
||||
state->constant_state->error = ZCBOR_SUCCESS;
|
||||
return err;
|
||||
}
|
||||
|
||||
/** Look at current error state without altering it */
|
||||
static inline int zcbor_peek_error(const zcbor_state_t *state)
|
||||
{
|
||||
if (!state->constant_state) {
|
||||
return ZCBOR_SUCCESS;
|
||||
} else {
|
||||
return state->constant_state->error;
|
||||
}
|
||||
}
|
||||
|
||||
/** Write the provided error to the error state. */
|
||||
static inline void zcbor_error(zcbor_state_t *state, int err)
|
||||
{
|
||||
#ifdef ZCBOR_STOP_ON_ERROR
|
||||
if (zcbor_check_error(state))
|
||||
#endif
|
||||
{
|
||||
if (state->constant_state) {
|
||||
state->constant_state->error = err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Whether the current payload is exhausted. */
|
||||
static inline bool zcbor_payload_at_end(const zcbor_state_t *state)
|
||||
{
|
||||
return (state->payload == state->payload_end);
|
||||
}
|
||||
|
||||
/** Update the current payload pointer (and payload_end).
|
||||
*
|
||||
* For use when the payload is divided into multiple chunks.
|
||||
*
|
||||
* This function also updates all backups to the new payload_end.
|
||||
* This sets a flag so that @ref zcbor_process_backup fails if a backup is
|
||||
* processed with the flag @ref ZCBOR_FLAG_RESTORE, but without the flag
|
||||
* @ref ZCBOR_FLAG_KEEP_PAYLOAD since this would cause an invalid state.
|
||||
*
|
||||
* @param[inout] state The current state, will be updated with
|
||||
* the new payload pointer.
|
||||
* @param[in] payload The new payload chunk.
|
||||
* @param[in] payload_len The length of the new payload chunk.
|
||||
*/
|
||||
void zcbor_update_state(zcbor_state_t *state,
|
||||
const uint8_t *payload, size_t payload_len);
|
||||
|
||||
/** Check that the provided fragments are complete and in the right order.
|
||||
*
|
||||
* If the total length is not known, the total_len can have the value
|
||||
* @ref ZCBOR_STRING_FRAGMENT_UNKNOWN_LENGTH. If so, all fragments will be
|
||||
* updated with the actual total length.
|
||||
*
|
||||
* @param[in] fragments An array of string fragments. Cannot be NULL.
|
||||
* @param[in] num_fragments The number of fragments in @p fragments.
|
||||
*
|
||||
* @retval true If the fragments are in the right order, and there are no
|
||||
* fragments missing.
|
||||
* @retval false If not all fragments have the same total_len, or gaps are
|
||||
* found, or if any fragment value is NULL.
|
||||
*/
|
||||
bool zcbor_validate_string_fragments(struct zcbor_string_fragment *fragments,
|
||||
size_t num_fragments);
|
||||
|
||||
/** Assemble the fragments into a single string.
|
||||
*
|
||||
* The fragments are copied in the order they appear, without regard for
|
||||
* offset or total_len. To ensure that the fragments are correct, first
|
||||
* validate with @ref zcbor_validate_string_fragments.
|
||||
*
|
||||
* @param[in] fragments An array of string fragments. Cannot be NULL.
|
||||
* @param[in] num_fragments The number of fragments in @p fragments.
|
||||
* @param[out] result The buffer to place the assembled string into.
|
||||
* @param[inout] result_len In: The length of the @p result.
|
||||
* Out: The length of the assembled string.
|
||||
*
|
||||
* @retval true On success.
|
||||
* @retval false If the assembled string would be larger than the buffer.
|
||||
* The buffer might still be written to.
|
||||
*/
|
||||
bool zcbor_splice_string_fragments(struct zcbor_string_fragment *fragments,
|
||||
size_t num_fragments, uint8_t *result, size_t *result_len);
|
||||
|
||||
/** Compare two struct zcbor_string instances.
|
||||
*
|
||||
* @param[in] str1 A string
|
||||
* @param[in] str2 A string to compare to @p str1
|
||||
*
|
||||
* @retval true if the strings are identical
|
||||
* @retval false if length or contents don't match, or one one or both strings is NULL.
|
||||
*/
|
||||
bool zcbor_compare_strings(const struct zcbor_string *str1,
|
||||
const struct zcbor_string *str2);
|
||||
|
||||
/** Calculate the length of a CBOR string, list, or map header.
|
||||
*
|
||||
* This can be used to find the start of the CBOR object when you have a
|
||||
* pointer to the start of the contents. The function assumes that the header
|
||||
* will be the shortest it can be.
|
||||
*
|
||||
* @param[in] num_elems The number of elements in the string, list, or map.
|
||||
*
|
||||
* @return The length of the header in bytes (1-9).
|
||||
*/
|
||||
size_t zcbor_header_len(uint64_t value);
|
||||
|
||||
/** Like @ref zcbor_header_len but for integer of any size <= 8. */
|
||||
size_t zcbor_header_len_ptr(const void *const value, size_t value_len);
|
||||
|
||||
/** Convert a float16 value to float32.
|
||||
*
|
||||
* @param[in] input The float16 value stored in a uint16_t.
|
||||
*
|
||||
* @return The resulting float32 value.
|
||||
*/
|
||||
float zcbor_float16_to_32(uint16_t input);
|
||||
|
||||
/** Convert a float32 value to float16.
|
||||
*
|
||||
* @param[in] input The float32 value.
|
||||
*
|
||||
* @return The resulting float16 value as a uint16_t.
|
||||
*/
|
||||
uint16_t zcbor_float32_to_16(float input);
|
||||
|
||||
#ifdef ZCBOR_MAP_SMART_SEARCH
|
||||
static inline size_t zcbor_round_up(size_t x, size_t align)
|
||||
{
|
||||
return (((x) + (align) - 1) / (align) * (align));
|
||||
}
|
||||
|
||||
#define ZCBOR_BITS_PER_BYTE 8
|
||||
/** Calculate the number of bytes needed to hold @p num_flags 1 bit flags
|
||||
*/
|
||||
static inline size_t zcbor_flags_to_bytes(size_t num_flags)
|
||||
{
|
||||
return zcbor_round_up(num_flags, ZCBOR_BITS_PER_BYTE) / ZCBOR_BITS_PER_BYTE;
|
||||
}
|
||||
|
||||
/** Calculate the number of zcbor_state_t instances needed to hold @p num_flags 1 bit flags
|
||||
*/
|
||||
static inline size_t zcbor_flags_to_states(size_t num_flags)
|
||||
{
|
||||
return zcbor_round_up(num_flags, sizeof(zcbor_state_t) * ZCBOR_BITS_PER_BYTE)
|
||||
/ (sizeof(zcbor_state_t) * ZCBOR_BITS_PER_BYTE);
|
||||
}
|
||||
|
||||
#define ZCBOR_FLAG_STATES(n_flags) zcbor_flags_to_states(n_flags)
|
||||
|
||||
#else
|
||||
#define ZCBOR_FLAG_STATES(n_flags) 0
|
||||
#endif
|
||||
|
||||
size_t strnlen(const char *, size_t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZCBOR_COMMON_H__ */
|
||||
452
bootloader/mcuboot/boot/zcbor/include/zcbor_decode.h
Normal file
452
bootloader/mcuboot/boot/zcbor/include/zcbor_decode.h
Normal file
@@ -0,0 +1,452 @@
|
||||
/*
|
||||
* This file has been copied from the zcbor library.
|
||||
* Commit zcbor 0.8.1
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2020 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZCBOR_DECODE_H__
|
||||
#define ZCBOR_DECODE_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include "zcbor_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** The zcbor_decode library provides functions for decoding CBOR data elements.
|
||||
*
|
||||
* See The README for an introduction to CBOR, including the meaning of pint,
|
||||
* nint, bstr etc.
|
||||
*/
|
||||
|
||||
|
||||
/** See @ref zcbor_new_state() */
|
||||
void zcbor_new_decode_state(zcbor_state_t *state_array, size_t n_states,
|
||||
const uint8_t *payload, size_t payload_len, size_t elem_count,
|
||||
uint8_t *elem_state, size_t elem_state_bytes);
|
||||
|
||||
/** Convenience macro for declaring and initializing a decoding state with backups.
|
||||
*
|
||||
* This gives you a state variable named @p name. The variable functions like
|
||||
* a pointer.
|
||||
*
|
||||
* @param[in] name The name of the new state variable.
|
||||
* @param[in] num_backups The number of backup slots to keep in the state.
|
||||
* @param[in] payload The payload to work on.
|
||||
* @param[in] payload_size The size (in bytes) of @p payload.
|
||||
* @param[in] elem_count The starting elem_count (typically 1).
|
||||
* @param[in] n_flags For use if ZCBOR_MAP_SMART_SEARCH is enabled, ignored otherwise.
|
||||
* The total number of unordered map search flags needed.
|
||||
* I.e. the largest number of elements expected in an unordered map,
|
||||
* including elements in nested unordered maps.
|
||||
*/
|
||||
#define ZCBOR_STATE_D(name, num_backups, payload, payload_size, elem_count, n_flags) \
|
||||
zcbor_state_t name[((num_backups) + 2 + ZCBOR_FLAG_STATES(n_flags))]; \
|
||||
do { \
|
||||
zcbor_new_decode_state(name, ZCBOR_ARRAY_SIZE(name), payload, payload_size, elem_count, \
|
||||
(uint8_t *)&name[(num_backups) + 1], ZCBOR_FLAG_STATES(n_flags) * sizeof(zcbor_state_t)); \
|
||||
} while(0)
|
||||
|
||||
|
||||
/** The following applies to all _decode() functions listed directly below.
|
||||
*
|
||||
* @param[inout] state The current state of the decoding.
|
||||
* @param[out] result Where to place the decoded value.
|
||||
* @param[in] result_size (if present) Size in bytes of the memory at @p result
|
||||
*
|
||||
* @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, or the value was larger than can
|
||||
* fit in the result variable.
|
||||
* Use zcbor_peek_error() to see the error code.
|
||||
*/
|
||||
bool zcbor_int32_decode(zcbor_state_t *state, int32_t *result); /* pint/nint */
|
||||
bool zcbor_int64_decode(zcbor_state_t *state, int64_t *result); /* pint/nint */
|
||||
bool zcbor_uint32_decode(zcbor_state_t *state, uint32_t *result); /* pint */
|
||||
bool zcbor_uint64_decode(zcbor_state_t *state, uint64_t *result); /* pint */
|
||||
bool zcbor_size_decode(zcbor_state_t *state, size_t *result); /* pint */
|
||||
bool zcbor_int_decode(zcbor_state_t *state, void *result, size_t result_size); /* pint/nint */
|
||||
bool zcbor_uint_decode(zcbor_state_t *state, void *result, size_t result_size); /* pint */
|
||||
bool zcbor_bstr_decode(zcbor_state_t *state, struct zcbor_string *result); /* bstr */
|
||||
bool zcbor_tstr_decode(zcbor_state_t *state, struct zcbor_string *result); /* tstr */
|
||||
bool zcbor_tag_decode(zcbor_state_t *state, uint32_t *result); /* CBOR tag */
|
||||
bool zcbor_simple_decode(zcbor_state_t *state, uint8_t *result); /* CBOR simple value */
|
||||
bool zcbor_bool_decode(zcbor_state_t *state, bool *result); /* boolean CBOR simple value */
|
||||
bool zcbor_float16_decode(zcbor_state_t *state, float *result); /* IEEE754 float16 */
|
||||
bool zcbor_float16_bytes_decode(zcbor_state_t *state, uint16_t *result); /* IEEE754 float16 raw bytes */
|
||||
bool zcbor_float16_32_decode(zcbor_state_t *state, float *result); /* IEEE754 float16 or float32 */
|
||||
bool zcbor_float32_decode(zcbor_state_t *state, float *result); /* IEEE754 float32 */
|
||||
bool zcbor_float32_64_decode(zcbor_state_t *state, double *result); /* IEEE754 float32 or float64 */
|
||||
bool zcbor_float64_decode(zcbor_state_t *state, double *result); /* IEEE754 float64 */
|
||||
bool zcbor_float_decode(zcbor_state_t *state, double *result); /* IEEE754 float16, float32, or float64 */
|
||||
|
||||
/** The following applies to all _expect() and _pexpect() functions listed directly below.
|
||||
*
|
||||
* @param[inout] state The current state of the decoding.
|
||||
* @param[in] expected The expected value.
|
||||
*
|
||||
* @retval true If the result was decoded correctly and has the expected value.
|
||||
* @retval false If the decoding failed or the result doesn't have the
|
||||
* expected value.
|
||||
* Use zcbor_peek_error() to see the error code.
|
||||
*/
|
||||
bool zcbor_int32_expect(zcbor_state_t *state, int32_t expected); /* pint/nint */
|
||||
bool zcbor_int64_expect(zcbor_state_t *state, int64_t expected); /* pint/nint */
|
||||
bool zcbor_uint32_expect(zcbor_state_t *state, uint32_t expected); /* pint */
|
||||
bool zcbor_uint64_expect(zcbor_state_t *state, uint64_t expected); /* pint */
|
||||
bool zcbor_size_expect(zcbor_state_t *state, size_t expected); /* pint */
|
||||
bool zcbor_bstr_expect(zcbor_state_t *state, struct zcbor_string *expected); /* bstr */
|
||||
bool zcbor_tstr_expect(zcbor_state_t *state, struct zcbor_string *expected); /* tstr */
|
||||
bool zcbor_tag_expect(zcbor_state_t *state, uint32_t expected); /* CBOR tag */
|
||||
bool zcbor_simple_expect(zcbor_state_t *state, uint8_t expected); /* CBOR simple value */
|
||||
bool zcbor_bool_expect(zcbor_state_t *state, bool expected); /* boolean CBOR simple value */
|
||||
bool zcbor_nil_expect(zcbor_state_t *state, void *unused); /* 'nil' CBOR simple value */
|
||||
bool zcbor_undefined_expect(zcbor_state_t *state, void *unused); /* 'undefined' CBOR simple value */
|
||||
bool zcbor_float16_expect(zcbor_state_t *state, float expected); /* IEEE754 float16 */
|
||||
bool zcbor_float16_bytes_expect(zcbor_state_t *state, uint16_t expected); /* IEEE754 float16 raw bytes */
|
||||
bool zcbor_float16_32_expect(zcbor_state_t *state, float expected); /* IEEE754 float16 or float32 */
|
||||
bool zcbor_float32_expect(zcbor_state_t *state, float expected); /* IEEE754 float32 */
|
||||
bool zcbor_float32_64_expect(zcbor_state_t *state, double expected); /* IEEE754 float32 or float64 */
|
||||
bool zcbor_float64_expect(zcbor_state_t *state, double expected); /* IEEE754 float64 */
|
||||
bool zcbor_float_expect(zcbor_state_t *state, double expected); /* IEEE754 float16, float32, or float64 */
|
||||
|
||||
/** Like the _expect() functions but the value is passed through a pointer.
|
||||
* (for use as a zcbor_decoder_t function) */
|
||||
bool zcbor_int32_pexpect(zcbor_state_t *state, int32_t *expected); /* pint/nint */
|
||||
bool zcbor_int64_pexpect(zcbor_state_t *state, int64_t *expected); /* pint/nint */
|
||||
bool zcbor_uint32_pexpect(zcbor_state_t *state, uint32_t *expected); /* pint */
|
||||
bool zcbor_uint64_pexpect(zcbor_state_t *state, uint64_t *expected); /* pint */
|
||||
bool zcbor_size_pexpect(zcbor_state_t *state, size_t *expected); /* pint */
|
||||
bool zcbor_tag_pexpect(zcbor_state_t *state, uint32_t *expected); /* CBOR tag */
|
||||
bool zcbor_simple_pexpect(zcbor_state_t *state, uint8_t *expected); /* CBOR simple value */
|
||||
bool zcbor_bool_pexpect(zcbor_state_t *state, bool *expected); /* boolean CBOR simple value */
|
||||
bool zcbor_float16_pexpect(zcbor_state_t *state, float *expected); /* IEEE754 float16 */
|
||||
bool zcbor_float16_bytes_pexpect(zcbor_state_t *state, uint16_t *expected); /* IEEE754 float16 raw bytes */
|
||||
bool zcbor_float16_32_pexpect(zcbor_state_t *state, float *expected); /* IEEE754 float16 or float32 */
|
||||
bool zcbor_float32_pexpect(zcbor_state_t *state, float *expected); /* IEEE754 float32 */
|
||||
bool zcbor_float32_64_pexpect(zcbor_state_t *state, double *expected); /* IEEE754 float32 or float64 */
|
||||
bool zcbor_float64_pexpect(zcbor_state_t *state, double *expected); /* IEEE754 float64 */
|
||||
bool zcbor_float_pexpect(zcbor_state_t *state, double *expected); /* IEEE754 float16, float32, or float64 */
|
||||
|
||||
/** Consume and expect a pint/nint with a certain value, within a union.
|
||||
*
|
||||
* Calls @ref zcbor_union_elem_code then @ref zcbor_[u]int[32|64]_expect.
|
||||
*/
|
||||
bool zcbor_int32_expect_union(zcbor_state_t *state, int32_t expected);
|
||||
bool zcbor_int64_expect_union(zcbor_state_t *state, int64_t expected);
|
||||
bool zcbor_uint32_expect_union(zcbor_state_t *state, uint32_t expected);
|
||||
bool zcbor_uint64_expect_union(zcbor_state_t *state, uint64_t expected);
|
||||
|
||||
/** Decode and consume a list/map 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.
|
||||
* Call @ref zcbor_list_end_decode / @ref zcbor_map_end_decode when done
|
||||
* decoding the contents of the list/map
|
||||
*
|
||||
* @retval true Header decoded correctly
|
||||
* @retval false Header decoded incorrectly, or backup failed.
|
||||
*/
|
||||
bool zcbor_list_start_decode(zcbor_state_t *state);
|
||||
bool zcbor_map_start_decode(zcbor_state_t *state);
|
||||
bool zcbor_unordered_map_start_decode(zcbor_state_t *state);
|
||||
|
||||
/** Search for a key in a map.
|
||||
*
|
||||
* The CBOR spec allows elements (key-value pairs) in maps to appear in any order.
|
||||
* This function should be used when the order of elements is unknown.
|
||||
*
|
||||
* This must only be used while inside a map that has been entered via
|
||||
* @ref zcbor_unordered_map_start_decode. Use @ref zcbor_unordered_map_end_decode
|
||||
* when leaving the map.
|
||||
*
|
||||
* This function searches for keys. When this function returns successfully,
|
||||
* the @p state is pointing to the value corresponding to the found key.
|
||||
* Therefore, to be able to call this function again, the value must first be
|
||||
* decoded or skipped.
|
||||
*
|
||||
* When searching unordered maps, the found elements must be kept track of.
|
||||
* By default, this function automatically keeps track, which means it keeps a
|
||||
* running count of the number of found elements, which is checked when exiting
|
||||
* the map. You can do this manually instead, see @ref zcbor_elem_processed and
|
||||
* @ref manually_process_elem. If ZCBOR_MAP_SMART_SEARCH is defined, a flag is
|
||||
* kept for each element, instead of a rolling count.
|
||||
*
|
||||
* @note Unless ZCBOR_MAP_SMART_SEARCH is defined,
|
||||
* elements are not individually marked as processed, so they may
|
||||
* be returned again in a subsequent call to this function, if it is
|
||||
* matched by the @p key_decoder of that call. Because of this, you should
|
||||
* only use this function when you know the @p key_decoder matches no more
|
||||
* than one of the keys. Typically this means all keys are known strings
|
||||
* or integers, i.e. the @p key_decoder is typically a _pexpect() function.
|
||||
*
|
||||
* When searching for strings, there are convenience functions available,
|
||||
* see the zcbor_search_key_* functions.
|
||||
*
|
||||
* @param[in] key_decoder A decoding function that will be tried against all
|
||||
* keys in the map until it returns true, at which point
|
||||
* @ref zcbor_unordered_map_search will return true.
|
||||
* For example, a zcbor_*_pexpect() function.
|
||||
* @param[inout] state The current state of decoding. Must be currently decoding
|
||||
* the contents of a map, and pointing to one (any) of the
|
||||
* keys, not one of the values. If successful, the @p state
|
||||
* will be pointing to the value corresponding to the
|
||||
* matched key. If unsuccessful, the @p state will be
|
||||
* unchanged.
|
||||
* @param[inout] key_result This will be passed as the second argument to the
|
||||
* @p key_decoder.
|
||||
*
|
||||
* @retval true If the key was found, i.e. @p key_decoder returned true.
|
||||
* @retval false If the key was not found after searching all map elements.
|
||||
* Or the map was pointing to a value (not a key).
|
||||
* Or an unexpected error happened while skipping elements or
|
||||
* jumping from the end of the map to the start.
|
||||
*/
|
||||
bool zcbor_unordered_map_search(zcbor_decoder_t key_decoder, zcbor_state_t *state, void *key_result);
|
||||
|
||||
/** Find a specific bstr/tstr key as part of a map with unknown element order.
|
||||
*
|
||||
* Uses @ref zcbor_unordered_map_search under the hood. Please refer to those docs
|
||||
* for the conditions under which this can be called.
|
||||
* Refer to the docs for zcbor_(t|b)str_expect_* (e.g. @ref zcbor_bstr_expect_ptr)
|
||||
* for parameter docs.
|
||||
*/
|
||||
bool zcbor_search_key_bstr_ptr(zcbor_state_t *state, char const *ptr, size_t len);
|
||||
bool zcbor_search_key_tstr_ptr(zcbor_state_t *state, char const *ptr, size_t len);
|
||||
bool zcbor_search_key_bstr_term(zcbor_state_t *state, char const *str, size_t maxlen);
|
||||
bool zcbor_search_key_tstr_term(zcbor_state_t *state, char const *str, size_t maxlen);
|
||||
#define zcbor_search_key_bstr_lit(state, str) zcbor_search_key_bstr_ptr(state, str, sizeof(str) - 1)
|
||||
#define zcbor_search_key_tstr_lit(state, str) zcbor_search_key_tstr_ptr(state, str, sizeof(str) - 1)
|
||||
#define zcbor_search_key_bstr_arr(state, str) zcbor_search_key_bstr_ptr(state, str, (sizeof(str)))
|
||||
#define zcbor_search_key_tstr_arr(state, str) zcbor_search_key_tstr_ptr(state, str, (sizeof(str)))
|
||||
|
||||
/** (Optional) Call this function to mark an (unordered map) element as processed.
|
||||
*
|
||||
* @note This should not be called unless the @ref manually_process_elem flag is set.
|
||||
* By default, i.e. when @ref manually_process_elem is not set, this function is
|
||||
* called internally by @ref zcbor_unordered_map_search whenever a key is found.
|
||||
*
|
||||
* By default, this function increments the internal count @ref map_elems_processed.
|
||||
*
|
||||
* If ZCBOR_MAP_SMART_SEARCH is defined, this function instead clears a flag for the
|
||||
* element (key-value pair) that is currently being processed, or that has just been
|
||||
* processed, meaning the element won't be found again via @ref zcbor_unordered_map_search.
|
||||
*
|
||||
* @ref zcbor_unordered_map_end_decode will fail if @ref map_elems_processed does not
|
||||
* match the number of elements in the map, or if any of the map element's flag is set.
|
||||
*/
|
||||
bool zcbor_elem_processed(zcbor_state_t *state);
|
||||
|
||||
/** Finalize decoding a list/map
|
||||
*
|
||||
* Check that the list/map had the correct number of elements, and restore the
|
||||
* previous element count from the backup.
|
||||
*
|
||||
* Use @ref zcbor_list_map_end_force_decode to forcibly consume the backup if
|
||||
* something has gone wrong.
|
||||
*
|
||||
* In all successful cases, the state is returned pointing to the byte/element
|
||||
* after the list/map in the payload.
|
||||
*
|
||||
* @retval true Everything ok.
|
||||
* @retval false Element count not correct.
|
||||
*/
|
||||
bool zcbor_list_end_decode(zcbor_state_t *state);
|
||||
bool zcbor_map_end_decode(zcbor_state_t *state);
|
||||
bool zcbor_unordered_map_end_decode(zcbor_state_t *state);
|
||||
bool zcbor_list_map_end_force_decode(zcbor_state_t *state);
|
||||
|
||||
/** Find whether the state is at the end of a list or map.
|
||||
*/
|
||||
bool zcbor_array_at_end(zcbor_state_t *state);
|
||||
|
||||
/** Skip a single element, regardless of type and value.
|
||||
*
|
||||
* This means if the element is a map or list, this function will recursively
|
||||
* skip all its contents.
|
||||
* This function will also skip any tags preceeding the element.
|
||||
*
|
||||
* @param[inout] state The current state of the decoding.
|
||||
* @param[in] unused Unused parameter to maintain signature parity with
|
||||
* @ref zcbor_decoder_t.
|
||||
*/
|
||||
bool zcbor_any_skip(zcbor_state_t *state, void *unused);
|
||||
|
||||
/** Decode 0 or more elements with the same type and constraints.
|
||||
*
|
||||
* The decoded values will appear consecutively in the @p result array.
|
||||
*
|
||||
* The following is an example of decoding a list containing 3 INTS followed by
|
||||
* 0 to 2 bstrs:
|
||||
*
|
||||
* @code{c}
|
||||
* uint32_t ints[3];
|
||||
* struct zcbor_string bstrs[2];
|
||||
* uint32_t num_decode;
|
||||
* bool res;
|
||||
*
|
||||
* res = zcbor_list_start_decode(state);
|
||||
* res = res && zcbor_multi_decode(3, 3, &num_decode, zcbor_uint32_decode,
|
||||
* state, ints, sizeof(ints[0]));
|
||||
* res = res && zcbor_multi_decode(0, 2, &num_decode, zcbor_bstr_decode,
|
||||
* state, bstrs, sizeof(bstrs[0]));
|
||||
* res = res && zcbor_list_end_decode(state);
|
||||
* // check res
|
||||
* @endcode
|
||||
*
|
||||
* The @ref zcbor_decoder_t type is designed to be compatible with all single-
|
||||
* value decoder functions in this library, e.g. @ref zcbor_uint32_decode,
|
||||
* @ref zcbor_tstr_expect, @ref zcbor_nil_expect, etc. For _expect() functions,
|
||||
* @p result will be used as a value instead of an array/pointer, so
|
||||
* @p result_len will determine how much the value changes for each call.
|
||||
* To decode the same value multiple times, use a @p result_len of 0.
|
||||
* This function can also be used with custom decoder functions, such as those
|
||||
* generated by the zcbor.py script, which for example decodes larger chunks of
|
||||
* the data at once.
|
||||
*
|
||||
* @param[in] min_decode The minimum acceptable number of elements.
|
||||
* @param[in] max_decode The maximum acceptable number of elements.
|
||||
* @param[out] num_decode The actual number of elements decoded.
|
||||
* @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.
|
||||
* The result pointer is moved @p result_len bytes for
|
||||
* each call to @p decoder, i.e. @p result refers to
|
||||
* an array of result variables.
|
||||
* Should not be an _expect() function, use
|
||||
* _pexpect() instead.
|
||||
* @param[out] result Where to place the decoded values. Must be an array
|
||||
* of at least @p max_decode elements.
|
||||
* @param[in] result_len The length of each result variable. Must be the
|
||||
* length of the individual 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 zcbor_multi_decode(size_t min_decode, size_t max_decode, size_t *num_decode,
|
||||
zcbor_decoder_t decoder, zcbor_state_t *state, void *result,
|
||||
size_t result_len);
|
||||
|
||||
/** Attempt to decode a value that might not be present in the data.
|
||||
*
|
||||
* Works like @ref zcbor_multi_decode, with @p present as num_decode.
|
||||
* Will return true, even if the data is not present.
|
||||
*
|
||||
* @param[out] present Whether or not the data was present and successfully decoded.
|
||||
* @param[in] decoder The decoder to attempt.
|
||||
* @param[out] result The result, if present.
|
||||
*
|
||||
* @return Should always return true.
|
||||
*/
|
||||
bool zcbor_present_decode(bool *present,
|
||||
zcbor_decoder_t decoder,
|
||||
zcbor_state_t *state,
|
||||
void *result);
|
||||
|
||||
|
||||
/** Supplementary string (bstr/tstr) decoding functions: */
|
||||
|
||||
/** Consume and expect a bstr/tstr with the value of the provided char/uint8_t array.
|
||||
*
|
||||
* @param[inout] state The current state of the decoding.
|
||||
* @param[in] str The value to expect. A pointer to the string/array.
|
||||
* _term() uses strnlen(), so @p str must be null-terminated.
|
||||
* _lit() uses sizeof()-1, so @p str must be a (null-terminated) string literal.
|
||||
* _arr() uses sizeof(), so @p str must be a uint8_t array (not null-terminated).
|
||||
* @param[in] len (if present) The length of the string pointed to by @p str
|
||||
* @param[in] maxlen (if present) The maximum length of the string pointed to by @p str.
|
||||
* This value is passed to strnlen.
|
||||
*/
|
||||
bool zcbor_bstr_expect_ptr(zcbor_state_t *state, char const *ptr, size_t len);
|
||||
bool zcbor_tstr_expect_ptr(zcbor_state_t *state, char const *ptr, size_t len);
|
||||
bool zcbor_bstr_expect_term(zcbor_state_t *state, char const *str, size_t maxlen);
|
||||
bool zcbor_tstr_expect_term(zcbor_state_t *state, char const *str, size_t maxlen);
|
||||
#define zcbor_bstr_expect_lit(state, str) zcbor_bstr_expect_ptr(state, str, sizeof(str) - 1)
|
||||
#define zcbor_tstr_expect_lit(state, str) zcbor_tstr_expect_ptr(state, str, sizeof(str) - 1)
|
||||
#define zcbor_bstr_expect_arr(state, str) zcbor_bstr_expect_ptr(state, str, sizeof(str))
|
||||
#define zcbor_tstr_expect_arr(state, str) zcbor_tstr_expect_ptr(state, str, sizeof(str))
|
||||
|
||||
/** Decode and consume a bstr header.
|
||||
*
|
||||
* The rest of the string can be decoded as CBOR.
|
||||
* A state backup is created to keep track of the element count.
|
||||
* Call @ref zcbor_bstr_end_decode when done decoding the contents of the bstr.
|
||||
*
|
||||
* @param[inout] state The current state of the decoding.
|
||||
* @param[out] result The resulting string, for reference. The string should be decoded via
|
||||
* functions from this API since state is pointing to the start of the string,
|
||||
* not the end.
|
||||
*
|
||||
* @retval true Header decoded correctly
|
||||
* @retval false Header decoded incorrectly, or backup failed, or payload is not large enough
|
||||
* to contain the contents of the string. Use @ref zcbor_bstr_start_decode_fragment
|
||||
* for decoding fragmented payloads.
|
||||
*/
|
||||
bool zcbor_bstr_start_decode(zcbor_state_t *state, struct zcbor_string *result);
|
||||
|
||||
/** Finalize decoding a CBOR-encoded bstr.
|
||||
*
|
||||
* Restore element count from backup.
|
||||
*/
|
||||
bool zcbor_bstr_end_decode(zcbor_state_t *state);
|
||||
|
||||
|
||||
/** Supplementary string (bstr/tstr) decoding functions for fragmented payloads: */
|
||||
|
||||
/** Start decoding a bstr/tstr, even if the payload contains only part of it.
|
||||
*
|
||||
* This must be followed by a call to @ref zcbor_update_state, which can be
|
||||
* followed by a call to @ref zcbor_next_fragment. Do not call this function
|
||||
* again on subsequent fragments of the same string.
|
||||
*
|
||||
* This consumes the remaining payload as long as it belongs to the string.
|
||||
*/
|
||||
bool zcbor_bstr_decode_fragment(zcbor_state_t *state, struct zcbor_string_fragment *result);
|
||||
bool zcbor_tstr_decode_fragment(zcbor_state_t *state, struct zcbor_string_fragment *result);
|
||||
|
||||
/** Extract the next fragment of a string.
|
||||
*
|
||||
* Use this function to extract all but the first fragment.
|
||||
*/
|
||||
void zcbor_next_fragment(zcbor_state_t *state,
|
||||
struct zcbor_string_fragment *prev_fragment,
|
||||
struct zcbor_string_fragment *result);
|
||||
|
||||
/** Decode and consume a bstr header, assuming the payload does not contain the whole bstr.
|
||||
*
|
||||
* The rest of the string can be decoded as CBOR.
|
||||
* A state backup is created to keep track of the element count.
|
||||
* Call @ref zcbor_update_state followed by @ref zcbor_bstr_next_fragment when
|
||||
* the current payload has been exhausted.
|
||||
* Call @ref zcbor_bstr_end_decode when done decoding the contents of the bstr.
|
||||
*/
|
||||
bool zcbor_bstr_start_decode_fragment(zcbor_state_t *state,
|
||||
struct zcbor_string_fragment *result);
|
||||
|
||||
/** Start decoding the next fragment of a string.
|
||||
*
|
||||
* Use this function to extract all but the first fragment of a CBOR-encoded
|
||||
* bstr.
|
||||
*/
|
||||
void zcbor_bstr_next_fragment(zcbor_state_t *state,
|
||||
struct zcbor_string_fragment *prev_fragment,
|
||||
struct zcbor_string_fragment *result);
|
||||
|
||||
/** Can be used on any fragment to tell if it is the final fragment of the string. */
|
||||
bool zcbor_is_last_fragment(const struct zcbor_string_fragment *fragment);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZCBOR_DECODE_H__ */
|
||||
245
bootloader/mcuboot/boot/zcbor/include/zcbor_encode.h
Normal file
245
bootloader/mcuboot/boot/zcbor/include/zcbor_encode.h
Normal file
@@ -0,0 +1,245 @@
|
||||
/*
|
||||
* This file has been copied from the zcbor library.
|
||||
* Commit zcbor 0.8.1
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2020 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZCBOR_ENCODE_H__
|
||||
#define ZCBOR_ENCODE_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include "zcbor_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/** The zcbor_encode library provides functions for encoding CBOR data elements.
|
||||
*
|
||||
* See The README for an introduction to CBOR, including the meaning of pint,
|
||||
* nint, bstr etc.
|
||||
*/
|
||||
|
||||
|
||||
/** See @ref zcbor_new_state() */
|
||||
void zcbor_new_encode_state(zcbor_state_t *state_array, size_t n_states,
|
||||
uint8_t *payload, size_t payload_len, size_t elem_count);
|
||||
|
||||
/** Convenience macro for declaring and initializing an encoding state with backups.
|
||||
*
|
||||
* This gives you a state variable named @p name. The variable functions like
|
||||
* a pointer.
|
||||
*
|
||||
* @param[in] name The name of the new state variable.
|
||||
* @param[in] num_backups The number of backup slots to keep in the state.
|
||||
* @param[in] payload The payload to work on.
|
||||
* @param[in] payload_size The size (in bytes) of @p payload.
|
||||
* @param[in] elem_count The starting elem_count (typically 1).
|
||||
*/
|
||||
#define ZCBOR_STATE_E(name, num_backups, payload, payload_size, elem_count) \
|
||||
zcbor_state_t name[((num_backups) + 2)]; \
|
||||
do { \
|
||||
zcbor_new_encode_state(name, ZCBOR_ARRAY_SIZE(name), payload, payload_size, elem_count); \
|
||||
} while(0)
|
||||
|
||||
|
||||
/** The following applies to all _put and _encode functions listed directly below.
|
||||
*
|
||||
* The difference between _put and _encode is only in the argument type,
|
||||
* but when a @ref zcbor_encoder_t is needed, such as for @ref zcbor_multi_encode,
|
||||
* the _encode variant must be used.
|
||||
*
|
||||
* @param[inout] state The current state of the encoding.
|
||||
* @param[in] input The value to encode.
|
||||
*
|
||||
* @retval true Everything is ok.
|
||||
* @retval false If the payload is exhausted. Or an unexpected error happened.
|
||||
* Use zcbor_peek_error() to see the error code.
|
||||
*/
|
||||
bool zcbor_int32_put(zcbor_state_t *state, int32_t input); /* pint/nint */
|
||||
bool zcbor_int64_put(zcbor_state_t *state, int64_t input); /* pint/nint */
|
||||
bool zcbor_uint32_put(zcbor_state_t *state, uint32_t input); /* pint */
|
||||
bool zcbor_uint64_put(zcbor_state_t *state, uint64_t input); /* pint */
|
||||
bool zcbor_size_put(zcbor_state_t *state, size_t input); /* pint */
|
||||
bool zcbor_tag_put(zcbor_state_t *state, uint32_t tag); /* CBOR tag */
|
||||
bool zcbor_simple_put(zcbor_state_t *state, uint8_t input); /* CBOR simple value */
|
||||
bool zcbor_bool_put(zcbor_state_t *state, bool input); /* boolean CBOR simple value */
|
||||
bool zcbor_nil_put(zcbor_state_t *state, const void *unused); /* 'nil' CBOR simple value */
|
||||
bool zcbor_undefined_put(zcbor_state_t *state, const void *unused); /* 'undefined' CBOR simple value */
|
||||
bool zcbor_float16_put(zcbor_state_t *state, float input); /* IEEE754 float16 */
|
||||
bool zcbor_float16_bytes_put(zcbor_state_t *state, uint16_t input); /* IEEE754 float16 raw bytes */
|
||||
bool zcbor_float32_put(zcbor_state_t *state, float input); /* IEEE754 float32 */
|
||||
bool zcbor_float64_put(zcbor_state_t *state, double input); /* IEEE754 float64 */
|
||||
|
||||
bool zcbor_int32_encode(zcbor_state_t *state, const int32_t *input); /* pint/nint */
|
||||
bool zcbor_int64_encode(zcbor_state_t *state, const int64_t *input); /* pint/nint */
|
||||
bool zcbor_uint32_encode(zcbor_state_t *state, const uint32_t *input); /* pint */
|
||||
bool zcbor_uint64_encode(zcbor_state_t *state, const uint64_t *input); /* pint */
|
||||
bool zcbor_size_encode(zcbor_state_t *state, const size_t *input); /* pint */
|
||||
bool zcbor_int_encode(zcbor_state_t *state, const void *input_int, size_t int_size);
|
||||
bool zcbor_uint_encode(zcbor_state_t *state, const void *input_uint, size_t uint_size);
|
||||
bool zcbor_bstr_encode(zcbor_state_t *state, const struct zcbor_string *input); /* bstr */
|
||||
bool zcbor_tstr_encode(zcbor_state_t *state, const struct zcbor_string *input); /* tstr */
|
||||
bool zcbor_tag_encode(zcbor_state_t *state, uint32_t *tag); /* CBOR tag. Note that zcbor_tag_encode()'s argument was changed to be a pointer. See also zcbor_tag_put(). */
|
||||
bool zcbor_simple_encode(zcbor_state_t *state, uint8_t *input); /* CBOR simple value */
|
||||
bool zcbor_bool_encode(zcbor_state_t *state, const bool *input); /* boolean CBOR simple value */
|
||||
bool zcbor_float16_encode(zcbor_state_t *state, const float *input); /* IEEE754 float16 */
|
||||
bool zcbor_float16_bytes_encode(zcbor_state_t *state, const uint16_t *input); /* IEEE754 float16 raw bytes */
|
||||
bool zcbor_float32_encode(zcbor_state_t *state, const float *input); /* IEEE754 float32 */
|
||||
bool zcbor_float64_encode(zcbor_state_t *state, const double *input); /* IEEE754 float64 */
|
||||
|
||||
/** Encode a list/map header.
|
||||
*
|
||||
* The contents of the list/map can be encoded via subsequent function calls.
|
||||
* If ZCBOR_CANONICAL is defined, a state backup is created to keep track of the
|
||||
* element count.
|
||||
* When all members have been encoded, call @ref zcbor_list_end_encode /
|
||||
* @ref zcbor_map_end_encode to close the list/map.
|
||||
*
|
||||
* @param[inout] state The current state of the encoding.
|
||||
* @param[in] max_num The maximum number of members in the list/map.
|
||||
* This serves as a size hint for the header. Must be
|
||||
* equal to the max_num provided to the corresponding
|
||||
* @ref zcbor_list_end_encode / @ref zcbor_map_end_encode
|
||||
* call.
|
||||
* Only used when ZCBOR_CANONICAL is defined.
|
||||
*/
|
||||
bool zcbor_list_start_encode(zcbor_state_t *state, size_t max_num);
|
||||
bool zcbor_map_start_encode(zcbor_state_t *state, size_t max_num);
|
||||
|
||||
/** Encode the end of a list/map. Do some checks and deallocate backup.
|
||||
*
|
||||
* - Default: Adds a list terminator (0xFF) to mark the
|
||||
* end of the list/map.
|
||||
* - If ZCBOR_CANONICAL is defined: Instead encodes the number of members in
|
||||
* the list/map header. If the header ends up a different size than expected,
|
||||
* the list/map contents are moved using memmove().
|
||||
*
|
||||
* Use @ref zcbor_list_map_end_force_encode to forcibly consume the backup if
|
||||
* something has gone wrong.
|
||||
*
|
||||
* @param[inout] state The current state of the encoding.
|
||||
* @param[in] max_num The maximum number of members in the list/map. Must be
|
||||
* equal to the max_num provided to the corresponding
|
||||
* @ref zcbor_list_start_encode call.
|
||||
* Only used when ZCBOR_CANONICAL is defined.
|
||||
*/
|
||||
bool zcbor_list_end_encode(zcbor_state_t *state, size_t max_num);
|
||||
bool zcbor_map_end_encode(zcbor_state_t *state, size_t max_num);
|
||||
bool zcbor_list_map_end_force_encode(zcbor_state_t *state);
|
||||
|
||||
/** Encode 0 or more elements with the same type and constraints.
|
||||
*
|
||||
* The encoded values are taken from the @p input array.
|
||||
*
|
||||
* The following is an example of encoding a list containing 3 INTS followed by
|
||||
* 0 to 2 bstrs:
|
||||
*
|
||||
* @code{c}
|
||||
* uint32_t ints[3] = <initialize>;
|
||||
* struct zcbor_string bstrs[2] = <initialize>;
|
||||
* bool res;
|
||||
*
|
||||
* res = zcbor_list_start_encode(state, 5);
|
||||
* res = res && zcbor_multi_encode(3, zcbor_uint32_encode, state,
|
||||
* ints, sizeof(uint32_t));
|
||||
* res = res && zcbor_multi_encode(2, zcbor_bstr_encode, state,
|
||||
* bstrs, sizeof(struct zcbor_string));
|
||||
* res = res && zcbor_list_end_encode(state, 5);
|
||||
* // check res
|
||||
* @endcode
|
||||
*
|
||||
* The @ref zcbor_encoder_t type is designed to be compatible with all single-
|
||||
* value encoder functions in this library, e.g. @ref zcbor_uint32_encode,
|
||||
* @ref zcbor_tstr_put, @ref zcbor_nil_put, etc. For _put() functions,
|
||||
* @p input will be used as a value instead of an array/pointer, so
|
||||
* @p input_len will determine how much the value changes for each call.
|
||||
* To encode the same value multiple times, use a @p input_len of 0.
|
||||
* This function can also be used with custom decoder functions, such as those
|
||||
* generated by the zcbor.py script, which for example encodes larger chunks of
|
||||
* the data at once.
|
||||
*
|
||||
* @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.
|
||||
* The input pointer is moved @p input_len bytes for
|
||||
* each call to @p encoder, i.e. @p input refers to an
|
||||
* array of input variables.
|
||||
* @param[in] input Source of the encoded values. Must be an array of
|
||||
* at least @p max_encode elements.
|
||||
* @param[in] input_len The length of the input variables. Must be the
|
||||
* length of the individual elements in input.
|
||||
*
|
||||
* @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 zcbor_multi_encode(size_t num_encode, zcbor_encoder_t encoder,
|
||||
zcbor_state_t *state, const void *input, size_t result_len);
|
||||
|
||||
/** Works like @ref zcbor_multi_encode
|
||||
*
|
||||
* But first checks that @p num_encode is between @p min_encode and @p max_encode.
|
||||
*/
|
||||
bool zcbor_multi_encode_minmax(size_t min_encode, size_t max_encode,
|
||||
const size_t *num_encode, zcbor_encoder_t encoder,
|
||||
zcbor_state_t *state, const void *input, size_t input_len);
|
||||
|
||||
|
||||
/* Supplementary string (bstr/tstr) encoding functions: */
|
||||
|
||||
/** Encode a char/uint8_t pointer as a bstr/tstr.
|
||||
*
|
||||
* @param[inout] state The current state of the encoding.
|
||||
* @param[in] str The value to encode. A pointer to the string/array.
|
||||
* _term() uses strnlen(), so @p str must be null-terminated.
|
||||
* _lit() uses sizeof()-1, so @p str must be a (null-terminated) string literal.
|
||||
* _arr() uses sizeof(), so @p str must be a uint8_t array (not null-terminated).
|
||||
* @param[in] len (if present) The length of the string pointed to by @p str
|
||||
* @param[in] maxlen (if present) The maximum length of the string pointed to by @p str.
|
||||
* This value is passed to strnlen.
|
||||
*/
|
||||
bool zcbor_bstr_encode_ptr(zcbor_state_t *state, const char *str, size_t len);
|
||||
bool zcbor_tstr_encode_ptr(zcbor_state_t *state, const char *str, size_t len);
|
||||
bool zcbor_bstr_put_term(zcbor_state_t *state, char const *str, size_t maxlen);
|
||||
bool zcbor_tstr_put_term(zcbor_state_t *state, char const *str, size_t maxlen);
|
||||
#define zcbor_bstr_put_lit(state, str) zcbor_bstr_encode_ptr(state, str, sizeof(str) - 1)
|
||||
#define zcbor_tstr_put_lit(state, str) zcbor_tstr_encode_ptr(state, str, sizeof(str) - 1)
|
||||
#define zcbor_bstr_put_arr(state, str) zcbor_bstr_encode_ptr(state, str, sizeof(str))
|
||||
#define zcbor_tstr_put_arr(state, str) zcbor_tstr_encode_ptr(state, str, sizeof(str))
|
||||
|
||||
/** 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.
|
||||
* Call @ref zcbor_bstr_end_encode when done encoding the contents of the bstr.
|
||||
*
|
||||
* @param[inout] state The current state of the encoding.
|
||||
*
|
||||
* @retval true Header encoded correctly
|
||||
* @retval false Header encoded incorrectly, or backup failed.
|
||||
*/
|
||||
bool zcbor_bstr_start_encode(zcbor_state_t *state);
|
||||
|
||||
/** Finalize encoding a CBOR-encoded bstr.
|
||||
*
|
||||
* This writes the final size of the bstr to the header.
|
||||
* Restore element count from backup.
|
||||
*/
|
||||
bool zcbor_bstr_end_encode(zcbor_state_t *state, struct zcbor_string *result);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZCBOR_ENCODE_H__ */
|
||||
170
bootloader/mcuboot/boot/zcbor/include/zcbor_print.h
Normal file
170
bootloader/mcuboot/boot/zcbor/include/zcbor_print.h
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* This file has been copied from the zcbor library.
|
||||
* Commit zcbor 0.8.1
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2023 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZCBOR_PRINT_H__
|
||||
#define ZCBOR_PRINT_H__
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef ZCBOR_PRINT_FUNC
|
||||
#include <stdio.h>
|
||||
#define zcbor_do_print(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define zcbor_do_print(...) ZCBOR_PRINT_FUNC(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#ifdef ZCBOR_VERBOSE
|
||||
#define zcbor_trace_raw(state) (zcbor_do_print("rem: %zu, cur: 0x%x, ec: 0x%zx, err: %d",\
|
||||
(size_t)state->payload_end - (size_t)state->payload, *state->payload, state->elem_count, \
|
||||
state->constant_state ? state->constant_state->error : 0))
|
||||
#define zcbor_trace(state, appendix) do { \
|
||||
zcbor_trace_raw(state); \
|
||||
zcbor_do_print(", %s\n", appendix); \
|
||||
} while(0)
|
||||
#define zcbor_trace_file(state) do { \
|
||||
zcbor_trace_raw(state); \
|
||||
zcbor_do_print(", %s:%d\n", __FILE__, __LINE__); \
|
||||
} while(0)
|
||||
|
||||
#define zcbor_log_assert(expr, ...) \
|
||||
do { \
|
||||
zcbor_do_print("ASSERTION \n \"" #expr \
|
||||
"\"\nfailed at %s:%d with message:\n ", \
|
||||
__FILE__, __LINE__); \
|
||||
zcbor_do_print(__VA_ARGS__);\
|
||||
} while(0)
|
||||
#define zcbor_log(...) zcbor_do_print(__VA_ARGS__)
|
||||
#else
|
||||
#define zcbor_trace(state, appendix)
|
||||
#define zcbor_trace_file(state) ((void)state)
|
||||
#define zcbor_log_assert(...)
|
||||
#define zcbor_log(...)
|
||||
#endif
|
||||
|
||||
#ifdef ZCBOR_ASSERTS
|
||||
#define zcbor_assert(expr, ...) \
|
||||
do { \
|
||||
if (!(expr)) { \
|
||||
zcbor_log_assert(expr, __VA_ARGS__); \
|
||||
ZCBOR_FAIL(); \
|
||||
} \
|
||||
} while(0)
|
||||
#define zcbor_assert_state(expr, ...) \
|
||||
do { \
|
||||
if (!(expr)) { \
|
||||
zcbor_log_assert(expr, __VA_ARGS__); \
|
||||
ZCBOR_ERR(ZCBOR_ERR_ASSERTION); \
|
||||
} \
|
||||
} while(0)
|
||||
#else
|
||||
#define zcbor_assert(expr, ...)
|
||||
#define zcbor_assert_state(expr, ...)
|
||||
#endif
|
||||
|
||||
__attribute__((used))
|
||||
static void zcbor_print_compare_lines(const uint8_t *str1, const uint8_t *str2, size_t size)
|
||||
{
|
||||
for (size_t j = 0; j < size; j++) {
|
||||
zcbor_do_print("%x ", str1[j]);
|
||||
}
|
||||
zcbor_do_print("\r\n");
|
||||
for (size_t j = 0; j < size; j++) {
|
||||
zcbor_do_print("%x ", str2[j]);
|
||||
}
|
||||
zcbor_do_print("\r\n");
|
||||
for (size_t j = 0; j < size; j++) {
|
||||
zcbor_do_print("%x ", str1[j] != str2[j]);
|
||||
}
|
||||
zcbor_do_print("\r\n");
|
||||
zcbor_do_print("\r\n");
|
||||
}
|
||||
|
||||
__attribute__((used))
|
||||
static void zcbor_print_compare_strings(const uint8_t *str1, const uint8_t *str2, size_t size)
|
||||
{
|
||||
const size_t col_width = 16;
|
||||
|
||||
for (size_t i = 0; i <= size / col_width; i++) {
|
||||
zcbor_do_print("line %zu (char %zu)\r\n", i, i*col_width);
|
||||
zcbor_print_compare_lines(&str1[i*col_width], &str2[i*col_width],
|
||||
MIN(col_width, (size - i*col_width)));
|
||||
}
|
||||
zcbor_do_print("\r\n");
|
||||
}
|
||||
|
||||
__attribute__((used))
|
||||
static void zcbor_print_compare_strings_diff(const uint8_t *str1, const uint8_t *str2, size_t size)
|
||||
{
|
||||
const size_t col_width = 16;
|
||||
bool printed = false;
|
||||
|
||||
for (size_t i = 0; i <= size / col_width; i++) {
|
||||
if (memcmp(&str1[i*col_width], &str2[i*col_width], MIN(col_width, (size - i*col_width))) != 0) {
|
||||
zcbor_do_print("line %zu (char %zu)\r\n", i, i*col_width);
|
||||
zcbor_print_compare_lines(&str1[i*col_width], &str2[i*col_width],
|
||||
MIN(col_width, (size - i*col_width)));
|
||||
printed = true;
|
||||
}
|
||||
}
|
||||
if (printed) {
|
||||
zcbor_do_print("\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((used))
|
||||
static const char *zcbor_error_str(int error)
|
||||
{
|
||||
#define ZCBOR_ERR_CASE(err) case err: \
|
||||
return #err; /* The literal is static per C99 6.4.5 paragraph 5. */\
|
||||
|
||||
switch(error) {
|
||||
ZCBOR_ERR_CASE(ZCBOR_SUCCESS)
|
||||
ZCBOR_ERR_CASE(ZCBOR_ERR_NO_BACKUP_MEM)
|
||||
ZCBOR_ERR_CASE(ZCBOR_ERR_NO_BACKUP_ACTIVE)
|
||||
ZCBOR_ERR_CASE(ZCBOR_ERR_LOW_ELEM_COUNT)
|
||||
ZCBOR_ERR_CASE(ZCBOR_ERR_HIGH_ELEM_COUNT)
|
||||
ZCBOR_ERR_CASE(ZCBOR_ERR_INT_SIZE)
|
||||
ZCBOR_ERR_CASE(ZCBOR_ERR_FLOAT_SIZE)
|
||||
ZCBOR_ERR_CASE(ZCBOR_ERR_ADDITIONAL_INVAL)
|
||||
ZCBOR_ERR_CASE(ZCBOR_ERR_NO_PAYLOAD)
|
||||
ZCBOR_ERR_CASE(ZCBOR_ERR_PAYLOAD_NOT_CONSUMED)
|
||||
ZCBOR_ERR_CASE(ZCBOR_ERR_WRONG_TYPE)
|
||||
ZCBOR_ERR_CASE(ZCBOR_ERR_WRONG_VALUE)
|
||||
ZCBOR_ERR_CASE(ZCBOR_ERR_WRONG_RANGE)
|
||||
ZCBOR_ERR_CASE(ZCBOR_ERR_ITERATIONS)
|
||||
ZCBOR_ERR_CASE(ZCBOR_ERR_ASSERTION)
|
||||
ZCBOR_ERR_CASE(ZCBOR_ERR_PAYLOAD_OUTDATED)
|
||||
ZCBOR_ERR_CASE(ZCBOR_ERR_ELEM_NOT_FOUND)
|
||||
ZCBOR_ERR_CASE(ZCBOR_ERR_MAP_MISALIGNED)
|
||||
ZCBOR_ERR_CASE(ZCBOR_ERR_ELEMS_NOT_PROCESSED)
|
||||
ZCBOR_ERR_CASE(ZCBOR_ERR_NOT_AT_END)
|
||||
ZCBOR_ERR_CASE(ZCBOR_ERR_MAP_FLAGS_NOT_AVAILABLE)
|
||||
ZCBOR_ERR_CASE(ZCBOR_ERR_INVALID_VALUE_ENCODING)
|
||||
}
|
||||
#undef ZCBOR_ERR_CASE
|
||||
|
||||
return "ZCBOR_ERR_UNKNOWN";
|
||||
}
|
||||
|
||||
__attribute__((used))
|
||||
static void zcbor_print_error(int error)
|
||||
{
|
||||
zcbor_do_print("%s\r\n", zcbor_error_str(error));
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZCBOR_PRINT_H__ */
|
||||
99
bootloader/mcuboot/boot/zcbor/include/zcbor_tags.h
Normal file
99
bootloader/mcuboot/boot/zcbor/include/zcbor_tags.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* This file has been copied from the zcbor library.
|
||||
* Commit zcbor 0.8.1
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2022 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZCBOR_TAGS_H__
|
||||
#define ZCBOR_TAGS_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Values defined by RFCs via www.iana.org/assignments/cbor-tags/cbor-tags.xhtml */
|
||||
enum zcbor_tag {
|
||||
ZCBOR_TAG_TIME_TSTR = 0, ///! text string [RFC8949] Standard date/time string
|
||||
ZCBOR_TAG_TIME_NUM = 1, ///! integer or float [RFC8949] Epoch-based date/time
|
||||
ZCBOR_TAG_UBIGNUM_BSTR = 2, ///! byte string [RFC8949] Unsigned bignum
|
||||
ZCBOR_TAG_BIGNUM_BSTR = 3, ///! byte string [RFC8949] Negative bignum
|
||||
ZCBOR_TAG_DECFRAC_ARR = 4, ///! array [RFC8949] Decimal fraction
|
||||
ZCBOR_TAG_BIGFLOAT_ARR = 5, ///! array [RFC8949] Bigfloat
|
||||
ZCBOR_TAG_COSE_ENCRYPT0 = 16, ///! COSE_Encrypt0 [RFC9052] COSE Single Recipient Encrypted Data Object
|
||||
ZCBOR_TAG_COSE_MAC0 = 17, ///! COSE_Mac0 [RFC9052] COSE MAC w/o Recipients Object
|
||||
ZCBOR_TAG_COSE_SIGN1 = 18, ///! COSE_Sign1 [RFC9052] COSE Single Signer Data Object
|
||||
ZCBOR_TAG_2BASE64URL = 21, ///! (any) [RFC8949] Expected conversion to base64url encoding
|
||||
ZCBOR_TAG_2BASE64 = 22, ///! (any) [RFC8949] Expected conversion to base64 encoding
|
||||
ZCBOR_TAG_2BASE16 = 23, ///! (any) [RFC8949] Expected conversion to base16 encoding
|
||||
ZCBOR_TAG_BSTR = 24, ///! byte string [RFC8949] Encoded CBOR data item
|
||||
ZCBOR_TAG_URI_TSTR = 32, ///! text string [RFC8949] URI
|
||||
ZCBOR_TAG_BASE64URL_TSTR = 33, ///! text string [RFC8949] base64url
|
||||
ZCBOR_TAG_BASE64_TSTR = 34, ///! text string [RFC8949] base64
|
||||
ZCBOR_TAG_REGEX = 35, ///! text string [RFC7049] Regular expression (UTF-8)
|
||||
ZCBOR_TAG_MIME_TSTR = 36, ///! text string [RFC8949] MIME message
|
||||
ZCBOR_TAG_LANG_TSTR = 38, ///! array [RFC9290] Text string with language tag
|
||||
ZCBOR_TAG_MULTI_DIM_ARR_R = 40, ///! array of arrays [RFC8746] Multi-dimensional array, row-major order
|
||||
ZCBOR_TAG_HOMOG_ARR = 41, ///! array [RFC8746] Homogeneous array
|
||||
ZCBOR_TAG_YANG_BITS = 42, ///! text string [RFC9254] YANG bits datatype; see Section 6.7.
|
||||
ZCBOR_TAG_YANG_ENUM = 43, ///! text string [RFC9254] YANG enumeration datatype; see Section 6.6.
|
||||
ZCBOR_TAG_YANG_IDENTITYREF = 44, ///! uint/tstr [RFC9254] YANG identityref datatype; see Section 6.10.
|
||||
ZCBOR_TAG_YANK_INSTANCE_ID = 45, ///! uint/tstr/array [RFC9254] YANG instance-identifier datatype; see Section 6.13.
|
||||
ZCBOR_TAG_SID = 46, ///! uint [RFC9254] YANG Schema Item iDentifier (sid); see Section 3.2.
|
||||
ZCBOR_TAG_IPV4 = 52, ///! bstr or array [RFC9164] IPv4
|
||||
ZCBOR_TAG_IPV6 = 54, ///! bstr or array [RFC9164] IPv6
|
||||
ZCBOR_TAG_CWT = 61, ///! CWT [RFC8392] CBOR Web Token
|
||||
ZCBOR_TAG_TYPED_ARR_U8 = 64, ///! byte string [RFC8746] uint8 Typed Array
|
||||
ZCBOR_TAG_TYPED_ARR_U16_BE = 65, ///! byte string [RFC8746] uint16, big endian, Typed Array
|
||||
ZCBOR_TAG_TYPED_ARR_U32_BE = 66, ///! byte string [RFC8746] uint32, big endian, Typed Array
|
||||
ZCBOR_TAG_TYPED_ARR_U64_BE = 67, ///! byte string [RFC8746] uint64, big endian, Typed Array
|
||||
ZCBOR_TAG_TYPED_ARR_U8_CA = 68, ///! byte string [RFC8746] uint8 Typed Array, clamped arithmetic
|
||||
ZCBOR_TAG_TYPED_ARR_U16_LE = 69, ///! byte string [RFC8746] uint16, little endian, Typed Array
|
||||
ZCBOR_TAG_TYPED_ARR_U32_LE = 70, ///! byte string [RFC8746] uint32, little endian, Typed Array
|
||||
ZCBOR_TAG_TYPED_ARR_U64_LE = 71, ///! byte string [RFC8746] uint64, little endian, Typed Array
|
||||
ZCBOR_TAG_TYPED_ARR_S8 = 72, ///! byte string [RFC8746] sint8 Typed Array
|
||||
ZCBOR_TAG_TYPED_ARR_S16_BE = 73, ///! byte string [RFC8746] sint16, big endian, Typed Array
|
||||
ZCBOR_TAG_TYPED_ARR_S32_BE = 74, ///! byte string [RFC8746] sint32, big endian, Typed Array
|
||||
ZCBOR_TAG_TYPED_ARR_S64_BE = 75, ///! byte string [RFC8746] sint64, big endian, Typed Array
|
||||
ZCBOR_TAG_TYPED_ARR_S16_LE = 77, ///! byte string [RFC8746] sint16, little endian, Typed Array
|
||||
ZCBOR_TAG_TYPED_ARR_S32_LE = 78, ///! byte string [RFC8746] sint32, little endian, Typed Array
|
||||
ZCBOR_TAG_TYPED_ARR_S64_LE = 79, ///! byte string [RFC8746] sint64, little endian, Typed Array
|
||||
ZCBOR_TAG_TYPED_ARR_F16_BE = 80, ///! byte string [RFC8746] IEEE 754 binary16, big endian, Typed Array
|
||||
ZCBOR_TAG_TYPED_ARR_F32_BE = 81, ///! byte string [RFC8746] IEEE 754 binary32, big endian, Typed Array
|
||||
ZCBOR_TAG_TYPED_ARR_F64_BE = 82, ///! byte string [RFC8746] IEEE 754 binary64, big endian, Typed Array
|
||||
ZCBOR_TAG_TYPED_ARR_F128_BE = 83, ///! byte string [RFC8746] IEEE 754 binary128, big endian, Typed Array
|
||||
ZCBOR_TAG_TYPED_ARR_F16_LE = 84, ///! byte string [RFC8746] IEEE 754 binary16, little endian, Typed Array
|
||||
ZCBOR_TAG_TYPED_ARR_F32_LE = 85, ///! byte string [RFC8746] IEEE 754 binary32, little endian, Typed Array
|
||||
ZCBOR_TAG_TYPED_ARR_F64_LE = 86, ///! byte string [RFC8746] IEEE 754 binary64, little endian, Typed Array
|
||||
ZCBOR_TAG_TYPED_ARR_F128_LE = 87, ///! byte string [RFC8746] IEEE 754 binary128, little endian, Typed Array
|
||||
ZCBOR_TAG_COSE_ENCRYPT = 96, ///! COSE_Encrypt [RFC9052] COSE Encrypted Data Object
|
||||
ZCBOR_TAG_COSE_MAC = 97, ///! COSE_Mac [RFC9052] COSE MACed Data Object
|
||||
ZCBOR_TAG_COSE_SIGN = 98, ///! COSE_Sign [RFC9052] COSE Signed Data Object
|
||||
ZCBOR_TAG_EPOCH_DAYS = 100, ///! integer [RFC8943] Number of days since the epoch date 1970-01-01
|
||||
ZCBOR_TAG_REL_OID_BER_SDNV = 110, ///! bstr/array/map [RFC9090] relative object identifier (BER encoding); SDNV [RFC6256] sequence
|
||||
ZCBOR_TAG_OID_BER = 111, ///! bstr/array/map [RFC9090] object identifier (BER encoding)
|
||||
ZCBOR_TAG_PEN_REL_OID_BER = 112, ///! bstr/array/map [RFC9090] object identifier (BER encoding), relative to 1.3.6.1.4.1
|
||||
ZCBOR_TAG_DOTS_SIG_CHAN_OBJ = 271, ///! DOTS sig chan obj [RFC9132] DDoS Open Threat Signaling (DOTS) signal channel object
|
||||
ZCBOR_TAG_FULL_DATE_STR = 1004, ///! tstr (UTF-8) [RFC8943] Full-date string
|
||||
ZCBOR_TAG_MULTI_DIM_ARR_C = 1040, ///! array of arrays [RFC8746] Multi-dimensional array, column-major order
|
||||
ZCBOR_TAG_CBOR = 55799, ///! (any) [RFC8949] Self-described CBOR
|
||||
ZCBOR_TAG_CBOR_SEQ_FILE = 55800, ///! tagged bstr [RFC9277] indicates that the file contains CBOR Sequences
|
||||
ZCBOR_TAG_CBOR_FILE_LABEL = 55801, ///! tagged bstr [RFC9277] indicates that the file starts with a CBOR-Labeled Non-CBOR Data label.
|
||||
ZCBOR_TAG_COAP_CT = 1668546817, ///! bstr or (any) [RFC9277] Start of range: the representation of content-format ct < 65025 is indicated by tag number TN(ct) = 0x63740101 + (ct / 255) * 256 + ct % 255
|
||||
ZCBOR_TAG_COAP_CT_END = 1668612095, ///! bstr or (any) [RFC9277] End of range: the representation of content-format ct < 65025 is indicated by tag number TN(ct) = 0x63740101 + (ct / 255) * 256 + ct % 255
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZCBOR_TAGS_H__ */
|
||||
27
bootloader/mcuboot/boot/zcbor/pkg.yml
Normal file
27
bootloader/mcuboot/boot/zcbor/pkg.yml
Normal file
@@ -0,0 +1,27 @@
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
pkg.name: boot/zcbor
|
||||
pkg.description: Library for encoding and decoding data to/from cbor.
|
||||
pkg.author: "Nordic Semiconductor"
|
||||
pkg.homepage: "https://github.com/NordicSemiconductor/zcbor"
|
||||
pkg.keywords:
|
||||
- zcbor
|
||||
|
||||
#pkg.src_dirs: src
|
||||
442
bootloader/mcuboot/boot/zcbor/src/zcbor_common.c
Normal file
442
bootloader/mcuboot/boot/zcbor/src/zcbor_common.c
Normal file
@@ -0,0 +1,442 @@
|
||||
/*
|
||||
* This file has been copied from the zcbor library.
|
||||
* Commit zcbor 0.8.1
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 "zcbor_common.h"
|
||||
#include "zcbor_print.h"
|
||||
|
||||
_Static_assert((sizeof(size_t) == sizeof(void *)),
|
||||
"This code needs size_t to be the same length as pointers.");
|
||||
|
||||
_Static_assert((sizeof(zcbor_state_t) >= sizeof(struct zcbor_state_constant)),
|
||||
"This code needs zcbor_state_t to be at least as large as zcbor_backups_t.");
|
||||
|
||||
bool zcbor_new_backup(zcbor_state_t *state, size_t new_elem_count)
|
||||
{
|
||||
ZCBOR_CHECK_ERROR();
|
||||
|
||||
if ((state->constant_state->current_backup)
|
||||
>= state->constant_state->num_backups) {
|
||||
ZCBOR_ERR(ZCBOR_ERR_NO_BACKUP_MEM);
|
||||
}
|
||||
|
||||
state->payload_moved = false;
|
||||
|
||||
(state->constant_state->current_backup)++;
|
||||
|
||||
/* use the backup at current_backup - 1, since otherwise, the 0th
|
||||
* backup would be unused. */
|
||||
size_t i = (state->constant_state->current_backup) - 1;
|
||||
|
||||
memcpy(&state->constant_state->backup_list[i], state,
|
||||
sizeof(zcbor_state_t));
|
||||
|
||||
state->elem_count = new_elem_count;
|
||||
|
||||
zcbor_log("New backup (level %zu)\n", i);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_process_backup(zcbor_state_t *state, uint32_t flags,
|
||||
size_t max_elem_count)
|
||||
{
|
||||
ZCBOR_CHECK_ERROR();
|
||||
zcbor_state_t local_copy = *state;
|
||||
|
||||
if (state->constant_state->current_backup == 0) {
|
||||
zcbor_log("No backups available.\r\n");
|
||||
ZCBOR_ERR(ZCBOR_ERR_NO_BACKUP_ACTIVE);
|
||||
}
|
||||
|
||||
/* use the backup at current_backup - 1, since otherwise, the
|
||||
* 0th backup would be unused. */
|
||||
size_t i = state->constant_state->current_backup - 1;
|
||||
|
||||
zcbor_log("Process backup (level %zu, flags 0x%x)\n", i, flags);
|
||||
|
||||
if (flags & ZCBOR_FLAG_RESTORE) {
|
||||
if (!(flags & ZCBOR_FLAG_KEEP_PAYLOAD)) {
|
||||
if (state->constant_state->backup_list[i].payload_moved) {
|
||||
zcbor_log("Payload pointer out of date.\r\n");
|
||||
ZCBOR_ERR(ZCBOR_ERR_PAYLOAD_OUTDATED);
|
||||
}
|
||||
}
|
||||
memcpy(state, &state->constant_state->backup_list[i],
|
||||
sizeof(zcbor_state_t));
|
||||
}
|
||||
|
||||
if (flags & ZCBOR_FLAG_CONSUME) {
|
||||
state->constant_state->current_backup--;
|
||||
}
|
||||
|
||||
if (local_copy.elem_count > max_elem_count) {
|
||||
zcbor_log("elem_count: %zu (expected max %zu)\r\n",
|
||||
local_copy.elem_count, max_elem_count);
|
||||
ZCBOR_ERR(ZCBOR_ERR_HIGH_ELEM_COUNT);
|
||||
}
|
||||
|
||||
if (flags & ZCBOR_FLAG_KEEP_PAYLOAD) {
|
||||
state->payload = local_copy.payload;
|
||||
}
|
||||
|
||||
if (flags & ZCBOR_FLAG_KEEP_DECODE_STATE) {
|
||||
/* Copy decode state */
|
||||
state->decode_state = local_copy.decode_state;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void update_backups(zcbor_state_t *state, uint8_t const *new_payload_end)
|
||||
{
|
||||
if (state->constant_state) {
|
||||
for (unsigned int i = 0; i < state->constant_state->current_backup; i++) {
|
||||
state->constant_state->backup_list[i].payload_end = new_payload_end;
|
||||
state->constant_state->backup_list[i].payload_moved = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_union_start_code(zcbor_state_t *state)
|
||||
{
|
||||
if (!zcbor_new_backup(state, state->elem_count)) {
|
||||
ZCBOR_FAIL();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_union_elem_code(zcbor_state_t *state)
|
||||
{
|
||||
if (!zcbor_process_backup(state, ZCBOR_FLAG_RESTORE, state->elem_count)) {
|
||||
ZCBOR_FAIL();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool zcbor_union_end_code(zcbor_state_t *state)
|
||||
{
|
||||
if (!zcbor_process_backup(state, ZCBOR_FLAG_CONSUME, state->elem_count)) {
|
||||
ZCBOR_FAIL();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void zcbor_new_state(zcbor_state_t *state_array, size_t n_states,
|
||||
const uint8_t *payload, size_t payload_len, size_t elem_count,
|
||||
uint8_t *flags, size_t flags_bytes)
|
||||
{
|
||||
state_array[0].payload = payload;
|
||||
state_array[0].payload_end = payload + payload_len;
|
||||
state_array[0].elem_count = elem_count;
|
||||
state_array[0].payload_moved = false;
|
||||
state_array[0].decode_state.indefinite_length_array = false;
|
||||
#ifdef ZCBOR_MAP_SMART_SEARCH
|
||||
state_array[0].decode_state.map_search_elem_state = flags;
|
||||
state_array[0].decode_state.map_elem_count = 0;
|
||||
#else
|
||||
state_array[0].decode_state.map_elems_processed = 0;
|
||||
(void)flags;
|
||||
(void)flags_bytes;
|
||||
#endif
|
||||
state_array[0].constant_state = NULL;
|
||||
|
||||
if (n_states < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Use the last state as a struct zcbor_state_constant object. */
|
||||
state_array[0].constant_state = (struct zcbor_state_constant *)&state_array[n_states - 1];
|
||||
state_array[0].constant_state->backup_list = NULL;
|
||||
state_array[0].constant_state->num_backups = n_states - 2;
|
||||
state_array[0].constant_state->current_backup = 0;
|
||||
state_array[0].constant_state->error = ZCBOR_SUCCESS;
|
||||
#ifdef ZCBOR_STOP_ON_ERROR
|
||||
state_array[0].constant_state->stop_on_error = false;
|
||||
#endif
|
||||
state_array[0].constant_state->manually_process_elem = false;
|
||||
#ifdef ZCBOR_MAP_SMART_SEARCH
|
||||
state_array[0].constant_state->map_search_elem_state_end = flags + flags_bytes;
|
||||
#endif
|
||||
if (n_states > 2) {
|
||||
state_array[0].constant_state->backup_list = &state_array[1];
|
||||
}
|
||||
}
|
||||
|
||||
void zcbor_update_state(zcbor_state_t *state,
|
||||
const uint8_t *payload, size_t payload_len)
|
||||
{
|
||||
state->payload = payload;
|
||||
state->payload_end = payload + payload_len;
|
||||
|
||||
update_backups(state, state->payload_end);
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_validate_string_fragments(struct zcbor_string_fragment *fragments,
|
||||
size_t num_fragments)
|
||||
{
|
||||
size_t total_len = 0;
|
||||
|
||||
if (fragments == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < num_fragments; i++) {
|
||||
if (fragments[i].offset != total_len) {
|
||||
return false;
|
||||
}
|
||||
if (fragments[i].fragment.value == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (fragments[i].total_len != fragments[0].total_len) {
|
||||
return false;
|
||||
}
|
||||
total_len += fragments[i].fragment.len;
|
||||
if (total_len > fragments[0].total_len) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_fragments && total_len != fragments[0].total_len) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (num_fragments && (fragments[0].total_len == ZCBOR_STRING_FRAGMENT_UNKNOWN_LENGTH)) {
|
||||
for (size_t i = 0; i < num_fragments; i++) {
|
||||
fragments[i].total_len = total_len;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool zcbor_splice_string_fragments(struct zcbor_string_fragment *fragments,
|
||||
size_t num_fragments, uint8_t *result, size_t *result_len)
|
||||
{
|
||||
size_t total_len = 0;
|
||||
|
||||
if (!fragments) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < num_fragments; i++) {
|
||||
if ((total_len > *result_len)
|
||||
|| (fragments[i].fragment.len > (*result_len - total_len))) {
|
||||
return false;
|
||||
}
|
||||
memcpy(&result[total_len],
|
||||
fragments[i].fragment.value, fragments[i].fragment.len);
|
||||
total_len += fragments[i].fragment.len;
|
||||
}
|
||||
|
||||
*result_len = total_len;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_compare_strings(const struct zcbor_string *str1,
|
||||
const struct zcbor_string *str2)
|
||||
{
|
||||
return (str1 != NULL) && (str2 != NULL)
|
||||
&& (str1->value != NULL) && (str2->value != NULL) && (str1->len == str2->len)
|
||||
&& (memcmp(str1->value, str2->value, str1->len) == 0);
|
||||
}
|
||||
|
||||
|
||||
size_t zcbor_header_len(uint64_t value)
|
||||
{
|
||||
if (value <= ZCBOR_VALUE_IN_HEADER) {
|
||||
return 1;
|
||||
} else if (value <= 0xFF) {
|
||||
return 2;
|
||||
} else if (value <= 0xFFFF) {
|
||||
return 3;
|
||||
} else if (value <= 0xFFFFFFFF) {
|
||||
return 5;
|
||||
} else {
|
||||
return 9;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
size_t zcbor_header_len_ptr(const void *const value, size_t value_len)
|
||||
{
|
||||
uint64_t val64 = 0;
|
||||
|
||||
if (value_len > sizeof(val64)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(((uint8_t*)&val64) + ZCBOR_ECPY_OFFS(sizeof(val64), value_len), value, value_len);
|
||||
return zcbor_header_len(val64);
|
||||
}
|
||||
|
||||
|
||||
int zcbor_entry_function(const uint8_t *payload, size_t payload_len,
|
||||
void *result, size_t *payload_len_out, zcbor_state_t *state, zcbor_decoder_t func,
|
||||
size_t n_states, size_t elem_count)
|
||||
{
|
||||
zcbor_new_state(state, n_states, payload, payload_len, elem_count, NULL, 0);
|
||||
|
||||
bool ret = func(state, result);
|
||||
|
||||
if (!ret) {
|
||||
int err = zcbor_pop_error(state);
|
||||
|
||||
err = (err == ZCBOR_SUCCESS) ? ZCBOR_ERR_UNKNOWN : err;
|
||||
return err;
|
||||
}
|
||||
|
||||
if (payload_len_out != NULL) {
|
||||
*payload_len_out = MIN(payload_len,
|
||||
(size_t)state[0].payload - (size_t)payload);
|
||||
}
|
||||
return ZCBOR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* Float16: */
|
||||
#define F16_SIGN_OFFS 15 /* Bit offset of the sign bit. */
|
||||
#define F16_EXPO_OFFS 10 /* Bit offset of the exponent. */
|
||||
#define F16_EXPO_MSK 0x1F /* Bitmask for the exponent (right shifted by F16_EXPO_OFFS). */
|
||||
#define F16_MANTISSA_MSK 0x3FF /* Bitmask for the mantissa. */
|
||||
#define F16_MAX 65520 /* Lowest float32 value that rounds up to float16 infinity.
|
||||
* (65519.996 rounds to 65504) */
|
||||
#define F16_MIN_EXPO 24 /* Negative exponent of the non-zero float16 value closest to 0 (2^-24) */
|
||||
#define F16_MIN (1.0f / (1 << F16_MIN_EXPO)) /* The non-zero float16 value closest to 0 (2^-24) */
|
||||
#define F16_MIN_NORM (1.0f / (1 << 14)) /* The normalized float16 value closest to 0 (2^-14) */
|
||||
#define F16_BIAS 15 /* The exponent bias of normalized float16 values. */
|
||||
|
||||
/* Float32: */
|
||||
#define F32_SIGN_OFFS 31 /* Bit offset of the sign bit. */
|
||||
#define F32_EXPO_OFFS 23 /* Bit offset of the exponent. */
|
||||
#define F32_EXPO_MSK 0xFF /* Bitmask for the exponent (right shifted by F32_EXPO_OFFS). */
|
||||
#define F32_MANTISSA_MSK 0x7FFFFF /* Bitmask for the mantissa. */
|
||||
#define F32_BIAS 127 /* The exponent bias of normalized float32 values. */
|
||||
|
||||
/* Rounding: */
|
||||
#define SUBNORM_ROUND_MSK (F32_MANTISSA_MSK | (1 << F32_EXPO_OFFS)) /* mantissa + lsb of expo for
|
||||
* tiebreak. */
|
||||
#define SUBNORM_ROUND_BIT_MSK (1 << (F32_EXPO_OFFS - 1)) /* msb of mantissa (0x400000) */
|
||||
#define NORM_ROUND_MSK (F32_MANTISSA_MSK >> (F16_EXPO_OFFS - 1)) /* excess mantissa when going from
|
||||
* float32 to float16 + 1 extra bit
|
||||
* for tiebreak. */
|
||||
#define NORM_ROUND_BIT_MSK (1 << (F32_EXPO_OFFS - F16_EXPO_OFFS - 1)) /* bit 12 (0x1000) */
|
||||
|
||||
|
||||
float zcbor_float16_to_32(uint16_t input)
|
||||
{
|
||||
uint32_t sign = input >> F16_SIGN_OFFS;
|
||||
uint32_t expo = (input >> F16_EXPO_OFFS) & F16_EXPO_MSK;
|
||||
uint32_t mantissa = input & F16_MANTISSA_MSK;
|
||||
|
||||
if ((expo == 0) && (mantissa != 0)) {
|
||||
/* Subnormal float16 - convert to normalized float32 */
|
||||
return ((float)mantissa * F16_MIN) * (sign ? -1 : 1);
|
||||
} else {
|
||||
/* Normalized / zero / Infinity / NaN */
|
||||
uint32_t new_expo = (expo == 0 /* zero */) ? 0
|
||||
: (expo == F16_EXPO_MSK /* inf/NaN */) ? F32_EXPO_MSK
|
||||
: (expo + (F32_BIAS - F16_BIAS));
|
||||
uint32_t value32 = (sign << F32_SIGN_OFFS) | (new_expo << F32_EXPO_OFFS)
|
||||
| (mantissa << (F32_EXPO_OFFS - F16_EXPO_OFFS));
|
||||
float result;
|
||||
|
||||
memcpy(&result, &value32, sizeof(result));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint16_t zcbor_float32_to_16(float input)
|
||||
{
|
||||
uint32_t value32;
|
||||
|
||||
memcpy(&value32, &input, sizeof(value32));
|
||||
|
||||
uint32_t sign = value32 >> F32_SIGN_OFFS;
|
||||
uint32_t expo = (value32 >> F32_EXPO_OFFS) & F32_EXPO_MSK;
|
||||
uint32_t mantissa = value32 & F32_MANTISSA_MSK;
|
||||
|
||||
uint16_t value16 = (uint16_t)(sign << F16_SIGN_OFFS);
|
||||
|
||||
uint32_t abs_value32 = value32 & ~(1 << F32_SIGN_OFFS);
|
||||
float abs_input;
|
||||
|
||||
memcpy(&abs_input, &abs_value32, sizeof(abs_input));
|
||||
|
||||
if (abs_input <= (F16_MIN / 2)) {
|
||||
/* 0 or too small for float16. Round down to 0. value16 is already correct. */
|
||||
} else if (abs_input < F16_MIN) {
|
||||
/* Round up to 2^(-24) (F16_MIN), has other rounding rules than larger values. */
|
||||
value16 |= 0x0001;
|
||||
} else if (abs_input < F16_MIN_NORM) {
|
||||
/* Subnormal float16 (normal float32) */
|
||||
uint32_t adjusted_mantissa =
|
||||
/* Adjust for the purposes of checking rounding. */
|
||||
/* The lsb of expo is needed for the cases where expo is 103 (minimum). */
|
||||
((value32 << (expo - (F32_BIAS - F16_MIN_EXPO))) & SUBNORM_ROUND_MSK);
|
||||
uint16_t rounding_bit =
|
||||
/* "Round to nearest, ties to even". */
|
||||
/* 0x400000 means ties go down towards even. (0xC00000 means ties go up.) */
|
||||
(adjusted_mantissa & SUBNORM_ROUND_BIT_MSK)
|
||||
&& (adjusted_mantissa != SUBNORM_ROUND_BIT_MSK);
|
||||
value16 |= ((uint16_t)(abs_input * (1 << 24)) + rounding_bit); /* expo is 0 */
|
||||
} else if (abs_input < F16_MAX) {
|
||||
/* Normal float16 (normal float32) */
|
||||
uint16_t rounding_bit =
|
||||
/* Bit 13 of the mantissa represents which way to round, except for the */
|
||||
/* special case where bits 0-12 and 14 are 0. */
|
||||
/* This is because of "Round to nearest, ties to even". */
|
||||
/* 0x1000 means ties go down towards even. (0x3000 means ties go up.) */
|
||||
((mantissa & NORM_ROUND_BIT_MSK)
|
||||
&& ((mantissa & NORM_ROUND_MSK) != NORM_ROUND_BIT_MSK));
|
||||
value16 |= (uint16_t)((expo - (F32_BIAS - F16_BIAS)) << F16_EXPO_OFFS);
|
||||
value16 |= (uint16_t)(mantissa >> (F32_EXPO_OFFS - F16_EXPO_OFFS));
|
||||
value16 += rounding_bit; /* Might propagate to exponent. */
|
||||
} else if (expo != F32_EXPO_MSK || !mantissa) {
|
||||
/* Infinite, or finite normal float32 too large for float16. Round up to inf. */
|
||||
value16 |= (F16_EXPO_MSK << F16_EXPO_OFFS);
|
||||
} else {
|
||||
/* NaN */
|
||||
/* Preserve msbit of mantissa. */
|
||||
uint16_t new_mantissa = (uint16_t)(mantissa >> (F32_EXPO_OFFS - F16_EXPO_OFFS));
|
||||
value16 |= (F16_EXPO_MSK << F16_EXPO_OFFS) | (new_mantissa ? new_mantissa : 1);
|
||||
}
|
||||
|
||||
return value16;
|
||||
}
|
||||
|
||||
|
||||
/** Weak strnlen() implementation in case it is not available.
|
||||
*
|
||||
* This function is in the public domain, according to:
|
||||
* https://github.com/arm-embedded/gcc-arm-none-eabi.debian/blob/master/src/libiberty/strnlen.c
|
||||
*/
|
||||
__attribute__((__weak__))
|
||||
size_t strnlen (const char *s, size_t maxlen)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < maxlen; ++i) {
|
||||
if (s[i] == '\0') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
1572
bootloader/mcuboot/boot/zcbor/src/zcbor_decode.c
Normal file
1572
bootloader/mcuboot/boot/zcbor/src/zcbor_decode.c
Normal file
File diff suppressed because it is too large
Load Diff
614
bootloader/mcuboot/boot/zcbor/src/zcbor_encode.c
Normal file
614
bootloader/mcuboot/boot/zcbor/src/zcbor_encode.c
Normal file
@@ -0,0 +1,614 @@
|
||||
/*
|
||||
* This file has been copied from the zcbor library.
|
||||
* Commit zcbor 0.8.1
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 "zcbor_encode.h"
|
||||
#include "zcbor_common.h"
|
||||
#include "zcbor_print.h"
|
||||
|
||||
_Static_assert((sizeof(size_t) == sizeof(void *)),
|
||||
"This code needs size_t to be the same length as pointers.");
|
||||
|
||||
|
||||
static uint8_t log2ceil(size_t val)
|
||||
{
|
||||
switch(val) {
|
||||
case 1: return 0;
|
||||
case 2: return 1;
|
||||
case 3: return 2;
|
||||
case 4: return 2;
|
||||
case 5: return 3;
|
||||
case 6: return 3;
|
||||
case 7: return 3;
|
||||
case 8: return 3;
|
||||
}
|
||||
|
||||
zcbor_log("Should not come here.\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t get_additional(size_t len, uint8_t value0)
|
||||
{
|
||||
return len == 0 ? value0 : (uint8_t)(24 + log2ceil(len));
|
||||
}
|
||||
|
||||
|
||||
static bool encode_header_byte(zcbor_state_t *state,
|
||||
zcbor_major_type_t major_type, uint8_t additional)
|
||||
{
|
||||
ZCBOR_CHECK_ERROR();
|
||||
ZCBOR_CHECK_PAYLOAD();
|
||||
|
||||
zcbor_assert_state(additional < 32, "Unsupported additional value: %d\r\n", additional);
|
||||
|
||||
*(state->payload_mut++) = (uint8_t)((major_type << 5) | (additional & 0x1F));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** Encode a single value.
|
||||
*/
|
||||
static bool value_encode_len(zcbor_state_t *state, zcbor_major_type_t major_type,
|
||||
const void *const result, size_t result_len)
|
||||
{
|
||||
uint8_t *u8_result = (uint8_t *)result;
|
||||
|
||||
if ((state->payload + 1 + result_len) > state->payload_end) {
|
||||
ZCBOR_ERR(ZCBOR_ERR_NO_PAYLOAD);
|
||||
}
|
||||
|
||||
if (!encode_header_byte(state, major_type,
|
||||
get_additional(result_len, u8_result[0]))) {
|
||||
ZCBOR_FAIL();
|
||||
}
|
||||
state->payload_mut--;
|
||||
zcbor_trace(state, "value_encode_len");
|
||||
state->payload_mut++;
|
||||
|
||||
#ifdef ZCBOR_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 /* ZCBOR_BIG_ENDIAN */
|
||||
|
||||
state->elem_count++;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool value_encode(zcbor_state_t *state, zcbor_major_type_t major_type,
|
||||
const void *const input, size_t max_result_len)
|
||||
{
|
||||
zcbor_assert_state(max_result_len != 0, "0-length result not supported.\r\n");
|
||||
|
||||
size_t result_len = zcbor_header_len_ptr(input, max_result_len) - 1;
|
||||
const void *result = input;
|
||||
|
||||
#ifdef ZCBOR_BIG_ENDIAN
|
||||
result = (uint8_t *)input + max_result_len - (result_len ? result_len : 1);
|
||||
#endif
|
||||
|
||||
return value_encode_len(state, major_type, result, result_len);
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_int_encode(zcbor_state_t *state, const void *input_int, size_t int_size)
|
||||
{
|
||||
zcbor_major_type_t major_type;
|
||||
uint8_t input_buf[8];
|
||||
const uint8_t *input_uint8 = input_int;
|
||||
const int8_t *input_int8 = input_int;
|
||||
const uint8_t *input = input_int;
|
||||
|
||||
if (int_size > sizeof(int64_t)) {
|
||||
ZCBOR_ERR(ZCBOR_ERR_INT_SIZE);
|
||||
}
|
||||
|
||||
#ifdef ZCBOR_BIG_ENDIAN
|
||||
if (input_int8[0] < 0) {
|
||||
#else
|
||||
if (input_int8[int_size - 1] < 0) {
|
||||
#endif
|
||||
major_type = ZCBOR_MAJOR_TYPE_NINT;
|
||||
|
||||
/* Convert to CBOR's representation by flipping all bits. */
|
||||
for (unsigned int i = 0; i < int_size; i++) {
|
||||
input_buf[i] = (uint8_t)~input_uint8[i];
|
||||
}
|
||||
input = input_buf;
|
||||
} else {
|
||||
major_type = ZCBOR_MAJOR_TYPE_PINT;
|
||||
}
|
||||
|
||||
if (!value_encode(state, major_type, input, int_size)) {
|
||||
ZCBOR_FAIL();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_uint_encode(zcbor_state_t *state, const void *input_uint, size_t uint_size)
|
||||
{
|
||||
if (!value_encode(state, ZCBOR_MAJOR_TYPE_PINT, input_uint, uint_size)) {
|
||||
zcbor_log("uint with size %zu failed.\r\n", uint_size);
|
||||
ZCBOR_FAIL();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_int32_encode(zcbor_state_t *state, const int32_t *input)
|
||||
{
|
||||
return zcbor_int_encode(state, input, sizeof(*input));
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_int64_encode(zcbor_state_t *state, const int64_t *input)
|
||||
{
|
||||
return zcbor_int_encode(state, input, sizeof(*input));
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_uint32_encode(zcbor_state_t *state, const uint32_t *input)
|
||||
{
|
||||
return zcbor_uint_encode(state, input, sizeof(*input));
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_uint64_encode(zcbor_state_t *state, const uint64_t *input)
|
||||
{
|
||||
return zcbor_uint_encode(state, input, sizeof(*input));
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_int32_put(zcbor_state_t *state, int32_t input)
|
||||
{
|
||||
return zcbor_int_encode(state, &input, sizeof(input));
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_int64_put(zcbor_state_t *state, int64_t input)
|
||||
{
|
||||
return zcbor_int_encode(state, &input, sizeof(input));
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_uint32_put(zcbor_state_t *state, uint32_t input)
|
||||
{
|
||||
return zcbor_uint_encode(state, &input, sizeof(input));
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_uint64_put(zcbor_state_t *state, uint64_t input)
|
||||
{
|
||||
return zcbor_uint_encode(state, &input, sizeof(input));
|
||||
}
|
||||
|
||||
|
||||
#ifdef ZCBOR_SUPPORTS_SIZE_T
|
||||
bool zcbor_size_put(zcbor_state_t *state, size_t input)
|
||||
{
|
||||
return zcbor_uint_encode(state, &input, sizeof(input));
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_size_encode(zcbor_state_t *state, const size_t *input)
|
||||
{
|
||||
return zcbor_uint_encode(state, input, sizeof(*input));
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool str_start_encode(zcbor_state_t *state,
|
||||
const struct zcbor_string *input, zcbor_major_type_t major_type)
|
||||
{
|
||||
if (input->value && ((zcbor_header_len_ptr(&input->len, sizeof(input->len))
|
||||
+ input->len + (size_t)state->payload)
|
||||
> (size_t)state->payload_end)) {
|
||||
ZCBOR_ERR(ZCBOR_ERR_NO_PAYLOAD);
|
||||
}
|
||||
if (!value_encode(state, major_type, &input->len, sizeof(input->len))) {
|
||||
ZCBOR_FAIL();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static size_t remaining_str_len(zcbor_state_t *state)
|
||||
{
|
||||
size_t max_len = (size_t)state->payload_end - (size_t)state->payload;
|
||||
size_t result_len = zcbor_header_len_ptr(&max_len, sizeof(max_len)) - 1;
|
||||
|
||||
return max_len - result_len - 1;
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_bstr_start_encode(zcbor_state_t *state)
|
||||
{
|
||||
if (!zcbor_new_backup(state, 0)) {
|
||||
ZCBOR_FAIL();
|
||||
}
|
||||
|
||||
uint64_t max_len = remaining_str_len(state);
|
||||
|
||||
/* Encode a dummy header */
|
||||
if (!value_encode(state, ZCBOR_MAJOR_TYPE_BSTR, &max_len, sizeof(max_len))) {
|
||||
ZCBOR_FAIL();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_bstr_end_encode(zcbor_state_t *state, struct zcbor_string *result)
|
||||
{
|
||||
const uint8_t *payload = state->payload;
|
||||
struct zcbor_string dummy_value;
|
||||
|
||||
if (result == NULL) {
|
||||
/* Use a dummy value for the sake of the length calculation below.
|
||||
* Will not be returned.
|
||||
*/
|
||||
result = &dummy_value;
|
||||
}
|
||||
|
||||
if (!zcbor_process_backup(state, ZCBOR_FLAG_RESTORE | ZCBOR_FLAG_CONSUME, 0xFFFFFFFF)) {
|
||||
ZCBOR_FAIL();
|
||||
}
|
||||
|
||||
result->value = state->payload_end - remaining_str_len(state);
|
||||
result->len = (size_t)payload - (size_t)result->value;
|
||||
|
||||
/* Reencode header of list now that we know the number of elements. */
|
||||
if (!zcbor_bstr_encode(state, result)) {
|
||||
ZCBOR_FAIL();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool str_encode(zcbor_state_t *state,
|
||||
const struct zcbor_string *input, zcbor_major_type_t major_type)
|
||||
{
|
||||
ZCBOR_CHECK_PAYLOAD(); /* To make the size_t cast below safe. */
|
||||
if (input->len > (size_t)(state->payload_end - state->payload)) {
|
||||
ZCBOR_ERR(ZCBOR_ERR_NO_PAYLOAD);
|
||||
}
|
||||
if (!str_start_encode(state, input, major_type)) {
|
||||
ZCBOR_FAIL();
|
||||
}
|
||||
if (state->payload_mut != input->value) {
|
||||
/* Use memmove since string might be encoded into the same space
|
||||
* because of bstrx_cbor_start_encode/bstrx_cbor_end_encode. */
|
||||
memmove(state->payload_mut, input->value, input->len);
|
||||
}
|
||||
state->payload += input->len;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_bstr_encode(zcbor_state_t *state, const struct zcbor_string *input)
|
||||
{
|
||||
return str_encode(state, input, ZCBOR_MAJOR_TYPE_BSTR);
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_tstr_encode(zcbor_state_t *state, const struct zcbor_string *input)
|
||||
{
|
||||
return str_encode(state, input, ZCBOR_MAJOR_TYPE_TSTR);
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_bstr_encode_ptr(zcbor_state_t *state, const char *str, size_t len)
|
||||
{
|
||||
const struct zcbor_string zs = { .value = (const uint8_t *)str, .len = len };
|
||||
|
||||
return zcbor_bstr_encode(state, &zs);
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_tstr_encode_ptr(zcbor_state_t *state, const char *str, size_t len)
|
||||
{
|
||||
const struct zcbor_string zs = { .value = (const uint8_t *)str, .len = len };
|
||||
|
||||
return zcbor_tstr_encode(state, &zs);
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_bstr_put_term(zcbor_state_t *state, char const *str, size_t maxlen)
|
||||
{
|
||||
return zcbor_bstr_encode_ptr(state, str, strnlen(str, maxlen));
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_tstr_put_term(zcbor_state_t *state, char const *str, size_t maxlen)
|
||||
{
|
||||
return zcbor_tstr_encode_ptr(state, str, strnlen(str, maxlen));
|
||||
}
|
||||
|
||||
|
||||
static bool list_map_start_encode(zcbor_state_t *state, size_t max_num,
|
||||
zcbor_major_type_t major_type)
|
||||
{
|
||||
#ifdef ZCBOR_CANONICAL
|
||||
if (!zcbor_new_backup(state, 0)) {
|
||||
ZCBOR_FAIL();
|
||||
}
|
||||
|
||||
/* Encode dummy header with max number of elements. */
|
||||
if (!value_encode(state, major_type, &max_num, sizeof(max_num))) {
|
||||
ZCBOR_FAIL();
|
||||
}
|
||||
state->elem_count--; /* Because of dummy header. */
|
||||
#else
|
||||
(void)max_num;
|
||||
|
||||
if (!encode_header_byte(state, major_type, ZCBOR_VALUE_IS_INDEFINITE_LENGTH)) {
|
||||
ZCBOR_FAIL();
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_list_start_encode(zcbor_state_t *state, size_t max_num)
|
||||
{
|
||||
return list_map_start_encode(state, max_num, ZCBOR_MAJOR_TYPE_LIST);
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_map_start_encode(zcbor_state_t *state, size_t max_num)
|
||||
{
|
||||
return list_map_start_encode(state, max_num, ZCBOR_MAJOR_TYPE_MAP);
|
||||
}
|
||||
|
||||
|
||||
static bool list_map_end_encode(zcbor_state_t *state, size_t max_num,
|
||||
zcbor_major_type_t major_type)
|
||||
{
|
||||
#ifdef ZCBOR_CANONICAL
|
||||
size_t list_count = ((major_type == ZCBOR_MAJOR_TYPE_LIST) ?
|
||||
state->elem_count
|
||||
: (state->elem_count / 2));
|
||||
|
||||
const uint8_t *payload = state->payload;
|
||||
|
||||
size_t max_header_len = zcbor_header_len_ptr(&max_num, 4) - 1;
|
||||
size_t header_len = zcbor_header_len_ptr(&list_count, 4) - 1;
|
||||
|
||||
if (!zcbor_process_backup(state, ZCBOR_FLAG_RESTORE | ZCBOR_FLAG_CONSUME, 0xFFFFFFFF)) {
|
||||
ZCBOR_FAIL();
|
||||
}
|
||||
|
||||
zcbor_log("list_count: %zu\r\n", list_count);
|
||||
|
||||
|
||||
/** If max_num is smaller than the actual number of encoded elements,
|
||||
* the value_encode() below will corrupt the data if the encoded
|
||||
* header is larger than the previously encoded header. */
|
||||
if (header_len > max_header_len) {
|
||||
zcbor_log("max_num too small.\r\n");
|
||||
ZCBOR_ERR(ZCBOR_ERR_HIGH_ELEM_COUNT);
|
||||
}
|
||||
|
||||
/* Reencode header of list now that we know the number of elements. */
|
||||
if (!(value_encode(state, major_type, &list_count, sizeof(list_count)))) {
|
||||
ZCBOR_FAIL();
|
||||
}
|
||||
|
||||
if (max_header_len != header_len) {
|
||||
const uint8_t *start = state->payload + max_header_len - header_len;
|
||||
size_t body_size = (size_t)payload - (size_t)start;
|
||||
|
||||
memmove(state->payload_mut, start, 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
|
||||
(void)max_num;
|
||||
(void)major_type;
|
||||
if (!encode_header_byte(state, ZCBOR_MAJOR_TYPE_SIMPLE, ZCBOR_VALUE_IS_INDEFINITE_LENGTH)) {
|
||||
ZCBOR_FAIL();
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_list_end_encode(zcbor_state_t *state, size_t max_num)
|
||||
{
|
||||
return list_map_end_encode(state, max_num, ZCBOR_MAJOR_TYPE_LIST);
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_map_end_encode(zcbor_state_t *state, size_t max_num)
|
||||
{
|
||||
return list_map_end_encode(state, max_num, ZCBOR_MAJOR_TYPE_MAP);
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_list_map_end_force_encode(zcbor_state_t *state)
|
||||
{
|
||||
#ifdef ZCBOR_CANONICAL
|
||||
if (!zcbor_process_backup(state, ZCBOR_FLAG_RESTORE | ZCBOR_FLAG_CONSUME,
|
||||
ZCBOR_MAX_ELEM_COUNT)) {
|
||||
ZCBOR_FAIL();
|
||||
}
|
||||
#endif
|
||||
(void)state;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_simple_encode(zcbor_state_t *state, uint8_t *input)
|
||||
{
|
||||
if (!value_encode(state, ZCBOR_MAJOR_TYPE_SIMPLE, input, sizeof(*input))) {
|
||||
zcbor_log("Error encoding %u (0x%p)\r\n", *input, input);
|
||||
ZCBOR_FAIL();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_simple_put(zcbor_state_t *state, uint8_t input)
|
||||
{
|
||||
return value_encode(state, ZCBOR_MAJOR_TYPE_SIMPLE, &input, sizeof(input));
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_nil_put(zcbor_state_t *state, const void *unused)
|
||||
{
|
||||
(void)unused;
|
||||
return zcbor_simple_put(state, 22);
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_undefined_put(zcbor_state_t *state, const void *unused)
|
||||
{
|
||||
(void)unused;
|
||||
return zcbor_simple_put(state, 23);
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_bool_encode(zcbor_state_t *state, const bool *input)
|
||||
{
|
||||
return zcbor_bool_put(state, *input);
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_bool_put(zcbor_state_t *state, bool input)
|
||||
{
|
||||
return zcbor_simple_put(state, (!!input + ZCBOR_BOOL_TO_SIMPLE));
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_float64_encode(zcbor_state_t *state, const double *input)
|
||||
{
|
||||
if (!value_encode_len(state, ZCBOR_MAJOR_TYPE_SIMPLE, input,
|
||||
sizeof(*input))) {
|
||||
ZCBOR_FAIL();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_float64_put(zcbor_state_t *state, double input)
|
||||
{
|
||||
return zcbor_float64_encode(state, &input);
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_float32_encode(zcbor_state_t *state, const float *input)
|
||||
{
|
||||
if (!value_encode_len(state, ZCBOR_MAJOR_TYPE_SIMPLE, input,
|
||||
sizeof(*input))) {
|
||||
ZCBOR_FAIL();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_float32_put(zcbor_state_t *state, float input)
|
||||
{
|
||||
return zcbor_float32_encode(state, &input);
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_float16_encode(zcbor_state_t *state, const float *input)
|
||||
{
|
||||
return zcbor_float16_put(state, *input);
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_float16_put(zcbor_state_t *state, float input)
|
||||
{
|
||||
return zcbor_float16_bytes_put(state, zcbor_float32_to_16(input));
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_float16_bytes_encode(zcbor_state_t *state, const uint16_t *input)
|
||||
{
|
||||
if (!value_encode_len(state, ZCBOR_MAJOR_TYPE_SIMPLE, input,
|
||||
sizeof(*input))) {
|
||||
ZCBOR_FAIL();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_float16_bytes_put(zcbor_state_t *state, uint16_t input)
|
||||
{
|
||||
return zcbor_float16_bytes_encode(state, &input);
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_tag_put(zcbor_state_t *state, uint32_t tag)
|
||||
{
|
||||
if (!value_encode(state, ZCBOR_MAJOR_TYPE_TAG, &tag, sizeof(tag))) {
|
||||
ZCBOR_FAIL();
|
||||
}
|
||||
state->elem_count--;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_tag_encode(zcbor_state_t *state, uint32_t *tag)
|
||||
{
|
||||
return zcbor_tag_put(state, *tag);
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_multi_encode_minmax(size_t min_encode, size_t max_encode,
|
||||
const size_t *num_encode, zcbor_encoder_t encoder,
|
||||
zcbor_state_t *state, const void *input, size_t result_len)
|
||||
{
|
||||
|
||||
if ((*num_encode >= min_encode) && (*num_encode <= max_encode)) {
|
||||
return zcbor_multi_encode(*num_encode, encoder, state, input, result_len);
|
||||
} else {
|
||||
ZCBOR_ERR(ZCBOR_ERR_ITERATIONS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool zcbor_multi_encode(const size_t num_encode, zcbor_encoder_t encoder,
|
||||
zcbor_state_t *state, const void *input, size_t result_len)
|
||||
{
|
||||
ZCBOR_CHECK_ERROR();
|
||||
for (size_t i = 0; i < num_encode; i++) {
|
||||
if (!encoder(state, (const uint8_t *)input + i*result_len)) {
|
||||
ZCBOR_FAIL();
|
||||
}
|
||||
}
|
||||
zcbor_log("Encoded %zu elements.\n", num_encode);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void zcbor_new_encode_state(zcbor_state_t *state_array, size_t n_states,
|
||||
uint8_t *payload, size_t payload_len, size_t elem_count)
|
||||
{
|
||||
zcbor_new_state(state_array, n_states, payload, payload_len, elem_count, NULL, 0);
|
||||
}
|
||||
Reference in New Issue
Block a user