wangzhibo
2026-10-08 220e4fab27b7f419b3e89e2f2d28ae789aac09d7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#pragma once
 
#include <aes/esp_aes.h>
#include <cassert>
#include <cstring>
#include <vector>
#include "esp_blufi_api.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 {
public:
    /**
     * @brief Get the singleton instance of the Blufi class.
     */
    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.
     * This is the main entry point to start the Blufi process.
     * @return ESP_OK on success, otherwise an error code.
     */
    esp_err_t init();
 
    /**
     * @brief Deinitializes Blufi and the Bluetooth stack.
     * @return ESP_OK on success, otherwise an error code.
     */
    esp_err_t deinit();
 
    // Delete copy constructor and assignment operator for singleton
    Blufi(const Blufi &) = delete;
 
    Blufi &operator=(const Blufi &) = delete;
 
private:
    bool inited_ = false;
 
    Blufi();
 
    ~Blufi();
 
    // Initialization logic
    static esp_err_t _controller_init();
 
    static esp_err_t _controller_deinit();
 
    static esp_err_t _host_init();
 
    static esp_err_t _host_deinit();
 
    static esp_err_t _gap_register_callback();
 
    static esp_err_t _host_and_cb_init();
 
    void _security_init();
 
    void _security_deinit();
 
    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_decrypt(uint8_t iv8, uint8_t *crypt_data, int crypt_len);
 
    static uint16_t _crc_checksum(uint8_t iv8, uint8_t *data, int len);
 
    void _handle_event(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *param);
 
    static int _get_softap_conn_num();
 
    // 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 _negotiate_data_handler_trampoline(uint8_t *data, int len, uint8_t **output_data,
                                                   int *output_len, bool *need_free);
 
    static int _encrypt_func_trampoline(uint8_t iv8, uint8_t *crypt_data, int crypt_len);
 
    static int _decrypt_func_trampoline(uint8_t iv8, uint8_t *crypt_data, int crypt_len);
 
    static uint16_t _checksum_func_trampoline(uint8_t iv8, uint8_t *data, int len);
 
#ifdef CONFIG_BT_NIMBLE_ENABLED
    static void _nimble_on_reset(int reason);
    static void _nimble_on_sync();
    static void _nimble_host_task(void *param);
#endif
 
    // Security context, formerly blufi_sec struct
    struct BlufiSecurity {
#define DH_SELF_PUB_KEY_LEN 128
        uint8_t self_public_key[DH_SELF_PUB_KEY_LEN];
#define SHARE_KEY_LEN 128
        uint8_t share_key[SHARE_KEY_LEN];
        size_t share_len;
#define PSK_LEN 16
        uint8_t psk[PSK_LEN];
        uint8_t *dh_param;
        int dh_param_len;
        uint8_t iv[16];
        mbedtls_dhm_context *dhm;
        esp_aes_context *aes;
    };
 
    BlufiSecurity *m_sec;
 
    // State variables
    wifi_config_t m_sta_config{};
    bool m_ble_is_connected;
    bool m_sta_connected;
    bool m_sta_got_ip;
    bool m_provisioned;
    bool m_deinited;
    uint8_t m_sta_bssid[6]{};
    uint8_t m_sta_ssid[32]{};
    int m_sta_ssid_len;
    bool m_sta_is_connecting;
    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;
};