ESP32 在混杂模式和 STA 模式之间切换
ESP32 Switch Between Promiscuous and STA Mode
我正在做一个基于 ESP32 平台的项目。目的是计算该地区 MAC 地址的数量,并通过 WiFi 传输此信息(使用 http POST 请求)。
第一个任务是通过嗅探 WIFI 数据包并收集包含的地址来实现的,如下例所示:https://blog.podkalicki.com/esp32-wifi-sniffer/
我相信 "sniffs" 数据包的代码在混杂模式下将 ESP 设置为 运行,因此我无法再连接到任何 AP。
我尝试了几种解决方案,首先从定时器中断开始。然而,这种方法总是会导致 Core Panic 和芯片复位。
我还了解到我可以使用 RTOS 在 CPU 的两个内核上并行 运行 不同的任务,但这对解决问题没有帮助。
void wifi_sniffer_packet_handler(void* buff, wifi_promiscuous_pkt_type_t type)
{
if (type != WIFI_PKT_MGMT)//aggiungere filtro su RSSI a questa altezza.
return;
const wifi_promiscuous_pkt_t *ppkt = (wifi_promiscuous_pkt_t *)buff;
const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)ppkt->payload;
const wifi_ieee80211_mac_hdr_t *hdr = &ipkt->hdr;
//some analysis and then print the MAC address
}
void setup() {
Serial.begin(115200);
timer = timerBegin(0, 80, true);
timerAttachInterrupt(timer, &chUpdate, true);
timerAlarmWrite(timer, 1000000, true);//timer, arr_val, reload=true
delay(4000);
wifi_sniffer_init();
timerAlarmEnable(timer);
}
// the loop function runs over and over again forever
void loop() {
//Serial.print("inside loop");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Establishing connection to WiFi..");
}
Serial.println("Connected to network");
}
我还注意到循环中的代码卡在了 while 中,并且每次数据包处理程序 运行 时都会重新启动(我从来没有看到 "Connected to network",但我看到 "Establishing connection to WiFi.."几次。
谁能给我解释一下这是怎么回事?有没有不同的方法来实现这个结果?
谢谢。
你可能有两个任务和两个内核,但 ESP32 仍然只有一个 wifi 芯片。您编写代码的方式(至少,您共享的代码),您将在尝试 运行 混杂模式的同时尝试连接到 wifi 网络。您一次只能做其中一件事情。
在尝试连接到接入点之前,您需要停止混杂模式。现在您的代码不断尝试连接到 wifi 接入点。使用 volatile
变量来存储当前模式 - 混杂或连接。当你需要改变状态时改变它。仅当变量显示您想要处于连接模式时才尝试连接到 wifi。
在连接到 wifi 接入点之前,您可能需要一些代码 运行 在更改状态时关闭混杂模式。
如果您使用链接到的示例中的 wifi_sniffer_init()
,则该代码在 Arduino Core 应用程序中并不意味着 运行。它会执行 Arduino Core 也会执行的一些网络初始化。这样做两次可能不安全(可能有效,也可能无效……但绝对不打算那样做)。
您正在设置一个您没有共享的中断句柄 chUpdate()
。我敢打赌这就是您的核心恐慌的原因。您可以在中断处理程序中做很少的事情。您绝对不能调用大多数 Arduino Core 函数或大多数 ESP-IDF 函数。大多数代码都没有针对中断进行保护,因此当数据结构处于不一致状态时可能会发生定时器中断。 Re-entering 代码可能会破坏数据结构并导致您描述的那种崩溃。你最好设置一个 volatile
变量并唤醒一个任务来完成你需要完成的工作,而不是在中断处理程序中。
最后,您应该在调用 WiFi.begin()
之前调用 WiFi.mode(WIFI_STA);
。
对于任何对为什么在混杂模式下无法连接到 wifi 网络感到困惑的人 - ESP8266 和 ESP32 调用 "promiscuous mode" 实际上是 "wifi monitor mode",它可以让您监控 wifi 无线电频道并查看其上发送的所有 wifi 帧。他们使用的术语 "promiscuous mode" 与业内其他人不同。通常 "promiscuous mode" 表示看到所有在您连接的网络(wifi 或硬连线)上发送的数据包。
我知道已经过去一年多了,但多亏了 romkey 提供的信息,我想我通过在连接到 WiFi 上传 MAC 数据之前调用此例程解决了我的应用程序中的这个问题。
void end_Scan_WiFi() {
esp_wifi_set_promiscuous(false);
esp_wifi_stop();
}
接着是这个...
WiFi.mode(WIFI_STA);
WiFi.begin(ssid,pass);
我正在做一个基于 ESP32 平台的项目。目的是计算该地区 MAC 地址的数量,并通过 WiFi 传输此信息(使用 http POST 请求)。
第一个任务是通过嗅探 WIFI 数据包并收集包含的地址来实现的,如下例所示:https://blog.podkalicki.com/esp32-wifi-sniffer/ 我相信 "sniffs" 数据包的代码在混杂模式下将 ESP 设置为 运行,因此我无法再连接到任何 AP。
我尝试了几种解决方案,首先从定时器中断开始。然而,这种方法总是会导致 Core Panic 和芯片复位。 我还了解到我可以使用 RTOS 在 CPU 的两个内核上并行 运行 不同的任务,但这对解决问题没有帮助。
void wifi_sniffer_packet_handler(void* buff, wifi_promiscuous_pkt_type_t type)
{
if (type != WIFI_PKT_MGMT)//aggiungere filtro su RSSI a questa altezza.
return;
const wifi_promiscuous_pkt_t *ppkt = (wifi_promiscuous_pkt_t *)buff;
const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)ppkt->payload;
const wifi_ieee80211_mac_hdr_t *hdr = &ipkt->hdr;
//some analysis and then print the MAC address
}
void setup() {
Serial.begin(115200);
timer = timerBegin(0, 80, true);
timerAttachInterrupt(timer, &chUpdate, true);
timerAlarmWrite(timer, 1000000, true);//timer, arr_val, reload=true
delay(4000);
wifi_sniffer_init();
timerAlarmEnable(timer);
}
// the loop function runs over and over again forever
void loop() {
//Serial.print("inside loop");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Establishing connection to WiFi..");
}
Serial.println("Connected to network");
}
我还注意到循环中的代码卡在了 while 中,并且每次数据包处理程序 运行 时都会重新启动(我从来没有看到 "Connected to network",但我看到 "Establishing connection to WiFi.."几次。
谁能给我解释一下这是怎么回事?有没有不同的方法来实现这个结果? 谢谢。
你可能有两个任务和两个内核,但 ESP32 仍然只有一个 wifi 芯片。您编写代码的方式(至少,您共享的代码),您将在尝试 运行 混杂模式的同时尝试连接到 wifi 网络。您一次只能做其中一件事情。
在尝试连接到接入点之前,您需要停止混杂模式。现在您的代码不断尝试连接到 wifi 接入点。使用 volatile
变量来存储当前模式 - 混杂或连接。当你需要改变状态时改变它。仅当变量显示您想要处于连接模式时才尝试连接到 wifi。
在连接到 wifi 接入点之前,您可能需要一些代码 运行 在更改状态时关闭混杂模式。
如果您使用链接到的示例中的 wifi_sniffer_init()
,则该代码在 Arduino Core 应用程序中并不意味着 运行。它会执行 Arduino Core 也会执行的一些网络初始化。这样做两次可能不安全(可能有效,也可能无效……但绝对不打算那样做)。
您正在设置一个您没有共享的中断句柄 chUpdate()
。我敢打赌这就是您的核心恐慌的原因。您可以在中断处理程序中做很少的事情。您绝对不能调用大多数 Arduino Core 函数或大多数 ESP-IDF 函数。大多数代码都没有针对中断进行保护,因此当数据结构处于不一致状态时可能会发生定时器中断。 Re-entering 代码可能会破坏数据结构并导致您描述的那种崩溃。你最好设置一个 volatile
变量并唤醒一个任务来完成你需要完成的工作,而不是在中断处理程序中。
最后,您应该在调用 WiFi.begin()
之前调用 WiFi.mode(WIFI_STA);
。
对于任何对为什么在混杂模式下无法连接到 wifi 网络感到困惑的人 - ESP8266 和 ESP32 调用 "promiscuous mode" 实际上是 "wifi monitor mode",它可以让您监控 wifi 无线电频道并查看其上发送的所有 wifi 帧。他们使用的术语 "promiscuous mode" 与业内其他人不同。通常 "promiscuous mode" 表示看到所有在您连接的网络(wifi 或硬连线)上发送的数据包。
我知道已经过去一年多了,但多亏了 romkey 提供的信息,我想我通过在连接到 WiFi 上传 MAC 数据之前调用此例程解决了我的应用程序中的这个问题。
void end_Scan_WiFi() {
esp_wifi_set_promiscuous(false);
esp_wifi_stop();
}
接着是这个...
WiFi.mode(WIFI_STA);
WiFi.begin(ssid,pass);