Skip to content

hardware: surface modem CRC counter on TCP and USB radios#74

Merged
rightup merged 1 commit into
pyMC-dev:devfrom
yellowcooln:crc-error-count-upstream-dev
May 21, 2026
Merged

hardware: surface modem CRC counter on TCP and USB radios#74
rightup merged 1 commit into
pyMC-dev:devfrom
yellowcooln:crc-error-count-upstream-dev

Conversation

@yellowcooln
Copy link
Copy Markdown
Contributor

Summary

This PR exposes modem CRC errors through the TCPLoRaRadio and USBLoRaRadio interfaces in the way pyMC_Repeater already expects.

The modem firmware already includes crc_errors in CMD_STATUS_RESP, but the host-side radio wrappers were not copying that value onto the radio object as crc_error_count.

This change:

  • Caches modem crc_errors in both transport drivers
  • Exposes crc_error_count on the radio objects
  • Refreshes that counter during normal health checks

Problem

pyMC_Repeater records CRC errors using:

getattr(radio, "crc_error_count", 0)

This already works for local SX1262 radios, but not for pymc_usb modem transports unless the wrapper exposes the same attribute.

Before this PR:

  • Modem firmware sent crc_errors in CMD_STATUS_RESP

  • get_modem_status() parsed the field correctly

  • TCPLoRaRadio and USBLoRaRadio did not expose:

    • radio.crc_error_count

As a result, repeater-side CRC tracking remained at 0 even when the modem itself was reporting CRC errors.


What Changed

1. Added Cached CRC State to Both Radio Wrappers

Updated:

  • src/pymc_core/hardware/tcp_radio.py
  • src/pymc_core/hardware/usb_radio.py

New attributes:

  • self._crc_errors = 0
  • self.crc_error_count = 0

2. Synced Modem CRC Errors Into the Radio Object

After unpacking CMD_STATUS_RESP, both wrappers now:

  • Store status["crc_errors"] in self._crc_errors
  • Store status["crc_errors"] in self.crc_error_count

This is the core compatibility fix for repeater integration.


3. Surfaced CRC Counters in get_status()

Both wrappers now expose:

  • "crc_errors"
  • "crc_error_count"

This keeps the returned status dictionary aligned with the live cached values.


4. Refreshed Status During Normal Health Polling

Previously, health polling only refreshed the noise floor.

Now, the periodic health check refreshes:

  • Noise floor
  • Modem status

This keeps crc_error_count current during normal operation without requiring special polling paths.


Why This Is the Right Fix

The existing repeater logic already expects a radio-level attribute:

radio.crc_error_count

That means the compatibility boundary belongs inside pyMC_core transport wrappers rather than in repeater itself.

This keeps:

  • Repeater logic unchanged
  • Transport wrappers aligned with the existing radio interface contract
  • Modem-specific status normalized into the standard radio abstraction

Files Changed

  • src/pymc_core/hardware/tcp_radio.py
  • src/pymc_core/hardware/usb_radio.py

Behavior After This PR

When a pymc_usb modem reports CRC errors in CMD_STATUS_RESP:

  • TCPLoRaRadio.crc_error_count updates
  • USBLoRaRadio.crc_error_count updates
  • Repeater storage records CRC error deltas without repeater-side changes
  • Existing API/dashboard paths can surface modem CRC history correctly

Testing

Validated by:

  • Patching both wrappers
  • Successfully compiling both modules with py_compile
  • Running patched pyMC_core against a live repeater install
  • Confirming radio objects expose crc_error_count
  • Confirming repeater storage and API record modem CRC errors after malformed modem frames were injected

Observed on a live system:

  • Modem reported CRC errors
  • Repeater database recorded CRC deltas
  • Authenticated repeater API returned non-zero CRC totals/history

Scope

This PR is intentionally narrow:

  • No repeater code changes
  • No firmware protocol changes
  • No repeater API schema changes
  • Only pyMC_core transport wrapper behavior changes

This is a compatibility fix so pymc_usb modem transports behave like other radios from the repeater’s perspective.

@yellowcooln
Copy link
Copy Markdown
Contributor Author

itk80/pymc_usb#4

@rightup rightup merged commit 3987d3e into pyMC-dev:dev May 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants