asrt
Automated System Runtime Testing library
Loading...
Searching...
No Matches
param_proto.h
1
11#ifndef ASRT_PARAM_PROTO_H
12#define ASRT_PARAM_PROTO_H
13
14#ifdef __cplusplus
15extern "C" {
16#endif
17
18#include "./chann.h"
19#include "./flat_tree.h"
20#include "./status.h"
21#include "./util.h"
22
23// Message IDs (uint8_t, channel 4)
24enum asrt_param_message_id_e
25{
26 ASRT_PARAM_MSG_READY = 0x01, // controller -> reactor
27 ASRT_PARAM_MSG_READY_ACK = 0x02, // reactor -> controller
28 ASRT_PARAM_MSG_QUERY = 0x03, // reactor -> controller
29 ASRT_PARAM_MSG_RESPONSE = 0x04, // controller -> reactor
30 ASRT_PARAM_MSG_ERROR = 0x05, // controller -> reactor
31 ASRT_PARAM_MSG_FIND_BY_KEY = 0x06, // reactor -> controller
32};
33typedef uint8_t asrt_param_message_id;
34
35// node_id=0 is the reserved NONE sentinel.
36#define ASRT_PARAM_NONE_ID ( (asrt_flat_id) 0 )
37
38// Error codes in PARAM_ERROR payload
39enum asrt_param_err_e
40{
41 ASRT_PARAM_ERR_NONE = 0x00,
42 ASRT_PARAM_ERR_RESPONSE_TOO_LARGE = 0x01,
43 ASRT_PARAM_ERR_INVALID_QUERY = 0x02,
44 ASRT_PARAM_ERR_ENCODE_FAILURE = 0x03,
45 ASRT_PARAM_ERR_TYPE_MISMATCH = 0x04,
46 ASRT_PARAM_ERR_TIMEOUT = 0x05,
47};
48
49static inline struct asrt_send_req* asrt_msg_ctor_param_ready(
50 struct asrt_u8d5msg* ready_msg,
51 asrt_flat_id root_id )
52{
53 uint8_t* p = ready_msg->buff;
54 *p++ = ASRT_PARAM_MSG_READY;
55 asrt_add_u32( &p, root_id );
56 ready_msg->req.buff = ( struct asrt_span_span ){
57 .b = ready_msg->buff,
58 .e = p,
59 .rest = NULL,
60 .rest_count = 0,
61 };
62 return &ready_msg->req;
63}
64
65static inline struct asrt_send_req* asrt_msg_rtoc_param_ready_ack(
66 struct asrt_u8d5msg* msg,
67 uint32_t max_msg_size )
68{
69 uint8_t* p = msg->buff;
70 *p++ = ASRT_PARAM_MSG_READY_ACK;
71 asrt_add_u32( &p, max_msg_size );
72 msg->req.buff = ( struct asrt_span_span ){
73 .b = msg->buff,
74 .e = msg->buff + sizeof msg->buff,
75 .rest = NULL,
76 .rest_count = 0,
77 };
78 return &msg->req;
79}
80
81static inline struct asrt_send_req* asrt_msg_rtoc_param_query(
82 struct asrt_u8d5msg* msg,
83 asrt_flat_id node_id )
84{
85 uint8_t* p = msg->buff;
86 *p++ = ASRT_PARAM_MSG_QUERY;
87 asrt_add_u32( &p, node_id );
88 msg->req.buff = ( struct asrt_span_span ){
89 .b = msg->buff,
90 .e = msg->buff + sizeof msg->buff,
91 .rest = NULL,
92 .rest_count = 0,
93 };
94 return &msg->req;
95}
96
98{
99 uint8_t nul; // embedded NUL terminator for key
100 struct asrt_span spans[2]; // [0] = key bytes, [1] = &nul
101 uint8_t hdr[5]; // msg_id + parent_id
102 struct asrt_send_req req;
103};
104
105static inline struct asrt_send_req* asrt_msg_rtoc_param_find_by_key(
106 struct asrt_param_find_by_key_msg* msg,
107 asrt_flat_id parent_id,
108 char const* key )
109{
110 uint8_t* h = msg->hdr;
111 *h++ = ASRT_PARAM_MSG_FIND_BY_KEY;
112 asrt_add_u32( &h, parent_id );
113 size_t key_len = strlen( key );
114 msg->nul = '\0';
115 msg->spans[0] = ( struct asrt_span ){ .b = (uint8_t*) key, .e = (uint8_t*) key + key_len };
116 msg->spans[1] = ( struct asrt_span ){ .b = &msg->nul, .e = &msg->nul + 1 };
117 msg->req.buff = ( struct asrt_span_span ){
118 .b = msg->hdr,
119 .e = msg->hdr + sizeof msg->hdr,
120 .rest = msg->spans,
121 .rest_count = 2,
122 };
123 return &msg->req;
124}
125
126static inline struct asrt_send_req* asrt_msg_ctor_param_error(
127 struct asrt_u8d6msg* msg,
128 enum asrt_param_err_e error_code,
129 asrt_flat_id node_id )
130{
131 uint8_t* p = msg->buff;
132 *p++ = ASRT_PARAM_MSG_ERROR;
133 *p++ = error_code;
134 asrt_add_u32( &p, node_id );
135 msg->req.buff = ( struct asrt_span_span ){
136 .b = msg->buff,
137 .e = p,
138 .rest = NULL,
139 .rest_count = 0,
140 };
141 return &msg->req;
142}
143
144// Returns the number of bytes the value payload occupies on the wire (not
145// including node_id, key, or type byte).
146static inline size_t asrt_param_value_wire_size( struct asrt_flat_value v )
147{
148 return asrt_flat_value_wire_size( v );
149}
150
151static inline void asrt_param_write_value( uint8_t** p, struct asrt_flat_value v )
152{
153 asrt_flat_value_write( p, v );
154}
155
156static inline enum asrt_status asrt_param_decode_value(
157 struct asrt_span* buff,
158 uint8_t raw_type,
159 struct asrt_flat_value* val )
160{
161 return asrt_flat_value_decode( buff, raw_type, val );
162}
163
164// Encodes msg_id + N sibling nodes (null-terminated keys/values) + trailing u32
165// next_sibling_id into out_buff[0..max_bytes-1]. Writes total length to *out_len.
166// Returns ASRT_SIZE_ERR when the first node does not fit, ASRT_ARG_ERR on bad args.
167// A missing node is encoded as type=NONE with an empty key.
168static inline enum asrt_status asrt_msg_ctor_param_response(
169 struct asrt_flat_tree* tree,
170 asrt_flat_id start_id,
171 uint32_t max_bytes,
172 uint8_t* out_buff,
173 uint32_t* out_len )
174{
175 if ( !tree || !out_buff || !out_len )
176 return ASRT_ARG_ERR;
177 if ( max_bytes < 11U ) // msg_id(1)+node_id(4)+key\0(1)+type(1)+next_sib(4)
178 return ASRT_SIZE_ERR;
179
180 uint8_t* p = out_buff;
181 uint8_t* nodes_end = out_buff + max_bytes - 4; // 4 bytes reserved for trailer
182 asrt_flat_id current = start_id;
183 asrt_flat_id next_sib = ASRT_PARAM_NONE_ID;
184 int encoded = 0;
185
186 *p++ = ASRT_PARAM_MSG_RESPONSE;
187
188 while ( current != ASRT_PARAM_NONE_ID ) {
189 struct asrt_flat_query_result qr;
190 int not_found = ( asrt_flat_tree_query( tree, current, &qr ) != ASRT_SUCCESS );
191 if ( not_found ) {
192 qr.id = current;
193 qr.key = NULL;
194 qr.value.type = ASRT_FLAT_STYPE_NONE;
195 qr.next_sibling = ASRT_PARAM_NONE_ID;
196 }
197
198 size_t key_len = qr.key ? strlen( qr.key ) : 0U;
199 size_t node_size = 4U + key_len + 1U + 1U // node_id + key\0 + type
200 + asrt_param_value_wire_size( qr.value );
201
202 if ( p + node_size > nodes_end ) {
203 if ( encoded == 0 )
204 return ASRT_SIZE_ERR;
205 next_sib = current;
206 break;
207 }
208
209 asrt_add_u32( &p, qr.id );
210 if ( qr.key ) {
211 memcpy( p, qr.key, key_len );
212 p += key_len;
213 }
214 *p++ = '\0';
215 *p++ = (uint8_t) qr.value.type;
216 asrt_param_write_value( &p, qr.value );
217
218 encoded++;
219 if ( not_found )
220 break;
221 current = qr.next_sibling;
222 }
223
224 asrt_add_u32( &p, next_sib );
225 *out_len = (uint32_t) ( p - out_buff );
226 return ASRT_SUCCESS;
227}
228
229
230#ifdef __cplusplus
231}
232#endif
233
234#endif // ASRT_PARAM_PROTO_H
Definition: flat_tree.h:156
node_id maps to blocks[node_id / node_capacity][node_id % node_capacity].
Definition: flat_tree.h:121
Definition: flat_tree.h:90
Definition: param_proto.h:98
An outgoing message request placed in a module's send queue.
Definition: chann.h:64
struct asrt_span_span buff
Message payload (scatter-gather).
Definition: chann.h:65
Scatter-gather buffer: a primary byte range [b, e) followed by rest_count additional spans.
Definition: span.h:37
uint8_t * b
Primary buffer start.
Definition: span.h:38
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee ...
Definition: span.h:23
uint8_t * b
Pointer to the first byte.
Definition: span.h:24
uint8_t * e
One-past-the-end pointer.
Definition: span.h:25
Definition: chann.h:206
Definition: chann.h:211