|
Safe API Framework 0.1.0 build 384e6ae
Layered API framework for safety-related applications (ERTMS RBC reference targeting CENELEC EN 50128 SIL 4)
|
Files | |
| file | src/redundancy/voter/rte_voter.c |
| N-way voting engine (ADR-025): validates parameters, dispatches send/receive to every registered healthy channel, and - for receive - groups the responses by mutual agreement and picks the largest group meeting quorum. | |
Data Structures | |
| struct | rte_voter_config_t |
| Configuration for rte_voter_init(). More... | |
| struct | rte_voter_storage_t |
| Storage for one voter instance (opaque to caller). No dynamic memory. More... | |
Macros | |
| #define | RTE_VOTER_MAX_CHANNELS 8U |
| Maximum number of channels a single voter can register. | |
| #define | RTE_VOTER_MAX_MESSAGE_SIZE 256U |
| Maximum payload size rte_voter_send()/_receive() supports. | |
Typedefs | |
| typedef bool(*) | rte_voter_compare_fn(const void *a, const void *b, size_t size, void *user_ctx) |
| Optional custom comparison callback. | |
| typedef rte_voter_storage_t | rte_voter_t |
| Opaque handle to a voter instance. | |
Enumerations | |
| enum | rte_voting_strategy_t { RTE_VOTING_2OO2 = 1 , RTE_VOTING_2OO3 = 2 , RTE_VOTING_NMR = 3 } |
| Voting strategy: how many registered channels must agree. More... | |
| enum | rte_voting_result_t { RTE_VOTING_AGREED = 0 , RTE_VOTING_DISAGREED = 1 , RTE_VOTING_TIMEOUT = 2 , RTE_VOTING_INSUFFICIENT_QUORUM = 3 } |
| Outcome of one rte_voter_receive() call. More... | |
Functions | |
| 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_register_channel (rte_voter_t *voter, rte_channel_t *channel) |
| Registers one already-initialized channel with this voter. | |
| 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_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. | |
| rte_status_t | rte_voter_vote_buffers (rte_voter_t *voter, const void *const *buffers, uint32_t buffer_count, size_t data_size, rte_voting_result_t *result, void *out_data, size_t *out_size) |
N-way vote on caller-collected buffers, without any registered-channel I/O (ADR-039's N-way cross-compare half: rte_voter used directly, buffer-based, matching rte_cross_comparator_execute_buffers()'s existing shape - decided over building a separate primitive). Same grouping/quorum logic as rte_voter_receive() (REQ-VOTER-004), applied to buffers instead of polling registered channels - this function performs no I/O and ignores any channels registered on voter (same posture rte_cross_comparator_execute_buffers() already established for its own module: a Voter (N-way channel voting) with zero registered channels is a legitimate, expected call shape here). | |
| 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. | |
| uint32_t | rte_voter_get_channel_count (const rte_voter_t *voter) |
| Number of channels currently registered with this voter. | |
| rte_channel_t * | rte_voter_get_channel (const rte_voter_t *voter, uint32_t index) |
| Direct access to one registered channel, by index. | |
| rte_channel_t * | rte_voter_get_channel_by_name (const rte_voter_t *voter, const char *name) |
| Direct access to one registered channel, by name (e.g. "ChannelAtoB") - the name each channel was given via rte_channel_config_t::name at its own rte_channel_init() time. | |
| rte_status_t | rte_voter_destroy (rte_voter_t *voter) |
| Destroys a voter instance. | |
| #define RTE_VOTER_MAX_CHANNELS 8U |
Maximum number of channels a single voter can register.
Definition at line 132 of file rte_voter.h.
| #define RTE_VOTER_MAX_MESSAGE_SIZE 256U |
Maximum payload size rte_voter_send()/_receive() supports.
Definition at line 135 of file rte_voter.h.
| typedef bool(*) rte_voter_compare_fn(const void *a, const void *b, size_t size, void *user_ctx) |
Optional custom comparison callback.
If not registered (rte_voter_config_t::compare == NULL), the default is a full byte compare (memcmp(a, b, size) == 0) - the payloads being compared have already had their transport-integrity CRC verified by the channel layer (rte_checksum) if the OSAdapter uses rte_checksum_vital_message_verify(); this callback is about semantic/value comparison, not integrity checking.
| [in] | a | First buffer. |
| [in] | b | Second buffer. |
| [in] | size | Number of bytes to compare. |
| [in] | user_ctx | rte_voter_config_t::compare_context, passed through verbatim. |
Definition at line 82 of file rte_voter.h.
| typedef rte_voter_storage_t rte_voter_t |
Opaque handle to a voter instance.
Definition at line 149 of file rte_voter.h.
Voting strategy: how many registered channels must agree.
| Enumerator | |
|---|---|
| RTE_VOTING_2OO2 | 2 out of 2: both channels must agree. |
| RTE_VOTING_2OO3 | 2 out of 3: majority among 3 channels, tolerates 1 fault. |
| RTE_VOTING_NMR | N out of M: rte_voter_config_t::quorum_size of registered channels must agree. |
Definition at line 42 of file rte_voter.h.
| enum rte_voting_result_t |
Outcome of one rte_voter_receive() call.
Definition at line 54 of file rte_voter.h.
| rte_status_t rte_voter_init | ( | rte_voter_storage_t * | storage, |
| const rte_voter_config_t * | config ) |
Initializes a voter with zero registered channels.
| [out] | storage | Pre-allocated storage. Must not be NULL. |
| [in] | config | Voting configuration. Must not be NULL. For RTE_VOTING_NMR, config->quorum_size must be >= 1. |
REQ-VOTER-001: No dynamic allocation; fixed RTE_VOTER_MAX_CHANNELS array. REQ-VOTER-002: Rejects an unrecognized voting_strategy, or NMR with quorum_size == 0.
Definition at line 201 of file rte_voter.c.
| rte_status_t rte_voter_register_channel | ( | rte_voter_t * | voter, |
| rte_channel_t * | channel ) |
Registers one already-initialized channel with this voter.
| [in] | voter | Voter handle. Must not be NULL and must be initialized. |
| [in] | channel | Already rte_channel_init()'d channel. Must not be NULL. |
Definition at line 240 of file rte_voter.c.
| rte_status_t rte_voter_send | ( | rte_voter_t * | voter, |
| const void * | data, | ||
| size_t | data_size ) |
Broadcasts data to every registered, healthy channel.
| [in] | voter | Voter handle. Must not be NULL and initialized. |
| [in] | data | Data to send. Must not be NULL. |
| [in] | data_size | Size in bytes; must be > 0 and <= RTE_VOTER_MAX_MESSAGE_SIZE. |
REQ-VOTER-003: Requires the registered-channel count to match the configured strategy before sending.
Definition at line 269 of file rte_voter.c.
| 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.
Groups the channels that responded successfully by mutual agreement (per config->compare, default memcmp); the largest group that meets the configured quorum wins - AGREED, with *data set to that group's value. If no group is large enough, DISAGREED. If fewer than 2 channels responded at all, TIMEOUT (0 responded) or INSUFFICIENT_QUORUM (1 responded, or not enough healthy channels to possibly meet quorum before even trying).
| [in] | voter | Voter handle. Must not be NULL and initialized. |
| [out] | data | Buffer to receive the winning group's data. Must not be NULL. |
| [in] | data_size | Size of data buffer; must be > 0 and <= RTE_VOTER_MAX_MESSAGE_SIZE. |
| [out] | result | Voting outcome. Can be NULL. |
| [out] | bytes_received | Bytes written to data. Can be NULL. |
REQ-VOTER-003: Requires the registered-channel count to match the configured strategy before receiving/voting. REQ-VOTER-004: Groups responses by mutual agreement and selects the largest quorum-meeting group (majority vote), not a pairwise compare against a single reference channel. REQ-VOTER-005: On DISAGREED, always invokes on_disagreement (if registered) and then unconditionally enters config->safestate_level.
Definition at line 331 of file rte_voter.c.
| rte_status_t rte_voter_vote_buffers | ( | rte_voter_t * | voter, |
| const void *const * | buffers, | ||
| uint32_t | buffer_count, | ||
| size_t | data_size, | ||
| rte_voting_result_t * | result, | ||
| void * | out_data, | ||
| size_t * | out_size ) |
N-way vote on caller-collected buffers, without any registered-channel I/O (ADR-039's N-way cross-compare half: rte_voter used directly, buffer-based, matching rte_cross_comparator_execute_buffers()'s existing shape - decided over building a separate primitive). Same grouping/quorum logic as rte_voter_receive() (REQ-VOTER-004), applied to buffers instead of polling registered channels - this function performs no I/O and ignores any channels registered on voter (same posture rte_cross_comparator_execute_buffers() already established for its own module: a Voter (N-way channel voting) with zero registered channels is a legitimate, expected call shape here).
| [in] | voter | Voter handle (rte_voter_init()'d - registered channels, if any, are ignored). Must not be NULL. |
| [in] | buffers | Array of buffer_count already-collected buffers (e.g. each replica's own value for the same logical quantity, gathered by the caller over whatever transport it uses). Must not be NULL. |
| [in] | buffer_count | Number of entries in buffers; must match voter->config. voting_strategy the same way rte_voter_receive()'s own registered- channel count must (REQ-VOTER-003, generalized to a caller-supplied count instead of a registered one) - RTE_STATUS_INVALID_PARAM otherwise. Must not exceed RTE_VOTER_MAX_CHANNELS. |
| [in] | data_size | Bytes of each buffer to compare; must be > 0 and <= RTE_VOTER_MAX_MESSAGE_SIZE. |
| [out] | result | Voting outcome (always RTE_VOTING_AGREED or RTE_VOTING_DISAGREED - there is no I/O here, so TIMEOUT/INSUFFICIENT_QUORUM never occur, same as rte_cross_comparator_execute_buffers()). Can be NULL. |
| [out] | out_data | Receives the winning group's data on AGREED. Can be NULL. |
| [out] | out_size | Bytes written to out_data. Can be NULL. |
Definition at line 480 of file rte_voter.c.
| 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.
| [in] | voter | Voter handle. Must not be NULL. |
| [out] | healthy_count | Number of currently-healthy registered channels. Can be NULL. |
| [out] | total_disagreements | Running count of DISAGREED results returned by this voter. Can be NULL. |
Definition at line 603 of file rte_voter.c.
| uint32_t rte_voter_get_channel_count | ( | const rte_voter_t * | voter | ) |
Number of channels currently registered with this voter.
Intended for callers (e.g. rte_channel_checkpoint()) that need to iterate the voter's registered channels directly rather than through send()/receive()'s own voting.
| [in] | voter | Voter handle. Must not be NULL. |
Definition at line 622 of file rte_voter.c.
| rte_channel_t * rte_voter_get_channel | ( | const rte_voter_t * | voter, |
| uint32_t | index ) |
Direct access to one registered channel, by index.
| [in] | voter | Voter handle. Must not be NULL. |
| [in] | index | 0-based index; must be < rte_voter_get_channel_count(voter). |
Definition at line 627 of file rte_voter.c.
| rte_channel_t * rte_voter_get_channel_by_name | ( | const rte_voter_t * | voter, |
| const char * | name ) |
Direct access to one registered channel, by name (e.g. "ChannelAtoB") - the name each channel was given via rte_channel_config_t::name at its own rte_channel_init() time.
Linear search over the registered channels (channel counts here are small - RTE_VOTER_MAX_CHANNELS - so this is not a hot-path lookup by design); compares with strcmp(), so an exact, case-sensitive match is required.
| [in] | voter | Voter handle. Must not be NULL. |
| [in] | name | Name to search for. Must not be NULL. |
REQ-VOTER-006: Returns the first registered channel whose rte_channel_get_name() exactly (strcmp()) matches name; NULL if voter/name is NULL or no name matches (a channel with a NULL name is never matched, REQ-CHANNEL-005).
Definition at line 636 of file rte_voter.c.
| rte_status_t rte_voter_destroy | ( | rte_voter_t * | voter | ) |
Destroys a voter instance.
No dynamic memory to free; registered channels are NOT destroyed (caller retains ownership).
| [in] | voter | Voter handle. May be NULL. |
Definition at line 656 of file rte_voter.c.