Skip to content

--print-airtime answers for the chip's defaults, not the flags it was given #10

Description

@A13xB0

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions