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_channel_payload.c
Go to the documentation of this file.
1
7
8#include "rte/utils/buffer/rte_buffer.h"
9#include "rte/redundancy/checksum/rte_checksum.h"
10#include "rte/utils/lifecycle/rte_lifecycle.h"
11
13
15
17typedef struct
18{
19 uint32_t wire_size; /* this collector's own total contribution, bytes */
20 uint32_t offset; /* byte offset of this collector's own slice within
21 * the combined payload */
24 void *context;
26
28/* Module-private registry - fan-out list, not a single slot: more than
29 * one module can each contribute its own slice (see this file's own
30 * header doc). Relies on C's static zero-initialization, same convention
31 * this codebase already uses for every other module-private registry. */
33static uint32_t g_collector_count = 0U;
34static uint32_t g_payload_size = 0U; /* running total of every registered
35 * collector's own wire_size */
36
38
40
41
44 ab_gp_channel_payload_decode_fn decode_fn, void *context,
46{
47 rte_status_t lifecycle_status;
49
50 if ((wire_size == 0U) || (encode_fn == NULL) || (decode_fn == NULL) || (out_id == NULL))
51 {
52 return RTE_STATUS_INVALID_PARAM;
53 }
54 lifecycle_status = rte_lifecycle_check_setup_allowed();
55 if (lifecycle_status != RTE_STATUS_OK)
56 {
57 return lifecycle_status;
58 }
60 {
61 return RTE_STATUS_RESOURCE_EXHAUSTED;
62 }
63
65 slot->wire_size = wire_size;
66 slot->offset = g_payload_size;
67 slot->encode_fn = encode_fn;
68 slot->decode_fn = decode_fn;
69 slot->context = context;
70
71 *out_id = g_collector_count;
72 g_payload_size += wire_size;
74 return RTE_STATUS_OK;
75}
76
78{
79 if (id >= g_collector_count)
80 {
81 RTE_EXAMPLE_LOG("ab_gp_channel_payload: encode_collector() called with unregistered id %u\n",
82 (unsigned int)id);
83 return;
84 }
85 g_collectors[id].encode_fn(g_collectors[id].context, items, out);
86}
87
89{
90 if (id >= g_collector_count)
91 {
92 RTE_EXAMPLE_LOG("ab_gp_channel_payload: decode_collector() called with unregistered id %u\n",
93 (unsigned int)id);
94 return;
95 }
96 g_collectors[id].decode_fn(g_collectors[id].context, in, out_items);
97}
98
100 const void *const sources[AB_GP_CHANNEL_PAYLOAD_MAX_COLLECTORS])
101{
102 rte_buffer_t buf;
103 rte_crc64_t crc;
104 uint32_t i;
105
106 (void)rte_buffer_init(&buf, out, AB_SAMPLE_WIRE_SIZE);
107 (void)rte_buffer_write_u32_le(&buf, cycle);
108 for (i = 0U; i < g_collector_count; i++)
109 {
110 ab_gp_channel_payload_encode_collector(i, &out[4U + g_collectors[i].offset], sources[i]);
111 }
112 crc = rte_checksum_crc64(out, 4U + g_payload_size);
113 (void)rte_buffer_set_length(&buf, 4U + g_payload_size);
114 (void)rte_buffer_write_u64_le(&buf, crc);
115}
116
117rte_status_t ab_gp_channel_payload_decode_ab_sample(uint8_t in[AB_SAMPLE_WIRE_SIZE], uint32_t *out_cycle,
118 void *const dests[AB_GP_CHANNEL_PAYLOAD_MAX_COLLECTORS])
119{
120 rte_buffer_t buf;
121 uint32_t cycle;
122 rte_crc64_t received_crc;
123 rte_checksum_result_t crc_result;
124 rte_status_t status;
125 const uint32_t crc_offset = 4U + g_payload_size;
126 uint32_t i;
127
128 if (rte_buffer_init(&buf, in, AB_SAMPLE_WIRE_SIZE) != RTE_STATUS_OK)
129 {
130 return RTE_STATUS_INVALID_PARAM;
131 }
132 (void)rte_buffer_set_length(&buf, AB_SAMPLE_WIRE_SIZE);
133
134 if ((rte_buffer_read_u32_le(&buf, 0U, &cycle) != RTE_STATUS_OK)
135 || (rte_buffer_read_u64_le(&buf, crc_offset, &received_crc) != RTE_STATUS_OK))
136 {
137 return RTE_STATUS_INVALID_PARAM;
138 }
139
140 status = rte_checksum_crc64_verify(in, crc_offset, received_crc, &crc_result);
141 if (status != RTE_STATUS_OK)
142 {
143 return status;
144 }
145
146 *out_cycle = cycle;
147 for (i = 0U; i < g_collector_count; i++)
148 {
149 ab_gp_channel_payload_decode_collector(i, &in[4U + g_collectors[i].offset], dests[i]);
150 }
151 return RTE_STATUS_OK;
152}
void ab_gp_channel_payload_decode_collector(ab_gp_channel_payload_collector_id_t id, const uint8_t *in, void *out_items)
Decodes one collector's own items - see ab_gp_channel_payload_encode_collector() (same contract,...
void ab_gp_channel_payload_encode_ab_sample(uint8_t out[AB_SAMPLE_WIRE_SIZE], uint32_t cycle, const void *const sources[AB_GP_CHANNEL_PAYLOAD_MAX_COLLECTORS])
Encodes an A<->B peer-link sample: {cycle, every registered collector's own bytes in registration ord...
static ab_gp_channel_payload_collector_t g_collectors[AB_GP_CHANNEL_PAYLOAD_MAX_COLLECTORS]
rte_status_t ab_gp_channel_payload_register_collector(uint32_t wire_size, ab_gp_channel_payload_encode_fn encode_fn, ab_gp_channel_payload_decode_fn decode_fn, void *context, ab_gp_channel_payload_collector_id_t *out_id)
Registers a collector: a module's own fixed-size contribution to the combined A<->B payload - a fan-o...
static uint32_t g_collector_count
static uint32_t g_payload_size
void ab_gp_channel_payload_encode_collector(ab_gp_channel_payload_collector_id_t id, uint8_t *out, const void *items)
Encodes one collector's own items into its own slice of a combined buffer - used both standalone (e....
rte_status_t ab_gp_channel_payload_decode_ab_sample(uint8_t in[AB_SAMPLE_WIRE_SIZE], uint32_t *out_cycle, void *const dests[AB_GP_CHANNEL_PAYLOAD_MAX_COLLECTORS])
Decodes and CRC-64-verifies an A<->B peer-link sample.
Generic, data-blind wire framing for the A<->B peer link's AB_SAMPLE frame (CRC-64-protected,...
void(*) ab_gp_channel_payload_encode_fn(void *context, const void *items, uint8_t *out)
Encodes a collector's own whole item array into its own wire_size-byte slice of a combined buffer - t...
void(*) ab_gp_channel_payload_decode_fn(void *context, const uint8_t *in, void *out_items)
Decodes a collector's own whole item array from its own wire_size-byte slice - see ab_gp_channel_payl...
uint32_t ab_gp_channel_payload_collector_id_t
Opaque handle to a registered collector - returned by ab_gp_channel_payload_register_collector() belo...
#define AB_GP_CHANNEL_PAYLOAD_MAX_COLLECTORS
#define AB_SAMPLE_WIRE_SIZE
#define RTE_EXAMPLE_LOG(...)
ab_gp_channel_payload_encode_fn encode_fn
ab_gp_channel_payload_decode_fn decode_fn