9#include "rte/oal/memory/rte_mem_util.h"
10#include "rte/oal/log/rte_log.h"
11#include "common/common_config.h"
12#include "common/rbc_util_frame.h"
13#include "gateway_c_common.h"
14#include "gateway_c_selfstatus.h"
18static const char *peer_name(gateway_c_peer_t peer)
20 return (peer == GATEWAY_C_PEER_A) ?
"A" :
"B";
23static void broadcast_one(gateway_c_peer_t peer,
const uint8_t bytes[RBC_ENVELOPE_WIRE_SIZE])
25 rte_status_t status = rte_channel_service_send(&g_il.relay_channel[peer], bytes,
26 RBC_ENVELOPE_WIRE_SIZE, 0U);
29 if ((status != RTE_STATUS_OK) && (status != RTE_STATUS_TIMEOUT) && (status != RTE_STATUS_NOT_CONNECTED))
31 rte_log_write_event(RTE_LOG_LEVEL_WARNING,
"-", 0U,
"GW", peer_name(peer),
"LOG_LEVEL",
32 rte_status_to_string(status), NULL);
38 broadcast_one(GATEWAY_C_PEER_A, bytes);
39 broadcast_one(GATEWAY_C_PEER_B, bytes);
42rte_status_t gateway_c_il_handler_init(gateway_c_context_t *ctx)
46 g_il.last_known_tag =
"SUPPRESSED";
47 g_il.relay_consecutive_timeout = 0U;
48 g_il.relay_down_since_ms[GATEWAY_C_PEER_A] = 0U;
49 g_il.relay_down_since_ms[GATEWAY_C_PEER_B] = 0U;
50 g_il.send_down_since_ms[GATEWAY_C_PEER_A] = 0U;
51 g_il.send_down_since_ms[GATEWAY_C_PEER_B] = 0U;
52 g_il.a_seen_this_cycle = 0U;
53 g_il.a_stale_cycles = 0U;
54 gateway_c_dedup_init(&g_il.dedup);
56 status = rte_channel_service_setup(&g_il.relay_channel[GATEWAY_C_PEER_A],
"c-relay-il-a");
57 if (status != RTE_STATUS_OK)
59 RTE_EXAMPLE_LOG(
"[GW %s] ILHandler: relay A channel setup failed (%s)\n",
60 site_config_name(ctx->site), rte_status_to_string(status));
63 status = rte_channel_service_setup(&g_il.relay_channel[GATEWAY_C_PEER_B],
"c-relay-il-b");
64 if (status != RTE_STATUS_OK)
66 RTE_EXAMPLE_LOG(
"[GW %s] ILHandler: relay B channel setup failed (%s)\n",
67 site_config_name(ctx->site), rte_status_to_string(status));
70 status = rte_channel_service_setup(&g_il.sim_channel,
"c-sim-il");
71 if (status != RTE_STATUS_OK)
73 RTE_EXAMPLE_LOG(
"[GW %s] ILHandler: sim channel setup failed (%s)\n",
74 site_config_name(ctx->site), rte_status_to_string(status));
80static void send_to_relay(gateway_c_context_t *ctx, gateway_c_peer_t peer,
81 const uint8_t bytes[RBC_ENVELOPE_WIRE_SIZE])
83 rte_status_t status = rte_channel_service_send(&g_il.relay_channel[peer],
84 bytes, RBC_ENVELOPE_WIRE_SIZE, 0U);
88 if ((status == RTE_STATUS_OK) || (status == RTE_STATUS_NOT_CONNECTED))
92 g_il.send_down_since_ms[peer] = 0U;
99 if (g_il.send_down_since_ms[peer] == 0U)
101 (void)rte_timer_now(&g_il.send_down_since_ms[peer]);
103 if (status == RTE_STATUS_TIMEOUT)
107 RTE_EXAMPLE_LOG(
"[GW %s] ILHandler: forward to %s failed (%s)\n", site_config_name(ctx->site),
108 peer_name(peer), rte_status_to_string(status));
109 rte_log_write_event(RTE_LOG_LEVEL_ERROR, site_config_name(ctx->site), 0U,
"GW", peer_name(peer),
110 "ENVELOPE", rte_status_to_string(status), NULL);
114static void send_to_sim(gateway_c_context_t *ctx,
const uint8_t bytes[RBC_ENVELOPE_WIRE_SIZE])
116 rte_status_t status = rte_channel_service_send(&g_il.sim_channel,
117 bytes, RBC_ENVELOPE_WIRE_SIZE, 0U);
119 if ((status != RTE_STATUS_OK) && (status != RTE_STATUS_TIMEOUT) && (status != RTE_STATUS_NOT_CONNECTED))
121 RTE_EXAMPLE_LOG(
"[GW %s] ILHandler: forward to ILSim failed (%s)\n",
122 site_config_name(ctx->site), rte_status_to_string(status));
123 rte_log_write_event(RTE_LOG_LEVEL_ERROR, site_config_name(ctx->site), 0U,
"GW",
"IL",
"ENVELOPE",
124 rte_status_to_string(status), NULL);
128void gateway_c_il_handler_execute(gateway_c_context_t *ctx, uint32_t cycle)
130 uint8_t bytes[RBC_ENVELOPE_WIRE_SIZE];
131 char sim_status[RBC_UTIL_PAYLOAD_MAX + 1];
133 bool forwarded_this_cycle =
false;
137 while (rte_channel_service_read(&g_il.sim_channel, bytes,
sizeof(bytes), 0U) == RTE_STATUS_OK)
143 if (rbc_envelope_is_sim_status(bytes, sim_status, (uint16_t)
sizeof(sim_status)))
145 gateway_c_selfstatus_publish((uint8_t)RBC_UTIL_SRC_SIM_IL, sim_status);
148 send_to_relay(ctx, GATEWAY_C_PEER_A, bytes);
149 send_to_relay(ctx, GATEWAY_C_PEER_B, bytes);
150 forwarded_this_cycle =
true;
158 if (!forwarded_this_cycle)
160 uint8_t keepalive[RBC_ENVELOPE_WIRE_SIZE];
162 rbc_envelope_write_keepalive(keepalive);
163 send_to_relay(ctx, GATEWAY_C_PEER_A, keepalive);
164 send_to_relay(ctx, GATEWAY_C_PEER_B, keepalive);
173 uint32_t a_count = 0U;
174 uint32_t b_count = 0U;
176 while ((status = rte_channel_service_read(&g_il.relay_channel[GATEWAY_C_PEER_A],
177 bytes,
sizeof(bytes), 0U)) == RTE_STATUS_OK)
179 if (rbc_envelope_is_keepalive(bytes))
184 if (!gateway_c_dedup_check_and_record(&g_il.dedup, bytes,
sizeof(bytes)))
186 send_to_sim(ctx, bytes);
190 if ((status != RTE_STATUS_OK) && (status != RTE_STATUS_TIMEOUT))
192 if (g_il.relay_down_since_ms[GATEWAY_C_PEER_A] == 0U)
194 (void)rte_timer_now(&g_il.relay_down_since_ms[GATEWAY_C_PEER_A]);
197 else if (a_count > 0U)
199 g_il.relay_down_since_ms[GATEWAY_C_PEER_A] = 0U;
200 g_il.relay_consecutive_timeout = 0U;
201 g_il.a_stale_cycles = 0U;
205 g_il.a_stale_cycles++;
207 g_il.a_seen_this_cycle = a_count;
209 while ((status = rte_channel_service_read(&g_il.relay_channel[GATEWAY_C_PEER_B],
210 bytes,
sizeof(bytes), 0U)) == RTE_STATUS_OK)
212 if (rbc_envelope_is_keepalive(bytes))
217 if (!gateway_c_dedup_check_and_record(&g_il.dedup, bytes,
sizeof(bytes)))
219 send_to_sim(ctx, bytes);
223 if ((status != RTE_STATUS_OK) && (status != RTE_STATUS_TIMEOUT))
225 if (g_il.relay_down_since_ms[GATEWAY_C_PEER_B] == 0U)
227 (void)rte_timer_now(&g_il.relay_down_since_ms[GATEWAY_C_PEER_B]);
230 else if (b_count > 0U)
232 g_il.relay_down_since_ms[GATEWAY_C_PEER_B] = 0U;
235 g_il.last_known_tag = ((a_count > 0U) || (b_count > 0U)) ?
"ACTIVE" :
"SUPPRESSED";
239void gateway_c_il_handler_shutdown(
void)
241 (void)rte_channel_service_close(&g_il.sim_channel);
242 (void)rte_channel_service_close(&g_il.relay_channel[GATEWAY_C_PEER_A]);
243 (void)rte_channel_service_close(&g_il.relay_channel[GATEWAY_C_PEER_B]);
246bool gateway_c_il_handler_check_link_down(rte_timestamp_ms_t threshold_ms, rte_timestamp_ms_t now_ms,
247 char *out_which,
size_t which_size)
249 gateway_c_peer_t peer;
251 for (peer = GATEWAY_C_PEER_A; peer <= GATEWAY_C_PEER_B; peer = (gateway_c_peer_t)((int)peer + 1))
253 rte_timestamp_ms_t down_since = g_il.relay_down_since_ms[peer];
254 rte_timestamp_ms_t send_down_since = g_il.send_down_since_ms[peer];
256 if (((down_since != 0U) && ((now_ms - down_since) >= threshold_ms)) ||
257 ((send_down_since != 0U) && ((now_ms - send_down_since) >= threshold_ms)))
259 (void)snprintf(out_which, which_size,
"IL relay link to %s", peer_name(peer));
void gateway_c_il_handler_broadcast_to_ab(const uint8_t bytes[RBC_ENVELOPE_WIRE_SIZE])
Sends one RBC_ENVELOPE_WIRE_SIZE frame to BOTH A and B on the IL relay link. Used by gateway_c_logctl...
ILHandler - Role C Gateway's TCP/IP server for the ONE multiplexed IL sim connection and the ONE dedi...