IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 2021-07-14 -> 正文阅读

[网络协议]2021-07-14

ESP32-S2 wifi
1):AP,无线接入点,网络的中心节点(无心路由器)。这个路由器的特点是不能插入网络,没有接入Internet,只能等待其他设备的连接,只能智能接入,类似于点对点的连接。
2):STA站点:每一个连接到无线网络的终端设备就是一个站点
在STA 和AP建立链路的过程中,当STA通信信标帧或探测响应帧扫描到可接入的服务集标识符来选择合适的SSID进行接入。
3)SSID(service set identifier):每个无限AP都应有一个标示用于用户识别,SSID就是这个用于用户识别的名字,也就是我们说的WiFi名。
4)BSSID:每一个网络设备都有一个用于识别的物理地址(MAC),设备的标识符。对于STA的设备来说,拿到AP接入点的MAC地址就是这个BSSID.
5) ESSID:实际和SSID相同,多个无线路由器共同的名字,单个路由器的名字是SSID
6) RSSI:通过STA扫描到AP站点的信号强度

WiFi库支持配置及监控esp32-s2 wi-fi连网功能
支持配置:

  • 基站模式(STA模式/wi-fi客户端模式),此时esp32-s2连接到接入点(AP)
  • AP模式(soft-AP模式/接入点模式),此时基站连接到esp32-s2
  • AP-STA共存模式(esp32-s2是接入点,同时又作为站点接入到 另一个接入点)
  • 上述模式的安全模式(WPA,WPA2,WEP)
  • 扫描接入点(主动扫描和被动扫描)
  • 使用混合模式监控IEEE802.11 WI-FI数据包。

esp32-s2 wi-fi功能列表

  • 支持仅 station 模式、仅 AP 模式、station/AP 共存模式
  • 支持使用 IEEE 802.11B、IEEE 802.11G、IEEE 802.11N 和 API 配置协议模式
  • 支持 WPA/WPA2/WPA2-企业版和 WPS
  • 支持 AMPDU、HT40、QoS 以及其它主要功能
  • 支持 Modem-sleep
  • 支持乐鑫专属协议,可实现 1 km 数据通信量
  • 空中数据传输最高可达 20 MBit/s TCP 吞吐量和 30 MBit/s UDP 吞吐量
  • 支持 Sniffer
  • 支持用于 Wi-Fi 连接的 fast_crypto 算法与普通算法的切换
  • 支持快速扫描和全信道扫描
  • 支持多个天线
  • 支持获取信道状态信息

ESP32-S2 wifi station :
在这里插入图片描述
在这里插入图片描述
1.Wi-Fi/LwIP 初始化阶段
esp_netif_init() 创建一个 LwIP 核心任务,并初始化 LwIP 相关工作。esp_event_loop_create() 创建一个系统事件任务,并初始化应用程序事件的回调函数。主任务通过调用函数 esp_netif_create_default_wifi_ap() 或 esp_netif_create_default_wifi_sta() 创建有 TCP/IP 堆栈的默认网络接口实例绑定 station 或 AP。主任务通过调用函数 esp_wifi_init() 创建 Wi-Fi 驱动程序任务,并初始化 Wi-Fi 驱动程序。主任务通过调用 OS API 创建应用程序任务

2.Wi-Fi 配置阶段
Wi-Fi 驱动程序处于 station 模式。因此,首先您需调用函数 esp_wifi_set_mode() (WIFI_MODE_STA) 将 Wi-Fi 模式配置为 station 模式
3.Wi-Fi 启动阶段
调用函数 esp_wifi_start() 启动 Wi-Fi 驱动程序
Wi-Fi 驱动程序将事件 WIFI_EVENT_STA_START 发布到事件任务中,然后,事件任务将执行一些正常操作并调用应用程序的事件回调函数。
应用程序的事件回调函数将事件 WIFI_EVENT_STA_START 中继到应用程序任务中。推荐您此时调用函数 esp_wifi_connect() 进行 Wi-Fi 连接。当然,您也可以等待在 WIFI_EVENT_STA_START 事件发生后的其它阶段再调用此函数。
4.Wi-Fi 连接阶段
调用函数 esp_wifi_connect() 后,Wi-Fi 驱动程序将启动内部扫描/连接过程。
如果内部扫描/连接过程成功,将产生 WIFI_EVENT_STA_CONNECTED 事件。然后,事件任务将启动 DHCP 客户端服务,最终触发 DHCP 程序。
在此情况下,应用程序的事件回调函数会将 WIFI_EVENT_STA_CONNECTED 事件中继到应用程序任务中。通常,应用程序不需进行操作,而您可以执行任何动作
5.Wi-Fi 获取 IP 阶段
一旦步骤 4.2 中的 DHCP 客户端初始化完成,Wi-Fi 驱动程序将进入 获取 IP 阶段
如果 Wi-Fi 成功从 DHCP 服务器接收到 IP 地址,则将引发 IP_EVENT_STA_GOT_IP 事件,事件任务将执行正常处理
6.Wi-Fi 断开阶段
WIFI_EVENT_STA_DISCONNECTED 事件发生时,任何套接字都无法正常工作
上述情况下,应用程序的事件回调函数会将 WIFI_EVENT_STA_DISCONNECTED 事件中继到应用程序任务中。推荐您调用函数 esp_wifi_connect() 重新连接 Wi-Fi,关闭所有套接字,并在必要时重新创建套接字。
7.Wi-Fi IP 更改阶段
如果 IP 地址发生更改,将引发 IP_EVENT_STA_GOT_IP 事件,其中 “ip_change” 被置为 “true”。
此事件对应用程序至关重要。这一事件发生时,适合关闭所有已创建的套接字并进行重新创建

8.Wi-Fi 清理阶段
调用函数 esp_wifi_disconnect() 断开 Wi-Fi 连接。

调用函数 esp_wifi_stop() 终止 Wi-Fi 驱动程序。

调用函数 esp_wifi_deinit() 清理 Wi-Fi 驱动程序。

wifi-station 代码分析:

  • 初始化LwIP

     创建lwIP核心任务并初始化与lwIP相关的工作
    
ESP_ERROR_CHECK(esp_netif_init());
  • 初始化wifi事件处理
    wifi事件处理基于esp_event库。wifi驱动程序会将事件发送到默认事件循环。应用程序可以在使用进行注册的回调中处理这些事件esp_event_handler_register(). esp_netif组件还处理wifi事件,以提供一组默认行为。例如,当wifi站连接到AP时,esp_netif将自动启动DHCP客户端
//创建系统事件任务并初始化应用程序事件的回调函数
ESP_ERROR_CHECK(esp_event_loop_create_default());
//创建具有TCP/IP堆栈的默认网络接口实例绑定基站
esp_netif_create_default_wifi_sta();

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_EVNET,ESP_EVENT_ANY_ID,&event_handler,NULL,&instance_any_id));
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,IP_EVETN_STA_GOT_IP,&event_handler,NULL,instance_got_ip));

  • 初始化wifi
wifi_init_config_t cfg=WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg);
  • wi-fi配置阶段
wifi_config_t  wifi_config={
		.sta={
				.ssid=EXAMPLE_ESP_WIFI_SSID,
				.password=EXAMPLE_ESP_WIFI_PASS,
				.threshold.authmode=WIFI_AUTH_WPA2_PSK,
				.pmf_cfg={
						.capable=true,
						.required=false
						},
					},
				};
	ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA);
	ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA,&wifi_config));			
  • wi-fi启动阶段
    调用esp_wifi_start()以启动wifi驱动程序
    wi-fi驱动程序将WIFI_EVENT_STA_START发布到事件任务;然后,事件任务将执行一些常规操作,并将调用应用程序事件回调函数
    应用程序事件回调函数将WIFI_EVENT_STA_START中继到应用程序任务。此时调用esp_wifi_connect().
ESP_ERROR_CHECK(esp_wifi_start());
  • wifi连接阶段
    一旦esp_wifi_connect()被调用,wifi驱动程序将开始内部扫描/连接过程
    如果内部扫描/连接过程成功,将生成WIFI_EVENT_STA_CONNECTED.在事件任务中,它将启动DHCP客户端,该客户端最终将触发DHCP进程。
    由于例如密码错误,找不到AP等原因,Wi-Fi连接可能会失败。在这种情况下,会出现WIFI_EVENT_STA_DISCONNECTED并提供这种失败的原因。
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_evnet_group,WIFI_FAIL_BIT);
					}
					ESP_LOGI(TAG,"connect  to the  AP  fail");
					}else if(evnet_base==IP_EVENT&&evnet_id=IP_EVNET_STA_GOT_IP){
					ip_event_got_ip_t * event=(ip_event_got_ip_t*)evnet_data;
					ESP_LOGI(TAG,"got ip:"  IPSTR,IP2STR(&event->ip_info.ip));
					s_retry_num=0;
					xEventGroupSetBits(s_wifi_event_group,WIFI_CONNECTED_BIT);
	}					
			
  • Wi-Fi“Got IP”阶段
    初始化DHCP客户端后,将开始IP阶段。如果从DHCP服务器成功接收到IP地址,则将出现IP_EVENT_STA_GOT_IP,并且事件任务将执行常规处理。

在应用程序事件回调中,IP_EVENT_STA_GOT_IP被中继到应用程序任务。对于基于LwIP的应用程序,此事件非常特殊,这意味着该应用程序已准备就绪,可以开始其任务,例如创建TCP / UDP套接字等。一个非常常见的错误是在收到IP_EVENT_STA_GOT_IP之前初始化套接字。接收IP之前,请勿开始与套接字相关的工作。

  • 扫描
    当前,esp_wifi_scan_start()仅在Station或Station + AP模式下支持该API。

扫描所有频道后,将出现WIFI_EVENT_SCAN_DONE。

应用程序的事件回调函数通知应用程序任务已接收到WIFI_EVENT_SCAN_DONE。esp_wifi_scan_get_ap_num()调用以获取在此扫描中找到的AP的数量。然后,它分配足够的条目和调用esp_wifi_scan_get_ap_records()以获取AP记录。请注意,一旦esp_wifi_scan_get_ap_records()被调用,Wi-Fi驱动程序中的AP记录将被释放。esp_wifi_scan_get_ap_records()一次扫描完成事件请勿调用两次。如果esp_wifi_scan_get_ap_records()在发生扫描完成事件时未调用,则不会释放由Wi-Fi驱动程序分配的AP记录。因此,请确保调用esp_wifi_scan_get_ap_records(),但只能调用一次。

完整代码(STA)

/* Scan Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/

/*
    This example shows how to scan for available set of APs.
*/
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "esp_log.h"
#include "esp_event.h"
#include "nvs_flash.h"

#define DEFAULT_SCAN_LIST_SIZE CONFIG_EXAMPLE_SCAN_LIST_SIZE

static const char *TAG = "scan";

static void print_auth_mode(int authmode)
{
    switch (authmode) {
    case WIFI_AUTH_OPEN:
        ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_OPEN");
        break;
    case WIFI_AUTH_WEP:
        ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WEP");
        break;
    case WIFI_AUTH_WPA_PSK:
        ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA_PSK");
        break;
    case WIFI_AUTH_WPA2_PSK:
        ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA2_PSK");
        break;
    case WIFI_AUTH_WPA_WPA2_PSK:
        ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA_WPA2_PSK");
        break;
    case WIFI_AUTH_WPA2_ENTERPRISE:
        ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA2_ENTERPRISE");
        break;
    case WIFI_AUTH_WPA3_PSK:
        ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA3_PSK");
        break;
    case WIFI_AUTH_WPA2_WPA3_PSK:
        ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA2_WPA3_PSK");
        break;
    default:
        ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_UNKNOWN");
        break;
    }
}

static void print_cipher_type(int pairwise_cipher, int group_cipher)
{
    switch (pairwise_cipher) {
    case WIFI_CIPHER_TYPE_NONE:
        ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_NONE");
        break;
    case WIFI_CIPHER_TYPE_WEP40:
        ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_WEP40");
        break;
    case WIFI_CIPHER_TYPE_WEP104:
        ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_WEP104");
        break;
    case WIFI_CIPHER_TYPE_TKIP:
        ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_TKIP");
        break;
    case WIFI_CIPHER_TYPE_CCMP:
        ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_CCMP");
        break;
    case WIFI_CIPHER_TYPE_TKIP_CCMP:
        ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_TKIP_CCMP");
        break;
    default:
        ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_UNKNOWN");
        break;
    }

    switch (group_cipher) {
    case WIFI_CIPHER_TYPE_NONE:
        ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_NONE");
        break;
    case WIFI_CIPHER_TYPE_WEP40:
        ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_WEP40");
        break;
    case WIFI_CIPHER_TYPE_WEP104:
        ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_WEP104");
        break;
    case WIFI_CIPHER_TYPE_TKIP:
        ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_TKIP");
        break;
    case WIFI_CIPHER_TYPE_CCMP:
        ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_CCMP");
        break;
    case WIFI_CIPHER_TYPE_TKIP_CCMP:
        ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_TKIP_CCMP");
        break;
    default:
        ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_UNKNOWN");
        break;
    }
}

/* Initialize Wi-Fi as sta and set scan method */
static void wifi_scan(void)
{
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
    assert(sta_netif);

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    uint16_t number = DEFAULT_SCAN_LIST_SIZE;
    wifi_ap_record_t ap_info[DEFAULT_SCAN_LIST_SIZE];
    uint16_t ap_count = 0;
    memset(ap_info, 0, sizeof(ap_info));

    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
    ESP_ERROR_CHECK(esp_wifi_start());
    ESP_ERROR_CHECK(esp_wifi_scan_start(NULL, true));
    ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&number, ap_info));
    ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&ap_count));
    ESP_LOGI(TAG, "Total APs scanned = %u", ap_count);
    for (int i = 0; (i < DEFAULT_SCAN_LIST_SIZE) && (i < ap_count); i++) {
        ESP_LOGI(TAG, "SSID \t\t%s", ap_info[i].ssid);
        ESP_LOGI(TAG, "RSSI \t\t%d", ap_info[i].rssi);
        print_auth_mode(ap_info[i].authmode);
        if (ap_info[i].authmode != WIFI_AUTH_WEP) {
            print_cipher_type(ap_info[i].pairwise_cipher, ap_info[i].group_cipher);
        }
        ESP_LOGI(TAG, "Channel \t\t%d\n", ap_info[i].primary);
    }

}

void app_main(void)
{
    // Initialize NVS
    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 );

    wifi_scan();
}

ESP32-S2 wifi AP:
在这里插入图片描述
在这里插入图片描述
ESP32-S2 Wi-Fi 扫描
仅 station 或 station/AP 共存模式支持 esp_wifi_scan_start() API。
在这里插入图片描述
在这里插入图片描述
主动扫描和被动扫描的区别:被动扫描侦听接入点发送的信标。这意味着等待发送信标(通常是几秒钟)。 主动扫描会立即向这些AP发射探测。

Wi-Fi/LwIP初始阶段

  1. 初始化LwIP
    创建LwIP核心任务并初始化与LwIP相关的工作。
ESP_ERROR_CHECK(esp_netif_init());
  1. 初始化Wi-Fi事件处理
    Wi-Fi事件处理基于esp_event库。Wi-Fi驱动程序会将事件发送到默认事件循环。应用程序可以在使用进行注册的回调中处理这些事件esp_event_handler_register()。esp_netif组件还处理Wi-Fi事件,以提供一组默认行为。例如,当Wi-Fi站连接到AP时,esp_netif将自动启动DHCP客户端(默认情况下)。
// 创建系统事件任务并初始化应用程序事件的回调函数。
ESP_ERROR_CHECK(esp_event_loop_create_default());
// 创建具有TCP / IP堆栈的默认网络接口实例绑定AP。
esp_netif_create_default_wifi_ap();

ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
                                                    ESP_EVENT_ANY_ID,
                                                    &wifi_event_handler,
                                                    NULL,
                                                    NULL));

  1. 初始化Wi-Fi
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));

  1. Wi-Fi配置阶段
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(ESP_IF_WIFI_AP, &wifi_config));

  1. Wi-Fi启动阶段
ESP_ERROR_CHECK(esp_wifi_start());

  1. Wi-Fi连接阶段
    当有终端接入或断开连接时,产生 WIFI_EVENT_AP_STACONNECTED 或 WIFI_EVENT_AP_STADISCONNECTED 事件。
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);
    }
}

完整代码(AP)

/*  WiFi softAP Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"

#include "lwip/err.h"
#include "lwip/sys.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 with
   the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
*/
#define EXAMPLE_ESP_WIFI_SSID      CONFIG_ESP_WIFI_SSID
#define EXAMPLE_ESP_WIFI_PASS      CONFIG_ESP_WIFI_PASSWORD
#define EXAMPLE_ESP_WIFI_CHANNEL   CONFIG_ESP_WIFI_CHANNEL
#define EXAMPLE_MAX_STA_CONN       CONFIG_ESP_MAX_STA_CONN

static const char *TAG = "wifi softAP";

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);
    }
}

void wifi_init_softap(void)
{
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    esp_netif_create_default_wifi_ap();

    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));

    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(ESP_IF_WIFI_AP, &wifi_config));
    ESP_ERROR_CHECK(esp_wifi_start());

    ESP_LOGI(TAG, "wifi_init_softap finished. SSID:%s password:%s channel:%d",
             EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS, EXAMPLE_ESP_WIFI_CHANNEL);
}

void app_main(void)
{
    //Initialize NVS
    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);

    ESP_LOGI(TAG, "ESP_WIFI_MODE_AP");
    wifi_init_softap();
}

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-07-15 16:36:12  更:2021-07-15 16:37:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/6 5:24:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码