20 for (i = 0U; i < count; i++)
22 if (channel->link_handles[i] != NULL)
25 channel->link_handles[i] = NULL;
42 memset(&cfg, 0,
sizeof(cfg));
89 memset(&dual_cfg, 0,
sizeof(dual_cfg));
92 dual_cfg.
links[i] = channel->link_handles[i];
105 channel->link_count = 0U;
166 memset(&voter_cfg, 0,
sizeof(voter_cfg));
182 channel->link_count = 0U;
190 memset(&chan_cfg, 0,
sizeof(chan_cfg));
203 channel->link_count = 0U;
215 if ((channel == NULL) || (config == NULL))
219 memset(channel, 0,
sizeof(*channel));
220 channel->type = config->
type;
222 switch (config->
type)
225 status = safechannel_open_dual(channel, &config->as.dual);
228 status = safechannel_open_vital(channel, &config->as.vital);
241 if ((channel == NULL) || (!channel->is_open))
248 if (payload_size > (
size_t)UINT8_MAX)
254 return rte_voter_send(&channel->impl.vital.voter, payload, payload_size);
260 if ((channel == NULL) || (!channel->is_open) || (out_size == NULL))
267 uint8_t received_size = 0U;
270 if (max_size > (
size_t)UINT8_MAX)
272 max_size = (size_t)UINT8_MAX;
276 *out_size = (size_t)received_size;
282 return rte_voter_receive(&channel->impl.vital.voter, out_payload, max_size, &result, out_size);
288 if ((channel == NULL) || (!channel->is_open))
307 uint32_t healthy_count = 0U;
310 &healthy_count, NULL);
311 if (healthy_count == 0U)
315 if (healthy_count < channel->link_count)
329 if (!channel->is_open)
338 for (i = 0U; i < channel->link_count; i++)
345 channel->link_count = 0U;
346 channel->is_open =
false;
rte_status_t rte_dual_channel_send(rte_dual_channel_t *channel, const uint8_t *payload, uint8_t payload_size, uint32_t *out_ack_link_count)
Sends payload as a DATA frame on every configured redundant link - never gated by any negotiated stat...
rte_status_t rte_dual_channel_init(rte_dual_channel_t *channel, const rte_dual_channel_config_t *config)
Initializes a rte_dual_channel_t: initializes every configured redundant link (rte_dual_msgchannel_in...
rte_dual_channel_status_t rte_dual_channel_get_status(const rte_dual_channel_t *channel)
Returns the aggregate connection status across every configured redundant link, as of the most recent...
rte_status_t rte_dual_channel_receive(rte_dual_channel_t *channel, uint8_t *out_payload, uint8_t max_size, rte_duration_ms_t timeout_ms, uint8_t *out_size)
Returns the most recently staged inbound DATA frame, actively polling the configured links (each auto...
@ RTE_DUAL_CHANNEL_STATUS_FULL
@ RTE_DUAL_CHANNEL_STATUS_DOWN
@ RTE_DUAL_CHANNEL_STATUS_DEGRADED
struct rte_netlink_impl_s * rte_netlink_handle_t
Opaque handle to an established link, returned by rte_netlink_open().
rte_status_t rte_netlink_open(rte_netlink_storage_t *storage, const rte_netlink_config_t *config, rte_netlink_handle_t *out_handle)
Establishes a point-to-point link: binds+accepts (LISTEN) or dials (CONNECT), per config->role.
rte_status_t rte_netlink_close(rte_netlink_handle_t handle)
Closes a link.
rte_status_t rte_netlink_send(rte_netlink_handle_t handle, const void *message, size_t message_size, rte_duration_ms_t timeout_ms)
Sends one fixed-size message, blocking at most timeout_ms.
rte_status_t rte_netlink_receive(rte_netlink_handle_t handle, void *out_message, size_t buffer_size, rte_duration_ms_t timeout_ms)
Receives one fixed-size message, blocking at most timeout_ms.
@ RTE_NETLINK_ROLE_CONNECT
rte_status_t rte_safechannel_receive(rte_safechannel_t *channel, uint8_t *out_payload, size_t max_size, rte_duration_ms_t timeout_ms, size_t *out_size)
Returns the most recent inbound payload, actively polling the underlying channel if nothing was alrea...
rte_status_t rte_safechannel_send(rte_safechannel_t *channel, const uint8_t *payload, size_t payload_size)
Sends payload on the underlying channel - broadcast-with-ACK- wait for DUAL_REDUNDANT (rte_dual_chann...
rte_status_t rte_safechannel_open(rte_safechannel_t *channel, const rte_safechannel_config_t *config)
Opens a channel: opens every configured endpoint via the registered rte_netlink OSAdapter,...
rte_safechannel_link_status_t rte_safechannel_get_status(const rte_safechannel_t *channel)
Aggregate status across every configured endpoint - DOWN before the first send/receive.
rte_status_t rte_safechannel_close(rte_safechannel_t *channel)
Closes every endpoint this instance opened and releases the wrapped channel. Safe to call on an alrea...
#define RTE_SAFECHANNEL_MAX_LINKS
Maximum number of redundant endpoints one rte_safechannel_t may be configured with,...
rte_safechannel_link_status_t
Aggregate link status, uniform across both wrapped types.
@ RTE_SAFECHANNEL_TYPE_VITAL_VOTED
@ RTE_SAFECHANNEL_TYPE_DUAL_REDUNDANT
@ RTE_SAFECHANNEL_LINK_DEGRADED
@ RTE_SAFECHANNEL_LINK_FULL
@ RTE_SAFECHANNEL_LINK_DOWN
#define RTE_SAFESTATE_REASON_UNSPECIFIED
@ RTE_SAFESTATE_LEVEL_SAFE
rte_status_t
Common result/status codes.
@ RTE_STATUS_INVALID_PARAM
uint32_t rte_duration_ms_t
rte_status_t rte_channel_destroy(rte_channel_t *handle)
Destroys 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_status_t rte_voter_get_aggregated_health(const rte_voter_t *voter, uint32_t *healthy_count, uint32_t *total_disagreements)
Aggregated health across every registered channel.
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_voting_result_t
Outcome of one rte_voter_receive() call.
rte_status_t rte_voter_send(rte_voter_t *voter, const void *data, size_t data_size)
Broadcasts data to every registered, healthy channel.
rte_status_t rte_voter_init(rte_voter_storage_t *storage, const rte_voter_config_t *config)
Initializes a voter with zero registered channels.
rte_status_t rte_voter_receive(rte_voter_t *voter, void *data, size_t data_size, rte_voting_result_t *result, size_t *bytes_received)
Receives from every registered, healthy channel and votes.
Checksum and CRC utilities for data integrity in redundant systems.
static void safechannel_close_links(rte_safechannel_t *channel, uint32_t count)
Closes every already-opened link handles[0..count-1] and resets the caller's bookkeeping - used both ...
static rte_status_t safechannel_vital_backend_recv(void *channel_handle, void *data, size_t data_size, uint32_t timeout_ms)
rte_channel_config_t::recv bridge - see safechannel_vital_backend_send().
static rte_status_t safechannel_vital_backend_send(void *channel_handle, const void *data, size_t data_size)
rte_channel_config_t::send bridge: casts the opaque channel handle back to the rte_netlink_handle_t i...
static rte_status_t safechannel_open_one_endpoint(rte_netlink_storage_t *storage, const rte_safechannel_endpoint_t *endpoint, size_t message_size, rte_duration_ms_t connect_timeout_ms, rte_netlink_handle_t *out_handle)
Opens one endpoint, retrying rte_netlink_open() with a short fixed delay until connect_timeout_ms ela...
Unified, transport-hiding channel factory (ADR-022).
Configuration for rte_channel_init().
Configuration for rte_dual_channel_init().
uint32_t expected_peer_id
rte_dual_channel_status_callback_t status_callback
rte_duration_ms_t ack_timeout_ms
void * status_callback_ctx
rte_netlink_handle_t links[RTE_DUAL_CHANNEL_MAX_LINKS]
Configuration for rte_netlink_open().
rte_duration_ms_t connect_timeout_ms
Configuration for rte_safechannel_open().
rte_safechannel_type_t type
Configuration specific to RTE_SAFECHANNEL_TYPE_DUAL_REDUNDANT.
void * status_callback_ctx
rte_dual_channel_status_callback_t status_callback
rte_safechannel_endpoint_t endpoints[RTE_SAFECHANNEL_MAX_LINKS]
rte_duration_ms_t connect_timeout_ms
rte_duration_ms_t ack_timeout_ms
uint32_t expected_peer_id
One remote endpoint to open internally - replaces a caller- supplied rte_netlink_handle_t (ADR-022 se...
Caller-owned storage for one rte_safechannel_t instance. Every field is private - reach it only throu...
rte_netlink_storage_t links[RTE_SAFECHANNEL_MAX_LINKS]
Configuration specific to RTE_SAFECHANNEL_TYPE_VITAL_VOTED.
rte_safechannel_endpoint_t endpoints[RTE_SAFECHANNEL_MAX_LINKS]
rte_duration_ms_t channel_timeout_ms
rte_duration_ms_t connect_timeout_ms
rte_voting_strategy_t voting_strategy
void(*) on_disagreement(void *context, rte_voting_result_t result)
Vital channel message with integrated CRC-64.
Configuration for rte_voter_init().
rte_safestate_level_t safestate_level
void * disagreement_context
uint32_t channel_timeout_ms
rte_safestate_reason_t safestate_reason
void(*) on_disagreement(void *context, rte_voting_result_t result)
rte_voting_strategy_t voting_strategy