Skip to content

Network & Web Services Module

The Network & Web Services module is the central connectivity layer of the Pibot CNC Pendant firmware. It owns the entire radio lifecycle — from raw hardware bring-up through to the application-level services that let the pendant talk to a CNC controller, serve a WebUI, and announce itself on the local network.

The module runs inside a single dedicated FreeRTOS task on Core 0, protected by a binary mutex. All sub-services (HTTP server, WebSocket servers, mDNS, SSDP, authentication, NTP, notifications, and CNC transports) are started only after the selected radio interface is fully operational, ensuring stable initialization under the ESP32’s tight memory constraints.

ResponsibilityOwner
Radio mode state machine (WiFi / Bluetooth / off)ESP3DNetwork
FreeRTOS task lifecycle & mutexESP3DXNetwork / networkTask
WiFi STA connection, reconnect, static IPESP3DWifiClient
WiFi AP provisioning modeESP3DWifiClient
Bluetooth Classic SPP (serial profile)ESP3DBTSerialClient
Bluetooth BLE (GATT client)ESP3DBTBleClient
HTTP / HTTPS server & REST handlersESP3DHttpService
WebSocket server — WebUI channelESP3DWebUiService
WebSocket server — binary data channelESP3DWsDataService
mDNS / Bonjour announcements and scanESP3DmDNS
SSDP / UPnP device discoveryESP3Dssdp
Session-based authenticationESP3DAuthenticationService
NTP time synchronisationTimeService
Push notifications (Telegram, email, etc.)ESP3DNotificationsService
TCP socket CNC transport (Telnet-style)ESP3DSocketClient
WebSocket CNC transportESP3DWebsocketClient

CNC Transports (started by Services)

Application Services (WiFi only)

Radio Layer

Core 0 · Network Task

esp3d_task_create_pinned

Core 0

begin / handle

handle

on WiFi ready

ESP3DXNetwork

Task Launcher

networkTask

FreeRTOS task

xNetworkSemaphore

Binary Mutex

ESP3DNetwork

Radio Orchestrator

ESP3DNetworkServices

Services Manager

ESP3DWifiClient

STA + AP

ESP3DBTSerialClient

Bluetooth SPP

ESP3DBTBleClient

Bluetooth BLE

ESP3DHttpService

HTTP / HTTPS Server

ESP3DWebUiService

WebSocket - WebUI

ESP3DWsDataService

WebSocket - Data

ESP3DmDNS

mDNS / Bonjour

ESP3Dssdp

SSDP / UPnP

ESP3DAuthenticationService

Session Auth

TimeService

NTP

ESP3DNotificationsService

Push Notifications

ESP3DSocketClient

TCP Raw Socket

ESP3DWebsocketClient

WebSocket Client


Files: main/modules/network/esp3d_x_network.h / esp3d_x_network.cpp

ESP3DXNetwork is the entry point called by ESP3DX::begin() during firmware initialisation. Its sole job is to pin-create the networkTask FreeRTOS task and then delegate all periodic work to ESP3DNetwork::handle() through the task loop.

bool ESP3DXNetwork::begin() {
// Pins networkTask to NETWORK_TASK_CORE (Core 0)
BaseType_t res = esp3d_task_create_pinned(networkTask, "tftNetwork",
STACKDEPTH, NULL,
TASKPRIORITY, &xHandle, TASKCORE);
}

The global instance esp3dXnetwork is used internally by the task loop. No other module calls it directly.


File: main/modules/network/esp3d_x_network.cpp

This is the main loop for all network activity. It runs on Core 0 and never returns.

Yes

No

Task start

Create xNetworkSemaphore

WIFI_FEATURE?

esp_netif_init

esp_event_loop_create_default

esp3dNetwork.begin

Loop forever

Wait 10 ms

Take mutex

esp3dXnetwork.handle

esp3dNetwork.handle

esp3d_sensor.handle

Give mutex

The mutex (xNetworkSemaphore) serialises concurrent access. Any other task that calls network APIs must acquire this semaphore first.


File: main/modules/network/esp3d_network.h

ESP3DNetwork is a final singleton (esp3dNetwork) that owns the radio-mode state machine. It selects which radio back-end is active and manages all mode transitions.

begin() / default

setMode(wifi_sta)

setMode(wifi_ap)

setMode(wifi_ap_config)

setMode(wifi_ap_limited)

setMode(bluetooth_serial)

setMode(bluetooth_ble)

setMode(none)

setMode(off)

setMode(off)

setMode(off)

setMode(off)

setMode(off)

setMode(off)

setMode(off)

mode change

mode change

off

wifi_sta

wifi_ap

wifi_ap_config

wifi_ap_limited

bluetooth_serial

bluetooth_ble

none

ESP3DRadioModeValueDescription
off0Radio disabled
wifi_sta1WiFi Station — connects to an existing AP
wifi_ap2WiFi Access Point — hosts its own network
wifi_ap_config3WiFi AP configuration / captive portal
bluetooth_serial4Bluetooth Classic (SPP profile)
bluetooth_ble5Bluetooth Low Energy (GATT)
wifi_ap_limited6WiFi AP with limited functionality
none7Radio initialised but idle

Boot validation (a14): a radio mode read from NVS that is not a valid value (for example 255, stored by [ESP110]WIFI-STA before the setting was validated) is replaced by the default instead of leaving the radio in an undefined state.

STA rejoin from the setup fallback ([ESP109], a14): when a wifi_sta start fails and the setup AP (wifi_ap_config) is started as fallback, _in_sta_fallback is set (and "Waiting for STA network" is sent to all clients when the setting esp3d_sta_fallback_retry is on). Every 2 minutes (STA_FALLBACK_RETRY_INTERVAL_MS) handleStaFallbackRetry(), on the network task, scans for the configured STA SSID (blocking, about 2 s, filtered on that SSID so no AP list is kept in RAM), in APSTA mode so the AP keeps running. When the SSID is visible it sends "STA network found, reconnecting" and calls setMode(wifi_sta); if that attempt fails, setMode() falls back to the setup AP as at boot. The retry is skipped while a station uses the setup AP (a scan changes channel), while another scan runs (the WiFi Scan screen and [ESP410] switch to APSTA themselves), when the setting is off, or when the saved radio mode is not wifi_sta. Any other mode change clears _in_sta_fallback.

⚠️ Mutual exclusion: WiFi and Bluetooth cannot run simultaneously on this hardware (no PSRAM). cmake/sanity_check.cmake enforces this at build time. See docs/features/feature_resource_matrix.md.

MethodDescription
begin()Reads mode from NVS settings, starts the configured radio back-end
handle()Called every 10 ms — polls the active transport and triggers service updates
end()Stops all active services and the radio
setMode(mode, restart)Synchronous mode switch; stops current mode, starts new one
setModeAsync(mode)Posts a mode change for execution on the next handle() tick (safe from callbacks). _async_radio_mode is a std::atomic, consumed with exchange(none), so a request posted while handle() consumes the previous one is never lost (a14)
radioIsCncLink() (static, a14)true when the CNC output client goes through the radio (socket / WebSocket client, BT serial / BLE). Only then may the radio layers (WiFi, network, network services) write connection_status / server_status; with a serial / UART Ext / USB output the radio is for remote or debug access and those values belong to the CNC transport. Radio-layer writes go through setCncLinkStatus()
getLocalIp()Returns ESP3DIpInfos (IP + DNS) for the active STA interface
getBTMac()Returns the Bluetooth MAC address string

File: main/modules/network/esp3d_network_services.h

ESP3DNetworkServices starts all application-level services once the WiFi stack is ready. It uses deferred startup with absolute deadlines to absorb the WiFi IP acquisition delay and avoid tight polling.

NotificationsTime ServiceSSDPmDNSWebSocket ServicesHTTP ServiceAuthenticationESP3DNetworkServicesESP3DNetworkNotificationsTime ServiceSSDPmDNSWebSocket ServicesHTTP ServiceAuthenticationESP3DNetworkServicesESP3DNetworkDeferred ~500 ms (avoids lwIP race)Deferred ~500 msSocket / WS client started\nif SOCKET_CLIENT / WS_CLIENT feature ONbegin() [after IP acquired]begin()begin()register WebSocket handlersbegin()begin()begin() [after deadline]begin() [after deadline]SocketClient / WsClient begin()

Deferred start state is tracked per-service with boolean flags and int64_t deadline timestamps:

// Excerpt from ESP3DNetworkServices private members
bool _mdns_defer_pending;
std::int64_t _mdns_defer_deadline_ms;
bool _ssdp_defer_pending;
std::int64_t _ssdp_defer_deadline_ms;
#if ESP3D_SOCKET_CLIENT_FEATURE
bool _socket_client_defer_pending;
std::int64_t _socket_client_defer_deadline_ms;
#endif

ℹ️ esp3dNetworkServices is only instantiated when ESP3D_WIFI_FEATURE is enabled.


Files: main/modules/wifi/esp3d_wifi_client.h, esp3d_wifi_sta.cpp, esp3d_wifi_ap.cpp

ESP3DWifiClient (global esp3dWifiClient) manages both the STA and AP netifs through the ESP-IDF WiFi driver. A single FreeRTOS event group (_s_wifi_event_group) synchronises connection state with the network task.

ESP3DValueswifi_sta_event_handlerESP3DWifiClientESP3DNetworkESP3DValueswifi_sta_event_handlerESP3DWifiClientESP3DNetworkalt[Got IP (IP_EVENT_STA_GOT_IP)][Auth failure (wrong password)][Disconnect / retry][Max retries exceeded]connect()esp_wifi_start()connection_status = "T"esp_wifi_connect()connection_status = "C"Set WIFI_CONNECTED_BITconnect() returns trueesp3dNetworkServices.begin()connection_status = "A"disableAutoReconnect()Set WIFI_FAIL_BITconnect() returns falseconnection_status = "?"esp_wifi_connect() [retry loop]Set WIFI_FAIL_BITconnect() returns false

Published to ESP3DValues (ESP3DValuesIndex::connection_status) and consumed by the UI layer (see UI Framework & Screens). Since a14 the WiFi and network layers write it (and server_status) only when the radio is the CNC link (ESP3DNetwork::radioIsCncLink()); otherwise the CNC transport owns both values.

ValueMeaningTrigger
"U"Unconnected — no radio activeESP3DNetwork::startNoRadioMode()
"T"Trying — STA connection in progressWIFI_EVENT_STA_START handler
"C"Connected — IP acquired, services runningIP_EVENT_STA_GOT_IP handler
"?"Unknown / lost — retrying or timed outWIFI_EVENT_STA_DISCONNECTED / IP_EVENT_STA_LOST_IP
"A"Auth failed — wrong password, no further retryWIFI_REASON_AUTH_FAIL / WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT

AUTH_FAIL or

4WAY_TIMEOUT

other

yes

no

yes

no

DISCONNECTED event

reason?

disableAutoReconnect

status = A

Set FAIL_BIT

autoReconnect

disabled?

Stay disconnected

status = ?

retry_num <

MAX_RETRY?

esp_wifi_connect

retry_num++

Set FAIL_BIT

status = ?

retry_num = 0

disableAutoReconnect() is also set by userDisconnect() (user-initiated disconnect via UI). It is cleared on every WIFI_EVENT_STA_START event so that explicit mode changes and reboots work normally.

struct ESP3DIpInfos {
esp_netif_ip_info_t ip_info; // IP / netmask / gateway
esp_netif_dns_info_t dns_info; // Primary DNS
};

Populated by ESP3DWifiClient::getLocalIp() and used by the HTTP service, mDNS, and SSDP.


⚠️ WiFi and Bluetooth are mutually exclusive on this platform. The CMake build system forbids enabling both simultaneously.

Bluetooth Classic SPP — ESP3DBTSerialClient

Section titled “Bluetooth Classic SPP — ESP3DBTSerialClient”

Files: main/modules/bt_serial/
See Communication Transports for full transport details.

The client implements a four-state connection machine and shares the init-command / auto-reconnect patterns common to all CNC transports:

connect()

SPP_OPEN_EVT

stabilization delay (500 ms)

SPP_CLOSE_EVT / error

AUTH_FAIL / timeout

DISCONNECTED

CONNECTING

STABILIZING

CONNECTED

Key implementation details:

  • sendInitCommand() sent once after STABILIZING → CONNECTED transition
  • RX line-assembly buffer with 1 500 ms flush timeout (same as UART serial)
  • 5 000 ms throttle on init-command retries
  • pthread_mutex_t protection for TX queue, RX queue, RX buffer, and connection state

Files: main/modules/bt_ble/
See Communication Transports for full transport details.

  • Implements GATTC (client) to connect to a CNC controller advertising a UART-over-BLE service
  • MTU negotiation (default 23 bytes, max 247 bytes for BTT modules)
  • Identical auto-reconnect pattern and init-command protocol to BT Serial

Files: main/modules/http/

ESP3DHttpService (global esp3dHttpService) is an ESP-IDF httpd-based server that serves the embedded WebUI, exposes the REST command interface, and hosts WebSocket upgrades for both UI and data channels.

PathMethod(s)Description
/GETRoot redirect to WebUI index
/commandGET / POSTESP3D command execution
/configGETJSON configuration export
/loginPOSTSession login (auth enabled)
/filesGET / POSTFlash filesystem browse & upload
/sdfilesGET / POSTSD card browse & upload
/updatefwPOSTOTA firmware / raw partition update
/description.xmlGETSSDP UPnP schema (SSDP enabled)
/favicon.icoGETBrowser favicon
/wsWS UpgradeWebSocket — WebUI channel
/wsdataWS UpgradeWebSocket — binary data channel
/webdav/*DAV verbsWebDAV file access (WebDAV enabled)
/snapGETCamera snapshot (camera enabled)

Multi-part uploads are routed through PostUploadContext structs — one per upload destination — allowing each destination to supply its own writer and completion handler:

struct PostUploadContext {
esp_err_t (*writeFn)(const uint8_t *data, size_t datasize,
ESP3DUploadState state, const char *filename,
size_t filesize);
esp_err_t (*nextHandler)(httpd_req_t *req);
uint packetReadSize;
uint packetWriteSize;
std::list<std::pair<std::string, std::string>> args;
};

Upload destinations: flash filesystem, SD card, OTA firmware, raw partition (ui_resources, etc.).

When PSRAM is available, ESP3DWebUiPsramCache pre-loads WebUI files from flash into PSRAM for faster HTTP serving. A .gz compressed variant is preferred over the plain file when both exist. Since a14 it is mutex-protected, rebuilt before httpd_start(), and single entries can be dropped with invalidate(path); see http_service.md.

yes

no

HTTP GET /index.html

Cache hit

in PSRAM?

Serve directly

from PSRAM

Stream from

flash filesystem

The cache is rebuilt on service start and after flash writes (uploads, WebDAV); invalidate() drops one stale entry (WebSocket upload, preferences.json).


Files: main/modules/websocket_server/

Two WebSocket services are registered as handlers on the HTTP server, differentiated by path.

Inherits ESP3DWsService. Handles the real-time command/status channel consumed by the embedded browser interface:

  • Pushes JSON notifications to connected WebUI clients via pushNotification()
  • Processes text-format ESP3D commands from browser → CNC pipeline
  • Validates authentication sessions on WebSocket open

ESP3DWsDataService — Binary Data Channel (/wsdata)

Section titled “ESP3DWsDataService — Binary Data Channel (/wsdata)”

Inherits ESP3DWsService. Implements the V1 binary wire protocol for file transfers:

ESP3DWsDataServiceWS ClientESP3DWsDataServiceWS Clientloop[per packet]loop[per packet]STATUS_REQUEST (binary frame)Status frameUPLOAD_START + filename + sizeUPLOAD_PACKET_ACK (packet_id)UPLOAD_PACKET (payload)UPLOAD_ENDUPLOAD_ACKDOWNLOAD_START + pathDOWNLOAD_PACKET (payload)DOWNLOAD_PACKET_ACKDOWNLOAD_ENDDOWNLOAD_END_ACK

Each connected client is tracked by ESP3DWebSocketInfos:

struct ESP3DWebSocketInfos {
int socket_id;
struct sockaddr_storage source_addr;
char *buffer;
uint buf_position;
char session_id[25]; // populated when ESP3D_AUTHENTICATION_FEATURE is ON
};

For the full binary protocol specification, see docs/architecture/websockets_protocol.md.


File: main/modules/mdns/esp3d_mdns.h

Registers the pendant on the local network under its configured hostname and announces all active services as mDNS TXT records. Also provides a scan API used by the server_scan_screen to discover nearby ESP3D devices.

Local NetworkESP3DmDNSESP3DNetworkServicesLocal NetworkESP3DmDNSESP3DNetworkServicesloop[handle() each cycle]begin() [deferred ~500 ms after IP]mdns_init()registerDeviceInfoService()registerAnnouncedServices()Announce _http._tcp, _esp3d._tcp, _device-info._tcprefreshAnnouncements() [if needed]

Key methods:

MethodDescription
begin()Initialises mDNS and registers all services
refreshAnnouncements()Re-registers after a service restart
servicesScan(service, proto)Scans for _esp3d._tcp peers
getRecord(pos)Returns one scan result by index
freeServiceScan()Releases scan result memory

For the full TXT record reference, see docs/features/mdns.md.

Files: main/modules/ssdp/esp3d_ssdp.h, components/SSDP_IDF/

Implements UPnP Simple Service Discovery Protocol. Responds to M-SEARCH multicast UDP packets on 239.255.255.255:1900 and serves the device description XML via the HTTP /description.xml endpoint.

The SSDP task is configured via ssdp_config_t with fields for UPnP UUID, friendly name, model, manufacturer, presentation URL, and service descriptions.

⚠️ Build constraint: SSDP_SERVICE is forbidden when SOCKET_CLIENT_SERVICE is ON. See cmake/sanity_check.cmake and docs/features/feature_resource_matrix.md.


Files: main/modules/authentication/

ESP3DAuthenticationService manages session-based authentication across all connected clients (HTTP, WebSocket, socket server).

struct ESP3DAuthenticationRecord {
ESP3DAuthenticationLevel level; // guest | user | admin
int socket_id;
ESP3DClientType client_type; // http | ws_webui | ws_data | socket_server
char session_id[25];
int64_t last_time; // last activity timestamp (ms)
};

admin pwd

user pwd

wrong

Client connects

create_session_id

(source_addr + socket_id)

createRecord

level = guest

Login POST

with password

updateRecord

level = admin

updateRecord

level = user

Return 403 / not authenticated

Periodic handle()

purgeExpiredSessions

based on session_timeout setting

Client disconnects

clearSession

(socket_id + client_type)

Sessions are protected by pthread_mutex_t _sessions_mutex because the list is accessed concurrently from httpd worker threads, the socket server task, the WebSocket service, and handle().

For detailed authentication flows, see docs/architecture/authentication_lifecycle.md.


File: main/modules/time/esp3d_time_service.h

TimeService (global esp3dTimeService) configures lwIP SNTP synchronisation and manages the device clock. Supports up to CONFIG_LWIP_SNTP_MAX_SERVERS NTP servers and a configurable POSIX timezone string.

lwIP SNTPTimeServiceESP3DNetworkServiceslwIP SNTPTimeServiceESP3DNetworkServicesloop[handle()periodically-]begin()updateTimeZone(fromsettings=true)esp_sntp_init() + server listtime synced (async callback)getCurrentTime()

File: main/modules/notifications/esp3d_notifications_service.h

ESP3DNotificationsService abstracts multiple push-notification back-ends behind a single sendMSG(title, message) interface. The active provider is selected from settings during begin().

Provider classChannel
TelegramProviderTelegram Bot API
EmailNotificationProviderSMTP email
IFTTTProviderIFTTT Webhooks
PushoverProviderPushover
HomeAssistantProviderHome Assistant REST
WhatsAppProviderWhatsApp Business API

Auto-notification on connect is controlled by _autonotification flag, settable via HTTP command handler.

For architecture details, see docs/architecture/notifications_system.md.


These transports are started by ESP3DNetworkServices when the pendant is configured to reach the CNC controller over WiFi. Only one can be active at a time.

File: main/modules/socket_client/esp3d_socket_client.h
See Communication Transports for full details. Also see docs/architecture/socket_client.md.

no

yes

yes

no

yes

no

begin

Spawn RX task

Connected?

connectToServer()

non-blocking

5 s retry backoff

sendInitCommand()

$I + newline

readSocket loop

Data received?

pushMsgToRxQueue

Idle > ping

interval?

Send ? ping

Notable features:

  • Self-healing retry loop inside the RX task (no external supervision needed)
  • stopAutoConnect() prevents reconnect when WiFi SSID/password changes
  • Backoff counter for consecutive ECONNRESET errors to give Telnet server time to clear stale sessions
  • _requires_explicit_connect flag gating auto-start

WebSocket CNC Client — ESP3DWebsocketClient

Section titled “WebSocket CNC Client — ESP3DWebsocketClient”

File: main/modules/websocket_client/esp3d_websocket_client.h
See Communication Transports for full details.

  • Connects to a WebSocket endpoint on the CNC controller (configurable host, port, path)
  • Uses the esp_websocket_client IDF component with configurable subprotocol
  • Internal _chunk_queue bridges the IDF event callback to the RX task safely
  • Shares the same init-command ($I\n) and inactivity ping patterns as the socket client
  • stopAutoConnect() / _requires_explicit_connect flag mirrors the socket client API

⚠️ Build constraint: WS_CLIENT_SERVICE and SOCKET_CLIENT_SERVICE cannot coexist with WEBUI_SERVER, WS_SERVER_SERVICE, or SSDP_SERVICE. See cmake/sanity_check.cmake.


CNC ControllerActive Transport\n(Serial / BT / Socket / WS)GCodeHostService\n(Core 0)ESP3DCommandsUI Screen\n(LVGL · Core 1)CNC ControllerActive Transport\n(Serial / BT / Socket / WS)GCodeHostService\n(Core 0)ESP3DCommandsUI Screen\n(LVGL · Core 1)dispatchCommand(gcode)enqueue (normal / high priority)process(ESP3DMessage)raw bytes over transportresponse linepushMsgToRxQueue → dispatchResponseupdate ESP3DValues\n(position, status, …)

For the full GCode host state machine and flow control details, see:

Individual ServicesESP3DNetworkServicesESP3DNetworknetworkTask (Core 0)ESP3DXNetworkmain.cpp / app_mainIndividual ServicesESP3DNetworkServicesESP3DNetworknetworkTask (Core 0)ESP3DXNetworkmain.cpp / app_mainWiFi STA connects, IP acquired~500 ms deferreddeferred if SOCKET/WS CLIENT featureloop[Every 10 ms]begin()esp3d_task_create_pinned (Core 0)Create xNetworkSemaphoreesp_netif_init + event_loop_createbegin()Read mode from NVSstartWifiStaMode() [or BT / AP …]begin()AUTH begin()HTTP begin()NTP begin()Notifications begin()mDNS begin()SSDP begin()SocketClient / WsClient begin()handle()handle()handle() each active service

CNC Integration

UI Layer (Core 1)

Network Module

Core Platform

reads mode / SSID / credentials

writes connection_status

notifies

setModeAsync()

setModeAsync()

ESP3DMessage

transport

parsed responses

writes positions / status

ESP3DSettings

NVS

ESP3DValues

Observable

ESP3DCommands

Dispatcher

ESP3DNetwork

ESP3DNetworkServices

UIManager

Screens

WiFi / BT / Server

Scan Screens

Settings Screen

GCodeHostService

GCodeHandlerService

FluidNC / grbl / grblHAL


The network module is entirely feature-gated. Options are set in CMakeLists.txt and validated in cmake/sanity_check.cmake.

CMake OptionGuard MacroEffect
WIFI_FEATUREESP3D_WIFI_FEATUREWiFi, HTTP, WebSocket server, mDNS, SSDP
BT_SERIAL_FEATUREESP3D_BT_SERIAL_FEATUREBluetooth Classic SPP transport
BT_BLE_FEATUREESP3D_BT_BLE_FEATUREBluetooth BLE (GATT) transport
SOCKET_CLIENT_SERVICEESP3D_SOCKET_CLIENT_FEATURETCP socket CNC transport
WS_CLIENT_SERVICEESP3D_WS_CLIENT_SERVICE_FEATUREWebSocket CNC transport
WEBUI_SERVERESP3D_WEBUI_SERVER_FEATUREEmbedded WebUI WebSocket channel
WS_SERVER_SERVICEESP3D_WS_SERVER_SERVICE_FEATUREBinary data WebSocket channel
SSDP_SERVICEESP3D_SSDP_FEATURESSDP / UPnP discovery
MDNS_FEATUREESP3D_MDNS_FEATUREmDNS / Bonjour
AUTHENTICATION_FEATUREESP3D_AUTHENTICATION_FEATURESession-based auth
HTTPS_FEATUREESP3D_HTTPS_FEATURETLS / HTTPS (requires cert + key)
NOTIFICATIONS_FEATUREESP3D_NOTIFICATIONS_FEATUREPush notifications
ScenarioSOCKET_CLIENTWEBUI_SERVERSSDPWS_SERVER
Serial / USB CNC + WiFi Remote (default)OFF✅ ON✅ ON✅ ON
WiFi CNC only (socket client)✅ ON❌ OFF❌ OFF❌ OFF
Bluetooth CNCOFFOFFOFFOFF

🔴 sanity_check.cmake aborts the build if forbidden combinations are detected.
Full compatibility table: docs/features/feature_resource_matrix.md.

WiFi requires approximately ~200 KB DRAM at runtime, leaving very little for the rest of the system:

ConfigurationAvailable Heap (approx.)
WiFi active (STA + services)~75 KB
Bluetooth active~10 KB
WiFi + HTTP + WebSocket + mDNS< 50 KB

Always verify esp_get_minimum_free_heap_size() in the boot logs after enabling new services.
See docs/guides/esp32_memory_constraints.md for the full fragmentation playbook, especially the Serial CNC + WiFi remote — fragmentation playbook subsection.


DocumentDescription
Communication TransportsSerial, USB serial, BT Serial, BT BLE, Socket, WebSocket transports
CNC Firmware IntegrationGCode host service, flow control, firmware-specific parsers
Core Platform & InfrastructureESP3DValues, ESP3DSettings, ESP3DCommands
UI Framework & ScreensUIManager, screen transitions, WiFi/BT/server scan screens
docs/architecture/connection_management.mdConnection lifecycle and shared init sequence across transports
docs/architecture/websockets_protocol.mdWebSocket V1 binary protocol reference
docs/architecture/authentication_lifecycle.mdSession auth detailed lifecycle
docs/architecture/notifications_system.mdNotifications service architecture
docs/architecture/socket_client.mdTCP socket client implementation details
docs/features/feature_resource_matrix.mdFeature compatibility, WiFi/BT/CNC usage model, net “tickets”
docs/features/mdns.mdmDNS registered services and _device-info._tcp TXT record reference
docs/guides/esp32_memory_constraints.mdHeap, fragmentation, WiFi vs BT RAM budgets
docs/guides/https_tls_setup.mdTLS certificate setup for HTTPS
docs/guides/tools.mdWebSocket test client, serial bridge, BT client tools