173 lines
6.6 KiB
C++
173 lines
6.6 KiB
C++
#pragma once
|
||
|
||
/**
|
||
* @file bluetooth_provisioning.h
|
||
* @brief 蓝牙配网模块头文件(基于自定义 GATT Server)
|
||
*
|
||
* 使用自定义 BLE GATT Server 实现配网通讯,
|
||
* 采用原始广播数据(raw advertising)确保手机系统蓝牙可发现。
|
||
* 保留完整的 WiFi 配网业务逻辑、状态机和事件回调。
|
||
*/
|
||
|
||
#include <functional>
|
||
#include <string>
|
||
|
||
// 使用条件编译避免IDE环境中的头文件错误
|
||
#ifdef ESP_PLATFORM
|
||
#include "esp_gap_ble_api.h"
|
||
#include "esp_gatts_api.h"
|
||
#include "esp_gatt_common_api.h"
|
||
#include "esp_wifi.h"
|
||
#include "esp_event.h"
|
||
#else
|
||
// 在非ESP环境中定义必要的类型和常量
|
||
typedef int esp_event_base_t;
|
||
typedef void* wifi_ap_record_t;
|
||
#endif
|
||
|
||
// ============================================================
|
||
// 配网协议命令定义 (手机 → 设备, WRITE 特征)
|
||
// ============================================================
|
||
#define PROV_CMD_SET_SSID 0x01 // 设置 WiFi SSID
|
||
#define PROV_CMD_SET_PASSWORD 0x02 // 设置 WiFi 密码
|
||
#define PROV_CMD_SET_BSSID 0x03 // 设置 BSSID (6字节)
|
||
#define PROV_CMD_CONNECT_AP 0x04 // 请求连接 WiFi
|
||
#define PROV_CMD_DISCONNECT_AP 0x05 // 请求断开 WiFi
|
||
#define PROV_CMD_GET_WIFI_LIST 0x06 // 请求 WiFi 列表
|
||
#define PROV_CMD_DISCONNECT_BLE 0x07 // 请求断开 BLE
|
||
#define PROV_CMD_SET_WIFI_MODE 0x08 // 设置 WiFi 模式
|
||
#define PROV_CMD_GET_WIFI_STATUS 0x09 // 获取 WiFi 状态
|
||
#define PROV_CMD_CUSTOM_DATA 0x10 // 自定义数据
|
||
|
||
// ============================================================
|
||
// 配网协议响应定义 (设备 → 手机, NOTIFY 特征)
|
||
// ============================================================
|
||
#define PROV_RESP_WIFI_STATUS 0x81 // WiFi 状态: [success(1)][reason(1)]
|
||
#define PROV_RESP_WIFI_LIST 0x82 // WiFi 列表: [rssi(1)][ssid_len(1)][ssid...]
|
||
#define PROV_RESP_WIFI_LIST_END 0x83 // WiFi 列表结束标记
|
||
#define PROV_RESP_CUSTOM_DATA 0x84 // 自定义数据
|
||
|
||
// ============================================================
|
||
// GATT 服务配置
|
||
// ============================================================
|
||
#define PROV_SERVICE_UUID 0xABF0 // 配网服务 UUID
|
||
#define PROV_CHAR_WRITE_UUID 0xABF1 // 写入特征 UUID (手机→设备)
|
||
#define PROV_CHAR_NOTIFY_UUID 0xABF2 // 通知特征 UUID (设备→手机)
|
||
#define PROV_APP_ID 2 // GATTS App ID
|
||
#define PROV_HANDLE_NUM 8 // Service handle 数量
|
||
#define PROV_LOCAL_MTU 512 // 本地 MTU
|
||
|
||
/**
|
||
* @brief 蓝牙配网状态枚举
|
||
*/
|
||
enum class BluetoothProvisioningState {
|
||
IDLE, //< 空闲状态,未启动配网
|
||
INITIALIZING, //< 初始化中,正在初始化蓝牙和服务
|
||
ADVERTISING, //< 广播中,等待手机客户端连接
|
||
CONNECTED, //< 已连接,手机客户端已连接到设备
|
||
PROVISIONING, //< 配网中,正在接收和处理WiFi凭据
|
||
SUCCESS, //< 配网成功,WiFi连接建立成功
|
||
FAILED, //< 配网失败,WiFi连接失败或其他错误
|
||
STOPPED //< 已停止,配网服务已停止
|
||
};
|
||
|
||
/**
|
||
* @brief 蓝牙配网事件类型
|
||
*/
|
||
enum class BluetoothProvisioningEvent {
|
||
STATE_CHANGED, //< 状态改变事件
|
||
WIFI_CREDENTIALS, //< 收到WiFi凭据事件
|
||
WIFI_CONNECTED, //< WiFi连接成功事件
|
||
WIFI_FAILED, //< WiFi连接失败事件
|
||
CLIENT_CONNECTED, //< 客户端连接事件
|
||
CLIENT_DISCONNECTED //< 客户端断开事件
|
||
};
|
||
|
||
/**
|
||
* @brief WiFi凭据结构体
|
||
*/
|
||
struct WiFiCredentials {
|
||
std::string ssid; //< WiFi网络名称(SSID)
|
||
std::string password; //< WiFi网络密码
|
||
uint8_t bssid[6]; //< WiFi接入点的MAC地址(BSSID)
|
||
bool bssid_set; //< 是否设置了BSSID
|
||
};
|
||
|
||
/**
|
||
* @brief 蓝牙配网事件回调函数类型
|
||
*/
|
||
using BluetoothProvisioningCallback = std::function<void(BluetoothProvisioningEvent event, void* data)>;
|
||
|
||
/**
|
||
* @brief 蓝牙配网封装类(基于自定义 GATT Server)
|
||
*
|
||
* 使用自定义 BLE GATT Server + 原始广播数据,
|
||
* 手机系统蓝牙可直接搜索到设备。保留完整的 WiFi 配网业务逻辑。
|
||
*/
|
||
class BluetoothProvisioning {
|
||
public:
|
||
BluetoothProvisioning();
|
||
~BluetoothProvisioning();
|
||
|
||
bool Initialize();
|
||
bool Deinitialize();
|
||
bool StartProvisioning();
|
||
bool StopProvisioning();
|
||
|
||
BluetoothProvisioningState GetState() const { return state_; }
|
||
void SetCallback(BluetoothProvisioningCallback callback) { callback_ = callback; }
|
||
const WiFiCredentials& GetWiFiCredentials() const { return wifi_credentials_; }
|
||
bool IsClientConnected() const { return client_connected_; }
|
||
std::string GetStateString() const;
|
||
|
||
void ReportWiFiStatus(bool success, uint8_t reason = 0);
|
||
void SendWiFiList(const wifi_ap_record_t* ap_list, uint16_t ap_count);
|
||
bool SendMacAddressReliably();
|
||
void ResetMacSendingState();
|
||
|
||
private:
|
||
BluetoothProvisioningState state_;
|
||
BluetoothProvisioningCallback callback_;
|
||
WiFiCredentials wifi_credentials_;
|
||
bool client_connected_;
|
||
bool initialized_;
|
||
bool delayed_disconnect_;
|
||
bool wifi_connecting_;
|
||
bool mac_address_sent_;
|
||
|
||
static BluetoothProvisioning* instance_;
|
||
|
||
void SetState(BluetoothProvisioningState new_state);
|
||
void TriggerCallback(BluetoothProvisioningEvent event, void* data = nullptr);
|
||
|
||
#ifdef ESP_PLATFORM
|
||
// GATT 相关成员
|
||
esp_gatt_if_t gatts_if_ = ESP_GATT_IF_NONE;
|
||
uint16_t service_handle_ = 0;
|
||
uint16_t write_char_handle_ = 0;
|
||
uint16_t notify_char_handle_ = 0;
|
||
uint16_t notify_cccd_handle_ = 0;
|
||
uint16_t conn_id_ = 0;
|
||
bool notify_enabled_ = false;
|
||
uint16_t mtu_ = 23;
|
||
|
||
// BLE 回调
|
||
static void GattsEventHandler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t* param);
|
||
static void GapEventHandler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t* param);
|
||
void HandleGattsEvent(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t* param);
|
||
|
||
// GATT 辅助方法
|
||
void CreateService(esp_gatt_if_t gatts_if);
|
||
void StartAdvertising();
|
||
bool SendNotify(const uint8_t* data, uint16_t len);
|
||
void ProcessWriteData(const uint8_t* data, uint16_t len);
|
||
|
||
// WiFi 事件处理
|
||
static void WiFiEventHandler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data);
|
||
static void IPEventHandler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data);
|
||
#endif
|
||
|
||
BluetoothProvisioning(const BluetoothProvisioning&) = delete;
|
||
BluetoothProvisioning& operator=(const BluetoothProvisioning&) = delete;
|
||
};
|