40#include "rte/checkpoint/rte_checkpoint.h"
41#include "rte/checksum/rte_checksum.h"
42#include "rte/clocksync/rte_clocksync.h"
44#include "rte/safestate/rte_safestate.h"
45#include "rte/voter/rte_voter.h"
55static int g_site_index[SITE_COUNT] = { SITE_WEST, SITE_EAST };
56static void *g_channel_handles[SITE_COUNT] = { &g_site_index[SITE_WEST], &g_site_index[SITE_EAST] };
59static bool g_mail_ready[SITE_COUNT];
64static bool g_link_down[SITE_COUNT];
66static rte_status_t mock_send(
void *channel,
const void *data,
size_t data_size)
68 int idx = *(
const int *)channel;
79 (void)memcpy(&g_mailbox[idx], data, data_size);
80 g_mail_ready[idx] =
true;
84static rte_status_t mock_recv(
void *channel,
void *data,
size_t data_size, uint32_t timeout_ms)
86 int idx = *(
const int *)channel;
93 if (g_link_down[idx] || !g_mail_ready[idx])
97 (void)memcpy(data, &g_mailbox[idx], data_size);
106static rte_status_t clocksync_get_offset_ms(int64_t *out_offset_ms)
125static jmp_buf g_safestate_jmp;
128 int32_t line,
const char *message)
132 printf(
" [SAFE-STATE] level=%d reason=%u at line %d - withdrawing movement authority\n", (
int)level,
133 (
unsigned)reason, (
int)line);
134 longjmp(g_safestate_jmp, 1);
143 int64_t offset_ms = 0;
150 clock_osadapter.get_offset_ms = clocksync_get_offset_ms;
151 clock_osadapter.get_quality = clocksync_get_quality;
155 printf(
"Diagnostic clock offset WEST-vs-EAST: %lldms (quality=%d) - NOT used for the vote below\n",
156 (
long long)offset_ms, (
int)quality);
158 memset(&voter_config, 0,
sizeof(voter_config));
163 for (i = 0U; i < SITE_COUNT; i++)
167 memset(&chan_config, 0,
sizeof(chan_config));
169 chan_config.
send = mock_send;
170 chan_config.
recv = mock_recv;
180 g_mail_ready[SITE_WEST] =
false;
181 g_mail_ready[SITE_EAST] =
false;
188 printf(
"\nCycle 1: WEST and EAST both reach checkpoint 1...\n");
194 if (setjmp(g_safestate_jmp) == 0)
199 g_mail_ready[SITE_WEST] =
false;
200 g_mail_ready[SITE_EAST] =
false;
201 g_link_down[SITE_EAST] =
true;
208 printf(
"\nCycle 2: EAST's link is down - its confirmation never arrives...\n");
212 printf(
" rte_channel_checkpoint() -> %s (unexpected - should have diverted)\n",
217 printf(
" Cycle 2 correctly forced safe-state instead of voting on an unconfirmed cycle.\n");
221 for (i = 0U; i < SITE_COUNT; i++)
rte_status_t rte_channel_checkpoint(rte_voter_t *voter, const rte_checkpoint_config_t *config)
Performs one bounded checkpoint rendezvous across every channel registered with a voter.
rte_status_t rte_checksum_crc64_init(rte_crc64_polynomial_t polynomial)
Initialize CRC-64 lookup tables for chosen polynomial.
rte_clocksync_quality_t
Coarse quality/confidence of the current clock synchronization.
rte_status_t rte_clocksync_get_quality(rte_clocksync_quality_t *out_quality)
Reports the OSAdapter's current confidence in the clock offset.
rte_status_t rte_clocksync_get_offset_ms(int64_t *out_offset_ms)
Reports this node's estimated clock offset (diagnostic/timeout- sizing only - see the file-level note...
@ RTE_CLOCKSYNC_SYNCHRONIZED
@ RTE_CLOCKSYNC_UNSYNCHRONIZED
rte_safestate_level_t
Safe-state severity levels (ADR-004 section 2.1).
rte_status_t rte_safestate_register_handler(rte_safestate_level_t level, rte_safestate_handler_t handler)
Registers the reaction handler for one safe-state level. This is how an integrator supplies their own...
uint16_t rte_safestate_reason_t
Diagnostic reason code accompanying a safe-state transition.
@ RTE_SAFESTATE_LEVEL_SAFE
const char * rte_status_to_string(rte_status_t status)
Returns a short, static, human-readable string for a status code. Intended for diagnostics/logging on...
rte_status_t
Common result/status codes.
@ RTE_STATUS_INVALID_PARAM
rte_status_t rte_channel_destroy(rte_channel_t *handle)
Destroys a vital channel instance.
rte_channel_storage_t rte_channel_t
Opaque handle to a vital channel instance.
rte_status_t rte_channel_init(rte_channel_storage_t *storage, const rte_channel_config_t *config)
Initializes one vital channel over a caller-supplied transport.
rte_voter_storage_t rte_voter_t
Opaque handle to a voter instance.
rte_status_t rte_voter_register_channel(rte_voter_t *voter, rte_channel_t *channel)
Registers one already-initialized channel with this voter.
rte_status_t rte_voter_destroy(rte_voter_t *voter)
Destroys a voter instance.
rte_status_t rte_voter_init(rte_voter_storage_t *storage, const rte_voter_config_t *config)
Initializes a voter with zero registered channels.
OSAdapter interface for clock synchronization.
rte_status_t rte_osadapter_clocksync_register(const rte_osadapter_clocksync_t *adapter)
Registers the OSAdapter clock synchronization implementation.
Configuration for rte_channel_init().
Checkpoint configuration.
rte_duration_ms_t max_delay_ms
uint32_t expected_node_count
OSAdapter clock synchronization operations vtable.
Vital channel message with integrated CRC-64.
Configuration for rte_voter_init().
uint32_t channel_timeout_ms
rte_voting_strategy_t voting_strategy