How ESP-NOW Works: The Protocol Powering BLEShark Shiver Mesh
BLEShark Nano's Shiver mesh runs on ESP-NOW - Espressif's proprietary peer-to-peer protocol that operates over the 802.11 physical layer. If you've used WiFi, you're familiar with the stack it sits on. But ESP-NOW throws away almost everything above the PHY layer that makes regular WiFi what it is.
No SSID negotiation. No DHCP. No TCP/IP. No association handshake. Just MAC-to-MAC frames over the air at up to 250 kbps in Long Range mode, with delivery confirmation at the hardware level.
Understanding ESP-NOW matters if you want to understand why Shiver works the way it does - why the range is what it is, why latency is low, why you can run a mesh on ESP32-C3 hardware with 320KB of RAM without running a TCP stack, and why the 250-byte frame limit shapes everything about how the protocol is used.
Table of Contents
- What Problem ESP-NOW Solves
- How It Differs From Regular WiFi
- How It Differs From BLE
- The Frame Structure
- Long Range Mode
- Encryption Model
- ESP-NOW in Shiver
- Limitations Worth Knowing
graph LR
subgraph ESPNOW["ESP-NOW Frame (inside WiFi Vendor Action)"]
subgraph WIFI_HDR["WiFi MAC Header"]
FC["Frame Control
(Action frame)"]
ADDR1["Dest Address
(Broadcast or Unicast)"]
ADDR2["Source Address
(Sender MAC)"]
BSSID["BSSID
(Broadcast)"]
end
subgraph VENDOR["Vendor Action Frame"]
OUI["Espressif OUI
18:FE:34"]
TYPE_F["Type: 0x04
(ESP-NOW)"]
VER["Version"]
end
subgraph PAYLOAD["ESP-NOW Payload"]
SRC["Source MAC
(6 bytes)"]
DST["Destination MAC
(6 bytes)"]
DATA_LEN["Data Length
(1 byte, max 250)"]
APP_DATA["Application Data
(up to 250 bytes)"]
end
FCS["FCS
(CRC-32)"]
end
FC --> ADDR1 --> ADDR2 --> BSSID --> OUI --> TYPE_F --> VER --> SRC --> DST --> DATA_LEN --> APP_DATA --> FCS
subgraph COMPARE["Protocol Comparison"]
subgraph ESP["ESP-NOW"]
E1["No association needed"]
E2["No AP required"]
E3["Max 250 bytes/frame"]
E4["Up to 20 peers"]
E5["~1ms latency"]
end
subgraph WIFI_REG["Regular WiFi"]
W1["Association required"]
W2["AP infrastructure"]
W3["Full MTU (1500 bytes)"]
W4["IP-based routing"]
W5["~10-50ms latency"]
end
subgraph BLE_CMP["BLE"]
B1["Pairing required"]
B2["GATT connection"]
B3["Max ~247 bytes/packet"]
B4["Point-to-point"]
B5["~7.5ms latency"]
end
end
ESP-NOW frame structure embedded inside a WiFi vendor action frame - no association or AP needed, just peer-to-peer with up to 250 bytes payload at sub-millisecond latency.
What Problem ESP-NOW Solves
The standard 802.11 WiFi stack is designed for client-to-infrastructure communication. A client device associates with an access point, gets an IP address, and then communicates through that AP to reach other devices or the internet. The full stack - authentication, association, DHCP, ARP, IP routing - adds latency, RAM overhead, and complexity.
For IoT applications that need to communicate directly between devices without infrastructure, this overhead is expensive. Espressif designed ESP-NOW to operate at the 802.11 data link layer, bypassing the entire IP stack. Two ESP32 devices can exchange data within milliseconds of each other knowing the other's MAC address, with no network infrastructure involved at all.
This is the key value: fast, direct, infrastructure-free communication between ESP32 devices. For a mesh of BLEShark Nanos spread across a building, this means no router required, no IP address management, no WiFi credentials to configure on each node. Devices communicate directly, and the Shiver mesh protocol handles routing between devices that aren't in direct range of each other.
How It Differs From Regular WiFi
Regular 802.11 WiFi (the kind your phone and laptop use) requires several things before any data can flow:
First, device discovery: the client either listens for beacon frames from nearby APs or actively probes for known SSIDs. Then authentication: the client and AP perform a handshake (WPA2's 4-way handshake, or WPA3's SAE). Then association: the client formally joins the AP's BSS. Then network configuration: DHCP assigns an IP address. Then finally, application data flows.
Each of these steps takes time and requires protocol state to be maintained. The association state means the AP tracks which clients are connected. If you move out of range, you have to re-associate. If the AP goes down, clients need to find a new one.
ESP-NOW skips all of this. There is no association. No authentication in the 802.11 sense. No IP addresses. A device simply constructs an ESP-NOW frame addressed to a target MAC, and sends it. The hardware delivers it if the target is reachable. The only prerequisite is knowing the target device's MAC address - which in Shiver is handled during the initial BLE pairing.
The comparison table:
- WiFi: Association required, DHCP, IP routing, TCP/UDP stack, multiple RTTs before data flows
- ESP-NOW: No association, no IP, raw MAC frames, data flows in one round trip
The tradeoff is scope. WiFi is flexible - you can reach any device on the internet. ESP-NOW is local - it only works between ESP32 devices that know each other's MACs, and only within radio range (directly, or via mesh hops).
How It Differs From BLE
BLE (Bluetooth Low Energy) is a separate radio protocol that also runs at 2.4GHz, but is designed for different use cases. BLE advertising is designed for short-range, low-power device discovery and small data transfers. The maximum payload in a BLE advertising packet is 31 bytes (or 255 bytes with extended advertising on BLE 5.0).
BLE connections use a GATT (Generic Attribute Profile) model - a client and server negotiate a connection, establish characteristics, and exchange data in a structured way. Connection establishment takes several advertising intervals to complete. Power consumption in connected mode depends on the connection interval negotiated between devices.
ESP-NOW differences:
- Frame size: ESP-NOW supports up to 250 bytes per frame vs BLE advertising's 31-255 bytes
- Connectionless: ESP-NOW requires no connection establishment - send and receive immediately
- Range: ESP-NOW with Long Range PHY extends substantially beyond standard BLE range
- Throughput: ESP-NOW at standard rates is faster than BLE advertising
- Broadcast: ESP-NOW can broadcast to FF:FF:FF:FF:FF:FF (all nearby devices), BLE advertising is inherently broadcast but not addressed
In Shiver, BLE is used only for the initial pairing step - the one-time exchange of MACs, eFuse IDs, and the master secret. After that, all communication switches to ESP-NOW. BLE and the Shiver mesh cannot run simultaneously on a single device because the ESP32-C3 has one radio shared between both protocols.
The Frame Structure
An ESP-NOW frame is wrapped in a standard 802.11 data frame at the physical layer. From the ESP32 firmware perspective, you provide a destination MAC address and up to 250 bytes of payload. The hardware adds the 802.11 frame headers.
The 250-byte payload limit is a hard constraint that shapes all of Shiver's protocol design. Every wire format in Shiver - sync frames, HELLO messages, data frames, routing messages - is designed to fit within this envelope. When application payloads exceed 250 bytes (like a full WiFi scan result set or a settings JSON blob), Shiver's fragmentation layer splits them into chunks, each fitting within one ESP-NOW frame, and reassembles them at the destination.
Mesh communication between nodes runs over ESP-NOW - Espressif's connectionless WiFi protocol. BLE is used only for the initial pairing step; once paired, the radio operates exclusively in ESP-NOW mode. /li>
For comparison, a single WiFi scan result (SSID + BSSID + RSSI + channel + encryption type) is 42 bytes in Shiver's wire format. That fits about 4-5 complete AP records per ESP-NOW frame. Full scan results are fragmented across multiple frames.
stateDiagram-v2
[*] --> Discovery: Power on
state Discovery {
[*] --> Broadcast: Send beacon
Broadcast --> Listen: Wait for responses
Listen --> RegisterPeer: Peer found
RegisterPeer --> Broadcast: Continue scanning
RegisterPeer --> Ready: Max peers or timeout
}
state Ready {
[*] --> Idle
Idle --> SendUnicast: Data for direct peer
Idle --> RouteDiscovery: Data for remote peer
state RouteDiscovery {
[*] --> RREQ: Broadcast Route Request
RREQ --> WaitRREP: Wait for Route Reply
WaitRREP --> CacheRoute: Route found via relay
CacheRoute --> [*]
}
SendUnicast --> WaitACK: Frame sent
WaitACK --> Delivered: ACK received
WaitACK --> Retry: No ACK (timeout)
Retry --> SendUnicast: Retransmit
Retry --> Failed: Max retries exceeded
RouteDiscovery --> MultiHop: Route cached
state MultiHop {
[*] --> Hop1: Send to next relay
Hop1 --> Hop2: Relay forwards
Hop2 --> HopN: Additional relays
HopN --> Destination: Final delivery
}
}
state LongRange {
[*] --> LR_Config: Set PHY to 802.11 LR
LR_Config --> LR_Mode: 500Kbps or 250Kbps
LR_Mode --> Extended: Range up to 1km+
note right of Extended: Espressif proprietary
PHY rates
}
Ready --> LongRange: Enable LR mode
ESP-NOW peer-to-peer lifecycle with AODV mesh routing - from peer discovery through unicast delivery with ACK, multi-hop relay for distant nodes, and optional long-range mode for extended coverage.
Long Range Mode
Standard ESP-NOW uses the same PHY rates as regular WiFi - up to 54 Mbps in 802.11g. These rates work for short distances but signal degrades quickly over distance or through obstacles.
Espressif added a Long Range (LR) mode to ESP-NOW that uses a proprietary PHY rate: WIFI_PHY_RATE_LORA_250K. At 250 kbps, the bitrate is much lower than standard WiFi, but the extended preamble and modulation scheme used by LR mode provides substantially better link budget - meaning the signal can be received reliably at lower received power levels.
The practical effect: Shiver can maintain links between nodes that would be out of range with standard WiFi rates. The 20-50m range figure for Shiver nodes reflects Long Range mode enabled. In open space with line of sight, range extends further. Through walls and floors it reduces, but LR mode maintains links that standard ESP-NOW would drop.
Shiver enables Long Range mode at mesh initialization and re-enables it after any WiFi feature (portal, scan, deauth) that temporarily needed standard rates. The radio automatically reverts to LR mode when the mesh resumes.
One caveat: LR mode is not compatible with standard WiFi devices. A regular WiFi adapter or access point cannot receive ESP-NOW LR frames. This isn't a problem for Shiver - it only needs to communicate between BLEShark Nano devices, all of which support LR mode.
Encryption Model
ESP-NOW supports per-peer encryption using a 128-bit Link Master Key (LMK). When encryption is enabled, frames are encrypted with CCMP (the same cipher used in WPA2). Each peer relationship can have its own LMK, meaning compromising one link does not affect others.
The ESP-NOW encryption model is simpler than full WPA2 - there is no 4-way handshake, no session key rotation, and no replay protection beyond what the application layer implements. The trade-off is deliberate: ESP-NOW prioritizes low latency and minimal overhead over the full security guarantees of an association-based WiFi connection.
For applications that need stronger security, the encryption can be layered with application-level authentication. The BLEShark Nano's Shiver mesh uses ESP-NOW's encryption capabilities along with additional cryptographic measures to secure inter-node communication.
ESP-NOW in Shiver
The BLEShark Nano's Shiver mesh network is built entirely on ESP-NOW. When you pair two or more Nano nodes, they form a peer-to-peer mesh where each node communicates directly with its neighbors using ESP-NOW frames.
Shiver uses ESP-NOW's Long Range mode to extend the communication distance between nodes to 20-50 meters in typical indoor environments. The mesh supports up to 16 nodes, with multi-hop routing so nodes that are not within direct range of each other can still communicate through intermediate nodes.
The key capabilities that ESP-NOW enables for Shiver:
- Coordinated channel partitioning across nodes for full 2.4GHz coverage
- Distributed WiFi and BLE scanning with aggregated results
- Multi-device deauth detection across all channels simultaneously
- Captive portal A/B testing with different configurations per node
- RSSI-based device triangulation using multiple observation points
Because ESP-NOW operates without an access point, the mesh has no single point of failure. If one node goes offline, the remaining nodes re-route automatically. This peer-to-peer architecture is what makes Shiver practical for distributed security assessments.
Limitations Worth Knowing
250-byte frame limit: Every ESP-NOW frame can carry at most 250 bytes of application data. For larger payloads, the application must implement its own fragmentation and reassembly.
2.4GHz only: ESP-NOW operates exclusively on the 2.4GHz band. It cannot use 5GHz channels. This means it shares spectrum with WiFi, Bluetooth, Zigbee, and microwave ovens.
Single radio constraint: The ESP32-C3 has one radio. ESP-NOW, WiFi station mode, and BLE all share it. You cannot run ESP-NOW and maintain a persistent BLE connection at the same time - the firmware must time-share the radio between protocols.
No built-in routing: ESP-NOW itself is a single-hop protocol. Multi-hop communication (like Shiver's mesh routing) must be implemented at the application layer on top of ESP-NOW's raw frame delivery.
Peer limit: The ESP-NOW API supports a limited number of peers per device. For mesh networks that exceed this limit, the application must manage peer table rotation.
No guaranteed delivery: ESP-NOW provides a per-frame ACK mechanism, but there is no built-in retry or reliability layer. If a frame is not acknowledged, the application decides whether and how to retry.