WiFi Service

Overview

The WiFi Service provides comprehensive WiFi connectivity for the ESP32, supporting three operation modes: Station (STA), Access Point (AP), and simultaneous AP+STA. It uses the Zephyr network management API and ESP32 WiFi driver.

Architecture

Class Design

class WiFiService {
public:
    enum class Mode {
        STA,      // Station mode - connect to existing WiFi
        AP,       // Access Point mode - create WiFi hotspot
        AP_STA    // Both modes simultaneously
    };

    static WiFiService& getInstance();

    int init(Mode mode = Mode::STA);
    int start();
    int stop();

    // Station mode operations
    int connect(const char* ssid, const char* password);
    int disconnect();
    int scan(ScanResultCallback callback);

    // Access Point mode operations
    int startAP(const char* ssid, const char* password);
    int stopAP();

    bool isConnected() const;
    Mode getMode() const;

    void setConnectionCallback(ConnectionCallback cb);
    void setScanResultCallback(ScanResultCallback cb);

private:
    WiFiService();
    ~WiFiService();
};

Operation Modes

Station Mode (STA)

Connect to an existing WiFi network as a client.

Use Cases:

  • Internet connectivity

  • Cloud communication

  • OTA updates

  • Network time synchronization

Configuration:

WiFiService& wifi = WiFiService::getInstance();
wifi.init(WiFiService::Mode::STA);
wifi.connect("MyWiFi", "password123");

Access Point Mode (AP)

Create a WiFi hotspot for other devices to connect.

Use Cases:

  • Device provisioning

  • Local configuration

  • Direct device-to-device communication

  • Captive portal for setup

Configuration:

WiFiService& wifi = WiFiService::getInstance();
wifi.init(WiFiService::Mode::AP);
wifi.startAP("ESP32_SmartHome_AP", "12345678");

AP+STA Mode

Operate as both access point and station simultaneously.

Use Cases:

  • WiFi range extender

  • Gateway applications

  • Configuration while maintaining internet

  • Mesh networking

Configuration:

WiFiService& wifi = WiFiService::getInstance();
wifi.init(WiFiService::Mode::AP_STA);

// Start AP for local connections
wifi.startAP("ESP32_Config", "setup123");

// Connect to internet
wifi.connect("HomeWiFi", "password");

Station Mode Operations

Network Scanning

Scan for available WiFi networks:

static void scan_result_callback(wifi_scan_result* result) {
    LOG_INF("SSID: %s, RSSI: %d, Channel: %d",
            result->ssid, result->rssi, result->channel);
}

WiFiService& wifi = WiFiService::getInstance();
wifi.setScanResultCallback(scan_result_callback);
wifi.scan(scan_result_callback);

Connecting to Network

static void connection_callback(bool connected) {
    if (connected) {
        LOG_INF("WiFi connected");
        // Get IP address, start services, etc.
    } else {
        LOG_WRN("WiFi disconnected");
        // Attempt reconnection
    }
}

WiFiService& wifi = WiFiService::getInstance();
wifi.setConnectionCallback(connection_callback);

int ret = wifi.connect("MySSID", "MyPassword");
if (ret != 0) {
    LOG_ERR("Connection failed: %d", ret);
}

Disconnecting

WiFiService& wifi = WiFiService::getInstance();
wifi.disconnect();

Access Point Operations

Starting AP

WiFiService& wifi = WiFiService::getInstance();

// Start AP with custom SSID and password
int ret = wifi.startAP("ESP32_IoT_Device", "SecurePass123");
if (ret == 0) {
    LOG_INF("AP started successfully");
    // AP is now active on channel 6
}

Default AP Configuration

static constexpr const char* DEFAULT_SSID = "ESP32_SmartHome_AP";
static constexpr const char* DEFAULT_PASSWORD = "12345678";
static constexpr uint8_t DEFAULT_CHANNEL = 6;

AP Parameters:

  • Security: WPA2-PSK (if password provided), Open (no password)

  • Channel: 6 (2.4GHz)

  • Band: 2.4 GHz

  • Max Clients: Depends on CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM

Stopping AP

WiFiService& wifi = WiFiService::getInstance();
wifi.stopAP();

Network Management

Event Handling

The WiFi service handles the following network events:

Event

Description

NET_EVENT_WIFI_SCAN_RESULT

WiFi scan found a network

NET_EVENT_WIFI_SCAN_DONE

WiFi scan completed

NET_EVENT_WIFI_CONNECT_RESULT

Connection attempt completed

NET_EVENT_WIFI_DISCONNECT_RESULT

Disconnection occurred

NET_EVENT_IPV4_ADDR_ADD

IP address assigned

NET_EVENT_IPV4_ADDR_DEL

IP address removed

DHCP Client

Automatic IP address assignment is enabled in STA mode:

CONFIG_ESP32_WIFI_STA_AUTO_DHCPV4=y
CONFIG_NET_DHCPV4=y

API Reference

Initialization

int WiFiService::init(Mode mode)

Initialize WiFi service with specified operation mode.

Parameters:

mode – Operation mode (STA, AP, or AP_STA)

Returns:

0 on success, negative error code on failure

int WiFiService::start()

Start WiFi operation based on configured mode.

Returns:

0 on success, negative error code on failure

int WiFiService::stop()

Stop WiFi operation and disconnect.

Returns:

0 on success, negative error code on failure

Station Mode

int WiFiService::connect(const char *ssid, const char *password)

Connect to a WiFi network.

Parameters:
  • ssid – Network SSID (max 32 bytes)

  • password – Network password (max 64 bytes)

Returns:

0 on success, negative error code on failure

Return values:
  • -EINVAL – Invalid SSID or password

  • -ENODEV – No network interface

  • -EALREADY – Already connected

int WiFiService::disconnect()

Disconnect from current WiFi network.

Returns:

0 on success, negative error code on failure

int WiFiService::scan(ScanResultCallback callback)

Scan for available WiFi networks.

Parameters:

callback – Function called for each network found

Returns:

0 on success, negative error code on failure

Access Point Mode

int WiFiService::startAP(const char *ssid, const char *password)

Start WiFi Access Point.

Parameters:
  • ssid – AP SSID (max 32 bytes)

  • password – AP password (min 8 bytes for WPA2, empty for open)

Returns:

0 on success, negative error code on failure

Return values:
  • -ENOTSUP – AP mode not supported in configuration

  • -ENODEV – No network interface

int WiFiService::stopAP()

Stop WiFi Access Point.

Returns:

0 on success, negative error code on failure

Status Query

bool WiFiService::isConnected() const

Check if connected to a WiFi network (STA mode).

Returns:

true if connected, false otherwise

Mode WiFiService::getMode() const

Get current operation mode.

Returns:

Current WiFi mode (STA, AP, or AP_STA)

Configuration

Required Kconfig

Basic WiFi configuration in prj.conf:

# WiFi driver
CONFIG_WIFI=y
CONFIG_WIFI_ESP32=y
CONFIG_ESP32_WIFI_STA_AUTO_DHCPV4=y

# Network management
CONFIG_NET_L2_WIFI_MGMT=y
CONFIG_NET_MGMT=y
CONFIG_NET_MGMT_EVENT=y
CONFIG_NET_MGMT_EVENT_INFO=y
CONFIG_NET_MGMT_EVENT_STACK_SIZE=2048

# AP+STA mode support
CONFIG_WIFI_NM=y
CONFIG_ESP32_WIFI_AP_STA_MODE=y

# Networking
CONFIG_NETWORKING=y
CONFIG_NET_IPV4=y
CONFIG_NET_DHCPV4=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_CONNECTION_MANAGER=y

# Network buffers
CONFIG_NET_PKT_RX_COUNT=10
CONFIG_NET_PKT_TX_COUNT=10
CONFIG_NET_BUF_RX_COUNT=10
CONFIG_NET_BUF_TX_COUNT=10

Device Tree

For AP+STA mode, a second WiFi device node is required:

File: boards/esp32_devkitc.overlay

/ {
    wifi_ap: wifi_ap {
        compatible = "espressif,esp32-wifi";
        status = "okay";
    };
};

Usage Examples

Station Mode Example

#include "modules/wifi/wifiservice.hpp"

static void wifi_connected(bool connected) {
    if (connected) {
        LOG_INF("Connected to WiFi");
        // Start cloud services
    } else {
        LOG_WRN("WiFi disconnected");
        // Reconnect logic
    }
}

void wifi_task_entry(void) {
    WiFiService& wifi = WiFiService::getInstance();

    // Initialize in STA mode
    wifi.init(WiFiService::Mode::STA);
    wifi.setConnectionCallback(wifi_connected);

    // Connect to network
    wifi.connect("HomeNetwork", "password123");

    while (1) {
        k_sleep(K_FOREVER);
    }
}

AP Mode Example

void setup_ap_mode(void) {
    WiFiService& wifi = WiFiService::getInstance();

    // Initialize in AP mode
    wifi.init(WiFiService::Mode::AP);

    // Start AP for device configuration
    int ret = wifi.startAP("ESP32_Setup", "Config123");
    if (ret == 0) {
        LOG_INF("Configuration AP started");
        LOG_INF("Connect to 'ESP32_Setup' with password 'Config123'");

        // Start web server for configuration
        // start_config_server();
    }
}

AP+STA Mode Example

void dual_mode_setup(void) {
    WiFiService& wifi = WiFiService::getInstance();

    // Initialize in AP+STA mode
    wifi.init(WiFiService::Mode::AP_STA);

    // Start AP for local access
    wifi.startAP("ESP32_Local", "local123");

    // Connect to internet
    wifi.connect("InternetRouter", "router_pass");

    // Now device is accessible locally via AP
    // and has internet via STA connection
}

Network Scanning Example

static void handle_scan_result(wifi_scan_result* result) {
    printf("Found: %-32s | RSSI: %4d | Ch: %2d | Sec: %d\n",
           result->ssid,
           result->rssi,
           result->channel,
           result->security);
}

void scan_networks(void) {
    WiFiService& wifi = WiFiService::getInstance();
    wifi.init(WiFiService::Mode::STA);

    LOG_INF("Scanning for WiFi networks...");
    wifi.scan(handle_scan_result);
}

Troubleshooting

Connection Issues

Cannot connect to WiFi:

  • Verify SSID and password are correct

  • Check WiFi signal strength (RSSI)

  • Ensure security type matches (WPA2/WPA3)

  • Check if MAC address is filtered

  • Verify channel is supported (1-13 for 2.4GHz)

AP not visible:

  • Ensure AP mode is enabled in Kconfig

  • Check devicetree overlay is applied

  • Verify channel 6 is not congested

  • Check if other devices can create APs

DHCP timeout:

  • Increase DHCP timeout: CONFIG_NET_DHCPV4_INITIAL_DELAY_MAX

  • Check router DHCP server is working

  • Verify IP pool is not exhausted

Performance Issues

Slow throughput:

  • Check WiFi signal strength

  • Reduce distance to router

  • Change WiFi channel (less congestion)

  • Increase buffer counts in Kconfig

  • Use 5GHz if available (ESP32-S3/C3)

Frequent disconnections:

  • Improve signal strength

  • Increase connection timeout

  • Enable WiFi power saving mode

  • Check for interference sources

Memory Issues

Stack overflow in WiFi task:

  • Increase CONFIG_NET_MGMT_EVENT_STACK_SIZE

  • Reduce buffer counts if memory constrained

  • Check for memory leaks

Performance Optimization

Throughput

To maximize WiFi throughput:

  1. Increase Buffers:

    CONFIG_NET_PKT_RX_COUNT=20
    CONFIG_NET_PKT_TX_COUNT=20
    CONFIG_NET_BUF_RX_COUNT=20
    CONFIG_NET_BUF_TX_COUNT=20
    
  2. Use TCP Window Scaling

  3. Disable WiFi power saving in high-performance mode

  4. Use QoS priorities for time-sensitive data

Power Saving

To minimize power consumption:

  1. Enable WiFi Power Saving:

    CONFIG_ESP32_WIFI_STA_PS_ENABLED=y
    
  2. Use longer beacon intervals

  3. Implement sleep modes between transmissions

  4. Use AP mode only when needed

Source Code Reference

  • app/src/modules/wifi/wifiservice.hpp - WiFi service interface

  • app/src/modules/wifi/wifiservice.cpp - WiFi service implementation

  • app/src/thread/wifi_task.cpp - WiFi task orchestration

  • app/boards/esp32_devkitc.overlay - Device tree overlay for AP mode

See Also