1 /*
2  * This file has been copied from the cddl-gen submodule.
3  * Commit 9f77837f9950da1633d22abf6181a830521a6688
4  */
5 
6 /*
7  * Copyright (c) 2020 Nordic Semiconductor ASA
8  *
9  * SPDX-License-Identifier: Apache-2.0
10  */
11 
12 #ifndef CBOR_COMMON_H__
13 #define CBOR_COMMON_H__
14 #include <stdint.h>
15 #include <stdbool.h>
16 #include <stddef.h>
17 
18 
19 /** Convenience type that allows pointing to strings directly inside the payload
20  *  without the need to copy out.
21  */
22 typedef struct
23 {
24 	const uint8_t *value;
25 	uint32_t len;
26 } cbor_string_type_t;
27 
28 #ifdef CDDL_CBOR_VERBOSE
29 #include <sys/printk.h>
30 #define cbor_trace() (printk("bytes left: %d, byte: 0x%x, elem_count: 0x%zx, %s:%d\n",\
31 	(uint32_t)state->payload_end - (uint32_t)state->payload, *state->payload, state->elem_count,\
32 	__FILE__, __LINE__))
33 #define cbor_assert(expr, ...) \
34 do { \
35 	if (!(expr)) { \
36 		printk("ASSERTION \n  \"" #expr \
37 			"\"\nfailed at %s:%d with message:\n  ", \
38 			__FILE__, __LINE__); \
39 		printk(__VA_ARGS__);\
40 		return false; \
41 	} \
42 } while(0)
43 #define cbor_print(...) printk(__VA_ARGS__)
44 #else
45 #define cbor_trace() ((void)state)
46 #define cbor_assert(...)
47 #define cbor_print(...)
48 #endif
49 
50 #ifndef MIN
51 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
52 #endif
53 
54 
55 struct cbor_state_backups_s;
56 
57 typedef struct cbor_state_backups_s cbor_state_backups_t;
58 
59 typedef struct{
60 union {
61 	uint8_t *payload_mut;
62 	uint8_t const *payload; /**< The current place in the payload. Will be
63 	                             updated when an element is correctly
64 	                             processed. */
65 };
66 	uint8_t const *payload_bak; /**< Temporary backup of payload. */
67 	uint32_t elem_count; /**< The current element is part of a LIST or a MAP,
68 	                          and this keeps count of how many elements are
69 	                          expected. This will be checked before processing
70 	                          and decremented if the element is correctly
71 	                          processed. */
72 	uint8_t const *payload_end; /**< The end of the payload. This will be
73 	                                 checked against payload before
74 	                                 processing each element. */
75 	cbor_state_backups_t *backups;
76 } cbor_state_t;
77 
78 struct cbor_state_backups_s{
79 	cbor_state_t *backup_list;
80 	uint32_t current_backup;
81 	uint32_t num_backups;
82 };
83 
84 /** Function pointer type used with multi_decode.
85  *
86  * This type is compatible with all decoding functions here and in the generated
87  * code, except for multi_decode.
88  */
89 typedef bool(cbor_encoder_t)(cbor_state_t *, const void *);
90 typedef bool(cbor_decoder_t)(cbor_state_t *, void *);
91 
92 /** Enumeration representing the major types available in CBOR.
93  *
94  * The major type is represented in the 3 first bits of the header byte.
95  */
96 typedef enum
97 {
98 	CBOR_MAJOR_TYPE_PINT = 0, ///! Positive Integer
99 	CBOR_MAJOR_TYPE_NINT = 1, ///! Negative Integer
100 	CBOR_MAJOR_TYPE_BSTR = 2, ///! Byte String
101 	CBOR_MAJOR_TYPE_TSTR = 3, ///! Text String
102 	CBOR_MAJOR_TYPE_LIST = 4, ///! List
103 	CBOR_MAJOR_TYPE_MAP  = 5, ///! Map
104 	CBOR_MAJOR_TYPE_TAG  = 6, ///! Semantic Tag
105 	CBOR_MAJOR_TYPE_PRIM = 7, ///! Primitive Type
106 } cbor_major_type_t;
107 
108 /** Shorthand macro to check if a result is within min/max constraints.
109  */
110 #define PTR_VALUE_IN_RANGE(type, res, min, max) \
111 		(((min == NULL) || (*(type *)res >= *(type *)min)) \
112 		&& ((max == NULL) || (*(type *)res <= *(type *)max)))
113 
114 #define FAIL() \
115 do {\
116 	cbor_trace(); \
117 	return false; \
118 } while(0)
119 
120 
121 #define VALUE_IN_HEADER 23 /**! For values below this, the value is encoded
122                                 directly in the header. */
123 
124 #define BOOL_TO_PRIM 20 ///! In CBOR, false/true have the values 20/21
125 
126 #define FLAG_RESTORE 1UL
127 #define FLAG_DISCARD 2UL
128 #define FLAG_TRANSFER_PAYLOAD 4UL
129 
130 bool new_backup(cbor_state_t *state, uint32_t new_elem_count);
131 
132 bool restore_backup(cbor_state_t *state, uint32_t flags,
133 		uint32_t max_elem_count);
134 
135 bool union_start_code(cbor_state_t *state);
136 
137 bool union_elem_code(cbor_state_t *state);
138 
139 bool union_end_code(cbor_state_t *state);
140 
141 bool entry_function(const uint8_t *payload, uint32_t payload_len,
142 		const void *struct_ptr, uint32_t *payload_len_out,
143 		cbor_encoder_t func, uint32_t elem_count, uint32_t num_backups);
144 
145 #endif /* CBOR_COMMON_H__ */
146