Tools · Field ops · MeshCore

MeshCore POTA gateway

Flash a Heltec V3, V4, V4 R8, or a XIAO ESP32-S3 + SX1262 as a MeshCore room server. Firmware v1.17.1+ (build a852559f). Field ops log in over LoRa, post a SPOT line, and this node HTTPS-POSTs it to pota.app. TLS runs on a background task so the radio keeps running. This image includes the gateway anti-abuse checks.

Repeater & companion images

Need a repeater or companion image? The full test set (repeaters, companions, and room servers) is on the MeshCore test builds page.

Running a club / field gateway?

Stand one up only when activators need an internet-edge room (no cell at the parks you care about, or a supervised club/EOC weekend). One named live …-POTA room per mesh; spare cold; repeat off; change room and admin passwords before you advert; share the room password out-of-band — never on a public page.

Firmware anti-abuse runs before a spot is queued for HTTPS (shape checks, duplicate window, rate limits, block list). A rejected SPOT still lands in the room log. The room password is still who may post. Details are on the guide.

Gateway operator card · Anti-abuse

1 · Firmware

Flash a room server

Chrome or Edge on USB. Pick the board, then Install. Published image is v1.17.1+ / a852559f from the test set. This is room-server firmware, not a repeater. Do not overwrite a node that must keep repeating. The XIAO build has no OLED; status is the serial pota command.

2 · Source

Build it yourself

Build Heltec_v3_room_server_pota, heltec_v4_room_server_pota, heltec_v4_r8_room_server_pota, or Xiao_S3_WIO_room_server_pota. Each one is the stock room server plus the gateway. The plain room-server environments stay stock. The XIAO build has no OLED.

What this is (and is not)

A MeshCore room is a BBS, not a group channel named #pota. Operators add the room as a contact, log in with the room password, and post text. An optional #pota prefix is accepted in that post body. There is no shared-channel secret to configure.

HTTPS is queued off the LoRa path. The room still stores every post as a normal BBS message. Non-spot chat is ignored after a cheap string check.

MeshCore stays intact

The gateway is an overlay, not a fork of the radio stack.

  • src/ (Dispatcher, BaseChatMesh, Mesh) is unmodified.
  • simple_repeater is unmodified. Repeaters keep daily traffic.
  • Room login, ACL, adverts, post sync, and guest rejection stay the room-server path. The extra calls are behind -D WITH_POTA_GATEWAY=1 on Heltec_v3_room_server_pota, heltec_v4_room_server_pota, heltec_v4_r8_room_server_pota, and Xiao_S3_WIO_room_server_pota. The plain room-server environments stay stock.
  • storePost still writes the cyclic BBS queue first, then queues a possible HTTP spot.
  • handleLoop() runs after the_mesh.loop() so LoRa is always serviced first. TLS is a FreeRTOS task on core 0, not inside the receive callback.
  • Default set repeat off. This node is a destination + internet edge, not a flood repeater.

One live gateway

A room post is encrypted to one room identity. A second board on the same frequency cannot decrypt that post. Two boards only double-spot if someone logs into both rooms and posts twice. Run one named room (example BSR-POTA). Keep a second flashed board as a spare.

Setup checklist

  1. Flash, then open serial at 115200. You want a Room ID line and [POTA] Wi-Fi STA starting.
  2. Match radio to the mesh. Upstream compile defaults are often EU (869.618). Copy get radio from a working node, then set radio <freq>,<bw>,<sf>,<cr> and reboot.
  3. set name BSR-POTA (or your club name). Change the compiled defaults: admin password, room hello.
  4. Leave get repeat off. Send advert so clients can find the room.
  5. Wi-Fi: saved credentials get about 25 seconds. If none, join AP MeshCore-POTA-Gateway at http://192.168.4.1, pick the hotspot, save, then leave that AP so the board can join. Phone tethering is fine (iPhone 172.20.10.x is normal). Cellular data must stay on. Heltec OLED boards show the DHCP address; the XIAO does not, so use serial pota. Open http://<that-ip>/ on the same network to set an optional ParksnPeaks user ID and API key (does not touch Wi-Fi). WWFF/SOTA spotting stays off until both validate. pota shows pnp=on or pnp=off.
Serial commandPurpose
get radio / set radio …Match the mesh, then reboot
set name …Advertised room name
set guest.password …Room login (operators use this)
password …Admin CLI
potaWi-Fi / queue / pnp=on|off
room.post SPOT …USB dry-run, no second node

First spot

From a MeshCore client, log into the room (room password, not admin) and post:

SPOT W1AW US-1234 14.285 SSB Test Activation

K-1234 is rewritten to US-1234. Frequency may be MHz or kHz. USB dry-run:

room.post SPOT KB3CMT US-0001 14235 SSB Testing MeshCore Gateway

Serial should show [POTA] Queued then [POTA] OK HTTP 200. Then check pota.app. TLS must connect to hostname api.pota.app (CloudFront needs SNI). Connecting by raw IP fails with a fatal alert.

WWFF / SOTA go to ParksnPeaks only with a valid portal API key (pnp=on):

SPOT WWFF W1AW KFF-0001 7.144 SSB CQ WWFF
SPOT SOTA W1AW/P W1/GM-001 14.285 SSB CQ SOTA

Daily mesh

Companions still use existing repeaters. This board advertises as a room. Login and posts are peer datagrams to its public key — same as any MeshCore room. Extra RF is one short post per spot plus the usual advert schedule. Park the gateway at the internet edge (vehicle hotspot, EOC, house Wi-Fi), not as the only RF hop in the middle of the mesh.

Wi-Fi TX on these ESP32-S3 boards can slightly desense the SX1262. That is hardware coexistence, not a MeshCore bug.

Build from source

pio run -e Heltec_v3_room_server_pota -t upload -t monitor
pio run -e heltec_v4_room_server_pota -t upload -t monitor
pio run -e heltec_v4_r8_room_server_pota -t upload -t monitor
pio run -e Xiao_S3_WIO_room_server_pota -t upload -t monitor

Each POTA environment adds the flag, include path, gateway sources, WiFiManager, and lib_ldf_mode = deep+. The matching room-server environment without _pota does not. Repeater, companion, and room server images are on the MeshCore test builds page.