toy-Kapi_Rtc/main/bluetooth_provisioning.cc
2026-01-20 16:55:17 +08:00

1178 lines
47 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @file bluetooth_provisioning.cc
* @brief BluFi蓝牙配网模块实现文件
*
* 本文件实现了BluFi蓝牙配网的核心功能包括
* - 蓝牙控制器和协议栈的初始化与管理
* - BluFi服务的启动、停止和事件处理
* - WiFi凭据的接收、验证和连接管理
* - 配网状态机的管理和事件回调
* - WiFi连接状态的监控和报告
* - 配网成功后的自动保存和重启机制
*
* 该实现基于ESP-IDF的BluFi API提供了完整的蓝牙配网解决方案。
*/
#include "bluetooth_provisioning.h"
#include "esp_log.h"
#include "esp_bt.h"
#include "esp_bt_main.h"
#include "esp_bt_device.h"
#include "esp_gap_ble_api.h"
#include "esp_blufi.h"
#include "esp_blufi_api.h"
#include "esp_wifi.h"
#include "esp_netif.h"
#include "freertos/event_groups.h"
#include "freertos/timers.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "application.h"
#include "assets/lang_config.h"
#include <ssid_manager.h>
#include "nvs_flash.h"
#include "nvs.h"
#include <cstring>
/// 日志标签用于ESP_LOG系列函数的日志输出
#define TAG "BluetoothProvisioning"
/// WiFi连接成功事件位
#define WIFI_CONNECTED_BIT BIT0
/// WiFi连接失败事件位
#define WIFI_FAIL_BIT BIT1
/// 静态单例实例指针用于C回调函数访问类成员
BluetoothProvisioning* BluetoothProvisioning::instance_ = nullptr;
/// WiFi事件组句柄用于同步WiFi连接状态
static EventGroupHandle_t s_wifi_event_group = nullptr;
/// WiFi连接重试计数器
static int s_retry_num = 0;
/// 最大重试次数
static const int MAX_RETRY = 2;//Wi-Fi连接最大重试次数(wifi连接失败最大重试次数)
/// WiFi连接超时时间毫秒
static const int WIFI_CONNECT_TIMEOUT_MS = 30000; // 增强从15秒延长到30秒
/// WiFi连接超时定时器句柄
static TimerHandle_t wifi_connect_timer = nullptr;
/**
* @brief BLUFI回调函数配置结构体
*
* 配置BluFi服务的各种回调函数包括事件处理、数据协商、
* 加密解密和校验等功能。当前实现仅使用事件回调。
*/
static esp_blufi_callbacks_t blufi_callbacks = {
.event_cb = BluetoothProvisioning::BlufiEventCallback, ///< 事件回调函数
.negotiate_data_handler = nullptr, ///< 数据协商处理器(可选)
.encrypt_func = nullptr, ///< 加密函数(可选)
.decrypt_func = nullptr, ///< 解密函数(可选)
.checksum_func = nullptr, ///< 校验函数(可选)
};
/**
* @brief 构造函数
*
* 初始化蓝牙配网对象的所有成员变量,设置初始状态,
* 清空WiFi凭据并设置静态实例指针用于回调函数访问。
*/
BluetoothProvisioning::BluetoothProvisioning()
: state_(BluetoothProvisioningState::IDLE) ///< 初始状态为空闲
, callback_(nullptr) ///< 回调函数指针初始化为空
, client_connected_(false) ///< 客户端连接状态初始化为未连接
, initialized_(false) ///< 初始化状态标志为未初始化
, delayed_disconnect_(false) ///< 延迟断开标志初始化为false
, wifi_connecting_(false) ///< WiFi连接状态标志初始化为false
, mac_address_sent_(false) { ///< MAC地址发送状态初始化为未发送
// 清空WiFi凭据结构体
wifi_credentials_.ssid.clear();
wifi_credentials_.password.clear();
memset(wifi_credentials_.bssid, 0, sizeof(wifi_credentials_.bssid));
wifi_credentials_.bssid_set = false;
// 设置静态实例指针用于C风格回调函数访问类成员
instance_ = this;
ESP_LOGI(TAG, "蓝牙配网对象创建完成");
}
/**
* @brief 析构函数
*
* 清理蓝牙配网对象的所有资源,包括停止配网服务、
* 释放蓝牙资源、清空静态实例指针等。
*/
BluetoothProvisioning::~BluetoothProvisioning() {
// 确保资源被正确释放,如果已初始化则进行反初始化
if (initialized_) {
Deinitialize();
}
// 清空静态实例指针
instance_ = nullptr;
ESP_LOGI(TAG, "蓝牙配网对象销毁完成");
}
/**
* @brief 初始化蓝牙配网功能
*
* 按顺序初始化以下组件:
* 1. WiFi模块STA模式
* 2. 蓝牙控制器
* 3. Bluedroid协议栈
* 4. BluFi服务和回调
* 5. WiFi事件处理器
*
* @return true 初始化成功false 初始化失败
*/
bool BluetoothProvisioning::Initialize() {
if (initialized_) {
ESP_LOGW(TAG, "蓝牙配网已经初始化");
return true;
}
SetState(BluetoothProvisioningState::INITIALIZING);
esp_err_t ret;
// 步骤1: 初始化WiFi模块
ESP_LOGI(TAG, "初始化WiFi...");
// 创建默认WiFi STA网络接口
esp_netif_create_default_wifi_sta();
// 使用默认配置初始化WiFi
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ret = esp_wifi_init(&cfg);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "WiFi初始化失败: %s", esp_err_to_name(ret));
SetState(BluetoothProvisioningState::FAILED);
return false;
}
// 设置WiFi工作模式为STAStation模式
ret = esp_wifi_set_mode(WIFI_MODE_STA);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "WiFi模式设置失败: %s", esp_err_to_name(ret));
SetState(BluetoothProvisioningState::FAILED);
return false;
}
// 启动WiFi服务
ret = esp_wifi_start();
if (ret != ESP_OK) {
ESP_LOGE(TAG, "WiFi启动失败: %s", esp_err_to_name(ret));
SetState(BluetoothProvisioningState::FAILED);
return false;
}
ESP_LOGI(TAG, "WiFi初始化完成");
ESP_LOGI(TAG, "初始化蓝牙控制器...");
esp_bt_controller_status_t ctl_status = esp_bt_controller_get_status();
#if CONFIG_IDF_TARGET_ESP32
ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));
#else
esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
#endif
if (ctl_status == ESP_BT_CONTROLLER_STATUS_ENABLED) {
esp_bt_controller_disable();
ctl_status = esp_bt_controller_get_status();
}
if (ctl_status == ESP_BT_CONTROLLER_STATUS_INITED) {
esp_bt_controller_deinit();
}
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
ret = esp_bt_controller_init(&bt_cfg);
if (ret != ESP_OK && ret != ESP_ERR_INVALID_STATE) {
ESP_LOGE(TAG, "蓝牙控制器初始化失败: %s", esp_err_to_name(ret));
SetState(BluetoothProvisioningState::FAILED);
return false;
}
ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
if (ret != ESP_OK && ret != ESP_ERR_INVALID_STATE) {
ESP_LOGE(TAG, "蓝牙控制器启用失败: %s", esp_err_to_name(ret));
SetState(BluetoothProvisioningState::FAILED);
return false;
}
ESP_LOGI(TAG, "初始化Bluedroid协议栈...");
auto bd_status = esp_bluedroid_get_status();
if (bd_status == ESP_BLUEDROID_STATUS_ENABLED) {
esp_bluedroid_disable();
bd_status = esp_bluedroid_get_status();
}
if (bd_status == ESP_BLUEDROID_STATUS_INITIALIZED) {
esp_bluedroid_deinit();
}
ret = esp_bluedroid_init();
if (ret != ESP_OK && ret != ESP_ERR_INVALID_STATE) {
ESP_LOGE(TAG, "Bluedroid初始化失败: %s", esp_err_to_name(ret));
SetState(BluetoothProvisioningState::FAILED);
return false;
}
ret = esp_bluedroid_enable();
if (ret != ESP_OK && ret != ESP_ERR_INVALID_STATE) {
ESP_LOGE(TAG, "Bluedroid启用失败: %s", esp_err_to_name(ret));
SetState(BluetoothProvisioningState::FAILED);
return false;
}
// 注意设备名称将在StartProvisioning中设置
ESP_LOGI(TAG, "蓝牙初始化完成,设备名称将在启动配网时设置");
// 步骤4: 注册BluFi服务和回调函数
ESP_LOGI(TAG, "注册BLUFI回调函数...");
// 注册BluFi事件回调函数
ret = esp_blufi_register_callbacks(&blufi_callbacks);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "BLUFI回调注册失败: %s", esp_err_to_name(ret));
SetState(BluetoothProvisioningState::FAILED);
return false;
}
// 注册BLE GAPGeneric Access Profile事件处理器
ret = esp_ble_gap_register_callback(esp_blufi_gap_event_handler);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "BLE GAP事件处理器注册失败: %s", esp_err_to_name(ret));
SetState(BluetoothProvisioningState::FAILED);
return false;
}
ret = esp_blufi_profile_init();
if (ret != ESP_OK && ret != ESP_ERR_INVALID_STATE) {
ESP_LOGE(TAG, "BLUFI配置文件初始化失败: %s", esp_err_to_name(ret));
SetState(BluetoothProvisioningState::FAILED);
return false;
}
// 步骤5: 创建WiFi事件同步机制
if (s_wifi_event_group == nullptr) {
s_wifi_event_group = xEventGroupCreate();
if (s_wifi_event_group == nullptr) {
ESP_LOGE(TAG, "WiFi事件组创建失败");
SetState(BluetoothProvisioningState::FAILED);
return false;
}
}
// 步骤6: 注册WiFi和IP事件处理器
ESP_LOGI(TAG, "注册WiFi事件处理器...");
// 注册WiFi事件处理器监听所有WiFi相关事件
ret = esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &WiFiEventHandler, this);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "WiFi事件处理器注册失败: %s", esp_err_to_name(ret));
SetState(BluetoothProvisioningState::FAILED);
return false;
}
// 注册IP事件处理器监听IP地址获取事件
ret = esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &IPEventHandler, this);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "IP事件处理器注册失败: %s", esp_err_to_name(ret));
SetState(BluetoothProvisioningState::FAILED);
return false;
}
// 标记初始化完成,设置状态为空闲
initialized_ = true;
SetState(BluetoothProvisioningState::IDLE);
ESP_LOGI(TAG, "蓝牙配网初始化完成");
ESP_LOGI(TAG, "蓝牙MAC地址: " ESP_BD_ADDR_STR, ESP_BD_ADDR_HEX(esp_bt_dev_get_address()));
return true;
}
/**
* @brief 反初始化蓝牙配网功能
*
* 按相反顺序清理所有初始化的组件和资源:
* 1. 停止配网服务
* 2. 注销事件处理器
* 3. 销毁WiFi事件组
* 4. 反初始化BluFi服务
* 5. 反初始化Bluedroid协议栈
* 6. 反初始化蓝牙控制器
*
* @return true 反初始化成功false 反初始化失败
*/
bool BluetoothProvisioning::Deinitialize() {
if (!initialized_) {
ESP_LOGW(TAG, "蓝牙配网未初始化");
return true;
}
ESP_LOGI(TAG, "开始反初始化蓝牙配网...");
// 步骤1: 停止配网服务(如果正在运行)
if (state_ != BluetoothProvisioningState::IDLE &&
state_ != BluetoothProvisioningState::STOPPED) {
StopProvisioning();
}
// 步骤2: 注销事件处理器
esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &WiFiEventHandler);
esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &IPEventHandler);
// 步骤3: 销毁WiFi事件同步机制
if (s_wifi_event_group != nullptr) {
vEventGroupDelete(s_wifi_event_group);
s_wifi_event_group = nullptr;
}
// 步骤4: 反初始化BluFi服务
esp_blufi_profile_deinit();
// 步骤5: 反初始化Bluedroid协议栈
esp_bluedroid_disable();
esp_bluedroid_deinit();
// 步骤6: 反初始化蓝牙控制器
esp_bt_controller_disable();
esp_bt_controller_deinit();
// 标记为未初始化状态
initialized_ = false;
SetState(BluetoothProvisioningState::STOPPED);
ESP_LOGI(TAG, "蓝牙配网反初始化完成");
return true;
}
// 开始配网
bool BluetoothProvisioning::StartProvisioning(const char* device_name) {
ESP_LOGI(TAG, "🔵 开始启动BluFi配网服务...");
ESP_LOGI(TAG, "🔍 检查初始化状态: initialized_ = %s", initialized_ ? "true" : "false");
if (!initialized_) {
ESP_LOGE(TAG, "❌ 蓝牙配网未初始化,无法启动");
return false;
}
if (state_ == BluetoothProvisioningState::ADVERTISING ||
state_ == BluetoothProvisioningState::CONNECTED ||
state_ == BluetoothProvisioningState::PROVISIONING) {
ESP_LOGW(TAG, "⚠️ 蓝牙配网已在运行中");
return true;
}
ESP_LOGI(TAG, "🚀 开始蓝牙配网,设备名称: %s", device_name);
// 重置状态
client_connected_ = false;
s_retry_num = 0;
// 重置MAC地址发送状态为新的配网会话做准备
ResetMacSendingState();
ESP_LOGI(TAG, "🔄 MAC地址发送状态已重置");
// 清空之前的WiFi凭据
ESP_LOGI(TAG, "🧹 清除之前的WiFi凭据...");
if (!wifi_credentials_.ssid.empty()) {
ESP_LOGI(TAG, "🗑️ 删除已保存的SSID: %s", wifi_credentials_.ssid.c_str());
}
if (!wifi_credentials_.password.empty()) {
ESP_LOGI(TAG, "🗑️ 删除已保存的WiFi密码 (长度: %d)", wifi_credentials_.password.length());
}
wifi_credentials_.ssid.clear();
wifi_credentials_.password.clear();
wifi_credentials_.bssid_set = false;
ESP_LOGI(TAG, "✅ WiFi凭据清除完成准备接收新的配网信息");
// 开始BLUFI广播
esp_blufi_adv_start();
ESP_LOGI(TAG, "BLUFI广播已启动");
// // 配置自定义广播数据包以确保设备名称正确显示(改蓝牙名称 必备操作)
// //=====================================================================================================
// esp_ble_adv_data_t adv_data = {};
// adv_data.set_scan_rsp = false;
// adv_data.include_name = true; // 包含设备名称
// adv_data.include_txpower = true;
// adv_data.min_interval = 0x0006;
// adv_data.max_interval = 0x0010;
// adv_data.appearance = 0x00;
// // 添加厂商特定数据
// static uint8_t manufacturer_data[] = {0xFF, 0xFF, 0x00, 0x00}; // ESP厂商ID
// adv_data.manufacturer_len = sizeof(manufacturer_data);
// adv_data.p_manufacturer_data = manufacturer_data;
// adv_data.service_data_len = 0;
// adv_data.p_service_data = NULL;
// // 添加BluFi服务UUID确保ESP官方APP能够识别
// // UUID: 0000FFFF-0000-1000-8000-00805F9B34FB (小端序)
// static uint8_t blufi_service_uuid128[16] = {
// 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x10,
// 0x00, 0x80, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb
// };
// adv_data.service_uuid_len = sizeof(blufi_service_uuid128);
// adv_data.p_service_uuid = blufi_service_uuid128;
// adv_data.flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT);
// //===================================================
// // 重新设置设备名称并配置广播数据
// esp_err_t ret = esp_ble_gap_set_device_name(device_name);
// if (ret != ESP_OK) {
// ESP_LOGE(TAG, "❌ 设置蓝牙设备名称失败: %s", esp_err_to_name(ret));
// return false;
// }
// ret = esp_ble_gap_config_adv_data(&adv_data);
// if (ret != ESP_OK) {
// ESP_LOGE(TAG, "❌ 配置广播数据失败: %s", esp_err_to_name(ret));
// return false;
// }
// // 配置广播参数(按官方示例设置)
// //==================================================
// esp_ble_adv_params_t adv_params = {};
// adv_params.adv_int_min = 0x100; // 100ms间隔
// adv_params.adv_int_max = 0x100; // 100ms间隔
// adv_params.adv_type = ADV_TYPE_IND;
// adv_params.own_addr_type = BLE_ADDR_TYPE_PUBLIC;
// adv_params.channel_map = ADV_CHNL_ALL;
// adv_params.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY;
// // 配置完所有广播数据后再启动广播
// //==================================================
// ret = esp_ble_gap_start_advertising(&adv_params);
// if (ret != ESP_OK) {
// ESP_LOGE(TAG, "❌ 启动广播失败: %s", esp_err_to_name(ret));
// return false;
// }
// ESP_LOGI(TAG, "✅ 蓝牙设备名称和广播数据配置成功: %s", device_name);
// //=====================================================================================================
SetState(BluetoothProvisioningState::ADVERTISING);// 设置蓝牙状态为广播中
ESP_LOGI(TAG, "蓝牙配网广播已启动,等待客户端连接...");
return true;
}
// 停止蓝牙配网
bool BluetoothProvisioning::StopProvisioning() {
if (state_ == BluetoothProvisioningState::IDLE ||
state_ == BluetoothProvisioningState::STOPPED) {
ESP_LOGW(TAG, "蓝牙配网未在运行");
return true;
}
ESP_LOGI(TAG, "停止蓝牙配网...");
// 停止BLUFI广播
esp_blufi_adv_stop();
// 如果有客户端连接,断开连接
if (client_connected_) {
esp_blufi_disconnect();
}
SetState(BluetoothProvisioningState::IDLE);
ESP_LOGI(TAG, "蓝牙配网已停止");
return true;
}
// 向客户端/小程序 报告WiFi连接状态
void BluetoothProvisioning::ReportWiFiStatus(bool success, uint8_t reason) {
ESP_LOGI(TAG, "🔍 [DEBUG] ReportWiFiStatus调用: success=%s, client_connected_=%s",
success ? "true" : "false", client_connected_ ? "true" : "false");
if (!client_connected_) {
ESP_LOGW(TAG, "客户端未连接无法发送WiFi状态");
return;
}
wifi_mode_t mode;
esp_wifi_get_mode(&mode);//获取当前WiFi模式
if (success) {
ESP_LOGI(TAG, "向客户端报告设备连接WiFi成功!");
esp_err_t ret = esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONN_SUCCESS, 0, nullptr);
ESP_LOGI(TAG, "🔍 [DEBUG] WiFi成功报告发送结果: %s", esp_err_to_name(ret));
} else {
ESP_LOGI(TAG, "向客户端报告连接WiFi失败原因: %d", reason);
esp_blufi_extra_info_t info;
memset(&info, 0, sizeof(info));
info.sta_conn_end_reason_set = true;
info.sta_conn_end_reason = reason;
esp_err_t ret = esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONN_FAIL, 0, &info);
ESP_LOGI(TAG, "🔍 [DEBUG] WiFi失败报告发送结果: %s", esp_err_to_name(ret));
}
}
// 将WI-FI扫描列表 发送给客户端Wi-Fi扫描
void BluetoothProvisioning::SendWiFiList(const wifi_ap_record_t* ap_list, uint16_t ap_count) {
if (!client_connected_) {
ESP_LOGW(TAG, "客户端未连接无法发送WiFi列表");
return;
}
if (ap_list == nullptr || ap_count == 0) {
ESP_LOGW(TAG, "WiFi列表为空");
return;
}
// 转换为BLUFI格式
esp_blufi_ap_record_t* blufi_ap_list = new esp_blufi_ap_record_t[ap_count];
if (blufi_ap_list == nullptr) {
ESP_LOGE(TAG, "内存分配失败");
return;
}
for (uint16_t i = 0; i < ap_count; i++) {
blufi_ap_list[i].rssi = ap_list[i].rssi;
memcpy(blufi_ap_list[i].ssid, ap_list[i].ssid, sizeof(ap_list[i].ssid));
}
ESP_LOGI(TAG, "向客户端发送WiFi列表共%d个AP", ap_count);
esp_blufi_send_wifi_list(ap_count, blufi_ap_list);
delete[] blufi_ap_list;
}
bool BluetoothProvisioning::SendMacAddressReliably() {
// 第一重检查:基本连接状态
if (!client_connected_) {
ESP_LOGW(TAG, "客户端未连接无法发送MAC地址");
return false;
}
// 获取设备MAC地址
uint8_t mac[6];
esp_err_t ret = esp_wifi_get_mac(WIFI_IF_STA, mac);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "获取MAC地址失败: %s", esp_err_to_name(ret));
return false;
}
// 格式化MAC地址字符串
char mac_str[18];
snprintf(mac_str, sizeof(mac_str), "%02X:%02X:%02X:%02X:%02X:%02X",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
// 检查是否已经发送过MAC地址WiFi MAC地址不会因重启而变化
if (mac_address_sent_) {
ESP_LOGI(TAG, "MAC地址已发送过跳过重复发送: %s", mac_str);
return true;
}
ESP_LOGI(TAG, "开始可靠发送MAC地址: %s", mac_str);
// 多次重试发送机制
const int MAX_SEND_ATTEMPTS = 3;
const int RETRY_DELAY_MS = 50;
for (int attempt = 1; attempt <= MAX_SEND_ATTEMPTS; attempt++) {
// 第二重检查:发送前再次确认连接状态
if (!client_connected_) {
ESP_LOGW(TAG, "发送前检查发现客户端已断开连接 (尝试 %d/%d)", attempt, MAX_SEND_ATTEMPTS);
return false;
}
ESP_LOGI(TAG, "发送MAC地址尝试 %d/%d: %s", attempt, MAX_SEND_ATTEMPTS, mac_str);
// 创建包含MAC地址的自定义数据还原原有格式
char mac_data[32];
snprintf(mac_data, sizeof(mac_data), "STA_MAC:%02x:%02x:%02x:%02x:%02x:%02x",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
// 发送带前缀的MAC地址数据
ret = esp_blufi_send_custom_data((uint8_t*)mac_data, strlen(mac_data));
if (ret == ESP_OK) {
ESP_LOGI(TAG, "✅ MAC地址发送成功 (尝试 %d/%d): %s", attempt, MAX_SEND_ATTEMPTS, mac_str);
// 记录发送状态
mac_address_sent_ = true;
// 发送成功后的确认延迟
vTaskDelay(pdMS_TO_TICKS(100));
// 第三重检查:发送后确认连接仍然有效
if (client_connected_) {
ESP_LOGI(TAG, "MAC地址发送完成连接状态正常");
return true;
} else {
ESP_LOGW(TAG, "MAC地址发送后检测到连接断开");
return false;
}
} else {
ESP_LOGW(TAG, "❌ MAC地址发送失败 (尝试 %d/%d): %s, 错误: %s",
attempt, MAX_SEND_ATTEMPTS, mac_str, esp_err_to_name(ret));
// 如果不是最后一次尝试,等待后重试
if (attempt < MAX_SEND_ATTEMPTS) {
vTaskDelay(pdMS_TO_TICKS(RETRY_DELAY_MS));
}
}
}
ESP_LOGE(TAG, "MAC地址发送失败已达到最大重试次数: %s", mac_str);
return false;
}
void BluetoothProvisioning::ResetMacSendingState() {
mac_address_sent_ = false;
ESP_LOGI(TAG, "MAC地址发送状态已重置");
}
void BluetoothProvisioning::SetState(BluetoothProvisioningState new_state) {
if (state_ != new_state) {
BluetoothProvisioningState old_state = state_;
state_ = new_state;
const char* state_names[] = {
"IDLE", "INITIALIZING", "ADVERTISING", "CONNECTED",
"PROVISIONING", "SUCCESS", "FAILED", "STOPPED"
};
ESP_LOGI(TAG, "🔄 BluFi状态变化: %s -> %s",
state_names[static_cast<int>(old_state)],
state_names[static_cast<int>(new_state)]);
TriggerCallback(BluetoothProvisioningEvent::STATE_CHANGED, nullptr);
}
}
void BluetoothProvisioning::TriggerCallback(BluetoothProvisioningEvent event, void* data) {
if (callback_) {
callback_(event, data);
}
}
std::string BluetoothProvisioning::GetStateString() const {
const char* state_names[] = {
"IDLE", "INITIALIZING", "ADVERTISING", "CONNECTED",
"PROVISIONING", "SUCCESS", "FAILED", "STOPPED"
};
return std::string(state_names[static_cast<int>(state_)]);
}
// BLUFI事件回调函数
void BluetoothProvisioning::BlufiEventCallback(esp_blufi_cb_event_t event, esp_blufi_cb_param_t* param) {
if (instance_ == nullptr) {
ESP_LOGE(TAG, "实例指针为空");
return;
}
// 打印事件详细信息
const char* event_name = "UNKNOWN";
switch (event) {
case ESP_BLUFI_EVENT_INIT_FINISH: event_name = "INIT_FINISH"; break;
case ESP_BLUFI_EVENT_DEINIT_FINISH: event_name = "DEINIT_FINISH"; break;
case ESP_BLUFI_EVENT_BLE_CONNECT: event_name = "BLE_CONNECT"; break;
case ESP_BLUFI_EVENT_BLE_DISCONNECT: event_name = "BLE_DISCONNECT"; break;
case ESP_BLUFI_EVENT_RECV_CUSTOM_DATA: event_name = "RECV_CUSTOM_DATA"; break;
case ESP_BLUFI_EVENT_RECV_STA_SSID: event_name = "RECV_STA_SSID"; break;
case ESP_BLUFI_EVENT_RECV_STA_PASSWD: event_name = "RECV_STA_PASSWD"; break;
case ESP_BLUFI_EVENT_GET_WIFI_LIST: event_name = "GET_WIFI_LIST"; break;
default: break;
}
// 打印事件参数
ESP_LOGI(TAG, "🔔 BluFi事件回调: %d (%s), param=%p", event, event_name, param);
switch (event) {
case ESP_BLUFI_EVENT_INIT_FINISH:
ESP_LOGI(TAG, "✅ BLUFI初始化完成");
break;
case ESP_BLUFI_EVENT_DEINIT_FINISH:
ESP_LOGI(TAG, "BLUFI反初始化完成");
break;
// 客户端连接事件
case ESP_BLUFI_EVENT_BLE_CONNECT:
ESP_LOGI(TAG, "📱 BluFi客户端已连接");//GATT连接成功建立
ESP_LOGI(TAG, "🔍 [DEBUG] 设置client_connected_为true");
instance_->client_connected_ = true;//GATT连接成功建立标志位设置为true
// 重置MAC地址发送状态为新的配网会话做准备
instance_->ResetMacSendingState();
ESP_LOGI(TAG, "🔄 MAC地址发送状态已重置");
instance_->SetState(BluetoothProvisioningState::CONNECTED); //GATT连接成功建立状态设置为CONNECTED
instance_->TriggerCallback(BluetoothProvisioningEvent::CLIENT_CONNECTED, nullptr);//回调通知,通知上层应用有客户端连接
// // 在Wi-Fi连接前向客户端发送Mac地址
// // 🆕 在BluFi客户端连接成功后立即发送MAC地址
// ESP_LOGI(TAG, "📡 BluFi客户端连接成功立即发送设备MAC地址");
// if (instance_->SendMacAddressReliably()) {
// ESP_LOGI(TAG, "✅ BluFi连接后MAC地址发送成功");
// } else {
// ESP_LOGW(TAG, "⚠️ BluFi连接后MAC地址发送失败将在Wi-Fi连接成功后重试");
// }
// 停止广播
esp_blufi_adv_stop();
ESP_LOGI(TAG, "🔍 [DEBUG] BLE连接处理完成client_connected_=%s",
instance_->client_connected_ ? "true" : "false");
break;
// 客户端断开连接事件
case ESP_BLUFI_EVENT_BLE_DISCONNECT:
ESP_LOGI(TAG, "📱 BluFi客户端已断开连接当前状态: %s",
instance_->GetStateString().c_str());
ESP_LOGI(TAG, "🔍 [DEBUG] 设置client_connected_为false");
instance_->client_connected_ = false;
// 如果正在配网过程中延迟处理断开事件给WiFi连接更多时间
if (instance_->state_ == BluetoothProvisioningState::PROVISIONING) {
ESP_LOGW(TAG, "⚠️ 配网过程中BLE断开延迟5秒后处理以等待WiFi连接完成");
// 设置一个标志,延迟处理断开
instance_->delayed_disconnect_ = true;
// 创建延迟任务
xTaskCreate([](void* param) {
vTaskDelay(pdMS_TO_TICKS(2000)); // 缩短延迟到2秒
BluetoothProvisioning* self = static_cast<BluetoothProvisioning*>(param);
if (self->delayed_disconnect_) {
if (self->state_ == BluetoothProvisioningState::PROVISIONING && self->wifi_connecting_) {
ESP_LOGW(TAG, "⏰ BLE延迟断开但WiFi仍在连接中继续等待");
// WiFi仍在连接不断开BLE让WiFi超时定时器处理
} else if (self->state_ == BluetoothProvisioningState::PROVISIONING) {
ESP_LOGW(TAG, "⏰ 延迟处理BLE断开WiFi连接可能已超时");
self->SetState(BluetoothProvisioningState::ADVERTISING);
self->TriggerCallback(BluetoothProvisioningEvent::CLIENT_DISCONNECTED, nullptr);
esp_blufi_adv_start();
}
self->delayed_disconnect_ = false;
}
vTaskDelete(nullptr);
}, "delayed_disconnect", 2048, instance_, 1, nullptr);
} else {
instance_->SetState(BluetoothProvisioningState::ADVERTISING);
instance_->TriggerCallback(BluetoothProvisioningEvent::CLIENT_DISCONNECTED, nullptr);
// 重新开始广播
esp_blufi_adv_start();
}
break;
// 设置WiFi模式
case ESP_BLUFI_EVENT_SET_WIFI_OPMODE:
ESP_LOGI(TAG, "设置WiFi模式: %d", param->wifi_mode.op_mode);
esp_wifi_set_mode(param->wifi_mode.op_mode);
break;
// 请求连接到AP Wi-Fi
case ESP_BLUFI_EVENT_REQ_CONNECT_TO_AP:
ESP_LOGI(TAG, "📡 请求连接到APSSID: %s", instance_->wifi_credentials_.ssid.c_str());
ESP_LOGI(TAG, "🔍 [DEBUG] 当前状态: %s, client_connected_: %s",
instance_->GetStateString().c_str(),
instance_->client_connected_ ? "true" : "false");
instance_->SetState(BluetoothProvisioningState::PROVISIONING);
instance_->delayed_disconnect_ = false; // 重置延迟断开标志
s_retry_num = 0; // 重置重试计数
ESP_LOGI(TAG, "🔄 重置WiFi重试计数开始连接流程");
// 断开当前WiFi连接如果有
esp_wifi_disconnect();
vTaskDelay(pdMS_TO_TICKS(100)); // 短暂延迟确保断开完成
// 连接到新的AP
esp_wifi_connect();//连接到新的 Wi-Fi
ESP_LOGI(TAG, "🚀 已发起WiFi连接请求");
break;
// 请求断开AP连接
case ESP_BLUFI_EVENT_REQ_DISCONNECT_FROM_AP:
ESP_LOGI(TAG, "请求断开AP连接");
esp_wifi_disconnect();//断开当前连接的AP
break;
// 接收到WI-FI的 SSID
case ESP_BLUFI_EVENT_RECV_STA_SSID:
ESP_LOGI(TAG, "📶 收到WiFi SSID: %.*s", param->sta_ssid.ssid_len, param->sta_ssid.ssid);
instance_->wifi_credentials_.ssid.assign(
reinterpret_cast<const char*>(param->sta_ssid.ssid),
param->sta_ssid.ssid_len);//保存Wi-Fi的 SSID
// 设置WiFi配置
{
wifi_config_t wifi_config = {};
strncpy(reinterpret_cast<char*>(wifi_config.sta.ssid),
instance_->wifi_credentials_.ssid.c_str(),
sizeof(wifi_config.sta.ssid) - 1);
esp_wifi_set_config(WIFI_IF_STA, &wifi_config);//设置WiFi配置
}
break;
// 接收到WI-FI的 密码
case ESP_BLUFI_EVENT_RECV_STA_PASSWD:
ESP_LOGI(TAG, "🔐 收到WiFi密码 (长度: %d)", param->sta_passwd.passwd_len);
instance_->wifi_credentials_.password.assign(
reinterpret_cast<const char*>(param->sta_passwd.passwd),
param->sta_passwd.passwd_len);// 保存WI-FI密码凭证
// 设置WiFi配置
{
wifi_config_t wifi_config = {};
strncpy(reinterpret_cast<char*>(wifi_config.sta.ssid),
instance_->wifi_credentials_.ssid.c_str(),
sizeof(wifi_config.sta.ssid) - 1);
strncpy(reinterpret_cast<char*>(wifi_config.sta.password),
instance_->wifi_credentials_.password.c_str(),
sizeof(wifi_config.sta.password) - 1);
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));//设置WiFi配置
}
// 重置重试计数器
s_retry_num = 0;
instance_->wifi_connecting_ = true;
// 启动WiFi连接超时定时器
if (wifi_connect_timer) {
xTimerStop(wifi_connect_timer, 0);
xTimerDelete(wifi_connect_timer, 0);
}
wifi_connect_timer = xTimerCreate("wifi_timeout",
pdMS_TO_TICKS(WIFI_CONNECT_TIMEOUT_MS),
pdFALSE, nullptr,
[](TimerHandle_t timer) {
ESP_LOGW(TAG, "⏰ WiFi连接超时强制失败处理");
if (instance_ && instance_->wifi_connecting_) {
instance_->wifi_connecting_ = false;
instance_->delayed_disconnect_ = false;
instance_->SetState(BluetoothProvisioningState::FAILED);
instance_->TriggerCallback(BluetoothProvisioningEvent::WIFI_FAILED, nullptr);
instance_->ReportWiFiStatus(false, WIFI_REASON_UNSPECIFIED);
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
}
});
xTimerStart(wifi_connect_timer, 0);
esp_wifi_connect(); // 核心连接函数连接到WiFi
ESP_LOGI(TAG, "📡 已发起WiFi连接请求启动15秒超时监控");
instance_->TriggerCallback(BluetoothProvisioningEvent::WIFI_CREDENTIALS,
&instance_->wifi_credentials_);
break;
// 接收到WI-FI的 BSSID 特定接入点MAC地址
case ESP_BLUFI_EVENT_RECV_STA_BSSID:
ESP_LOGI(TAG, "收到BSSID");
memcpy(instance_->wifi_credentials_.bssid, param->sta_bssid.bssid, 6);
instance_->wifi_credentials_.bssid_set = true;// 标记BSSID已设置
// 设置WiFi配置
{
wifi_config_t wifi_config = {};
strncpy(reinterpret_cast<char*>(wifi_config.sta.ssid),
instance_->wifi_credentials_.ssid.c_str(),
sizeof(wifi_config.sta.ssid) - 1);// 复制SSID到配置
strncpy(reinterpret_cast<char*>(wifi_config.sta.password),
instance_->wifi_credentials_.password.c_str(),
sizeof(wifi_config.sta.password) - 1);// 复制密码到配置
memcpy(wifi_config.sta.bssid, instance_->wifi_credentials_.bssid, 6);
wifi_config.sta.bssid_set = true;
esp_wifi_set_config(WIFI_IF_STA, &wifi_config);//设置WiFi配置
}
break;
// 客户端请求WiFi状态
case ESP_BLUFI_EVENT_GET_WIFI_STATUS:
ESP_LOGI(TAG, "客户端请求WiFi状态");
// 这里可以发送当前WiFi状态
break;
// 新增代码
//========================================================================
// 客户端请求WiFi列表
case ESP_BLUFI_EVENT_GET_WIFI_LIST:
ESP_LOGI(TAG, "📱 手机APP请求获取WiFi列表开始扫描周围WiFi网络");
// 启动WiFi扫描
{
wifi_scan_config_t scan_config = {};
scan_config.ssid = nullptr; // 扫描所有SSID
scan_config.bssid = nullptr; // 扫描所有BSSID
scan_config.channel = 0; // 扫描所有信道
scan_config.show_hidden = true; // 显示隐藏网络
scan_config.scan_type = WIFI_SCAN_TYPE_ACTIVE;
scan_config.scan_time.active.min = 100;
scan_config.scan_time.active.max = 300;
esp_err_t ret = esp_wifi_scan_start(&scan_config, false);
if (ret == ESP_OK) {
ESP_LOGI(TAG, "🔍 WiFi扫描已启动等待扫描结果");
} else {
ESP_LOGE(TAG, "❌ WiFi扫描启动失败: %s", esp_err_to_name(ret));
}
}
break;
//========================================================================
// 客户端请求断开BLE连接
case ESP_BLUFI_EVENT_RECV_SLAVE_DISCONNECT_BLE:
ESP_LOGI(TAG, "收到断开BLE连接请求");
esp_blufi_disconnect();
break;
default:
ESP_LOGD(TAG, "未处理的BLUFI事件: %d", event);
break;
}
}
// 处理WiFi事件
void BluetoothProvisioning::WiFiEventHandler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data) {
BluetoothProvisioning* self = static_cast<BluetoothProvisioning*>(arg);
if (event_base == WIFI_EVENT) {
switch (event_id) {
case WIFI_EVENT_STA_START:
ESP_LOGI(TAG, "WiFi STA启动");
break;
case WIFI_EVENT_STA_CONNECTED: {
wifi_event_sta_connected_t* event = static_cast<wifi_event_sta_connected_t*>(event_data);
ESP_LOGI(TAG, "✅ WiFi连接成功SSID: %.*s等待获取IP地址", event->ssid_len, event->ssid);
// 停止WiFi连接超时定时器
if (wifi_connect_timer) {
xTimerStop(wifi_connect_timer, 0);
}
// 清除连接状态标志
self->wifi_connecting_ = false;
self->delayed_disconnect_ = false;
break;
}
case WIFI_EVENT_STA_DISCONNECTED: {
wifi_event_sta_disconnected_t* event = static_cast<wifi_event_sta_disconnected_t*>(event_data);
ESP_LOGI(TAG, "WiFi断开连接原因: %d", event->reason);
// 如果不是在配网状态,不处理断开事件
if (self->state_ != BluetoothProvisioningState::PROVISIONING) {
ESP_LOGD(TAG, "非配网状态下的WiFi断开忽略处理");
break;
}
if (s_retry_num < MAX_RETRY) {
// 立即重试连接,不等待
esp_err_t ret = esp_wifi_connect();//连接到WiFi
s_retry_num++;
ESP_LOGI(TAG, "🔄 立即重试连接WiFi (%d/%d),断开原因: %d重试结果: %s",
s_retry_num, MAX_RETRY, event->reason,
ret == ESP_OK ? "成功" : "失败");
// 重新启动超时定时器
if (wifi_connect_timer && ret == ESP_OK) {
xTimerReset(wifi_connect_timer, 0);
}
} else {
ESP_LOGE(TAG, "❌ WiFi连接失败已达到最大重试次数断开原因: %d", event->reason);
// 停止超时定时器
if (wifi_connect_timer) {
xTimerStop(wifi_connect_timer, 0);
}
// 清除状态标志
self->wifi_connecting_ = false;
self->delayed_disconnect_ = false;
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
self->SetState(BluetoothProvisioningState::FAILED);
self->TriggerCallback(BluetoothProvisioningEvent::WIFI_FAILED, &event->reason);
self->ReportWiFiStatus(false, event->reason);
}
break;
}
// 新增代码
//========================================================================
case WIFI_EVENT_SCAN_DONE: {
ESP_LOGI(TAG, "📡 WiFi扫描完成准备发送WiFi列表给手机APP");
// 获取扫描结果
uint16_t ap_count = 0;
esp_err_t ret = esp_wifi_scan_get_ap_num(&ap_count);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "❌ 获取WiFi扫描结果数量失败: %s", esp_err_to_name(ret));
break;
}
ESP_LOGI(TAG, "📊 扫描到 %d 个WiFi热点", ap_count);
if (ap_count > 0) {
// 分配内存存储扫描结果
wifi_ap_record_t* ap_list = (wifi_ap_record_t*)malloc(sizeof(wifi_ap_record_t) * ap_count);
if (ap_list == nullptr) {
ESP_LOGE(TAG, "❌ 分配WiFi扫描结果内存失败");
break;
}
// 获取扫描结果详细信息
ret = esp_wifi_scan_get_ap_records(&ap_count, ap_list);
if (ret == ESP_OK) {
ESP_LOGI(TAG, "✅ 成功获取WiFi扫描结果准备发送给手机APP");
// 打印扫描到的WiFi列表调试用
for (int i = 0; i < ap_count; i++) {
ESP_LOGD(TAG, "WiFi[%d]: SSID=%s, RSSI=%d, 加密=%d",
i, ap_list[i].ssid, ap_list[i].rssi, ap_list[i].authmode);
}
// 发送WiFi列表给手机APP
self->SendWiFiList(ap_list, ap_count);
ESP_LOGI(TAG, "📤 WiFi列表已发送给手机APP包含 %d 个热点", ap_count);
} else {
ESP_LOGE(TAG, "❌ 获取WiFi扫描结果详细信息失败: %s", esp_err_to_name(ret));
}
// 释放内存
free(ap_list);
} else {
ESP_LOGW(TAG, "⚠️ 未扫描到任何WiFi热点");
// 发送空列表
self->SendWiFiList(nullptr, 0);
}
break;
}
//========================================================================
default:
break;
}
}
}
void BluetoothProvisioning::IPEventHandler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data) {
BluetoothProvisioning* self = static_cast<BluetoothProvisioning*>(arg);
switch (event_id) {
case IP_EVENT_STA_GOT_IP: {
ip_event_got_ip_t* event = static_cast<ip_event_got_ip_t*>(event_data);
ESP_LOGI(TAG, "✅ WiFi获取IP地址成功: " IPSTR, IP2STR(&event->ip_info.ip));
s_retry_num = 0;
// 停止WiFi连接超时定时器
if (wifi_connect_timer) {
xTimerStop(wifi_connect_timer, 0);
xTimerDelete(wifi_connect_timer, 0);
wifi_connect_timer = nullptr;
}
// 清除状态标志
self->wifi_connecting_ = false;
self->delayed_disconnect_ = false;
// 设置WiFi连接成功标志
if (s_wifi_event_group) {
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
}
// 如果BluFi客户端已连接发送WiFi连接成功报告
ESP_LOGI(TAG, "🔍 [DEBUG] 检查BluFi客户端连接状态: client_connected_=%s",
self->client_connected_ ? "true" : "false");
if (self && self->client_connected_) {
// ==================================================================================
// 使用专用的可靠MAC地址发送函数优化版本2
ESP_LOGI(TAG, "🔍 [DEBUG] 使用专用函数发送设备MAC地址...");
bool mac_sent = self->SendMacAddressReliably();
if (mac_sent) {
ESP_LOGI(TAG, "✅ 设备MAC地址发送成功");
} else {
ESP_LOGW(TAG, "⚠️ 设备MAC地址发送失败");
}
// ==================================================================================
// ==================================================================================
// 注释由于只需要发送设备MAC地址暂时注释掉WiFi连接报告相关代码
// 这样可以避免发送不必要的信息如SSID等
// ==================================================================================
/*
ESP_LOGI(TAG, "🔍 [DEBUG] 准备发送WiFi连接成功报告给手机APP");
wifi_mode_t mode;
esp_wifi_get_mode(&mode);
esp_blufi_extra_info_t info;
memset(&info, 0, sizeof(esp_blufi_extra_info_t));
// 获取当前连接的WiFi信息
wifi_ap_record_t ap_info;
if (esp_wifi_sta_get_ap_info(&ap_info) == ESP_OK) {
// memcpy(info.sta_bssid, ap_info.bssid, 6); // 发送路由器MAC地址
// info.sta_bssid_set = true; // 设置BSSID已获取
info.sta_bssid_set = false; // 明确标记不发送BSSID
info.sta_ssid = ap_info.ssid;
info.sta_ssid_len = strlen((char*)ap_info.ssid);
// ESP_LOGI(TAG, "🔍 [DEBUG] 获取到WiFi信息: SSID=%.*s",info.sta_ssid_len, info.sta_ssid);
}
// 发送WiFi连接成功报告
esp_err_t ret = esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONN_SUCCESS, 0, &info);
if (ret == ESP_OK) {
ESP_LOGI(TAG, "✅ 已向手机APP发送WiFi连接成功报告");
} else {
ESP_LOGW(TAG, "⚠️ 发送WiFi连接成功报告失败: %s", esp_err_to_name(ret));
}
*/
ESP_LOGI(TAG, "🔍 [DEBUG] 已跳过WiFi连接报告发送仅发送设备MAC地址");
} else {
ESP_LOGW(TAG, "🔍 [DEBUG] 无法发送WiFi连接成功报告: client_connected_=%s",
self->client_connected_ ? "true" : "false");
}
// 启用WiFi配置自动保存到NVS存储
ESP_LOGI(TAG, "💾 启用WiFi配置自动保存到NVS存储...");
esp_err_t storage_ret = esp_wifi_set_storage(WIFI_STORAGE_FLASH);// 设置WiFi存储模式为FLASH
if (storage_ret == ESP_OK) {
ESP_LOGI(TAG, "✅ WiFi配置将自动保存到NVS存储");
} else {
ESP_LOGW(TAG, "⚠️ 设置WiFi存储模式失败: %s", esp_err_to_name(storage_ret));
}
// 手动获取当前WiFi配置并保存到NVS列表
wifi_config_t wifi_config;// 定义WiFi配置结构体
esp_err_t get_config_ret = esp_wifi_get_config(WIFI_IF_STA, &wifi_config);// 获取当前WiFi配置
if (get_config_ret == ESP_OK) {
ESP_LOGI(TAG, "📋 获取当前WiFi配置成功SSID: %s", wifi_config.sta.ssid);
auto& ssid_manager = SsidManager::GetInstance();
ssid_manager.AddSsid((const char*)wifi_config.sta.ssid, (const char*)wifi_config.sta.password);
ESP_LOGI(TAG, "✅ WiFi凭据已保存到NVS列表");
} else {
ESP_LOGW(TAG, "⚠️ 获取当前WiFi配置失败: %s", esp_err_to_name(get_config_ret));
}
auto& application = Application::GetInstance();
bool skip_session = application.ShouldSkipDialogIdleSession();// 是否跳过对话待机会话
ESP_LOGI(TAG, "BluetoothProvisioning WIFI_CONNECTED skip_session=%d", (int)skip_session);
if (!skip_session) {
if(strcmp(CONFIG_DEVICE_ROLE, "KAKA") == 0){
application.PlaySound(Lang::Sounds::P3_KAKA_LIANJIEWANGLUO);
}
else if(strcmp(CONFIG_DEVICE_ROLE, "RTC_Test") == 0){
application.PlaySound(Lang::Sounds::P3_LALA_LIANJIEWANGLUO);
}
} else {
application.ClearDialogIdleSkipSession();// 清除对话待机会话标志位
}
// 更新状态和触发回调
ESP_LOGI(TAG, "🔍 准备设置状态为SUCCESS并触发回调");
self->SetState(BluetoothProvisioningState::SUCCESS);
self->TriggerCallback(BluetoothProvisioningEvent::WIFI_CONNECTED, &event->ip_info.ip);
self->ReportWiFiStatus(true, 0);
ESP_LOGI(TAG, "📋 配网流程完成,状态: %s, client_connected_: %s",
self->GetStateString().c_str(),
self->client_connected_ ? "true" : "false");
// 延迟2000ms后强制重启设备
ESP_LOGI(TAG, "⏰ 延迟2000ms后重启设备以确保配置生效...");
vTaskDelay(pdMS_TO_TICKS(2000));// 配网成功后,设备重启会自动连接到新的WiFi网络
ESP_LOGI(TAG, "🔄 强制重启设备...");
esp_restart();
break;
}
default:
break;
}
}