RTE RBC 2oo2 Reference Application 0.1.0 build 0006685
SIL 4 2oo2 Dual-Site Fault-Tolerant ERTMS Radio Block Centre Reference Architecture
Loading...
Searching...
No Matches
ab_gp_status.c
Go to the documentation of this file.
1
5#include "ab_gp_status.h"
6#include "ab_gp_site_status.h"
7
8#include <stdio.h>
9#include <string.h>
10
11#include "rte/oal/log/rte_log.h"
12#include "rte/redundancy/dual/rte_dual_negotiator.h"
13
17
18/* RTE_EXAMPLE_STATUS_PERIOD_MS worth of cycles. */
19#define AB_GP_STATUS_EVERY_CYCLES \
20 ((uint32_t)RTE_EXAMPLE_STATUS_PERIOD_MS / (uint32_t)RTE_EXAMPLE_AB_CYCLE_PERIOD_MS)
21
22static uint8_t s_seq; /* per-process publish sequence, wraps */
23
25{
26 uint8_t n = 0U;
27 uint8_t i;
28
29 for (i = 0U; i < (uint8_t)RTE_EXAMPLE_MAX_TRAINS; i++)
30 {
31 if (ctx->sessions[i].in_use)
32 {
33 n++;
34 }
35 }
36 return n;
37}
38
40{
41 char payload[RBC_UTIL_PAYLOAD_MAX];
42 uint8_t frame[RBC_UTIL_FRAME_SIZE];
43 rte_dual_state_t own_state;
44 rte_dual_state_t peer_state;
45 bool peer_up;
46 uint8_t src_id;
47
48 static uint32_t s_status_last_cycle = 0U; /* one channel per process */
49
50 if (ctx == NULL)
51 {
52 return;
53 }
54 /* Not "cycle % N": the cycle number follows real time (missed ticks are counted) and is renumbered by a state
55 * transfer, so it can step by 2 or jump back, and a modulo test then never hit for a minute (Docker takeover test:
56 * no status line for 70 s after a promotion). Emit when N cycles have passed since the last one, or the number went back. */
57 if ((cycle != 1U) && (cycle >= s_status_last_cycle) && ((cycle - s_status_last_cycle) < AB_GP_STATUS_EVERY_CYCLES))
58 {
59 return;
60 }
61 s_status_last_cycle = cycle;
62
63 rte_site_role_get_negotiator_states(&ctx->site_role, &own_state, &peer_state);
64 /* Peer (A<->B within this site) considered up if it sent us an
65 * AB_SAMPLE within the last few cycles. */
66 peer_up = ((cycle - ctx->last_peer_sample_cycle) <= 3U);
67 src_id = ctx->is_role_a ? (uint8_t)RBC_UTIL_SRC_A : (uint8_t)RBC_UTIL_SRC_B;
68
69 (void)snprintf(payload, sizeof(payload),
70 "unit=%s up=1 role=%s site=%s other=%s peer=%d trains=%u single=%d",
71 ctx->role_tag,
72 ctx->is_online ? "ONLINE" : "STANDBY",
73 rte_dual_state_to_string(own_state),
74 rte_dual_state_to_string(peer_state),
75 peer_up ? 1 : 0,
76 (unsigned int)connected_train_count(ctx),
77 ctx->single_mode ? 1 : 0);
78
79 {
80 /* ADR-040 step 4b: the current takeover challenge, which the issuer MACs into this channel's token. Absent
81 * without a takeover key (interim unauthenticated path) or while no challenge is held. */
82 uint32_t challenge = 0U;
83 size_t used = strlen(payload);
84
85 if (rte_site_role_takeover_challenge(&ctx->site_role, &challenge))
86 {
87 (void)snprintf(&payload[used], sizeof(payload) - used, " tko=%08x", (unsigned int)challenge);
88 }
89 }
90
91 {
92 /* The site status monitor's view: what this channel waits for and why its role last changed. */
93 ab_gp_site_status_t site_status;
94 size_t used = strlen(payload);
95
96 ab_gp_site_status_collect(ctx, &site_status);
97 (void)ab_gp_site_status_append_text(&site_status, &payload[used], sizeof(payload) - used);
98 }
99
100 /* Self line - independent of whether the util link / broker are up. */
101 rte_log_write_event(RTE_LOG_LEVEL_INFO, site_config_name(ctx->site), cycle, ctx->role_tag, "-",
102 "STATUS", "self", payload);
103
104 /* Publish to the C-side broker over the UTIL relay (best-effort). */
105 s_seq++;
107 payload);
109 (size_t)RBC_UTIL_FRAME_SIZE);
110}
rte_status_t ab_gp_channel_send_relay(ab_gp_channel_handle_t handle, rte_example_relay_kind_t kind, uint8_t index, const uint8_t *bytes, size_t size)
Sends an envelope over a specific C relay channel.
struct ab_gp_channel_context_s * ab_gp_channel_handle_t
Opaque handle over this component's own static per-process context.
static uint8_t s_seq
size_t ab_gp_site_status_append_text(const ab_gp_site_status_t *st, char *buf, size_t size)
Appends " site_wait=<none|dispatcher|link> site_why=<short reason>" to a status payload.
void ab_gp_site_status_collect(const ab_gp_channel_context_t *ctx, ab_gp_site_status_t *out)
The site status monitor: collects, in one struct, the facts that decide and explain this channel's si...
static uint8_t connected_train_count(const ab_gp_channel_context_t *ctx)
void ab_gp_status_tick(ab_gp_channel_handle_t handle, const ab_gp_channel_context_t *ctx, uint32_t cycle)
Call once per cyclic-executive cycle from post_execute. Emits a status self line and publishes a STAT...
#define AB_GP_STATUS_EVERY_CYCLES
ADR-038: this A/B channel's periodic status - a self log line plus a PUBLISH(STATUS) rbc_util_frame_t...
#define RTE_EXAMPLE_MAX_TRAINS
ADR-038: the wire frame for the A/B<->C util side channel (RTE_EXAMPLE_RELAY_KIND_UTIL) and the C-sid...
static void rbc_util_frame_encode(uint8_t out[RBC_UTIL_FRAME_SIZE], rbc_util_msg_type_t msg_type, uint8_t source_id, uint16_t topic_id, uint8_t seq, const char *payload)
Encodes a util frame into a fixed RBC_UTIL_FRAME_SIZE buffer.
#define RBC_UTIL_FRAME_SIZE
#define RBC_UTIL_PAYLOAD_MAX
#define RBC_UTIL_TOPIC_STATUS
Topic ids (byte 2..3).
@ RBC_UTIL_SRC_B
@ RBC_UTIL_SRC_A
@ RBC_UTIL_MSG_PUBLISH
const char * site_config_name(rte_example_site_t site)
Definition site_config.c:52
West/East site identity and the per-site config derived from it (ports, container host lookup) - see ...
@ RTE_EXAMPLE_RELAY_KIND_UTIL
Definition site_config.h:48
Central application context owned by composition root (main.c).
ab_gp_train_session_t sessions[RTE_EXAMPLE_MAX_TRAINS]