Problem
--print-airtime always answers for the chip's constructed defaults, whatever
--sf, --bw-khz and --cr say. SF7 and SF12 both report 136 ms for 64 bytes,
where they should differ by roughly forty times.
Where it goes wrong
The flags are parsed and do reach globals:
else if (!strcmp(argv[i], "--sf")) g_sf = atoi(next());
else if (!strcmp(argv[i], "--bw-khz")) g_bwKHz = (float)atof(next());
else if (!strcmp(argv[i], "--cr")) g_cr = atoi(next());
But there are two airtime paths, and they read different state:
HostRadio.cpp computes from the globals g_sf / g_bwKHz / g_cr.
VirtualSX1262::estAirtimeMs computes from the chip's own sf_, bwKHz_,
cr_ - the values the firmware programmed into the chip through
applyModulation.
--print-airtime asks the chip:
if (printAirtimeFor >= 0) {
printf("%u\n", sim_hal.chip().estAirtimeMs(printAirtimeFor));
return 0;
}
and returns before setup() has run, so nothing has programmed the chip yet.
It is still at sf_ = 10, bwKHz_ = 250, cr_ = 5 from
variants/host/VirtualSX1262.h:198-201. The flags never reach that object.
Why it matters
The self-report exists so the simulator can check that this transcription of the
airtime formula still agrees with its own, and the comment above it says why:
"Two copies of a formula that nothing compares are two formulas." Today it can
only ever compare one point, the compiled default, so a divergence at any other
spreading factor would go unnoticed.
That check is not decorative. MeshCore's CSMA timing, its duty-cycle budget and
its send timeout are all built on getEstAirtimeFor(), so if the two
transcriptions drift the simulator and the firmware disagree about how long the
air was occupied, and every collision result after that is fiction.
Suggested fix
Program the chip from the flags before printing, so --print-airtime answers
for the settings it was given. Something equivalent to applying g_sf,
g_bwKHz and g_cr to the chip in the printAirtimeFor branch, rather than
reading defaults nothing has overwritten.
Worth considering separately whether the two formulas should be one. Two
implementations reading different state is how this stayed invisible.
How it was found
MeshBench has a test asserting the two agree. It passed because it only ever
asked at the compiled default. Sweeping SF 7 to 12 at 125 and 250 kHz showed
every combination returning the same number. That test now skips loudly, naming
this repository, and starts checking again on its own once this is fixed:
this build answers 136 ms for SF12 and for SF7, so it is not applying
--sf/--bw-khz/--cr to --print-airtime and only its compiled default can be
compared; that is MeshBench/meshcore-native's to fix
Problem
--print-airtimealways answers for the chip's constructed defaults, whatever--sf,--bw-khzand--crsay. SF7 and SF12 both report 136 ms for 64 bytes,where they should differ by roughly forty times.
Where it goes wrong
The flags are parsed and do reach globals:
But there are two airtime paths, and they read different state:
HostRadio.cppcomputes from the globalsg_sf/g_bwKHz/g_cr.VirtualSX1262::estAirtimeMscomputes from the chip's ownsf_,bwKHz_,cr_- the values the firmware programmed into the chip throughapplyModulation.--print-airtimeasks the chip:and returns before
setup()has run, so nothing has programmed the chip yet.It is still at
sf_ = 10,bwKHz_ = 250,cr_ = 5fromvariants/host/VirtualSX1262.h:198-201. The flags never reach that object.Why it matters
The self-report exists so the simulator can check that this transcription of the
airtime formula still agrees with its own, and the comment above it says why:
"Two copies of a formula that nothing compares are two formulas." Today it can
only ever compare one point, the compiled default, so a divergence at any other
spreading factor would go unnoticed.
That check is not decorative. MeshCore's CSMA timing, its duty-cycle budget and
its send timeout are all built on
getEstAirtimeFor(), so if the twotranscriptions drift the simulator and the firmware disagree about how long the
air was occupied, and every collision result after that is fiction.
Suggested fix
Program the chip from the flags before printing, so
--print-airtimeanswersfor the settings it was given. Something equivalent to applying
g_sf,g_bwKHzandg_crto the chip in theprintAirtimeForbranch, rather thanreading defaults nothing has overwritten.
Worth considering separately whether the two formulas should be one. Two
implementations reading different state is how this stayed invisible.
How it was found
MeshBench has a test asserting the two agree. It passed because it only ever
asked at the compiled default. Sweeping SF 7 to 12 at 125 and 250 kHz showed
every combination returning the same number. That test now skips loudly, naming
this repository, and starts checking again on its own once this is fixed: