ESP8266/ESP32 中查看,修改AP的IP信息,并剔除指定的STA

ESP系列的芯片支持WiFi功能的STA+AP工作模式,今天我们来聊一聊当ESP系列的芯片工作在AP模式(即作为一个WiFi热点)时,如何查看其IP、修改其IP,并剔除不想让其连接到AP的指定STA。

1.查看并修改AP的IP

实验环境是一块ESP8266作为AP,一块ESP32作为STA,代码模板使用的是ESP8266 RTOS SDK/ESP-IDF上的WiFi_Start代码。不多说,上代码:(代码在ESP8266/ESP32下的实现基本一致,并全部通过了测试,注释给出了相关说明)

/* 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_MAX_STA_CONN CONFIG_ESP_MAX_STA_CONN

static const char *TAG = "wifi softAP";

/* define some temporary variable to show the result*/
tcpip_adapter_ip_info_t local_ip;
esp_err_t res_ap_get;
esp_err_t res_ap_set;

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);
/*printf self mac and IP*/
res_ap_get = tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &local_ip);
if(res_ap_get == ESP_OK){
ESP_LOGI(TAG,"get is success\n");
ESP_LOGI(TAG, "now_self_ip:"IPSTR"\n",IP2STR(&local_ip.ip));
ESP_LOGI(TAG, "now_self_netmask:"IPSTR"\n",IP2STR(&local_ip.netmask));
ESP_LOGI(TAG, "now_self_gw:"IPSTR"\n",IP2STR(&local_ip.gw)); 
}
} 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()
{
tcpip_adapter_init();
ESP_ERROR_CHECK(esp_event_loop_create_default());

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

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

wifi_config_t wifi_config = {
.ap = {
.ssid = EXAMPLE_ESP_WIFI_SSID,
.ssid_len = strlen(EXAMPLE_ESP_WIFI_SSID),
.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));

/*you must call esp_wifi_start() before set your new IP,
because the WiFi system's start always load the original IP information
from the tcpip_adapter_init(),if you want change the original IP ,
please change the IP in tcpip_adapter_init(),otherwise,please allow the 
system load the original IP firstly when call esp_wifi_start(), 
and then you can set your new IP*/
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "wifi_init_softap finished. SSID:%s password:%s",
EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);

/*print old IP information*/
res_ap_get = tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &local_ip);
if(res_ap_get == ESP_OK){
ESP_LOGI(TAG,"get is success\n");
}
ESP_LOGI(TAG, "old_self_ip:"IPSTR"\n",IP2STR(&local_ip.ip));
ESP_LOGI(TAG, "old_self_netmask:"IPSTR"\n",IP2STR(&local_ip.netmask));
ESP_LOGI(TAG, "old_self_gw:"IPSTR"\n",IP2STR(&local_ip.gw));

/*stop dhcps*/
tcpip_adapter_dhcps_stop(TCPIP_ADAPTER_IF_AP); 

/*write */
IP4_ADDR(&local_ip.ip, 192, 168 , 47, 110);
IP4_ADDR(&local_ip.gw, 192, 168 , 47, 120);
IP4_ADDR(&local_ip.netmask, 255, 255 , 255, 0);
/*print set IP information*/
ESP_LOGI(TAG,"set ip:"IPSTR"\n",IP2STR(&local_ip.ip));
ESP_LOGI(TAG,"set:netmask"IPSTR"\n",IP2STR(&local_ip.netmask));
ESP_LOGI(TAG,"set gw:"IPSTR"\n",IP2STR(&local_ip.gw));
/*set new IP*/
res_ap_set = tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_AP, &local_ip);
if(res_ap_set == ESP_OK){
ESP_LOGI(TAG,"set is success\n");
}
else
{
ESP_LOGI(TAG,"set is failed\n");
}

/*restart adapter dhcps*/
tcpip_adapter_dhcps_start(TCPIP_ADAPTER_IF_AP);

/*print new IP information*/
res_ap_get = tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &local_ip);
if(res_ap_get == ESP_OK){
ESP_LOGI(TAG,"get is success\n");
}
ESP_LOGI(TAG, "new_self_ip:"IPSTR"\n",IP2STR(&local_ip.ip));
ESP_LOGI(TAG, "new_self_netmask:"IPSTR"\n",IP2STR(&local_ip.netmask));
ESP_LOGI(TAG, "new_self_gw:"IPSTR"\n",IP2STR(&local_ip.gw));

}

void app_main()
{
ESP_ERROR_CHECK(nvs_flash_init());

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

测试结果如下:

结果分析:

获取原IP:192.168.4.1 

要设置的IP:192.168.47.110 

设置成功后再次获取当前IP为:192.168.47.110,证明设置IP成功。

作为补充,我在 WIFI_EVENT_AP_STACONNECTED事件下添加了每当有STA连接该AP,就打印一次AP当前IP的代码,从图中可以看到,now_self_ip为192.168.47.110,这正是我们设置的IP值,因此,再一次证明了我们已经成功修改该AP的IP。

上述提供了一种再运行时修改AP的IP的方法,如果想在开发板上电运行就使用指定的IP,可以在

模式AP模式获取自身IP、修改自己的IP,剔除指定id的STA。如果不想在运行时修改IP,可以在始化代码tcpip_adapter_init()的实现中直接修改结构体中的IP和掩码,就可以在初始化时加载指定的IP。

2.剔除指定的STA

有时候我们希望将一些”蹭网“的STA拉入黑名单,防止其连接到我们的AP上。

下面的代码给出了一种剔除连接到AP的指定STA的方法:(替换掉上面代码的同名函数即可,就增加了小部分代码)

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);
/*printf self mac and IP*/
res_ap_get = tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &local_ip);
if(res_ap_get == ESP_OK){
ESP_LOGI(TAG,"get is success\n");
ESP_LOGI(TAG, "now_self_ip:"IPSTR"\n",IP2STR(&local_ip.ip));
ESP_LOGI(TAG, "now_self_netmask:"IPSTR"\n",IP2STR(&local_ip.netmask));
ESP_LOGI(TAG, "now_self_gw:"IPSTR"\n",IP2STR(&local_ip.gw)); 
}

esp_err_t res_deauth_sta;
res_deauth_sta = esp_wifi_deauth_sta(event->aid);/* deauth the sta*/
if(res_deauth_sta == ESP_OK){
ESP_LOGI(TAG,"deauth OK");
}
else{
ESP_LOGI(TAG,"deauth failed");
}

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

通过esp_wifi_deauth_sta()函数就可以将指定的STA剔除,从而断开其对AP的连接。

实验结果如下:

结果分析:每当station 在join(即加入)该AP时,就会触发对应的WIFI_EVENT_AP_STACONNECTED事件,而在该事件下,我们调用了对应的剔除函数esp_wifi_deauth_sta(),因此每当该STA接入,就会剔除它(提示deauth OK)。所以,上述代码会提示该STA不停的join、leave.

下图还给出了STA被不停剔除的串口输出:

该串口输出提示,该STA在连接的auth -> assoc阶段未成功,因此,提示STA_DISCONNECTED,即STA连接不到AP。

3.参考资料与WLAN的基础扫盲链接:

1.esp8266 AP模式下剔除station https://blog.csdn.net/u013550000/article/details/89407724

2.[填坑]ESP32修改softap IP地址后WiFi信号丢失问题 https://blog.csdn.net/qq_20515461/article/details/102816663

3.非常好的WLAN、WiFi基础知识讲解资源:https://forum.huawei.com/enterprise/zh/forum.php?mod=collection&action=view&ctid=61

  • 9
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
ESP32是一款低功耗的Wi-Fi和蓝牙双模模块,具有强大的处理能力和丰富的外设接口。它可以作为一个Web服务器,同时支持AP(Access Point)和STAStation)模式。 在AP模式下,ESP32可以创建一个独立的Wi-Fi网络,其他设备可以连接到该网络并与ESP32进行通信。这种模式适用于需要ESP32作为主机设备提供网络服务的场景,比如智能家居控制心或者物联网网关。 在STA模式下,ESP32可以连接到一个已存在的Wi-Fi网络,并作为一个客户端设备与其他服务器进行通信。这种模式适用于需要ESP32作为客户端设备获取网络资源或者与云服务器进行数据交互的场景。 在Web服务器方面,ESP32可以通过使用ESPAsyncWebServer库来实现。该库提供了简单易用的API,可以帮助我们快速搭建一个基于ESP32的Web服务器。我们可以通过编写代码来定义不同的路由和处理函数,实现对不同URL请求的响应。 在AP模式下,我们可以设置ESP32IP地址、SSID和密码,并创建一个Web服务器来处理客户端的请求。客户端可以通过浏览器访问ESP32IP地址,并与其进行交互。 在STA模式下,我们可以将ESP32连接到一个已存在的Wi-Fi网络,并通过Web服务器提供不同的服务。客户端可以通过浏览器访问ESP32IP地址,与其进行通信。 总结一下,ESP32作为一个Web服务器可以在AP模式下创建一个独立的Wi-Fi网络,或者在STA模式下连接到一个已存在的Wi-Fi网络,并通过使用ESPAsyncWebServer库来实现对不同URL请求的响应。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

物联网老王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值