Skip to content

File burst_capture_core.h

File List > burst_capture > burst_capture_core.h

Go to the documentation of this file

#ifndef BURST_CAPTURE_CORE_H
#define BURST_CAPTURE_CORE_H

#include "clib_common.h"
#include "jm_perf.h"
#include "buffer/buffer.h"
#include "dp_state.h"
#include "burst_acq/burst_acq_core.h"
#include "acq/acq_core.h"
#include "corr2d/corr2d_core.h"
#include "fft2d/fft2d_core.h"
#include "fft/fft_core.h"
#include "detection/detection_core.h"
#include "pn/pn_core.h"

#define BURST_CAPTURE_HITS 16u

#define BURST_CAPTURE_STATE_MAGIC DP_FOURCC ('B', 'C', 'A', 'P')
#define BURST_CAPTURE_STATE_VERSION 2u

#ifdef __cplusplus
extern "C" {
#endif

typedef struct
{
  uint64_t preamble_start; 
  double   doppler_hz_est; 
  double   doppler_res_hz; 
  double   cn0_dbhz_est;   
  double   refine_margin;  
} burst_capture_event_t;

typedef struct
{
  uint64_t epoch;      
  double   doppler_hz; 
  double   cn0_dbhz;   
  double   test_stat;  
  double   peak_mag;   
} burst_capture_detection_t;

typedef struct
{
  uint64_t anchor;     
  uint64_t start;      
  double   doppler_hz; 
  double   cn0_dbhz;   
  double   margin;     
  double   peak_mag;   
  int      refined;    
  int      shadowed;   
} burst_capture_pending_t;

typedef struct
{
  /* ── Configuration, copied at create() ──────────────────────────────── */
  uint8_t *acq_code;     
  size_t   acq_code_len; 
  size_t   reps;         
  size_t   spc;          
  double   chip_rate;    
  /* ── Derived geometry ───────────────────────────────────────────────── */
  size_t code_period; 
  size_t burst_len;   
  /* ── The composed child ─────────────────────────────────────────────── */
  burst_acq_state_t *acq; 
  /* ── Look-back (docs/design/dsss-burst-receiver.md §7.1) ────────────── */
  dp_f32_t *hist;      
  uint64_t samples_fed; 
  /* ── The event describing the most recent window emitted ────────────── */
  uint64_t preamble_start; 
  double   doppler_hz_est; 
  double   doppler_res_hz; 
  double   cn0_dbhz_est;   
  double   refine_margin;  
  /* ── Refine scratch (docs/design/dsss-burst-receiver.md §3.4) ───────── */
  float *ref_sign;   
  float _Complex *corr_buf; 
  size_t refine_span;  
  size_t corr_len;     
  size_t min_gap;      
  size_t retain_span;  
  size_t chunk_max;    
  size_t k_lo;         
  size_t k_hi;         
  /* ── Detections in flight ────────────────────────────────────────────
   * Only detections whose burst window has NOT yet arrived live here: every
   * one whose window HAS arrived is emitted before push() returns, which is
   * what bounds retention (see the trim rule in the implementation). */
  burst_capture_pending_t *q; 
  size_t q_cap;   
  size_t q_head;  
  size_t pending; 
  /* ── The windows of the LAST push ────────────────────────────────────
   * Scratch, deliberately NOT serialized: it describes the most recent
   * push() only, so keeping it out of the blob is what lets state_bytes()
   * stay a pure function of configuration.
   *
   * The windows are COPIED here rather than left in the ring. A window in
   * the ring is a borrow whose lifetime the retention rule would have to
   * extend across the whole call, and one push can complete several bursts
   * -- so the ring would have to hold every one of them at once, which its
   * derived capacity does not promise. The cost is one memcpy per BURST,
   * not per sample, which is a different order of magnitude from the copy
   * §6.1 weighs (that one is the whole stream). It is also what lets a C
   * consumer borrow a window through burst_capture_window() and hand it
   * onward with no further copy. */
  burst_capture_detection_t *det;     
  size_t                     det_cap; 
  size_t                     det_len; 
  float _Complex *win;     
  size_t          win_cap; 
  burst_capture_event_t *ev; 
  size_t ev_cap;           
  size_t ev_len;           
  uint8_t *released;       
  uint64_t suppress_until; 
  uint64_t suppress_base;  
  size_t acq_blob_max;     
  /* ── Persistence (docs/design/burst-capture.md §9) ───────────────────── */
  int backed;   
  int recovered; 
  /* ── Diagnostics ────────────────────────────────────────────────────
   * Mirrored from the engine at create() rather than read through it on
   * demand, because jm's declared warning needs a bare bool field on THIS
   * struct -- the reason the sibling BurstAcquisition's copy of the same
   * warning has to be a hand-patch in its fragment (see the note at the top
   * of objects/burst_acq.toml). */
  int underpowered; 
  /* ── Bookkeeping ────────────────────────────────────────────────────── */
  uint64_t dropped;  
  uint64_t n_bursts; 
/*<<property_struct_fields>>*/
} burst_capture_state_t;

burst_capture_state_t *burst_capture_create (const uint8_t *acq_code,
                                             size_t acq_code_len,
                                             size_t burst_len, size_t reps,
                                             size_t spc, double chip_rate,
                                             double cn0_dbhz,
                                             double doppler_uncertainty,
                                             double pfa, double pd,
                                             int noise_mode);

burst_capture_state_t *
burst_capture_create_backed (const char *path, const uint8_t *acq_code,
                             size_t acq_code_len, size_t burst_len,
                             size_t reps, size_t spc, double chip_rate,
                             double cn0_dbhz, double doppler_uncertainty,
                             double pfa, double pd, int noise_mode);

void burst_capture_destroy (burst_capture_state_t *state);

void burst_capture_reset (burst_capture_state_t *state);

size_t burst_capture_push_max_out (burst_capture_state_t *state,
                                   size_t x_len);

size_t burst_capture_push (burst_capture_state_t *state,
                           const float _Complex *x, size_t x_len,
                           float _Complex *out, size_t max_out);

size_t burst_capture_detections_max_out (burst_capture_state_t *state,
                                         size_t n);

size_t burst_capture_detections (burst_capture_state_t *state, size_t n,
                                 burst_capture_detection_t *out,
                                 size_t max_out);

size_t burst_capture_events_max_out (burst_capture_state_t *state, size_t n);

size_t burst_capture_events (burst_capture_state_t *state, size_t n,
                             burst_capture_event_t *out, size_t max_out);

size_t burst_capture_ready (const burst_capture_state_t *state);

const float _Complex *burst_capture_window (const burst_capture_state_t *state,
                                           size_t i);

const burst_capture_event_t *
burst_capture_event_at (const burst_capture_state_t *state, size_t i);

int burst_capture_release (burst_capture_state_t *state, size_t i);

int burst_capture_configure_search_raw (burst_capture_state_t *state,
                                        size_t doppler_bins,
                                        size_t n_noncoh);

/* ── Serializable state — the elastic / pure-transducer face ──────────── */

/* ── The search this capture will do, as numbers ──────────────────────
 *
 * A capture is only as good as the search under it, and a caller sizing a
 * link needs to see that search rather than infer it. These forward the
 * engine's own figures: what a detection must clear, how deep the sizer
 * went, and how wide in Doppler and code phase it will look.
 *
 * They are read-backs, not knobs -- every one is derived at create() from
 * the parameters above, and `configure_search_raw()` is the one call that
 * moves them. */

size_t burst_capture_get_min_gap (const burst_capture_state_t *state);

double burst_capture_get_eta (const burst_capture_state_t *state);
double burst_capture_get_eta_nc (const burst_capture_state_t *state);
double burst_capture_get_straddle_loss (const burst_capture_state_t *state);
double burst_capture_get_pd_predicted (const burst_capture_state_t *state);
size_t burst_capture_get_doppler_bins (const burst_capture_state_t *state);
size_t burst_capture_get_n_noncoh (const burst_capture_state_t *state);
size_t burst_capture_get_code_bins (const burst_capture_state_t *state);
double burst_capture_get_doppler_span_hz (const burst_capture_state_t *state);

size_t burst_capture_state_bytes (const burst_capture_state_t *state);
void burst_capture_get_state (const burst_capture_state_t *state, void *blob);
int burst_capture_set_state (burst_capture_state_t *state, const void *blob);

uint64_t burst_capture_get_preamble_start(const burst_capture_state_t *state);
double burst_capture_get_doppler_hz_est(const burst_capture_state_t *state);
double burst_capture_get_doppler_res_hz(const burst_capture_state_t *state);
double burst_capture_get_cn0_dbhz_est(const burst_capture_state_t *state);
double burst_capture_get_refine_margin(const burst_capture_state_t *state);
size_t burst_capture_get_pending(const burst_capture_state_t *state);
uint64_t burst_capture_get_dropped(const burst_capture_state_t *state);
uint64_t burst_capture_get_n_bursts(const burst_capture_state_t *state);
#ifdef __cplusplus
}
#endif

#endif /* BURST_CAPTURE_CORE_H */