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

Application-level redundancy topology configuration (2oo2 / 2oo2 with redundancy / 2oo3 / NMR), loaded from a small JSON file at startup. More...

#include <stdint.h>
#include <stdbool.h>
#include "rte/utils/status/rte_status.h"
#include "rte/redundancy/voter/rte_voter.h"
Include dependency graph for rte_redundancy_config.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  rte_channel_def_t
struct  rte_redundancy_config_t

Macros

#define RTE_REDUNDANCY_CONFIG_MAX_ROLE_NAME_LEN   16U
#define RTE_REDUNDANCY_CONFIG_MAX_REPLICAS   5U
#define RTE_REDUNDANCY_CONFIG_MAX_FILE_SIZE   8192U
#define RTE_CHANNEL_CONFIG_MAX_CHANNELS   32U
#define RTE_CHANNEL_CONFIG_MAX_NAME_LEN   32U
#define RTE_CHANNEL_CONFIG_MAX_HOST_LEN   64U

Typedefs

typedef bool(*) rte_redundancy_capability_fn(rte_redundancy_topology_t topology, uint32_t replica_count, void *context)
 Integrator-supplied capability query: can THIS application actually run the given topology/replica_count combination? This is how an integrator (e.g. RBC_GP) declares what it supports to the Platform, instead of the Platform (or the integrator's own call site) hardcoding a topology allowlist - matches OCORA's own "Platform decides" posture already used throughout this module and rte_voter/rte_cross_comparator's own safestate-transition ownership.

Enumerations

enum  rte_channel_transport_t { RTE_CHANNEL_TRANSPORT_FLOW = 0 , RTE_CHANNEL_TRANSPORT_POSIX_NETLINK = 1 , RTE_CHANNEL_TRANSPORT_DDS = 2 }
enum  rte_channel_role_t { RTE_CHANNEL_ROLE_LISTEN = 0 , RTE_CHANNEL_ROLE_CONNECT = 1 }
enum  rte_redundancy_topology_t { RTE_REDUNDANCY_TOPOLOGY_2OO2 = 0 , RTE_REDUNDANCY_TOPOLOGY_2OO2_REDUNDANT = 1 , RTE_REDUNDANCY_TOPOLOGY_2OO3 = 2 , RTE_REDUNDANCY_TOPOLOGY_NMR = 3 }
enum  rte_standby_mode_t { RTE_STANDBY_MODE_HOT = 0 , RTE_STANDBY_MODE_WARM = 1 , RTE_STANDBY_MODE_COLD = 2 }
 How a non-active replica ("standby") keeps itself ready to take over, and how rte_state_transfer (redundancy/state_transfer/ rte_state_transfer.h) gets used, if at all. This is a CADENCE policy only - it says nothing about WHAT data is registered (that stays the integrator's own rte_state_transfer_register_field() calls) or how a promotion is detected (that stays e.g. rte_dual_negotiator_t's own job). More...

Functions

rte_status_t rte_redundancy_config_standby_mode_from_string (const char *name, rte_standby_mode_t *out_mode)
 Parse a standby-mode name string ("hot", "warm", "cold") into its enum value.
const char * rte_redundancy_config_standby_mode_to_string (rte_standby_mode_t mode)
 Inverse of rte_redundancy_config_standby_mode_from_string() - for logging/diagnostics.
rte_status_t rte_redundancy_config_topology_from_string (const char *name, rte_redundancy_topology_t *out_topology)
 Parse a topology name string ("2oo2", "2oo2_redundant", "2oo3", "nmr") into its enum value.
const char * rte_redundancy_config_topology_to_string (rte_redundancy_topology_t topology)
 Inverse of rte_redundancy_config_topology_from_string() - for logging/diagnostics.
rte_status_t rte_redundancy_config_register_capability (rte_redundancy_capability_fn fn, void *context)
 Registers the capability callback rte_redundancy_config_load() consults after successfully parsing a file, before returning RTE_STATUS_OK. Call once at startup, before load(). No callback registered (the default) means load() accepts any successfully-parsed, internally-consistent config - the same behavior this module had before this function existed.
rte_status_t rte_redundancy_config_load (const char *path, rte_redundancy_config_t *out_config)
 Load a redundancy topology config from a JSON file.
rte_status_t rte_redundancy_config_apply_to_voter (const rte_redundancy_config_t *config, rte_voter_config_t *voter_cfg)
 Copy the resolved quorum from a loaded redundancy config into a rte_voter_config_t, leaving every other field of voter_cfg untouched (compare()/context/timeouts/safestate fields remain the caller's own responsibility to set).
rte_status_t rte_channel_config_transport_from_string (const char *name, rte_channel_transport_t *out_transport)
 Parse transport name string ("flow", "netlink", "posix", "dds") into enum.
rte_status_t rte_channel_config_role_from_string (const char *name, rte_channel_role_t *out_role)
 Parse channel role name string ("listen", "connect", "publisher", "subscriber") into enum.
rte_status_t rte_redundancy_config_find_channel_by_name (const rte_redundancy_config_t *config, const char *name, rte_channel_def_t *out_channel)
 Find channel definition by name in the given configuration.
rte_status_t rte_redundancy_config_find_channel_by_id (const rte_redundancy_config_t *config, uint32_t id, rte_channel_def_t *out_channel)
 Find channel definition by ID in the given configuration.
const rte_redundancy_config_t * rte_redundancy_config_get_active (void)
 Get the currently active loaded redundancy/channel configuration (if any).
void rte_redundancy_config_set_active (const rte_redundancy_config_t *config)
 Set the active configuration explicitly (or automatically by rte_redundancy_config_load).

Detailed Description

Application-level redundancy topology configuration (2oo2 / 2oo2 with redundancy / 2oo3 / NMR), loaded from a small JSON file at startup.

Added per direct request as part of the RCA/OCORA compatibility initiative (see docs/rca/ at the workspace root, and TODO.dox's "Platform (RCA/OCORA)" section). OCORA's own Safe Computing Platform model treats voting topology (how many Replicas, what quorum) as a Platform-level concern the Functional Application does not hardcode - this module is that Platform-level piece: an integrator (e.g. RBC_GP) reads its intended topology from a deployment-time JSON file instead of a compiled-in constant, then hands the resolved quorum to rte_voter's own config (rte_redundancy_config_apply_to_voter()).

This module does NOT create channels or replicas itself - it only resolves "what topology, how many replicas, what quorum" from a file. Registering the actual rte_channel_t links for each replica remains the integrator's job (transport/addressing is deployment-specific, not something a generic redundancy-topology file can express).

JSON format (flat, fixed shape - this is a hand-rolled scanner for exactly this schema, not a general JSON parser; a SIL4/MISRA C99 static library avoids pulling in a third-party JSON library the same way safecomm_config_load avoids one for its own "key = value" files):

{
"topology": "2oo3",
"replicas": 3,
"quorum": 2,
"roles": ["A", "B", "C"]
}

"quorum" and "roles" are optional. When "quorum" is absent, a topology-based default is used (see rte_redundancy_config_load()'s own doc). Key order in the file does not matter; unrecognized keys are ignored.

An optional "channels" array holds flat channel objects (rte_channel_def_t):

"channels": [
{ "id": 1, "name": "ab-peer", "transport": "netlink", "role": "listen",
"host": "127.0.0.1", "port": 15001, "message_size": 384,
"connect_timeout_ms": 1000, "rcvbuf_bytes": 262144, "sndbuf_bytes": 262144 }
]

"rcvbuf_bytes" and "sndbuf_bytes" are optional socket buffer sizes in bytes (0 or absent = OS default). Unlike the older numeric channel keys, a value that is not a plain unsigned decimal integer, or is above UINT32_MAX, fails the whole load (REQ-REDCFG-001).

Definition in file rte_redundancy_config.h.