Phreak — Wireless AT Command Reference

DeMon's wireless companion is an ESP32-C5 — a dual-band Wi-Fi 6 (2.4 GHz + 5 GHz) and Bluetooth LE 5 SoC, and the core of Phreak, the Ant64's wireless subsystem (Wi-Fi/BLE plus optional LoRa and GPS — see Communications). One way to drive it from DeMon (the CM5) is Espressif's ESP-AT firmware: the C5 runs a ready-made image that accepts text AT commands over a serial link and answers OK / ERROR, so DeMon gets networking and BLE without linking a wireless stack into AntOS. This document is a reference to that command set as shipped for the C5 in the latest firmware. (The alternative — running the C5 as an esp_hosted radio co-processor — is a separate integration path.)

Status: external reference. This summarises Espressif's ESP-AT command set for the ESP32-C5 at the latest release. The authoritative, parameter-level documentation is Espressif's (links at the end). Command availability depends on the firmware build — see §3.

Want to see what it's for? Phreak Fun collects creative and research projects built on these commands — RF cartography, LoRa mesh chat, CSI presence art, radio fox-hunts, CTF labs — all receive-only and ethically framed.


1. Firmware and versions

ESP-AT is Espressif's official AT-command firmware, maintained for the C5 alongside the C2 / C3 / C6 / ESP32 / S2 families. Espressif's prebuilt AT binary targets the 4 MB-flash, no-PSRAM part (ESP32-C5-4MB). The Ant64's C5 is a larger module, though — currently ESP32-C5-WROOM-1-N16R8 (16 MB flash + 8 MB PSRAM), moving to N32R8 (32 MB flash + 8 MB PSRAM) — so the Ant64's own AT build (needed anyway for §12–§15) has far more flash than the stock image and can lean on PSRAM for buffers.

  • Latest released: v5.0.1.0 (recommended) and v5.0.0.0. The version string from AT+GMR reads like AT version:5.0.0.0(... ESP32C5 ...) on an ESP-IDF v5.5-class SDK.
  • Getting firmware: production binaries come from Espressif's AT Firmware Application form (per chip and version); test builds come from the project's GitHub Actions or a local compile. Self-compiled firmware cannot OTA-upgrade from Espressif's servers.
  • Customising: the at.py tool re-configures a released binary (UART pins, Wi-Fi defaults, certificates, GATTS database) without a full rebuild; a local ESP-AT build is what enables the compile-in command sets listed in §3.

2. Serial transport and DeMon wiring

The Ant64 build uses the C5's interfaces three ways:

Interface Role
UART0 AT command / response — the DeMon control link (up to 5 Mbps, HW flow control); also the firmware-download port when the C5 needs reflashing
USB-Serial-JTAG debug / log output, carried over USB to DeMon's USB-FS hub — kept off the AT stream
UART1 optional GPS (NMEA) — see §13

The AT port (UART0) uses a custom pin map for DeMon's layout — TX IO11, RX IO12, CTS IO23, RTS IO24 — re-mappable via at.py ("How to Set AT Port Pins"); stock ESP-AT's default AT-port pins are TX23/RX24/CTS25/RTS26. Both the C5 and DeMon sustain up to 5 Mbps on this link (~0.5 MB/s practical), set at runtime with AT+UART_CUR (RAM) or AT+UART_DEF (saved to flash). At that rate hardware flow control is essential, not optional — the RX FIFO fills in microseconds, so the CTS/RTS pair (DeMon wires the match — see DeMon) is what stops dropped bytes when either side is briefly busy; give the RTS-deassert threshold headroom below the 128-byte FIFO. Putting the log on the USB-Serial-JTAG keeps it out of the AT byte-stream, so UART0 carries only AT traffic at runtime — and the download stream when flashing, which never overlaps.

Transport split — benchmark pending. The table above is the working default. The C5 also reaches DeMon over QSPI (the SPI2 slave), and its USB-Serial-JTAG is itself a usable data path, so the final AT transport is a measurement call rather than settled. Rough expectation: 5 Mbps UART (~0.5 MB/s, lowest latency, never contended) is enough for everyday AT; QSPI is the bulk accelerator (a few MB/s) when DeMon's SPI bus is free; USB-FS sits between them (~0.5–1 MB/s) for sustained transfers like OTA images or the §14 capture feed. If a benchmark favours it, AT could move to USB or QSPI with UART taking debug — but UART stays the always-available control and recovery path regardless.

Optional — LoRa Plus add-on. A Semtech LR2021 (Seeed Wio-LR2021) dual-band LoRa Plus transceiver can be added to the C5 (on its SPI bus). This stays transparent to the DeMon host: it surfaces as a handful of extra LoRa AT commands on the same serial link, alongside the Wi-Fi/BLE set. LoRa is not part of stock ESP-AT, so those commands are added as custom user-defined AT commands in a local build (see §12).

Optional — GPS add-on. A GNSS receiver (u-blox NEO-M10) hangs off the C5's UART1; the C5 parses its NMEA and exposes position to DeMon as extra AT commands — the same custom-bridge pattern as LoRa (see §13).

Every command line is terminated with CR LF (\r\n); the firmware replies with optional data lines followed by OK or ERROR. Confirm the link with AT (expect OK) and read the build with AT+GMR.

On DeMon (see DeMon for the authoritative pinout): the C5's BOOT strap (its GPIO28) is driven by DeMon's MCP23017 PA7 and the C5's EN (reset) by PA6, so DeMon can hold BOOT low and toggle EN to drop the C5 into download mode and reflash it over UART0; C5 pin 27 is tied high. DeMon also runs a QSPI link to the C5 (an SPI2 chip-select); DeMon is the source of truth for the wiring, and Firmware & Flashing covers the flash sequence end-to-end.

3. Command-set availability (C5-4MB firmware)

What the released C5-4MB binary ships by default, what needs a custom build, and the radio facts:

Command set C5-4MB default
Base / system, User included
Wi-Fi included
TCP-IP (incl. SSL, SNTP, ping, mDNS) included
WPS, SmartConfig included
MQTT included
HTTP included
Bluetooth LE included
BluFi included
OTA (network firmware upgrade) included
FileSystem compile-in
Web server compile-in
WebSocket compile-in
Driver (ADC / PWM / I2C / SPI) compile-in
WPA2-Enterprise (AT+CWJEAP) compile-in

Radio: dual-band Wi-Fi 6 (2.4 + 5 GHz) and BLE 5, sharing one RF antenna between Wi-Fi and BLE. Anything not listed above is unsupported. AT+CMD enumerates exactly what the running firmware exposes.

The compile-in rows are absent only from Espressif's prebuilt binary; they are real ESP-AT command sets. The Ant64's larger module (§1) has the flash to enable them all, so on the Ant64 build they are present too — their commands are documented in §10.

4. Basic / system commands

Command Function
AT link test; returns OK if AT is alive
AT+RST restart the C5
AT+GMR firmware / SDK / bin version
AT+CMD list every command the running firmware supports
ATE command echo on / off
AT+RESTORE restore factory defaults (clears NVS)
AT+GSLP deep sleep for a set time
AT+SLEEP set modem / light sleep mode
AT+SLEEPWKCFG light-sleep wake source / GPIO
AT+UART_CUR / AT+UART_DEF UART config, RAM-only / saved to flash
AT+SYSRAM free-heap status
AT+SYSMSG / AT+SYSMSGFILTER / AT+SYSMSGFILTERCFG system-prompt messages + filtering
AT+SYSSTORE whether parameter changes persist to flash
AT+SYSFLASH / AT+SYSMFG user flash partitions / manufacturing-NVS
AT+SYSREG read / write a register
AT+SYSTIMESTAMP local timestamp
AT+SYSLOG verbose AT error codes on / off
AT+RFPOWER RF TX power (Wi-Fi + BLE)
AT+RFCAL force RF full calibration
AT+SYSROLLBACK roll back to the previous firmware image
AT+SAVETRANSLINK auto-enter passthrough (TCP/SSL/UDP or BLE) at boot
AT+TRANSINTVL data-batching interval in passthrough mode

5. Wi-Fi commands

Station, SoftAP, and the C5's dual-band controls.

Command Function
AT+CWINIT initialise / de-initialise the Wi-Fi driver
AT+CWMODE mode: station, SoftAP, or both
AT+CWBANDMODE select 2.4 GHz / 5 GHz / dual band
AT+CWBANDWIDTH channel bandwidth
AT+CWSTATE current Wi-Fi state + connection info
AT+CWCONFIG inactive time / listen interval
AT+CWJAP connect station to an AP
AT+CWRECONNCFG auto-reconnect policy
AT+CWLAP / AT+CWLAPOPT scan for APs / configure scan output
AT+CWQAP disconnect from the AP
AT+CWSAP configure the SoftAP
AT+CWLIF / AT+CWQIF list / disconnect SoftAP clients
AT+CWDHCP / AT+CWDHCPS DHCP enable / SoftAP lease range
AT+CWAUTOCONN auto-connect on power-up
AT+CWSTAPROTO / AT+CWAPPROTO 802.11 b/g/n/ax protocol for station / SoftAP
AT+CIPSTA / AT+CIPAP station / SoftAP IP address
AT+CIPSTAMAC / AT+CIPAPMAC station / SoftAP MAC address
AT+CWHOSTNAME station hostname
AT+CWCOUNTRY Wi-Fi country / regulatory code
AT+CWSTARTSMART / AT+CWSTOPSMART SmartConfig provisioning
AT+WPS WPS push-button provisioning
AT+CWJEAP connect to a WPA2-Enterprise AP (compile-in)

Dual-band note. AT+CWBANDMODE is the C5-specific lever — 2.4 GHz only, 5 GHz only, or both. AT+CWSTAPROTO / AT+CWAPPROTO extend the negotiated standard up to Wi-Fi 6 (ax). AT+CWCOUNTRY governs which 5 GHz channels are legal in the region, so it matters more here than on a 2.4 GHz-only part.

6. TCP/IP, SSL, SNTP, ping, mDNS, OTA

Sockets, secure sockets, time, name resolution, and network firmware upgrade.

Command Function
AT+CIPV6 enable / disable IPv6
AT+CIPSTART / AT+CIPSTARTEX open TCP / UDP / SSL (fixed / auto-assigned link id)
AT+CIPSEND / AT+CIPSENDEX / AT+CIPSENDL / AT+CIPSENDLCFG send data (normal / expanded / long-parallel + its config)
AT+CIPCLOSE close a connection
AT+CIPSTATE list active TCP / UDP / SSL connections
AT+CIPMUX single vs multiple connections
AT+CIPSERVER / AT+CIPSERVERMAXCONN run a TCP/SSL server / cap its clients
AT+CIPMODE normal vs passthrough ("transparent") transmission
+++ escape from passthrough back to command mode
AT+CIPRECONNINTV passthrough reconnect interval
AT+CIPCONNPERSIST keep a connection across resets
AT+CIPSTO server idle timeout
AT+CIPRECVTYPE / AT+CIPRECVDATA / AT+CIPRECVLEN passive-receive mode + read buffered data / length
AT+CIPDINFO include peer IP/port in +IPD notifications
AT+CIPTCPOPT per-socket options (keepalive, etc.)
AT+CIFSR local IP + MAC
AT+CIPDOMAIN resolve a hostname (DNS)
AT+CIPDNS configure DNS servers
AT+PING ICMP ping a host
AT+MDNS advertise / query mDNS services
AT+CIPSNTPCFG / AT+CIPSNTPTIME / AT+CIPSNTPINTV SNTP server + TZ / read time / sync interval
AT+CIPSSLCCONF SSL client mode / CA validation
AT+CIPSSLCCIPHER SSL cipher suite
AT+CIPSSLCCN / AT+CIPSSLCSNI / AT+CIPSSLCALPN SSL common name / SNI / ALPN
AT+CIPSSLCPSK / AT+CIPSSLCPSKHEX SSL pre-shared key (string / hex)
AT+CIPFWVER AT firmware version available on Espressif's OTA server
AT+CIUPDATE OTA-upgrade the AT firmware over the network

7. Bluetooth LE commands

GAP (advertise / scan / connect), GATT server and client, serial passthrough, and pairing.

Command Function
AT+BLEINIT initialise BLE (client / server role)
AT+BLEADDR query / set the BLE address
AT+BLENAME device name
AT+BLESCANPARAM / AT+BLESCAN / AT+BLESCANRSPDATA scan parameters / run scan / scan-response data
AT+BLEADVPARAM / AT+BLEADVDATA / AT+BLEADVDATAEX advertising parameters / raw advert / auto-built advert
AT+BLEADVSTART / AT+BLEADVSTOP start / stop advertising
AT+BLECONN / AT+BLEDISCONN open / close a connection
AT+BLECONNPARAM query / update connection parameters
AT+BLECFGMTU set ATT MTU
AT+BLEGATTSSRV / AT+BLEGATTSCHAR (server) list services / characteristics
AT+BLEGATTSNTFY / AT+BLEGATTSIND (server) notify / indicate a characteristic
AT+BLEGATTSSETATTR (server) set a characteristic value
AT+BLEGATTCPRIMSRV / AT+BLEGATTCINCLSRV / AT+BLEGATTCCHAR (client) discover primary / included services / characteristics
AT+BLEGATTCRD / AT+BLEGATTCWR (client) read / write a characteristic
AT+BLESPPCFG / AT+BLESPP configure / enter BLE serial-passthrough (SPP)
AT+BLESECPARAM pairing / encryption parameters
AT+BLEENC / AT+BLEENCRSP / AT+BLEKEYREPLY / AT+BLECONFREPLY start encryption / respond / supply passkey / confirm
AT+BLEENCDEV / AT+BLEENCCLEAR list / clear bonded devices

BLE security command names beyond the core set vary slightly by version; AT+CMD lists what the running build exposes.

8. MQTT commands

Command Function
AT+MQTTUSERCFG scheme (TCP / TLS), client id, user, password, cert options
AT+MQTTLONGCLIENTID / AT+MQTTLONGUSERNAME / AT+MQTTLONGPASSWORD set long client id / username / password
AT+MQTTCONNCFG keep-alive, clean-session, last-will
AT+MQTTALPN / AT+MQTTSNI TLS ALPN / SNI
AT+MQTTCONN connect to a broker
AT+MQTTPUB / AT+MQTTPUBRAW publish (string / long-raw)
AT+MQTTSUB / AT+MQTTUNSUB subscribe / unsubscribe
AT+MQTTCLEAN disconnect and free the MQTT client

9. HTTP commands

Command Function
AT+HTTPCLIENT one-shot HTTP request (GET / POST / PUT / HEAD…)
AT+HTTPGETSIZE content length of a resource
AT+HTTPCGET fetch a resource
AT+HTTPCPOST / AT+HTTPCPUT POST / PUT a fixed-length body
AT+HTTPURLCFG set a long URL out of band
AT+HTTPCHEAD set / query custom request headers
AT+HTTPCFG client options (content-type, transport, etc.)

10. Other and configurable sets

  • BluFi (default): AT+BLUFI, AT+BLUFINAME, AT+BLUFISEND — Wi-Fi provisioning carried over BLE.
  • User (default): AT+USERRAM, AT+USEROTA, AT+USERWKMCUCFG, AT+USERMCUSLEEP and similar hooks for user-defined RAM storage, user OTA, and a host-MCU wake/sleep handshake.
  • Compile-in only (need a custom ESP-AT build): see below — the Ant64 build enables all of these.

The sets below are absent from Espressif's prebuilt binary but are real ESP-AT commands a local build switches on. The Ant64's N16R8 / N32R8 flash (§1) has room to enable them all, so on the Ant64 build they are available.

FileSystem — a FAT partition in the C5's flash, driven by one multi-operation command:

Command Function
AT+FS filesystem op on a flash FAT file — list, read, write, delete, or query size

WebSocket — up to three client connections, over TCP or TLS:

Command Function
AT+WSCFG per-link config: ping interval / timeout, buffer size, TLS auth
AT+WSOPEN open (or query) a WebSocket connection
AT+WSSEND send data on a connection
AT+WSDATAFMT set the received-data format
AT+WSCLOSE close a connection

Web server — a browser-based config portal served from the C5:

Command Function
AT+WEBSERVER start / stop a captive-portal web server for Wi-Fi provisioning and browser OTA (HTML from a FAT partition or embedded files; FATFS needs FileSystem above)

Driver — lets the host drive the C5's own ADC / PWM / I2C / SPI peripherals over the AT link:

Command Function
AT+DRVADC read an ADC channel
AT+DRVPWMINIT / AT+DRVPWMDUTY / AT+DRVPWMFADE PWM init / set duty / fade
AT+DRVI2CINIT initialise the I2C master
AT+DRVI2CRD / AT+DRVI2CWRDATA / AT+DRVI2CWRBYTES I2C read / write data / write ≤ 4 bytes
AT+DRVSPICONFGPIO / AT+DRVSPIINIT configure SPI pins / init the SPI master
AT+DRVSPIRD / AT+DRVSPIWR SPI read / write

WPA2-Enterprise — adds AT+CWJEAP to the Wi-Fi set (§5) for enterprise-AP association.

11. Using it from DeMon / AntOS

The natural pattern is a small AT-driver task in AntOS that owns the C5 link: bring-up (AT, AT+GMR, AT+CWINIT, AT+CWMODE), join (AT+CWJAP), then either raw sockets (AT+CIPSTART / AT+CIPSEND, with inbound data arriving as +IPD notifications) or a higher-level set (MQTT, HTTP). Two things worth designing around:

  • Command vs passthrough. For bulk single-socket streaming, AT+CIPMODE=1 plus AT+CIPSEND puts the link in transparent passthrough so DeMon streams raw bytes with no per-packet framing; +++ returns to command mode. AT+SAVETRANSLINK can make the C5 enter passthrough automatically at boot.
  • Persistence and flash wear. AT+SYSSTORE controls whether Wi-Fi / config changes are written to NVS. Turning it off keeps joins RAM-only — sensible if DeMon re-provisions the C5 from AntOS on every boot and wants to spare the C5's flash.

Because Wi-Fi and BLE share a single antenna, heavy simultaneous use of both contends for the radio; AT+RFPOWER tunes TX power to the enclosure and regulatory limits.

Conventions for the custom extensions (§12–§15)

Command grammar (§12–§15)

AT+<PREFIX><CMD>[=<param1>,<param2>,…]<CR><LF>
  • Every command line is terminated with \r\n.
  • Parameters are comma-separated (no spaces around commas unless inside a quoted string).
  • Query (read) form: AT+<PREFIX><CMD>? — returns current value(s) or configuration.
  • Execute / set form: AT+<PREFIX><CMD>=<params> — performs an action or writes config.
  • Test form (where implemented): AT+<PREFIX><CMD>=? — returns supported parameter ranges.

Parameter types

Notation Meaning Example
<uint> Unsigned decimal integer 868, 22
<int> Signed decimal integer -120
<hex> Hexadecimal string (no 0x prefix) 1A2B3C
<hex16> 16-character hex string A1B2C3D4E5F67890
<hex32> 32-character hex string 00112233445566778899AABBCCDDEEFF
<string> Quoted if it contains commas, spaces, or control chars "My Network"
<addr> MAC address / BSSID format A1:B2:C3:D4:E5:F6
<ipv4> IPv4 dotted decimal 192.168.1.1
<freq> Frequency in Hz 868000000
<dBm> Power in dBm 14
<enum> One of a fixed set of values; listed per command 0, 1, 2
[opt] Optional parameter

Response grammar

Success:

<CR><LF>
[+PREFIX: <field1>,<field2>,...]<CR><LF>
...
OK<CR><LF>

Error:

<CR><LF>
ERROR<CR><LF>

Or, if AT+SYSLOG=1 is enabled:

<CR><LF>
+ERROR: <err_code>,<err_msg><CR><LF>

Unsolicited result codes (URCs):

<CR><LF>
+PREFIX: <field1>,<field2>,...<CR><LF>
  • Fields are comma-separated.
  • Strings containing commas, spaces, or quotes are enclosed in double quotes ".
  • Binary / raw data payloads are either hex-encoded or sent as length-prefixed blocks (noted per command).
  • URCs always start with + and end with \r\n.

Custom-extension error codes

Code Meaning
600 Generic LoRa radio error
601 LoRa not initialised / no response from LR2021
602 LoRa TX timeout
603 LoRa invalid parameter combination
610 GNSS not powered / no fix
611 GNSS unsupported command / rate
620 RF analysis: monitor mode not available (Wi-Fi station active)
621 RF analysis: FATFS not available (capture storage)
622 RF analysis: CSI not supported by current Wi-Fi config
630 IoT stack: requested stack not compiled in
631 IoT stack: mode change requires restart
632 IoT stack: not joined / not provisioned
640 Invalid argument count or type
641 Command not available in current radio profile

12. LoRa Plus (LR2021) Commands

Prefix: LORA
Radio: Semtech LR2021 (Seeed Wio-LR2021 module) on the C5 SPI bus — a 4th-generation LoRa Plus transceiver
Note: Not present in stock ESP-AT. Added as custom user commands, built on Semtech's LoRa USP / LR20xx radio driver ported to the C5 (replacing the older SX126x driver). LoRa and LoRaWAN share the same namespace; AT+LORANWM selects the mode.

The LR2021 is backward-compatible with LoRa / LoRaWAN, so the point-to-point and LoRaWAN commands in this section carry over unchanged from the SX1262 design. It adds capabilities the SX1262 lacked — dual-band operation (Sub-GHz 863–928 MHz and 2.4 GHz ISM), an S-band satellite / NTN path (≈1.9–2.5 GHz), and high-speed FLRC up to 2.6 Mbps (fast enough for image / audio / bulk-OTA over the link), plus LR-FHSS, (G)FSK and OQPSK. The AT surface for those newer modes is sketched in §12.6; its exact grammar is being finalised during EVK bring-up.

Radio namespacing. The Ant64 has two 2.4 GHz-capable radios — the C5 (Wi-Fi 6 + BLE) and the LR2021 (BLE / 802.15.4 / LoRa). Commands for the C5 keep their plain names (AT+BLESCAN, AT+CWLAP, …); commands that target the LR2021 for a capability the C5 also has are tagged AT+LR… (e.g. AT+LRBLESCAN = BLE scan on the LR2021). LoRa-only commands stay in the AT+LORA… namespace — only the LR2021 has LoRa, so there's no ambiguity. Keeping the literal AT+ prefix matters: the ESP-AT parser dispatches on AT, so an ATLR+ prefix would break it — the LR goes on the command name, not the prefix.

2.4 GHz coexistence. The two radios are independent chips on separate antennas, mounted ~30–40 cm apart (opposite edges of the board) — about 2.5–3 wavelengths at 2.4 GHz, so the isolation between them is substantial and concurrent 2.4 GHz operation is practical: dual-BLE (scan on one, advertise on the other), or the C5 on Wi-Fi while the LR2021 runs a separate 802.15.4 mesh. The LR2021's 2.4 GHz TX also caps at +12 dBm (vs +22 at Sub-GHz), making it a quiet neighbour. Only the worst case — the C5 running high-duty Wi-Fi while the LR2021 tries to receive on 2.4 GHz — benefits from a coexistence hand-off line between the two, extending the C5's existing internal Wi-Fi/BLE coex arbitration.

12.1 Power & initialisation

AT+LORAPWR

Power the LR2021 on or off (toggles GPIO enable line and performs reset sequence).

Syntax Response
AT+LORAPWR? +LORAPWR: <state>
AT+LORAPWR=<state> OK or ERROR

Parameters:

  • <state>: 0 = power off, 1 = power on and reset

Errors: 600, 601


AT+LORARST

Soft-reset the LR2021 (digital reset via SPI command).

Syntax Response
AT+LORARST OK or ERROR

Errors: 600, 601


AT+LORAFACTORY

Restore LR2021 factory defaults (clears volatile config, not flash).

Syntax Response
AT+LORAFACTORY OK or ERROR

AT+LORAVER

Query the LR2021 firmware / chip version.

Syntax Response
AT+LORAVER? +LORAVER: <chip_type>,<version_hex>

Response fields:

  • <chip_type>: LR2021
  • <version_hex>: 4-digit hex version code

AT+LORAUID

Query the LR2021 unique chip ID.

Syntax Response
AT+LORAUID? +LORAUID: <hex16>

12.2 Mode selection (P2P vs LoRaWAN)

AT+LORANWM

Select network work mode.

Syntax Response
AT+LORANWM? +LORANWM: <mode>
AT+LORANWM=<mode> OK or ERROR

Parameters:

  • <mode>:
    • 0 — Point-to-point (raw LoRa, default)
    • 1 — LoRaWAN

Note: Changing mode resets the LoRa stack to default parameters for that mode.


12.3 Point-to-point (P2P) parameters

AT+LORABAND

Set the centre frequency.

Syntax Response
AT+LORABAND? +LORABAND: <freq_hz>
AT+LORABAND=<freq_hz> OK or ERROR

Parameters:

  • <freq_hz>: Centre frequency in Hz. Common values:
    • 433000000 (EU433)
    • 868000000 (EU868)
    • 915000000 (US915)
    • 923000000 (AS923)

Range: 150000000 – 960000000 (hardware limited)

Default: 868000000

Errors: 603


AT+LORAPARAM

Set the modem parameters (spreading factor, bandwidth, coding rate, preamble).

Syntax Response
AT+LORAPARAM? +LORAPARAM: <sf>,<bw>,<cr>,<preamble>
AT+LORAPARAM=<sf>,<bw>,<cr>,<preamble> OK or ERROR

Parameters:

  • <sf>: Spreading factor. 7, 8, 9, 10, 11, 12
  • <bw>: Bandwidth in kHz. 125, 250
  • <cr>: Coding rate denominator. 5 (4/5), 6 (4/6), 7 (4/7), 8 (4/8)
  • <preamble>: Preamble length in symbols. 8 – 65535

Default: 9,125,5,12

Errors: 603


AT+LORAADDR

Set this node's P2P address.

Syntax Response
AT+LORAADDR? +LORAADDR: <addr>
AT+LORAADDR=<addr> OK or ERROR

Parameters:

  • <addr>: 16-bit unsigned address. 0 – 65535

Default: 0


AT+LORANETID

Set the network / group ID (P2P filter).

Syntax Response
AT+LORANETID? +LORANETID: <netid>
AT+LORANETID=<netid> OK or ERROR

Parameters:

  • <netid>: Network ID. 0 – 65535

Default: 0


AT+LORATXPWR

Set RF output power.

Syntax Response
AT+LORATXPWR? +LORATXPWR: <dBm>
AT+LORATXPWR=<dBm> OK or ERROR

Parameters:

  • <dBm>: TX power in dBm. -9 – +22

Default: 14

Errors: 603


AT+LORAMODE

Set the transceiver work mode.

Syntax Response
AT+LORAMODE? +LORAMODE: <mode>
AT+LORAMODE=<mode> OK or ERROR

Parameters:

  • <mode>:
    • 0 — Transceiver (TX + RX, default)
    • 1 — Sleep (low-power standby)
    • 2 — RX duty-cycle (periodic receive for power saving)

12.4 P2P data transfer

AT+LORASEND

Transmit a payload to a destination address.

Syntax Response
AT+LORASEND=<dest_addr>,<len>,<data_hex> OK or ERROR

Overloaded command: this P2P signature applies when AT+LORANWM (§12.2) is in P2P mode; in LoRaWAN mode AT+LORASEND instead takes <port>,<confirm>,<len>,<data_hex> (§12.5). The firmware selects the parser from the active mode, not the argument count.

Parameters:

  • <dest_addr>: Destination 16-bit address. 0 – 65535 (65535 = broadcast)
  • <len>: Payload length in bytes. 0 – 255
  • <data_hex>: Hex-encoded payload. Length must equal <len> × 2 characters.

URC on TX complete:

+LORATX: <dest_addr>,<len>,<status>
  • <status>: 0 = success, 1 = timeout, 2 = CRC error (RX ack if implemented)

Errors: 600, 602, 640


+LORARCV (URC)

Unsolicited inbound packet.

+LORARCV: <src_addr>,<len>,<data_hex>,<rssi>,<snr>

Fields:

  • <src_addr>: Source 16-bit address
  • <len>: Payload length in bytes
  • <data_hex>: Hex-encoded payload
  • <rssi>: Received signal strength indicator (dBm)
  • <snr>: Signal-to-noise ratio (dB, signed integer)

12.5 LoRaWAN parameters

AT+LORADEVEUI

Set the device EUI (OTAA).

Syntax Response
AT+LORADEVEUI? +LORADEVEUI: <hex16>
AT+LORADEVEUI=<hex16> OK or ERROR

AT+LORAAPPEUI

Set the application EUI (OTAA).

Syntax Response
AT+LORAAPPEUI? +LORAAPPEUI: <hex16>
AT+LORAAPPEUI=<hex16> OK or ERROR

AT+LORAAPPKEY

Set the application key (OTAA).

Syntax Response
AT+LORAAPPKEY? +LORAAPPKEY: <hex32>
AT+LORAAPPKEY=<hex32> OK or ERROR

AT+LORADEVADDR

Set the device address (ABP).

Syntax Response
AT+LORADEVADDR? +LORADEVADDR: <hex8>
AT+LORADEVADDR=<hex8> OK or ERROR

AT+LORAJOIN

Join the LoRaWAN network (OTAA or ABP).

Syntax Response
AT+LORAJOIN=<mode>[,<timeout_sec>] OK (async) or ERROR

Parameters:

  • <mode>: 0 = OTAA, 1 = ABP
  • <timeout_sec>: Join attempt timeout. 30 – 600. Default 300.

URC:

+LORAJOIN: <status>    // 0=success, 1=fail, 2=no_free_channel

Errors: 632


AT+LORACLASS

Set the LoRaWAN device class.

Syntax Response
AT+LORACLASS? +LORACLASS: <class>
AT+LORACLASS=<class> OK or ERROR

Parameters:

  • <class>: A, B, or C

AT+LORADR

Set the data rate.

Syntax Response
AT+LORADR? +LORADR: <dr>
AT+LORADR=<dr> OK or ERROR

Parameters:

  • <dr>: Data rate index. 0 – 7 (region-dependent; see regional spec)

AT+LORABAND (LoRaWAN context)

In LoRaWAN mode, AT+LORABAND sets the regional band index rather than raw frequency.

Syntax Response
AT+LORABAND? +LORABAND: <band>
AT+LORABAND=<band> OK or ERROR

Parameters:

  • <band>:
    • 0 = EU868
    • 1 = US915
    • 2 = AU915
    • 3 = AS923
    • 4 = KR920
    • 5 = IN865
    • 6 = EU433

AT+LORASEND (LoRaWAN context)

Uplink data.

Syntax Response
AT+LORASEND=<port>,<confirm>,<len>,<data_hex> OK (async) or ERROR

Overloaded command: this LoRaWAN signature applies when AT+LORANWM (§12.2) is in LoRaWAN mode; in P2P mode AT+LORASEND instead takes <dest_addr>,<len>,<data_hex> (§12.4). The firmware selects the parser from the active mode, not the argument count.

Parameters:

  • <port>: LoRaWAN port. 1 – 223
  • <confirm>: 0 = unconfirmed, 1 = confirmed
  • <len>: Payload length. 0 – 242
  • <data_hex>: Hex-encoded payload

URCs:

+LORATX: <port>,<len>,<status>     // 0=success, 1=no_ack, 2=timeout
+LORARX: <port>,<len>,<data_hex>,<rssi>,<snr>   // downlink received

AT+LORAUSEND

Confirmed uplink with retry control.

Syntax Response
AT+LORAUSEND=<port>,<retries>,<len>,<data_hex> OK (async) or ERROR

Parameters:

  • <retries>: Max retries if no ACK. 0 – 8

AT+LORANJS

Query join status.

Syntax Response
AT+LORANJS? +LORANJS: <status>

Response:

  • <status>: 0 = not joined, 1 = joined, 2 = joining


12.6 New-radio capabilities (LR2021) — provisional

The LR2021 exposes capabilities beyond the SX1262. Everything below extends the existing LORA namespace and is driven through Semtech's LoRa USP driver. The specs are provisional — command and parameter names will be finalised during EVK bring-up; the stubs show the intended shape. The underlying operations map to documented LR2021 host commands (packet-type/modulation select, RTToF ranging, CAD, duty-cycled RX, sleep/standby, GetRandomNumber, GetRssiInst, GetTemp, SetTxTestMode) — see the LR2021 datasheet (Rev 1.1). Error codes 600 (general) and 601 (radio not responding) apply throughout; individual modes may add codes later.

AT+LORABAND

Select the operating RF band (provisional) — the LR2021 is multi-band, so this chooses the front-end port and default frequency plan.

Syntax Response
AT+LORABAND? +LORABAND: <band>
AT+LORABAND=<band> OK or ERROR

Parameters:

  • <band>: SUBGHZ (the chip tunes 150–960 MHz; default LoRaWAN sub-GHz plan, backward-compatible) · 2G4 (2.4 GHz ISM, global single-SKU) · SBAND (S-band NTN / satellite, ≈1.9–2.5 GHz; licensed L-band ≈1.5–2.0 GHz is also supported)

AT+LORAMOD

Select the modulation (provisional). The P2P and LoRaWAN commands (§12.2–§12.5) then run over whichever modulation is active.

Syntax Response
AT+LORAMOD? +LORAMOD: <mod>
AT+LORAMOD=<mod> OK or ERROR

Parameters:

  • <mod>: LORA (default, ≤200 kbps) · FLRC (≤2.6 Mbps) · LRFHSS · FSK · GFSK · OQPSK · OOK

AT+LORAFLRC

Configure FLRC parameters (active when AT+LORAMOD=FLRC) (provisional) — the high-speed mode for image / audio / bulk transfer.

Syntax Response
AT+LORAFLRC? +LORAFLRC: <bitrate>,<cr>,<bt>
AT+LORAFLRC=<bitrate>,<cr>,<bt> OK or ERROR

Parameters:

  • <bitrate>: FLRC bitrate in kbps, up to 2600
  • <cr>: coding rate
  • <bt>: Gaussian filter BT

AT+LORARANGE

Measure distance to a peer node by Round-Trip Time-of-Flight (RTToF) ranging (provisional).

Syntax Response
AT+LORARANGE=<role>,<peer_addr> +LORARANGE: <distance_m>,<rssi>,<quality> then OK, or ERROR

Parameters:

  • <role>: 0 = subordinate (responder) · 1 = manager (initiator, reports the distance)
  • <peer_addr>: address of the node to range against
  • <distance_m>: measured distance in metres (from the RTToF exchange)
  • <quality>: ranging confidence / status (from the radio's ranging stats)

AT+LORASCAN

Spectral scan — sweep a frequency range and report RSSI per step (provisional). Receive-only. Built on the radio's instantaneous-RSSI read (GetRssiInst): with no packet present, that value is the RF noise floor at each frequency, so the sweep is a firmware loop over GetRssiInst, not a single chip command.

Syntax Response
AT+LORASCAN=<start_hz>,<stop_hz>,<step_hz> +LORASCAN: <freq_hz>,<rssi> per bin, then OK

Parameters:

  • <start_hz> / <stop_hz>: sweep range (within the active band)
  • <step_hz>: bin width

AT+LORACAD

Run the LR2021's enhanced Channel Activity Detection (provisional) — listen-before-talk / wake-on-radio. The radio also supports Multi-SF CAD (sensing several spreading factors at once) and Fast CAD (adaptive threshold, early termination).

Syntax Response
AT+LORACAD=<symbols> +LORACAD: <result> then OK

Parameters:

  • <symbols>: number of symbols to sense
  • <result>: 0 = clear · 1 = activity detected

AT+LORAPER

Packet-error-rate / ping-pong link test between two nodes (provisional) — for range and quality checks.

Syntax Response
AT+LORAPER=<role>,<count> +LORAPER: <sent>,<recv>,<per_pct>,<avg_rssi> then OK

Parameters:

  • <role>: 0 = receiver · 1 = transmitter
  • <count>: number of packets

AT+LORASLEEP

Put the radio into a low-power sleep or standby state (provisional) — distinct from AT+LORAPWR, which cuts the GPIO enable line. Maps to SetSleep / SetStandby.

Syntax Response
AT+LORASLEEP=<mode> OK or ERROR

Parameters:

  • <mode>: STANDBY (fast wake, config retained) · SLEEP (deep, ~470 nA, wakes on timer / DIO)

AT+LORARXDC

Enter Rx Duty-Cycle mode (provisional) — the radio periodically wakes to listen, then drops back to sleep until a packet arrives (SetRxDutyCycle). Wake-on-radio for battery beacons and sensors.

Syntax Response
AT+LORARXDC=<rx_ms>,<sleep_ms> OK or ERROR

Parameters:

  • <rx_ms>: listen window per cycle
  • <sleep_ms>: sleep interval between windows

AT+LORATEMP

Read the radio's on-chip temperature (provisional) — GetTemp.

Syntax Response
AT+LORATEMP? +LORATEMP: <celsius> then OK

AT+LORACW

Transmit a continuous-wave / test carrier (provisional) — SetTxTestMode. For antenna tuning, front-end / coexistence checks and certification during bring-up; TX, so mind the front-end limits.

Syntax Response
AT+LORACW=<state> OK or ERROR

Parameters:

  • <state>: 0 = stop · 1 = start CW at the current band / frequency / power

AT+LORARAND

Read hardware random bytes from the radio's true RNG (provisional) — the LR2021 has an on-chip random-number generator (GetRandomNumber), handy for nonces, keys, seeds and games.

Syntax Response
AT+LORARAND=<n> +LORARAND: <hex> then OK

Parameters:

  • <n>: number of random bytes to return (hex-encoded in the response)

AT+LORASAT

Enable the S-band satellite / NTN uplink profile (provisional). Uses S-band + LR-FHSS through a licensed satellite-IoT service — not open transmission.

Syntax Response
AT+LORASAT? +LORASAT: <state>,<profile>
AT+LORASAT=<state>,<profile> OK or ERROR

Parameters:

  • <state>: 0 = off · 1 = on
  • <profile>: satellite-service network profile (operator-specific)

AT+LORATXP

Set transmit power (provisional).

Syntax Response
AT+LORATXP? +LORATXP: <dbm>
AT+LORATXP=<dbm> OK or ERROR

Parameters:

  • <dbm>: target output power — band-dependent max: up to +22 dBm at Sub-GHz, up to +12 dBm at 2.4 GHz; 32 dB range in 0.5 dB steps.

Front-end caution. The switchless PA/LNA share the RF node; transmitting above +6 dBm needs external front-end protection, and absolute-max input is +10 dBm.


Multi-protocol / second-radio headroom. The silicon has PHY-level hardware for Amazon Sidewalk, Meshtastic, Wi-SUN, Wireless M-Bus, Z-Wave, BLE 5 and 802.15.4. With the LR2021 ~30–40 cm from the C5 on its own antenna, its BLE and 802.15.4 are a genuine second 2.4 GHz radio, not dead weight — dual-BLE, or a separate 802.15.4 mesh running alongside the C5's Wi-Fi (see the coexistence note in the §12 intro). Each is exposed only when its stack is ported to the C5 — a real undertaking per protocol — and when exposed it's namespaced AT+LR… to distinguish it from the C5's own BLE / Thread / Zigbee. None are wired up today: a designed-in option, not a committed feature.

RF note. The switchless front end (§AT+LORATXP) and the 2.4 GHz overlap with the C5's Wi-Fi / BLE are the two board-level RF concerns; the ~30–40 cm antenna separation and coexistence approach are covered in the §12 intro.


13. GPS / GNSS Commands

Prefix: GNSS
Receiver: u-blox NEO-M10 (marking NEO-M10 1612F-00-010) on C5 UART1
Note: Not present in stock ESP-AT. Added as custom user commands.

13.1 Power & control

AT+GNSSPWR

Power the GNSS receiver and start/stop NMEA parsing.

Syntax Response
AT+GNSSPWR? +GNSSPWR: <state>
AT+GNSSPWR=<state> OK or ERROR

Parameters:

  • <state>: 0 = power off, 1 = power on and start parsing

Note: If the module has a hardware enable line wired to C5 GPIO, this toggles it.

Errors: 610


AT+GNSSCLR

Clear assistance / almanac data to force a cold start.

Syntax Response
AT+GNSSCLR OK or ERROR

AT+GNSSVER

Query receiver model and firmware version.

Syntax Response
AT+GNSSVER? +GNSSVER: <model>,<fw_ver>,<hw_ver>

Response fields:

  • <model>: NEO-M10N
  • <fw_ver>: Firmware version string
  • <hw_ver>: Hardware version string

13.2 Configuration

AT+GNSSCFG

Configure constellations, baud rate, and similar.

Syntax Response
AT+GNSSCFG? +GNSSCFG: <constellations>,<baud>,<dyn_model>
AT+GNSSCFG=<constellations>,<baud>,<dyn_model> OK or ERROR

Parameters:

  • <constellations>: Bitmask of enabled constellations:
    • 1 = GPS
    • 2 = GLONASS
    • 4 = Galileo
    • 8 = BeiDou
    • Common combos: 1 (GPS only), 5 (GPS+Galileo), 15 (all)
  • <baud>: UART baud rate for NEO-M10. 9600, 19200, 38400, 57600, 115200. Default 9600.
  • <dyn_model>: Dynamic platform model:
    • 0 = Portable (default)
    • 2 = Stationary
    • 3 = Pedestrian
    • 4 = Automotive

Errors: 611


AT+GNSSRATE

Set position update rate.

Syntax Response
AT+GNSSRATE? +GNSSRATE: <hz>
AT+GNSSRATE=<hz> OK or ERROR

Parameters:

  • <hz>: Update rate in Hz. 1, 2, 5, 10

Note: NEO-M10 supports up to 10 Hz in standard multi-constellation mode. Higher rates require GPS-only mode and are not guaranteed.

Default: 1

Errors: 611


AT+GNSSCMD

Pass a raw UBX or NMEA command to the receiver.

Syntax Response
AT+GNSSCMD=<protocol>,<cmd_hex> OK or ERROR

Parameters:

  • <protocol>: 0 = NMEA, 1 = UBX
  • <cmd_hex>: Hex-encoded command string

Response: protocol-tagged, so the host can dispatch without inspecting the payload:

  • NMEA reply (within 1 second): +GNSSCMD: NMEA,<reply_string>
  • UBX reply: +GNSSCMD: UBX,<reply_hex>
  • No reply: only OK is returned.

Errors: 610


13.3 Position queries

AT+GNSSINF

One-shot fix summary.

Syntax Response
AT+GNSSINF? +GNSSINF: <fix_status>,<utc_date>,<utc_time>,<lat>,<lon>,<alt>,<speed>,<course>,<fix_mode>,<hdop>,<pdop>,<vdop>,<sats_used>,<sats_in_view>

Response fields:

  • <fix_status>: 0 = no fix, 1 = fix, 2 = differential fix
  • <utc_date>: YYYYMMDD
  • <utc_time>: HHMMSS.sss
  • <lat>: Latitude in degrees, signed decimal (e.g. 51.5074)
  • <lon>: Longitude in degrees, signed decimal
  • <alt>: Altitude above mean sea level in metres
  • <speed>: Ground speed in km/h
  • <course>: Course over ground in degrees
  • <fix_mode>: 1 = no fix, 2 = 2D, 3 = 3D
  • <hdop> / <pdop> / <vdop>: Dilution of precision
  • <sats_used>: Satellites used for fix
  • <sats_in_view>: Satellites in view

Note: If no fix, lat/lon/alt are 0 and fix_status is 0.


AT+GNSSLOC

Shorter location-only query.

Syntax Response
AT+GNSSLOC? +GNSSLOC: <fix_quality>,<lat>,<lon>,<utc_time>

Response fields:

  • <fix_quality>: 0 = invalid, 1 = GPS fix, 2 = DGPS fix
  • <lat> / <lon>: Signed decimal degrees
  • <utc_time>: HHMMSS.sss

AT+GNSSNMEA

Fetch a specific NMEA sentence on demand.

Syntax Response
AT+GNSSNMEA=<sentence> $<sentence>,...*<cs><CR><LF>OK or ERROR

Parameters:

  • <sentence>: GGA, RMC, GSV, GSA, VTG, GLL

Note: Returns the most recent cached sentence of that type. If none cached, waits up to 2 seconds for the receiver to emit one.


13.4 Unsolicited reporting

AT+GNSSURC

Enable/disable periodic position push.

Syntax Response
AT+GNSSURC? +GNSSURC: <interval_sec>
AT+GNSSURC=<interval_sec> OK or ERROR

Parameters:

  • <interval_sec>: Report interval in seconds. 0 = disable URC. 1 – 3600.

URC format:

+GNSS: <fix_status>,<utc_date>,<utc_time>,<lat>,<lon>,<alt>,<speed>,<course>,<sats_used>

13.5 Raw passthrough

AT+GNSSTST

Raw-NMEA passthrough mode.

Syntax Response
AT+GNSSTST? +GNSSTST: <state>
AT+GNSSTST=<state> OK or ERROR

Parameters:

  • <state>: 0 = off (parsed mode, default), 1 = on (raw NMEA streamed to AT link)

Note: When enabled, every NMEA sentence received from the receiver is emitted on the AT link as raw text (not prefixed with +GNSS:). This lets AntOS parse NMEA itself. All other AT+GNSS… commands remain functional but may interleave with raw sentences.



14. RF Analysis and Link Diagnostics

Prefix: MON (passive monitors), WIFI (Wi-Fi tools), BLE (BLE tools), IPERF, LINKQ, LATTEST, ANTBENCH
Note: Not present in stock ESP-AT. Added as custom user commands.
Authorised use only: observation-only for your own networks and devices.

14.1 Channel & survey

AT+CHANNELSCORE

Recommend best operating channel.

Syntax Response
AT+CHANNELSCORE? +CHANNELSCORE: <band>,<ch1>,<score1>,<ch2>,<score2>,...
AT+CHANNELSCORE=<band> +CHANNELSCORE: <band>,<ch1>,<score1>,...

Parameters:

  • <band>: 0 = 2.4 GHz, 1 = 5 GHz. If omitted in query, scores both bands.

Response fields:

  • <band>: 0 or 1
  • Channel-score pairs: <channel>,<score> where score is 0–100 (higher = cleaner)

AT+WIFIHEATMAP

Long-term channel-utilisation survey.

Syntax Response
AT+WIFIHEATMAP=<action>[,<duration_sec>] OK or +WIFIHEATMAP: <data> or ERROR

Parameters:

  • <action>:
    • 0 = stop survey
    • 1 = start survey
    • 2 = query results
  • <duration_sec>: Survey duration if starting. 10 – 3600. Default 60.

Response (action=2):

+WIFIHEATMAP: <channel>,<busy_pct>,<ap_count>,<sta_count>,<noise_dbm>,<avg_rssi>

(Repeated per channel, terminated by OK)

Errors: 620


AT+WIFICHAN

Park the radio on a specific channel.

Syntax Response
AT+WIFICHAN? +WIFICHAN: <channel>,<dwell_ms>
AT+WIFICHAN=<channel>[,<dwell_ms>] OK or ERROR

Parameters:

  • <channel>: Wi-Fi channel number. 1–14 (2.4 GHz), 36–177 (5 GHz)
  • <dwell_ms>: Dwell time in milliseconds. 50 – 10000. Default 100.

Note: Requires Wi-Fi to be in monitor mode or disconnected. Returns ERROR if station is connected.

Errors: 620


14.2 Capture & CSI

AT+PCAPSTART

Start promiscuous monitor capture.

Syntax Response
AT+PCAPSTART[=<filename>][,<mode>] OK or ERROR

Parameters:

  • <filename>: Name for FATFS file. Max 31 chars. If omitted, stream mode.
  • <mode>:
    • 0 = stream to UART as +PCAP: URCs (see below) — the AT parser stays live, so AT+PCAPSTOP can end the session at any time
    • 1 = record to FATFS (default if filename given)

URC (mode 0):

+PCAP: <seq>,<hex>
  • <seq>: monotonic chunk counter
  • <hex>: hex-encoded captured PCAP record (one frame per URC)

Note: Capture takes the radio off normal station/AP duty. Wi-Fi connectivity pauses. Mode 0 streams hex URCs rather than raw binary specifically so the AT parser is never suspended.

Errors: 620, 621


AT+PCAPSTOP

Stop capture.

Syntax Response
AT+PCAPSTOP +PCAP: <records>,<bytes> then OK or ERROR

Response fields:

  • <records>: Number of frames captured
  • <bytes>: Total bytes captured

AT+WIFICAPCFG

Configure capture filter.

Syntax Response
AT+WIFICAPCFG? +WIFICAPCFG: <frame_class>,<bssid_filter>,<max_records>
AT+WIFICAPCFG=<frame_class>[,<bssid_filter>][,<max_records>] OK or ERROR

Parameters:

  • <frame_class>: Bitmask:
    • 1 = Management
    • 2 = Control
    • 4 = Data
    • 7 = All (default)
  • <bssid_filter>: Optional BSSID to filter (AA:BB:CC:DD:EE:FF or any). Default any.
  • <max_records>: Max frames to capture. 0 = unlimited. Default 0.

AT+CSISTREAM

Start continuous CSI capture.

Syntax Response
AT+CSISTREAM=<action>[,<interval_ms>] OK or ERROR

Parameters:

  • <action>: 0 = stop, 1 = start
  • <interval_ms>: Sampling interval. 10 – 1000. Default 100.

URC:

+CSI: <timestamp>,<subcarrier_count>,<amplitude_hex>,<phase_hex>

Errors: 620, 622


AT+CSISTATS

Report CSI statistics.

Syntax Response
AT+CSISTATS? +CSISTATS: <samples>,<avg_amp>,<std_amp>,<motion_detected>

Response fields:

  • <samples>: Total CSI samples since start
  • <avg_amp>: Average amplitude across subcarriers
  • <std_amp>: Standard deviation of amplitude
  • <motion_detected>: 0 or 1

AT+PRESENCE

Occupancy / motion detection using CSI.

Syntax Response
AT+PRESENCE? +PRESENCE: <state>,<confidence>
AT+PRESENCE=<action> OK or ERROR

Parameters:

  • <action>: 0 = disable, 1 = enable

Response / URC:

+PRESENCE: <state>,<confidence>
  • <state>: 0 = vacant, 1 = occupied, 2 = motion detected
  • <confidence>: 0–100

14.3 BLE tracking

AT+BLETRACK

Track BLE advertisers over time.

Syntax Response
AT+BLETRACK=<action>[,<duration_sec>] OK or ERROR

Parameters:

  • <action>: 0 = stop, 1 = start
  • <duration_sec>: 10 – 3600. Default 60.

URC:

+BLETRACK: <addr>,<addr_type>,<rssi>,<name>,<last_seen_sec>

AT+BLEIBEACONSCAN

Decode iBeacon / Eddystone frames.

Syntax Response
AT+BLEIBEACONSCAN=<action> OK or ERROR

Parameters:

  • <action>: 0 = stop, 1 = start

URC:

+IBEACON: <type>,<uuid>,<major>,<minor>,<tx_power>,<rssi>     // iBeacon
+EDDYSTONE: <type>,<namespace>,<instance>,<rssi>              // Eddystone

14.4 Service discovery

AT+NETDISCOVER

Discover mDNS / SSDP services.

Syntax Response
AT+NETDISCOVER=<protocol>,<service>[,<timeout_sec>] OK + URCs or ERROR

Parameters:

  • <protocol>: 0 = mDNS, 1 = SSDP
  • <service>: Service type string, e.g. "_http._tcp" or "upnp:rootdevice"
  • <timeout_sec>: 1 – 30. Default 5.

URC:

+NETDISCOVER: <ip>,<port>,<name>,<txt>

14.5 Logging & diagnostics

AT+RFLOGGER

Periodic RF environment logging.

Syntax Response
AT+RFLOGGER=<action>[,<interval_sec>] OK or ERROR

Parameters:

  • <action>: 0 = stop, 1 = start
  • <interval_sec>: 5 – 300. Default 30.

URC:

+RFLOG: <timestamp>,<wifi_ch>,<wifi_rssi>,<ble_dev_count>,<noise_floor>

AT+WIFIDIAG

Complete RF health report.

Syntax Response
AT+WIFIDIAG? +WIFIDIAG: <report>

Response fields (multi-line):

+WIFIDIAG: <tx_packets>,<tx_retries>,<tx_failures>
+WIFIDIAG: <rx_packets>,<rx_crc_err>,<rx_drop>
+WIFIDIAG: <phy_rate>,<rssi>,<noise_floor>

AT+COEXSTAT

Wi-Fi / BLE coexistence statistics.

Syntax Response
AT+COEXSTAT? +COEXSTAT: <wifi_state>,<ble_state>,<iot_state>,<lora_state>,<wifi_airtime_pct>,<ble_airtime_pct>,<last_conflict_reason>

Response fields:

  • <wifi_state>: 0 = off, 1 = idle, 2 = STA connected, 3 = AP, 4 = monitor
  • <ble_state>: 0 = off, 1 = idle, 2 = advertising, 3 = scanning, 4 = connected
  • <iot_state>: 0 = off, 1 = thread, 2 = zigbee, 3 = matter, 4 = blemesh, 5 = meshlite
  • <lora_state>: 0 = off, 1 = idle, 2 = TX, 3 = RX
  • <wifi_airtime_pct>: 0–100
  • <ble_airtime_pct>: 0–100
  • <last_conflict_reason>: 0 = none, 1 = Wi-Fi priority, 2 = BLE priority, 3 = radio unavailable

14.6 Active link tests

AT+IPERF

TCP / UDP throughput test.

Syntax Response
AT+IPERF=<role>,<proto>,<dir>,<host>,<port>,<duration_sec>[,<bw_mbps>] OK (async) or ERROR

Parameters:

  • <role>: 0 = client, 1 = server
  • <proto>: 0 = TCP, 1 = UDP
  • <dir>: 0 = download (RX), 1 = upload (TX), 2 = bidirectional
  • <host>: Target IP (client only). "" or omitted for server.
  • <port>: Port number. 1 – 65535
  • <duration_sec>: Test duration. 1 – 600
  • <bw_mbps>: UDP target bandwidth in Mbps (UDP only). 0 = unlimited.

URC:

+IPERF: <role>,<proto>,<dir>,<bytes>,<bps>,<jitter_ms>,<loss_pct>

Errors: 640


AT+LINKQ

One-shot link-quality snapshot.

Syntax Response
AT+LINKQ? +LINKQ: <rssi>,<phy_rate>,<band>,<channel>,<tx_retries>,<rx_retries>

Response fields:

  • <rssi>: dBm
  • <phy_rate>: Mbps (e.g. 72.2)
  • <band>: 0 = 2.4 GHz, 1 = 5 GHz
  • <channel>: Channel number
  • <tx_retries> / <rx_retries>: Retry counts since connect

AT+LATTEST

Latency profile to a host.

Syntax Response
AT+LATTEST=<host>,<count>,<interval_ms> OK (async) or ERROR

Parameters:

  • <host>: IP address or hostname
  • <count>: Number of probes. 1 – 1000
  • <interval_ms>: Interval between probes. 10 – 10000

URC:

+LATTEST: <host>,<sent>,<received>,<min_ms>,<avg_ms>,<max_ms>,<jitter_ms>,<loss_pct>

AT+ANTBENCH

Antenna / placement comparison benchmark.

Syntax Response
AT+ANTBENCH=<ant_sel>,<test_type>,<duration_sec> OK (async) or ERROR

Parameters:

  • <ant_sel>: Antenna selection:
    • 0 = onboard ceramic
    • 1 = external port 1
    • 2 = external port 2
  • <test_type>: 0 = RSSI survey, 1 = throughput (needs peer), 2 = link quality
  • <duration_sec>: 5 – 300

URC:

+ANTBENCH: <ant_sel>,<test_type>,<score>,<rssi_avg>,<throughput_mbps>

Note: If the hardware has no RF switch, <ant_sel> is ignored and only onboard is tested.


14.7 Defensive security monitoring

The observation-only primitives above double as a home-network defence toolkit: the same monitor-mode capture that surveys RF also detects attacks against your own network, and the TCP/IP stack (§6) lets AntOS audit your own LAN. The guiding principle mirrors §14's stance and is worth stating plainly:

Defence is achieved by listening, not transmitting. Every capability here is receive-only or aimed inward at a network you own. There are deliberately no attack primitives – no deauthentication, no evil-twin AP, no beacon flood, no frame injection. You detect a deauth attack by hearing the flood, spot an evil twin by seeing the duplicate SSID, and find a stalking tracker by noticing the MAC that follows you. None of it requires transmitting, which is exactly what keeps the toolkit cleanly defensive. Two namespaces keep the split legible: AT+MON… are passive monitors (no target, safe always-on); AT+SCAN… are active but require an explicit in-scope target (your own subnet) and refuse to run without one.

AT+WIFISNIFF

Enter monitor mode and stream frame metadata.

Syntax Response
AT+WIFISNIFF=<action>,<channel>[,<filter_mask>] OK or ERROR

Parameters:

  • <action>: 0 = stop, 1 = start
  • <channel>: Channel to monitor
  • <filter_mask>: Bitmask of frame types to report:
    • 1 = Management (beacon, probe, auth, assoc)
    • 2 = Control (RTS, CTS, ACK)
    • 4 = Data
    • 8 = Deauth / disassoc only
    • Combine by addition (e.g. 7 = mgmt + ctrl + data). Default 1 (management only) — correct for the defensive deauth / rogue-AP use case; set 7 for general recon, or control and data frames won't be reported.

URC:

+SNIFF: <timestamp>,<type>,<src_addr>,<dst_addr>,<bssid>,<rssi>,<channel>
  • <type>: MGMT, CTRL, DATA, DEAUTH

Errors: 620


AT+MONDEAUTH

Watch for deauth / disassoc floods.

Syntax Response
AT+MONDEAUTH=<action>[,<threshold>[,<window_sec>]] OK or ERROR

Parameters:

  • <action>: 0 = stop, 1 = start
  • <threshold>: Frames per window to alarm. 10 – 1000. Default 50.
  • <window_sec>: Time window in seconds. 1 – 60. Default 10.

URC (alarm):

+MONDEAUTH: <timestamp>,<count>,<src_addr>,<dst_addr>,<channel>

AT+MONROGUECFG

Configure known-good BSSID database for rogue-AP detection.

Syntax Response
AT+MONROGUECFG=<op>[,<ssid>,<bssid>] OK or +MONROGUECFG: <entries> or ERROR

Parameters:

  • <op>:
    • 0 = clear all
    • 1 = add entry
    • 2 = delete entry
    • 3 = list entries
  • <ssid>: Network name (quoted if needed). Required for op 1 and 2.
  • <bssid>: MAC address. Required for op 1 and 2.

Response (op=3):

+MONROGUECFG: <ssid>,<bssid>

(repeated, terminated by OK)


AT+MONROGUE

Detect evil-twin APs (SSIDs with unexpected BSSIDs).

Syntax Response
AT+MONROGUE=<action> OK or ERROR

Parameters:

  • <action>: 0 = stop, 1 = start

URC:

+MONROGUE: <timestamp>,<ssid>,<expected_bssid>,<rogue_bssid>,<channel>,<rssi>

Note: Requires entries in the AT+MONROGUECFG database, or auto-learns from past AT+CWJAP connections (documented behaviour).


AT+CLIENTWATCH

Inventory stations on your network.

Syntax Response
AT+CLIENTWATCH=<action>[,<bssid>[,<channel>]] OK or ERROR

Parameters:

  • <action>: 0 = stop, 1 = start, 2 = dump current inventory
  • <bssid>: Your AP's BSSID to filter against. Required for start.
  • <channel>: Channel your AP is on. Required for start.

URC:

+CLIENTWATCH: <mac>,<first_seen>,<last_seen>,<rssi>,<pkts>

Note: Without <bssid>, the command returns ERROR (no default target).


AT+BEACONMON

Track all APs in range over time.

Syntax Response
AT+BEACONMON=<action> OK or ERROR

Parameters:

  • <action>: 0 = stop, 1 = start

URC:

+BEACONMON: <timestamp>,<bssid>,<ssid>,<channel>,<rssi>,<security>,<new_flag>
  • <new_flag>: 0 = seen before, 1 = new since start

AT+BLERECON

Continuous BLE scan logging.

Syntax Response
AT+BLERECON=<action> OK or ERROR

Parameters:

  • <action>: 0 = stop, 1 = start

URC:

+BLERECON: <timestamp>,<addr>,<addr_type>,<rssi>,<name>,<service_uuids>,<mfg_data_hex>

AT+MONBLETAG

Unwanted-tracker detector (AirTag-style stalking).

Syntax Response
AT+MONBLETAG=<action>[,<threshold_min>] OK or ERROR

Parameters:

  • <action>: 0 = stop, 1 = start
  • <threshold_min>: Minutes a non-randomising MAC must follow you. 5 – 120. Default 15.

URC:

+MONBLETAG: <timestamp>,<addr>,<rssi_history_hex>,<duration_min>

AT+BLESPOOFDETECT

Detect duplicate advertised BLE identities.

Syntax Response
AT+BLESPOOFDETECT=<action> OK or ERROR

Parameters:

  • <action>: 0 = stop, 1 = start

URC:

+BLESPOOFDETECT: <timestamp>,<legitimate_addr>,<spoof_addr>,<rssi>,<name>


14.8 Example – scan.lua (LAN host + port audit, stock firmware)

A worked AntOS example of the active-but-inward pattern: sweep your own subnet for live hosts, then probe a short list of common ports on each. It uses only stock AT commands (AT+PING, AT+CIPSTART / AT+CIPCLOSE), so it runs on a bare ESP-AT flash with no custom at_ant64 build. Note the deliberate design: the subnet is a required argument – the tool will not run without an explicit in-scope target, which is what keeps an active scanner defensible.

-- scan.lua  -  audit YOUR OWN LAN: live-host sweep + common-port probe.
-- Active scanning: requires an explicit in-scope subnet (no default target).
-- Built entirely on stock ESP-AT (AT+PING, AT+CIPSTART) via the phreak lib.

local a, done = os.arguments{
    name = "scan",
    desc = "Audit your own LAN for live hosts and open ports",
    long = "Pings every host in a /24 you specify, then probes common TCP "
        .. "ports on the ones that answer. Point it ONLY at a network you "
        .. "own or are authorised to test.",
    { "*Subnet", help = "in-scope /24 base, e.g. 192.168.1  (REQUIRED)" },
    { "-Ports",  help = "comma list to probe (default: common set)" },
}
if done then return end

if not a.subnet then
    print("scan: refusing to run without an explicit subnet (in-scope target).")
    print("usage: scan 192.168.1   [-ports 22,80,443]")
    return
end

local phreak = require("phreak")           -- Phreak AT link (see wiki: phreak)
local base   = a.subnet:gsub("%.%d+$", "") -- tolerate "192.168.1" or "192.168.1.0"

-- Common ports worth flagging on a home LAN (services that often shouldn't
-- be exposed). Override with -ports.
local ports = { 22, 23, 53, 80, 139, 443, 445, 554, 1900, 3389, 8080, 8443 }
if a.ports then
    ports = {}
    for p in a.ports:gmatch("%d+") do ports[#ports+1] = tonumber(p) end
end

print("scan: sweeping " .. base .. ".1-254 (in-scope: you own this) ...")

local live = {}
for host = 1, 254 do
    local ip = base .. "." .. host
    -- AT+PING <ip> -> round-trip ms, or timeout. phreak.ping wraps it.
    local ok, ms = phreak.ping(ip, 300)    -- 300 ms budget per host
    if ok then
        live[#live+1] = ip
        print(string.format("  up   %-15s  %d ms", ip, ms))
    end
end

if #live == 0 then
    print("scan: no hosts answered - check the subnet and that Wi-Fi is joined.")
    return
end

print(string.format("scan: %d live host(s); probing %d port(s) each ...",
                    #live, #ports))

for _, ip in ipairs(live) do
    local openp = {}
    for _, port in ipairs(ports) do
        -- AT+CIPSTART="TCP",<ip>,<port> with a short timeout: a successful
        -- connect => port open. phreak.tcpprobe wraps start+close.
        if phreak.tcpprobe(ip, port, 400) then
            openp[#openp+1] = port
        end
    end
    if #openp > 0 then
        print(string.format("  %-15s  open: %s", ip,
                            table.concat(openp, ", ")))
    end
end

print("scan: done. Review anything unexpected - unknown hosts, or ports "
    .. "open that shouldn't be (e.g. 23/telnet, 3389/RDP, 445/SMB to the WAN).")

phreak.ping and phreak.tcpprobe are thin lib_phreak helpers over AT+PING and AT+CIPSTART/AT+CIPCLOSE – the same require-only pattern as the flasher verbs. The script never transmits anything but connection attempts to addresses you named, and refuses to start without a subnet: the active-but-inward rule in code.

15. IoT Radios — 802.15.4 and Mesh

Prefix: IOT, THREAD, ZB, MATTER, BMESH, MLITE
Note: Not present in stock ESP-AT. Added as custom user commands. The 802.15.4 radio runs one stack at a time.

15.1 Stack selection

AT+IOTMODE

Select the active 802.15.4 / IoT personality.

Syntax Response
AT+IOTMODE? +IOTMODE: <mode>
AT+IOTMODE=<mode> OK or ERROR

Parameters:

  • <mode>:
    • 0 = off
    • 1 = Thread
    • 2 = Zigbee
    • 3 = Matter-over-Thread
    • 4 = Matter-over-Wi-Fi
    • 5 = BLE Mesh
    • 6 = ESP-Mesh-Lite (Wi-Fi)

Note: Changing AT+IOTMODE requires AT+RST to unload the previous stack and initialise the new one. The command returns OK immediately but sets a pending flag; the switch happens on the next boot. Querying after OK but before restart returns the pending mode.

Errors: 630, 631


15.2 Thread

AT+THREADINIT

Initialise the Thread stack.

Syntax Response
AT+THREADINIT OK or ERROR

Note: Must be called after AT+IOTMODE=1 and restart.


AT+THREADDATASET

Get / set the active dataset.

Syntax Response
AT+THREADDATASET? one +THREADDATASET: <field>,<value> line per field (see below), then OK
AT+THREADDATASET=<field>,<value> OK or ERROR

Parameters:

  • <field>: KEY, PANID, XPANID, NAME, CHAN
  • <value>:
    • KEY: 32-char hex network key
    • PANID: 4-char hex PAN ID
    • XPANID: 16-char hex extended PAN ID
    • NAME: Network name string (max 16 chars)
    • CHAN: Channel. 11–26

Query response — one field per line, so the host can parse incrementally with no comma/semicolon splitting:

+THREADDATASET: KEY,<hex32>
+THREADDATASET: PANID,<hex4>
+THREADDATASET: XPANID,<hex16>
+THREADDATASET: NAME,<string>
+THREADDATASET: CHAN,<uint>
OK

AT+THREADIF

Bring the Thread IPv6 interface up or down.

Syntax Response
AT+THREADIF=<state> OK or ERROR

Parameters:

  • <state>: 0 = down, 1 = up

AT+THREADSTART / AT+THREADSTOP

Start / stop the Thread protocol.

Syntax Response
AT+THREADSTART OK or ERROR
AT+THREADSTOP OK or ERROR

AT+THREADSTATE

Query Thread role / state.

Syntax Response
AT+THREADSTATE? +THREADSTATE: <state>

Response:

  • <state>: disabled, detached, child, router, leader

AT+THREADSCAN

Active scan for nearby Thread networks.

Syntax Response
AT+THREADSCAN OK + URCs or ERROR

URC:

+THREAD: SCAN,<panid>,<name>,<channel>,<rssi>,<lqi>,<ext_addr>

AT+THREADJOIN

Join by commissioning (joiner start).

Syntax Response
AT+THREADJOIN=<pskd>[,<timeout_sec>] OK (async) or ERROR

Parameters:

  • <pskd>: Joiner passphrase. 6–32 chars.
  • <timeout_sec>: 30–600. Default 120.

URC:

+THREAD: JOIN,<status>    // 0=success, 1=timeout, 2=credentials_rejected

AT+THREADCOMM

Act as commissioner.

Syntax Response
AT+THREADCOMM=<action>[,<eui64>,<pskd>] OK or ERROR

Parameters:

  • <action>: 0 = stop commissioner, 1 = start commissioner, 2 = add joiner
  • <eui64>: Joiner EUI-64 (16 hex chars). Required for action 2.
  • <pskd>: Joiner passphrase. Required for action 2.

AT+THREADIPADDR

List / add IPv6 addresses.

Syntax Response
AT+THREADIPADDR? +THREADIPADDR: <addr1>,<addr2>,...
AT+THREADIPADDR=<action>[,<addr>] OK or ERROR

Parameters:

  • <action>: 0 = list, 1 = add, 2 = remove

+THREAD (URC)

Thread state changes and inbound datagrams.

+THREAD: STATE,<old_state>,<new_state>
+THREAD: DATA,<src_addr>,<port>,<len>,<data_hex>

15.3 Zigbee

AT+ZBROLE

Set Zigbee role.

Syntax Response
AT+ZBROLE? +ZBROLE: <role>
AT+ZBROLE=<role> OK or ERROR

Parameters:

  • <role>: 0 = coordinator, 1 = router, 2 = end-device

Note: Must be set before AT+ZBINIT.


AT+ZBINIT

Initialise the Zigbee stack.

Syntax Response
AT+ZBINIT OK or ERROR

AT+ZBPANID / AT+ZBCHAN

Set PAN ID and channel.

Syntax Response
AT+ZBPANID=<panid> OK or ERROR
AT+ZBCHAN=<channel> OK or ERROR

Parameters:

  • <panid>: 16-bit hex PAN ID. 0x0000–0xFFF7
  • <channel>: 11–26

AT+ZBFORM

Form a network (coordinator only).

Syntax Response
AT+ZBFORM OK or ERROR

AT+ZBSTEER

Join an existing network.

Syntax Response
AT+ZBSTEER OK (async) or ERROR

URC:

+ZB: STEER,<status>    // 0=success, 1=fail, 2=no_network

AT+ZBPERMIT

Open / close the join window.

Syntax Response
AT+ZBPERMIT=<seconds> OK or ERROR

Parameters:

  • <seconds>: 0 = close, 1–254 = open for N seconds, 255 = always open

AT+ZBNODES

List joined nodes.

Syntax Response
AT+ZBNODES? +ZBNODES: <short_addr>,<ieee_addr>,<role> (repeated)

AT+ZBATTRRD / AT+ZBATTRWR

Read / write ZCL attribute.

Syntax Response
AT+ZBATTRRD=<short_addr>,<endpoint>,<cluster_hex>,<attr_hex> +ZBATTR: <status>,<data_type>,<data_hex>
AT+ZBATTRWR=<short_addr>,<endpoint>,<cluster_hex>,<attr_hex>,<data_type>,<data_hex> OK or ERROR

Parameters:

  • <short_addr>: 16-bit hex network address
  • <endpoint>: 1–240
  • <cluster_hex>: 4-char hex cluster ID
  • <attr_hex>: 4-char hex attribute ID
  • <data_type>: ZCL data type enum (e.g. 0x10 = bool, 0x21 = uint16)

AT+ZBCMD

Send a ZCL cluster command.

Syntax Response
AT+ZBCMD=<short_addr>,<endpoint>,<cluster_hex>,<cmd_hex>[,<data_hex>] OK or ERROR

AT+ZBREPORT

Configure attribute reporting.

Syntax Response
AT+ZBREPORT=<short_addr>,<endpoint>,<cluster_hex>,<attr_hex>,<min_int>,<max_int>[,<delta>] OK or ERROR

AT+ZBBIND

Bind clusters between endpoints.

Syntax Response
AT+ZBBIND=<src_addr>,<src_ep>,<cluster_hex>,<dst_addr>,<dst_ep> OK or ERROR

+ZB (URC)

Zigbee events.

+ZB: JOIN,<short_addr>,<ieee_addr>,<role>
+ZB: REPORT,<short_addr>,<endpoint>,<cluster_hex>,<attr_hex>,<data_hex>
+ZB: CMD,<short_addr>,<endpoint>,<cluster_hex>,<cmd_hex>,<data_hex>

15.4 Matter

AT+MATTERINIT

Initialise Matter on the chosen transport.

Syntax Response
AT+MATTERINIT OK or ERROR

Note: Transport is determined by AT+IOTMODE (3 = Thread, 4 = Wi-Fi).


AT+MATTERCOMM

Commission a device.

Syntax Response
AT+MATTERCOMM=<type>,<payload> OK (async) or ERROR

Parameters:

  • <type>: 0 = manual pairing code, 1 = QR code payload
  • <payload>: String payload

URC:

+MATTER: COMM,<status>,<node_id>    // 0=success

AT+MATTERFABRIC

List / remove commissioned fabrics.

Syntax Response
AT+MATTERFABRIC=<action>[,<fabric_index>] OK or +MATTERFABRIC: <index>,<label> or ERROR

Parameters:

  • <action>: 0 = list, 1 = remove by index

AT+MATTERINVOKE

Invoke a cluster command.

Syntax Response
AT+MATTERINVOKE=<node_id>,<endpoint>,<cluster_hex>,<command_hex>[,<arg_tlv_hex>] OK or ERROR

Parameters:

  • <node_id>: 64-bit hex node ID
  • <endpoint>: 0–65535
  • <cluster_hex>: 8-char hex cluster ID
  • <command_hex>: 4-char hex command ID
  • <arg_tlv_hex>: Optional hex-encoded Matter TLV arguments

Note: For simple types, use AT+MATTERCONV first (see below).


AT+MATTERREAD / AT+MATTERSUB

Read / subscribe to an attribute.

Syntax Response
AT+MATTERREAD=<node_id>,<endpoint>,<cluster_hex>,<attr_hex> +MATTER: READ,<data_tlv_hex>
AT+MATTERSUB=<node_id>,<endpoint>,<cluster_hex>,<attr_hex>[,<min_int>[,<max_int>]] OK or ERROR

AT+MATTERCONV

Helper: convert simple value to Matter TLV hex.

Syntax Response
AT+MATTERCONV=<type>,<value> +MATTERCONV: <tlv_hex>

Parameters:

  • <type>:
    • 0 = bool (0 or 1)
    • 1 = uint8
    • 2 = uint16
    • 3 = uint32
    • 4 = int8
    • 5 = int16
    • 6 = int32
    • 7 = string (quoted)

AT+MATTERONOFF

Shortcut for On/Off cluster.

Syntax Response
AT+MATTERONOFF=<node_id>,<endpoint>,<state> OK or ERROR

Parameters:

  • <state>: 0 = off, 1 = on, 2 = toggle

+MATTER (URC)

Matter events.

+MATTER: COMM,<status>,<node_id>
+MATTER: REPORT,<node_id>,<endpoint>,<cluster_hex>,<attr_hex>,<data_tlv_hex>

15.5 Bluetooth LE Mesh

AT+BMESHROLE

Set BLE Mesh role.

Syntax Response
AT+BMESHROLE? +BMESHROLE: <role>
AT+BMESHROLE=<role> OK or ERROR

Parameters:

  • <role>: 0 = provisioner, 1 = node

AT+BMESHPROV

Provision or emit unprovisioned beacon.

Syntax Response
AT+BMESHPROV=<action>[,<uuid>] OK (async) or ERROR

Parameters:

  • <action>:
    • 0 = stop
    • 1 = start beaconing (node)
    • 2 = start scanning + provisioning (provisioner)
  • <uuid>: 32-char hex device UUID (provisioner action 2, optional filter)

URC:

+BMESH: PROV,<status>,<uuid>,<addr>    // status: 0=success

AT+BMESHKEY

Set network / application keys.

Syntax Response
AT+BMESHKEY=<type>,<index>,<hex_key> OK or ERROR

Parameters:

  • <type>: 0 = net key, 1 = app key
  • <index>: Key index. 0–4095
  • <hex_key>: 32-char hex (128-bit)

AT+BMESHBIND

Bind a model to an app key.

Syntax Response
AT+BMESHBIND=<elem_addr>,<model_id>,<appkey_index> OK or ERROR

AT+BMESHPUB / AT+BMESHSUB

Model publish address / subscription.

Syntax Response
AT+BMESHPUB=<elem_addr>,<model_id>,<pub_addr>[,<ttl>[,<period>]] OK or ERROR
AT+BMESHSUB=<elem_addr>,<model_id>,<sub_addr> OK or ERROR

AT+BMESHONOFF

Generic OnOff model get / set.

Syntax Response
AT+BMESHONOFF=<addr>,<state> OK or ERROR
AT+BMESHONOFF=<addr>,? +BMESHONOFF: <addr>,<state>

Parameters:

  • <addr>: Destination unicast or group address
  • <state>: 0 = off, 1 = on, ? = get

+BMESH (URC)

BLE Mesh events.

+BMESH: PROV,<status>,<uuid>,<addr>
+BMESH: MSG,<src_addr>,<model_id>,<opcode>,<data_hex>

15.6 ESP-Mesh-Lite (Wi-Fi)

AT+MLITEEN

Enable / disable Wi-Fi mesh.

Syntax Response
AT+MLITEEN? +MLITEEN: <state>
AT+MLITEEN=<state> OK or ERROR

Parameters:

  • <state>: 0 = disable, 1 = enable

AT+MLITEID

Set mesh ID / configuration.

Syntax Response
AT+MLITEID? +MLITEID: <mesh_id>,<channel>,<password>
AT+MLITEID=<mesh_id>[,<channel>[,<password>]] OK or ERROR

Parameters:

  • <mesh_id>: Mesh network identifier string (max 32 chars)
  • <channel>: Wi-Fi channel. 1–14
  • <password>: WPA2 passphrase (quoted, max 64 chars)

AT+MLITELEVEL

Query or pin node level.

Syntax Response
AT+MLITELEVEL? +MLITELEVEL: <level>,<is_root>
AT+MLITELEVEL=<pin>[,<desired_level>] OK or ERROR

Parameters:

  • <pin>: 0 = automatic, 1 = pin as root, 2 = pin as leaf
  • <desired_level>: Only used if pin=1 (force root level). 0–6.

AT+MLITETOPO

Query topology.

Syntax Response
AT+MLITETOPO? +MLITETOPO: <parent_mac>,<parent_rssi>,<level>,<child_count>

Response fields:

  • <parent_mac>: Parent node MAC or 00:00:00:00:00:00 if root
  • <parent_rssi>: dBm to parent
  • <level>: Current tree level
  • <child_count>: Number of children

AT+MLITESEND

Send data in the mesh.

Syntax Response
AT+MLITESEND=<dest_type>,<dest>[,<len>,<data_hex>] OK or ERROR

Parameters:

  • <dest_type>: 0 = root, 1 = parent, 2 = broadcast downward, 3 = unicast MAC
  • <dest>: MAC address if dest_type=3, else omitted or 0
  • <len>: Payload length. 0–1460
  • <data_hex>: Hex-encoded payload

+MLITE (URC)

Mesh events and inbound messages.

+MLITE: TOPO,<parent_mac>,<level>
+MLITE: DATA,<src_mac>,<len>,<data_hex>

16. Bridging & gateway commands

Prefix: BRIDGE
Note: Not present in stock ESP-AT. Added as custom user commands. A bridge spans both radios, so it's its own namespace — not under AT+LORA… or the AT+LR… tag.

The C5 hosts both the LR2021 (over SPI) and its own Wi-Fi / BLE, so both packet streams already live inside one chip. That makes the Ant64 a gateway: it can sit between two otherwise-incompatible networks and translate. The bridge runs in the C5 firmware — DeMon configures a few rules over AT and then stays out of the data path; the C5 forwards autonomously. DeMon sets policy, the C5 moves the bytes.

These are provisional (like §12.6) and gated by the stacks underneath: a bridge can only connect protocols the C5 actually speaks. LoRa ↔ BLE is near-term (both largely present); anything involving Zigbee / Wi-SUN / Z-Wave waits on that stack being ported to the LR2021. The command set can be documented before every endpoint it could name is live. Bridge errors use 660 (unknown rule id) and 661 (endpoint protocol / stack not available).

Endpoints name a radio + protocol: LORA · LRBLE (LR2021 BLE) · LR154 (LR2021 802.15.4) · BLE (C5) · WIFI (C5, e.g. an MQTT topic) · THREAD / ZB (C5 802.15.4). A rule forwards <from> → <to>.


AT+BRIDGEADD

Create a bridging rule (provisional) — returns a rule <id>.

Syntax Response
AT+BRIDGEADD=<from>,<to>,<filter> +BRIDGEADD: <id> then OK, or ERROR

Parameters:

  • <from> / <to>: source and destination endpoints (see above)
  • <filter>: optional match — address / type / topic; empty = forward everything

Errors: 661 (endpoint not available)


AT+BRIDGEMAP

Set how a rule translates payloads (provisional).

Syntax Response
AT+BRIDGEMAP=<id>,<rule> OK or ERROR

Parameters:

  • <id>: rule from AT+BRIDGEADD
  • <rule>: PASS (identity passthrough) · REMAP:<spec> (field remap) · a named codec

Errors: 660 (unknown id)


AT+BRIDGE

Start or stop a rule (provisional).

Syntax Response
AT+BRIDGE=<id>,<state> OK or ERROR

Parameters:

  • <id>: rule id
  • <state>: 0 = stop · 1 = start

Errors: 660


AT+BRIDGE? / AT+BRIDGESTAT

List rules, or read a rule's counters (provisional).

Syntax Response
AT+BRIDGE? one +BRIDGE: <id>,<from>,<to>,<state> per rule, then OK
AT+BRIDGESTAT=<id> +BRIDGESTAT: <forwarded>,<dropped>,<errors> then OK

AT+BRIDGEDEL

Remove a rule (provisional).

Syntax Response
AT+BRIDGEDEL=<id> OK or ERROR

Errors: 660


URC — +BRIDGE: (provisional). When enabled on a rule, the C5 emits a notification each time a packet crosses, so DeMon can log or intervene without sitting in the fast path:

+BRIDGE: <id>,<from>,<to>,<len>

Store-and-forward. Buffering is C5-local — the C5's PSRAM holds the queue, so DeMon is not in the data path. A rule runs in one of three tiers:

  • Pass-through — no buffering; the C5 forwards live.
  • PSRAM buffered (C5) — absorb bursts, hold a short queue while the far side is briefly unreachable, or rate-match a fast LoRa-FLRC feed into slower BLE advertisements. Entirely C5-side; covers the large majority of gateway needs. Queue depth is bounded by free PSRAM after the radio stacks take their share (an EVK bring-up measurement — TBD).
  • DBFS staged (DeMon) — only for what PSRAM can't be: persistence across reboot / power-loss, very large backlogs, or hold-for-hours windows. This tier is about durability and capacity, not smoothing; crossings are handed to DeMon / DBFS.

Appendix A. Quick-reference: Prefix-to-domain mapping

Prefix Domain Section
LORA LoRa / LoRaWAN / FLRC (LR2021) §12
GNSS GPS / GNSS (NEO-M10) §13
MON Passive security monitors §14.7
WIFI Wi-Fi analysis tools §14.1–14.3
BLE BLE tracking §14.3
IPERF / LINKQ / LATTEST / ANTBENCH Active link tests §14.6
IOT IoT stack selection §15.1
THREAD Thread (802.15.4) §15.2
ZB Zigbee (802.15.4) §15.3
MATTER Matter §15.4
BMESH BLE Mesh §15.5
MLITE ESP-Mesh-Lite (Wi-Fi) §15.6
BRIDGE Cross-radio bridging / gateway §16

Sources

Espressif ESP-AT User Guide for the ESP32-C5 (latest) is the authoritative reference:

The §12 radio is the Semtech LR2021 (Seeed Wio-LR2021 module), driven by Semtech's LoRa USP; the AT naming conventions for the backward-compatible LoRa / LoRaWAN modes are drawn from off-the-shelf LoRa AT modules:

For the GPS/GNSS command vocabulary (§13), the conventions follow GNSS-over-AT modems:

  • SIMCom SIM868 / SIM7000 GNSS Application Note — AT+CGNSPWR, AT+CGNSINF, AT+CGNSURC, AT+CGNSTST
  • Quectel GNSS AT Commands Manual (EC25 / BG96) — AT+QGPS, AT+QGPSLOC, AT+QGPSGNMEA, AT+QGPSCFG

The RF analysis and link diagnostics (§14) sit on standard ESP-IDF features plus ESP-CSI — the Wi-Fi driver's promiscuous (monitor) mode for capture, ESP-CSI for channel-state / presence, NimBLE for BLE, and the Wi-Fi iperf example for the active throughput tests:

The IoT radios (§15) bridge these stacks, whose CLI/SDK vocabularies the proposed commands follow:

Important: The Ant64 family of home computers are at early design/prototype stage, everything you see here is subject to change.