无线路由器中的WPS是Wi-Fi Protected Setup的简称,中文翻译为Wi-Fi安全防护设置,它是由Wi-Fi安全联盟推出的一种无线加密认证方式。主要是为了简化无线局域网的安装及安全性能配置工作,通过这种设置,让无线连接更加方便和安全。省去了输入繁琐密码的过程,也增加了wifi的安全性,但现在手机只有少部分还保留了这个功能。
在嵌入式wifi系统中比如esp32无线配对还是非常实用,匹配时需要一对一触发,否则相互干扰。
esp32作为ap端:
1.需要在menuconfig中添加组件支持,
component config -->wifi-->add wps register support in softap mode
2.wps配置和功能
#ifndef __BOARD_AP_WPS_H__
#define __BOARD_AP_WPS_H__#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "esp_mac.h"
#include "esp_log.h"
#include "esp_wps.h"
#include "esp_event.h"
#include "nvs_flash.h"
#include <string.h>/*** #ifndef os_memcpy* #define os_memcpy(d, s, n) memcpy((d), (s), (n))* #endif* 由此可见是一回事* */
#include <os.h>/*set wps mode via project configuration */
#define WPS_MODE WPS_TYPE_PBC//PBC方式使用默认的PIN"00000000",改变他和常规的差异化,只适合自己的设备配对
#define WPS_PIN_REDEFINE "12345678"static esp_wps_config_t ap_config = WPS_CONFIG_INIT_DEFAULT(WPS_MODE);static bool is_wps_rg_status = false;static inline void ap_wps_start(void)
{os_memcpy((void *)ap_config.pin, WPS_PIN_REDEFINE, 8);ESP_ERROR_CHECK(esp_wifi_ap_wps_enable(&ap_config));if (ap_config.wps_type == WPS_TYPE_PBC) {//ESP_LOGI(TAG, "Staring WPS registrar in PBC mode");} else {//ESP_LOGI(TAG, "Staring WPS registrar with random generated pin");}is_wps_rg_status = false;ESP_ERROR_CHECK(esp_wifi_ap_wps_start(NULL));}static inline void ap_wps_restart(void)
{os_memcpy((void *)ap_config.pin, WPS_PIN_REDEFINE, 8);ESP_ERROR_CHECK(esp_wifi_ap_wps_disable());ESP_ERROR_CHECK(esp_wifi_ap_wps_enable(&ap_config));is_wps_rg_status = false;ESP_ERROR_CHECK(esp_wifi_ap_wps_start(NULL));}static inline void ap_wps_stop(void)
{ESP_ERROR_CHECK(esp_wifi_ap_wps_disable());}static inline void ap_wps_set_rg_status(bool status)
{is_wps_rg_status = status;
}static inline bool ap_wps_get_rg_status(void)
{return is_wps_rg_status;
}#endif
3.板上配置一个按键用来监听配对触发
#ifndef __BOARD_GPIO_IN_H__
#define __BOARD_GPIO_IN_H__#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"//复用BOOT脚作为wps key触发引脚,这个脚默认是没有接的,悬空状态,那就将其配置为内部上拉,下降沿触发
#define GPIO_INPUT_IO (0)
#define GPIO_INPUT_PIN_SEL (1ULL<<GPIO_INPUT_IO)//((1ULL<<GPIO_INPUT_IO_0) | (1ULL<<GPIO_INPUT_IO_1))#define ESP_INTR_FLAG_DEFAULT (0)static QueueHandle_t gpio_evt_queue = NULL;//需要这种事件传递的形式
static void IRAM_ATTR gpio_isr_handler(void* arg)
{uint32_t gpio_num = (uint32_t) arg;xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
}static void gpio_task_example(void* arg)
{#define WPS_TRIGGER_TIME (2000)#define WPS_LOOP_TIME (100)#define WPS_TIMEOUT (20 * 1000)uint32_t io_num;for(;;) {if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {//printf("GPIO[%"PRIu32"] intr, val: %d\n", io_num, gpio_get_level(io_num));int loop_cnt = 0;while(loop_cnt < (WPS_TRIGGER_TIME / WPS_LOOP_TIME)){//按键松开了就重新开始监听if(gpio_get_level(io_num)){break;}loop_cnt++;vTaskDelay(WPS_LOOP_TIME / portTICK_PERIOD_MS);}if(loop_cnt < (WPS_TRIGGER_TIME / WPS_LOOP_TIME)){printf("wps key abort!\n");continue;}printf("wps key pressed!\n");ap_wps_restart();/*** 尽管WIFI_EVENT_AP_WPS_RG_TIMEOUT时间比较长,不过他是* 超时以后不断循环ap_wps_restart,所以默认上超时是无限期的,* 这时候就可以人为的使用一个延时来主动停止wps即可,同时也避免了* wps按键的重复触发问题.* */loop_cnt = 0;while(loop_cnt < (WPS_TIMEOUT / WPS_LOOP_TIME)){if(ap_wps_get_rg_status()){break;}loop_cnt++;vTaskDelay(WPS_LOOP_TIME / portTICK_PERIOD_MS);}ap_wps_stop();printf("wps stop!\n");//清空队列防止干扰xQueueReset(gpio_evt_queue);}}
}static inline void gpio_in_init(void)
{//interrupt of rising edgegpio_config_t io_conf = {};io_conf.intr_type = GPIO_INTR_NEGEDGE;//bit mask of the pins, use GPIO4/5 hereio_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL;//set as input modeio_conf.mode = GPIO_MODE_INPUT;//enable pull-up modeio_conf.pull_up_en = 1;//下降沿触发当然默认拉高io_conf.pull_down_en = 0;//上升沿当然先拉低默认gpio_config(&io_conf);//change gpio interrupt type for one pin//gpio_set_intr_type(GPIO_INPUT_IO_0, GPIO_INTR_ANYEDGE);//create a queue to handle gpio event from isr//不需要发送10次,发送1次就好gpio_evt_queue = xQueueCreate(1/*10*/, sizeof(uint32_t));//start gpio taskxTaskCreate(gpio_task_example, "gpio_task_example", 2048, NULL, GPIO_KEY_TASK_PRIORITY, NULL);//install gpio isr servicegpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);//hook isr handler for specific gpio pingpio_isr_handler_add(GPIO_INPUT_IO, gpio_isr_handler, (void*) GPIO_INPUT_IO);}static inline void test_gpio_in(void)
{gpio_in_init();gpio_out_init();gpio_out_value(0);
}#endif
/ /
4.wifi事件的监听和处理
static void wifi_event_handler(void* arg, esp_event_base_t event_base,int32_t event_id, void* event_data)
{switch (event_id) {case WIFI_EVENT_AP_START:ESP_LOGI(TAG, "WIFI_EVENT_AP_START");break;case WIFI_EVENT_AP_STADISCONNECTED:{ESP_LOGI(TAG, "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);}break;case WIFI_EVENT_AP_STACONNECTED:{ESP_LOGI(TAG, "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);}break;case WIFI_EVENT_AP_WPS_RG_SUCCESS:{ESP_LOGI(TAG, "WIFI_EVENT_AP_WPS_RG_SUCCESS");wifi_event_ap_wps_rg_success_t *evt = (wifi_event_ap_wps_rg_success_t *)event_data;ESP_LOGI(TAG, "station "MACSTR" WPS successful",MAC2STR(evt->peer_macaddr));ap_wps_set_rg_status(true);}break;case WIFI_EVENT_AP_WPS_RG_FAILED:{ESP_LOGI(TAG, "WIFI_EVENT_AP_WPS_RG_FAILED");wifi_event_ap_wps_rg_fail_reason_t *evt = (wifi_event_ap_wps_rg_fail_reason_t *)event_data;ESP_LOGI(TAG, "station "MACSTR" WPS failed, reason=%d",MAC2STR(evt->peer_macaddr), evt->reason);ap_wps_restart();}break;case WIFI_EVENT_AP_WPS_RG_TIMEOUT:{ESP_LOGI(TAG, "WIFI_EVENT_AP_WPS_RG_TIMEOUT");ap_wps_restart();}break;default:break;}
}static void wifi_init_softap(void)
{ESP_ERROR_CHECK(esp_netif_init());ESP_ERROR_CHECK(esp_event_loop_create_default());esp_netif_t*mynetif = esp_netif_create_default_wifi_ap();esp_netif_ip_info_t ipInfo;IP4_ADDR(&ipInfo.ip, 192,168,28,1);IP4_ADDR(&ipInfo.gw, 192,168,28,1);IP4_ADDR(&ipInfo.netmask, 255,255,255,0);esp_netif_dhcps_stop(mynetif);esp_netif_set_ip_info(mynetif, &ipInfo);esp_netif_dhcps_start(mynetif);wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();ESP_ERROR_CHECK(esp_wifi_init(&cfg));ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,ESP_EVENT_ANY_ID,&wifi_event_handler,NULL,NULL));//这个是默认mac base,比如softap是+1等等.//本地无线网卡地址uint8_t local_mac[6];//esp_efuse_mac_get_default(mac);esp_read_mac(local_mac,ESP_MAC_WIFI_SOFTAP);//for(int i=0;i<sizeof(mac);i++)// printf("%2X ",mac[i]);//printf("\n");uint8_t buf[32] = {0};sprintf((char*)buf,"%s-%02X%02X%02X",EXAMPLE_ESP_WIFI_SSID_PREFIX,local_mac[3],local_mac[4],local_mac[5]);wifi_config_t wifi_config = {.ap = {.ssid = EXAMPLE_ESP_WIFI_SSID_PREFIX,//此处只能常量.ssid_len = strlen(EXAMPLE_ESP_WIFI_SSID_PREFIX),.channel = EXAMPLE_ESP_WIFI_CHANNEL,.password = EXAMPLE_ESP_WIFI_PASS,.max_connection = EXAMPLE_MAX_STA_CONN,
#ifdef CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT.authmode = WIFI_AUTH_WPA3_PSK,.sae_pwe_h2e = WPA3_SAE_PWE_BOTH,
#else /* CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT */.authmode = WIFI_AUTH_WPA2_PSK,
#endif.pmf_cfg = {.required = true,},},};
//wifi_config.ap.pairwise_cipherwifi_config.ap.ssid_len = strlen((char*)buf);memcpy(wifi_config.ap.ssid,buf,wifi_config.ap.ssid_len);wifi_config.ap.channel = sta_wifi_get_best_channel();if (strlen(EXAMPLE_ESP_WIFI_PASS) == 0) {wifi_config.ap.authmode = WIFI_AUTH_OPEN;}ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE));ESP_ERROR_CHECK(esp_wifi_start());ESP_LOGI(TAG, "wifi_init_softap finished. SSID:%s password:%s channel:%d",buf, EXAMPLE_ESP_WIFI_PASS, wifi_config.ap.channel);}
esp32作为sta端:
1.wps配置和功能
#ifndef __BOARD_STA_WPS_H__
#define __BOARD_STA_WPS_H__#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "esp_log.h"
#include "esp_wps.h"
#include "esp_event.h"
#include "nvs_flash.h"
#include <string.h>#define WPS_PIN_REDEFINE "12345678"static esp_wps_config_t sta_config = WPS_CONFIG_INIT_DEFAULT(WPS_TYPE_PBC);static bool is_wps_er_status = false;static inline void sta_wps_start(void)
{//暂停wifi连接esp_wifi_disconnect();memcpy(sta_config.pin, WPS_PIN_REDEFINE, 8);ESP_ERROR_CHECK(esp_wifi_wps_enable(&sta_config));is_wps_er_status = false;ESP_ERROR_CHECK(esp_wifi_wps_start(0));}static inline void sta_wps_restart(void)
{//暂停wifi连接esp_wifi_disconnect();memcpy(sta_config.pin, WPS_PIN_REDEFINE, 8);ESP_ERROR_CHECK(esp_wifi_wps_disable());ESP_ERROR_CHECK(esp_wifi_wps_enable(&sta_config));is_wps_er_status = false;ESP_ERROR_CHECK(esp_wifi_wps_start(0));}static inline void sta_wps_stop(void)
{ESP_ERROR_CHECK(esp_wifi_wps_disable());//恢复wifi连接esp_wifi_connect();}static inline void sta_wps_set_er_status(bool status)
{is_wps_er_status = status;
}static inline bool sta_wps_get_er_status(void)
{return is_wps_er_status;
}#endif
/
2.板上配置一个按键用来监听配对触发
#ifndef __BOARD_GPIO_IN_H__
#define __BOARD_GPIO_IN_H__#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"//暂时假设服用BOOT脚作为wps key触发引脚,这个脚默认是没有接的,悬空状态,那就将其配置为内部上拉,下降沿触发
#define GPIO_INPUT_IO (0)
#define GPIO_INPUT_PIN_SEL (1ULL<<GPIO_INPUT_IO)//((1ULL<<GPIO_INPUT_IO_0) | (1ULL<<GPIO_INPUT_IO_1))#define ESP_INTR_FLAG_DEFAULT (0)extern int global_wifi_connect;static QueueHandle_t gpio_evt_queue = NULL;static bool is_wps_key_pressed = false;//需要这种事件传递的形式
static void IRAM_ATTR gpio_isr_handler(void* arg)
{uint32_t gpio_num = (uint32_t) arg;xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
}static void gpio_task_example(void* arg)
{#define WPS_TRIGGER_TIME (2000)#define WPS_LOOP_TIME (100)#define WPS_TIMEOUT (20 * 1000)uint32_t io_num;for(;;) {if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {//printf("GPIO[%"PRIu32"] intr, val: %d\n", io_num, gpio_get_level(io_num));int loop_cnt = 0;while(loop_cnt < (WPS_TRIGGER_TIME / WPS_LOOP_TIME)){//按键松开了就重新开始监听if(gpio_get_level(io_num)){break;}loop_cnt++;vTaskDelay(WPS_LOOP_TIME / portTICK_PERIOD_MS);}if(loop_cnt < (WPS_TRIGGER_TIME / WPS_LOOP_TIME)){printf("sta wps key abort!\n");continue;}printf("sta wps key pressed!\n");is_wps_key_pressed = true;/**在wifi已经连接上的情况下,先断开wifi连接,再终止wifi重连,再启动wps* */if(global_wifi_connect > 0){//由于is_wps_key_pressed = true,WIFI_EVENT_STA_DISCONNECTED中wifi不能改变状态//所以要手动更改.global_wifi_connect = 0;esp_wifi_disconnect();vTaskDelay(100 / portTICK_PERIOD_MS);}/*** W (20543) wifi:sta_scan: STA is connecting, scan are not allowed!* 看来wifi在连接的时候是不能进行wps配对的.* */sta_wps_restart();/*** 尽管WIFI_EVENT_AP_WPS_RG_TIMEOUT时间比较长,不过他是* 超时以后不断循环ap_wps_restart,所以默认上超时是无限期的,* 这时候就可以人为的使用一个延时来主动停止wps即可,同时也避免了* wps按键的重复触发问题.* */loop_cnt = 0;while(loop_cnt < (WPS_TIMEOUT / WPS_LOOP_TIME)){if(sta_wps_get_er_status()){break;}loop_cnt++;vTaskDelay(WPS_LOOP_TIME / portTICK_PERIOD_MS);}if(!sta_wps_get_er_status()){sta_wps_stop();printf("sta wps stop!\n");}is_wps_key_pressed = false;//清空队列防止干扰xQueueReset(gpio_evt_queue);}}
}static inline void gpio_in_init(void)
{//interrupt of rising edgegpio_config_t io_conf = {};io_conf.intr_type = GPIO_INTR_NEGEDGE;//bit mask of the pins, use GPIO4/5 hereio_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL;//set as input modeio_conf.mode = GPIO_MODE_INPUT;//enable pull-up modeio_conf.pull_up_en = 1;//下降沿触发当然默认拉高io_conf.pull_down_en = 0;//上升沿当然先拉低默认gpio_config(&io_conf);//change gpio interrupt type for one pin//gpio_set_intr_type(GPIO_INPUT_IO_0, GPIO_INTR_ANYEDGE);//create a queue to handle gpio event from isr//不需要发送10次,发送1次就好gpio_evt_queue = xQueueCreate(1/*10*/, sizeof(uint32_t));//start gpio taskxTaskCreate(gpio_task_example, "gpio_task_example", 2048, NULL, GPIO_KEY_TASK_PRIORITY, NULL);//install gpio isr servicegpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);//hook isr handler for specific gpio pingpio_isr_handler_add(GPIO_INPUT_IO, gpio_isr_handler, (void*) GPIO_INPUT_IO);}static inline bool board_gpio_get_wps_key_status(void)
{return is_wps_key_pressed;
}static inline void test_gpio_in(void)
{gpio_in_init();gpio_out_init();gpio_out_value(0);
}#endif
/ /
3.wifi事件的监听和处理
static void event_handler(void* arg, esp_event_base_t event_base,int32_t event_id, void* event_data)
{//普通连接if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START){global_wifi_connect = -1;esp_wifi_connect();}else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED){if(!board_gpio_get_wps_key_status()){/*** 这种基于事件的重连方式不错* */if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) {global_wifi_connect = 0;esp_wifi_connect();s_retry_num++;ESP_LOGI(TAG, "retry to connect to the AP");} else {global_wifi_connect = -1;xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);}ESP_LOGI(TAG,"connect to the AP fail");}}else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_CONNECTED){//此处获取bssid,wifi ap's wlan macwifi_event_sta_connected_t* event = (wifi_event_sta_connected_t*) event_data;//printf("get ap's bssid:");//print0x(event->bssid,sizeof(event->bssid));uint16_t chs = Crc_Calculate(event->bssid, sizeof(event->bssid));set_send_mavlink_protocol_crc(chs >> 8,chs & 0xFF);//printf("ap's mac chs=%04X\n",chs);char str[32] = {0};size_t str_len = sizeof(str);esp_err_t err;err = board_read_string("wifi_name", str, &str_len);if(err == ESP_OK && str_len > 0){str[str_len] = 0;//和已经保存的ssid不一致才需要重新保存if(strcmp((char*)event->ssid,(char*)str)){board_write_string("wifi_name", (char*)event->ssid);printf("wifi name differ,need save!\n");}}else{//没有保存ssid就立即保存if(ESP_ERR_NVS_NOT_FOUND == err){board_write_string("wifi_name", (char*)event->ssid);printf("wifi name not found,need save!\n");}}}else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP){ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));s_retry_num = 0;xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);global_wifi_connect = 1;}//wps连接switch (event_id) {case WIFI_EVENT_STA_WPS_ER_SUCCESS:ESP_LOGI(TAG, "WIFI_EVENT_STA_WPS_ER_SUCCESS");{wifi_event_sta_wps_er_success_t *evt =(wifi_event_sta_wps_er_success_t *)event_data;int i;if (evt) {s_ap_creds_num = evt->ap_cred_cnt;for (i = 0; i < s_ap_creds_num; i++) {memcpy(wps_ap_creds[i].sta.ssid, evt->ap_cred[i].ssid,sizeof(evt->ap_cred[i].ssid));memcpy(wps_ap_creds[i].sta.password, evt->ap_cred[i].passphrase,sizeof(evt->ap_cred[i].passphrase));}/* If multiple AP credentials are received from WPS, connect with first one */ESP_LOGI(TAG, "Connecting to SSID: %s, Passphrase: %s",wps_ap_creds[0].sta.ssid, wps_ap_creds[0].sta.password);ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wps_ap_creds[0]) );}//此处已经说明只有一个ap wps则没有event data,直接连接即可/** If only one AP credential is received from WPS, there will be no event data and* esp_wifi_set_config() is already called by WPS modules for backward compatibility* with legacy apps. So directly attempt connection here.*/ESP_ERROR_CHECK(esp_wifi_wps_disable());sta_wps_set_er_status(true);esp_wifi_connect();}break;case WIFI_EVENT_STA_WPS_ER_FAILED:ESP_LOGI(TAG, "WIFI_EVENT_STA_WPS_ER_FAILED");sta_wps_restart();break;case WIFI_EVENT_STA_WPS_ER_TIMEOUT:ESP_LOGI(TAG, "WIFI_EVENT_STA_WPS_ER_TIMEOUT");sta_wps_restart();break;case WIFI_EVENT_STA_WPS_ER_PIN:ESP_LOGI(TAG, "WIFI_EVENT_STA_WPS_ER_PIN");/* display the PIN code */wifi_event_sta_wps_er_pin_t* event = (wifi_event_sta_wps_er_pin_t*) event_data;printf("display pincode=%s\n",(char*)event->pin_code);break;default:break;}
}void wifi_init_sta(void)
{s_wifi_event_group = xEventGroupCreate();ESP_ERROR_CHECK(esp_netif_init());ESP_ERROR_CHECK(esp_event_loop_create_default());esp_netif_create_default_wifi_sta();wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();ESP_ERROR_CHECK(esp_wifi_init(&cfg));esp_event_handler_instance_t instance_any_id;esp_event_handler_instance_t instance_got_ip;ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,ESP_EVENT_ANY_ID,&event_handler,NULL,&instance_any_id));ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,IP_EVENT_STA_GOT_IP,&event_handler,NULL,&instance_got_ip));wifi_config_t wifi_config = {.sta = {.ssid = EXAMPLE_ESP_WIFI_SSID,.password = EXAMPLE_ESP_WIFI_PASS,/* Authmode threshold resets to WPA2 as default if password matches WPA2 standards (pasword len => 8).* If you want to connect the device to deprecated WEP/WPA networks, Please set the threshold value* to WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK and set the password with length and format matching to* WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK standards.*/.threshold.authmode = WIFI_AUTH_WPA3_PSK,.sae_pwe_h2e = WPA3_SAE_PWE_BOTH,.sae_h2e_identifier = "",},};/*** 获取已经保存的wifi&password* */char str[32] = {0};size_t str_len = sizeof(str);esp_err_t err;err = board_read_string("wifi_name", str, &str_len);if(err == ESP_OK && str_len > 0){str[str_len] = 0;strcpy((char*)wifi_config.sta.ssid,str);printf("get saved wifi_name=%s\n",str);memset(str,0,sizeof(str));str_len = sizeof(str);}err = board_read_string("wifi_passwd", str, &str_len);if(err == ESP_OK && str_len > 0){str[str_len] = 0;strcpy((char*)wifi_config.sta.password,str);printf("get saved wifi_passwd=%s\n",str);}ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );//禁止modem休眠,降低延迟ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE));ESP_ERROR_CHECK(esp_wifi_start() );ESP_LOGI(TAG, "wifi_init_sta finished.");//不需要堵塞等候连接!不过没有连接堵塞在这里也不搓,也没必要后续初始化和任务启动,只需要wps已经启动即可/* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum* number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,pdFALSE,pdFALSE,portMAX_DELAY);/* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually* happened. */if (bits & WIFI_CONNECTED_BIT) {
// ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
// EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",wifi_config.sta.ssid, wifi_config.sta.password);} else if (bits & WIFI_FAIL_BIT) {ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);} else {ESP_LOGE(TAG, "UNEXPECTED EVENT");}}
最后两块板子在2秒时间内依次按下配对按键,即可建立无线配对,sta端保存ap端wifi信息用于下次启动直连,方便快捷。