Safe API Framework 0.1.0 build 384e6ae
Layered API framework for safety-related applications (ERTMS RBC reference targeting CENELEC EN 50128 SIL 4)
Loading...
Searching...
No Matches
rte_state_transfer.c
Go to the documentation of this file.
1
5
7
9{
10 if (registry == NULL)
11 {
13 }
14 rte_mem_set(registry, 0, sizeof(*registry));
15 return RTE_STATUS_OK;
16}
17
19 const char *name, void *data, size_t size)
20{
21 return rte_state_transfer_register_field_ex(registry, name, data, size, NULL, NULL);
22}
23
25 const char *name, void *data, size_t size,
28{
30
31 if ((registry == NULL) || (data == NULL) || (size == 0U))
32 {
34 }
35 /* Both-or-neither: a field either uses this module's default raw
36 * memcpy (both NULL) or a fully custom codec (both non-NULL) - never
37 * a mix, which would leave encode/decode asymmetric. */
38 if ((encode_fn == NULL) != (decode_fn == NULL))
39 {
41 }
42 if (registry->field_count >= RTE_STATE_TRANSFER_MAX_FIELDS)
43 {
45 }
46 slot = &registry->fields[registry->field_count];
47 slot->name = name;
48 slot->data = data;
49 slot->size = size;
50 slot->encode_fn = encode_fn;
51 slot->decode_fn = decode_fn;
52 registry->field_count++;
53 return RTE_STATUS_OK;
54}
55
57{
58 size_t total = 0U;
59 uint32_t i;
60
61 if (registry == NULL)
62 {
63 return 0U;
64 }
65 for (i = 0U; i < registry->field_count; i++)
66 {
67 total += registry->fields[i].size;
68 }
69 return total;
70}
71
73 uint8_t *out, size_t out_size, size_t *out_len)
74{
75 size_t offset = 0U;
76 uint32_t i;
77
78 if ((registry == NULL) || (out == NULL))
79 {
81 }
82 if (out_size < rte_state_transfer_encoded_size(registry))
83 {
85 }
86 for (i = 0U; i < registry->field_count; i++)
87 {
88 const rte_state_field_t *field = &registry->fields[i];
89 if (field->encode_fn != NULL)
90 {
91 rte_status_t status = field->encode_fn(field->data, &out[offset], field->size);
92 if (status != RTE_STATUS_OK)
93 {
94 return status;
95 }
96 }
97 else
98 {
99 rte_mem_copy(&out[offset], field->data, field->size);
100 }
101 offset += field->size;
102 }
103 if (out_len != NULL)
104 {
105 *out_len = offset;
106 }
107 return RTE_STATUS_OK;
108}
109
111 const uint8_t *in, size_t in_len)
112{
113 size_t offset = 0U;
114 uint32_t i;
115
116 if ((registry == NULL) || (in == NULL))
117 {
119 }
120 if (in_len < rte_state_transfer_encoded_size(registry))
121 {
123 }
124 for (i = 0U; i < registry->field_count; i++)
125 {
126 const rte_state_field_t *field = &registry->fields[i];
127 if (field->decode_fn != NULL)
128 {
129 rte_status_t status = field->decode_fn(field->data, &in[offset], field->size);
130 if (status != RTE_STATUS_OK)
131 {
132 return status;
133 }
134 }
135 else
136 {
137 rte_mem_copy(field->data, &in[offset], field->size);
138 }
139 offset += field->size;
140 }
141 return RTE_STATUS_OK;
142}
rte_status_t
Common result/status codes.
Definition rte_status.h:27
@ RTE_STATUS_OK
Definition rte_status.h:28
@ RTE_STATUS_INVALID_PARAM
Definition rte_status.h:29
@ RTE_STATUS_RESOURCE_EXHAUSTED
Definition rte_status.h:33
rte_status_t rte_state_transfer_register_field(rte_state_transfer_registry_t *registry, const char *name, void *data, size_t size)
Registers one field. Order matters - encode()/decode() pack/unpack in registration order.
#define RTE_STATE_TRANSFER_MAX_FIELDS
rte_status_t(*) rte_state_field_encode_fn(const void *data, uint8_t *out, size_t size)
Optional custom wire encoder for one field, registered via rte_state_transfer_register_field_ex() - e...
rte_status_t rte_state_transfer_decode(const rte_state_transfer_registry_t *registry, const uint8_t *in, size_t in_len)
Inverse of encode(): overwrites every registered field's live value from in, in registration order.
rte_status_t(*) rte_state_field_decode_fn(void *data, const uint8_t *in, size_t size)
Inverse of rte_state_field_encode_fn - must consume EXACTLY size bytes from in and write the result i...
rte_status_t rte_state_transfer_encode(const rte_state_transfer_registry_t *registry, uint8_t *out, size_t out_size, size_t *out_len)
Packs every registered field's current live value into out, in registration order,...
size_t rte_state_transfer_encoded_size(const rte_state_transfer_registry_t *registry)
Total encoded size (sum of every registered field's size) - the minimum buffer size encode()/decode()...
rte_status_t rte_state_transfer_register_field_ex(rte_state_transfer_registry_t *registry, const char *name, void *data, size_t size, rte_state_field_encode_fn encode_fn, rte_state_field_decode_fn decode_fn)
Registers one field with a custom wire encoder/decoder pair instead of this module's default raw memc...
rte_status_t rte_state_transfer_registry_init(rte_state_transfer_registry_t *registry)
Initializes an empty registry.
Thin, MISRA-visible wrappers over the three raw memory-block primitives (fill/copy/compare) every oth...
static void rte_mem_copy(void *dest, const void *src, size_t count)
Copies count bytes from src to dest - the one sanctioned call site for libc memcpy() in this framewor...
static void rte_mem_set(void *dest, int value, size_t count)
Fills count bytes starting at dest with value - the one sanctioned call site for libc memset() in thi...
Declarative registry of application state that must survive a STANDBY -> ONLINE promotion (RCA/OCORA ...
rte_state_field_encode_fn encode_fn
rte_state_field_decode_fn decode_fn