WiFi usage of esp32 idf

ESP32’s WiFi has three modes, AP mode, STA mode and smart_config. In order to facilitate management, I integrated the initialization of these three modes into one file for later use.

Project directory

moqi@5d30a855738f:~/project/esp32-demo/project$ tree
├── CMakeLists.txt
├── components
│ └── hardware
│ ├── CMakeLists.txt
│ ├── component.mk
│ ├── inc
│ │ └── Wifi_Hardware.h
│ └── src
│ └── Wifi_Hardware.c
├── main
│ ├── CMakeLists.txt
│ ├── inc
│ │ └── main.h
│ └── src
│ └── main.c
└──readme.md

Project file content

components/hardware/inc/Wifi_Hardware.h

#ifndef __WIFI_HARDWARE_H__
#define __WIFI_HARDWARE_H__

#include <esp_mac.h>
#include <esp_wifi.h>
#include <esp_smartconfig.h>

typedef enum {<!-- -->
    Wifi_ConfigAirkissMode,
    Wifi_ConfigApMode,
    Wifi_ConfigStaMode,
}Wifi_ConfigMode;

void Wifi_Init(int Wifimode, esp_event_handler_t event_handler);

void Wifi_ConfigSoftap(char *SSID, char *PASS);
void Wifi_ConfigSta(char *SSID, char *PASS);
void Wifi_ConfigAirkiss(void);

#endif
/* __WIFI_HARDWARE_H__ */

components/hardware/src/Wifi_Hardware.c

#include <string.h>
#include "Wifi_Hardware.h"

static void Dev_GetMac(uint8_t *base_mac_addr)
{<!-- -->
    esp_err_t ret = ESP_OK;

    if ( base_mac_addr == NULL ) {<!-- -->
        return;
    }

    #ifdef CONFIG_BASE_MAC_STORED_EFUSE_BLK3
    //Get base MAC address from EFUSE BLK3
    ret = esp_read_mac(base_mac_addr, ESP_MAC_EFUSE_CUSTOM);
    if (ret != ESP_OK) {<!-- -->
        #ifdef CONFIG_BASE_MAC_STORED_EFUSE_BLK3_ERROR_ABORT
        abort();
        #else
        ESP_ERROR_CHECK(esp_read_mac(base_mac_addr, ESP_MAC_EFUSE_FACTORY));
        #endif//CONFIG_BASE_MAC_STORED_EFUSE_BLK3_ERROR_ABORT
    }
    #elif defined(CONFIG_BASE_MAC_STORED_OTHER_EXTERNAL_STORAGE)
    //Get base MAC address from other external storage, or set by software
    ret = external_storage_mac_get(base_mac_addr);
    if (ret != ESP_OK) {<!-- -->
        abort();
    }
    #else
    //Get base MAC address from EFUSE BLK0(default option)
    ret = esp_read_mac(base_mac_addr, ESP_MAC_EFUSE_FACTORY);
    if (ret != ESP_OK) {<!-- -->
        abort();
    }
    #endif
}

void Wifi_Init(int Wifimode, esp_event_handler_t event_handler)
{<!-- -->
    char hostname[16];
    uint8_t mac_addr[6] = {<!-- -->0};
    esp_netif_t *netif;
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();

    memset (hostname, 0, 16);
    Dev_GetMac(mac_addr);
    sprintf (hostname, "Moqi_%.2X%.2X%.2X",
             mac_addr[3], mac_addr[4], mac_addr[5]);

    switch(Wifimode)
    {<!-- -->
        case Wifi_ConfigApMode:
            ESP_ERROR_CHECK(esp_netif_init());
            ESP_ERROR_CHECK(esp_event_loop_create_default());
            esp_netif_create_default_wifi_ap();
            ESP_ERROR_CHECK(esp_wifi_init( & amp;cfg));
            ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
            ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
                                                            ESP_EVENT_ANY_ID,
                                                            event_handler,
                                                            NULL,
                                                            NULL));
            break;
        case Wifi_ConfigStaMode:
            ESP_ERROR_CHECK(esp_netif_init());
            ESP_ERROR_CHECK(esp_event_loop_create_default());
            netif = esp_netif_create_default_wifi_sta();
            esp_netif_set_hostname(netif, hostname);
            ESP_ERROR_CHECK(esp_wifi_init( & amp;cfg));
            ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
            ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
                                                            ESP_EVENT_ANY_ID,
                                                            event_handler,
                                                            NULL,
                                                            NULL));
            ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
                                                            IP_EVENT_STA_GOT_IP,
                                                            event_handler,
                                                            NULL,
                                                            NULL));
            ESP_ERROR_CHECK(esp_wifi_start());
            break;
        case Wifi_ConfigAirkissMode:
            ESP_ERROR_CHECK(esp_netif_init());
            ESP_ERROR_CHECK(esp_event_loop_create_default());
            netif = esp_netif_create_default_wifi_sta();
            esp_netif_set_hostname(netif, hostname);
            ESP_ERROR_CHECK(esp_wifi_init( & amp;cfg));
            ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, event_handler, NULL));
            ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, event_handler, NULL));
            ESP_ERROR_CHECK(esp_event_handler_register(SC_EVENT, ESP_EVENT_ANY_ID, event_handler, NULL));
            ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
            ESP_ERROR_CHECK(esp_wifi_start());
            break;
        default:
            break;
    }
}

  void Wifi_ConfigSoftap(char *SSID, char *PASS)
{<!-- -->
    wifi_config_t wifi_config = {<!-- -->
        .ap = {<!-- -->
            .channel = 1,
            .max_connection = 3,
            .authmode = WIFI_AUTH_WPA_WPA2_PSK},
    };
    uint8_t mac_addr[6] = {<!-- -->0};
    Dev_GetMac(mac_addr);
    if (strlen(SSID)==0)
    {<!-- -->
        sprintf (SSID, "ESP32_%.2X%.2X%.2X",
                 mac_addr[3], mac_addr[4], mac_addr[5]);
    }

    memset(wifi_config.ap.ssid, 0, 32);
    memcpy(wifi_config.ap.ssid, SSID, strlen(SSID));

    if (strlen(PASS) == 0)
    {<!-- -->
        wifi_config.ap.authmode = WIFI_AUTH_OPEN;
    }
    memset(wifi_config.ap.password, 0, 32);
    memcpy(wifi_config.ap.password, PASS, strlen(PASS));
    wifi_config.ap.ssid_len = strlen(SSID);

    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, & amp;wifi_config));
    ESP_ERROR_CHECK(esp_wifi_start());
}

  void Wifi_ConfigSta(char *SSID, char *PASS)
{<!-- -->
    wifi_config_t wifi_config = {<!-- -->
        .sta = {<!-- -->
            .threshold.authmode = WIFI_AUTH_WPA2_PSK,

            .pmf_cfg = {<!-- -->
                .capable = true,
                .required = false},
        },
    };

    memset(wifi_config.sta.ssid, 0, 32);
    memcpy(wifi_config.sta.ssid, SSID, strlen(SSID));
    memset(wifi_config.sta.password, 0, 32);
    memcpy(wifi_config.sta.password, PASS, strlen(PASS));

    ESP_ERROR_CHECK(esp_wifi_disconnect());
    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, & amp;wifi_config));
    esp_wifi_connect();
}

  void Wifi_ConfigAirkiss(void)
{<!-- -->
    ESP_ERROR_CHECK(esp_smartconfig_set_type(SC_TYPE_AIRKISS));
    smartconfig_start_config_t cfg = SMARTCONFIG_START_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_smartconfig_start( & amp;cfg));
}

components/hardware/CMakeLists.txt

idf_build_get_property(idf_target IDF_TARGET)

set(board_srcs "src/Wifi_Hardware.c")

idf_component_register(SRCS "${board_srcs}"
                       PRIV_REQUIRES esp_wifi
                       INCLUDE_DIRS "./inc")

components/hardware/component.mk

#
#Component Makefile
#

COMPONENT_ADD_INCLUDEDIRS + = inc
COMPONENT_SRCDIRS + = src
main/CMakeLists.txt
set(board_srcs "src/main.c")

idf_component_register(SRCS "${board_srcs}"
                       INCLUDE_DIRS "./inc")

Main file code content

The contents of main.c in different modes are different and need to be set separately.

AP mode

#include <stdio.h>
#include <stdio.h>
#include <string.h>

#include <esp_log.h>
#include <esp_event.h>

#include <nvs_flash.h>

#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/event_groups.h>
#include "Wifi_Hardware.h"

#include "main.h"

#define TAG "main"

#defineWIFI_IP_LENGTH 16

static void wifi_event_handler(void *arg, esp_event_base_t event_base,
                               int32_t event_id, void *event_data);

char StaIP[WIFI_IP_LENGTH];

void app_main(void)
{<!-- -->
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {<!-- -->
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);

    memset (StaIP, 0, WIFI_IP_LENGTH);
    Wifi_Init(Wifi_ConfigApMode, & amp;wifi_event_handler);
    Wifi_ConfigSoftap("ap123", "12345678");
}

static void wifi_event_handler(void *arg, esp_event_base_t event_base,
                               int32_t event_id, void *event_data)
{<!-- -->
    if (event_id == WIFI_EVENT_AP_STACONNECTED) {<!-- -->
        wifi_event_ap_staconnected_t *event = (wifi_event_ap_staconnected_t *)event_data;
        ESP_LOGI(TAG, "station " MACSTR " join, AID=%d",
                 MAC2STR(event->mac), event->aid);
    } else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) {<!-- -->
        wifi_event_ap_stadisconnected_t *event = (wifi_event_ap_stadisconnected_t *)event_data;
        ESP_LOGI(TAG, "station " MACSTR " leave, AID=%d",
                 MAC2STR(event->mac), event->aid);
    } else if (event_base == WIFI_EVENT & amp; & amp; event_id == WIFI_EVENT_STA_START) {<!-- -->
        esp_wifi_connect();
    } else if (event_base == WIFI_EVENT & amp; & amp; event_id == WIFI_EVENT_STA_DISCONNECTED) {<!-- -->
        esp_wifi_connect();
        ESP_LOGI(TAG, "connect to the AP fail");
    } else if (event_base == IP_EVENT & amp; & amp; event_id == IP_EVENT_STA_GOT_IP) {<!-- -->
        ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
        memset(StaIP, 0, WIFI_IP_LENGTH);
        sprintf(StaIP, IPSTR, IP2STR( & amp;event->ip_info.ip));
        ESP_LOGI(TAG, "got StaIP: %s", StaIP);
    } else if (event_base == SC_EVENT & amp; & amp; event_id == SC_EVENT_SCAN_DONE) {<!-- -->
        ESP_LOGI(TAG, "Scan done");
    } else if (event_base == SC_EVENT & amp; & amp; event_id == SC_EVENT_FOUND_CHANNEL) {<!-- -->
        ESP_LOGI(TAG, "Found channel");
    } else if (event_base == SC_EVENT & amp; & amp; event_id == SC_EVENT_GOT_SSID_PSWD) {<!-- -->
        ESP_LOGI(TAG, "Got SSID and password");
    } else if (event_base == SC_EVENT & amp; & amp; event_id == SC_EVENT_SEND_ACK_DONE) {<!-- -->
        ESP_LOGI(TAG, "esptouch done");
    }
}

STA mode

#include <stdio.h>
#include <stdio.h>
#include <string.h>

#include <esp_log.h>
#include <esp_event.h>

#include <nvs_flash.h>

#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/event_groups.h>
#include "Wifi_Hardware.h"

#include "main.h"

#define TAG "main"

#defineWIFI_IP_LENGTH 16

static void wifi_event_handler(void *arg, esp_event_base_t event_base,
                               int32_t event_id, void *event_data);

char StaIP[WIFI_IP_LENGTH];

void app_main(void)
{<!-- -->
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {<!-- -->
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);

    memset (StaIP, 0, WIFI_IP_LENGTH);
    Wifi_Init(Wifi_ConfigApMode, & amp;wifi_event_handler);
    Wifi_ConfigSoftap("ap123", "12345678");
}

static void wifi_event_handler(void *arg, esp_event_base_t event_base,
                               int32_t event_id, void *event_data)
{<!-- -->
    if (event_id == WIFI_EVENT_AP_STACONNECTED) {<!-- -->
        wifi_event_ap_staconnected_t *event = (wifi_event_ap_staconnected_t *)event_data;
        ESP_LOGI(TAG, "station " MACSTR " join, AID=%d",
                 MAC2STR(event->mac), event->aid);
    } else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) {<!-- -->
        wifi_event_ap_stadisconnected_t *event = (wifi_event_ap_stadisconnected_t *)event_data;
        ESP_LOGI(TAG, "station " MACSTR " leave, AID=%d",
                 MAC2STR(event->mac), event->aid);
    } else if (event_base == WIFI_EVENT & amp; & amp; event_id == WIFI_EVENT_STA_START) {<!-- -->
        esp_wifi_connect();
    } else if (event_base == WIFI_EVENT & amp; & amp; event_id == WIFI_EVENT_STA_DISCONNECTED) {<!-- -->
        esp_wifi_connect();
        ESP_LOGI(TAG, "connect to the AP fail");
    } else if (event_base == IP_EVENT & amp; & amp; event_id == IP_EVENT_STA_GOT_IP) {<!-- -->
        ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
        memset(StaIP, 0, WIFI_IP_LENGTH);
        sprintf(StaIP, IPSTR, IP2STR( & amp;event->ip_info.ip));
        ESP_LOGI(TAG, "got StaIP: %s", StaIP);
    } else if (event_base == SC_EVENT & amp; & amp; event_id == SC_EVENT_SCAN_DONE) {<!-- -->
        ESP_LOGI(TAG, "Scan done");
    } else if (event_base == SC_EVENT & amp; & amp; event_id == SC_EVENT_FOUND_CHANNEL) {<!-- -->
        ESP_LOGI(TAG, "Found channel");
    } else if (event_base == SC_EVENT & amp; & amp; event_id == SC_EVENT_GOT_SSID_PSWD) {<!-- -->
        ESP_LOGI(TAG, "Got SSID and password");
    } else if (event_base == SC_EVENT & amp; & amp; event_id == SC_EVENT_SEND_ACK_DONE) {<!-- -->
        ESP_LOGI(TAG, "esptouch done");
    }
}

smart_config

#include <stdio.h>
#include <stdio.h>
#include <string.h>

#include <esp_log.h>
#include <esp_event.h>

#include <nvs_flash.h>

#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/event_groups.h>
#include "Wifi_Hardware.h"

#include "main.h"

#define TAG "main"

#defineWIFI_IP_LENGTH 16
#define WIFI_SSID_LENGTH 64
#define WIFI_PASS_LENGTH 128

static void wifi_event_handler(void *arg, esp_event_base_t event_base,
                               int32_t event_id, void *event_data);

char StaIP[WIFI_PASS_LENGTH];
char StaSSID[WIFI_SSID_LENGTH];
char StaPASS[WIFI_PASS_LENGTH];

void app_main(void)
{<!-- -->
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {<!-- -->
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);

    memset (StaIP, 0, WIFI_IP_LENGTH);
    memset (StaSSID, 0, WIFI_SSID_LENGTH);
    memset (StaPASS, 0, WIFI_PASS_LENGTH);

    Wifi_Init(Wifi_ConfigAirkissMode, & amp;wifi_event_handler);
}

static void wifi_event_handler(void *arg, esp_event_base_t event_base,
                               int32_t event_id, void *event_data)
{<!-- -->
    if (event_id == WIFI_EVENT_AP_STACONNECTED) {<!-- -->
        wifi_event_ap_staconnected_t *event = (wifi_event_ap_staconnected_t *)event_data;
        ESP_LOGI(TAG, "station " MACSTR " join, AID=%d",
                 MAC2STR(event->mac), event->aid);
    } else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) {<!-- -->
        wifi_event_ap_stadisconnected_t *event = (wifi_event_ap_stadisconnected_t *)event_data;
        ESP_LOGI(TAG, "station " MACSTR " leave, AID=%d",
                 MAC2STR(event->mac), event->aid);
    } else if (event_base == WIFI_EVENT & amp; & amp; event_id == WIFI_EVENT_STA_START) {<!-- -->
        if (strlen (StaSSID) == 0 ) {<!-- -->
            Wifi_ConfigAirkiss();
            ESP_LOGI(TAG, "config Airkiss");
        } else {<!-- -->
            esp_wifi_connect();
            ESP_LOGI(TAG, "connect WiFi");
        }
    } else if (event_base == WIFI_EVENT & amp; & amp; event_id == WIFI_EVENT_STA_DISCONNECTED) {<!-- -->
        esp_wifi_connect();
        ESP_LOGI(TAG, "connect to the AP fail");
    } else if (event_base == IP_EVENT & amp; & amp; event_id == IP_EVENT_STA_GOT_IP) {<!-- -->
        ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
        memset(StaIP, 0, WIFI_IP_LENGTH);
        sprintf(StaIP, IPSTR, IP2STR( & amp;event->ip_info.ip));
        ESP_LOGI(TAG, "got StaIP: %s", StaIP);
    } else if (event_base == SC_EVENT & amp; & amp; event_id == SC_EVENT_SCAN_DONE) {<!-- -->
        ESP_LOGI(TAG, "Scan done");
    } else if (event_base == SC_EVENT & amp; & amp; event_id == SC_EVENT_FOUND_CHANNEL) {<!-- -->
        ESP_LOGI(TAG, "Found channel");
    } else if (event_base == SC_EVENT & amp; & amp; event_id == SC_EVENT_GOT_SSID_PSWD) {<!-- -->
        ESP_LOGI(TAG, "Got SSID and password");
        smartconfig_event_got_ssid_pswd_t *evt = (smartconfig_event_got_ssid_pswd_t *)event_data;
        memset(StaSSID, 0, WIFI_SSID_LENGTH);
        memset(StaPASS, 0, WIFI_PASS_LENGTH);
        memcpy(StaSSID, evt->ssid, sizeof(evt->ssid));
        memcpy(StaPASS, evt->password, sizeof(evt->password));
        Wifi_ConfigSta(StaSSID, StaPASS);
    } else if (event_base == SC_EVENT & amp; & amp; event_id == SC_EVENT_SEND_ACK_DONE) {<!-- -->
        ESP_LOGI(TAG, "esptouch done");
        esp_smartconfig_stop();
    }
}