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_site_role.h
Go to the documentation of this file.
1
49#ifndef RTE_SITE_ROLE_H
50#define RTE_SITE_ROLE_H
51
52#include <stdbool.h>
53#include <stddef.h>
54#include <stdint.h>
55
62
63#ifdef __cplusplus
64extern "C" {
65#endif
66
68#define RTE_SITE_ROLE_FRAME_OVERHEAD 7U
70#define RTE_SITE_ROLE_FRAME_STATE_OFFSET 6U
72#define RTE_SITE_ROLE_VALID_MARKER 0xA5U
74#define RTE_SITE_ROLE_SINGLE_MODE_DUAL 0U
75#define RTE_SITE_ROLE_SINGLE_MODE_SINGLE 1U
76
87
95
106
110typedef rte_status_t (*rte_site_role_encode_state_fn)(void *user, uint8_t *out, size_t size, bool live);
113typedef bool (*rte_site_role_receive_state_fn)(void *user, const uint8_t *in, size_t size, bool valid);
115typedef void (*rte_site_role_change_fn)(void *user, const rte_site_role_change_t *change);
117typedef void (*rte_site_role_trace_fn)(void *user, const char *line);
119typedef void (*rte_site_role_delay_fn)(void *user, uint32_t ms);
120
121/*
122 * Takeover confirmation token (ADR-040 step 4, REQ-SITEROLE-015), RTE_SITE_ROLE_TOKEN_LEN bytes:
123 * message (RTE_SITE_ROLE_TOKEN_MSG_LEN): version(1) | site id(1) | channel id(1) | 0(1) |
124 * challenge(4, little endian) | issuer sequence(4, little endian) | 0(4)
125 * mac (RTE_SITE_ROLE_TOKEN_MAC_LEN): the issuer's MAC over the message, with the site's takeover key
126 * The challenge makes a token single-use and bounds its age without a wall clock: the issuer reads the current
127 * challenge from the channel's status, and a token for an older challenge is rejected.
128 */
129#define RTE_SITE_ROLE_TOKEN_MSG_LEN 16U
130#define RTE_SITE_ROLE_TOKEN_MAC_LEN 8U
131#define RTE_SITE_ROLE_TOKEN_LEN (RTE_SITE_ROLE_TOKEN_MSG_LEN + RTE_SITE_ROLE_TOKEN_MAC_LEN)
132#define RTE_SITE_ROLE_TOKEN_VERSION 1U
134#define RTE_SITE_ROLE_CHALLENGE_LIFETIME_DEFAULT_CYCLES 240U
135
138typedef bool (*rte_site_role_verify_mac_fn)(void *user, const uint8_t *msg, size_t msg_len,
139 const uint8_t mac[RTE_SITE_ROLE_TOKEN_MAC_LEN]);
140
152
154#define RTE_SITE_ROLE_SIBLING_MISMATCH_LIMIT 3U
157#define RTE_SITE_ROLE_SIBLING_REACH_DEFAULT_CYCLES 3U
158
161typedef struct
162{
163 bool known;
164 bool online;
166 bool ready;
168
173
182
184typedef struct
185{
186 uint32_t own_id;
187 uint32_t peer_id;
188 bool is_west;
189 bool listen;
190 const char *peer_host;
191 uint16_t port;
203 size_t frame_size;
204 uint8_t *tx_buf;
205 uint8_t *rx_buf;
206 const char *role_tag;
207 const char *peer_tag;
208 const char *site_name;
209 const char *sibling_tag;
211 rte_site_role_receive_state_fn receive_state;
212 rte_site_role_change_fn on_change;
215 void *user;
216 /* Takeover confirmation (REQ-SITEROLE-015). verify_mac NULL = the interim unauthenticated path. */
218 uint8_t channel_id;
220 /* Sibling site state (REQ-SITEROLE-016). sibling_source NULL = the application supplies the sibling facts in
221 * rte_site_role_local_t and calls rte_site_role_check_sibling() itself (step 3). Also polled once by
222 * rte_site_role_start() before the inter-site negotiation (REQ-SITEROLE-017). */
223 rte_site_role_sibling_source_fn sibling_source;
226
228typedef struct
229{
230 bool online;
231 bool link_up;
233 bool peer_online_now;
234 bool peer_unresponsive;
235 bool standby_warm;
236 bool standby_healthy;
237 rte_site_role_reason_t last_reason;
239
241typedef struct
242{
244 rte_netlink_storage_t link_storage;
246 rte_dual_channel_t dual_channel;
247 rte_dual_negotiator_t negotiator;
248 rte_timestamp_ms_t startup_timestamp_ms;
249 uint8_t send_miss;
250 bool online;
251 bool local_faulted;
252 bool local_single_mode;
253 bool peer_faulted;
254 uint8_t peer_single_mode;
255 bool peer_online_now;
256 uint32_t peer_last_rx_cycle;
257 bool peer_snapshot_valid;
258 uint32_t peer_snapshot_cycle;
259 bool peer_unresponsive;
260 bool lost_peer_while_online;
261 bool takeover_confirmed;
262 uint32_t takeover_confirm_cycle;
263 uint32_t both_standby_cycles;
264 rte_site_role_reason_t last_reason;
265 bool last_reason_set;
266 bool standby_healthy;
267 uint32_t standby_last_try_cycle;
268 uint32_t standby_rx_cycle;
269 bool standby_warm;
270 uint32_t cycle;
271 uint8_t sibling_mismatch;
272 bool challenge_valid;
273 uint32_t challenge;
274 uint32_t challenge_cycle;
275 bool challenge_fail_reported;
280
287
303
305void rte_site_role_execute(rte_site_role_t *rs, uint32_t cycle, const rte_site_role_local_t *local);
306
308void rte_site_role_service_link(rte_site_role_t *rs, uint32_t cycle);
309
311void rte_site_role_sync_standby(rte_site_role_t *rs, uint32_t cycle, const rte_site_role_local_t *local);
312
317void rte_site_role_on_takeover_confirm(rte_site_role_t *rs, uint32_t cycle);
318
327 size_t token_len);
328
334bool rte_site_role_takeover_challenge(const rte_site_role_t *rs, uint32_t *out);
335
338
340void rte_site_role_flush_faulted(rte_site_role_t *rs, bool single_mode);
341
348rte_site_role_sibling_verdict_t rte_site_role_check_sibling(rte_site_role_t *rs, uint32_t cycle, bool own_single_mode,
349 const rte_site_role_sibling_t *sibling);
350
358
361
364
367
370
371#ifdef __cplusplus
372}
373#endif
374
375#endif /* RTE_SITE_ROLE_H */
rte_dual_state_t
State of one instance in a dual (two-redundant-instance) relationship, as decided by rte_dual_negotia...
rte_status_t
Common result/status codes.
Definition rte_status.h:27
uint32_t rte_duration_ms_t
Definition rte_types.h:27
uint64_t rte_timestamp_ms_t
Definition rte_types.h:30
"DualChannel" layer of ADR-020: wraps 1..N redundant rte_dual_msgchannel_t links for fault-tolerant,...
Dual state negotiator of ADR-020: decides rte_dual_state_t for both this instance and its peer,...
rte_site_role_sibling_verdict_t rte_site_role_sibling_verdict(const rte_site_role_t *rs)
The A/B agreement verdict of the check run by the last rte_site_role_execute() (REQ-SITEROLE-016).
rte_site_role_sibling_verdict_t rte_site_role_check_sibling(rte_site_role_t *rs, uint32_t cycle, bool own_single_mode, const rte_site_role_sibling_t *sibling)
A/B role agreement (REQ-SITEROLE-014): compares this channel's role and single_mode with its sibling'...
void rte_site_role_execute(rte_site_role_t *rs, uint32_t cycle, const rte_site_role_local_t *local)
One cycle: reconnect if needed, exchange frames, update the standby state, decide and apply the role.
rte_status_t(*) rte_site_role_encode_state_fn(void *user, uint8_t *out, size_t size, bool live)
void rte_site_role_shutdown(rte_site_role_t *rs)
Closes the link. Idempotent.
void rte_site_role_flush_faulted(rte_site_role_t *rs, bool single_mode)
Best-effort final frame with faulted=1 before the process reboots, so the counterpart can promote.
bool(*) rte_site_role_verify_mac_fn(void *user, const uint8_t *msg, size_t msg_len, const uint8_t mac[RTE_SITE_ROLE_TOKEN_MAC_LEN])
rte_status_t rte_site_role_init(rte_site_role_t *rs, const rte_site_role_config_t *cfg)
Validates and stores the configuration. Opens nothing.
rte_site_role_change_kind_t
@ RTE_SITE_ROLE_CHANGE_DEMOTED
@ RTE_SITE_ROLE_CHANGE_RENEGOTIATED
@ RTE_SITE_ROLE_CHANGE_PROMOTED
bool(*) rte_site_role_sibling_source_fn(void *user, rte_site_role_sibling_t *out)
void(*) rte_site_role_trace_fn(void *user, const char *line)
rte_status_t rte_site_role_start(rte_site_role_t *rs)
Opens the link (blocking, bounded by startup_timeout_ms) and runs the startup negotiation until it se...
rte_site_role_token_result_t rte_site_role_on_takeover_token(rte_site_role_t *rs, uint32_t cycle, const uint8_t *token, size_t token_len)
Verifies a takeover confirmation token (REQ-SITEROLE-015) and, when it is valid, records the confirma...
void rte_site_role_on_takeover_confirm(rte_site_role_t *rs, uint32_t cycle)
Records an unauthenticated dispatcher confirmation that the other site is not ONLINE (ignored while O...
void rte_site_role_service_link(rte_site_role_t *rs, uint32_t cycle)
Fast tick: drains up to 4 frames so acknowledgements do not depend on the two sites' cycle phase.
void rte_site_role_get_status(const rte_site_role_t *rs, rte_site_role_status_t *out)
Fills a status snapshot for monitors.
bool(*) rte_site_role_receive_state_fn(void *user, const uint8_t *in, size_t size, bool valid)
rte_site_role_token_result_t
@ RTE_SITE_ROLE_TOKEN_BAD_FORMAT
@ RTE_SITE_ROLE_TOKEN_NOT_CONFIGURED
@ RTE_SITE_ROLE_TOKEN_NO_CHALLENGE
@ RTE_SITE_ROLE_TOKEN_STALE_CHALLENGE
@ RTE_SITE_ROLE_TOKEN_ACCEPTED
@ RTE_SITE_ROLE_TOKEN_IGNORED_ONLINE
@ RTE_SITE_ROLE_TOKEN_BAD_MAC
void(*) rte_site_role_change_fn(void *user, const rte_site_role_change_t *change)
void(*) rte_site_role_delay_fn(void *user, uint32_t ms)
void rte_site_role_note_lost_contact(rte_site_role_t *rs)
The application stalled while ONLINE long enough for the counterpart to have taken over: yield if it ...
bool rte_site_role_is_online(const rte_site_role_t *rs)
void rte_site_role_get_negotiator_states(const rte_site_role_t *rs, rte_dual_state_t *own, rte_dual_state_t *peer)
The underlying negotiator's own and peer states (diagnostic only; the role is rte_site_role_is_online...
rte_site_role_sibling_verdict_t
@ RTE_SITE_ROLE_SIBLING_PENDING
@ RTE_SITE_ROLE_SIBLING_FAULT
@ RTE_SITE_ROLE_SIBLING_AGREE
@ RTE_SITE_ROLE_SIBLING_UNKNOWN
bool rte_site_role_takeover_challenge(const rte_site_role_t *rs, uint32_t *out)
This channel's current takeover challenge, for the application's status line (the issuer MACs it).
void rte_site_role_sync_standby(rte_site_role_t *rs, uint32_t cycle, const rte_site_role_local_t *local)
ONLINE, warm/hot standby: sends this cycle's snapshot before the output commit and tracks the ack.
Site-role policy: one pure decision function for "should this channel promote, demote or stay?...
rte_site_role_reason_t
Common status/error codes returned by every Safe API Framework function. Shared across all OS Abstrac...
Common fixed-width types and the caller-owned-storage handle pattern used by every OAL service (see A...
One rte_dual_channel_t instance's state. Caller-owned storage; every field is private - reach it only...
One rte_dual_negotiator_t instance's state. Caller-owned storage; every field is private - reach it o...
rte_timestamp_ms_t startup_timestamp_ms
rte_duration_ms_t ack_timeout_ms
rte_duration_ms_t peer_lost_timeout_ms
rte_site_role_trace_fn trace
rte_duration_ms_t startup_timeout_ms
rte_site_role_delay_fn delay
rte_duration_ms_t connect_timeout_ms
rte_duration_ms_t link_poll_ms
rte_duration_ms_t reconnect_attempt_ms
rte_site_role_sibling_verdict_t sibling_verdict
rte_site_role_sibling_t sibling
uint32_t sibling_rx_cycle