libwebsockets
Lightweight C library for HTML5 websockets
Loading...
Searching...
No Matches
ESP32 Support

See Building for ESP32 for details on how to build lws as a component in an ESP-IDF project.

Lws provides a "factory" application

https://github.com/warmcat/lws-esp32-factory

and a test application which implements the generic lws server test apps

https://github.com/warmcat/lws-esp32-test-server-demos

The behaviours of the generic factory are are quite rich, and cover uploading SSL certs through factory and user configuration, AP selection and passphrase entry, and managing a switch to allow the user to force entry to user setup mode at boot subsequently.

The factory app comes with partitioning for a 1MB factory partition containing that app and data, and a single 2.9MB OTA partition containing the main app.

The factory app is able to do OTA updates for both the factory and OTA partition slots; updating the factory slot first writes the new image to the OTA slot and copies it into place at the next boot, after which the user can reload the OTA slot.

State Image AP SSID Port URL Mode
Factory Reset or Uninitialized Factory AP: ESP_012345 80 http://192.168.4.1 factory.html - to set certificates and serial
User configuration Factory AP: config-model-serial 443 https://192.168.4.1 index.html - user set up his AP information
Operation OTA Station only 443 https://model-serial.local OTA application

Basic Auth

The lws-esp32-test-server-demos app also demos basic auth.

On a normal platform this is done by binding a mount to a text file somewhere in the filesystem, which contains user:password information one per line.

On ESP32 there is not necessarily any generic VFS in use. So instead, the basic auth lookup is bound to a given nvs domain, where the username is the key and the password the value. main/main.c in the test demos app shows how to both make the mount use basic auth, and how to set a user:password combination using nvs.

Certificate generation

lws_x509_create_cert() and lws_x509_create_self_signed() use the mbedtls x509 writer, which ESP-IDF leaves out of its mbedtls by default. If your application generates certificates on the device, enable Component config -> mbedTLS -> Certificates -> X.509 certificate creation (CONFIG_MBEDTLS_X509_CREATE_C) in menuconfig. Without it lws still builds, and those calls fail with an error log saying MBEDTLS_X509_CRT_WRITE_C is missing.

IPv6

lws builds with LWS_WITH_IPV6 by default, but on ESP32 lwIP must also have it enabled for the lws netdev wifi driver to bring IPv6 up. Set, in menuconfig under Component config -> LWIP,

  • CONFIG_LWIP_IPV6, to have IPv6 in lwIP at all, and
  • CONFIG_LWIP_IPV6_AUTOCONFIG, so lwIP can get global addresses from router advertisements by SLAAC.

The minimal examples' sdkconfigs set both. Each time it associates, the driver starts the link-local address, and as global addresses are acquired or go away, it adds or removes an IPv6 default route for each one in the lws routing table. Each new one is also announced by an SMD NETWORK message like {"type":"ipacq","if":"wl0","ipv6":"2001:db8::1"}, the same as the IPv4 one with "ipv4".

Without CONFIG_LWIP_IPV6_AUTOCONFIG, the device only gets a link-local IPv6 address, so lws has no IPv6 route and uses IPv4 alone.

Optimization

ESP-IDF only builds its own components with the optimization level chosen in the sdkconfig (CONFIG_COMPILER_OPTIMIZATION_*, idf.py menuconfig under Compiler options), and with -ffunction-sections -fdata-sections, so the link can drop functions nothing calls. lws is added to the project with add_subdirectory() rather than as a component, so lws applies the same level and section flags to itself.

The esp32 examples choose "Optimize for size" (-Os), since flash for two OTA slots is tight on 4MB parts. For debugging, "Debug" (-Og) builds larger.