use kshana::clock_state::q_from_allan;
use kshana::tpl::{timing_protection_level_ns, tpl_band, TplInputs};
const ADEV_1S: f64 = 2.8e-9;
const OBSERVED_PULL_NS: f64 = 1_010_923.0;
const CLAIMED_TACC_NS: f64 = 51.0;
const MONITOR_CONSISTENCY_NS: f64 = 22.1;
fn main() {
let (q_wf, q_rw, q_drift) = q_from_allan(ADEV_1S, 4.4e-10, 1.0e-11);
let base = TplInputs {
q_wf,
q_rw,
q_drift,
r: (MONITOR_CONSISTENCY_NS * 1e-9).powi(2), tau: 1.0,
samples: 1.0,
k: 5.0,
detection_latency_s: 1.0,
};
println!("Timing Protection Level -- calibrated on JammerTest 2024 scenario 2.1.1");
println!(" receiver clock ADEV(1 s) : {:.1e}", ADEV_1S);
println!(
" OBSERVED uncontrolled pull : {:.0} ns ({:.2} ms) <- silently served",
OBSERVED_PULL_NS,
OBSERVED_PULL_NS / 1e6
);
println!(
" receiver CLAIMED accuracy : <= {:.0} ns (gap {:.0}x)",
CLAIMED_TACC_NS,
OBSERVED_PULL_NS / CLAIMED_TACC_NS
);
println!(" conditional TPL vs detection latency (given model-free detection + holdover):");
for lat in [1.0, 5.0, 10.0, 30.0, 60.0] {
let inp = TplInputs {
detection_latency_s: lat,
..base
};
let tpl = timing_protection_level_ns(&inp);
println!(
" latency {:5.0} s -> TPL {:8.0} ns ({:.0}x below the uncontrolled pull)",
lat,
tpl,
OBSERVED_PULL_NS / tpl
);
}
let band = tpl_band(
&TplInputs {
detection_latency_s: 30.0,
..base
},
1.0,
);
println!(
" red-noise-floor band @30 s : [{:.0}, {:.0}, {:.0}] ns (low, nominal, high; +/-1 decade)",
band.low_ns, band.nominal_ns, band.high_ns
);
println!(
" => even at a 60 s coast the conditional bound is far below the 1.01 ms the\n receiver accepted while reporting <= 51 ns: the protection is the holdover,\n not the receiver's own (untrustworthy) integrity flag."
);
}