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_dual_channel.h File Reference

"DualChannel" layer of ADR-020: wraps 1..N redundant rte_dual_msgchannel_t links for fault-tolerant, always-send + bounded-ACK-wait delivery. More...

Include dependency graph for rte_dual_channel.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  rte_dual_channel_t
 One rte_dual_channel_t instance's state. Caller-owned storage; every field is private - reach it only through the functions below. More...
struct  rte_dual_channel_config_t
 Configuration for rte_dual_channel_init(). More...

Macros

#define RTE_DUAL_CHANNEL_MAX_LINKS   4U
 Maximum number of redundant links one rte_dual_channel_t may be configured with. Fixed, not dynamic (REQ-OAL-COMMON-010).
#define RTE_DUAL_CHANNEL_MAX_PAYLOAD   (RTE_DUAL_MSGCHANNEL_MAX_PAYLOAD - 4U)
 Max application payload bytes usable via rte_dual_channel_send()/_receive() - Layer-1's own RTE_DUAL_MSGCHANNEL_MAX_PAYLOAD minus this layer's 4-byte rte_dual_frame_header_t.

Typedefs

typedef void(*) rte_dual_channel_status_callback_t(rte_dual_channel_status_t new_status, rte_dual_channel_status_t old_status, void *user_ctx)
 Optional callback invoked whenever rte_dual_channel_get_status()'s value changes (ADR-020 section 2's "indicate to the user via callback if registered" requirement). Called synchronously from inside rte_dual_channel_send() (the only place aggregate status is recomputed) - keep this fast; it is on the same call path as the send it was triggered by.

Functions

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_init()) and starts rte_dual_channel_get_status() at RTE_DUAL_CHANNEL_STATUS_DOWN (no traffic has been sent/received yet).
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 state (ADR-020 section 2: the real payload traffic itself is the liveness check). For each link, waits up to config->ack_timeout_ms for that link's own ACK (matched by sequence number, not just "an ACK arrived") before moving on; a DATA or STATE frame received from the peer while waiting is still auto-ACKed/staged as a side effect, not dropped.
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-ACked on arrival - see rte_dual_channel_send()'s own doc) if none was already staged from a previous rte_dual_channel_send() call's own incidental polling.
rte_status_t rte_dual_channel_send_heartbeat (rte_dual_channel_t *channel, uint32_t *out_ack_count)
 Transmits a connection maintenance heartbeat frame across every configured link and waits up to ack_timeout_ms for an ACK on each.
rte_status_t rte_dual_channel_send_state_frame (rte_dual_channel_t *channel, rte_dual_state_t state, bool channel_degraded, uint64_t timestamp_ms)
 Sends a rte_dual_state_frame_t (rte_dual_frames.h) on every configured redundant link - fire-and-forget, no ACK wait (unlike rte_dual_channel_send()'s DATA frames), matching the periodic-beacon nature of state negotiation. Intended to be called by a rte_dual_negotiator_t, not directly by application code - see ADR-020 section 3.
rte_status_t rte_dual_channel_receive_state_frame (rte_dual_channel_t *channel, rte_duration_ms_t timeout_ms, rte_dual_state_frame_t *out_frame)
 Returns the most recently staged inbound STATE frame, actively polling the configured links if none was already staged. Intended to be called by a rte_dual_negotiator_t - see ADR-020 section 3.
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_dual_channel_send() call (ADR-020 section 2). RTE_DUAL_CHANNEL_STATUS_DOWN before the first send.
bool rte_dual_channel_is_link_up (const rte_dual_channel_t *channel, uint32_t link_index)
 Returns whether one specific configured link is currently considered up, as of the most recent rte_dual_channel_send() call - for diagnostics/logging (e.g. which specific redundant path is the one that's down), not a safety-decision input on its own (see rte_dual_channel_get_status() for the aggregate).
rte_status_t rte_dual_channel_set_resync_on_sequence_error (rte_dual_channel_t *channel, bool enable)

Detailed Description

"DualChannel" layer of ADR-020: wraps 1..N redundant rte_dual_msgchannel_t links for fault-tolerant, always-send + bounded-ACK-wait delivery.

rte_dual_channel_t has no knowledge of rte_dual_negotiator_t (ADR-020 section 3's ownership direction: the negotiator depends on this module, not the other way around) - it exposes two independent frame flows over the same redundant links:

  • rte_dual_channel_send()/_receive(): application DATA, always sent on every configured link, each link's send waits up to config->ack_timeout_ms for that specific link's ACK before that link is counted as down for this round (ADR-020 section 2) - inbound DATA frames are auto-ACKed and staged for the next _receive() call.
  • rte_dual_channel_send_state_frame()/_receive_state_frame(): a narrower, negotiator-facing pair for fire-and-forget rte_dual_state_frame_t beacons (rte_dual_frames.h), sharing the same redundant links and the same DOWN/DEGRADED/FULL bookkeeping, but never counted toward or against DATA's own ACK accounting.

REQ-DUAL-CHANNEL-001: no dynamic allocation; fixed array of at most RTE_DUAL_CHANNEL_MAX_LINKS redundant links. REQ-DUAL-CHANNEL-002: rte_dual_channel_send() always transmits DATA on every configured link, never gated by any negotiated rte_dual_state_t. REQ-DUAL-CHANNEL-003: aggregate status is recomputed after every send and status_callback fires only on an actual change. REQ-DUAL-CHANNEL-004: DATA and STATE frame flows share links and status bookkeeping; STATE traffic is fire-and-forget and never counted toward or against DATA's own ACK accounting. REQ-DUAL-CHANNEL-005: rte_dual_channel_receive()/_receive_state_frame() poll every configured link on every call, never stopping early, so one link cannot starve another of its own auto-ACK. REQ-DUAL-CHANNEL-006: an inbound frame shorter than this layer's own header, or shorter than its kind's full fixed size, is reported as RTE_STATUS_DATA_CORRUPTION.

Definition in file rte_dual_channel.h.