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_ga_hooks.c
Go to the documentation of this file.
1
14#include "ab_gp_ga_hooks.h"
15
16#include "rte/utils/buffer/rte_buffer.h"
17#include "rte/utils/lifecycle/rte_lifecycle.h"
18#include "rte/utils/notify/rte_notify.h"
19#include "rte/oal/memory/rte_mem_util.h"
20
21#include "rbc_wire_types.h" /* rbc_envelope_t, RBC_MSG_CTC_ALARM, rbc_alarm_severity_t */
22
25RTE_DECLARE_CALLBACK_LIST(ab_gp_il_envelope_handler_list_t, ab_gp_il_envelope_handler_fn, 1U);
26static ab_gp_il_envelope_handler_list_t g_il_envelope_handler;
27
29{
30 rte_status_t lifecycle_status;
31
32 if (fn == NULL)
33 {
34 return RTE_STATUS_INVALID_PARAM;
35 }
36 lifecycle_status = rte_lifecycle_check_setup_allowed();
37 if (lifecycle_status != RTE_STATUS_OK)
38 {
39 return lifecycle_status;
40 }
41 if (g_il_envelope_handler.count >= 1U)
42 {
43 return RTE_STATUS_RESOURCE_EXHAUSTED;
44 }
45 g_il_envelope_handler.slots[0].fn = fn;
46 g_il_envelope_handler.slots[0].context = (void *)context; /* see
47 AB/GP/ma_logic/ab_gp_logic.c's own identical cast for why this is safe */
48 g_il_envelope_handler.count = 1U;
49 return RTE_STATUS_OK;
50}
51
53 const uint8_t env_bytes[RBC_ENVELOPE_WIRE_SIZE], uint32_t cycle,
54 rte_example_site_t site, const char *role_tag)
55{
56 if ((g_il_envelope_handler.count == 0U) || (g_il_envelope_handler.slots[0].fn == NULL))
57 {
58 return false;
59 }
60 return g_il_envelope_handler.slots[0].fn(g_il_envelope_handler.slots[0].context, sessions, db, env_bytes, cycle,
61 site, role_tag);
62}
63
64
67RTE_DECLARE_CALLBACK_LIST(ab_gp_il_output_producer_list_t, ab_gp_il_output_producer_fn, 1U);
68static ab_gp_il_output_producer_list_t g_il_output_producer;
69/* Plain static, not part of the macro-generated slot struct above (that
70 * struct's own shape is fixed to one function-pointer type) - see
71 * ab_gp_il_output_confirm_fn's own doc, ga_interface.h, for why this
72 * exists and must only be invoked once a build's outputs are confirmed
73 * forwarded. */
75
77 const void *context)
78{
79 rte_status_t lifecycle_status;
80
81 if (fn == NULL)
82 {
83 return RTE_STATUS_INVALID_PARAM;
84 }
85 lifecycle_status = rte_lifecycle_check_setup_allowed();
86 if (lifecycle_status != RTE_STATUS_OK)
87 {
88 return lifecycle_status;
89 }
90 if (g_il_output_producer.count >= 1U)
91 {
92 return RTE_STATUS_RESOURCE_EXHAUSTED;
93 }
94 g_il_output_producer.slots[0].fn = fn;
95 g_il_output_producer.slots[0].context = (void *)context;
96 g_il_output_producer.count = 1U;
97 g_il_output_confirm_fn = confirm_fn;
98 return RTE_STATUS_OK;
99}
100
102{
103 if ((g_il_output_producer.count == 0U) || (g_il_output_producer.slots[0].fn == NULL))
104 {
105 return 0U;
106 }
107 return g_il_output_producer.slots[0].fn(g_il_output_producer.slots[0].context, out);
108}
109
111{
112 if ((g_il_output_producer.count != 0U) && (g_il_output_confirm_fn != NULL))
113 {
115 }
116}
117
118
121RTE_DECLARE_CALLBACK_LIST(ab_gp_ctc_output_producer_list_t, ab_gp_ctc_output_producer_fn, 1U);
122static ab_gp_ctc_output_producer_list_t g_ctc_output_producer;
123/* Same reasoning as g_il_output_confirm_fn above. */
125
127 ab_gp_ctc_output_confirm_fn confirm_fn, const void *context)
128{
129 rte_status_t lifecycle_status;
130
131 if (fn == NULL)
132 {
133 return RTE_STATUS_INVALID_PARAM;
134 }
135 lifecycle_status = rte_lifecycle_check_setup_allowed();
136 if (lifecycle_status != RTE_STATUS_OK)
137 {
138 return lifecycle_status;
139 }
140 if (g_ctc_output_producer.count >= 1U)
141 {
142 return RTE_STATUS_RESOURCE_EXHAUSTED;
143 }
144 g_ctc_output_producer.slots[0].fn = fn;
145 g_ctc_output_producer.slots[0].context = (void *)context;
146 g_ctc_output_producer.count = 1U;
147 g_ctc_output_confirm_fn = confirm_fn;
148 return RTE_STATUS_OK;
149}
150
152{
153 if ((g_ctc_output_producer.count == 0U) || (g_ctc_output_producer.slots[0].fn == NULL))
154 {
155 return 0U;
156 }
157 return g_ctc_output_producer.slots[0].fn(g_ctc_output_producer.slots[0].context, out);
158}
159
161{
162 if ((g_ctc_output_producer.count != 0U) && (g_ctc_output_confirm_fn != NULL))
163 {
165 }
166}
167
168
179#define AB_GP_CTC_ALARM_WIRE_HEADER_SIZE 12U
180#define AB_GP_CTC_ALARM_WIRE_L_MESSAGE 36U /* header(12) + base content(24), matching every non-TRAIN_INFO
181 * CTC_* kind's own l_message - see ab_ga_ctc.c's own
182 * CTC_WIRE_HEADER_SIZE/CTC_WIRE_CONTENT_SIZE_BASE. */
183
184void ab_gp_build_ctc_alarm(uint8_t out[RBC_ENVELOPE_WIRE_SIZE], rbc_alarm_severity_t severity, uint32_t code,
185 uint32_t cycle, uint32_t timestamp_ms)
186{
187 rte_buffer_t buf;
188
189 rte_mem_set(out, 0, RBC_ENVELOPE_WIRE_SIZE);
190 (void)rte_buffer_init(&buf, out, RBC_ENVELOPE_WIRE_SIZE);
191 out[0] = (uint8_t)RBC_MSG_CTC_ALARM;
192 out[1] = 0U; /* no train_id - an alarm is channel/site-level, not about one train */
193 out[2] = 0U; /* no real Subset-026 nid_message for any CTC_* kind */
194 out[3] = 0U; /* reserved */
195 (void)rte_buffer_set_length(&buf, 4U);
196 (void)rte_buffer_write_u16_le(&buf, (uint16_t)AB_GP_CTC_ALARM_WIRE_L_MESSAGE); /* offset 4-5 */
197 (void)rte_buffer_write_u16_le(&buf, 0U); /* offset 6-7, reserved */
198 (void)rte_buffer_write_u32_le(&buf, timestamp_ms); /* offset 8-11 */
199 (void)rte_buffer_write_u32_le(&buf, cycle); /* offset 12-15 */
200 (void)rte_buffer_write_u32_le(&buf, 0U); /* offset 16-19, d_lrbg - N/A */
201 (void)rte_buffer_write_u32_le(&buf, (uint32_t)severity); /* offset 20-23 */
202 (void)rte_buffer_write_u32_le(&buf, 0U); /* offset 24-27, N/A */
203 (void)rte_buffer_write_u32_le(&buf, code); /* offset 28-31 */
204 (void)rte_buffer_write_u32_le(&buf, 0U); /* offset 32-35, N/A */
205}
206
RTE_DECLARE_CALLBACK_LIST(ab_gp_db_route_context_list_t, ab_gp_route_context_notify_fn, AB_GP_DB_MAX_ROUTE_CONTEXT_SUBSCRIBERS)
bool ab_gp_dispatch_il_envelope(ab_gp_train_session_t *sessions, ab_gp_db_t *db, const uint8_t env_bytes[RBC_ENVELOPE_WIRE_SIZE], uint32_t cycle, rte_example_site_t site, const char *role_tag)
Calls the registered IL envelope handler, if any - see ab_gp_register_il_envelope_handler()'s own doc...
#define AB_GP_CTC_ALARM_WIRE_L_MESSAGE
static ab_gp_il_output_producer_list_t g_il_output_producer
uint8_t ab_gp_drain_ctc_outputs(ab_gp_ctc_pending_output_t out[AB_GP_CTC_MAX_PENDING_OUTPUTS])
Calls the registered CTC output producer, if any - see ab_gp_register_ctc_output_producer()'s own doc...
static ab_gp_ctc_output_confirm_fn g_ctc_output_confirm_fn
static ab_gp_ctc_output_producer_list_t g_ctc_output_producer
void ab_gp_confirm_il_outputs_sent(void)
Calls the registered IL output producer's own confirm callback, if any - see ab_gp_il_output_confirm_...
static ab_gp_il_output_confirm_fn g_il_output_confirm_fn
void ab_gp_confirm_ctc_outputs_sent(void)
Calls the registered CTC output producer's own confirm callback, if any - same contract as ab_gp_conf...
void ab_gp_build_ctc_alarm(uint8_t out[RBC_ENVELOPE_WIRE_SIZE], rbc_alarm_severity_t severity, uint32_t code, uint32_t cycle, uint32_t timestamp_ms)
Builds and wire-encodes an outbound CTC_ALARM envelope - GP's own now (moved from GA,...
static ab_gp_il_envelope_handler_list_t g_il_envelope_handler
uint8_t ab_gp_drain_il_outputs(ab_gp_il_pending_output_t out[AB_GP_IL_MAX_PENDING_OUTPUTS])
Calls the registered IL output producer, if any - see ab_gp_register_il_output_producer()'s own doc,...
GP's own dispatch side of the "GP calls into GA" surface - see ga_interface.h's own "functions GP cal...
#define RBC_ENVELOPE_WIRE_SIZE
bool(*) ab_gp_il_envelope_handler_fn(const void *context, ab_gp_train_session_t *sessions, ab_gp_db_t *db, const uint8_t env_bytes[RBC_ENVELOPE_WIRE_SIZE], uint32_t cycle, rte_example_site_t site, const char *role_tag)
uint8_t(*) ab_gp_ctc_output_producer_fn(const void *context, ab_gp_ctc_pending_output_t out[AB_GP_CTC_MAX_PENDING_OUTPUTS])
void(*) ab_gp_il_output_confirm_fn(const void *context)
#define AB_GP_IL_MAX_PENDING_OUTPUTS
uint8_t(*) ab_gp_il_output_producer_fn(const void *context, ab_gp_il_pending_output_t out[AB_GP_IL_MAX_PENDING_OUTPUTS])
void(*) ab_gp_ctc_output_confirm_fn(const void *context)
#define AB_GP_CTC_MAX_PENDING_OUTPUTS
rte_status_t ab_gp_register_ctc_output_producer(ab_gp_ctc_output_producer_fn fn, ab_gp_ctc_output_confirm_fn confirm_fn, const void *context)
rte_status_t ab_gp_register_il_output_producer(ab_gp_il_output_producer_fn fn, ab_gp_il_output_confirm_fn confirm_fn, const void *context)
rte_status_t ab_gp_register_il_envelope_handler(ab_gp_il_envelope_handler_fn fn, const void *context)
The RBC Train/IL/CTC scenario's shared wire envelope (ADR-029) - one fixed-size struct/frame reused f...
rbc_alarm_severity_t
Severity of an RBC_MSG_CTC_ALARM envelope (msg_type field on the wire) - deliberately a small,...
@ RBC_MSG_CTC_ALARM
rte_example_site_t
Definition site_config.h:20