ESP32 IoT SmartConfig Wi-Fi provisioning library

The great strength of the ESP32 from Espressif is the integrated Wi-Fi module. This makes the microcontroller perfect for IoT projects because no additional hardware is needed for connectivity. With just a few lines of code, the ESP32 can be integrated into a network. Of course, the prerequisite is that the microcontroller knows both the SSID and the Wi-Fi password. But how does it get this data?

With devices such as notebooks or smartphones, you simply enter the access data via a keyboard. For so-called headless devices, i.e. devices without an input option, a different method is needed. The process of bringing a headless device into a Wi-Fi network is generally called provisioning, whereby a distinction is made between in-band provisioning and out-of-band provisioning. With in-band provisioning, only the Wi-Fi radio network is used to send the network information to the unprovisioned device. This has the advantage that no additional interfaces or hardware are required. In contrast, out-of-band provisioning uses a different channel. Here, the transmission is either wired or wireless via another radio network. Although this increases flexibility, it also makes provisioning more complex.

The following list provides a brief overview of some methods widely used in the market:

In-band Provisioning

  • Wi-Fi protected setup (WPS): Standard developed by the Wi-Fi Alliance to easily set up a wireless local area network with encryption. The goal of WPS was to simplify adding devices to an existing network. It is considered insecure and should no longer be used.
  • Access point mode: The non-provisioned device first identifies itself as an access point with a predefined SSID. A client can thus connect to the headless device, which provides a page for configuration via an embedded web server. After the configuration is complete, the device can connect to the specified Wi-Fi network.
  • SmartConfig: A method developed by Texas Instruments to connect a new device to a Wi-Fi network. The network access data is transmitted from a client to the unprovisioned device via a special protocol.

 Out-of-band Provisioning

  • USB Interface: The access data is transferred via the USB interface, for example via a USB stick. Of course, this assumes that the device has a free and accessible USB port.
  • NFC: The Near Field Communication transmission standard is used to transmit the access data. Since the ESP32 does not support this standard, this is only possible with additional hardware.
  • Bluetooth: Transmission is done via the Bluetooth standard.

In addition to these methods, there are numerous other ways to send the necessary access data to a Wi-Fi-capable device. For example, light signals or sounds can also be used as a transmission medium. With the WPA3 security standard, the Wi-Fi Alliance has introduced a new protocol called Wi-Fi Easy Connect, also called Device Provisioning Protocol (DPP). This allows devices to be integrated into the network via QR codes or NFC tags.

The Espressif SDK supports SmartConfig, SoftAP, Bluetooth and Easy Connect out of the box. For my projects, I use SmartConfig because I like the idea and the provisioning via smartphone is very convenient.

SmartConfig

So how does SmartConfig work? First you have to understand the actual problem. A device in the encrypted Wi-Fi network wants to communicate the SSID and password to another device. However, since the communication is only encrypted, the new device cannot understand the messages. But even if the new device cannot decrypt the messages sent, there is some information that is visible to the new device. This includes the MAC address of the sender and receiver, as well as the type of a data packet. This way, all packets that are not of a certain type can be ignored. The most important visible information is the length of the data packets. Although the length changes due to the encryption, it is the same for all packets.

This is exactly the secret of SmartConfig. Instead of sending the data directly, the characters are encoded by the length of data packets. The content does not matter, as it cannot be read by the new device anyway. The sending device sends this data via UDP into the network until the new device has filtered out the relevant packets and can register in the Wi-Fi. It then sends a success message to the sender, which completes the SmartConfig process.

ESP SmartConfig Library 

The library for the ESP32 is essentially based on the code example from Espressif. However, since the code only contains the pure connection setup via SmartConfig, I have extended the example to include saving the login data in the Non-volatile storage (NVS) and the normal connection setup after provisioning. The following diagram shows an overview of the process:

Init NVS & WiFi
Init NVS & WiFi
No
No
Yes
Yes
WiFi
connected?
WiFi...
Stop SmartConfig
Stop SmartConfig
Register Event Handler
Register Event Handl...
OK
OK
Start SmartConfig
Start SmartConfig
Connect to WiFi
Connect to WiFi
Store data in NVS
Store data in NVS
Wait for Data
Wait for Data
Connect to WiFi
Connect to WiFi
Yes
Yes
No
No
WiFi
connected?
WiFi...
Failed
Failed
OK
OK
Load settings from NVS
Load settings from N...
Text is not SVG - cannot display

The SmartConfig implementation of Espressif offers several protocols. I use ESPTouch v2. This protocol makes it possible to transmit reserved data in addition to SSID and password. This means that the time zone is also transmitted in addition to the connection data. This makes it possible to set the current time of the ESP32 with the configuration of an NTP server and to keep it up to date via SNTP time synchronisation. The time zone is also stored in the NVS, which means that the time is set correctly again when the ESP32 is restarted.

The usage of the component is very simple:

void app_main(){

    esp_err_t ret;

    static wifi_conf_t wifi_conf = {
        .aes_key = "ESP32EXAMPLECODE",
        .hostname = "ESP32",
        .ntp_server = "pool.ntp.org",
    };

    wifi_t *smartconfig = wifi_new_smartconfig(&wifi_conf);
  
    if (smartconfig->init(smartconfig) == ESP_OK) {

        do {
            ret = smartconfig->connect(smartconfig);
        }
        while (ret != ESP_OK);

        smartconfig->init_sntp(smartconfig); 
        smartconfig->init_timezone(smartconfig);
    }
}


But how is the data sent to the ESP32? Espressif also offers a solution for this in the form of smartphone apps. The source code for Android and iOS is available on GitHub. The following two screenshots show how easy it is to connect the ESP32 to a Wi-Fi network:

ESP32 SmartConfig App Provisioning   ESP32 SmartConfig App Finished


Finally, a few words about the security of this solution. Of course, the access data must not simply be sent in plain text, as otherwise a third person could potentially intercept the data. For this reason, the transmitted data is secured with the AES encryption method. Only the sender and the recipient are allowed to know the necessary AES key. With a commercial product, it is therefore essential to ensure that the key cannot be read out of the ESP32. Secure Boot V2 is suitable for this purpose, with which the ESP32 can be secured against external access. This YouTube video shows very impressively how difficult this protection is.

The complete source code of the ESP32 component is available on GitHub. I would be very happy to receive feedback or suggestions for improvement.

Loading Conversation