ESP32发送Beacon帧

WiFi广播包(WiFi Beacon或Probe Request)是一种更普遍的广播方式,适用于所有支持WiFi的设备。

实现步骤:
  1. 设置ESP32为WiFi接入点(AP):配置ESP32为WiFi接入点(AP模式),这可以让周围的设备扫描到ESP32的SSID。
  2. 自定义Beacon包:修改ESP32的WiFi Beacon帧,在其数据字段中嵌入你想广播的自定义信息。
  3. 周期性发送Beacon帧:让ESP32定期发送包含数据的WiFi Beacon帧,周围的设备无需连接到ESP32的网络,也可以通过扫描获得这些广播数据。

这种方式不需要目标设备专门支持ESP-NOW,所有支持WiFi的设备都可以接收到这些广播数据。

使用WiFi广播包(如Beacon帧或Probe Request帧)在ESP32上发送自定义数据,需要深入操作ESP32的WiFi底层接口。虽然ESP-IDF原生支持对这些帧的操作,但Arduino框架中并没有直接提供修改WiFi Beacon帧的功能。

不过,你可以使用ESP32的ESP-IDF框架来修改WiFi Beacon帧,下面是一个使用ESP-IDF的示例,展示如何自定义并发送WiFi Beacon帧:

示例代码(自定义WiFi Beacon帧 - ESP-IDF):

#include "esp_wifi.h"
#include "esp_event.h"
#include "nvs_flash.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"

static const char *TAG = "beacon_broadcast";

// 定义自定义Beacon帧
uint8_t beacon_raw[] = {
    0x80, 0x00,                         // 帧控制字段(Frame Control)
    0x00, 0x00,                         // 持续时间(Duration)
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 广播地址(Broadcast Address)
    0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, // 源地址(Source Address)
    0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, // BSSID
    0x00, 0x00,                         // 序列控制字段
    0x00, 0x00,                         // 时间戳
    0x64, 0x00,                         // Beacon间隔(Beacon Interval)
    0x31, 0x04,                         // 能力信息字段
    0x00, 0x06, 'E', 'S', 'P', '3', '2', // SSID字段
    0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, // 支持的数据速率
    0x03, 0x01, 0x01                     // 当前通道
};

void send_beacon_task(void *pvParameter) {
    while (true) {
        esp_wifi_80211_tx(WIFI_IF_AP, beacon_raw, sizeof(beacon_raw), false);
        ESP_LOGI(TAG, "Beacon帧已发送");
        vTaskDelay(pdMS_TO_TICKS(100)); // 每100ms发送一次
    }
}

void app_main(void) {
    // 初始化NVS(用于存储WiFi配置)
    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
    ESP_ERROR_CHECK(esp_netif_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_wifi_set_mode(WIFI_MODE_AP)); // 设置为AP模式
    ESP_ERROR_CHECK(esp_wifi_start());

    // 创建发送Beacon帧的任务
    xTaskCreate(&send_beacon_task, "send_beacon_task", 4096, NULL, 5, NULL);
}

代码解析:

  1. 自定义Beacon帧beacon_raw数组中存储了WiFi Beacon帧的数据,你可以根据需要修改SSID和其他字段。
  2. Beacon发送任务send_beacon_task是一个FreeRTOS任务,它不断调用esp_wifi_80211_tx()函数来发送自定义的Beacon帧。这里使用WIFI_IF_AP接口将帧广播出去。
  3. 初始化WiFi:通过esp_wifi_init()和相关配置,将ESP32设置为WiFi接入点(AP模式),以便能够发送Beacon帧。

编译和运行:

  1. 你需要使用ESP-IDF进行开发,确保已经安装并配置好开发环境。
  2. 将上述代码放入main.c文件中,然后使用idf.py buildidf.py flash命令编译并烧录到ESP32中。

注意事项:

  • 帧格式:WiFi帧格式必须符合802.11标准,你可以根据需要修改Beacon帧中的字段,如SSID、自定义信息等。
  • 频率控制:不要频繁发送Beacon帧,以免影响其他设备的正常通信,通常Beacon帧的发送间隔为100ms左右。

这种方法能让附近的所有支持WiFi的设备通过扫描SSID看到你的自定义信息。

在WiFi Beacon帧中,自定义数据可以放置在帧的**可选信息元素(Information Element, IE)**部分。这些信息元素是灵活的字段,用于传递额外信息。你可以在SSID字段后添加一个自定义的IE来携带自己的数据。

WiFi Beacon帧结构概述:

WiFi Beacon帧的基本结构包含以下部分:

  1. MAC头:包含帧控制、持续时间、目的地址、源地址、BSSID等信息。
  2. 固定参数
    • 时间戳
    • Beacon间隔
    • 能力信息
  3. 可选信息元素(IEs):这里包括SSID、支持的数据速率、当前通道等。

你可以在这些信息元素之后加入你自己的自定义IE,格式为:

  • Tag Number(1字节):标识该IE的类型,取值范围0-255。你可以使用一个未被标准定义使用的数值(如221,用于厂商自定义的IE)。
  • Tag Length(1字节):自定义数据的长度。
  • Tag Value(可变长度):实际的数据内容。

示例:在Beacon帧中插入自定义数据

在前面示例代码的基础上,修改Beacon帧,插入自定义数据。假设你想插入"Hello"这段字符串作为自定义数据:

自定义IE格式:
  • Tag Number: 0xDD(221,表示厂商自定义IE)
  • Tag Length: 5("Hello"字符串的长度)
  • Tag Value: 5字节的"Hello"字符串(0x48 0x65 0x6C 0x6C 0x6F)

修改后的示例代码:

#include "esp_wifi.h"
#include "esp_event.h"
#include "nvs_flash.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"

static const char *TAG = "beacon_broadcast";

// 定义自定义Beacon帧,插入自定义数据 "Hello"
uint8_t beacon_raw[] = {
    0x80, 0x00,                         // 帧控制字段(Frame Control)
    0x00, 0x00,                         // 持续时间(Duration)
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 广播地址(Broadcast Address)
    0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, // 源地址(Source Address)
    0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, // BSSID
    0x00, 0x00,                         // 序列控制字段
    0x00, 0x00,                         // 时间戳
    0x64, 0x00,                         // Beacon间隔(Beacon Interval)
    0x31, 0x04,                         // 能力信息字段
    0x00, 0x06, 'E', 'S', 'P', '3', '2', // SSID字段
    0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, // 支持的数据速率
    0x03, 0x01, 0x01,                   // 当前通道

    // 自定义信息元素(IE): "Hello"
    0xDD,                               // Tag Number (厂商自定义IE)
    0x05,                               // Tag Length (5字节数据)
    0x48, 0x65, 0x6C, 0x6C, 0x6F        // 自定义数据 "Hello"
};

void send_beacon_task(void *pvParameter) {
    while (true) {
        // 发送自定义Beacon帧
        esp_wifi_80211_tx(WIFI_IF_AP, beacon_raw, sizeof(beacon_raw), false);
        ESP_LOGI(TAG, "Beacon帧已发送");
        vTaskDelay(pdMS_TO_TICKS(100)); // 每100ms发送一次
    }
}

void app_main(void) {
    // 初始化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
    ESP_ERROR_CHECK(esp_netif_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_wifi_set_mode(WIFI_MODE_AP)); // 设置为AP模式
    ESP_ERROR_CHECK(esp_wifi_start());

    // 创建发送Beacon帧的任务
    xTaskCreate(&send_beacon_task, "send_beacon_task", 4096, NULL, 5, NULL);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

laocui1

你的鼓励是我创作的最大动了

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

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

打赏作者

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

抵扣说明:

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

余额充值