MeshCore POTA gateway

A Heltec V3, V4, V4 R8, or XIAO ESP32-S3 + SX1262 running MeshCore room-server firmware, plus a small gateway module. Published firmware is v1.17.1+. Field operators log into the room over LoRa and post a SPOT line. The room HTTPS-POSTs that to api.pota.app on Wi-Fi. TLS runs on a background task so the LoRa stack keeps running. The XIAO build has no OLED; status is the serial pota command.

Utility page (flash, zip, first spot): MeshCore POTA gateway

It is not a group chat named #pota. MeshCore rooms are a BBS: add the room as a contact, log in, post text. Optional prefix #pota SPOT … is accepted in that post body.

Not affiliated with Parks on the Air or MeshCore. Independent tool from KB3CMT. Confirm spots on pota.app. Gateway / firmware bugs: Report a bug. General contact: kb3cmt@gmail.com.

What stays stock MeshCore

One live gateway

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

Flash

  1. USB, then the browser flasher. Pick Heltec V3, V4, V4 R8, or XIAO ESP32-S3 + SX1262. Chrome or Edge. The image is v1.17.1+. Other roles in the same tree are on the test builds page.
  2. Or PlatformIO from the build/pota-all branch:
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
  1. Serial (115200) should show a Room ID and [POTA] Wi-Fi STA starting.

Firmware compile default radio in upstream MeshCore is often EU (869.618 / BW 62.5 / SF 8). A US club mesh will not hear the room until you copy get radio from a working node and set radio <freq>,<bw>,<sf>,<cr> then reboot.

Room setup (once)

CommandPurpose
get radio / set radio …Match the mesh, then reboot
set name BSR-POTAAdvertised name
set guest.password …Room login (default compiled hello)
password …Admin CLI (default compiled password)
get repeatMust stay off
advertFlood advert so clients can find the room
potaWi-Fi / queue / pnp=on or pnp=off / blk=
pota block CALLAdmin: refuse that callsign (also /P and PREFIX/CALL)
pota unblock CALLAdmin: remove one block-list entry
pota blocksAdmin: list the block list
room.post SPOT …USB dry-run, no second node

Change the default passwords before the room is public.

Wi-Fi

Radio comes up first. Saved credentials get about 25 seconds. If none, AP MeshCore-POTA-Gateway at http://192.168.4.1. Phone hotspot is fine (iPhone 172.20.10.x is normal). After you save, leave that AP so the board can join the hotspot. Cellular data must be on.

Once STA is up, a Heltec OLED shows the DHCP address and serial prints [PNP] portal http://<ip>/. The XIAO has no screen, so read the address from serial pota. Open http://<that-ip>/ on the same Wi-Fi to set ParksnPeaks (this does not reconnect Wi-Fi). WWFF/SOTA spotting stays off until both validate. Enter OFF in the key field to clear. Blank key on save keeps the stored key.

pota on serial includes pnp=on or pnp=off.

First spot

From a MeshCore client (login with the room password, not admin):

SPOT W1AW US-1234 14.285 SSB Test Activation

K-1234 becomes US-1234. Frequency may be MHz or kHz. USB dry-run:

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

Serial: [POTA] Queued then [POTA] OK HTTP 200. Then check pota.app.

WWFF / SOTA (ParksnPeaks, only with a valid portal API key):

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

Daily mesh

Phones and 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 room advert schedule. Leave repeat off. 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.

Gateway operator card

When and why to stand up a node, how to name it, and how to shut it down cleanly. Flash and first-spot steps stay on the utility page and earlier sections of this guide. Independent tool from KB3CMT / Get On The Air — not affiliated with Parks on the Air or MeshCore. Confirm spots on pota.app. Passwords stay off public pages.

When to stand up a node

Stand up when…Skip or defer when…
Activators are in RF range of a mesh but no cell at parks you care aboutCell + pota.app (or APSPOT / SOTAMAT) already works reliably
Club / ARES / EOC wants a fixed internet-edge room for field weekendsYou would place it as the only RF hop in the middle of a busy mesh
Event / multi-activator weekend with a known LoRa footprintYou cannot change default passwords or supervise the room
Personal field kit: vehicle hotspot + board as your edge (not a public club room)A second live room on the same mesh with no clear “which room for spots” rule

Rule of thumb: one named live gateway per mesh; spare powered off; park at the internet edge; leave repeat off.

When not to

Naming

Before first advert (change defaults)

Compile defaults exist so the board boots; treat them as change-me, not club secrets.

  1. Match radio to the mesh (get radio on a working node → set radio … → reboot).
  2. set name … to your …-POTA name.
  3. Change room (guest) password — this is what field ops use to post.
  4. Change admin password — CLI only; never share with field ops.
  5. Confirm get repeat is off.
  6. advert, then USB dry-run: room.post SPOT … and check serial / pota.app.

Placement — internet edge

Repeat off · one live · spare cold

PracticeWhy
Repeat offRoom + gateway, not a flood repeater. Turning repeat on adds airtime on meshes that already have repeaters.
One live gatewayOne named room identity. Two live rooms only double-spot if someone logs into both and posts twice.
Spare powered offKeep a flashed spare for swap; power it only for maintenance or failover.

Rotate, revoke, shut down

ActionHow (high level)
Rotate room passwordChange guest password → advert → tell trusted ops the new password out-of-band.
Rotate adminChange admin password; do not share it.
Revoke accessNew room password is the revoke. Compromised ParksnPeaks key → clear via local portal (OFF) and re-issue at ParksnPeaks.
Temporary shutdownPower off or disconnect Wi-Fi so spots cannot leave; room posts without internet will queue one-deep only while powered.
Retire / re-roleRe-flash with erase when changing role (repeater ↔ room ↔ gateway). Re-do radio, name, passwords, repeat, advert.

Who should run one

A licensed amateur willing to keep firmware updated, rotate credentials, watch for abuse, and own the Wi-Fi/backhaul. Club-branded rooms: get trustee / ARES EC buy-in first.

Anti-abuse

Anti-abuse is in the gateway firmware and runs before a spot is queued for HTTPS. A SPOT line still lands in the room log; it is forwarded only if all checks pass. Rejection is logged on serial as [POTA] rejected … and does not count against the limits below. The room password is still who may post.

CheckWhat is forwarded
Callsign3–15 characters, letters and digits, up to two /, with at least one letter and one digit
POTA referenceUS-1234 shape: 1–3 letters, hyphen, 4 or 5 digits. K-1234 → US-1234
WWFF referenceKFF-0001 / VKFF-1234
SOTA referenceW1/GM-001
FrequencyDecimal = MHz (14.285, 146.52); bare integer = kHz. Kept range 100 kHz–1300 MHz
Mode2–8 letters or digits (SSB, CW, FT8)
DuplicateSame program + callsign + reference + frequency + mode within 5 minutes
Per callsign3 queued spots / 10 minutes for the activator callsign in the SPOT line
Whole gateway20 queued spots / hour (POTA + WWFF + SOTA share the cap)
Block listUp to 16 callsigns, persist across reboot. Admin: pota block CALL, pota unblock CALL, pota blocks. W1AW also matches W1AW/P and KH6/W1AW. Serial pota shows blk=. The open Wi-Fi page cannot edit this list

One park (reference) per line. A comma-separated 2-fer fails the reference check; post each park on its own line.

Caveat: one room login can rotate callsigns until the gateway hits the 20 / hour global cap. The room password still gates who may post.

The browser flasher is build/pota-all at a852559f (v1.17.1+). That image includes these checks.

Change the default passwords before you advert. Share the room password out-of-band. Rotate it to revoke. Run one live …-POTA room per mesh, keep the spare cold, and watch pota.app for spots you do not recognize.

The spotter still POSTs without a POTA session JWT. If api.pota.app/spot starts returning 401, operators will need a portal session field in a later build. Until then, confirm on pota.app.

Notes & edits