Skip to content

Latest commit

 

History

History
303 lines (139 loc) · 10.1 KB

File metadata and controls

303 lines (139 loc) · 10.1 KB

Project Proposal Draft — RTL-SDR Demodulator for MeshCore (LoRa PHY → MeshCore Packet Decode)

To: Project Stakeholders / Maintainers From: Engineering (Python / SDR) Date: 25 January 2026 Subject: Research-backed plan to demodulate MeshCore over LoRa using RTL-SDR IQ samples


  1. Objective

Design and implement a software LoRa demodulator that ingests RTL-SDR IQ samples (pipe/stream) and outputs validated MeshCore packets (decoded to fields; optional higher-layer decryption/interpretation).

Success criteria

Lock onto MeshCore LoRa transmissions with known radio parameters.

Produce correct packet bytes with integrity checks passing (LoRa CRC where applicable; MeshCore validity checks).

Provide a stable Python-facing API for downstream tooling (logging, forwarding, analysis).


  1. Background Research

2.1 What LoRa is and how it works (PHY)

LoRa is a Chirp Spread Spectrum (CSS) modulation: each symbol is a chirp sweeping across the configured bandwidth (BW). Data is encoded as cyclic time/frequency shifts of chirps, decoded by dechirping and FFT peak detection.

Key PHY parameters

Carrier frequency (RF center): region-dependent.

Bandwidth (BW): e.g., 125/250/500 kHz; determines occupied spectrum and symbol rate scale.

Spreading Factor (SF): controls processing gain vs data rate. Typical SF7–SF12 in LoRaWAN contexts; higher SF = lower rate, higher sensitivity.

Coding Rate (CR): forward error correction overhead (e.g., 4/5 … 4/8); improves robustness at cost of throughput.

Header mode: explicit vs implicit. Explicit includes PHY header (length, CR, CRC flags), implicit omits it and requires receiver to know length/config a priori.

Sync word: early-frame network discriminator used by common LoRa chipsets as part of frame detection/filtering.

Demod essentials (PHY DSP)

Detect preamble (upchirp repetition) → coarse timing & frequency estimates.

Correct carrier frequency offset (CFO) and, ideally, sampling frequency offset (SFO) drift.

Dechirp + FFT per symbol to estimate symbol values.

Apply deinterleaving/whitening and FEC decode; validate CRC. Reverse-engineering and reference implementations confirm these steps and highlight CFO/SFO tracking as critical.


2.2 How MeshCore is built on top of LoRa

MeshCore is a multi-hop packet routing system designed for embedded LoRa devices. The MeshCore project positions itself as a lightweight C++ library enabling decentralized networking over LoRa and other packet radios.

MeshCore radio configuration (current default guidance) MeshCore’s FAQ indicates “the rest of the radio settings are the same for all frequencies” with:

SF = 10

CR = 5 (i.e., 4/5)

BW = 250 kHz and region frequency guidance including Australia/NZ using 915.8 MHz.

MeshCore packet structure & decoding expectations A practical decoding reference exists via the MeshCore decoder library (used by the MeshCore Packet Analyzer). It shows:

A top-level decoded object with fields like messageHash, routeType, payloadType, payloadVersion, optional path, and payload raw/decoded forms.

Enumerated payload/packet types (Request/Response, plaintext, acknowledgments, node advertisements, group text, etc.).

Node advertisement decoding includes public key, timestamp, signature, and application data fields.

Implication for demodulator scope

The demodulator must output exact MeshCore on-air packet bytes that upstream decoders (e.g., meshcore-decoder or equivalent Python port) can parse reliably.

Cryptographic/decryption support is not required for demodulation, but the demodulator must preserve byte-accurate payloads; higher-layer tooling can decrypt.


  1. RTL-SDR Pipe Demodulation Requirements

3.1 RTL-SDR IQ stream characteristics

Common RTL-SDR output is interleaved 8-bit unsigned IQ (u8): I0, Q0, I1, Q1, … representing complex baseband samples.

RTL-SDR practical IQ sample rates are typically ~240 kS/s to ~3.2 MS/s, constrained by USB throughput and tuner/digital downconversion.

Constraints induced by MeshCore’s LoRa BW

With BW = 250 kHz (MeshCore default), a minimal viable complex sampling rate is typically ≥ 2×BW (Nyquist), but in practice higher helps with filtering and offset tolerance (then decimate). // Design intent: choose a stable RTL-SDR rate (e.g., 1.0–2.4 MS/s), then digitally channelize to 250 kHz.

3.2 Signal chain (what must exist in the demodulator)

Below is the minimum processing chain to convert an RTL-SDR IQ pipe into MeshCore packets.

A) RF capture and conditioning

Tuner to target frequency (e.g., AU/NZ ~915.8 MHz per MeshCore guidance).

Gain strategy: fixed manual gain is often more stable than AGC for bursty signals.

Optional DC spike avoidance: slight offset tuning + digital mixing back to center.

// Required outputs of this stage:

  • Complex baseband samples at Fs
  • Known center frequency and sample rate metadata

B) Channelization to LoRa bandwidth

Frequency translate to center LoRa channel precisely.

Low-pass filter to ~BW/2 and decimate to a convenient Fs’ (often an integer multiple of BW).

Maintain phase continuity across buffers.

// Goal: isolate the LoRa channel and reduce compute cost

C) Frame detection + synchronization

Detect LoRa preamble (repeating upchirps), estimate symbol boundary alignment.

Estimate coarse CFO using preamble structure; refine during payload.

Track fractional CFO/SFO over time to prevent FFT-bin drift across packets.

// Why this matters:

  • RTL-SDR oscillator error + low-cost LoRa TX error can be several kHz
  • Without tracking, symbol peaks smear and payload decode fails

D) Symbol demodulation (CSS)

Dechirp each symbol (multiply by conjugate reference upchirp).

FFT → peak bin index → symbol value.

Handle LoRa-specific quirks (preamble, sync, downchirps, quarter-chirp, etc.) per established PHY descriptions.

E) Header decode (explicit vs implicit) + payload extraction

If explicit header: decode PHY header to obtain payload length and CRC enablement.

If implicit header: receiver must already know payload length and CRC settings (project must confirm MeshCore’s choice).

// Open requirement:

  • Confirm whether MeshCore transmissions use explicit or implicit header mode

F) FEC decode, interleaving, whitening, CRC check

Apply LoRa deinterleaving and FEC decoding (CR parameter).

Apply data whitening as used by LoRa PHY.

Validate CRC (if enabled) to accept/reject frames.

G) MeshCore packet parsing handoff

Output raw packet bytes (payload) to a MeshCore packet decoder.

Validate against MeshCore’s known structure/types (e.g., payloadType, routeType, messageHash expectations).


  1. MeshCore-Specific Parameters and Unknowns (Must Be Resolved Early)

4.1 Known (from public MeshCore guidance)

SF10 / BW250kHz / CR4/5 are the shared baseline settings in MeshCore FAQ guidance.

Region frequency selection includes 915.8 MHz for AU/NZ.

4.2 Unknown / not safely assumable (must be verified in firmware or captures)

Sync word value used by MeshCore on-air network(s). Sync word affects frame detection and can be a hardware-level discriminator.

Explicit vs implicit header mode actually used on-air (LoRa supports both).

Preamble length configuration (affects detection and timing lock strategy).

CRC enablement at LoRa PHY payload.

IQ inversion / polarity settings (some LoRa stacks expose invert IQ; wrong assumption breaks decode).

Channel plan (single frequency vs multiple, hop schedule, etc.) beyond the FAQ’s suggested community frequencies.

// Early milestone requirement:

  • Capture a short on-air recording from a known MeshCore node
  • Or extract radio register configuration from MeshCore firmware source for the target build

  1. Recommended Technical Approach (Implementation Plan, No Code)

Phase 0 — Parameter ground-truth (blocking)

Confirm MeshCore LoRa PHY settings: (freq list), BW/SF/CR, sync word, header mode, CRC, preamble length.

Primary source: MeshCore documentation/guidance for defaults

Empirical: record IQ from known-good transmitter and test lock.

Phase 1 — Robust LoRa PHY demodulator core

Implement streaming demodulator that supports:

BW 250 kHz, SF10, CR4/5 baseline (and ideally configurable for other SF/BW).

Preamble detection, CFO correction, symbol extraction, header + payload decode, CRC.

Use known-good descriptions and proven demod strategies emphasizing CFO/SFO tracking.

Phase 2 — MeshCore decode integration

Feed demodulated payload bytes into MeshCore packet decoder logic (reuse existing packet definitions/types).

Validate against known packet types (Advert, Ack, GroupText, etc.) and expected decoded fields.

Phase 3 — Operationalization

Add multi-frequency scanning (if MeshCore community channels vary).

Add observability: RSSI/SNR estimates, CFO estimate logs, CRC fail counters, packet rate.


  1. Risks and Mitigations

RTL-SDR frequency stability / drift: LoRa decode is sensitive to CFO/SFO; mitigation is robust tracking and possibly using a TCXO dongle or calibration routine.

Unknown MeshCore sync word/header mode: incorrect assumptions prevent frame detection; mitigate by extracting from firmware config or recording a known reference transmission.

Compute load (Python): FFT per symbol at SF10 is manageable with vectorized FFTs, but multi-channel scanning increases cost; mitigate via channelization + decimation and optional native acceleration paths later.


  1. Deliverables
  1. Requirements & parameter sheet (MeshCore LoRa PHY configuration for AU/NZ and any alternates).

  2. Demodulator architecture doc (streaming stages, buffer contracts, timing model).

  3. Validation plan (golden captures + expected packet decode results).

  4. MeshCore packet decode integration spec (what exact bytes are handed off; framing if multiple packets per stream).


References

MeshCore repository overview and goals

MeshCore FAQ: default PHY parameters (SF10/BW250/CR5) and AU/NZ frequency guidance

LoRa PHY packet formats (explicit vs implicit)

LoRa modulation parameters and SF effects

LoRa reverse-engineering / demod details

RTL-SDR IQ stream format and practical sample-rate constraints

MeshCore packet decoding structure and payload types (MeshCore decoder library)