|
Mercury Modem
Mercury ARQ/Broadcast modem
|
#include "arq_protocol.h"#include <string.h>#include <stdio.h>#include <stdatomic.h>#include <math.h>#include "../common/virtual_clock.h"#include "../modem/freedv/freedv_api.h"#include "../modem/modem_mfsk.h"#include "../modem/framer.h"#include "arq.h"
Functions | |
| void | init_model (void) |
| int | arithmetic_encode (const char *msg, uint8_t *output) |
| int | arithmetic_decode (uint8_t *input, int max_len, char *output, int max_output) |
| 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) |
| 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. | |
| 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). | |
| uint16_t | arq_protocol_callsign_crc16 (const char *callsign) |
| Compute CRC16-CCITT of an uppercase-normalised callsign. | |
| static int | encode_callsign_payload (const char *src, const char *dst, uint8_t *out, size_t out_cap) |
| static int | decode_callsign_payload (const uint8_t *in, size_t in_len, char *src_out, char *dst_out) |
| static int | encode_callsign_only_payload (const char *src, uint8_t *out, size_t out_cap) |
| static int | decode_callsign_only_payload (const uint8_t *in, size_t in_len, char *src_out) |
| static uint8_t | connect_ext (uint8_t bw_token) |
| static void | put_crc16 (uint8_t *p, uint16_t crc) |
| static uint16_t | get_crc16 (const uint8_t *p) |
| bool | arq_protocol_connect_version_ok (const uint8_t *buf, size_t buf_len) |
| Is buf a CALL or ACCEPT of this protocol version? | |
| static int | connect_bw_hz (const uint8_t *buf) |
| 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_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 = ARQ_CALL_RETRY_SLOTS_DEFAULT |
| _Atomic int | arq_accept_retry_slots = ARQ_ACCEPT_RETRY_SLOTS_DEFAULT |
| _Atomic int | arq_disconnect_retry_slots = ARQ_DISCONNECT_RETRY_SLOTS_DEFAULT |
| _Atomic int | arq_retry_stagger_ms = ARQ_RETRY_STAGGER_MS_DEFAULT |
| _Atomic int | arq_disconnect_drain_timeout_s = ARQ_DISCONNECT_DRAIN_TIMEOUT_S_DEFAULT |
| const arq_mode_timing_t | arq_mode_table [] |
| const int | arq_mode_table_count |
| _Atomic float | arq_callint_override_s = 0.0f |
|
extern |
|
extern |
| 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 | ||
| ) |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
extern |
|
static |
| _Atomic int arq_accept_retry_slots = ARQ_ACCEPT_RETRY_SLOTS_DEFAULT |
| _Atomic int arq_call_retry_slots = ARQ_CALL_RETRY_SLOTS_DEFAULT |
| _Atomic float arq_callint_override_s = 0.0f |
| _Atomic int arq_disconnect_drain_timeout_s = ARQ_DISCONNECT_DRAIN_TIMEOUT_S_DEFAULT |
| _Atomic int arq_disconnect_retry_slots = ARQ_DISCONNECT_RETRY_SLOTS_DEFAULT |
| const arq_mode_timing_t arq_mode_table[] |
| const int arq_mode_table_count |
| _Atomic int arq_retry_stagger_ms = ARQ_RETRY_STAGGER_MS_DEFAULT |