Mercury Modem
Mercury ARQ/Broadcast modem
Loading...
Searching...
No Matches
Macros | Enumerations | Functions | Variables
carousel.c File Reference
#include "carousel.h"
#include "arq.h"
#include "arq_protocol.h"
#include "freedv_api.h"
#include "modem_mfsk.h"
#include <math.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
Include dependency graph for carousel.c:

Macros

#define FRAME_HDR   2
 
#define SEG_HDR   4
 
#define CTL_SEG_K1   127
 
#define INLINE_CTL   (SEG_HDR + CAR_POLL_BYTES)
 
#define FB_UNSEEN   255
 
#define SLOW_RUNG_FRAMES   3 /* round cap on the two slowest rungs */
 
#define TURN_QUANTUM_MS   30000
 
#define TURN_CAP_MS   45000
 
#define MAX_KEYDOWN_MS   30000 /* airtime cap per round */
 
#define HEAD_MS   (110 + nav_lead(c))
 
#define TAIL_MS   200
 
#define GUARD_MS   ARQ_CHANNEL_GUARD_MS
 
#define ISS_GUARD_MS   ARQ_ISS_POST_ACK_GUARD_MS
 
#define CHAIN_GAP_MS   ARQ_ACK_DATA_GAP_MS /* poll -> first burst, one keydown */
 
#define RESEND_RUN   2 /* pieces repeated from the receiver's gap */
 
#define WINDOW_MARGIN_MS   1000 /* a round that never came: re-poll after this */
 
#define SENSE_MS   1400 /* after keying, the sender is heard by now */
 
#define CARRIER_CHECK_MS   250 /* carrier re-checked this often */
 
#define SENDER_SILENCE_MS   90000 /* sender heard no poll this long: nudge */
 
#define FLOOR_POLL_EVERY   4
 
#define FLOOR_DEEP_DB   3.0f
 
#define FLOOR_POLL_EVERY_DEEP   12
 
#define FLOOR_SILENT_MAX   6
 
#define FLOOR_LATE_MS   9000
 
#define PATTERN_AIR_MS   640
 
#define PATTERN_SENSE_EXTRA_MS   2000
 
#define FLOOR_ANSWER_MS   4000
 
#define FLOOR_SENSE_MS   3000
 
#define FLOOR_DELAY_MARGIN_MS   2000
 
#define HANDOVER_SOON_MS   5000
 
#define BLOCK_CHECK   4
 
#define CTL_FLOOR_MARK   0x07
 
#define CTL_DEAF_ON_DB   (ARQ_SNR_MIN_DATAC15_DB - 0.5f)
 
#define CTL_DEAF_OFF_DB   (ARQ_SNR_MIN_DATAC15_DB + 1.0f)
 
#define BLOCK_MIN_K   8
 
#define BLOCK_AIR_MS   60000
 
#define PROBE_UP_DELIVERY   0.5 /* the best must deliver this well to probe above it */
 
#define PROBE_EVERY   8 /* polls before a measured rung is re-probed... */
 
#define DEAD_PROBE_MS   60000 /* a dead rung is re-probed after this... */
 
#define DEAD_PROBE_MAX_MS   480000 /* ...doubling to at most this */
 
#define LV_DECAY   0.8 /* per measured round: memory of ~5 frames */
 
#define DEAD_RUN   4 /* consecutive frames lost, none delivered: dead */
 
#define DEAD_P   0.02
 
#define SNR_GATE_DB   3.0f
 
#define ROUND_OVERHEAD_MS   (4400 + GUARD_MS + ISS_GUARD_MS + HEAD_MS + TAIL_MS)
 
#define FLOOR_OVERHEAD_MS   (PATTERN_AIR_MS + GUARD_MS + ISS_GUARD_MS + HEAD_MS + TAIL_MS)
 
#define PROVEN_FRAMES   2.0
 
#define TG_MS   ISS_GUARD_MS /* S's slot opens this long after the end */
 
#define TURN_G_MS   GUARD_MS /* M's guard either side of a slot */
 
#define D_OFDM_MS   1000 /* the latest S decodes an M keydown: OFDM, */
 
#define D_MFSK_MS   4500 /* MFSK (on air ~3.7 s after the unkey), */
 
#define D_PAT_MS   800 /* a pattern (detected ~0.24 s after it) */
 
#define LEAD_MAX_MS   (110 + 300) /* tx delay and head silence, with a margin */
 
#define K_FLOOR   2 /* continuations of a floor stream */
 
#define K_ABOVE   0 /* ...above the floor none: M re-polls */
 
#define S_FALLBACK_MS   90000
 
#define IDLE_POLL_MIN_MS   3000
 
#define IDLE_POLL_MAX_MS   60000 /* doubling up to this */
 
#define APP_GRACE_MS   1000
 
#define OFFER_RECENT_MS   120000
 
#define DATAC3_START_MARGIN_DB   2.0f
 
#define PAT_MIN_MS   (110 + PATTERN_AIR_MS)
 

Enumerations

enum  { M_DATA , M_POLL , M_REQ , M_STATUS }
 
enum  {
  KD_NONE , KD_POLL , KD_ROUND , KD_PATTERN_ACK ,
  KD_PATTERN_BREAK , KD_REQ , KD_DONE , KD_BOTH
}
 
enum  { PH_IDLE , PH_SEND , PH_RECV }
 
enum  { MS_WAIT , MS_PLAN , MS_IDLE }
 
enum  {
  ANC_POLL , ANC_DONE , ANC_ROUND , ANC_REQ ,
  ANC_PATTERN , ANC_BOTH
}
 

Functions

void car_set_nav_ms (uint32_t ms)
 
void car_set_nav_below_db (float db)
 
void car_set_nav_loss (double loss)
 
bool car_wants_nav (const car_t *c)
 
static uint32_t nav_lead (const car_t *c)
 
static uint32_t burst_gap_ms (int lv)
 
int car_level_mode (int level)
 
static bool has_data (const car_t *c)
 
static bool peer_direction_done (const car_t *c)
 
bool car_is_idle (const car_t *c)
 
size_t car_tx_inflight (const car_t *c)
 
const char * car_failed (const car_t *c)
 
int car_overruns (const car_t *c)
 
static uint64_t mslot_lo (const car_t *c, const car_mlog_t *l, int i)
 
static uint64_t mslot_hi (const car_t *c, const car_mlog_t *l, int i)
 
bool car_slot_reserved (const car_t *m, uint64_t start, uint64_t end)
 
static uint32_t crc32_step (uint32_t crc, const uint8_t *p, size_t n)
 
static int piece_of (const car_t *c)
 
static uint32_t block_check (const car_t *c, uint8_t id, int K, const uint8_t(*piece)[CAR_PIECE], int n)
 
static int level_of_mode (int mode)
 
static int mode_payload (int mode)
 
static uint64_t mode_air (int mode)
 
static uint64_t level_air (int lv)
 
static bool ctl_on_floor (const car_t *c)
 
static bool peer_ctl_on_floor (const car_t *c)
 
static int pieces_per_frame (const car_t *c, int lv)
 
static bool inline_ok (int lv)
 
static bool inline_poll (const car_t *c)
 
static uint64_t round_air (int lv, int n)
 
static int keydown_cap (int lv)
 
static int round_n (const car_t *c)
 
static bool both_ok (const car_t *c, int lv)
 
static bool offer_both (car_t *c, uint64_t now)
 
static uint64_t turn_quantum (int lv)
 
static uint64_t turn_cap (int lv)
 
static void encode_ctl (const msg_t *m, uint8_t *b)
 
static void put_ctl (const car_t *c, car_frame_t *f, const msg_t *m)
 
static bool decode_ctl (const uint8_t *b, size_t len, msg_t *m)
 
static bool decode_data (const uint8_t *b, size_t len, msg_t *m, int P)
 
static void put_seg_hdr (uint8_t *p, const car_sblock_t *s, int count, int first, int P)
 
static uint8_t resolve16 (uint8_t base, int v4)
 
static void car_trace (const car_t *c, const char *fmt,...)
 
static void arm (car_t *c, int t, uint64_t at)
 
uint64_t car_next_deadline (const car_t *c)
 
static bool peer_keyed (car_t *c, uint64_t now)
 
static bool defer_if_busy (car_t *c, int t, uint64_t now)
 
static void keydown (car_t *c, car_frame_t *fr, int n)
 
static void bind_rx (car_t *c, int lv)
 
static bool unopened (const car_t *c)
 
static int block_k_for (const car_t *c, int lv)
 
static void open_block (car_t *c, int max_k)
 
static void piece_bytes (const car_sblock_t *s, int idx, uint8_t *out, int P)
 
static void apply_need (car_t *c, const msg_t *m)
 
static int build_round (car_t *c, int lv, int n, uint32_t poll_id, car_frame_t *fr, int reserve0)
 
static double level_rate (const car_t *c, int lv)
 
static float level_min_db (int lv)
 
static bool level_marginal (const car_t *c, int lv)
 
static double level_delivery (const car_t *c, int lv)
 
static bool level_dead (const car_t *c, int lv)
 
static void measure_level (car_t *c, int lv, int frames, double loss, uint64_t now)
 
static bool level_gated (const car_t *c, int lv)
 
static bool level_allowed (const car_t *c, int lv)
 
static bool reprobe_due (const car_t *c, int lv, uint64_t now)
 
static uint64_t round_overhead (const car_t *c, int lv)
 
void car_rung_geometry (int lv, bool floor_patterns, int *bytes_per_frame, int *frames, uint64_t *round_air_ms, uint64_t *overhead_ms)
 
static double air_fraction (const car_t *c, int lv, int frames)
 
static int level_earned (const car_t *c, int lv)
 
static double level_goodput (const car_t *c, int lv)
 
static double level_potential (const car_t *c, int lv)
 
static int probe_every (const car_t *c, int lv)
 
static int cap_level (const car_t *c, int lv)
 
static int choose_level (const car_t *c, uint64_t now)
 
static int peer_outstanding (const car_t *c)
 
static int poll_size (const car_t *c, int lv, uint64_t now)
 
static void decode_block (car_t *c, car_rblock_t *r)
 
static void deliver_in_order (car_t *c)
 
static void fill_poll (car_t *c, msg_t *m)
 
static void take_pieces (car_t *c, const msg_t *m)
 
static uint32_t ctl_air_max (const car_t *c)
 
static uint32_t s_ctl_for (const car_t *c, bool deaf)
 
static uint32_t s_ctl_ms (const car_t *c)
 
static uint32_t s_round_ms (int lv, int n)
 
static uint32_t s_pat_ms (void)
 
static uint32_t r_cap_ms (void)
 
static uint32_t d_of_mode (int mode)
 
static uint32_t slot_period (const car_t *c, uint32_t d, uint32_t r)
 
static uint32_t r_floor_ms (void)
 
static void m_log_add (car_t *c, uint64_t e)
 
static uint64_t m_free_from (const car_t *c, uint64_t s, uint64_t len)
 
static void m_close_from (car_t *c, int j, int i)
 
static void m_close_slot (car_t *c, uint64_t te, int mk, bool pat, int slot)
 
static int send_poll_ex (car_t *c, int lv, int n, uint8_t id, bool with_round)
 
static void send_poll (car_t *c, int lv, int n, uint8_t id)
 
static void send_pattern (car_t *c, int kind)
 
static void send_status (car_t *c, uint8_t id)
 
static bool send_round (car_t *c, uint8_t id)
 
static void send_req (car_t *c, uint8_t id)
 
static bool tx_on_pattern (car_t *c, int kind)
 
static int floor_poll_every (const car_t *c)
 
static void rx_trace (car_t *c)
 
static void rx_measure (car_t *c, int lv, uint64_t now)
 
static int rx_next (car_t *c, uint64_t now, int *plv, int *pn)
 
static void rx_frame (car_t *c, const msg_t *m, int lv, bool counts)
 
static void m_enter (car_t *c, int phase, uint64_t now)
 
static void m_plan (car_t *c, int kind, int lv, int n)
 
static uint64_t kind_len (const car_t *c, int kind)
 
static uint64_t plan_len (const car_t *c)
 
static void m_note (car_t *c, int kind, uint32_t r, uint32_t d, int k, uint32_t rp)
 
static uint32_t my_ctl_d (const car_t *c)
 
static void m_key_plan (car_t *c)
 
static bool ack_can_carry (const car_t *c, uint64_t now)
 
static void m_try (car_t *c, uint64_t now)
 
static void m_start_recv (car_t *c, uint64_t now)
 
static void m_decide_idle (car_t *c, uint64_t now)
 
static void m_decide_send (car_t *c, uint64_t now)
 
static void m_decide_recv (car_t *c, uint64_t now)
 
static void m_decide (car_t *c, uint64_t now)
 
static void m_timer (car_t *c, uint64_t now)
 
static void m_heard_end (car_t *c, uint64_t te, int mk, bool pat, int slot)
 
static void m_on_data (car_t *c, uint64_t now, const msg_t *m, int lv)
 
static void m_on_ctl (car_t *c, uint64_t now, const msg_t *m)
 
static void s_anchor (car_t *c, int kind, uint8_t mk, uint64_t eh, uint32_t d, int k, uint32_t rp)
 
static void s_heard_m (car_t *c, uint64_t now)
 
static void s_answer (car_t *c, uint64_t now, bool req)
 
static void s_answer_both (car_t *c, uint64_t now)
 
static void s_slot (car_t *c, uint64_t now)
 
static void s_on_data (car_t *c, uint64_t now, const msg_t *m, int lv)
 
static void s_on_ctl (car_t *c, uint64_t now, const msg_t *m, int mode)
 
int car_start_level (float snr_db)
 
void car_init (car_t *c, const car_io_t *io, int rx_level, int tx_level)
 
int car_max_level_for_bw (int bw_hz)
 
void car_set_max_level (car_t *c, int lv)
 
int car_piece_for_start (int caller_start_level)
 
int car_piece (const car_t *c)
 
int car_ui_tx_mode (const car_t *c)
 
int car_ui_rx_mode (const car_t *c)
 
int car_ui_peer_mode (const car_t *c)
 
void car_start_sender (car_t *c, uint64_t now)
 
void car_start_receiver (car_t *c, uint64_t now)
 
static void note_peer_ctl_deaf (car_t *c, bool deaf)
 
bool car_peer_ctl_deaf (const car_t *c)
 
void car_seed_ctl_deaf (car_t *c, bool mine, bool peers)
 
void car_on_frame (car_t *c, uint64_t now, const uint8_t *bytes, size_t len, int mode, bool control, float snr_db, uint32_t age_ms)
 
void car_on_tx_done (car_t *c, uint64_t now)
 
static bool pattern_in_time (const car_t *c, uint64_t now)
 
void car_on_pattern (car_t *c, uint64_t now, int kind)
 
bool car_expect_pattern (const car_t *c)
 
void car_on_app_data (car_t *c, uint64_t now)
 
void car_on_time (car_t *c, uint64_t now)
 
uint64_t car_drain_budget_ms (const car_t *c)
 
bool car_is_master (const car_t *c)
 
uint64_t car_free_at (const car_t *c, uint64_t now, uint64_t len)
 
void car_log_ctl (car_t *c, uint64_t end, uint32_t tg)
 
void car_request_end (car_t *c)
 

Variables

static uint32_t g_nav_ms
 
static float g_nav_below_db = 99.0f
 
static double g_nav_loss = 0.3
 
static const int LADDER [CAR_NLEVELS]
 
struct { 
 
   int   mode 
 
   float   min_db 
 
} START [] 
 
struct { 
 
   int   bw_hz 
 
   int   top_mode 
 
} BW_TOP [] 
 

Macro Definition Documentation

◆ APP_GRACE_MS

#define APP_GRACE_MS   1000

◆ BLOCK_AIR_MS

#define BLOCK_AIR_MS   60000

◆ BLOCK_CHECK

#define BLOCK_CHECK   4

◆ BLOCK_MIN_K

#define BLOCK_MIN_K   8

◆ CARRIER_CHECK_MS

#define CARRIER_CHECK_MS   250 /* carrier re-checked this often */

◆ CHAIN_GAP_MS

#define CHAIN_GAP_MS   ARQ_ACK_DATA_GAP_MS /* poll -> first burst, one keydown */

◆ CTL_DEAF_OFF_DB

#define CTL_DEAF_OFF_DB   (ARQ_SNR_MIN_DATAC15_DB + 1.0f)

◆ CTL_DEAF_ON_DB

#define CTL_DEAF_ON_DB   (ARQ_SNR_MIN_DATAC15_DB - 0.5f)

◆ CTL_FLOOR_MARK

#define CTL_FLOOR_MARK   0x07

◆ CTL_SEG_K1

#define CTL_SEG_K1   127

◆ D_MFSK_MS

#define D_MFSK_MS   4500 /* MFSK (on air ~3.7 s after the unkey), */

◆ D_OFDM_MS

#define D_OFDM_MS   1000 /* the latest S decodes an M keydown: OFDM, */

◆ D_PAT_MS

#define D_PAT_MS   800 /* a pattern (detected ~0.24 s after it) */

◆ DATAC3_START_MARGIN_DB

#define DATAC3_START_MARGIN_DB   2.0f

◆ DEAD_P

#define DEAD_P   0.02

◆ DEAD_PROBE_MAX_MS

#define DEAD_PROBE_MAX_MS   480000 /* ...doubling to at most this */

◆ DEAD_PROBE_MS

#define DEAD_PROBE_MS   60000 /* a dead rung is re-probed after this... */

◆ DEAD_RUN

#define DEAD_RUN   4 /* consecutive frames lost, none delivered: dead */

◆ FB_UNSEEN

#define FB_UNSEEN   255

◆ FLOOR_ANSWER_MS

#define FLOOR_ANSWER_MS   4000

◆ FLOOR_DEEP_DB

#define FLOOR_DEEP_DB   3.0f

◆ FLOOR_DELAY_MARGIN_MS

#define FLOOR_DELAY_MARGIN_MS   2000

◆ FLOOR_LATE_MS

#define FLOOR_LATE_MS   9000

◆ FLOOR_OVERHEAD_MS

#define FLOOR_OVERHEAD_MS   (PATTERN_AIR_MS + GUARD_MS + ISS_GUARD_MS + HEAD_MS + TAIL_MS)

◆ FLOOR_POLL_EVERY

#define FLOOR_POLL_EVERY   4

◆ FLOOR_POLL_EVERY_DEEP

#define FLOOR_POLL_EVERY_DEEP   12

◆ FLOOR_SENSE_MS

#define FLOOR_SENSE_MS   3000

◆ FLOOR_SILENT_MAX

#define FLOOR_SILENT_MAX   6

◆ FRAME_HDR

#define FRAME_HDR   2

◆ GUARD_MS

#define GUARD_MS   ARQ_CHANNEL_GUARD_MS

◆ HANDOVER_SOON_MS

#define HANDOVER_SOON_MS   5000

◆ HEAD_MS

#define HEAD_MS   (110 + nav_lead(c))

◆ IDLE_POLL_MAX_MS

#define IDLE_POLL_MAX_MS   60000 /* doubling up to this */

◆ IDLE_POLL_MIN_MS

#define IDLE_POLL_MIN_MS   3000

◆ INLINE_CTL

#define INLINE_CTL   (SEG_HDR + CAR_POLL_BYTES)

◆ ISS_GUARD_MS

#define ISS_GUARD_MS   ARQ_ISS_POST_ACK_GUARD_MS

◆ K_ABOVE

#define K_ABOVE   0 /* ...above the floor none: M re-polls */

◆ K_FLOOR

#define K_FLOOR   2 /* continuations of a floor stream */

◆ LEAD_MAX_MS

#define LEAD_MAX_MS   (110 + 300) /* tx delay and head silence, with a margin */

◆ LV_DECAY

#define LV_DECAY   0.8 /* per measured round: memory of ~5 frames */

◆ MAX_KEYDOWN_MS

#define MAX_KEYDOWN_MS   30000 /* airtime cap per round */

◆ OFFER_RECENT_MS

#define OFFER_RECENT_MS   120000

◆ PAT_MIN_MS

#define PAT_MIN_MS   (110 + PATTERN_AIR_MS)

◆ PATTERN_AIR_MS

#define PATTERN_AIR_MS   640

◆ PATTERN_SENSE_EXTRA_MS

#define PATTERN_SENSE_EXTRA_MS   2000

◆ PROBE_EVERY

#define PROBE_EVERY   8 /* polls before a measured rung is re-probed... */

◆ PROBE_UP_DELIVERY

#define PROBE_UP_DELIVERY   0.5 /* the best must deliver this well to probe above it */

◆ PROVEN_FRAMES

#define PROVEN_FRAMES   2.0

◆ RESEND_RUN

#define RESEND_RUN   2 /* pieces repeated from the receiver's gap */

◆ ROUND_OVERHEAD_MS

#define ROUND_OVERHEAD_MS   (4400 + GUARD_MS + ISS_GUARD_MS + HEAD_MS + TAIL_MS)

◆ S_FALLBACK_MS

#define S_FALLBACK_MS   90000

◆ SEG_HDR

#define SEG_HDR   4

◆ SENDER_SILENCE_MS

#define SENDER_SILENCE_MS   90000 /* sender heard no poll this long: nudge */

◆ SENSE_MS

#define SENSE_MS   1400 /* after keying, the sender is heard by now */

◆ SLOW_RUNG_FRAMES

#define SLOW_RUNG_FRAMES   3 /* round cap on the two slowest rungs */

◆ SNR_GATE_DB

#define SNR_GATE_DB   3.0f

◆ TAIL_MS

#define TAIL_MS   200

◆ TG_MS

#define TG_MS   ISS_GUARD_MS /* S's slot opens this long after the end */

◆ TURN_CAP_MS

#define TURN_CAP_MS   45000

◆ TURN_G_MS

#define TURN_G_MS   GUARD_MS /* M's guard either side of a slot */

◆ TURN_QUANTUM_MS

#define TURN_QUANTUM_MS   30000

◆ WINDOW_MARGIN_MS

#define WINDOW_MARGIN_MS   1000 /* a round that never came: re-poll after this */

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
M_DATA 
M_POLL 
M_REQ 
M_STATUS 

◆ anonymous enum

anonymous enum
Enumerator
KD_NONE 
KD_POLL 
KD_ROUND 
KD_PATTERN_ACK 
KD_PATTERN_BREAK 
KD_REQ 
KD_DONE 
KD_BOTH 

◆ anonymous enum

anonymous enum
Enumerator
PH_IDLE 
PH_SEND 
PH_RECV 

◆ anonymous enum

anonymous enum
Enumerator
MS_WAIT 
MS_PLAN 
MS_IDLE 

◆ anonymous enum

anonymous enum
Enumerator
ANC_POLL 
ANC_DONE 
ANC_ROUND 
ANC_REQ 
ANC_PATTERN 
ANC_BOTH 

Function Documentation

◆ ack_can_carry()

static bool ack_can_carry ( const car_t *  c,
uint64_t  now 
)
static

◆ air_fraction()

static double air_fraction ( const car_t *  c,
int  lv,
int  frames 
)
static

◆ apply_need()

static void apply_need ( car_t *  c,
const msg_t *  m 
)
static

◆ arm()

static void arm ( car_t *  c,
int  t,
uint64_t  at 
)
static

◆ bind_rx()

static void bind_rx ( car_t *  c,
int  lv 
)
static

◆ block_check()

static uint32_t block_check ( const car_t *  c,
uint8_t  id,
int  K,
const uint8_t(*)  piece[CAR_PIECE],
int  n 
)
static

◆ block_k_for()

static int block_k_for ( const car_t *  c,
int  lv 
)
static

◆ both_ok()

static bool both_ok ( const car_t *  c,
int  lv 
)
static

◆ build_round()

static int build_round ( car_t *  c,
int  lv,
int  n,
uint32_t  poll_id,
car_frame_t *  fr,
int  reserve0 
)
static

◆ burst_gap_ms()

static uint32_t burst_gap_ms ( int  lv)
static

◆ cap_level()

static int cap_level ( const car_t *  c,
int  lv 
)
static

◆ car_drain_budget_ms()

uint64_t car_drain_budget_ms ( const car_t *  c)

◆ car_expect_pattern()

bool car_expect_pattern ( const car_t *  c)

◆ car_failed()

const char * car_failed ( const car_t *  c)

◆ car_free_at()

uint64_t car_free_at ( const car_t *  c,
uint64_t  now,
uint64_t  len 
)

◆ car_init()

void car_init ( car_t *  c,
const car_io_t *  io,
int  rx_level,
int  tx_level 
)

◆ car_is_idle()

bool car_is_idle ( const car_t *  c)

◆ car_is_master()

bool car_is_master ( const car_t *  c)

◆ car_level_mode()

int car_level_mode ( int  level)

◆ car_log_ctl()

void car_log_ctl ( car_t *  c,
uint64_t  end,
uint32_t  tg 
)

◆ car_max_level_for_bw()

int car_max_level_for_bw ( int  bw_hz)

◆ car_next_deadline()

uint64_t car_next_deadline ( const car_t *  c)

◆ car_on_app_data()

void car_on_app_data ( car_t *  c,
uint64_t  now 
)

◆ car_on_frame()

void car_on_frame ( car_t *  c,
uint64_t  now,
const uint8_t *  bytes,
size_t  len,
int  mode,
bool  control,
float  snr_db,
uint32_t  age_ms 
)

◆ car_on_pattern()

void car_on_pattern ( car_t *  c,
uint64_t  now,
int  kind 
)

◆ car_on_time()

void car_on_time ( car_t *  c,
uint64_t  now 
)

◆ car_on_tx_done()

void car_on_tx_done ( car_t *  c,
uint64_t  now 
)

◆ car_overruns()

int car_overruns ( const car_t *  c)

◆ car_peer_ctl_deaf()

bool car_peer_ctl_deaf ( const car_t *  c)

◆ car_piece()

int car_piece ( const car_t *  c)

◆ car_piece_for_start()

int car_piece_for_start ( int  caller_start_level)

◆ car_request_end()

void car_request_end ( car_t *  c)

◆ car_rung_geometry()

void car_rung_geometry ( int  lv,
bool  floor_patterns,
int *  bytes_per_frame,
int *  frames,
uint64_t *  round_air_ms,
uint64_t *  overhead_ms 
)

◆ car_seed_ctl_deaf()

void car_seed_ctl_deaf ( car_t *  c,
bool  mine,
bool  peers 
)

◆ car_set_max_level()

void car_set_max_level ( car_t *  c,
int  lv 
)

◆ car_set_nav_below_db()

void car_set_nav_below_db ( float  db)

◆ car_set_nav_loss()

void car_set_nav_loss ( double  loss)

◆ car_set_nav_ms()

void car_set_nav_ms ( uint32_t  ms)

◆ car_slot_reserved()

bool car_slot_reserved ( const car_t *  m,
uint64_t  start,
uint64_t  end 
)

◆ car_start_level()

int car_start_level ( float  snr_db)

◆ car_start_receiver()

void car_start_receiver ( car_t *  c,
uint64_t  now 
)

◆ car_start_sender()

void car_start_sender ( car_t *  c,
uint64_t  now 
)

◆ car_trace()

static void car_trace ( const car_t *  c,
const char *  fmt,
  ... 
)
static

◆ car_tx_inflight()

size_t car_tx_inflight ( const car_t *  c)

◆ car_ui_peer_mode()

int car_ui_peer_mode ( const car_t *  c)

◆ car_ui_rx_mode()

int car_ui_rx_mode ( const car_t *  c)

◆ car_ui_tx_mode()

int car_ui_tx_mode ( const car_t *  c)

◆ car_wants_nav()

bool car_wants_nav ( const car_t *  c)

◆ choose_level()

static int choose_level ( const car_t *  c,
uint64_t  now 
)
static

◆ crc32_step()

static uint32_t crc32_step ( uint32_t  crc,
const uint8_t *  p,
size_t  n 
)
static

◆ ctl_air_max()

static uint32_t ctl_air_max ( const car_t *  c)
static

◆ ctl_on_floor()

static bool ctl_on_floor ( const car_t *  c)
static

◆ d_of_mode()

static uint32_t d_of_mode ( int  mode)
static

◆ decode_block()

static void decode_block ( car_t *  c,
car_rblock_t *  r 
)
static

◆ decode_ctl()

static bool decode_ctl ( const uint8_t *  b,
size_t  len,
msg_t *  m 
)
static

◆ decode_data()

static bool decode_data ( const uint8_t *  b,
size_t  len,
msg_t *  m,
int  P 
)
static

◆ defer_if_busy()

static bool defer_if_busy ( car_t *  c,
int  t,
uint64_t  now 
)
static

◆ deliver_in_order()

static void deliver_in_order ( car_t *  c)
static

◆ encode_ctl()

static void encode_ctl ( const msg_t *  m,
uint8_t *  b 
)
static

◆ fill_poll()

static void fill_poll ( car_t *  c,
msg_t *  m 
)
static

◆ floor_poll_every()

static int floor_poll_every ( const car_t *  c)
static

◆ has_data()

static bool has_data ( const car_t *  c)
static

◆ inline_ok()

static bool inline_ok ( int  lv)
static

◆ inline_poll()

static bool inline_poll ( const car_t *  c)
static

◆ keydown()

static void keydown ( car_t *  c,
car_frame_t *  fr,
int  n 
)
static

◆ keydown_cap()

static int keydown_cap ( int  lv)
static

◆ kind_len()

static uint64_t kind_len ( const car_t *  c,
int  kind 
)
static

◆ level_air()

static uint64_t level_air ( int  lv)
static

◆ level_allowed()

static bool level_allowed ( const car_t *  c,
int  lv 
)
static

◆ level_dead()

static bool level_dead ( const car_t *  c,
int  lv 
)
static

◆ level_delivery()

static double level_delivery ( const car_t *  c,
int  lv 
)
static

◆ level_earned()

static int level_earned ( const car_t *  c,
int  lv 
)
static

◆ level_gated()

static bool level_gated ( const car_t *  c,
int  lv 
)
static

◆ level_goodput()

static double level_goodput ( const car_t *  c,
int  lv 
)
static

◆ level_marginal()

static bool level_marginal ( const car_t *  c,
int  lv 
)
static

◆ level_min_db()

static float level_min_db ( int  lv)
static

◆ level_of_mode()

static int level_of_mode ( int  mode)
static

◆ level_potential()

static double level_potential ( const car_t *  c,
int  lv 
)
static

◆ level_rate()

static double level_rate ( const car_t *  c,
int  lv 
)
static

◆ m_close_from()

static void m_close_from ( car_t *  c,
int  j,
int  i 
)
static

◆ m_close_slot()

static void m_close_slot ( car_t *  c,
uint64_t  te,
int  mk,
bool  pat,
int  slot 
)
static

◆ m_decide()

static void m_decide ( car_t *  c,
uint64_t  now 
)
static

◆ m_decide_idle()

static void m_decide_idle ( car_t *  c,
uint64_t  now 
)
static

◆ m_decide_recv()

static void m_decide_recv ( car_t *  c,
uint64_t  now 
)
static

◆ m_decide_send()

static void m_decide_send ( car_t *  c,
uint64_t  now 
)
static

◆ m_enter()

static void m_enter ( car_t *  c,
int  phase,
uint64_t  now 
)
static

◆ m_free_from()

static uint64_t m_free_from ( const car_t *  c,
uint64_t  s,
uint64_t  len 
)
static

◆ m_heard_end()

static void m_heard_end ( car_t *  c,
uint64_t  te,
int  mk,
bool  pat,
int  slot 
)
static

◆ m_key_plan()

static void m_key_plan ( car_t *  c)
static

◆ m_log_add()

static void m_log_add ( car_t *  c,
uint64_t  e 
)
static

◆ m_note()

static void m_note ( car_t *  c,
int  kind,
uint32_t  r,
uint32_t  d,
int  k,
uint32_t  rp 
)
static

◆ m_on_ctl()

static void m_on_ctl ( car_t *  c,
uint64_t  now,
const msg_t *  m 
)
static

◆ m_on_data()

static void m_on_data ( car_t *  c,
uint64_t  now,
const msg_t *  m,
int  lv 
)
static

◆ m_plan()

static void m_plan ( car_t *  c,
int  kind,
int  lv,
int  n 
)
static

◆ m_start_recv()

static void m_start_recv ( car_t *  c,
uint64_t  now 
)
static

◆ m_timer()

static void m_timer ( car_t *  c,
uint64_t  now 
)
static

◆ m_try()

static void m_try ( car_t *  c,
uint64_t  now 
)
static

◆ measure_level()

static void measure_level ( car_t *  c,
int  lv,
int  frames,
double  loss,
uint64_t  now 
)
static

◆ mode_air()

static uint64_t mode_air ( int  mode)
static

◆ mode_payload()

static int mode_payload ( int  mode)
static

◆ mslot_hi()

static uint64_t mslot_hi ( const car_t *  c,
const car_mlog_t *  l,
int  i 
)
static

◆ mslot_lo()

static uint64_t mslot_lo ( const car_t *  c,
const car_mlog_t *  l,
int  i 
)
static

◆ my_ctl_d()

static uint32_t my_ctl_d ( const car_t *  c)
static

◆ nav_lead()

static uint32_t nav_lead ( const car_t *  c)
static

◆ note_peer_ctl_deaf()

static void note_peer_ctl_deaf ( car_t *  c,
bool  deaf 
)
static

◆ offer_both()

static bool offer_both ( car_t *  c,
uint64_t  now 
)
static

◆ open_block()

static void open_block ( car_t *  c,
int  max_k 
)
static

◆ pattern_in_time()

static bool pattern_in_time ( const car_t *  c,
uint64_t  now 
)
static

◆ peer_ctl_on_floor()

static bool peer_ctl_on_floor ( const car_t *  c)
static

◆ peer_direction_done()

static bool peer_direction_done ( const car_t *  c)
static

◆ peer_keyed()

static bool peer_keyed ( car_t *  c,
uint64_t  now 
)
static

◆ peer_outstanding()

static int peer_outstanding ( const car_t *  c)
static

◆ piece_bytes()

static void piece_bytes ( const car_sblock_t *  s,
int  idx,
uint8_t *  out,
int  P 
)
static

◆ piece_of()

static int piece_of ( const car_t *  c)
static

◆ pieces_per_frame()

static int pieces_per_frame ( const car_t *  c,
int  lv 
)
static

◆ plan_len()

static uint64_t plan_len ( const car_t *  c)
static

◆ poll_size()

static int poll_size ( const car_t *  c,
int  lv,
uint64_t  now 
)
static

◆ probe_every()

static int probe_every ( const car_t *  c,
int  lv 
)
static

◆ put_ctl()

static void put_ctl ( const car_t *  c,
car_frame_t *  f,
const msg_t *  m 
)
static

◆ put_seg_hdr()

static void put_seg_hdr ( uint8_t *  p,
const car_sblock_t *  s,
int  count,
int  first,
int  P 
)
static

◆ r_cap_ms()

static uint32_t r_cap_ms ( void  )
static

◆ r_floor_ms()

static uint32_t r_floor_ms ( void  )
static

◆ reprobe_due()

static bool reprobe_due ( const car_t *  c,
int  lv,
uint64_t  now 
)
static

◆ resolve16()

static uint8_t resolve16 ( uint8_t  base,
int  v4 
)
static

◆ round_air()

static uint64_t round_air ( int  lv,
int  n 
)
static

◆ round_n()

static int round_n ( const car_t *  c)
static

◆ round_overhead()

static uint64_t round_overhead ( const car_t *  c,
int  lv 
)
static

◆ rx_frame()

static void rx_frame ( car_t *  c,
const msg_t *  m,
int  lv,
bool  counts 
)
static

◆ rx_measure()

static void rx_measure ( car_t *  c,
int  lv,
uint64_t  now 
)
static

◆ rx_next()

static int rx_next ( car_t *  c,
uint64_t  now,
int *  plv,
int *  pn 
)
static

◆ rx_trace()

static void rx_trace ( car_t *  c)
static

◆ s_anchor()

static void s_anchor ( car_t *  c,
int  kind,
uint8_t  mk,
uint64_t  eh,
uint32_t  d,
int  k,
uint32_t  rp 
)
static

◆ s_answer()

static void s_answer ( car_t *  c,
uint64_t  now,
bool  req 
)
static

◆ s_answer_both()

static void s_answer_both ( car_t *  c,
uint64_t  now 
)
static

◆ s_ctl_for()

static uint32_t s_ctl_for ( const car_t *  c,
bool  deaf 
)
static

◆ s_ctl_ms()

static uint32_t s_ctl_ms ( const car_t *  c)
static

◆ s_heard_m()

static void s_heard_m ( car_t *  c,
uint64_t  now 
)
static

◆ s_on_ctl()

static void s_on_ctl ( car_t *  c,
uint64_t  now,
const msg_t *  m,
int  mode 
)
static

◆ s_on_data()

static void s_on_data ( car_t *  c,
uint64_t  now,
const msg_t *  m,
int  lv 
)
static

◆ s_pat_ms()

static uint32_t s_pat_ms ( void  )
static

◆ s_round_ms()

static uint32_t s_round_ms ( int  lv,
int  n 
)
static

◆ s_slot()

static void s_slot ( car_t *  c,
uint64_t  now 
)
static

◆ send_pattern()

static void send_pattern ( car_t *  c,
int  kind 
)
static

◆ send_poll()

static void send_poll ( car_t *  c,
int  lv,
int  n,
uint8_t  id 
)
static

◆ send_poll_ex()

static int send_poll_ex ( car_t *  c,
int  lv,
int  n,
uint8_t  id,
bool  with_round 
)
static

◆ send_req()

static void send_req ( car_t *  c,
uint8_t  id 
)
static

◆ send_round()

static bool send_round ( car_t *  c,
uint8_t  id 
)
static

◆ send_status()

static void send_status ( car_t *  c,
uint8_t  id 
)
static

◆ slot_period()

static uint32_t slot_period ( const car_t *  c,
uint32_t  d,
uint32_t  r 
)
static

◆ take_pieces()

static void take_pieces ( car_t *  c,
const msg_t *  m 
)
static

◆ turn_cap()

static uint64_t turn_cap ( int  lv)
static

◆ turn_quantum()

static uint64_t turn_quantum ( int  lv)
static

◆ tx_on_pattern()

static bool tx_on_pattern ( car_t *  c,
int  kind 
)
static

◆ unopened()

static bool unopened ( const car_t *  c)
static

Variable Documentation

◆ bw_hz

int bw_hz

◆ [struct]

const struct { ... } BW_TOP[]
Initial value:
= {
{ ARQ_BANDWIDTH_NARROW_HZ, FREEDV_MODE_DATAC3 },
{ ARQ_BANDWIDTH_FULL_HZ, FREEDV_MODE_QAM16C2 },
{ ARQ_BANDWIDTH_TACTICAL_HZ, FREEDV_MODE_QAM16C2 },
}
#define ARQ_BANDWIDTH_NARROW_HZ
Definition arq.h:27
#define ARQ_BANDWIDTH_FULL_HZ
Definition arq.h:28
#define ARQ_BANDWIDTH_TACTICAL_HZ
Definition arq.h:29

◆ g_nav_below_db

float g_nav_below_db = 99.0f
static

◆ g_nav_loss

double g_nav_loss = 0.3
static

◆ g_nav_ms

uint32_t g_nav_ms
static

◆ LADDER

const int LADDER[CAR_NLEVELS]
static
Initial value:
= {
MERCURY_MODE_MFSK,
FREEDV_MODE_DATAC15, FREEDV_MODE_DATAC4, FREEDV_MODE_DATAC3,
FREEDV_MODE_DATAC1, FREEDV_MODE_DATAC17, FREEDV_MODE_QAM16C2,
}

◆ min_db

float min_db

◆ mode

int mode

◆ [struct]

const struct { ... } START[]
Initial value:
= {
{ FREEDV_MODE_QAM16C2, ARQ_SNR_MIN_QAM16C2_DB }, { FREEDV_MODE_DATAC17, ARQ_SNR_MIN_DATAC17_DB },
{ FREEDV_MODE_DATAC1, ARQ_SNR_MIN_DATAC1_DB },
{ FREEDV_MODE_DATAC15, -3.0f - ARQ_SNR_HYST_DB },
}
#define ARQ_SNR_MIN_DATAC3_DB
Definition arq_protocol.h:217
#define ARQ_SNR_HYST_DB
Definition arq_protocol.h:214
#define ARQ_SNR_MIN_QAM16C2_DB
Definition arq_protocol.h:220
#define ARQ_SNR_MIN_DATAC17_DB
Definition arq_protocol.h:219
#define ARQ_SNR_MIN_DATAC1_DB
Definition arq_protocol.h:218
#define DATAC3_START_MARGIN_DB
Definition carousel.c:2329

◆ top_mode

int top_mode