修改自此博主代码

参考博客

参考WEB配网的网页代码

ESP32学习笔记(23)——NVS(非易失性存储)接口使用

目录

前言

一、工程创建

1.获取源代码

2.新建一个ESP32的工程

3.移植代码到工程下

4.修改工程的配置信息

二、修改工程代码

1.main.c

2.ConnectWIFI.c

3.webserver.c

4.my_dns_server.c

三、测试

四、说明


前言

使用WEB配网可以使ESP32连接到WIFI更加的便捷,灵活性更高


一、工程创建

1.获取源代码

先拿到博主大大的代码代码在 13_captive_portal

2.新建一个ESP32的工程

3.移植代码到工程下

把博主其中的两份代码复制到新建的工程下

因为配网要连接WIFI,所以给连接WIFI单独写在一文件(自己新建)中,实现WIFI的STA和AP模式(移植自IDF的其他示例工程)

文件目录如下:

4.修改工程的配置信息

修改main下的CMakeLists.txt

修改如下内容

idf_component_register(SRCS "main.c" "./WIFI/ConnectWIFI.c" "./dns_server/my_dns_server.c" "./web_server/webserver.c" "./tcp_client/tcp_client.c"INCLUDE_DIRS "." "./WIFI" "./dns_server" "./web_server" "./tcp_client"EMBED_FILES "./web_server/index.html")

因为嵌入html,所以 EMBED_FILES "./web_server/index.html"   就是对html的处理

二、修改工程代码

1.main.c

#include <stdio.h>#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"#include "nvs_flash.h"
#include "esp_vfs_fat.h"#include <netdb.h>
#include <sys/socket.h>#include "WIFI/ConnectWIFI.h"
#include "my_dns_server.h"#include "webserver.h"void app_main(void)
{ESP_ERROR_CHECK( nvs_flash_init() );//NvsWriteDataToFlash("","","");char WIFI_Name[50] = { 0 };char WIFI_PassWord[50] = { 0 }; /*读取保存的WIFI信息*/if(NvsReadDataFromFlash("WIFI Config Is OK!",WIFI_Name,WIFI_PassWord) == 0x00){printf("WIFI SSID     :%s\r\n",WIFI_Name    );printf("WIFI PASSWORD :%s\r\n",WIFI_PassWord);printf("开始初始化WIFI Station 模式\r\n");wifi_init_sta(WIFI_Name,WIFI_PassWord);         /*按照读取的信息初始化WIFI Station模式*/}else{printf("未读取到WIFI配置信息\r\n");printf("开始初始化WIFI AP 模式\r\n");WIFI_AP_Init();     /*上电后配置WIFI为AP模式*///vTaskDelay(1000 / portTICK_PERIOD_MS);dns_server_start();  //开启DNS服务web_server_start();  //开启http服务}}

2.ConnectWIFI.c

别忘了修改一下STA模式下的WIFI的名字密码

#include <stdio.h>
#include "WIFI/ConnectWIFI.h"
/* The examples use WiFi configuration that you can set via project configuration menu.If you'd rather not, just change the below entries to strings withthe config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
*/
#define EXAMPLE_ESP_WIFI_SSID      "设置WIFI  STA模式的名字"
#define EXAMPLE_ESP_WIFI_PASS      "设置WIFI  STA模式的密码"
#define EXAMPLE_ESP_WIFI_CHANNEL   (10)
#define EXAMPLE_MAX_STA_CONN       (1)// #define EXAMPLE_ESP_WIFI_SSID      "espConnect"
// #define EXAMPLE_ESP_WIFI_PASS      "12345678"
#define EXAMPLE_ESP_MAXIMUM_RETRY  10#define CONFIG_ESP_WIFI_AUTH_OPEN 1#if CONFIG_ESP_WIFI_AUTH_OPEN
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_OPEN
#elif CONFIG_ESP_WIFI_AUTH_WEP
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WEP
#elif CONFIG_ESP_WIFI_AUTH_WPA_PSK
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_PSK
#elif CONFIG_ESP_WIFI_AUTH_WPA2_PSK
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_PSK
#elif CONFIG_ESP_WIFI_AUTH_WPA_WPA2_PSK
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_WPA2_PSK
#elif CONFIG_ESP_WIFI_AUTH_WPA3_PSK
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA3_PSK
#elif CONFIG_ESP_WIFI_AUTH_WPA2_WPA3_PSK
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_WPA3_PSK
#elif CONFIG_ESP_WIFI_AUTH_WAPI_PSK
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WAPI_PSK
#endifstatic 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("ESP32", "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("ESP32", "station "MACSTR" leave, AID=%d",MAC2STR(event->mac), event->aid);}
}void WIFI_AP_Init(void)
{ESP_LOGI("ESP32", "WIFI Start Init");ESP_ERROR_CHECK(esp_netif_init());                  /*初始化底层TCP/IP堆栈*/ESP_ERROR_CHECK(esp_event_loop_create_default());   /*创建默认事件循环*/esp_netif_create_default_wifi_ap();                 /*创建默认WIFI AP,如果出现任何初始化错误,此API将中止*/wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();ESP_ERROR_CHECK(esp_wifi_init(&cfg));               /*初始化WiFi为WiFi驱动程序分配资源,如WiFi控制结构、RX/TX缓冲区、WiFi NVS结构等。此WiFi还启动WiFi任务。*/ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,ESP_EVENT_ANY_ID,&wifi_event_handler,NULL,NULL));wifi_config_t wifi_config = {.ap = {.ssid = EXAMPLE_ESP_WIFI_SSID,.ssid_len = strlen(EXAMPLE_ESP_WIFI_SSID),.channel = EXAMPLE_ESP_WIFI_CHANNEL,.password = EXAMPLE_ESP_WIFI_PASS,.max_connection = EXAMPLE_MAX_STA_CONN,.authmode = WIFI_AUTH_WPA_WPA2_PSK},};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_start());ESP_LOGI("ESP32", "wifi_init_softap finished. SSID:%s password:%s channel:%d",EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS, EXAMPLE_ESP_WIFI_CHANNEL);
}/* FreeRTOS event group to signal when we are connected*/
static EventGroupHandle_t s_wifi_event_group;/* The event group allows multiple bits for each event, but we only care about two events:* - we are connected to the AP with an IP* - we failed to connect after the maximum amount of retries */
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT      BIT1static const char *TAG = "wifi station";static int s_retry_num = 0;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) {esp_wifi_connect();} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) {esp_wifi_connect();s_retry_num++;ESP_LOGI(TAG, "retry to connect to the AP");} else {xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);}ESP_LOGI(TAG,"connect to the AP fail");} 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);}
}void wifi_init_sta(char *WIFI_Name,char *WIFI_PassWord)
{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 = {/* Setting a password implies station will connect to all security modes including WEP/WPA.* However these modes are deprecated and not advisable to be used. Incase your Access point* doesn't support WPA2, these mode can be enabled by commenting below line */.threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD,},};strcpy((char *)&wifi_config.sta.ssid,WIFI_Name);strcpy((char *)&wifi_config.sta.password,WIFI_PassWord);ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );ESP_ERROR_CHECK(esp_wifi_start() );ESP_LOGI(TAG, "wifi_init_sta finished.");/* 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",WIFI_Name, WIFI_PassWord);//xTaskCreate(tcp_client_task, "tcp_client", 1024 * 10, NULL, 5, NULL);/*TCP_client 连接TCP*/} else if (bits & WIFI_FAIL_BIT) {ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",WIFI_Name, WIFI_PassWord);NvsWriteDataToFlash("","","");/*超出最大重连次数后,退出连接,清楚保存的连接信息,重启*/esp_restart();} else {ESP_LOGE(TAG, "UNEXPECTED EVENT");}
}void NvsWriteDataToFlash(char *ConfirmString,char *WIFI_Name,char *WIFI_PassWord)
{nvs_handle handle;// 写入一个整形数据,一个字符串,WIFI信息以及版本信息static const char *NVS_CUSTOMER = "customer data";static const char *DATA2 = "String";static const char *DATA3 = "blob_wifi";// static const char *DATA4 = "blob_version";// // 要写入的字符串// char str_for_store[50] = "WIFI Config Is OK!";// 要写入的WIFI信息wifi_config_t wifi_config_to_store;//  wifi_config_t wifi_config_to_store = {//     .sta = {//         .ssid = "store_ssid:hello_kitty",//         .password = "store_password:1234567890",//     },// };strcpy((char *)&wifi_config_to_store.sta.ssid,WIFI_Name);strcpy((char *)&wifi_config_to_store.sta.password,WIFI_PassWord);// // 要写入的版本号// uint8_t version_for_store[4] = {0x01, 0x01, 0x01, 0x00};printf("set size:%u\r\n", sizeof(wifi_config_to_store));ESP_ERROR_CHECK( nvs_open( NVS_CUSTOMER, NVS_READWRITE, &handle) );ESP_ERROR_CHECK( nvs_set_str( handle, DATA2, ConfirmString) );ESP_ERROR_CHECK( nvs_set_blob( handle, DATA3, &wifi_config_to_store, sizeof(wifi_config_to_store)) );// ESP_ERROR_CHECK( nvs_set_blob( handle, DATA4, version_for_store, 4) );ESP_ERROR_CHECK( nvs_commit(handle) );nvs_close(handle);}unsigned char NvsReadDataFromFlash(char *ConfirmString,char *WIFI_Name,char *WIFI_PassWord)
{nvs_handle handle;static const char *NVS_CUSTOMER = "customer data";static const char *DATA2 = "String";static const char *DATA3 = "blob_wifi";// static const char *DATA4 = "blob_version";uint32_t str_length = 50;char str_data[50] = {0};wifi_config_t wifi_config_stored;// uint8_t version[4] = {0};// uint32_t version_len = 4;memset(&wifi_config_stored, 0x0, sizeof(wifi_config_stored));uint32_t wifi_len = sizeof(wifi_config_stored);ESP_ERROR_CHECK( nvs_open(NVS_CUSTOMER, NVS_READWRITE, &handle) );ESP_ERROR_CHECK ( nvs_get_str(handle, DATA2, str_data, &str_length) );ESP_ERROR_CHECK ( nvs_get_blob(handle, DATA3, &wifi_config_stored, &wifi_len) );// ESP_ERROR_CHECK ( nvs_get_blob(handle, DATA4, version, &version_len) );printf("[data1]: %s len:%u\r\n", str_data, str_length);printf("[data3]: ssid:%s passwd:%s\r\n", wifi_config_stored.sta.ssid, wifi_config_stored.sta.password);strcpy(WIFI_Name,(char *)&wifi_config_stored.sta.ssid);strcpy(WIFI_PassWord,(char *)&wifi_config_stored.sta.password);nvs_close(handle);if(strcmp(ConfirmString,str_data) == 0){return 0x00;}else{return 0xFF;}
}

ConnectWIFI.h

#ifndef _CONNECT_WIFI_H
#define _CONNECT_WIFI_H
#include <string.h>
#include <stdlib.h>#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_event.h"#include "esp_wifi.h"
#include "nvs_flash.h"
#include "esp_log.h"#include "lwip/err.h"
#include "lwip/sys.h"void WIFI_AP_Init(void);void wifi_init_sta(char *WIFI_Name,char *WIFI_PassWord);void NvsWriteDataToFlash(char *ConfirmString,char *WIFI_Name,char *WIFI_PassWord);
unsigned char NvsReadDataFromFlash(char *ConfirmString,char *WIFI_Name,char *WIFI_PassWord);#endif

3.webserver.c

#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"#include "nvs_flash.h"#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include "lwip/netdb.h"
#include "lwip/dns.h"#include "esp_http_server.h"#include "webserver.h"
#include "WIFI/ConnectWIFI.h"extern const uint8_t index_html_start[] asm("_binary_index_html_start");
extern const uint8_t index_html_end[]   asm("_binary_index_html_end");static const char *TAG = "WEB_SERVER";#define MIN( x, y ) ( ( x ) < ( y ) ? ( x ) : ( y ) )/* Send HTTP response with a run-time generated html consisting of* a list of all files and folders under the requested path.* In case of SPIFFS this returns empty list when path is any* string other than '/', since SPIFFS doesn't support directories */
static esp_err_t http_SendText_html(httpd_req_t *req)
{/* Get handle to embedded file upload script */const size_t upload_script_size = (index_html_end - index_html_start);const char TxBuffer[] = "<h1> SSID1 other WIFI</h1>";/* Add file upload form and script which on execution sends a POST request to /upload */httpd_resp_send_chunk(req, (const char *)index_html_start, upload_script_size);httpd_resp_send_chunk(req,(const char *)TxBuffer,sizeof(TxBuffer));return ESP_OK;
}
unsigned char CharToNum(unsigned char Data)
{if(Data >= '0' && Data <= '9'){return Data - '0';}else if(Data >= 'a' && Data <= 'f'){switch (Data){case 'a':return 10;case 'b':return 11;case 'c':return 12;case 'd':return 13;case 'e':return 14;case 'f':return 15;default:break;}}else if(Data >= 'A' && Data <= 'F'){switch (Data){case 'A':return 10;case 'B':return 11;case 'C':return 12;case 'D':return 13;case 'E':return 14;case 'F':return 15;default:break;}}return 0;
}
/* 强制门户访问时连接wifi后的第一次任意GET请求 */
static esp_err_t HTTP_FirstGet_handler(httpd_req_t *req)
{http_SendText_html(req);return ESP_OK;
}
/* 门户页面发回的,带有要连接的WIFI的名字和密码 */
static esp_err_t WIFI_Config_POST_handler(httpd_req_t *req)
{char buf[100];int ret, remaining = req->content_len;while (remaining > 0) {/* Read the data for the request */if ((ret = httpd_req_recv(req, buf,MIN(remaining, sizeof(buf)))) <= 0) {if (ret == HTTPD_SOCK_ERR_TIMEOUT) {/* Retry receiving if timeout occurred */continue;}return ESP_FAIL;}/* Send back the same data */char WIFI_ConfigBackInformation[100] = "The WIFI To Connect :";strcat(WIFI_ConfigBackInformation,buf);httpd_resp_send_chunk(req, WIFI_ConfigBackInformation, sizeof(WIFI_ConfigBackInformation));remaining -= ret;char wifi_name[50];char wifi_password[50];char wifi_passwordTransformation[50] = {0};esp_err_t e = httpd_query_key_value(buf,"ssid",wifi_name,sizeof(wifi_name));if(e == ESP_OK) {printf("SSID = %s\r\n",wifi_name);}else {printf("error = %d\r\n",e);}e = httpd_query_key_value(buf,"passWord",wifi_password,sizeof(wifi_password));if(e == ESP_OK) {/*对传回来的数据进行处理*/unsigned char Len = strlen(wifi_password);char tempBuffer[2];char *temp;unsigned char Cnt = 0;temp = wifi_password;for(int i=0;i<Len;){if(*temp == '%'){tempBuffer[0] = CharToNum(temp[1]);tempBuffer[1] = CharToNum(temp[2]);*temp = tempBuffer[0] * 16 + tempBuffer[1];wifi_passwordTransformation[Cnt] = *temp;temp+=3;i+=3;Cnt++;}else{wifi_passwordTransformation[Cnt] = *temp;temp++;i++;Cnt++;}}temp -= Len;printf("Len = %d\r\n",Len);printf("wifi_password = %s\r\n",wifi_password);printf("pswd = %s\r\n",wifi_passwordTransformation);}else {printf("error = %d\r\n",e);}/* Log data received */ESP_LOGI(TAG, "=========== RECEIVED DATA ==========");ESP_LOGI(TAG, "%.*s", ret, buf);ESP_LOGI(TAG, "====================================");NvsWriteDataToFlash("WIFI Config Is OK!",wifi_name,wifi_passwordTransformation);esp_restart();// esp_wifi_stop();// esp_event_handler_unregister(WIFI_EVENT,//                                 ESP_EVENT_ANY_ID,//                                 &wifi_event_handler//                                 );// esp_netif_destroy_default_wifi(ap_netif);// esp_event_loop_delete_default();// esp_wifi_deinit();// esp_netif_deinit();// httpd_stop(server);// printf("hello \r\n");// ESP_LOGI(TAG,"led on");// wifi_init_sta(wifi_name,wifi_passwordTransformation);}return ESP_OK;
}void web_server_start(void)
{// xTaskCreate(&webserver, "webserver_task", 2048, NULL, 5, NULL);httpd_handle_t server = NULL;httpd_config_t config = HTTPD_DEFAULT_CONFIG();/* Use the URI wildcard matching function in order to* allow the same handler to respond to multiple different* target URIs which match the wildcard scheme */config.uri_match_fn = httpd_uri_match_wildcard;ESP_LOGI(TAG, "Starting HTTP Server on port: '%d'", config.server_port);if (httpd_start(&server, &config) != ESP_OK) {ESP_LOGE(TAG, "Failed to start file server!");return ;}/* URI handler for getting uploaded files */httpd_uri_t file_download = {.uri       = "/*",  // Match all URIs of type /path/to/file.method    = HTTP_GET,.handler   = HTTP_FirstGet_handler,.user_ctx  = NULL,};httpd_register_uri_handler(server, &file_download);/* URI handler for uploading files to server */httpd_uri_t file_upload = {.uri       = "/configwifi",   // Match all URIs of type /upload/path/to/file.method    = HTTP_POST,.handler   = WIFI_Config_POST_handler,.user_ctx  = NULL,};httpd_register_uri_handler(server, &file_upload);}

webserver.h

#ifndef WEB_SERVER_h
#define WEB_SERVER_h#ifdef __cplusplus
extern "C"
{
#endifvoid web_server_start(void);#endif  

index.html

<!DOCTYPE html>
<html><head><title>WIFI</title><meta name="viewport" content="width=device-width, initial-scale=1"></head><style type="text/css">.input{display: block; margin-top: 10px;}.input span{width: 100px; float: left; float: left; height: 36px; line-height: 36px;}.input input{height: 30px;width: 200px;}.btn{width: 120px; height: 35px; background-color: #000000; border:0px; color:#ffffff; margin-top:15px; margin-left:100px;}</style><body><form method="POST" action="configwifi"><label class="input"><span>WiFi SSID  </span><input type="text" name="SSID"></label><label class="input"><span>WiFi PASS</span> <input type="text"  name="passWord"></label><input class="btn" type="submit" name="submit" value="Submie">         <p><span> Nearby wifi:</P></form></body>
</html>

4.my_dns_server.c

#include <string.h>
#include <sys/param.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "cJSON.h"#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include <lwip/netdb.h>
#include "mbedtls/md5.h"
#include "webserver.h"static const char *TAG = "DNS_SERVER";static int create_udp_socket(int port)
{struct sockaddr_in saddr = { 0 };int sock = -1;int err = 0;sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);if (sock < 0) {ESP_LOGE(TAG,"Failed to create socket. Error %d", errno);return -1;}// Bind the socket to any addresssaddr.sin_family = PF_INET;saddr.sin_port = htons(port);saddr.sin_addr.s_addr = htonl(INADDR_ANY);err = bind(sock, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));if (err < 0) {ESP_LOGE(TAG,"Failed to bind socket. Error %d", errno);goto err;}// All set, socket is configured for sending and receivingreturn sock;err:close(sock);return -1;
}static void my_dns_server(void *pvParameters)
{
/* Wait for all the IPs we care about to be set*/uint8_t data[128];int len = 0;struct sockaddr_in client = { 0 };socklen_t  client_len=sizeof(struct sockaddr_in); uint32_t i = 0;ESP_LOGI(TAG,"DNS server start ...");int sock = create_udp_socket(53);if (sock < 0) {ESP_LOGE(TAG,"Failed to create IPv4 multicast socket");}while(1){len=recvfrom(sock,data,100,0,(struct sockaddr *)&client,&client_len); //阻塞式if((len < 0) || ( len > 100)){ESP_LOGE(TAG,"recvfrom error\n");continue;}printf("DNS request:");for(i = 0x4; i< len;i++){if((data[i] >= 'a' && data[i] <= 'z') || (data[i] >= 'A' && data[i] <= 'Z') ||(data[i] >= '0' && data[i] <= '9'))printf("%c",data[i]);elseprintf("_");}printf("\r\n");//printf("%d\r\n",esp_get_free_heap_size()); //打印系统可用内存//过滤掉一些乱糟糟的域名if( strstr((const char *)data+0xc,"taobao")||strstr((const char *)data+0xc,"qq")    || strstr((const char *)data+0xc,"sogou") ||strstr((const char *)data+0xc,"amap")  ||strstr((const char *)data+0xc,"alipay")||strstr((const char *)data+0xc,"youku") ||strstr((const char *)data+0xc,"iqiyi") ||strstr((const char *)data+0xc,"baidu")){continue;}data[2] |= 0x80;data[3] |= 0x80;data[7] =1;data[len++] =0xc0;data[len++] =0x0c;data[len++] =0x00;data[len++] =0x01;data[len++] =0x00;data[len++] =0x01;data[len++] =0x00;data[len++] =0x00;data[len++] =0x00;data[len++] =0x0A;data[len++] =0x00;data[len++] =0x04;data[len++] =192;data[len++] =168;data[len++] =4;data[len++] =1;/*打印客户端地址和端口号*/// inet_ntop(AF_INET,&client.sin_addr,(char *)data,sizeof(data));// printf("client IP is %s, port is %d\n",data,ntohs(client.sin_port));sendto(sock,data,len,0,(struct sockaddr*)&client,client_len);vTaskDelay(10);}ESP_LOGE(TAG,"DNS server stop ...");shutdown(sock, 0);close(sock);vTaskDelete(NULL);
}void dns_server_start()
{xTaskCreate(&my_dns_server, "dns_task", 2048, NULL, 5, NULL);
}

my_dns_server.h

#ifndef MY_DNS_SERVER_h
#define MY_DNS_SERVER_h#ifdef __cplusplus
extern "C"
{
#endifvoid dns_server_start();#ifdef __cplusplus
}
#endif
#endif  

三、测试

首次编译下载后:

连接ESP32发出的热点

连接后会弹出浏览器,没有弹出可以手动输入192.168.4.1也可以进入WEB配网界面

输入要连接的WIFI后,ESP32会重启自动连接

四、说明

由于代码基本是拼凑起来的,稳定性不能保证,正式使用还需要多次测试

其实还可以添加搜索附近WIFI的功能(官方例程自带)这样就可以避免输入WIFI名字

ESP32 强制门户 WEB配网相关推荐

  1. ESP8266的Web配网以及强制门户的实现(连接wifi自动打开网页)

    目录 前言 Web配网详解 强制门户详解 完整代码 实验效果 前言 1.Web配网概述 在应用到esp8266的场景,往往与wifi是离不开的,但用户的wifi账号密码又无从知晓,于是乎有了配网. 目 ...

  2. 验证可用的ESP32/8266配网方式,开源代码,web配网,smartconfig配网

    web配网 设备内做了个小web服务器通过网页交换SSID和PWD.这个方式比较友好,不依赖外部app或小程序,保密性更好,产品可用性更好(苹果等个别手机不能打开配网页面可直接浏览器登陆192.168 ...

  3. ESP8266开发之旅 网络篇⑭ web配网

    文章目录 1. 前言 2. Web配网(AP配网) 2.1 自定义AP配网 2.2 WiFiManager 3. 总结 授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大 ...

  4. ESP32 C3 使用ConfigWiFi配网

    ESP32C3 的配网方式有好多种,这里主要使用AP配网方式.在 ESP32C3 上建立热点AP,使用手机连接上后在浏览器打开配置网页,输入WIFI信息,完成配网.这种方式很可靠,而且允许在电脑端完成 ...

  5. ESP8266 web配网微信小程序配网 全平台配网库 arduino 傻瓜式通用库

    wifi_link_tool esp8266通用配网库 (arduino) 库地址:点击进入GitHub 这是一个为esp8266设计的通用配网库 该库免费提供 使用请注明出处 允许毕业设计使用本库 ...

  6. ESP32 smart_config和airkiss配网

    陈拓 2021/11/28-2021/11/30 1. 简介 官方例程: https://gitee.com/EspressifSystems/esp-idf/tree/master/examples ...

  7. Arduino ESP32Web配网(二)

    Arduino ESP32Web配网(二) 相关篇<Arduino ESP32Web配网> 相对于之前的那篇文章,这篇的配网有不同的地方就是,html页面修饰了一下. 配网操作 1.如果是 ...

  8. ESP32常见配网方式分析

    ESP32常见配网方式分析 SoftAP 配网 BLE 配网 Smartconfig 配网: WEB 配网: SoftAP 配网 在 SoftAP 模式下,ESP32会充当临时的 Wi-Fi 接入点. ...

  9. 【工程师有空了】安信可ESP8266系列及ESP32系列模组AT指令实现网页配网---又多了一个配网方式

    文章目录 前言 AT指令介绍: 配网原理 一.实验准备 可能你还要用到: 二.编译固件 三.开启配网 四.常见问题 1.AT固件烧录不显示 "ready" 2.显示配网失败 3.除 ...

最新文章

  1. 近期必读的6篇NeurIPS 2019零样本学习论文
  2. 蚂蚁金服开源增强版Spring Boot 的研发框架!
  3. Java swing 如何将一个按钮放置到弹出框框的任意位置?(Absolute layout 布局的使用)...
  4. 前端大神用React刻了一个Windows XP
  5. linux路由修改密码,Linux中修改Mysql root用户密码的方法
  6. 遍历HashMap的最佳方法
  7. vite配置 vite.config.js
  8. 修改mysql编码方式
  9. linux网络安装mysql_linux系统安装mysql
  10. Python Day56-57 js
  11. dtu阿里云自定义透传
  12. LabVIEW基于Kvaser USBcan的UDS烧录Hex文件
  13. 计算机类专业哪些专业比较好,计算机类专业有哪些 哪个专业比较好
  14. c语言项目研发实训,C语言实训项目表V1.0.doc
  15. 站群网站八大盈利模式浅析
  16. 飞机飞行与碰撞问题matlab,建模案例—飞行管理问题.ppt
  17. QQ农场破解思路(版本20091212)
  18. # android移动开发——第十三章——个人理财通案例(Eclipse版)
  19. 一九产业AI速写:工业篇
  20. 操作系统学习笔记:保护

热门文章

  1. Netty-编码和解码
  2. XX健康:预约管理-预约设置日历插件文件简单下载Excel文件解析Excel表数据批量导入
  3. 二阶振荡环节的谐振频率_典型环节的频率特性二阶振荡环节-西安电子科技大学.PPT...
  4. CSMA/CD中重传与冲突检测机制
  5. oracle日记账查询,OraEBSR12GL日记账业务操作16:按汇总模板进行查询
  6. win7/win10屏幕录制教程?--QVE屏幕录制
  7. 微型计算机原理及应用第四版第七章课后答案,郑学坚微型计算机原理及应用第4版笔记和课后习题答案详解...
  8. CKEditor 4使用方法,来自http://docs.ckeditor.com/#!/guide/dev_ckeditor_js_load官网地址
  9. MyBatis动态批量插入、更新Mysql数据库的通用实现方案
  10. 检测到可疑访问 php,php.net被Chrome/Firefox浏览器标注为可疑站点