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
rbc_wire_types.h
Go to the documentation of this file.
1#ifndef RTE_EXAMPLE_RBC_WIRE_TYPES_H
2#define RTE_EXAMPLE_RBC_WIRE_TYPES_H
3
44
45#include <stdbool.h>
46#include <stdint.h>
47#include "rte/oal/memory/rte_mem_util.h"
48
49#include "common_config.h"
50
273
274/* ========================================================================= */
275/* IL <-> RBC interface enums (dedicated IL messages 25/26/27) */
276/* All carried on the wire as a single uint8 unless noted; identity fields */
277/* (route_id/start_signal/end_signal/allocated_train_nid_engine) are int32 */
278/* little-endian with -1 as the "unset" sentinel. */
279/* ========================================================================= */
280
290
302
312
320
330
342
356
365
371typedef struct
372{
375 uint8_t train_id;
377 uint8_t nid_message;
386 uint16_t l_message;
392 uint32_t t_train;
395 uint32_t cycle;
397 uint32_t d_lrbg;
398 uint32_t msg_type;
399 uint32_t route_len;
400 uint32_t ma_seq;
401 uint32_t ma_length;
402 uint32_t t_train_ack;
408 /* M136 only (REQ-RBC-001 revised): real Subset-026 Packet 0 "Position
409 * Report" fields (SUBSET-026-7 section 7.4.3.1) - genuinely flat, no
410 * N_ITER/nesting, so addable the same additive way as t_train_ack
411 * above. d_lrbg (already existed) is that packet's own D_LRBG; these
412 * ten are the rest of it. 0 when kind != RBC_MSG_M136 (not present on
413 * the wire at all then - l_message says so). Real bit-widths are much
414 * narrower than uint32 (e.g. Q_DIRLRBG is 2 bits, M_MODE is 4 bits) -
415 * kept byte-aligned uint32 here for consistency with every other
416 * field in this struct, not bit-packed - see this file's own header
417 * for why (touching the 20+ rte_netlink_send()/_recv() call sites
418 * for genuinely narrower transmitted fields is out of scope here). */
419 uint32_t nid_lrbg;
420 uint32_t q_dirlrbg;
421 uint32_t q_dlrbg;
422 uint32_t l_doubtover;
423 uint32_t l_doubtunder;
424 uint32_t q_length;
425 uint32_t v_train;
426 uint32_t q_dirtrain;
427 uint32_t m_mode;
428 uint32_t m_level;
429 /* ROUTE_ADD/ROUTE_RELEASE/TRAIN_POSITION_IN_ROUTE only - appended
430 * after the M136 block above, same additive-growth precedent
431 * t_train_ack/the M136 block itself already set (this struct has
432 * been grown this way twice before; never by repurposing an existing
433 * field's meaning for a different kind). Route identity on the wire
434 * is (start_signal, end_signal) - the signal pair a route runs
435 * between (safeAPIRBC2oo2GA/include/ab_siteGA.h's own ab_site_ga_route_layout_t (route topology moved out of GP this session)), not a
436 * synthetic id - ROUTE_ADD/ROUTE_RELEASE both carry it; the RBC side
437 * resolves it to its own internal route_id via
438 * ab_ga_il_site_has_route_by_signals() before touching db->routes[].
439 * 0 when kind doesn't use a given field (not present on the wire at
440 * all then - l_message says so, same convention as every field
441 * above). */
442 uint32_t start_signal;
444 uint32_t end_signal;
446 uint32_t route_type;
448 uint32_t route_status;
451
458{
459 rte_mem_set(out, 0, RBC_ENVELOPE_WIRE_SIZE);
460 out[0] = (uint8_t)RBC_MSG_RELAY_KEEPALIVE;
461}
462
469static inline bool rbc_envelope_is_keepalive(const uint8_t in[RBC_ENVELOPE_WIRE_SIZE])
470{
471 return in[0] == (uint8_t)RBC_MSG_RELAY_KEEPALIVE;
472}
473
479static inline void rbc_envelope_write_set_log_level(uint8_t out[RBC_ENVELOPE_WIRE_SIZE], uint8_t level)
480{
481 rte_mem_set(out, 0, RBC_ENVELOPE_WIRE_SIZE);
482 out[0] = (uint8_t)RBC_MSG_SET_LOG_LEVEL;
483 out[1] = level;
484}
485
490static inline bool rbc_envelope_is_set_log_level(const uint8_t in[RBC_ENVELOPE_WIRE_SIZE], uint8_t *out_level)
491{
492 bool match = (in[0] == (uint8_t)RBC_MSG_SET_LOG_LEVEL);
493
494 if (match && (out_level != NULL))
495 {
496 *out_level = in[1];
497 }
498 return match;
499}
500
508static inline void rbc_envelope_write_sim_status(uint8_t out[RBC_ENVELOPE_WIRE_SIZE], const char *payload)
509{
510 uint16_t n = 0U;
511
512 rte_mem_set(out, 0, RBC_ENVELOPE_WIRE_SIZE);
513 out[0] = (uint8_t)RBC_MSG_SIM_STATUS;
514 if (payload != NULL)
515 {
516 while ((n < (uint16_t)(RBC_ENVELOPE_WIRE_SIZE - 2U)) && (payload[n] != '\0'))
517 {
518 out[2U + n] = (uint8_t)payload[n];
519 n++;
520 }
521 }
522 out[1] = (uint8_t)n;
523}
524
529static inline bool rbc_envelope_is_sim_status(const uint8_t in[RBC_ENVELOPE_WIRE_SIZE], char *out_payload,
530 uint16_t out_size)
531{
532 uint16_t n;
533 uint16_t i;
534
535 if (in[0] != (uint8_t)RBC_MSG_SIM_STATUS)
536 {
537 return false;
538 }
539 if ((out_payload != NULL) && (out_size > 0U))
540 {
541 n = (uint16_t)in[1];
542 if (n > (uint16_t)(RBC_ENVELOPE_WIRE_SIZE - 2U))
543 {
544 n = (uint16_t)(RBC_ENVELOPE_WIRE_SIZE - 2U);
545 }
546 if (n > (uint16_t)(out_size - 1U))
547 {
548 n = (uint16_t)(out_size - 1U);
549 }
550 for (i = 0U; i < n; i++)
551 {
552 out_payload[i] = (char)in[2U + i];
553 }
554 out_payload[n] = '\0';
555 }
556 return true;
557}
558
610#define RBC_ENVELOPE_QUEUE_CAPACITY 16U
611
612typedef struct
613{
614 volatile uint32_t write_index; /* producer-owned - see this struct's own doc */
615 volatile uint32_t read_index; /* consumer-owned */
618
620{
621 queue->write_index = 0U;
622 queue->read_index = 0U;
623}
624
628static inline bool rbc_envelope_queue_push(rbc_envelope_queue_t *queue, const uint8_t bytes[RBC_ENVELOPE_WIRE_SIZE])
629{
630 uint32_t w = queue->write_index;
631 uint32_t r = queue->read_index;
632
633 if ((w - r) >= (uint32_t)RBC_ENVELOPE_QUEUE_CAPACITY)
634 {
635 return false;
636 }
637 rte_mem_copy(queue->entries[w % (uint32_t)RBC_ENVELOPE_QUEUE_CAPACITY], bytes, RBC_ENVELOPE_WIRE_SIZE);
638 queue->write_index = w + 1U;
639 return true;
640}
641
647static inline bool rbc_envelope_queue_pop(rbc_envelope_queue_t *queue, uint8_t out_bytes[RBC_ENVELOPE_WIRE_SIZE])
648{
649 uint32_t w = queue->write_index;
650 uint32_t r = queue->read_index;
651
652 if (r == w)
653 {
654 return false;
655 }
656 rte_mem_copy(out_bytes, queue->entries[r % (uint32_t)RBC_ENVELOPE_QUEUE_CAPACITY], RBC_ENVELOPE_WIRE_SIZE);
657 queue->read_index = r + 1U;
658 return true;
659}
660
661#endif /* RTE_EXAMPLE_RBC_WIRE_TYPES_H */
#define RBC_ENVELOPE_WIRE_SIZE
static bool rbc_envelope_is_set_log_level(const uint8_t in[RBC_ENVELOPE_WIRE_SIZE], uint8_t *out_level)
true if in is a set-log-level control frame; *out_level (if non-NULL) then receives the requested lev...
rbc_il_status_t
RBC_MSG_IL_STATUS.il_status - IL process health.
@ RBC_IL_STATUS_DOWN
@ RBC_IL_STATUS_RESTARTING
@ RBC_IL_STATUS_UP
static bool rbc_envelope_is_sim_status(const uint8_t in[RBC_ENVELOPE_WIRE_SIZE], char *out_payload, uint16_t out_size)
true if in is a sim-status frame; when it is and out_payload is non-NULL, copies the ASCII payload th...
static bool rbc_envelope_queue_push(rbc_envelope_queue_t *queue, const uint8_t bytes[RBC_ENVELOPE_WIRE_SIZE])
#define RBC_ENVELOPE_QUEUE_CAPACITY
Fixed-capacity single-producer/single-consumer envelope queue - REQ-RBC-003. Unlike the M136/ANSWER s...
rbc_alarm_severity_t
Severity of an RBC_MSG_CTC_ALARM envelope (msg_type field on the wire) - deliberately a small,...
@ RBC_ALARM_SEVERITY_WARNING
@ RBC_ALARM_SEVERITY_INFO
@ RBC_ALARM_SEVERITY_ERROR
rbc_msg_kind_t
Which of this envelope's fields are meaningful, and which direction it travels - see this file's own ...
@ RBC_MSG_M146
@ RBC_MSG_CTC_ALARM
@ RBC_MSG_M24_M15
@ RBC_MSG_M136
@ RBC_MSG_RELAY_KEEPALIVE
@ RBC_MSG_TSR_ADD
@ RBC_MSG_CTC_TRAIN_INFO
@ RBC_MSG_IL_STATUS
@ RBC_MSG_SAF_ENVELOPE
@ RBC_MSG_CTC_CONNECTED
@ RBC_MSG_IL_ROUTE_INDICATION
@ RBC_MSG_CTC_MA_EXTENDED
@ RBC_MSG_TRAIN_POSITION_IN_ROUTE
@ RBC_MSG_TEXT_MESSAGE
@ RBC_MSG_SET_LOG_LEVEL
@ RBC_MSG_ROUTE_ADD
@ RBC_MSG_ERTMS_ENVELOPE
@ RBC_MSG_TEXT_MESSAGE_ACK
@ RBC_MSG_P0
@ RBC_MSG_M3
@ RBC_MSG_TRAIN_DISCONNECT
@ RBC_MSG_HANDOVER_ORDER
@ RBC_MSG_SIM_STATUS
@ RBC_MSG_IL_ROUTE_CMD
@ RBC_MSG_ROUTE_RELEASE
@ RBC_MSG_ROUTE_STATUS_REPORT
@ RBC_MSG_CTC_MA_GRANTED
@ RBC_MSG_TSR_REMOVE
rbc_route_status_t
TRAIN_POSITION_IN_ROUTE's own route_status field - see that kind's own doc (rbc_msg_kind_t)....
@ RBC_ROUTE_STATUS_NO_TRAIN
@ RBC_ROUTE_STATUS_TRAIN_IN_ROUTE
rbc_il_emergency_type_t
RBC_MSG_IL_ROUTE_INDICATION.emergency_type - carried as a SIGNED int8 on the wire,...
@ RBC_IL_EMERGENCY_TYPE_UEM
@ RBC_IL_EMERGENCY_TYPE_SAM
@ RBC_IL_EMERGENCY_TYPE_CEM
@ RBC_IL_EMERGENCY_TYPE_NONE
rbc_il_degraded_status_t
RBC_MSG_IL_ROUTE_CMD.degraded_status - severity, meaningful only when route_status == RBC_IL_ROUTE_ST...
@ RBC_IL_DEGRADED_STATUS_NO_STATUS
@ RBC_IL_DEGRADED_STATUS_MEDIUM
@ RBC_IL_DEGRADED_STATUS_HIGH
@ RBC_IL_DEGRADED_STATUS_LOW
static void rbc_envelope_write_sim_status(uint8_t out[RBC_ENVELOPE_WIRE_SIZE], const char *payload)
Fills out with an ADR-038 sim-status frame: RBC_MSG_SIM_STATUS in byte 0, the ASCII payload length in...
static void rbc_envelope_queue_init(rbc_envelope_queue_t *queue)
static bool rbc_envelope_is_keepalive(const uint8_t in[RBC_ENVELOPE_WIRE_SIZE])
true if in is a keepalive frame - see rbc_envelope_write_keepalive()'s own doc. Callers on the receiv...
static bool rbc_envelope_queue_pop(rbc_envelope_queue_t *queue, uint8_t out_bytes[RBC_ENVELOPE_WIRE_SIZE])
static void rbc_envelope_write_keepalive(uint8_t out[RBC_ENVELOPE_WIRE_SIZE])
Fills out with a keepalive frame (RBC_MSG_RELAY_KEEPALIVE in byte 0, every other byte zero) - see tha...
rbc_route_type_t
ROUTE_ADD's own route_type field - the supervision mode IL is granting this route under (real ETCS co...
@ RBC_ROUTE_TYPE_OS
@ RBC_ROUTE_TYPE_SH
@ RBC_ROUTE_TYPE_FS
rbc_il_route_type_t
RBC_MSG_IL_ROUTE_CMD.route_type - is IL indicating a route here at all, and is it locked....
@ RBC_IL_ROUTE_TYPE_NO_ROUTE
@ RBC_IL_ROUTE_TYPE_LOCKED
static void rbc_envelope_write_set_log_level(uint8_t out[RBC_ENVELOPE_WIRE_SIZE], uint8_t level)
Fills out with a set-log-level control frame: RBC_MSG_SET_LOG_LEVEL in byte 0, level in byte 1,...
rbc_il_route_status_t
RBC_MSG_IL_ROUTE_CMD.route_status - the supervision mode / lifecycle status IL reports for the route.
@ RBC_IL_ROUTE_STATUS_NO_STATUS
@ RBC_IL_ROUTE_STATUS_DEGRADED
@ RBC_IL_ROUTE_STATUS_USED
@ RBC_IL_ROUTE_STATUS_FS
@ RBC_IL_ROUTE_STATUS_OS
@ RBC_IL_ROUTE_STATUS_SH
volatile uint32_t write_index
volatile uint32_t read_index
uint8_t entries[RBC_ENVELOPE_QUEUE_CAPACITY][RBC_ENVELOPE_WIRE_SIZE]
One decoded envelope - see this file's own module doc for where the wire<->struct conversion now live...
uint32_t route_status
uint32_t start_signal
rbc_msg_kind_t kind
uint32_t l_doubtunder