|
Mercury Modem
Mercury ARQ/Broadcast modem
|
#include <stdbool.h>#include <stddef.h>#include <stdint.h>#include <stdatomic.h>

Go to the source code of this file.
Data Structures | |
| struct | arq_frame_hdr_t |
| struct | arq_mode_timing_t |
| struct | arq_accept_t |
Enumerations | |
| enum | arq_subtype_t { ARQ_SUBTYPE_DISCONNECT = 4 } |
Functions | |
| int | arq_protocol_retry_rank (const char *local_call, const char *remote_call) |
| uint64_t | arq_protocol_retry_deadline_ms (float seconds, int rank) |
| int | arq_protocol_encode_hdr (uint8_t *buf, size_t buf_len, const arq_frame_hdr_t *hdr) |
| Encode a parsed header into the first ARQ_FRAME_HDR_SIZE bytes of buf. | |
| int | arq_protocol_decode_hdr (const uint8_t *buf, size_t buf_len, arq_frame_hdr_t *hdr) |
| Decode the ARQ header from the first bytes of buf. | |
| uint8_t | arq_protocol_bw_token_from_hz (int bw_hz) |
| Map a configured bandwidth in Hz to an on-air BW token. | |
| int | arq_protocol_bw_hz_from_token (uint8_t bw_token) |
| Map an on-air BW token back to Hz. | |
| uint8_t | arq_protocol_encode_snr (float snr_db) |
| Encode a floating-point SNR (dB) into the snr_raw wire byte. | |
| float | arq_protocol_decode_snr (uint8_t snr_raw) |
| Decode snr_raw wire byte back to float dB. | |
| const arq_mode_timing_t * | arq_protocol_mode_timing (int freedv_mode) |
| Look up mode timing entry for a FreeDV mode. | |
| float | arq_protocol_longest_burst_s (void) |
| Longest single-burst airtime across the whole mode table, in seconds. | |
| float | arq_protocol_call_interval_s (void) |
| Return the CALL/ACCEPT retry interval in seconds, applying any CALLINT override. | |
| float | arq_protocol_call_interval_for_mode_s (int mode) |
| uint16_t | arq_protocol_callsign_crc16 (const char *callsign) |
| Compute CRC16-CCITT of an uppercase-normalised callsign. | |
| int | arq_protocol_build_disconnect (uint8_t *buf, size_t buf_len, uint8_t session_id, uint8_t snr_raw) |
| DISCONNECT frame (PACKET_TYPE_ARQ_CONTROL). | |
| int | arq_protocol_build_call (uint8_t *buf, size_t buf_len, uint8_t session_id, const char *caller, const char *called, int bw_hz) |
| Build a CALL. | |
| int | arq_protocol_build_accept (uint8_t *buf, size_t buf_len, uint8_t session_id, const char *called, const char *caller, int bw_hz, int start_level, uint16_t nonce) |
| Build an ACCEPT. | |
| bool | arq_protocol_connect_version_ok (const uint8_t *buf, size_t buf_len) |
| Is buf a CALL or ACCEPT of this protocol version? | |
| bool | arq_protocol_connect_dst_matches (const uint8_t *buf, const char *callsign) |
| Is a CALL or ACCEPT addressed to callsign (bytes 2-3, all 16 bits)? | |
| int | arq_protocol_parse_call (const uint8_t *buf, size_t buf_len, uint8_t *session_id_out, char *caller_out, int *bw_hz_out) |
| Parse a CALL: session id, the caller's callsign, the bandwidth. | |
| int | arq_protocol_parse_accept (const uint8_t *buf, size_t buf_len, arq_accept_t *out) |
| Parse an ACCEPT. | |
| int | arq_protocol_build_cq (uint8_t *buf, size_t buf_len, const char *src, int bw_hz) |
| Build a compact DATAC16 CQ frame carrying source callsign and BW token. | |
| int | arq_protocol_parse_cq (const uint8_t *buf, size_t buf_len, char *src_out, int *bw_hz_out) |
| Parse a compact DATAC16 CQ frame. | |
Variables | |
| _Atomic int | arq_call_retry_slots |
| _Atomic int | arq_accept_retry_slots |
| _Atomic int | arq_disconnect_retry_slots |
| _Atomic float | arq_callint_override_s |
| _Atomic int | arq_retry_stagger_ms |
| _Atomic int | arq_disconnect_drain_timeout_s |
| const arq_mode_timing_t | arq_mode_table [] |
| const int | arq_mode_table_count |
| #define ARQ_ACCEPT_CALLED_CRC_IDX 4 |
| #define ARQ_ACCEPT_LEVEL_CTL_DEAF |
| #define ARQ_ACCEPT_LEVEL_IDX 8 |
| #define ARQ_ACCEPT_NONCE_IDX 6 |
| #define ARQ_ACCEPT_RETRY_SLOTS atomic_load(&arq_accept_retry_slots) |
| #define ARQ_ACCEPT_RETRY_SLOTS_DEFAULT 4 /* ACCEPT retries before returning */ |
| #define ARQ_ACCEPT_RX_WINDOW_FLOOR_MS 26000 |
| #define ARQ_ACCEPT_RX_WINDOW_MS |
| #define ARQ_ACK_DATA_GAP_MS 300 |
| #define ARQ_BURST_MAX 5 |
| #define ARQ_BW_TOKEN_2300 2 |
| #define ARQ_BW_TOKEN_2750 3 |
| #define ARQ_BW_TOKEN_500 1 |
| #define ARQ_BW_TOKEN_NONE 0 |
| #define ARQ_CALL_FAST_SLOTS 2 |
| #define ARQ_CALL_RETRY_SLOTS atomic_load(&arq_call_retry_slots) |
| #define ARQ_CALL_RETRY_SLOTS_DEFAULT 4 /* CALL retries before giving up */ |
| #define ARQ_CALLINT_DEFAULT_S 0.0f /* 0 = use table default */ |
| #define ARQ_CALLINT_MIN_S 4.0f |
| #define ARQ_CHANNEL_DEFER_MAX 20 /* ~10 s, then key regardless */ |
| #define ARQ_CHANNEL_DEFER_MS 500 |
| #define ARQ_CHANNEL_GUARD_MS |
| #define ARQ_CHANNEL_SYNC_HOLD_MS 250 |
| #define ARQ_CONNECT_ACCEPT_FLAG 0x80 |
| #define ARQ_CONNECT_DST_CRC_SIZE 2 /* CRC16-CCITT of DST at bytes [2..3], little-endian */ |
| #define ARQ_CONNECT_EXT_BW_MASK 0x03 |
| #define ARQ_CONNECT_EXT_CAROUSEL 0x10 |
| #define ARQ_CONNECT_EXT_VERSION_MASK 0x0C |
| #define ARQ_CONNECT_EXT_VERSION_SHIFT 2 |
| #define ARQ_CONNECT_MAX_ENCODED (ARQ_CONTROL_FRAME_SIZE - ARQ_CONNECT_META_SIZE) |
| #define ARQ_CONNECT_META_SIZE 2 /* framer byte + connect_meta byte */ |
| #define ARQ_CONNECT_PAYLOAD_IDX 2 |
| #define ARQ_CONNECT_SESSION_IDX 1 |
| #define ARQ_CONNECT_SESSION_MASK 0x7F |
| #define ARQ_CONNECT_SRC_MAX_ENCODED (ARQ_CONNECT_MAX_ENCODED - ARQ_CONNECT_DST_CRC_SIZE) /* 10 */ |
| #define ARQ_CONNECT_VERSION 1 |
| #define ARQ_CONTROL_FRAME_SIZE 14 |
| #define ARQ_CONTROL_MODE FREEDV_MODE_DATAC16 |
| #define ARQ_CQ_PAYLOAD_IDX 1 |
| #define ARQ_CQ_SRC_MAX_ENCODED (ARQ_CONTROL_FRAME_SIZE - ARQ_CQ_PAYLOAD_IDX) /* 13 */ |
| #define ARQ_DISCONNECT_DRAIN_TIMEOUT_S atomic_load(&arq_disconnect_drain_timeout_s) |
| #define ARQ_DISCONNECT_DRAIN_TIMEOUT_S_DEFAULT 45 |
| #define ARQ_DISCONNECT_RETRY_SLOTS atomic_load(&arq_disconnect_retry_slots) |
| #define ARQ_DISCONNECT_RETRY_SLOTS_DEFAULT 2 /* DISCONNECT frame retries */ |
| #define ARQ_FRAME_HDR_SIZE 8 /* bytes 0-7 inclusive */ |
| #define ARQ_HDR_ACK_IDX 5 |
| #define ARQ_HDR_DELAY_IDX 7 |
| #define ARQ_HDR_FLAGS_IDX 2 |
| #define ARQ_HDR_SEQ_IDX 4 |
| #define ARQ_HDR_SESSION_IDX 3 |
| #define ARQ_HDR_SNR_IDX 6 |
| #define ARQ_HDR_SUBTYPE_IDX 1 |
| #define ARQ_ISS_POST_ACK_GUARD_MS |
| #define ARQ_LISTEN_OFF_GRACE_MS 2000 |
| #define ARQ_REPLY_WINDOW_MARGIN_MS 1000 |
| #define ARQ_RETRY_STAGGER_MS_DEFAULT 2000 |
| #define ARQ_RETRY_STAGGER_MS_MAX 5000 |
| #define ARQ_SNR_HYST_DB 5.0f |
| #define ARQ_SNR_MIN_DATAC15_DB |
| #define ARQ_SNR_MIN_DATAC17_DB |
| #define ARQ_SNR_MIN_DATAC1_DB 3.0f |
| #define ARQ_SNR_MIN_DATAC3_DB -1.0f |
| #define ARQ_SNR_MIN_DATAC4_DB |
| #define ARQ_SNR_MIN_QAM16C2_DB |
| enum arq_subtype_t |
| int arq_protocol_build_accept | ( | uint8_t * | buf, |
| size_t | buf_len, | ||
| uint8_t | session_id, | ||
| const char * | called, | ||
| const char * | caller, | ||
| int | bw_hz, | ||
| int | start_level, | ||
| uint16_t | nonce | ||
| ) |
Build an ACCEPT.
called: the callsign the CALL was addressed to (the callee's primary or a secondary); start_level 0..6, or ARQ_ACCEPT_LEVEL_CTL_DEAF.
| int arq_protocol_build_call | ( | uint8_t * | buf, |
| size_t | buf_len, | ||
| uint8_t | session_id, | ||
| const char * | caller, | ||
| const char * | called, | ||
| int | bw_hz | ||
| ) |
Build a CALL.
| int arq_protocol_build_cq | ( | uint8_t * | buf, |
| size_t | buf_len, | ||
| const char * | src, | ||
| int | bw_hz | ||
| ) |
Build a compact DATAC16 CQ frame carrying source callsign and BW token.
| int arq_protocol_build_disconnect | ( | uint8_t * | buf, |
| size_t | buf_len, | ||
| uint8_t | session_id, | ||
| uint8_t | snr_raw | ||
| ) |
DISCONNECT frame (PACKET_TYPE_ARQ_CONTROL).
| int arq_protocol_bw_hz_from_token | ( | uint8_t | bw_token | ) |
Map an on-air BW token back to Hz.
| uint8_t arq_protocol_bw_token_from_hz | ( | int | bw_hz | ) |
Map a configured bandwidth in Hz to an on-air BW token.
| float arq_protocol_call_interval_for_mode_s | ( | int | mode | ) |
| float arq_protocol_call_interval_s | ( | void | ) |
Return the CALL/ACCEPT retry interval in seconds, applying any CALLINT override.
Falls back to the DATAC16 table default (8.0s).
| uint16_t arq_protocol_callsign_crc16 | ( | const char * | callsign | ) |
Compute CRC16-CCITT of an uppercase-normalised callsign.
Used to encode/validate the DST field in CALL/ACCEPT frames.
| bool arq_protocol_connect_dst_matches | ( | const uint8_t * | buf, |
| const char * | callsign | ||
| ) |
Is a CALL or ACCEPT addressed to callsign (bytes 2-3, all 16 bits)?
| bool arq_protocol_connect_version_ok | ( | const uint8_t * | buf, |
| size_t | buf_len | ||
| ) |
Is buf a CALL or ACCEPT of this protocol version?
| int arq_protocol_decode_hdr | ( | const uint8_t * | buf, |
| size_t | buf_len, | ||
| arq_frame_hdr_t * | hdr | ||
| ) |
Decode the ARQ header from the first bytes of buf.
| float arq_protocol_decode_snr | ( | uint8_t | snr_raw | ) |
Decode snr_raw wire byte back to float dB.
| int arq_protocol_encode_hdr | ( | uint8_t * | buf, |
| size_t | buf_len, | ||
| const arq_frame_hdr_t * | hdr | ||
| ) |
Encode a parsed header into the first ARQ_FRAME_HDR_SIZE bytes of buf.
| uint8_t arq_protocol_encode_snr | ( | float | snr_db | ) |
Encode a floating-point SNR (dB) into the snr_raw wire byte.
| float arq_protocol_longest_burst_s | ( | void | ) |
Longest single-burst airtime across the whole mode table, in seconds.
The RX side must be able to hold a burst of ANY mode the peer might send, not just the one currently selected — the peer can change rung between our bursts, and the first frame of the new rung arrives before we know about it. Buffers sized from the active mode are therefore always one step behind.
| const arq_mode_timing_t * arq_protocol_mode_timing | ( | int | freedv_mode | ) |
Look up mode timing entry for a FreeDV mode.
| int arq_protocol_parse_accept | ( | const uint8_t * | buf, |
| size_t | buf_len, | ||
| arq_accept_t * | out | ||
| ) |
Parse an ACCEPT.
| int arq_protocol_parse_call | ( | const uint8_t * | buf, |
| size_t | buf_len, | ||
| uint8_t * | session_id_out, | ||
| char * | caller_out, | ||
| int * | bw_hz_out | ||
| ) |
Parse a CALL: session id, the caller's callsign, the bandwidth.
| int arq_protocol_parse_cq | ( | const uint8_t * | buf, |
| size_t | buf_len, | ||
| char * | src_out, | ||
| int * | bw_hz_out | ||
| ) |
Parse a compact DATAC16 CQ frame.
| uint64_t arq_protocol_retry_deadline_ms | ( | float | seconds, |
| int | rank | ||
| ) |
| int arq_protocol_retry_rank | ( | const char * | local_call, |
| const char * | remote_call | ||
| ) |
|
extern |
|
extern |
|
extern |
|
extern |
|
extern |
|
extern |
|
extern |
|
extern |