Pendant_Rtc_Toy/main/bluetooth_provisioning.h
Rdzleo 93f0e19d1d 初始化项目:精灵吊坠 RTC 语音助手 + VEML7700 石头同频匹配
ESP32-S3 吊坠设备固件,集成火山引擎 RTC 语音助手、蓝牙配网、
VEML7700 环境光传感器驱动及石头同频匹配交友功能。

VEML7700 驱动:
- 基于 ESP-IDF i2c_master API 实现,复用项目 I2cDevice 基类
- 支持 ALS + White 双通道、自动量程、Vishay 非线性校正
- 3 次采样取中位数过滤偶发异常

石头同频匹配算法(双维度):
- 维度1:光谱比值 ALS/White(石头固有光学特征,不随光照强度变化)
- 维度2:亮度等级(5级对数划分,排除极端环境差异)
- 比值阈值 15%,实测同石头姿势变化波动 1.6%~9.6%,安全余量充足

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 11:43:57 +08:00

173 lines
6.6 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.

#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;
};