49#ifndef RTE_SITE_ROLE_H
50#define RTE_SITE_ROLE_H
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
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
139 const uint8_t mac[RTE_SITE_ROLE_TOKEN_MAC_LEN]);
154#define RTE_SITE_ROLE_SIBLING_MISMATCH_LIMIT 3U
157#define RTE_SITE_ROLE_SIBLING_REACH_DEFAULT_CYCLES 3U
233 bool peer_online_now;
234 bool peer_unresponsive;
236 bool standby_healthy;
244 rte_netlink_storage_t link_storage;
252 bool local_single_mode;
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;
265 bool last_reason_set;
266 bool standby_healthy;
267 uint32_t standby_last_try_cycle;
268 uint32_t standby_rx_cycle;
271 uint8_t sibling_mismatch;
272 bool challenge_valid;
274 uint32_t challenge_cycle;
275 bool challenge_fail_reported;
rte_dual_state_t
State of one instance in a dual (two-redundant-instance) relationship, as decided by rte_dual_negotia...
struct rte_netlink_impl_s * rte_netlink_handle_t
Opaque handle to an established link, returned by rte_netlink_open().
rte_status_t
Common result/status codes.
uint32_t rte_duration_ms_t
uint64_t rte_timestamp_ms_t
"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,...
OS Abstraction Layer - Point-to-point network link service.
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?...
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
uint32_t connect_retry_ms
uint32_t sibling_reach_cycles
rte_duration_ms_t ack_timeout_ms
rte_duration_ms_t peer_lost_timeout_ms
uint8_t send_miss_threshold
rte_site_role_trace_fn trace
uint32_t challenge_lifetime_cycles
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