9#include "rte/utils/buffer/rte_buffer.h"
10#include "rte/oal/memory/rte_mem_util.h"
12#include "common_config.h"
14#include "ga_interface.h"
28#define CTC_WIRE_HEADER_SIZE 12U
29#define CTC_WIRE_CONTENT_SIZE_BASE 24U
79static ab_gp_train_context_t g_last_train_ctx[RTE_EXAMPLE_MAX_TRAINS];
89static void ctc_wire_encode(uint8_t out[RBC_ENVELOPE_WIRE_SIZE],
const rbc_envelope_t *env);
100 uint8_t route_count, uint32_t d_lrbg, uint16_t *out_front_signal,
101 uint32_t *out_dist_to_front, uint16_t *out_target_signal);
113 rte_mem_set(&env, 0,
sizeof(env));
114 env.kind = RBC_MSG_CTC_CONNECTED;
115 env.train_id = train_id;
125 rte_mem_set(&env, 0,
sizeof(env));
126 env.kind = RBC_MSG_CTC_MA_GRANTED;
127 env.train_id = train_id;
129 env.ma_length = ma_length;
138 rte_mem_set(&env, 0,
sizeof(env));
139 env.kind = RBC_MSG_CTC_MA_EXTENDED;
140 env.train_id = train_id;
142 env.ma_length = ma_length;
150 uint32_t ma_seq, uint32_t granted_length,
bool ma_granted,
151 uint16_t front_signal, uint32_t dist_to_front_signal, uint16_t target_signal,
152 uint32_t nid_lrbg, uint32_t v_train, uint32_t m_mode)
157 rte_mem_set(&env, 0,
sizeof(env));
158 env.kind = RBC_MSG_CTC_TRAIN_INFO;
159 env.train_id = train_id;
162 env.msg_type = ma_granted ? 1U : 0U;
164 env.route_len = (uint32_t)target_signal;
166 env.t_train = (uint32_t)front_signal;
168 env.cycle = dist_to_front_signal;
170 ma_offset = (int32_t)d_lrbg - (int32_t)granted_length;
175 env.ma_length = (uint32_t)ma_offset;
177 env.nid_lrbg = nid_lrbg;
181 env.v_train = v_train;
187 ab_gp_ctc_pending_output_t out[AB_GP_CTC_MAX_PENDING_OUTPUTS])
195 for (i = 0U; i < (uint8_t)RTE_EXAMPLE_MAX_TRAINS; i++)
201 for (i = 0U; i < (uint8_t)RTE_EXAMPLE_MAX_TRAINS; i++)
203 uint8_t train_id = (uint8_t)(i + 1U);
209 ab_gp_train_context_t tctx;
211 (void)ab_gp_get_train_context(sessions, db, train_id, &tctx);
223 if (tctx.in_use && !tctx.ctc_ma_granted_sent)
226 rte_mem_copy(out[count].tag,
"CTC_CONNECTED",
sizeof(
"CTC_CONNECTED"));
238 if (tctx.ma_pending_send || tctx.ctc_ma_notify_pending)
240 if (!tctx.ctc_ma_granted_sent)
243 rte_mem_copy(out[count].tag,
"CTC_MA_GRANTED",
sizeof(
"CTC_MA_GRANTED"));
250 rte_mem_copy(out[count].tag,
"CTC_MA_EXTENDED",
sizeof(
"CTC_MA_EXTENDED"));
255 AB_GA_CHECKPOINT_MARK();
269 const ab_gp_train_context_t *ctx = &g_last_train_ctx[i];
270 uint16_t front_signal = 0U;
271 uint32_t dist_to_front = 0U;
272 uint16_t target_signal = 0U;
273 bool ma_granted = ctx->has_ma;
278 ma_granted, front_signal, dist_to_front, target_signal, ctx->nid_lrbg,
279 ctx->v_train, ctx->m_mode);
280 rte_mem_copy(out[count].tag,
"CTC_TRAIN_INFO",
sizeof(
"CTC_TRAIN_INFO"));
292 for (i = 0U; i < (uint8_t)RTE_EXAMPLE_MAX_TRAINS; i++)
294 uint8_t train_id = (uint8_t)(i + 1U);
298 if (sessions != NULL)
300 (void)ab_gp_train_session_set_ctc_connected_sent(sessions, train_id,
true);
306 if (sessions != NULL)
308 (void)ab_gp_train_session_set_ctc_ma_granted_sent(sessions, train_id,
true);
329 if (update_type != AB_ROUTE_CONNECTED)
333 RTE_EXAMPLE_LOG(
"[%s] CTC notified: route %u connected to train %u\n",
g_ga_role_tag,
334 (
unsigned int)ctx->id, (
unsigned int)ctx->train_id);
341 bool nid_lrbg_changed;
342 bool v_train_changed;
344 bool granted_length_changed;
349 if ((ctx->train_id == 0U) || (ctx->train_id > (uint8_t)RTE_EXAMPLE_MAX_TRAINS))
353 idx = (uint8_t)(ctx->train_id - 1U);
395 g_last_train_ctx[idx] = *ctx;
401 d_lrbg_changed = (ctx->d_lrbg != g_last_train_ctx[idx].d_lrbg);
402 nid_lrbg_changed = (ctx->nid_lrbg != g_last_train_ctx[idx].nid_lrbg);
403 v_train_changed = (ctx->v_train != g_last_train_ctx[idx].v_train);
404 m_mode_changed = (ctx->m_mode != g_last_train_ctx[idx].m_mode);
405 granted_length_changed = (ctx->granted_length != g_last_train_ctx[idx].granted_length);
406 ma_seq_changed = (ctx->ma_seq != g_last_train_ctx[idx].ma_seq);
407 has_ma_changed = (ctx->has_ma != g_last_train_ctx[idx].has_ma);
409 g_last_train_ctx[idx] = *ctx;
410 if (d_lrbg_changed || nid_lrbg_changed || v_train_changed || m_mode_changed || granted_length_changed ||
411 ma_seq_changed || has_ma_changed)
425 uint8_t route_count, uint32_t d_lrbg, uint16_t *out_front_signal,
426 uint32_t *out_dist_to_front, uint16_t *out_target_signal)
428 uint32_t cumulative = 0U;
429 bool front_found =
false;
433 *out_front_signal = 0U;
434 *out_dist_to_front = 0U;
435 *out_target_signal = 0U;
437 if (route_count == 0U)
447 for (visited = 0U; visited < route_count; visited++)
450 bool prev_is_held =
false;
457 for (j = 0U; j < route_count; j++)
466 cur_id = route_ids[visited];
475 for (visited = 0U; (visited < route_count) && (cur_id != 0U); visited++)
486 boundary = cumulative + rt->
length_m;
487 if (!front_found && (d_lrbg < boundary))
490 *out_dist_to_front = boundary - d_lrbg;
494 cumulative = boundary;
497 for (j = 0U; j < route_count; j++)
501 next_id = route_ids[j];
513 *out_front_signal = *out_target_signal;
514 *out_dist_to_front = 0U;
518static void ctc_wire_encode(uint8_t out[RBC_ENVELOPE_WIRE_SIZE],
const rbc_envelope_t *env)
538 bool is_train_info = (env->kind == RBC_MSG_CTC_TRAIN_INFO);
541 uint16_t l_message = is_train_info ? 76U : (uint16_t)(
CTC_WIRE_HEADER_SIZE + CTC_WIRE_CONTENT_SIZE_BASE);
543 rte_mem_set(out, 0, RBC_ENVELOPE_WIRE_SIZE);
544 (void)rte_buffer_init(&buf, out, RBC_ENVELOPE_WIRE_SIZE);
545 out[0] = (uint8_t)env->kind;
546 out[1] = env->train_id;
549 (void)rte_buffer_set_length(&buf, 4U);
550 (void)rte_buffer_write_u16_le(&buf, l_message);
551 (void)rte_buffer_write_u16_le(&buf, 0U);
552 (void)rte_buffer_write_u32_le(&buf, env->t_train);
554 (void)rte_buffer_write_u32_le(&buf, env->cycle);
557 (void)rte_buffer_write_u32_le(&buf, env->d_lrbg);
558 (void)rte_buffer_write_u32_le(&buf, env->msg_type);
560 (void)rte_buffer_write_u32_le(&buf, env->route_len);
562 (void)rte_buffer_write_u32_le(&buf, env->ma_seq);
564 (void)rte_buffer_write_u32_le(&buf, env->ma_length);
568 (void)rte_buffer_set_length(&buf, 40U);
569 (void)rte_buffer_write_u32_le(&buf, env->nid_lrbg);
572 (void)rte_buffer_set_length(&buf, 64U);
573 (void)rte_buffer_write_u32_le(&buf, env->v_train);
575 (void)rte_buffer_set_length(&buf, 72U);
576 (void)rte_buffer_write_u32_le(&buf, env->m_mode);
void ab_ga_ctc_build_connected(uint8_t out[RBC_ENVELOPE_WIRE_SIZE], uint8_t train_id, uint32_t d_lrbg)
Builds and wire-encodes the outbound CTC_CONNECTED indication for train_id (kind=RBC_MSG_CTC_CONNECTE...
void ab_ga_ctc_build_ma_granted(uint8_t out[RBC_ENVELOPE_WIRE_SIZE], uint8_t train_id, uint32_t ma_seq, uint32_t ma_length)
Builds and wire-encodes the outbound CTC_MA_GRANTED indication for train_id (kind=RBC_MSG_CTC_MA_GRAN...
static bool g_ma_granted_built[RTE_EXAMPLE_MAX_TRAINS]
static void ctc_wire_encode(uint8_t out[RBC_ENVELOPE_WIRE_SIZE], const rbc_envelope_t *env)
void ab_ga_ctc_build_train_info(uint8_t out[RBC_ENVELOPE_WIRE_SIZE], uint8_t train_id, uint32_t d_lrbg, uint32_t ma_seq, uint32_t granted_length, bool ma_granted, uint16_t front_signal, uint32_t dist_to_front_signal, uint16_t target_signal, uint32_t nid_lrbg, uint32_t v_train, uint32_t m_mode)
Builds and wire-encodes a severity-leveled operational alarm (kind=RBC_MSG_CTC_ALARM) directly into o...
void ab_ga_ctc_confirm_outputs_sent(ab_gp_train_session_t *sessions)
Consumes what the immediately-preceding ab_ga_ctc_build_outputs() call actually included in its own o...
static bool g_train_info_pending[RTE_EXAMPLE_MAX_TRAINS]
#define CTC_WIRE_HEADER_SIZE
static void compute_train_info_signals(const uint16_t route_ids[RTE_EXAMPLE_MAX_ROUTES_PER_TRAIN], uint8_t route_count, uint32_t d_lrbg, uint16_t *out_front_signal, uint32_t *out_dist_to_front, uint16_t *out_target_signal)
static bool g_train_info_built[RTE_EXAMPLE_MAX_TRAINS]
static bool g_connected_built[RTE_EXAMPLE_MAX_TRAINS]
void ab_ga_ctc_on_train_context_changed(const ab_gp_train_context_t *ctx, ab_gp_train_update_type_t update_type)
GA's dispatch module fans every train-context change here - stores the received snapshot and marks th...
uint8_t ab_ga_ctc_build_outputs(const ab_gp_train_session_t *sessions, ab_gp_db_t *db, ab_gp_ctc_pending_output_t out[AB_GP_CTC_MAX_PENDING_OUTPUTS])
Decides which trains need a CTC indication THIS cycle and builds all of them - see this file's own mo...
void ab_ga_ctc_build_ma_extended(uint8_t out[RBC_ENVELOPE_WIRE_SIZE], uint8_t train_id, uint32_t ma_seq, uint32_t ma_length)
Builds and wire-encodes the outbound CTC_MA_EXTENDED indication for train_id (kind=RBC_MSG_CTC_MA_EXT...
static bool g_train_ctx_known[RTE_EXAMPLE_MAX_TRAINS]
void ab_ga_ctc_on_route_context_changed(const ab_gp_route_context_t *ctx, ab_gp_route_update_type_t update_type)
GA's single dispatch module (safeAPIRBC2oo2GA/src/AB/main/ ab_ga_dispatch.c) is the ONLY thing that r...
A/B's own outbound messages to CtcRBCSim. Two layers, same split as AB/GP/train/ab_gp_train....
GA's own site data: route composition, built from GP's raw physical elements (railML interlocking <ro...
const ab_site_ga_route_layout_t * ab_site_ga_get_route(uint16_t route_id)
Looks up a route by its ID.
One route's static layout entry (railML interlocking <route>) - GA's own full definition (not a reduc...