Mercury Modem
Mercury ARQ/Broadcast modem
Loading...
Searching...
No Matches
arq.h
Go to the documentation of this file.
1/* HERMES Modem
2 *
3 * Copyright (C) 2025 Rhizomatica
4 * Author: Rafael Diniz <rafael@riseup.net>
5 *
6 * This is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3, or (at your option)
9 * any later version.
10 *
11 * This software is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 *
19 */
20
21#ifndef ARQ_H_
22#define ARQ_H_
23
24#define CALLSIGN_MAX_SIZE 16
25#define CALLSIGN_MAX_SECONDARY 4
26
27#define ARQ_BANDWIDTH_NARROW_HZ 500
28#define ARQ_BANDWIDTH_FULL_HZ 2300
29#define ARQ_BANDWIDTH_TACTICAL_HZ 2750
30
31#define RX 0
32#define TX 1
33
34#define HEADER_SIZE 1
35
36#define PACKET_ARQ_CONTROL 0x00
37#define PACKET_ARQ_DATA 0x01
38#define PACKET_ARQ_CALL 0x02
39#define PACKET_BROADCAST_CONTROL 0x03
40#define PACKET_BROADCAST_PAYLOAD 0x04
41
42#include <stdbool.h>
43#include <stddef.h>
44#include <stdint.h>
45
46#include "arq_events.h"
47
49typedef struct
50{
51 int TRX; // RX (0) or TX (1)
52 char my_call_sign[CALLSIGN_MAX_SIZE];
55 char src_addr[CALLSIGN_MAX_SIZE], dst_addr[CALLSIGN_MAX_SIZE];
58 bool listen;
59 int bw; // configured local bandwidth in Hz
60 int session_bw; // negotiated session bandwidth in Hz (0 = not negotiated)
61 int retry_slots; // 0 = use compiled default
62 size_t frame_size;
63 int mode;
64} arq_info;
65
67typedef enum
68{
74 ARQ_ACTION_TX_PATTERN = 5 /* emit a Welch-Costas MFSK pattern: no coded
75 * frame, pattern_kind says which; ~0.64 s */
77
79typedef enum
80{
81 ARQ_PATTERN_ACK = 0, /* "got it" */
82 ARQ_PATTERN_BREAK = 1 /* "got it: the block is delivered"; reaches
83 * the FSM as RX_PATTERN with pattern_break */
85
86/* A keydown of separate bursts -- each its own preamble, frame and postamble,
87 * in its own mode -- with a silence before each but the first (the carousel
88 * data plane's rounds). Heap-allocated by the enqueuer; whoever dequeues the
89 * action frees it. */
90/* A NAV header (mfsk.h) and the silence after it, ahead of a keydown's first
91 * frame: what the carousel adds to a headed keydown's lead. */
92#define ARQ_NAV_GAP_MS 60
93#define ARQ_NAV_LEAD_MS (640 + ARQ_NAV_GAP_MS)
94#define ARQ_KEYDOWN_FRAMES 17
95#define ARQ_KEYDOWN_FRAME_MAX 1280
96typedef struct
97{
98 int n;
99 uint16_t crc_seed; /* XORed into every frame's CRC16 (0: plain) */
100 bool nav; /* open with a NAV header (ARQ_NAV_LEAD_MS) */
101 struct
102 {
103 int mode;
104 uint32_t gap_ms;
105 size_t len;
106 uint8_t bytes[ARQ_KEYDOWN_FRAME_MAX];
109
111typedef struct
112{
114 int mode;
115 size_t frame_size; /* bytes per frame */
116 int frame_count; /* frames in this PTT burst (>= 1); the modem reads
117 * frame_count * frame_size bytes and modulates them
118 * behind a single preamble */
119 arq_keydown_t *keydown; /* ARQ_ACTION_TX_KEYDOWN only */
120 int pattern_kind; /* arq_pattern_kind_t, ARQ_ACTION_TX_PATTERN only */
122
124typedef struct
125{
128 /* A pattern can arrive now: the RX pattern detector correlates only while
129 * this is set -- running it all the time costs the decoders CPU. */
131 /* A carousel session is up: the pattern detector runs throughout, for the
132 * peer's NAV headers (expect_pattern_ack still gates ACK/BREAK). */
134 /* Listening or accepting: a CALL can arrive on MFSK, and only the
135 * modem's MFSK call listener would decode it. */
137 int trx;
140 int payload_mode; /* my TX mode (ISS direction) */
141 int peer_tx_mode; /* RX decoder mode = peer's TX mode (IRS direction) */
145 uint64_t tx_bytes;
146 uint64_t rx_bytes;
147 /* In a carousel session (in_carousel), for the UI: the mode of my last
148 * data round, of the last data frame I took, and of the rung the peer
149 * last reported hearing me on (carousel.h car_ui_*). -1: none. */
154
155extern arq_info arq_conn;
156
157/* Thread-safe accessors for arq_conn (see g_conn_lock in arq.c).
158 * None may be called while the caller already holds the connection lock. */
159void arq_set_trx(int trx);
160int arq_get_trx(void);
161/* Configured (non-session) bandwidth in Hz, read under g_conn_lock. */
162int arq_get_bw(void);
163/* Copy the current callsign strings out under g_conn_lock. Each of my_call,
164 * src_addr, dst_addr may be NULL to skip; each receives up to bufsz bytes,
165 * always NUL-terminated. */
166void arq_conn_get_calls(char *my_call, char *src_addr, char *dst_addr, size_t bufsz);
167
168/* Wake the ARQ event loop so it re-reads time_now_ms(). Called by the
169 * -x sock virtual-clock transport after advancing signal time; harmless
170 * (a spurious wakeup) from any other context. */
171void arq_notify_virtual_time(void);
172
179int arq_init(size_t frame_size, int mode);
180
184void arq_shutdown();
185
189void arq_tick_1hz(void);
190
195void arq_post_event(int event);
196/* The RX pattern detector heard a pattern (is_break: the BREAK kind). */
197void arq_post_pattern_ack(bool is_break);
198
203bool arq_is_link_connected(void);
204
211void arq_discard_stale_rx(void);
212
218
225int arq_queue_data(const uint8_t *data, size_t len);
226
232
239void arq_set_disconnect_drain_timeout_s(int seconds);
240
241/* Idle ("listen") payload mode: what the payload decoder sits on while no ARQ
242 * session is up, and therefore which broadcast frames this station can hear.
243 * arq_set_listen_mode() returns 0 on success, -1 if a session is up (the ARQ
244 * carousel owns the mode then). Does not affect any later session: every
245 * session-start path resets the mode state to DATAC15. Read it back through
246 * modem_get_listen_mode(), which owns the operator-facing value. */
248
254void arq_set_active_modem_mode(int mode, size_t frame_size);
255
264bool arq_handle_incoming_connect_frame(uint8_t *data, size_t frame_size, float rx_snr, int mode);
265/* A frame that passed the session's seeded CRC (carousel data plane).
266 * from_control: the control decoder produced it; otherwise mode is the
267 * payload decoder's. */
268void arq_handle_carousel_frame(const uint8_t *data, size_t frame_size, int mode,
269 bool from_control, float rx_snr, uint32_t age_ms);
270
277bool arq_handle_incoming_cq_frame(uint8_t *data, size_t frame_size);
278
285void arq_notify_cq_tx_started(void);
287
294void arq_handle_incoming_frame(uint8_t *data, size_t frame_size, float rx_snr);
295
303void arq_update_link_metrics(int sync, float snr, int rx_status, bool frame_decoded);
304
310void arq_note_rx_preamble(int mode);
311void arq_note_rx_frame_done(void);
317void arq_note_rx_nav(uint32_t age_ms, uint32_t hold_ms);
318
325
332bool arq_wait_dequeue_action(arq_action_t *action, int timeout_ms);
333
340
346int arq_submit_tcp_cmd(const arq_cmd_msg_t *cmd);
347
354int arq_submit_tcp_payload(const uint8_t *data, size_t len);
355
360
366
376void arq_set_retry_slots(int slots);
377
378void arq_set_retry_stagger_ms(int ms);
379
383void call_remote();
384
389
390#endif
void arq_note_rx_nav(uint32_t age_ms, uint32_t hold_ms)
A NAV header that began age_ms ago says the peer's keydown ends within hold_ms of its start: the chan...
Definition arq.c:1168
#define CALLSIGN_MAX_SIZE
Definition arq.h:24
int arq_get_bw(void)
Definition arq.c:438
void arq_set_retry_slots(int slots)
Set runtime retry slot counts.
Definition arq.c:1304
int arq_submit_tcp_cmd(const arq_cmd_msg_t *cmd)
Submit parsed control command from TCP bridge to ARQ.
Definition arq.c:1258
void arq_handle_carousel_frame(const uint8_t *data, size_t frame_size, int mode, bool from_control, float rx_snr, uint32_t age_ms)
Definition arq.c:754
bool arq_handle_incoming_cq_frame(uint8_t *data, size_t frame_size)
Handle incoming compact CQ frame and emit host-side CQFRAME notification.
Definition arq.c:876
arq_info arq_conn
Definition arq.c:46
int arq_init(size_t frame_size, int mode)
Initialize ARQ subsystem.
Definition arq.c:936
int arq_submit_tcp_payload(const uint8_t *data, size_t len)
Submit payload bytes from TCP bridge to ARQ.
Definition arq.c:1264
void arq_update_link_metrics(int sync, float snr, int rx_status, bool frame_decoded)
Feed decoder/link metrics into ARQ adaptation.
Definition arq.c:1186
void arq_handle_incoming_frame(uint8_t *data, size_t frame_size, float rx_snr)
Handle incoming regular ARQ control/data frame.
Definition arq.c:907
void arq_set_retry_stagger_ms(int ms)
Definition arq.c:1324
bool arq_get_runtime_snapshot(arq_runtime_snapshot_t *snapshot)
Copy ARQ runtime snapshot.
Definition arq.c:1223
void clear_connection_data()
Clear legacy ARQ connection state and buffers.
Definition arq.c:1283
void arq_post_event(int event)
Post an FSM event to ARQ.
Definition arq.c:1059
void arq_note_rx_frame_done(void)
Definition arq.c:1179
bool arq_wait_dequeue_action(arq_action_t *action, int timeout_ms)
Wait for next modem action.
Definition arq.c:1217
#define CALLSIGN_MAX_SECONDARY
Definition arq.h:25
#define ARQ_KEYDOWN_FRAME_MAX
Definition arq.h:95
void arq_post_pattern_ack(bool is_break)
Definition arq.c:1061
arq_action_type_t
Action types emitted by ARQ for modem worker execution.
Definition arq.h:68
@ ARQ_ACTION_TX_PATTERN
Definition arq.h:74
@ ARQ_ACTION_TX_PAYLOAD
Definition arq.h:71
@ ARQ_ACTION_TX_CONTROL
Definition arq.h:70
@ ARQ_ACTION_TX_KEYDOWN
Definition arq.h:73
@ ARQ_ACTION_NONE
Definition arq.h:69
@ ARQ_ACTION_MODE_SWITCH
Definition arq.h:72
void arq_notify_cq_tx_started(void)
Emit VARA-style async status for an outgoing CQFRAME transmission.
Definition arq.c:895
int arq_get_trx(void)
Definition arq.c:420
void arq_set_active_modem_mode(int mode, size_t frame_size)
Inform ARQ of modem mode/frame size actually active in modem.
Definition arq.c:1137
void arq_notify_virtual_time(void)
Definition arq.c:150
bool arq_handle_incoming_connect_frame(uint8_t *data, size_t frame_size, float rx_snr, int mode)
Handle an incoming CALL/ACCEPT frame (protocol version 1).
Definition arq.c:771
void arq_set_disconnect_drain_timeout_s(int seconds)
Set the absolute cap on how long an app DISCONNECT may stay deferred while draining the last TX bytes...
Definition arq.c:1293
void arq_notify_cq_tx_complete(void)
Definition arq.c:901
#define ARQ_KEYDOWN_FRAMES
Definition arq.h:94
bool arq_try_dequeue_action(arq_action_t *action)
Try to dequeue next modem action without blocking.
Definition arq.c:1211
int arq_set_listen_mode(int mode)
Definition arq.c:1120
arq_pattern_kind_t
Pattern kind (ARQ_ACTION_TX_PATTERN).
Definition arq.h:80
@ ARQ_PATTERN_BREAK
Definition arq.h:82
@ ARQ_PATTERN_ACK
Definition arq.h:81
void reset_arq_info(arq_info *arq_conn)
Reset external arq_info structure.
Definition arq.c:1333
void callee_accept_connection()
Trigger callee-side accept flow in compatibility path.
Definition arq.c:1353
void call_remote()
Trigger outgoing call attempt using current ARQ addresses.
Definition arq.c:1352
void arq_discard_stale_rx(void)
Drop received bytes an ended session left in the RX buffer.
Definition arq.c:1077
void arq_shutdown()
Shut down ARQ workers and release ARQ resources.
Definition arq.c:1028
void arq_tick_1hz(void)
Execute 1 Hz ARQ maintenance tick.
Definition arq.c:1057
bool arq_is_link_connected(void)
Check whether ARQ link is connected.
Definition arq.c:1069
int arq_get_tx_backlog_bytes(void)
Get pending outbound payload backlog.
Definition arq.c:1101
int arq_queue_data(const uint8_t *data, size_t len)
Queue outbound payload bytes for ARQ transmission.
Definition arq.c:1089
int arq_reported_bandwidth_hz(void)
Get the configured ARQ bandwidth token to report to VARA clients.
Definition arq.c:408
void arq_set_trx(int trx)
Definition arq.c:413
void arq_note_rx_preamble(int mode)
A decoder for mode has just caught a frame's preamble: the channel is busy for that frame's airtime e...
Definition arq.c:1156
void arq_conn_get_calls(char *my_call, char *src_addr, char *dst_addr, size_t bufsz)
Definition arq.c:428
int mode
Definition carousel.c:2330
Single modem action item popped by modem TX worker.
Definition arq.h:112
size_t frame_size
Definition arq.h:115
int pattern_kind
Definition arq.h:120
int mode
Definition arq.h:114
int frame_count
Definition arq.h:116
arq_action_type_t type
Definition arq.h:113
arq_keydown_t * keydown
Definition arq.h:119
Definition arq_events.h:64
Runtime ARQ connection and mode state shared across modules.
Definition arq.h:50
int bw
Definition arq.h:59
bool encryption
Definition arq.h:56
int session_bw
Definition arq.h:60
size_t frame_size
Definition arq.h:62
int retry_slots
Definition arq.h:61
bool listen
Definition arq.h:58
int mode
Definition arq.h:63
int TRX
Definition arq.h:51
int call_burst_size
Definition arq.h:57
int secondary_call_count
Definition arq.h:54
Definition arq.h:97
bool nav
Definition arq.h:100
uint32_t gap_ms
Definition arq.h:104
int mode
Definition arq.h:103
size_t len
Definition arq.h:105
uint16_t crc_seed
Definition arq.h:99
int n
Definition arq.h:98
Snapshot of current ARQ runtime state for telemetry/decision making.
Definition arq.h:125
int tx_backlog_bytes
Definition arq.h:138
bool initialized
Definition arq.h:126
int speed_level
Definition arq.h:139
int trx
Definition arq.h:137
int peer_tx_mode
Definition arq.h:141
int preferred_rx_mode
Definition arq.h:143
int payload_mode
Definition arq.h:140
int control_mode
Definition arq.h:142
bool expect_pattern_ack
Definition arq.h:130
int car_rx_mode
Definition arq.h:151
int preferred_tx_mode
Definition arq.h:144
bool in_carousel
Definition arq.h:133
uint64_t tx_bytes
Definition arq.h:145
int car_peer_mode
Definition arq.h:152
uint64_t rx_bytes
Definition arq.h:146
bool listening_for_calls
Definition arq.h:136
int car_tx_mode
Definition arq.h:150
bool connected
Definition arq.h:127