Skip to the content
2 layers96 × 50 mmPager, the printed circuit board in 3D

Privacy-first LoRa mesh networking for ESP32-S3, built with ESP-IDF

Size
96 × 50 mm
Copper layers
2
Thickness
1.6 mm
Parts
97
Nets
101
Pads
362
Tracks, vias
898, 129
Pours
7
Routed
Yes
KiCad
KiCad 10.0 (file 20260206)
Created
4 Mar 2026
Updated
1 Nov 2026

Overview

Pager is an open-source printed circuit board by justinlindh, from the justinlindh/bramble repository on GitHub, published under the MIT licence. It is a 2-layer board of 96 × 50 mm with 97 parts on 101 nets, routed with 898 tracks and 129 vias.

It is built around the ATGM336H-5N31, ESP32-S3-WROOM-1-N8R2 and LORA1262-915TCXO, with the DW01A, FS8205A and USBLC6-2SC6 among its other parts. Its parts include 26 capacitors, 21 resistors, 10 diodes, 8 ICs and 5 transistors. It belongs with the radio and wireless boards and the ESP32 boards of this library.

Main components

12

README

README.md

Bramble

Bramble

Privacy-first LoRa mesh networking for ESP32-S3, built with ESP-IDF.

Quality Firmware Quality Webapp Quality License: MIT Hardware: verified

Bramble is an encrypted, multi-hop mesh protocol and firmware stack for long-range, infrastructure-free communication. It is designed for resilient field use while reducing metadata exposure; docs/SECURITY-MODEL.md documents exactly what is and is not protected.

Table of Contents

What is Bramble?

Bramble is a secure LoRa mesh protocol and firmware implementation for ESP32-S3 devices with SX1262 radios. It focuses on practical private communications in constrained, lossy RF environments, with explicit handling for routing, retransmission, airtime limits, and node identity.

The firmware runs on real hardware (including T-Deck Plus and Heltec V3/V4 targets), with host-side testing used to validate protocol behavior continuously during development.

What Makes Bramble Different

Compared to Meshtastic and MeshCore-style systems, Bramble leans on privacy and on authenticated, confirmable delivery at the protocol level. It is an early project: functional and hardware-verified on a small bench mesh, but not yet field-tested at scale. The claims below are what the code on main does, with the honest limits stated alongside.

  • Dual-substrate routing. Two forwarding substrates ship, and a runtime toggle (s_flood_transport, default off) selects between them. Reactive AODV is the default: RREQ/RREP discovery, a cached route table, reverse-route breadcrumbs learned from DATA, intermediate-node RREP, and route-forwarded ACKs. DM airtime is O(path_length), not O(N). Flooding is the opt-in alternative: hop-limited (configurable, default 8, range 1..32), deduplicated, airtime-budget-gated unicast/channel floods with a flooded ACK for route-free sender confirmation. Both substrates are first-class; the toggle picks one.
  • Authenticated traffic (wire v4), no insecure bootstrap. DATA frames and the control plane (RREP, RERR, ACK, delivery receipt, beacon) carry a network-key HMAC that relays verify before acting; a captured frame cannot be forged or replayed by an outsider on a provisioned network. There is no public default key: an unprovisioned node is inert (fail-closed) and refuses to emit or accept any authenticated frame until a real per-fleet key is provisioned (minted on-device or pasted in). Residual: any network-key holder is an insider and can still forge these MACs, narrowed by per-node identity rather than by provisioning (docs/SECURITY-MODEL.md).
  • Confirmed delivery. Acknowledged tiers report DELIVERED vs FAILED to the sender rather than fire-and-forget. Honest envelope: reactive holds confirmed delivery at small, dense scale; the flooded confirmation holds at low-to-moderate message load and degrades at high load because flood airtime scales as O(messages x nodes). It is explicitly not a high-load guarantee.
  • End-to-end direct messages. DMs use per-peer AES-256-GCM sessions keyed by a role-symmetric quad-DH X25519 exchange (components/dm_session), and are not readable by other channel members. Each message has forward secrecy from a symmetric HKDF ratchet, with a coarse per-epoch DH ratchet for post-compromise recovery. An identity-bound 7-digit safety number (SAS) lets two people verify a contact out of band; the verification UX ships in the web client, the T-Deck graphical build, and on the e-paper pager itself (a per-peer view under the Nodes screen with a two-step confirm), and verified state is remembered per contact and cleared automatically if a contact's identity key changes. See docs/SECURITY-MODEL.md for the threat model and residuals.
  • Channel encryption + multi-hop channels. Channel messages use AES-256-GCM (AEAD) with the channel ID hidden inside the ciphertext, and they relay multi-hop via the flood relay.
  • Privacy-first routing. Route-request sources are pseudonymized per query, so forwarded route requests do not carry the originator's address.
  • Airtime budgeting: every transmission goes through one budget-gated TX path (components/radio/tx_gate.c) with real time-on-air costing, per-tier token buckets, and regional duty-cycle caps enforced where the frequency plan requires them (for example EU 868 at 1%).
  • 3-tier reliability model: Broadcast (fire-and-forget), Normal (acknowledged, 3 retries with backoff), and Critical (8 retries plus delivery receipts carrying the relay path).
  • Cryptographic node identity + optional fleet trust anchor. Each node has an Ed25519 identity whose 4-byte address is the hash of its own public key (SHA-256(ed25519_pub)[0:4]), so an address cannot be claimed without the matching key: address impersonation is a preimage search, not a TOFU race. Nodes flood self-signed identity attestations that peers verify and TOFU-pin, refusing and counting any later conflicting key for a pinned address. An optional per-fleet trust anchor (an operator-held Ed25519 key that endorses each member's identity with a cert) closes Sybil identity minting on an anchored mesh, because an anchored node only pins peers carrying a cert its anchor signed. Residuals stated in the same breath: a compromised endorsed insider stays a valid member (endorsement is admission control, not behavioral trust), the anchor seed is the fleet's trust root and its custody is the whole scheme, and an un-anchored mesh keeps unforgeable but free-to-mint identities (docs/trust-anchor.md, docs/SECURITY-MODEL.md).
  • Attested roll-call. An initiator broadcasts a roll-call and every member answers with an Ed25519 identity-signed unicast, building a per-member ledger with relay paths (bramble.startRollCall / bramble.getRollCall, with a panel in the web client). An anchored mesh audits against the endorsed member set; an un-anchored mesh reports observed responders only. A signature proves an answer and absence proves nothing; both initiation and answering are rate-limited because a roll-call costs N unicast answers. Verified by host tests and the collision-modeled simulator; no field deployment (docs/rollcall.md).
  • Deployment digital twin. Each node exports its observed topology over RPC (bramble.exportTopology), and the simulator's twin subcommand replays that deployment against the collision model: capacity (delivery rate vs offered load) and which single node's loss partitions the mesh. The twin replays observed links at a moment in time; it predicts nothing about unplaced nodes, and its results are simulation (docs/digital-twin.md).
  • Browser playground. make playground boots the actual firmware binary as a small virtual fleet on a simulated ether, with a guided tour through provisioning (including the fail-closed inert state), multi-hop relay, SAS verification, and a delivery receipt. First contact needs no hardware and no toolchain; a browser fleet is not a field deployment (docs/playground.md).
  • Store-and-forward mailbox: offline nodes receive queued messages when they rejoin the mesh.
  • Location sharing with privacy tiers: presence, zone (a 0.003° by 0.006° cell, about 334 m north-south and 668 m east-west at the equator), or exact; per-peer control over what you share and with whom. Location payloads are AES-256-GCM encrypted end to end and padded to a fixed size so the ciphertext does not leak which tier was chosen; timing and the fact that a node shares location remain observable (docs/SECURITY-MODEL.md).
  • Browser-based flashing: flash firmware to new devices directly from the web, no toolchain required.

For a deeper feature-by-feature analysis, see docs/COMPARISON.md.

Web Client

Bramble includes a web client for live network operation and monitoring. It provides real-time chat (including delivery badges), map-based peer location views, neighbor and route visualization, traffic monitoring, channel management, and radio configuration.

Chat Nodes Map Stats Config

See docs/webapp/chat.md for current web client behavior and usage notes. To run it from source, cd webapp && npm ci && npm run dev; webapp/README.md covers the dev workflow, the WiFi-transport backend, and the Electron builds.

A desktop app (Linux, Windows, macOS) is also available, built from the same webapp. It connects directly to nodes on your local network instead of going through a hosted proxy, and can discover nodes on the LAN automatically. See docs/webapp/desktop.md.

Hardware Targets

BoardMCUDisplayInputRadioAudioStatus
Heltec WiFi LoRa 32 V3ESP32-S30.96" SSD1306 OLED (128x64)ButtonsSX1262N/ARunning target
Heltec WiFi LoRa 32 V4ESP32-S3OLED + optional L76K GNSSButtonsSX1262N/ARunning target
LilyGo T-Deck PlusESP32-S3ST7789 320x240 LCD with LVGL v9 UIGT911 capacitive touch + I2C keyboardSX1262 with TCXO (DIO3 1.8V, DC-DC)I2S with NVS-persisted volumeRunning target with full GUI
Bramble Pager v1 (custom PCB)ESP32-S3-WROOM-12.13" GDEY0213B74 e-paper (SSD1680, 250x122)ButtonsSX1262 with TCXO and DIO2 RF switch (DC-DC)Buzzer + vibra alertsDesign complete, boards not yet ordered
Seeed Wio-WM1110 Dev KitnRF52840None (BLE-only interface)NoneLR1110N/AExperimental: joins the bench mesh, BLE RPC + provisioning over an encrypted link, identity/key/bonds persist in flash; GNSS and power management not yet implemented (nrf/)
Seeed SenseCAP T1000-E (card tracker)nRF52840None (BLE-only interface)ButtonLR1110BuzzerExperimental: boots, BLE RPC, joins the mesh; GNSS driver implemented for the onboard AG3335 module and bench-verified (2026-07-31); power management not yet implemented (nrf/)

The Bramble Pager v1 is a custom in-house board, not an off-the-shelf dev kit: its own 96x50mm 2-layer PCB (ESP32-S3-WROOM-1 + SX1262 with a DIO2 RF switch, GDEY0213B74 2.13" e-paper, ATGM336H GPS, buzzer, vibration motor, and status LED), JLCPCB-fabbable, in a 3D-printed case. The authoritative design tree (spec, schematic, PCB, BOM, case, and bring-up gates) is hardware/pager/v1/; build it with the bramble-pager board profile.

This is what the firmware paints on each display class, as real framebuffers (T-Deck captured on hardware, the others rendered by the real firmware in the emulator):

T-Deck Plus home screenHeltec OLED home screenPager home screen
T-Deck Plus: LVGL color UIHeltec OLED: text UIPager v1 (alpha): e-paper text UI

Each image links to its device's section in the device screen gallery, which shows every screen and documents how each capture was made.

Simulator

Bramble ships with a mesh simulator that runs real protocol code against a virtual radio layer and renders topology/traffic in a browser. The radio layer models the shared LoRa medium (real time-on-air, collisions, capture, half-duplex, listen-before-talk), making it the primary proving ground for scale and routing behavior before field deployment.

See simulator/README.md for setup and scenarios. For measured scale results under the collision model, docs/results/simulation-2026-07-honest-baseline.md is the source of truth (it supersedes the June numbers for planning; the earlier collision-free "100% at 200 nodes" figures were retracted as sim artifacts). In short, re-measured on 2026-07-24 at the PHY firmware actually transmits on (the frequency plan's SF9/125 kHz, not the radio profile's SF10): 30% message delivery at 10 nodes, 10% at 50, 0-5% at 100 and 0% at 200, as a single channel saturates under control-plane load (0.91 erlang offered by control traffic alone at 50 nodes, 1.94 at 200). Scale is bounded by radio profile, node density, and hop budget; there is no field-tested-at-scale result.

Emulator

The simulator drives real protocol code through a test harness; the emulator goes one step further and runs the actual firmware binary. Each virtual node is app_main compiled for ESP-IDF's linux target, booted with a virtual board profile, with the radio, e-paper display, buttons, GPS, and battery replaced by virtual drivers at the existing hardware seams. N virtual Bramble Pagers attach to the gosim ether and are rendered in a browser as the physical device: a faithful SSD1680 e-paper panel, clickable buttons, per-node consoles, and true per-node identities that survive restart. It is the packaging/UX proving ground the simulator is not: what a user actually sees and does on the device.

Quick start: cd emulator && make run (local toolchain) or docker compose up --build (zero prerequisites), then open the printed URL and load the emu-channel-delivery scenario. A gated PHY-passthrough bridge lets a serial-attached real node inject the physical RF channel into the virtual ether. See emulator/README.md for setup, scenarios, and the headless CI/E2E suites. A QEMU true-VM backend (running the exact flashable image) is a documented phase-2 follow-on, not yet built.

Getting Started

Full build/flash instructions (including board-specific profiles and USB-port notes) are in docs/BUILDING.md.

Quick start (building from source needs ESP-IDF v5.4.1; see docs/BUILDING.md to install and activate it):

bash
git clone https://github.com/justinlindh/bramble.git
cd bramble

# activate ESP-IDF in this shell first
source "$IDF_PATH/export.sh"

bash scripts/flash.sh local heltec-v3 build
bash scripts/flash.sh local heltec-v3 flash /dev/ttyUSB0

Use tdeck-plus instead of heltec-v3 for T-Deck Plus builds.

No toolchain, no problem: the web flasher flashes a device over USB straight from the browser. If a build or flash stalls (serial permissions, a missing toolchain, a port collision), see docs/troubleshooting.md.

Keeping it up to date. Once a node is on your WiFi it installs new firmware over the air from the web client, no cable and no toolchain: docs/updating-your-node.md.

First-time setup. A freshly flashed node boots unprovisioned and inert: it has no network key, so it will not mesh (it neither emits nor accepts authenticated control-plane traffic) until you provision one, and the web client shows a prominent UNPROVISIONED banner until then. Follow docs/getting-started.md to connect the web client, provision a network key, optionally enroll the node under a trust anchor, and send your first message.

Testing

Host-side tests cover crypto, routing, security, packet handling, reliability, and integration behavior.

bash
cd test
./run_all_tests.sh

Architecture

Bramble is organized as ESP-IDF components with clear boundaries between protocol logic, radio abstraction, security, reliability, and UI/control layers. The architecture is designed so core protocol behavior can be validated on host and simulator environments before device rollout.

For the full component breakdown and interaction diagrams, see docs/bramble-architecture.md.

Documentation

API and SDK

Bramble exposes a JSON-RPC 2.0 interface for device control and observability.

CI/CD

Status

Bramble is an early but fully functional project: the protocol stack is implemented end to end, reviewed and host-tested, and running stable on real hardware (T-Deck Plus, Heltec V3, and Heltec V4). Every change must pass the full host test suite as a required CI gate (test/run_all_tests.sh, which fails if any suite fails or none are found). It has not yet been field-tested at scale, and development is ongoing.

Contributing and Community

Contributions are welcome, and you do not need hardware to make one. The webapp, the simulator, the host test suites, and the docs all build and run on an ordinary machine.

  • CONTRIBUTING.md: setup, the quality gates, branch and commit conventions, and what a good pull request looks like. Start there. Note the one step that is easy to miss: run make setup-hooks once per clone so the pre-commit checks run on your machine instead of failing in CI.
  • docs/troubleshooting.md: serial permissions, toolchain targets, port collisions, and the other common first-run stalls.
  • Issues: bug reports and feature requests.
  • Discussions: questions, ideas, and show-and-tell.
  • SECURITY.md: how to report a vulnerability privately. Please do not open a public issue for one.
  • CODE_OF_CONDUCT.md: what is expected of everyone taking part.

GitHub is canonical for outside contributions. Any other remote you may come across is a mirror.

License

MIT; see LICENSE

Parts

97
QtyValueFootprintReferences
81uF 50VC_0603_1608MetricC303, C304, C305, C306, C307, C308, C309, C310
7100nFC_0603_1608MetricC106, C107, C202, C205, C402, C404, C405
710uFC_0805_2012MetricC101, C102, C104, C105, C201, C204, C401
5100kR_0603_1608MetricR107, R108, R109, R201, R202
510kR_0603_1608MetricR401, R404, R405, R407, R408
4B5819WD_SOD-123D201, D301, D302, D303
4MountingHole_2.2mm_M2MountingHole_2.2mm_M2H1, H2, H3, H4
3100RR_0603_1608MetricR106, R402, R403
31kR_0603_1608MetricR104, R105, R406
34.7uF 25VC_0805_2012MetricC203, C301, C302
3AO3400ASOT-23Q301, Q401, Q402
3FiducialFiducial_1mm_Mask3mmFID1, FID2, FID3
25.1kR_0603_1608MetricR101, R102
2AO3401ASOT-23Q101, Q201
2SS14D_SMAD401, D402
2u.FL BWIPX-1-001EU.FL_Hirose_U.FL-R-SMT-1_VerticalANT1, ANT2
1+3V3TestPoint_Pad_1.5x1.5mmTP1
11MR_0603_1608MetricR301
11uFC_0603_1608MetricC403
12.2R 1%R_0805_2012MetricR302
12.2kR_0603_1608MetricR103
147nHL_0402_1005MetricL201
147uHIND-SMD_L4.0-W4.0_FNR40XXSL301
1ATGM336H-5N31GPSM-SMD_ATGM336H-TRU202
1DW01ASOT-23-6U103
1ESP32-S3-WROOM-1-N8R2ESP32-S3-WROOM-1U401
1FH34SRJ-24SFFC-SMD_24P-P0.50_FH34SRJ-24S-0.5SHEPD1
1FS8205ASOT-23-6_L2.9-W1.6-P0.95-LS2.8-BRU104
1GNDTestPoint_Pad_1.5x1.5mmTP2
1GNSS_RXTestPoint_Pad_1.5x1.5mmTP6
1GNSS_TXTestPoint_Pad_1.5x1.5mmTP5
1I2C debug (DNP option)JST_ZH_B4B-ZR-SM4-TF_1x04-1MP_P1.50mm_VerticalI2C1
1JST-PH BATTJST_PH_S2B-PH-SM4-TB_1x02-1MP_P2.00mm_HorizontalBATT1
1LoRa1262-915TCXOWIRELM-SMD_16P-L16.0-W16.0-P2.00_LORA-CC68-915MHZ-TCXOU201
1MLT-8530BUZ-SMD_4P-L8.5-W8.5-P8.50-BRBZ1
1SS34D_SMAD101
1TP4056-42ESOP-8_L4.9-W3.9-P1.27-LS6.0-BL-EPU102
1TS-1187A BOOTSW-SMD_4P-L5.1-W5.1-P3.70-LS6.5-TL_H1.5SW402
1TS-1187A DOWNSW-SMD_4P-L5.1-W5.1-P3.70-LS6.5-TL_H1.5SW403
1TS-1187A RESETSW-SMD_4P-L5.1-W5.1-P3.70-LS6.5-TL_H1.5SW401
1TS-1187A UPSW-SMD_4P-L5.1-W5.1-P3.70-LS6.5-TL_H1.5SW404
1TYPE-C-31-M-12USB_C_Receptacle_HRO_TYPE-C-31-M-12USBC1
1USBLC6-2SC6SOT-23-6U101
1VBAT_SENSETestPoint_Pad_1.5x1.5mmTP3
1VSYSTestPoint_Pad_1.5x1.5mmTP4
1XC6220B331MR-GSOT-23-5U105
1green STDBYLED_0603_1608MetricLED102
1redLED_0603_1608MetricLED401
1red CHRGLED_0603_1608MetricLED101
1vibra JST-ZHJST_ZH_B2B-ZR-SM4-TF_1x02-1MP_P1.50mm_VerticalVIB1

Similar boards

  • 2 layers90 × 55 mmS3.1-before repack, the printed circuit board in 3D

    S3.1-before repack

    puji4810/coffe-scale

    USB-C J5 ──► U8 ESD ──► R19/R20 22R ──► U4 IO19/IO20 (native USB-Serial/JTAG) │VBUS ├─► U5 TP4057 充电 ──► J6 1S Li-ion └─► D1/Q1 负载切换 ──► VSYS ──► U6 XC6220 3V3 1A ──► VCC3V3 ──► U4/外设 └──► U7 HT7533 ──► VDDADC ──► U1/U3…

    96 partsApache-2.0
  • 2 layers61.3 × 63.3 mmMonitoring Gunung, the printed circuit board in 3D

    Monitoring Gunung

    rafdi03/PCB_Desain

    Schematic PCB Project

    50 parts
  • 4 layers45 × 34 mmTriangle flywheel balancer, the printed circuit board in 3D

    Triangle flywheel balancer

    RobbyV2/smart_latch_lock

    A self-closing bike lock built as a clamshell ring. A fixed arc bolts to the housing, a hinged arc swings 180 degrees to meet it, and a worm gearmotor closes the loop around the frame and rim on a button press or a BLE…

    70 parts
  • 2 layers65 × 56 mmSatellite board, the printed circuit board in 3D

    Satellite board

    harshith998/ORCA-Optical-Replication-Control-Apparatus

    This repository is all software/PCB schematics for the dynamic lighting system in the CASAR lab. In order to track unbiased nitrogen fixation levels, the light intensity inside their incubation vessel has to match…

    27 parts
  • 4 layers62 × 46.9 mm4LayerLabProject, the printed circuit board in 3D

    4LayerLabProject

    ZharbolatDinmukhamed/Haptic-Glove-PCB

    A wrist-mounted PCB for a haptic feedback glove, developed as part of my Research Assistantship at the Tactile Laboratory, Nazarbayev University.

    122 parts
  • 2 layers48 × 38 mmRAMS RevC, the printed circuit board in 3D

    RAMS RevC

    JanClyde05/Road-Accident-Monitoring-System

    This directory contains the planning, specification, and initial KiCad project for RAMS Wearable PCB Revision C. Do not fabricate from this directory yet -- manual schematic wiring and DRC verification are still needed.

    68 parts1
  • 4 layers90 × 95 mmWiegand bridge, the printed circuit board in 3D

    Wiegand bridge

    EdgeCoil/wiegand-bridge

    ESP32-S3 Wiegand reader bridge for Home Assistant: 4-layer board, BOM and ESPHome firmware.

    197 parts1
  • 2 layers80 × 54 mmPl60c dmx, the printed circuit board in 3D

    Pl60c dmx

    tsmiltonAgents/pl60c-dmx-wakeup

    A small ESP32-S3 board that drives the wired DMX512 input of a Neewer PL60C panel light so the light can be ramped up slowly in the morning (sunrise alarm). Rev A, 2026-09-02.

    40 parts

Questions

How big is the Pager PCB?

It measures 96 × 50 mm and has 2 copper layers, 1.6 mm thick.

What parts does the Pager use?

97 parts, built around the ATGM336H-5N31, ESP32-S3-WROOM-1-N8R2, LORA1262-915TCXO and DW01A. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the Pager KiCad files?

From the justinlindh/bramble repository on GitHub, at the commit this page was made from: the board is hardware/pager/v1/kicad/pager.kicad_pcb and its schematic hardware/pager/v1/kicad/epaper.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Pager design in my own project?

Its repository publishes it under the MIT licence: you may reuse it on that licence's terms (keep the author's notice, and for a copyleft licence share your changes alike).