Fixed compilation errors that occurred after enabling blufi (#1677)

This commit is contained in:
Wang is proud
2026-01-24 21:55:24 +08:00
committed by GitHub
parent 6b3659c2f5
commit 3a52761d30
5 changed files with 207 additions and 64 deletions

View File

@ -8,13 +8,13 @@ BluFi
- 需要支持 BLE 的芯片与固件配置。 - 需要支持 BLE 的芯片与固件配置。
-`idf.py menuconfig` 中启用 `WiFi Configuration Method -> Esp Blufi``CONFIG_USE_ESP_BLUFI_WIFI_PROVISIONING=y` -`idf.py menuconfig` 中启用 `WiFi Configuration Method -> Esp Blufi``CONFIG_USE_ESP_BLUFI_WIFI_PROVISIONING=y`
)。如果想用 BluFi关闭同一菜单下的 Hotspot/Acoustic 选项。 )。如果想使用 BluFi必须关闭同一菜单下的 Hotspot 选项,否则默认使用 Hotspot 配网模式
- 保持默认的 NVS 与事件循环初始化(项目的 `app_main` 已处理)。 - 保持默认的 NVS 与事件循环初始化(项目的 `app_main` 已处理)。
- CONFIG_BT_BLUEDROID_ENABLED、CONFIG_BT_NIMBLE_ENABLED这两个宏应二选一不能同时启用。 - CONFIG_BT_BLUEDROID_ENABLED、CONFIG_BT_NIMBLE_ENABLED这两个宏应二选一不能同时启用。
## 工作流程 ## 工作流程
1) 手机端通过 BluFi如官方 EspBlufi App 或自研客户端)连接设备,发送 WiFi SSID/密码。 1) 手机端通过 BluFi如官方 EspBlufi App 或自研客户端)连接设备,发送 WiFi SSID/密码手机端可以通过blufi协议获取设备端扫描到的WiFi列表
2) 设备侧在 `ESP_BLUFI_EVENT_REQ_CONNECT_TO_AP` 中将凭据写入 `SsidManager`(存储到 NVS属于 `esp-wifi-connect` 组件)。 2) 设备侧在 `ESP_BLUFI_EVENT_REQ_CONNECT_TO_AP` 中将凭据写入 `SsidManager`(存储到 NVS属于 `esp-wifi-connect` 组件)。
3) 随后启动 `WifiStation` 扫描并连接;状态通过 BluFi 返回。 3) 随后启动 `WifiStation` 扫描并连接;状态通过 BluFi 返回。
4) 配网成功后设备会自动连接新 WiFi失败则返回失败状态。 4) 配网成功后设备会自动连接新 WiFi失败则返回失败状态。
@ -30,7 +30,7 @@ BluFi
## 注意事项 ## 注意事项
- BluFi 与 Hotspot/声波配网可以同时编译,但会同时启动,增加内存占用。建议在 menuconfig 中只保留一种方式。 - BluFi 配网不支持与热点配网同时开启。如果热点配网已经启动,则默认使用热点配网。请在 menuconfig 中只保留一种配网方式。
- 若多次测试,建议清除或覆盖存储的 SSID`wifi` 命名空间),避免旧配置干扰。 - 若多次测试,建议清除或覆盖存储的 SSID`wifi` 命名空间),避免旧配置干扰。
- 如果使用自定义 BluFi 客户端,需遵循官方协议帧格式,参考上文官方文档链接。 - 如果使用自定义 BluFi 客户端,需遵循官方协议帧格式,参考上文官方文档链接。
- 官方文档中已提供EspBlufi APP下载地址 - 官方文档中已提供EspBlufi APP下载地址

View File

@ -789,6 +789,7 @@ idf_component_register(SRCS ${SOURCES}
spi_flash spi_flash
console console
efuse efuse
bt
) )
# Use target_compile_definitions to define BOARD_TYPE, BOARD_NAME # Use target_compile_definitions to define BOARD_TYPE, BOARD_NAME

View File

@ -3,25 +3,21 @@
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
#include <string> #include <string>
#include <vector>
#include "application.h"
#include "esp_bt.h" #include "esp_bt.h"
#include "esp_event.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_mac.h" #include "esp_timer.h"
#include "esp_system.h"
#include "esp_wifi.h" #include "esp_wifi.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "wifi_manager.h" #include "wifi_manager.h"
// Bluedroid specific
#ifdef CONFIG_BT_BLUEDROID_ENABLED #ifdef CONFIG_BT_BLUEDROID_ENABLED
#include "esp_bt_device.h" #include "esp_bt_device.h"
#include "esp_bt_main.h" #include "esp_bt_main.h"
#include "esp_gap_ble_api.h" #include "esp_gap_ble_api.h"
#endif #endif
// NimBLE specific
#ifdef CONFIG_BT_NIMBLE_ENABLED #ifdef CONFIG_BT_NIMBLE_ENABLED
#include "console/console.h" #include "console/console.h"
#include "host/ble_hs.h" #include "host/ble_hs.h"
@ -36,22 +32,18 @@ extern void esp_blufi_btc_deinit(void);
#endif #endif
extern "C" { extern "C" {
// Blufi Advertising & Connection
void esp_blufi_adv_start(void); void esp_blufi_adv_start(void);
void esp_blufi_adv_stop(void); void esp_blufi_adv_stop(void);
void esp_blufi_disconnect(void); void esp_blufi_disconnect(void);
// Internal BTC layer functions needed for error reporting
void btc_blufi_report_error(esp_blufi_error_state_t state); void btc_blufi_report_error(esp_blufi_error_state_t state);
// Bluedroid specific GAP event handler
#ifdef CONFIG_BT_BLUEDROID_ENABLED #ifdef CONFIG_BT_BLUEDROID_ENABLED
void esp_blufi_gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param); void esp_blufi_gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param);
#endif #endif
// NimBLE specific internal functions
#ifdef CONFIG_BT_NIMBLE_ENABLED #ifdef CONFIG_BT_NIMBLE_ENABLED
void esp_blufi_gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); void esp_blufi_gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg);
int esp_blufi_gatt_svr_init(void); int esp_blufi_gatt_svr_init(void);
@ -61,14 +53,12 @@ void esp_blufi_btc_deinit(void);
#endif #endif
} }
// mbedTLS for security
#include <wifi_station.h> #include <wifi_station.h>
#include "esp_crc.h" #include "esp_crc.h"
#include "esp_random.h" #include "esp_random.h"
#include "mbedtls/md5.h" #include "mbedtls/md5.h"
#include "ssid_manager.h" #include "ssid_manager.h"
// Logging Tag
static const char *BLUFI_TAG = "BLUFI_CLASS"; static const char *BLUFI_TAG = "BLUFI_CLASS";
static wifi_mode_t GetWifiModeWithFallback(const WifiManager &wifi) { static wifi_mode_t GetWifiModeWithFallback(const WifiManager &wifi) {
@ -98,9 +88,7 @@ Blufi::Blufi()
m_deinited(false), m_deinited(false),
m_sta_ssid_len(0), m_sta_ssid_len(0),
m_sta_is_connecting(false) { m_sta_is_connecting(false) {
// Initialize member variables
memset(&m_sta_config, 0, sizeof(m_sta_config)); memset(&m_sta_config, 0, sizeof(m_sta_config));
memset(&m_ap_config, 0, sizeof(m_ap_config));
memset(m_sta_bssid, 0, sizeof(m_sta_bssid)); memset(m_sta_bssid, 0, sizeof(m_sta_bssid));
memset(m_sta_ssid, 0, sizeof(m_sta_ssid)); memset(m_sta_ssid, 0, sizeof(m_sta_ssid));
memset(&m_sta_conn_info, 0, sizeof(m_sta_conn_info)); memset(&m_sta_conn_info, 0, sizeof(m_sta_conn_info));
@ -113,11 +101,23 @@ Blufi::~Blufi() {
} }
esp_err_t Blufi::init() { esp_err_t Blufi::init() {
esp_err_t ret; esp_err_t ret = ESP_FAIL;
inited_ = true; inited_ = true;
m_provisioned = false; m_provisioned = false;
m_deinited = false; m_deinited = false;
// Start WiFi scan early to have results ready when user connects
auto &wifi_manager = WifiManager::GetInstance();
if (!wifi_manager.IsInitialized() || !wifi_manager.IsConfigMode()) {
// start scan immediately
start_wifi_scan();
} else {
ESP_LOGE(BLUFI_TAG,
"Blufi and WiFi hotspot network configuration cannot "
"be used simultaneously.");
return ret;
}
#if CONFIG_BT_CONTROLLER_ENABLED || !CONFIG_BT_NIMBLE_ENABLED #if CONFIG_BT_CONTROLLER_ENABLED || !CONFIG_BT_NIMBLE_ENABLED
ret = _controller_init(); ret = _controller_init();
if (ret) { if (ret) {
@ -236,26 +236,20 @@ void Blufi::_nimble_on_reset(int reason) {
ESP_LOGE(BLUFI_TAG, "NimBLE Resetting state; reason=%d", reason); ESP_LOGE(BLUFI_TAG, "NimBLE Resetting state; reason=%d", reason);
} }
void Blufi::_nimble_on_sync() { void Blufi::_nimble_on_sync() { esp_blufi_profile_init(); }
// This is called when the host and controller are synced.
// It's a good place to initialize the Blufi profile.
esp_blufi_profile_init();
}
void Blufi::_nimble_host_task(void *param) { void Blufi::_nimble_host_task(void *param) {
ESP_LOGI(BLUFI_TAG, "BLE Host Task Started"); ESP_LOGI(BLUFI_TAG, "BLE Host Task Started");
nimble_port_run(); // This function will return only when nimble_port_stop() is executed nimble_port_run();
nimble_port_freertos_deinit(); nimble_port_freertos_deinit();
} }
esp_err_t Blufi::_host_init() { esp_err_t Blufi::_host_init() {
// esp_nimble_init() is called by controller_init for NimBLE
ble_hs_cfg.reset_cb = _nimble_on_reset; ble_hs_cfg.reset_cb = _nimble_on_reset;
ble_hs_cfg.sync_cb = _nimble_on_sync; ble_hs_cfg.sync_cb = _nimble_on_sync;
ble_hs_cfg.gatts_register_cb = esp_blufi_gatt_svr_register_cb; ble_hs_cfg.gatts_register_cb = esp_blufi_gatt_svr_register_cb;
// Security Manager settings (can be customized) ble_hs_cfg.sm_io_cap = 4;
ble_hs_cfg.sm_io_cap = 4; // IO capability: No Input, No Output
#ifdef CONFIG_EXAMPLE_BONDING #ifdef CONFIG_EXAMPLE_BONDING
ble_hs_cfg.sm_bonding = 1; ble_hs_cfg.sm_bonding = 1;
#endif #endif
@ -263,7 +257,7 @@ esp_err_t Blufi::_host_init() {
int rc = esp_blufi_gatt_svr_init(); int rc = esp_blufi_gatt_svr_init();
assert(rc == 0); assert(rc == 0);
ble_store_config_init(); // Configure the BLE storage ble_store_config_init();
esp_blufi_btc_init(); esp_blufi_btc_init();
esp_err_t err = esp_nimble_enable(_nimble_host_task); esp_err_t err = esp_nimble_enable(_nimble_host_task);
@ -285,9 +279,7 @@ esp_err_t Blufi::_host_deinit(void) {
return ret; return ret;
} }
esp_err_t Blufi::_gap_register_callback(void) { esp_err_t Blufi::_gap_register_callback(void) { return ESP_OK; }
return ESP_OK; // For NimBLE, GAP callbacks are handled differently
}
esp_err_t Blufi::_host_and_cb_init() { esp_err_t Blufi::_host_and_cb_init() {
static esp_blufi_callbacks_t blufi_callbacks = { static esp_blufi_callbacks_t blufi_callbacks = {
@ -329,7 +321,6 @@ esp_err_t Blufi::_controller_init() {
} }
#ifdef CONFIG_BT_NIMBLE_ENABLED #ifdef CONFIG_BT_NIMBLE_ENABLED
// For NimBLE, host init needs to be done after controller init
ret = esp_nimble_init(); ret = esp_nimble_init();
if (ret) { if (ret) {
ESP_LOGE(BLUFI_TAG, "esp_nimble_init() failed: %s", esp_err_to_name(ret)); ESP_LOGE(BLUFI_TAG, "esp_nimble_init() failed: %s", esp_err_to_name(ret));
@ -350,7 +341,7 @@ esp_err_t Blufi::_controller_deinit() {
} }
return ret; return ret;
} }
#endif // Generic controller init #endif
static int myrand(void *rng_state, unsigned char *output, size_t len) { static int myrand(void *rng_state, unsigned char *output, size_t len) {
esp_fill_random(output, len); esp_fill_random(output, len);
@ -404,7 +395,7 @@ void Blufi::_dh_negotiate_data_handler(uint8_t *data, int len, uint8_t **output_
uint8_t type = data[0]; uint8_t type = data[0];
switch (type) { switch (type) {
case 0x00: /* DH_PARAM_LEN */ case 0x00:
if (len < 3) { if (len < 3) {
ESP_LOGE(BLUFI_TAG, "DH_PARAM_LEN packet too short"); ESP_LOGE(BLUFI_TAG, "DH_PARAM_LEN packet too short");
btc_blufi_report_error(ESP_BLUFI_DATA_FORMAT_ERROR); btc_blufi_report_error(ESP_BLUFI_DATA_FORMAT_ERROR);
@ -422,7 +413,7 @@ void Blufi::_dh_negotiate_data_handler(uint8_t *data, int len, uint8_t **output_
btc_blufi_report_error(ESP_BLUFI_DH_MALLOC_ERROR); btc_blufi_report_error(ESP_BLUFI_DH_MALLOC_ERROR);
} }
break; break;
case 0x01: /* DH_PARAM_DATA */ { case 0x01: {
if (m_sec->dh_param == nullptr) { if (m_sec->dh_param == nullptr) {
ESP_LOGE(BLUFI_TAG, "DH param not allocated"); ESP_LOGE(BLUFI_TAG, "DH param not allocated");
btc_blufi_report_error(ESP_BLUFI_DH_PARAM_ERROR); btc_blufi_report_error(ESP_BLUFI_DH_PARAM_ERROR);
@ -540,6 +531,119 @@ int Blufi::_get_softap_conn_num() {
return 0; return 0;
} }
void Blufi::start_wifi_scan() {
ESP_LOGI(BLUFI_TAG, "Starting dedicated WiFi scan");
// Check if a scan is already in progress
if (m_scan_in_progress) {
ESP_LOGW(BLUFI_TAG, "Scan already in progress, skipping");
return;
}
m_scan_in_progress = true;
// Get current WiFi mode
wifi_mode_t current_mode;
esp_err_t err = esp_wifi_get_mode(&current_mode);
if (current_mode == WIFI_MODE_AP) {
// If in AP mode, temporarily switch to APSTA to allow scanning
ESP_LOGI(BLUFI_TAG, "WiFi in AP mode");
err = esp_wifi_set_mode(WIFI_MODE_STA);
if (err != ESP_OK) {
ESP_LOGE(BLUFI_TAG, "Failed to set WiFi mode to STA: %s", esp_err_to_name(err));
m_scan_in_progress = false;
return;
}
// Need to restart WiFi for mode change to take effect
err = esp_wifi_start();
if (err != ESP_OK) {
ESP_LOGE(BLUFI_TAG, "Failed to start WiFi after mode switch: %s", esp_err_to_name(err));
m_scan_in_progress = false;
return;
}
// Register scan event handler
esp_event_handler_instance_t scan_event_instance;
esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID,
&Blufi::_wifi_scan_event_handler, this,
&scan_event_instance);
// Start scan
err = esp_wifi_scan_start(NULL, false);
if (err != ESP_OK) {
ESP_LOGE(BLUFI_TAG, "Failed to start WiFi scan: %s", esp_err_to_name(err));
m_scan_in_progress = false;
return;
}
} else if (current_mode == WIFI_MODE_STA) {
// Start scan
err = esp_wifi_scan_start(NULL, false);
if (err != ESP_OK) {
ESP_LOGE(BLUFI_TAG, "Failed to start WiFi scan: %s", esp_err_to_name(err));
m_scan_in_progress = false;
return;
}
} else {
ESP_LOGE(BLUFI_TAG, "Unexpected WiFi mode: %d", current_mode);
m_scan_in_progress = false;
return;
}
ESP_LOGI(BLUFI_TAG, "WiFi scan started");
}
void Blufi::_send_wifi_list() {
if (m_ap_records.empty()) {
ESP_LOGW(BLUFI_TAG, "No AP records available to send");
return;
}
ESP_LOGI(BLUFI_TAG, "Sending WiFi list with %d APs", m_ap_records.size());
std::vector<esp_blufi_ap_record_t> blufi_ap_list;
for (const auto &ap : m_ap_records) {
esp_blufi_ap_record_t blufi_ap;
memset(&blufi_ap, 0, sizeof(blufi_ap));
memcpy(blufi_ap.ssid, ap.ssid, std::min((size_t)32, sizeof(ap.ssid)));
blufi_ap.rssi = ap.rssi;
blufi_ap_list.push_back(blufi_ap);
}
esp_blufi_send_wifi_list(blufi_ap_list.size(), blufi_ap_list.data());
m_ap_records.clear();
start_wifi_scan();
}
void Blufi::_wifi_scan_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id,
void *event_data) {
Blufi *self = static_cast<Blufi *>(arg);
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_SCAN_DONE) {
ESP_LOGI(BLUFI_TAG, "WiFi scan done");
uint16_t ap_num = 0;
esp_wifi_scan_get_ap_num(&ap_num);
if (ap_num == 0) {
ESP_LOGW(BLUFI_TAG, "No APs found");
self->m_ap_records.clear();
} else {
if (static_cast<Blufi *>(arg)->m_scan_should_save_ssid == true) {
self->m_ap_records.resize(ap_num);
esp_wifi_scan_get_ap_records(&ap_num, self->m_ap_records.data());
ESP_LOGI(BLUFI_TAG, "Found %d APs", ap_num);
for (const auto &ap : self->m_ap_records) {
ESP_LOGI(BLUFI_TAG, " SSID: %s, RSSI: %d, Authmode: %d", (char *)ap.ssid,
ap.rssi, ap.authmode);
}
}
}
self->m_scan_in_progress = false;
}
}
void Blufi::_handle_event(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *param) { void Blufi::_handle_event(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *param) {
switch (event) { switch (event) {
case ESP_BLUFI_EVENT_INIT_FINISH: case ESP_BLUFI_EVENT_INIT_FINISH:
@ -564,7 +668,6 @@ void Blufi::_handle_event(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *para
} else { } else {
esp_blufi_adv_stop(); esp_blufi_adv_stop();
if (!m_deinited) { if (!m_deinited) {
// Deinit BLE stack after provisioning completes to free resources.
xTaskCreate( xTaskCreate(
[](void *ctx) { [](void *ctx) {
static_cast<Blufi *>(ctx)->deinit(); static_cast<Blufi *>(ctx)->deinit();
@ -604,33 +707,42 @@ void Blufi::_handle_event(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *para
std::string ssid(reinterpret_cast<const char *>(m_sta_config.sta.ssid)); std::string ssid(reinterpret_cast<const char *>(m_sta_config.sta.ssid));
std::string password(reinterpret_cast<const char *>(m_sta_config.sta.password)); std::string password(reinterpret_cast<const char *>(m_sta_config.sta.password));
// Save credentials through SsidManager
SsidManager::GetInstance().AddSsid(ssid, password); SsidManager::GetInstance().AddSsid(ssid, password);
auto &wifi_manager = WifiManager::GetInstance(); m_scan_should_save_ssid = false;
if (!wifi_manager.IsInitialized() && !wifi_manager.Initialize()) {
ESP_LOGE(BLUFI_TAG, "Failed to initialize WifiManager");
break;
}
// Track SSID for BLUFI status reporting.
m_sta_ssid_len = static_cast<int>(std::min(ssid.size(), sizeof(m_sta_ssid))); m_sta_ssid_len = static_cast<int>(std::min(ssid.size(), sizeof(m_sta_ssid)));
memcpy(m_sta_ssid, ssid.c_str(), m_sta_ssid_len); memcpy(m_sta_ssid, ssid.c_str(), m_sta_ssid_len);
memset(m_sta_bssid, 0, sizeof(m_sta_bssid)); memset(m_sta_bssid, 0, sizeof(m_sta_bssid));
m_sta_connected = false; m_sta_connected = false;
m_sta_got_ip = false; m_sta_got_ip = false;
m_sta_is_connecting = true; m_sta_is_connecting = true;
m_sta_conn_info = {}; // Reset connection info m_sta_conn_info = {};
m_sta_conn_info.sta_ssid = m_sta_ssid; m_sta_conn_info.sta_ssid = m_sta_ssid;
m_sta_conn_info.sta_ssid_len = m_sta_ssid_len; m_sta_conn_info.sta_ssid_len = m_sta_ssid_len;
auto &wifi_manager = WifiManager::GetInstance();
if (wifi_manager.IsInitialized()) {
if (wifi_manager.IsConfigMode()) {
wifi_manager.StopConfigAp();
}
wifi_manager.StopStation();
}
if (!wifi_manager.IsInitialized() && !wifi_manager.Initialize()) {
ESP_LOGE(BLUFI_TAG, "Failed to initialize WifiManager");
break;
}
vTaskDelay(pdMS_TO_TICKS(500));
wifi_manager.StartStation(); wifi_manager.StartStation();
// Wait for connection in a separate task to avoid blocking the BLUFI handler.
xTaskCreate( xTaskCreate(
[](void *ctx) { [](void *ctx) {
auto *self = static_cast<Blufi *>(ctx); auto *self = static_cast<Blufi *>(ctx);
auto &wifi = WifiManager::GetInstance(); auto &wifi = WifiManager::GetInstance();
constexpr int kConnectTimeoutMs = 10000; // 10s constexpr int kConnectTimeoutMs = 10000;
constexpr TickType_t kDelayTick = pdMS_TO_TICKS(200); constexpr TickType_t kDelayTick = pdMS_TO_TICKS(200);
int waited_ms = 0; int waited_ms = 0;
@ -669,7 +781,6 @@ void Blufi::_handle_event(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *para
softap_conn_num, &info); softap_conn_num, &info);
ESP_LOGI(BLUFI_TAG, "connected to WiFi"); ESP_LOGI(BLUFI_TAG, "connected to WiFi");
// Close BluFi session after successful provisioning to free resources.
if (self->m_ble_is_connected) { if (self->m_ble_is_connected) {
esp_blufi_disconnect(); esp_blufi_disconnect();
} }
@ -749,6 +860,14 @@ void Blufi::_handle_event(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *para
m_sta_config.sta.password[param->sta_passwd.passwd_len] = '\0'; m_sta_config.sta.password[param->sta_passwd.passwd_len] = '\0';
ESP_LOGI(BLUFI_TAG, "Recv STA PASSWORD : %s", m_sta_config.sta.password); ESP_LOGI(BLUFI_TAG, "Recv STA PASSWORD : %s", m_sta_config.sta.password);
break; break;
case ESP_BLUFI_EVENT_GET_WIFI_LIST: {
ESP_LOGI(BLUFI_TAG, "BLUFI get wifi list");
while (m_scan_in_progress) {
vTaskDelay(pdMS_TO_TICKS(500));
}
_send_wifi_list();
break;
}
default: default:
ESP_LOGW(BLUFI_TAG, "Unhandled event: %d", event); ESP_LOGW(BLUFI_TAG, "Unhandled event: %d", event);
break; break;

View File

@ -1,12 +1,17 @@
#pragma once #pragma once
#include <aes/esp_aes.h> #include <aes/esp_aes.h>
#include "mbedtls/dhm.h" #include <cassert>
#include "mbedtls/aes.h" #include <cstring>
#include "esp_err.h" #include <vector>
#include "esp_blufi_api.h" #include "esp_blufi_api.h"
#include "esp_wifi_types.h" #include "esp_err.h"
#include "esp_timer.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "mbedtls/aes.h"
#include "mbedtls/dhm.h"
#include "wifi_manager.h"
class Blufi { class Blufi {
public: public:
@ -15,6 +20,14 @@ public:
*/ */
static Blufi &GetInstance(); static Blufi &GetInstance();
/**
* @brief Start WiFi scan for Blufi provisioning
* This method intelligently handles WiFi scanning based on current WiFi state:
* - If WiFi config mode is active, it uses the existing scan results from WifiConfigurationAp
* - Otherwise, it performs a dedicated scan without interfering with normal WiFi operations
*/
void start_wifi_scan();
/** /**
* @brief Initializes the Bluetooth controller, host, and Blufi profile. * @brief Initializes the Bluetooth controller, host, and Blufi profile.
* This is the main entry point to start the Blufi process. * This is the main entry point to start the Blufi process.
@ -40,7 +53,6 @@ private:
~Blufi(); ~Blufi();
// Initialization logic // Initialization logic
static esp_err_t _controller_init(); static esp_err_t _controller_init();
@ -58,7 +70,8 @@ private:
void _security_deinit(); void _security_deinit();
void _dh_negotiate_data_handler(uint8_t *data, int len, uint8_t **output_data, int *output_len, bool *need_free); void _dh_negotiate_data_handler(uint8_t *data, int len, uint8_t **output_data, int *output_len,
bool *need_free);
int _aes_encrypt(uint8_t iv8, uint8_t *crypt_data, int crypt_len); int _aes_encrypt(uint8_t iv8, uint8_t *crypt_data, int crypt_len);
@ -70,12 +83,19 @@ private:
static int _get_softap_conn_num(); static int _get_softap_conn_num();
// These C-style functions are registered with ESP-IDF and call the corresponding instance methods. // WiFi scan methods
void _send_wifi_list();
void _start_dedicated_wifi_scan();
static void _wifi_scan_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id,
void *event_data);
// These C-style functions are registered with ESP-IDF and call the corresponding instance
// methods.
static void _event_callback_trampoline(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *param); static void _event_callback_trampoline(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *param);
static void _negotiate_data_handler_trampoline(uint8_t *data, int len, uint8_t **output_data, int *output_len, static void _negotiate_data_handler_trampoline(uint8_t *data, int len, uint8_t **output_data,
bool *need_free); int *output_len, bool *need_free);
static int _encrypt_func_trampoline(uint8_t iv8, uint8_t *crypt_data, int crypt_len); static int _encrypt_func_trampoline(uint8_t iv8, uint8_t *crypt_data, int crypt_len);
@ -109,7 +129,6 @@ private:
// State variables // State variables
wifi_config_t m_sta_config{}; wifi_config_t m_sta_config{};
wifi_config_t m_ap_config{};
bool m_ble_is_connected; bool m_ble_is_connected;
bool m_sta_connected; bool m_sta_connected;
bool m_sta_got_ip; bool m_sta_got_ip;
@ -120,4 +139,9 @@ private:
int m_sta_ssid_len; int m_sta_ssid_len;
bool m_sta_is_connecting; bool m_sta_is_connecting;
esp_blufi_extra_info_t m_sta_conn_info{}; esp_blufi_extra_info_t m_sta_conn_info{};
// WiFi scan related
std::vector<wifi_ap_record_t> m_ap_records;
bool m_scan_in_progress = false;
bool m_scan_should_save_ssid = true;
}; };

View File

@ -175,8 +175,7 @@ void WifiBoard::StartWifiConfigMode() {
Application::GetInstance().Alert(Lang::Strings::WIFI_CONFIG_MODE, hint.c_str(), "gear", Lang::Sounds::OGG_WIFICONFIG); Application::GetInstance().Alert(Lang::Strings::WIFI_CONFIG_MODE, hint.c_str(), "gear", Lang::Sounds::OGG_WIFICONFIG);
}); });
#endif #elif CONFIG_USE_ESP_BLUFI_WIFI_PROVISIONING
#if CONFIG_USE_ESP_BLUFI_WIFI_PROVISIONING
auto &blufi = Blufi::GetInstance(); auto &blufi = Blufi::GetInstance();
// initialize esp-blufi protocol // initialize esp-blufi protocol
blufi.init(); blufi.init();