bluedroid_host和nimble_host的主要区别

bluedroid_host和nimble_host的主要区别如下:

1. 协议栈不同:

- bluedroid_host基于Bluedroid协议栈(Android蓝牙协议栈)
- nimble_host基于NimBLE协议栈(轻量级开源蓝牙协议栈)

2. 架构差异:

- bluedroid_host使用BTA/BTC分层架构,通过BTA_GATTS_*等API操作
- nimble_host直接使用NimBLE的ble_gatt_*等原生API

3. 内存占用:

- nimble_host内存占用更小,适合资源受限设备
- bluedroid_host功能更全面但内存占用更大

4. 代码复杂度:

- nimble_host代码更简洁,直接操作NimBLE原语
- bluedroid_host需要处理更多中间层(BTA/BTC)的转换

5. 功能支持:

- bluedroid_host支持更多Android特有的蓝牙功能
- nimble_host更专注于BLE核心功能

6. 适用场景:

- bluedroid_host适合需要与Android设备深度交互的场景
- nimble_host适合对资源敏感的低功耗IoT设备

两者都实现了相同的BLUFI功能,但底层实现机制不同,开发者可以根据项目需求选择合适的实现。
 

这是blufi历程实例所包含的库,作为参考#include <stdio.h> #include <stdlib.h> #include <string.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/event_groups.h" #include "esp_system.h" #include "esp_wifi.h" #include "esp_event.h" #include "esp_log.h" #include "nvs_flash.h" #include "esp_random.h" #if CONFIG_BT_CONTROLLER_ENABLED || !CONFIG_BT_NIMBLE_ENABLED #include "esp_bt.h" #endif #include "esp_blufi_api.h" #include "blufi_example.h" #include "mbedtls/aes.h" #include "mbedtls/dhm.h" #include "mbedtls/md5.h" #include "esp_crc.h"#include <stdio.h> #include "esp_err.h" #include "esp_blufi_api.h" #include "esp_log.h" #include "esp_blufi.h" #include "blufi_example.h" #if CONFIG_BT_CONTROLLER_ENABLED || !CONFIG_BT_NIMBLE_ENABLED #include "esp_bt.h" #endif #ifdef CONFIG_BT_BLUEDROID_ENABLED #include "esp_bt_main.h" #include "esp_bt_device.h" #endif #ifdef CONFIG_BT_NIMBLE_ENABLED #include "nimble/nimble_port.h" #include "nimble/nimble_port_freertos.h" #include "host/ble_hs.h" #include "host/util/util.h" #include "services/gap/ble_svc_gap.h" #include "services/gatt/ble_svc_gatt.h" #include "console/console.h" #endif #ifdef CONFIG_BT_BLUEDROID_ENABLED#include <stdio.h> #include <stdlib.h> #include <string.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/event_groups.h" #include "esp_system.h" #include "esp_mac.h" #include "esp_wifi.h" #include "esp_event.h" #include "esp_log.h" #include "nvs_flash.h" #if CONFIG_BT_CONTROLLER_ENABLED || !CONFIG_BT_NIMBLE_ENABLED #include "esp_bt.h" #endif #include "esp_blufi_api.h" #include "blufi_example.h" #include "esp_blufi.h" #define EXAMPLE_WIFI_CONNECTION_MAXIMUM_RETRY CONFIG_EXAMPLE_WIFI_CONNECTION_MAXIMUM_RETRY #define EXAMPLE_INVALID_REASON 255 #define EXAMPLE_INVALID_RSSI -128 #if CONFIG_ESP_WIFI_AUTH_OPEN #define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_OPEN #elif CONFIG_ESP_WIFI_AUTH_WEP #define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WEP #elif CONFIG_ESP_WIFI_AUTH_WPA_PSK #define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_PSK #elif CONFIG_ESP_WIFI_AUTH_WPA2_PSK #define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_PSK #elif CONFIG_ESP_WIFI_AUTH_WPA_WPA2_PSK #define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_WPA2_PSK #elif CONFIG_ESP_WIFI_AUTH_WPA3_PSK #define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA3_PSK #elif CONFIG_ESP_WIFI_AUTH_WPA2_WPA3_PSK #define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_WPA3_PSK #elif CONFIG_ESP_WIFI_AUTH_WAPI_PSK #define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WAPI_PSK #endif static void example_event_callback(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *param); #define WIFI_LIST_NUM 10
07-12
[{ "resource": "/e:/esp32/esp32_spi_slave_transfer_Prj (3)/src/BLE_master.cpp", "owner": "cpp", "severity": 8, "message": "'clearAllBonds' is not a member of 'NimBLEDevice'", "startLineNumber": 21, "startColumn": 19, "endLineNumber": 21, "endColumn": 19 },{ "resource": "/e:/esp32/esp32_spi_slave_transfer_Prj (3)/src/BLE_master.cpp", "owner": "cpp", "severity": 8, "message": "'class NimBLEClient' has no member named 'setConnParams'; did you mean 'm_connParams'?", "startLineNumber": 48, "startColumn": 18, "endLineNumber": 48, "endColumn": 18 }] /* * Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and * esp-nimble-cpp, NimBLE-Arduino contributors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef NIMBLE_CPP_DEVICE_H_ #define NIMBLE_CPP_DEVICE_H_ #include "nimconfig.h" #if CONFIG_BT_ENABLED # ifdef ESP_PLATFORM # ifndef CONFIG_IDF_TARGET_ESP32P4 # include <esp_bt.h> # endif # endif # if defined(CONFIG_NIMBLE_CPP_IDF) # include <host/ble_gap.h> # else # include <nimble/nimble/host/include/host/ble_gap.h> # endif /**** FIX COMPILATION ****/ # undef min # undef max /**************************/ # include <string> # include <vector> # if CONFIG_BT_NIMBLE_ROLE_CENTRAL # include <array> class NimBLEClient; # endif # if CONFIG_BT_NIMBLE_ROLE_OBSERVER class NimBLEScan; # endif # if CONFIG_BT_NIMBLE_ROLE_BROADCASTER # if CONFIG_BT_NIMBLE_EXT_ADV class NimBLEExtAdvertising; # else class NimBLEAdvertising; # endif # endif # if CONFIG_BT_NIMBLE_ROLE_PERIPHERAL class NimBLEServer; # if CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM > 0 class NimBLEL2CAPServer; # endif # endif # if CONFIG_BT_NIMBLE_ROLE_PERIPHERAL || CONFIG_BT_NIMBLE_ROLE_CENTRAL class NimBLEConnInfo; # endif class NimBLEAddress; class NimBLEDeviceCallbacks; # define BLEDevice NimBLEDevice # define BLEClient NimBLEClient # define BLERemoteService NimBLERemoteService # define BLERemoteCharacteristic NimBLERemoteCharacteristic # define BLERemoteDescriptor NimBLERemoteDescriptor # define BLEAdvertisedDevice NimBLEAdvertisedDevice # define BLEScan NimBLEScan # define BLEUUID NimBLEUUID # define BLEAddress NimBLEAddress # define BLEUtils NimBLEUtils # define BLEClientCallbacks NimBLEClientCallbacks # define BLEAdvertisedDeviceCallbacks NimBLEScanCallbacks # define BLEScanResults NimBLEScanResults # define BLEServer NimBLEServer # define BLEService NimBLEService # define BLECharacteristic NimBLECharacteristic # define BLEAdvertising NimBLEAdvertising # define BLEServerCallbacks NimBLEServerCallbacks # define BLECharacteristicCallbacks NimBLECharacteristicCallbacks # define BLEAdvertisementData NimBLEAdvertisementData # define BLEDescriptor NimBLEDescriptor # define BLE2904 NimBLE2904 # define BLEDescriptorCallbacks NimBLEDescriptorCallbacks # define BLEBeacon NimBLEBeacon # define BLEEddystoneTLM NimBLEEddystoneTLM # define BLEEddystoneURL NimBLEEddystoneURL # define BLEConnInfo NimBLEConnInfo # define BLEL2CAPServer NimBLEL2CAPServer # define BLEL2CAPService NimBLEL2CAPService # define BLEL2CAPServiceCallbacks NimBLEL2CAPServiceCallbacks # define BLEL2CAPClient NimBLEL2CAPClient # define BLEL2CAPClientCallbacks NimBLEL2CAPClientCallbacks # define BLEL2CAPChannel NimBLEL2CAPChannel # define BLEL2CAPChannelCallbacks NimBLEL2CAPChannelCallbacks # ifdef CONFIG_BT_NIMBLE_MAX_CONNECTIONS # define NIMBLE_MAX_CONNECTIONS CONFIG_BT_NIMBLE_MAX_CONNECTIONS # else # define NIMBLE_MAX_CONNECTIONS CONFIG_NIMBLE_MAX_CONNECTIONS # endif enum class NimBLETxPowerType { All = 0, Advertise = 1, Scan = 2, Connection = 3 }; typedef int (*gap_event_handler)(ble_gap_event* event, void* arg); /** * @brief A model of a BLE Device from which all the BLE roles are created. */ class NimBLEDevice { public: static bool init(const std::string& deviceName); static bool deinit(bool clearAll = false); static bool setDeviceName(const std::string& deviceName); static bool isInitialized(); static NimBLEAddress getAddress(); static std::string toString(); static bool whiteListAdd(const NimBLEAddress& address); static bool whiteListRemove(const NimBLEAddress& address); static bool onWhiteList(const NimBLEAddress& address); static size_t getWhiteListCount(); static NimBLEAddress getWhiteListAddress(size_t index); static bool setOwnAddrType(uint8_t type); static bool setOwnAddr(const NimBLEAddress& addr); static bool setOwnAddr(const uint8_t* addr); static void setDeviceCallbacks(NimBLEDeviceCallbacks* cb); static void setScanDuplicateCacheSize(uint16_t cacheSize); static void setScanFilterMode(uint8_t type); static void setScanDuplicateCacheResetTime(uint16_t time); static bool setCustomGapHandler(gap_event_handler handler); static void setSecurityAuth(bool bonding, bool mitm, bool sc); static void setSecurityAuth(uint8_t auth); static void setSecurityIOCap(uint8_t iocap); static void setSecurityInitKey(uint8_t initKey); static void setSecurityRespKey(uint8_t respKey); static void setSecurityPasskey(uint32_t passKey); static uint32_t getSecurityPasskey(); static bool startSecurity(uint16_t connHandle, int* rcPtr = nullptr); static bool setMTU(uint16_t mtu); static uint16_t getMTU(); static void onReset(int reason); static void onSync(void); static void host_task(void* param); static int getPower(NimBLETxPowerType type = NimBLETxPowerType::All); static bool setPower(int8_t dbm, NimBLETxPowerType type = NimBLETxPowerType::All); static bool setDefaultPhy(uint8_t txPhyMask, uint8_t rxPhyMask); # ifdef ESP_PLATFORM # ifndef CONFIG_IDF_TARGET_ESP32P4 static esp_power_level_t getPowerLevel(esp_ble_power_type_t powerType = ESP_BLE_PWR_TYPE_DEFAULT); static bool setPowerLevel(esp_power_level_t powerLevel, esp_ble_power_type_t powerType = ESP_BLE_PWR_TYPE_DEFAULT); # endif # endif # if CONFIG_BT_NIMBLE_ROLE_OBSERVER static NimBLEScan* getScan(); # endif # if CONFIG_BT_NIMBLE_ROLE_PERIPHERAL static NimBLEServer* createServer(); static NimBLEServer* getServer(); # if CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM > 0 static NimBLEL2CAPServer* createL2CAPServer(); static NimBLEL2CAPServer* getL2CAPServer(); # endif # endif # if CONFIG_BT_NIMBLE_ROLE_PERIPHERAL || CONFIG_BT_NIMBLE_ROLE_CENTRAL static bool injectConfirmPasskey(const NimBLEConnInfo& peerInfo, bool accept); static bool injectPassKey(const NimBLEConnInfo& peerInfo, uint32_t pin); # endif # if CONFIG_BT_NIMBLE_ROLE_BROADCASTER # if CONFIG_BT_NIMBLE_EXT_ADV static NimBLEExtAdvertising* getAdvertising(); static bool startAdvertising(uint8_t instId, int duration = 0, int maxEvents = 0); static bool stopAdvertising(uint8_t instId); static bool stopAdvertising(); # endif # if !CONFIG_BT_NIMBLE_EXT_ADV || defined(_DOXYGEN_) static NimBLEAdvertising* getAdvertising(); static bool startAdvertising(uint32_t duration = 0); static bool stopAdvertising(); # endif # endif # if CONFIG_BT_NIMBLE_ROLE_CENTRAL static NimBLEClient* createClient(); static NimBLEClient* createClient(const NimBLEAddress& peerAddress); static bool deleteClient(NimBLEClient* pClient); static NimBLEClient* getClientByHandle(uint16_t connHandle); static NimBLEClient* getClientByPeerAddress(const NimBLEAddress& peerAddress); static NimBLEClient* getDisconnectedClient(); static size_t getCreatedClientCount(); static std::vector<NimBLEClient*> getConnectedClients(); # endif # if CONFIG_BT_NIMBLE_ROLE_CENTRAL || CONFIG_BT_NIMBLE_ROLE_PERIPHERAL static bool deleteBond(const NimBLEAddress& address); static int getNumBonds(); static bool isBonded(const NimBLEAddress& address); static bool deleteAllBonds(); static NimBLEAddress getBondedAddress(int index); # endif private: static bool m_synced; static bool m_initialized; static uint32_t m_passkey; static ble_gap_event_listener m_listener; static uint8_t m_ownAddrType; static std::vector<NimBLEAddress> m_whiteList; static NimBLEDeviceCallbacks* m_pDeviceCallbacks; static NimBLEDeviceCallbacks defaultDeviceCallbacks; # if CONFIG_BT_NIMBLE_ROLE_OBSERVER static NimBLEScan* m_pScan; # endif # if CONFIG_BT_NIMBLE_ROLE_PERIPHERAL static NimBLEServer* m_pServer; # if CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM > 0 static NimBLEL2CAPServer* m_pL2CAPServer; # endif # endif # if CONFIG_BT_NIMBLE_ROLE_BROADCASTER # if CONFIG_BT_NIMBLE_EXT_ADV static NimBLEExtAdvertising* m_bleAdvertising; # else static NimBLEAdvertising* m_bleAdvertising; # endif # endif # if CONFIG_BT_NIMBLE_ROLE_CENTRAL static std::array<NimBLEClient*, NIMBLE_MAX_CONNECTIONS> m_pClients; # endif # ifdef ESP_PLATFORM # if CONFIG_BTDM_BLE_SCAN_DUPL || CONFIG_BT_LE_SCAN_DUPL static uint16_t m_scanDuplicateSize; static uint8_t m_scanFilterMode; static uint16_t m_scanDuplicateResetTime; # endif # endif # if CONFIG_BT_NIMBLE_ROLE_CENTRAL friend class NimBLEClient; # endif # if CONFIG_BT_NIMBLE_ROLE_OBSERVER friend class NimBLEScan; # endif # if CONFIG_BT_NIMBLE_ROLE_PERIPHERAL friend class NimBLEServer; friend class NimBLECharacteristic; # endif # if CONFIG_BT_NIMBLE_ROLE_BROADCASTER friend class NimBLEAdvertising; # if CONFIG_BT_NIMBLE_EXT_ADV friend class NimBLEExtAdvertising; friend class NimBLEExtAdvertisement; # endif # endif }; # if CONFIG_BT_NIMBLE_ROLE_CENTRAL # include "NimBLEClient.h" # include "NimBLERemoteService.h" # include "NimBLERemoteCharacteristic.h" # include "NimBLERemoteDescriptor.h" # endif # if CONFIG_BT_NIMBLE_ROLE_OBSERVER # include "NimBLEScan.h" # endif # if CONFIG_BT_NIMBLE_ROLE_PERIPHERAL # include "NimBLEServer.h" # include "NimBLEService.h" # include "NimBLECharacteristic.h" # include "NimBLEDescriptor.h" # if CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM # include "NimBLEL2CAPServer.h" # include "NimBLEL2CAPChannel.h" # endif # endif # if CONFIG_BT_NIMBLE_ROLE_BROADCASTER # if CONFIG_BT_NIMBLE_EXT_ADV # include "NimBLEExtAdvertising.h" # else # include "NimBLEAdvertising.h" # endif # endif # if CONFIG_BT_NIMBLE_ROLE_CENTRAL || CONFIG_BT_NIMBLE_ROLE_PERIPHERAL # include "NimBLEConnInfo.h" # endif # include "NimBLEAddress.h" # include "NimBLEUtils.h" /** * @brief Callbacks associated with a BLE device. */ class NimBLEDeviceCallbacks { public: virtual ~NimBLEDeviceCallbacks() {}; /** * @brief Indicates an inability to perform a store operation. * This callback should do one of two things: * -Address the problem and return 0, indicating that the store operation * should proceed. * -Return nonzero to indicate that the store operation should be aborted. * @param event Describes the store event being reported. * BLE_STORE_EVENT_FULL; or * BLE_STORE_EVENT_OVERFLOW * @return 0 if the store operation should proceed; * nonzero if the store operation should be aborted. */ virtual int onStoreStatus(struct ble_store_status_event* event, void* arg); }; #endif // CONFIG_BT_ENABLED #endif // NIMBLE_CPP_DEVICE_H_ /* * Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and * esp-nimble-cpp, NimBLE-Arduino contributors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef NIMBLE_CPP_CLIENT_H_ #define NIMBLE_CPP_CLIENT_H_ #include "nimconfig.h" #if CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL # if defined(CONFIG_NIMBLE_CPP_IDF) # include "host/ble_gap.h" # else # include "nimble/nimble/host/include/host/ble_gap.h" # endif # include "NimBLEAddress.h" # include <stdint.h> # include <vector> # include <string> class NimBLEAddress; class NimBLEUUID; class NimBLERemoteService; class NimBLERemoteCharacteristic; class NimBLEAdvertisedDevice; class NimBLEAttValue; class NimBLEClientCallbacks; class NimBLEConnInfo; struct NimBLETaskData; /** * @brief A model of a BLE client. */ class NimBLEClient { public: # if CONFIG_BT_NIMBLE_ROLE_OBSERVER bool connect(const NimBLEAdvertisedDevice* device, bool deleteAttributes = true, bool asyncConnect = false, bool exchangeMTU = true); # endif bool connect(const NimBLEAddress& address, bool deleteAttributes = true, bool asyncConnect = false, bool exchangeMTU = true); bool connect(bool deleteAttributes = true, bool asyncConnect = false, bool exchangeMTU = true); bool disconnect(uint8_t reason = BLE_ERR_REM_USER_CONN_TERM); bool cancelConnect() const; void setSelfDelete(bool deleteOnDisconnect, bool deleteOnConnectFail); NimBLEAddress getPeerAddress() const; bool setPeerAddress(const NimBLEAddress& address); int getRssi() const; bool isConnected() const; void setClientCallbacks(NimBLEClientCallbacks* pClientCallbacks, bool deleteCallbacks = true); std::string toString() const; uint16_t getConnHandle() const; uint16_t getMTU() const; bool exchangeMTU(); bool secureConnection(bool async = false) const; void setConnectTimeout(uint32_t timeout); bool setDataLen(uint16_t txOctets); bool discoverAttributes(); NimBLEConnInfo getConnInfo() const; int getLastError() const; bool updateConnParams(uint16_t minInterval, uint16_t maxInterval, uint16_t latency, uint16_t timeout); void setConnectionParams(uint16_t minInterval, uint16_t maxInterval, uint16_t latency, uint16_t timeout, uint16_t scanInterval = 16, uint16_t scanWindow = 16); const std::vector<NimBLERemoteService*>& getServices(bool refresh = false); std::vector<NimBLERemoteService*>::iterator begin(); std::vector<NimBLERemoteService*>::iterator end(); NimBLERemoteCharacteristic* getCharacteristic(uint16_t handle); NimBLERemoteService* getService(const char* uuid); NimBLERemoteService* getService(const NimBLEUUID& uuid); void deleteServices(); size_t deleteService(const NimBLEUUID& uuid); NimBLEAttValue getValue(const NimBLEUUID& serviceUUID, const NimBLEUUID& characteristicUUID); bool setValue(const NimBLEUUID& serviceUUID, const NimBLEUUID& characteristicUUID, const NimBLEAttValue& value, bool response = false); # if CONFIG_BT_NIMBLE_EXT_ADV void setConnectPhy(uint8_t phyMask); # endif bool updatePhy(uint8_t txPhysMask, uint8_t rxPhysMask, uint16_t phyOptions = 0); bool getPhy(uint8_t* txPhy, uint8_t* rxPhy); struct Config { uint8_t deleteCallbacks : 1; // Delete the callback object when the client is deleted. uint8_t deleteOnDisconnect : 1; // Delete the client when disconnected. uint8_t deleteOnConnectFail : 1; // Delete the client when a connection attempt fails. uint8_t asyncConnect : 1; // Connect asynchronously. uint8_t exchangeMTU : 1; // Exchange MTU after connection. }; Config getConfig() const; void setConfig(Config config); private: NimBLEClient(const NimBLEAddress& peerAddress); ~NimBLEClient(); NimBLEClient(const NimBLEClient&) = delete; NimBLEClient& operator=(const NimBLEClient&) = delete; bool retrieveServices(const NimBLEUUID* uuidFilter = nullptr); static int handleGapEvent(struct ble_gap_event* event, void* arg); static int exchangeMTUCb(uint16_t conn_handle, const ble_gatt_error* error, uint16_t mtu, void* arg); static int serviceDiscoveredCB(uint16_t connHandle, const struct ble_gatt_error* error, const struct ble_gatt_svc* service, void* arg); NimBLEAddress m_peerAddress; mutable int m_lastErr; int32_t m_connectTimeout; mutable NimBLETaskData* m_pTaskData; std::vector<NimBLERemoteService*> m_svcVec; NimBLEClientCallbacks* m_pClientCallbacks; uint16_t m_connHandle; uint8_t m_terminateFailCount; mutable uint8_t m_asyncSecureAttempt; Config m_config; # if CONFIG_BT_NIMBLE_EXT_ADV uint8_t m_phyMask; # endif ble_gap_conn_params m_connParams; friend class NimBLEDevice; friend class NimBLEServer; }; // class NimBLEClient /** * @brief Callbacks associated with a %BLE client. */ class NimBLEClientCallbacks { public: virtual ~NimBLEClientCallbacks() {}; /** * @brief Called after client connects. * @param [in] pClient A pointer to the connecting client object. */ virtual void onConnect(NimBLEClient* pClient); /** * @brief Called when a connection attempt fails. * @param [in] pClient A pointer to the connecting client object. * @param [in] reason Contains the reason code for the connection failure. */ virtual void onConnectFail(NimBLEClient* pClient, int reason); /** * @brief Called when disconnected from the server. * @param [in] pClient A pointer to the calling client object. * @param [in] reason Contains the reason code for the disconnection. */ virtual void onDisconnect(NimBLEClient* pClient, int reason); /** * @brief Called when server requests to update the connection parameters. * @param [in] pClient A pointer to the calling client object. * @param [in] params A pointer to the struct containing the connection parameters requested. * @return True to accept the parameters. */ virtual bool onConnParamsUpdateRequest(NimBLEClient* pClient, const ble_gap_upd_params* params); /** * @brief Called when server requests a passkey for pairing. * @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info. */ virtual void onPassKeyEntry(NimBLEConnInfo& connInfo); /** * @brief Called when the pairing procedure is complete. * @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info.\n * This can be used to check the status of the connection encryption/pairing. */ virtual void onAuthenticationComplete(NimBLEConnInfo& connInfo); /** * @brief Called when using numeric comparision for pairing. * @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info. * @param [in] pin The pin to compare with the server. */ virtual void onConfirmPasskey(NimBLEConnInfo& connInfo, uint32_t pin); /** * @brief Called when the peer identity address is resolved. * @param [in] connInfo A reference to a NimBLEConnInfo instance with information */ virtual void onIdentity(NimBLEConnInfo& connInfo); /** * @brief Called when the connection MTU changes. * @param [in] pClient A pointer to the client that the MTU change is associated with. * @param [in] MTU The new MTU value. * about the peer connection parameters. */ virtual void onMTUChange(NimBLEClient* pClient, uint16_t MTU); /** * @brief Called when the PHY update procedure is complete. * @param [in] pClient A pointer to the client whose PHY was updated. * about the peer connection parameters. * @param [in] txPhy The transmit PHY. * @param [in] rxPhy The receive PHY. * Possible values: * * BLE_GAP_LE_PHY_1M * * BLE_GAP_LE_PHY_2M * * BLE_GAP_LE_PHY_CODED */ virtual void onPhyUpdate(NimBLEClient* pClient, uint8_t txPhy, uint8_t rxPhy); }; #endif // CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL #endif // NIMBLE_CPP_CLIENT_H_
10-12
# # Bluetooth # CONFIG_BT_ENABLED=y CONFIG_BT_BLUEDROID_ENABLED=y # CONFIG_BT_NIMBLE_ENABLED is not set # CONFIG_BT_CONTROLLER_ONLY is not set CONFIG_BT_CONTROLLER_ENABLED=y # CONFIG_BT_CONTROLLER_DISABLED is not set # # Bluedroid Options # CONFIG_BT_BTC_TASK_STACK_SIZE=3072 CONFIG_BT_BLUEDROID_PINNED_TO_CORE_0=y # CONFIG_BT_BLUEDROID_PINNED_TO_CORE_1 is not set CONFIG_BT_BLUEDROID_PINNED_TO_CORE=0 CONFIG_BT_BTU_TASK_STACK_SIZE=4352 # CONFIG_BT_BLUEDROID_MEM_DEBUG is not set CONFIG_BT_BLUEDROID_ESP_COEX_VSC=y CONFIG_BT_BLE_ENABLED=y CONFIG_BT_GATTS_ENABLE=y # CONFIG_BT_GATTS_PPCP_CHAR_GAP is not set # CONFIG_BT_BLE_BLUFI_ENABLE is not set CONFIG_BT_GATT_MAX_SR_PROFILES=8 CONFIG_BT_GATT_MAX_SR_ATTRIBUTES=100 # CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL is not set CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_AUTO=y CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MODE=0 # CONFIG_BT_GATTS_ROBUST_CACHING_ENABLED is not set # CONFIG_BT_GATTS_DEVICE_NAME_WRITABLE is not set # CONFIG_BT_GATTS_APPEARANCE_WRITABLE is not set CONFIG_BT_GATTC_ENABLE=y CONFIG_BT_GATTC_MAX_CACHE_CHAR=40 CONFIG_BT_GATTC_NOTIF_REG_MAX=5 # CONFIG_BT_GATTC_CACHE_NVS_FLASH is not set CONFIG_BT_GATTC_CONNECT_RETRY_COUNT=3 CONFIG_BT_BLE_SMP_ENABLE=y # CONFIG_BT_SMP_SLAVE_CON_PARAMS_UPD_ENABLE is not set # CONFIG_BT_BLE_SMP_ID_RESET_ENABLE is not set CONFIG_BT_BLE_SMP_BOND_NVS_FLASH=y # CONFIG_BT_STACK_NO_LOG is not set # # BT DEBUG LOG LEVEL # # CONFIG_BT_LOG_HCI_TRACE_LEVEL_NONE is not set # CONFIG_BT_LOG_HCI_TRACE_LEVEL_ERROR is not set CONFIG_BT_LOG_HCI_TRACE_LEVEL_WARNING=y # CONFIG_BT_LOG_HCI_TRACE_LEVEL_API is not set # CONFIG_BT_LOG_HCI_TRACE_LEVEL_EVENT is not set # CONFIG_BT_LOG_HCI_TRACE_LEVEL_DEBUG is not set # CONFIG_BT_LOG_HCI_TRACE_LEVEL_VERBOSE is not set CONFIG_BT_LOG_HCI_TRACE_LEVEL=2 # CONFIG_BT_LOG_BTM_TRACE_LEVEL_NONE is not set # CONFIG_BT_LOG_BTM_TRACE_LEVEL_ERROR is not set CONFIG_BT_LOG_BTM_TRACE_LEVEL_WARNING=y # CONFIG_BT_LOG_BTM_TRACE_LEVEL_API is not set # CONFIG_BT_LOG_BTM_TRACE_LEVEL_EVENT is not set # CONFIG_BT_LOG_BTM_TRACE_LEVEL_DEBUG is not set # CONFIG_BT_LOG_BTM_TRACE_LEVEL_VERBOSE is not set CONFIG_BT_LOG_BTM_TRACE_LEVEL=2 # CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_NONE is not set # CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_ERROR is not set CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_WARNING=y # CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_API is not set # CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_EVENT is not set # CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_DEBUG is not set # CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_VERBOSE is not set CONFIG_BT_LOG_L2CAP_TRACE_LEVEL=2 # CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_NONE is not set # CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_ERROR is not set CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_WARNING=y # CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_API is not set # CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_EVENT is not set # CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_DEBUG is not set # CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_VERBOSE is not set CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL=2 # CONFIG_BT_LOG_SDP_TRACE_LEVEL_NONE is not set # CONFIG_BT_LOG_SDP_TRACE_LEVEL_ERROR is not set CONFIG_BT_LOG_SDP_TRACE_LEVEL_WARNING=y # CONFIG_BT_LOG_SDP_TRACE_LEVEL_API is not set # CONFIG_BT_LOG_SDP_TRACE_LEVEL_EVENT is not set # CONFIG_BT_LOG_SDP_TRACE_LEVEL_DEBUG is not set # CONFIG_BT_LOG_SDP_TRACE_LEVEL_VERBOSE is not set CONFIG_BT_LOG_SDP_TRACE_LEVEL=2 # CONFIG_BT_LOG_GAP_TRACE_LEVEL_NONE is not set # CONFIG_BT_LOG_GAP_TRACE_LEVEL_ERROR is not set CONFIG_BT_LOG_GAP_TRACE_LEVEL_WARNING=y # CONFIG_BT_LOG_GAP_TRACE_LEVEL_API is not set # CONFIG_BT_LOG_GAP_TRACE_LEVEL_EVENT is not set # CONFIG_BT_LOG_GAP_TRACE_LEVEL_DEBUG is not set # CONFIG_BT_LOG_GAP_TRACE_LEVEL_VERBOSE is not set CONFIG_BT_LOG_GAP_TRACE_LEVEL=2 # CONFIG_BT_LOG_BNEP_TRACE_LEVEL_NONE is not set # CONFIG_BT_LOG_BNEP_TRACE_LEVEL_ERROR is not set CONFIG_BT_LOG_BNEP_TRACE_LEVEL_WARNING=y # CONFIG_BT_LOG_BNEP_TRACE_LEVEL_API is not set # CONFIG_BT_LOG_BNEP_TRACE_LEVEL_EVENT is not set # CONFIG_BT_LOG_BNEP_TRACE_LEVEL_DEBUG is not set # CONFIG_BT_LOG_BNEP_TRACE_LEVEL_VERBOSE is not set CONFIG_BT_LOG_BNEP_TRACE_LEVEL=2 # CONFIG_BT_LOG_PAN_TRACE_LEVEL_NONE is not set # CONFIG_BT_LOG_PAN_TRACE_LEVEL_ERROR is not set CONFIG_BT_LOG_PAN_TRACE_LEVEL_WARNING=y # CONFIG_BT_LOG_PAN_TRACE_LEVEL_API is not set # CONFIG_BT_LOG_PAN_TRACE_LEVEL_EVENT is not set # CONFIG_BT_LOG_PAN_TRACE_LEVEL_DEBUG is not set # CONFIG_BT_LOG_PAN_TRACE_LEVEL_VERBOSE is not set CONFIG_BT_LOG_PAN_TRACE_LEVEL=2 # CONFIG_BT_LOG_A2D_TRACE_LEVEL_NONE is not set # CONFIG_BT_LOG_A2D_TRACE_LEVEL_ERROR is not set CONFIG_BT_LOG_A2D_TRACE_LEVEL_WARNING=y # CONFIG_BT_LOG_A2D_TRACE_LEVEL_API is not set # CONFIG_BT_LOG_A2D_TRACE_LEVEL_EVENT is not set # CONFIG_BT_LOG_A2D_TRACE_LEVEL_DEBUG is not set # CONFIG_BT_LOG_A2D_TRACE_LEVEL_VERBOSE is not set CONFIG_BT_LOG_A2D_TRACE_LEVEL=2 # CONFIG_BT_LOG_AVDT_TRACE_LEVEL_NONE is not set # CONFIG_BT_LOG_AVDT_TRACE_LEVEL_ERROR is not set CONFIG_BT_LOG_AVDT_TRACE_LEVEL_WARNING=y # CONFIG_BT_LOG_AVDT_TRACE_LEVEL_API is not set # CONFIG_BT_LOG_AVDT_TRACE_LEVEL_EVENT is not set # CONFIG_BT_LOG_AVDT_TRACE_LEVEL_DEBUG is not set # CONFIG_BT_LOG_AVDT_TRACE_LEVEL_VERBOSE is not set CONFIG_BT_LOG_AVDT_TRACE_LEVEL=2 # CONFIG_BT_LOG_AVCT_TRACE_LEVEL_NONE is not set # CONFIG_BT_LOG_AVCT_TRACE_LEVEL_ERROR is not set CONFIG_BT_LOG_AVCT_TRACE_LEVEL_WARNING=y # CONFIG_BT_LOG_AVCT_TRACE_LEVEL_API is not set # CONFIG_BT_LOG_AVCT_TRACE_LEVEL_EVENT is not set # CONFIG_BT_LOG_AVCT_TRACE_LEVEL_DEBUG is not set # CONFIG_BT_LOG_AVCT_TRACE_LEVEL_VERBOSE is not set CONFIG_BT_LOG_AVCT_TRACE_LEVEL=2 # CONFIG_BT_LOG_AVRC_TRACE_LEVEL_NONE is not set # CONFIG_BT_LOG_AVRC_TRACE_LEVEL_ERROR is not set CONFIG_BT_LOG_AVRC_TRACE_LEVEL_WARNING=y # CONFIG_BT_LOG_AVRC_TRACE_LEVEL_API is not set # CONFIG_BT_LOG_AVRC_TRACE_LEVEL_EVENT is not set # CONFIG_BT_LOG_AVRC_TRACE_LEVEL_DEBUG is not set # CONFIG_BT_LOG_AVRC_TRACE_LEVEL_VERBOSE is not set CONFIG_BT_LOG_AVRC_TRACE_LEVEL=2 # CONFIG_BT_LOG_MCA_TRACE_LEVEL_NONE is not set # CONFIG_BT_LOG_MCA_TRACE_LEVEL_ERROR is not set CONFIG_BT_LOG_MCA_TRACE_LEVEL_WARNING=y # CONFIG_BT_LOG_MCA_TRACE_LEVEL_API is not set # CONFIG_BT_LOG_MCA_TRACE_LEVEL_EVENT is not set # CONFIG_BT_LOG_MCA_TRACE_LEVEL_DEBUG is not set # CONFIG_BT_LOG_MCA_TRACE_LEVEL_VERBOSE is not set CONFIG_BT_LOG_MCA_TRACE_LEVEL=2 # CONFIG_BT_LOG_HID_TRACE_LEVEL_NONE is not set # CONFIG_BT_LOG_HID_TRACE_LEVEL_ERROR is not set CONFIG_BT_LOG_HID_TRACE_LEVEL_WARNING=y # CONFIG_BT_LOG_HID_TRACE_LEVEL_API is not set # CONFIG_BT_LOG_HID_TRACE_LEVEL_EVENT is not set # CONFIG_BT_LOG_HID_TRACE_LEVEL_DEBUG is not set # CONFIG_BT_LOG_HID_TRACE_LEVEL_VERBOSE is not set CONFIG_BT_LOG_HID_TRACE_LEVEL=2 # CONFIG_BT_LOG_APPL_TRACE_LEVEL_NONE is not set # CONFIG_BT_LOG_APPL_TRACE_LEVEL_ERROR is not set CONFIG_BT_LOG_APPL_TRACE_LEVEL_WARNING=y # CONFIG_BT_LOG_APPL_TRACE_LEVEL_API is not set # CONFIG_BT_LOG_APPL_TRACE_LEVEL_EVENT is not set # CONFIG_BT_LOG_APPL_TRACE_LEVEL_DEBUG is not set # CONFIG_BT_LOG_APPL_TRACE_LEVEL_VERBOSE is not set CONFIG_BT_LOG_APPL_TRACE_LEVEL=2 # CONFIG_BT_LOG_GATT_TRACE_LEVEL_NONE is not set # CONFIG_BT_LOG_GATT_TRACE_LEVEL_ERROR is not set CONFIG_BT_LOG_GATT_TRACE_LEVEL_WARNING=y # CONFIG_BT_LOG_GATT_TRACE_LEVEL_API is not set # CONFIG_BT_LOG_GATT_TRACE_LEVEL_EVENT is not set # CONFIG_BT_LOG_GATT_TRACE_LEVEL_DEBUG is not set # CONFIG_BT_LOG_GATT_TRACE_LEVEL_VERBOSE is not set CONFIG_BT_LOG_GATT_TRACE_LEVEL=2 # CONFIG_BT_LOG_SMP_TRACE_LEVEL_NONE is not set # CONFIG_BT_LOG_SMP_TRACE_LEVEL_ERROR is not set CONFIG_BT_LOG_SMP_TRACE_LEVEL_WARNING=y # CONFIG_BT_LOG_SMP_TRACE_LEVEL_API is not set # CONFIG_BT_LOG_SMP_TRACE_LEVEL_EVENT is not set # CONFIG_BT_LOG_SMP_TRACE_LEVEL_DEBUG is not set # CONFIG_BT_LOG_SMP_TRACE_LEVEL_VERBOSE is not set CONFIG_BT_LOG_SMP_TRACE_LEVEL=2 # CONFIG_BT_LOG_BTIF_TRACE_LEVEL_NONE is not set # CONFIG_BT_LOG_BTIF_TRACE_LEVEL_ERROR is not set CONFIG_BT_LOG_BTIF_TRACE_LEVEL_WARNING=y # CONFIG_BT_LOG_BTIF_TRACE_LEVEL_API is not set # CONFIG_BT_LOG_BTIF_TRACE_LEVEL_EVENT is not set # CONFIG_BT_LOG_BTIF_TRACE_LEVEL_DEBUG is not set # CONFIG_BT_LOG_BTIF_TRACE_LEVEL_VERBOSE is not set CONFIG_BT_LOG_BTIF_TRACE_LEVEL=2 # CONFIG_BT_LOG_BTC_TRACE_LEVEL_NONE is not set # CONFIG_BT_LOG_BTC_TRACE_LEVEL_ERROR is not set CONFIG_BT_LOG_BTC_TRACE_LEVEL_WARNING=y # CONFIG_BT_LOG_BTC_TRACE_LEVEL_API is not set # CONFIG_BT_LOG_BTC_TRACE_LEVEL_EVENT is not set # CONFIG_BT_LOG_BTC_TRACE_LEVEL_DEBUG is not set # CONFIG_BT_LOG_BTC_TRACE_LEVEL_VERBOSE is not set CONFIG_BT_LOG_BTC_TRACE_LEVEL=2 # CONFIG_BT_LOG_OSI_TRACE_LEVEL_NONE is not set # CONFIG_BT_LOG_OSI_TRACE_LEVEL_ERROR is not set CONFIG_BT_LOG_OSI_TRACE_LEVEL_WARNING=y # CONFIG_BT_LOG_OSI_TRACE_LEVEL_API is not set # CONFIG_BT_LOG_OSI_TRACE_LEVEL_EVENT is not set # CONFIG_BT_LOG_OSI_TRACE_LEVEL_DEBUG is not set # CONFIG_BT_LOG_OSI_TRACE_LEVEL_VERBOSE is not set CONFIG_BT_LOG_OSI_TRACE_LEVEL=2 # CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_NONE is not set # CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_ERROR is not set CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_WARNING=y # CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_API is not set # CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_EVENT is not set # CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_DEBUG is not set # CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_VERBOSE is not set CONFIG_BT_LOG_BLUFI_TRACE_LEVEL=2 # end of BT DEBUG LOG LEVEL CONFIG_BT_ACL_CONNECTIONS=4 CONFIG_BT_MULTI_CONNECTION_ENBALE=y # CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST is not set # CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY is not set # CONFIG_BT_BLE_HOST_QUEUE_CONG_CHECK is not set CONFIG_BT_SMP_ENABLE=y CONFIG_BT_SMP_MAX_BONDS=15 # CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 CONFIG_BT_MAX_DEVICE_NAME_LEN=32 CONFIG_BT_BLE_RPA_TIMEOUT=900 # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y # CONFIG_BT_BLE_HIGH_DUTY_ADV_INTERVAL is not set # CONFIG_BT_ABORT_WHEN_ALLOCATION_FAILS is not set # end of Bluedroid Options
最新发布
11-11
#include "ble_service.h" #include "ble_config.h" // 假设你自己实现了该配置模块 #include "esp_log.h" #include "esp_nimble_hci.h" #include "nimble/nimble_port.h" #include "nimble/nimble_port_freertos.h" #include "host/ble_hs.h" #include "host/util/util.h" #include "services/gap/ble_svc_gap.h" #include "services/gatt/ble_svc_gatt.h" #include <string.h> #include <stdio.h> // 如果你没有实现 ble_at_parse,请注释掉相关逻辑或替换为 dummy 函数 extern esp_err_t ble_at_parse(const char *at_cmd); // 声明外部 AT 解析函数 static const char *TAG = "BLE_SERVICE"; // ------------------------------- // UUID 定义:Nordic UART Service (NUS) 风格 // ------------------------------- // 主服务 UUID: 6E400001-B5A3-F393-E0A9-E50E24DCCA9E static const ble_uuid128_t gatt_svr_svc_uuid = BLE_UUID128_INIT( 0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x01, 0x00, 0x40, 0x6E); // 写特征 UUID: 6E400002-B5A3-F393-E0A9-E50E24DCCA9E static const ble_uuid128_t gatt_svr_chr_write_uuid = BLE_UUID128_INIT( 0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x02, 0x00, 0x40, 0x6E); // 读特征 UUID: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E static const ble_uuid128_t gatt_svr_chr_read_uuid = BLE_UUID128_INIT( 0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x03, 0x00, 0x40, 0x6E); // ------------------------------- // 全局变量 // ------------------------------- static ble_event_callback_t g_event_callback = NULL; static bool g_service_started = false; static bool g_device_connected = false; static uint16_t g_conn_handle = 0; // ⚠️ 关键:必须用指针接收 handle 分配! static uint16_t g_rx_val_handle; // 接收写入的 Characteristic Value Handle static uint16_t g_tx_val_handle; // 发送通知的 Characteristic Value Handle #define BLE_DATA_BUFFER_SIZE 512 static uint8_t g_data_buffer[BLE_DATA_BUFFER_SIZE]; // ------------------------------- // GATT 访问回调函数 // ------------------------------- /** * @brief 处理客户端对 WRITE 特征的写操作 */ static int characteristic_write_cb(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) { if (ctxt->op != BLE_GATT_ACCESS_OP_WRITE_CHR) { return BLE_ATT_ERR_UNLIKELY; } size_t data_len = OS_MBUF_PKTLEN(ctxt->om); if (data_len == 0 || data_len >= BLE_DATA_BUFFER_SIZE) { return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } // 将 mbuf 数据拷贝到缓冲区 int rc = ble_hs_mbuf_to_flat(ctxt->om, g_data_buffer, BLE_DATA_BUFFER_SIZE, &data_len); if (rc != 0) { ESP_LOGE(TAG, "Failed to flatten mbuf: %d", rc); return BLE_ATT_ERR_UNLIKELY; } g_data_buffer[data_len] = '\0'; ESP_LOGI(TAG, "Received write: %.*s", (int)data_len, g_data_buffer); // 根据当前模式处理 if (ble_config_get_mode() == BLE_MODE_CONFIG) { if (strcmp((char*)g_data_buffer, "+++") == 0) { ble_config_set_mode(BLE_MODE_CONFIG); if (g_event_callback) { g_event_callback(BLE_EVENT_CONFIG_MODE_ENTERED, NULL, 0); } ble_service_send_string("OK\r\n"); } else if (strncmp((char*)g_data_buffer, "AT+", 3) == 0) { esp_err_t ret = ble_at_parse((char*)g_data_buffer); ble_service_send_string(ret == ESP_OK ? "OK\r\n" : "ERR\r\n"); } } else { if (g_event_callback) { g_event_callback(BLE_EVENT_DATA_RECEIVED, g_data_buffer, data_len); } } return 0; } /** * @brief 处理 READ 特征的读请求(可选) */ static int characteristic_read_cb(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) { // 示例:返回静态字符串 const char *response = "Hello from BLE"; int len = strlen(response); os_mbuf_append(ctxt->om, response, len); return 0; } // ------------------------------- // GATT 服务定义 // ------------------------------- static const struct ble_gatt_svc_def gatt_svr_svcs[] = { { .type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = &gatt_svr_svc_uuid.u, .characteristics = (struct ble_gatt_chr_def[]) { [0] = { .uuid = &gatt_svr_chr_write_uuid.u, .access_cb = characteristic_write_cb, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ, }, [1] = { .uuid = &gatt_svr_chr_read_uuid.u, .access_cb = characteristic_read_cb, .flags = BLE_GATT_CHR_F_NOTIFY | BLE_GATT_CHR_F_READ, .val_handle = &g_tx_val_handle, // ✅ 自动填充 handle }, [2] = { 0 } // End of characteristics } }, { 0 // End of services } }; // ------------------------------- // GAP 事件处理器 // ------------------------------- static int gap_event_handler(struct ble_gap_event *event, void *arg) { switch (event->type) { case BLE_GAP_EVENT_CONNECT: ESP_LOGI(TAG, "BLE connected"); g_conn_handle = event->connect.conn_handle; g_device_connected = true; struct ble_gap_conn_desc desc; int rc = ble_gap_conn_find(g_conn_handle, &desc); if (rc == 0) { ESP_LOGI(TAG, "Conn interval=%dms latency=%d timeout=%dms", desc.conn_itvl * 1.25, desc.conn_latency, desc.supervision_timeout * 10); } if (g_event_callback) { g_event_callback(BLE_EVENT_CONNECTED, NULL, 0); } break; case BLE_GAP_EVENT_DISCONNECT: ESP_LOGI(TAG, "Disconnected, reason=%d", event->disconnect.reason); g_device_connected = false; g_conn_handle = 0; g_tx_val_handle = 0; // Reset handle if (g_event_callback) { g_event_callback(BLE_EVENT_DISCONNECTED, NULL, 0); } // 可选择重新广播 if (g_service_started) { ble_service_start(); } break; case BLE_GAP_EVENT_ADV_COMPLETE: ESP_LOGI(TAG, "Advertising stopped"); break; case BLE_GAP_EVENT_SUBSCRIBE: ESP_LOGI(TAG, "Client subscribed to notify: val_handle=%d new_value=%d", g_tx_val_handle, event->subscribe.cur_notify); break; default: break; } return 0; } // ------------------------------- // NimBLE 同步与重置回调 // ------------------------------- static void ble_on_sync(void) { ESP_LOGI(TAG, "BLE Host synced"); // 获取设备名 char device_name[64] = {0}; ble_config_get_param("BLE_NAME", device_name, sizeof(device_name)); if (strlen(device_name) == 0) { strcpy(device_name, "SUPER BLE123"); } ble_svc_gap_device_name_set(device_name); // 开始广播(如果已启用) if (g_service_started) { struct ble_gap_adv_params adv_params = {0}; struct ble_hs_adv_fields fields = {0}; fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP; fields.tx_pwr_lvl_is_present = 1; fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; fields.name = (uint8_t *)device_name; fields.name_len = strlen(device_name); fields.name_is_complete = 1; ble_gap_adv_set_fields(&fields); adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; int rc = ble_gap_adv_start(BLE_OWN_ADDR_TYPE_PUBLIC, NULL, BLE_HS_FOREVER, &adv_params, gap_event_handler, NULL); if (rc != 0) { ESP_LOGE(TAG, "Failed to start advertising: %d", rc); } else { ESP_LOGI(TAG, "Advertising started: %s", device_name); } } } static void ble_on_reset(int reason) { ESP_LOGE(TAG, "Resetting BLE stack, reason=%d", reason); } // ------------------------------- // 主机任务(由 nimble_port_freertos_init 调用) // ------------------------------- static void ble_host_task(void *param) { ESP_LOGI(TAG, "BLE Host Task Running"); nimble_port_run(); // 永久阻塞运行 nimble_port_freertos_deinit(); vTaskDelete(NULL); } // ------------------------------- // API 实现 // ------------------------------- esp_err_t ble_service_init(ble_event_callback_t callback) { if (g_service_started) { ESP_LOGW(TAG, "Already initialized"); return ESP_ERR_INVALID_STATE; } g_event_callback = callback; // 初始化 HCI 层 esp_err_t ret = esp_nimble_hci_and_controller_init(); if (ret != ESP_OK) { ESP_LOGE(TAG, "HCI init failed: %s", esp_err_to_name(ret)); return ret; } // 初始化 NimBLE 主机 nimble_port_init(); // 设置回调 ble_hs_cfg.sync_cb = ble_on_sync; ble_hs_cfg.reset_cb = ble_on_reset; // 注册 GATT 服务 int rc = ble_gatts_count_cfg(gatt_svr_svcs); if (rc != 0) { ESP_LOGE(TAG, "Service count failed: %d", rc); goto err; } rc = ble_gatts_add_svcs(gatt_svr_svcs); if (rc != 0) { ESP_LOGE(TAG, "Add services failed: %d", rc); goto err; } // 启动主机任务 nimble_port_freertos_init(ble_host_task); ESP_LOGI(TAG, "BLE service initialized"); return ESP_OK; err: esp_nimble_hci_and_controller_deinit(); return ESP_FAIL; } esp_err_t ble_service_start(void) { if (g_service_started) { ESP_LOGW(TAG, "Already started"); return ESP_ERR_INVALID_STATE; } g_service_started = true; if (ble_hs_is_enabled()) { ble_on_sync(); // 手动触发同步流程 } return ESP_OK; } esp_err_t ble_service_stop(void) { if (!g_service_started) { return ESP_ERR_INVALID_STATE; } ble_gap_adv_stop(); if (g_device_connected) { ble_gap_terminate(g_conn_handle, BLE_ERR_REM_USER_CONN_TERM); } g_service_started = false; g_device_connected = false; ESP_LOGI(TAG, "BLE service stopped"); return ESP_OK; } esp_err_t ble_service_send_data(const uint8_t *data, size_t length) { if (!g_service_started || !g_device_connected) { ESP_LOGW(TAG, "Not connected or not started"); return ESP_ERR_INVALID_STATE; } if (!data || length == 0) { return ESP_ERR_INVALID_ARG; } if (g_tx_val_handle == 0) { ESP_LOGE(TAG, "TX handle not assigned yet!"); return ESP_ERR_INVALID_STATE; } int rc = ble_gattc_notify_custom(g_conn_handle, g_tx_val_handle, length, (uint8_t *)data); if (rc != 0) { ESP_LOGE(TAG, "Notify failed: %d", rc); return ESP_FAIL; } ESP_LOGD(TAG, "Sent %zu bytes via notify", length); return ESP_OK; } esp_err_t ble_service_send_string(const char *str) { if (!str) return ESP_ERR_INVALID_ARG; return ble_service_send_data((const uint8_t *)str, strlen(str)); } esp_err_t ble_service_send_at_response(const char *response) { return ble_service_send_string(response); } bool ble_service_is_connected(void) { return g_device_connected; } ble_config_t* ble_service_get_config(void) { // 假设你有一个全局配置对象,否则请实现它 extern ble_config_t g_ble_config; return &g_ble_config; } In file included from C:/Espressif/frameworks/esp-idf-v5.3.1/components/bt/host/nimble/nimble/porting/nimble/include/modlog/modlog.h:30, from C:/Espressif/frameworks/esp-idf-v5.3.1/components/bt/host/nimble/nimble/nimble/host/include/host/ble_hs_log.h:36, from C:/Espressif/frameworks/esp-idf-v5.3.1/components/bt/host/nimble/nimble/nimble/host/include/host/ble_hs.h:38: E:/espdemo/LED/components/BLE/ble_service.c: In function 'gap_event_handler': C:/Espressif/frameworks/esp-idf-v5.3.1/components/log/include/esp_log.h:290:27: error: format '%d' expects argument of type 'int', but argument 6 has type 'double' [-Werror=format=] 290 | #define LOG_COLOR(COLOR) "\033[0;" COLOR "m" | ^~~~~~~~~ C:/Espressif/frameworks/esp-idf-v5.3.1/components/log/include/esp_log.h:293:27: note: in expansion of macro 'LOG_COLOR' 293 | #define LOG_COLOR_E LOG_COLOR(LOG_COLOR_RED) | ^~~~~~~~~ C:/Espressif/frameworks/esp-idf-v5.3.1/components/log/include/esp_log.h:307:37: note: in expansion of macro 'LOG_COLOR_E' 307 | #define LOG_FORMAT(letter, format) LOG_COLOR_ ## letter #letter " (%" PRIu32 ") %s: " format LOG_RESET_COLOR "\n" | ^~~~~~~~~~ C:/Espressif/frameworks/esp-idf-v5.3.1/components/log/include/esp_log.h:435:86: note: in expansion of macro 'LOG_FORMAT' 435 | if (level==ESP_LOG_ERROR ) { esp_log_write(ESP_LOG_ERROR, tag, LOG_FORMAT(E, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } \ | ^~~~~~~~~~ C:/Espressif/frameworks/esp-idf-v5.3.1/components/log/include/esp_log.h:463:41: note: in expansion of macro 'ESP_LOG_LEVEL' 463 | if ( LOG_LOCAL_LEVEL >= level ) ESP_LOG_LEVEL(level, tag, format, ##__VA_ARGS__); \ | ^~~~~~~~~~~~~ C:/Espressif/frameworks/esp-idf-v5.3.1/components/log/include/esp_log.h:367:38: note: in expansion of macro 'ESP_LOG_LEVEL_LOCAL' 367 | #define ESP_LOGI( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_INFO, tag, format, ##__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~ E:/espdemo/LED/components/BLE/ble_service.c:165:17: note: in expansion of macro 'ESP_LOGI' 165 | ESP_LOGI(TAG, "Conn interval=%dms latency=%d timeout=%dms", | ^~~~~~~~ C:/Espressif/frameworks/esp-idf-v5.3.1/components/log/include/esp_log.h:290:27: error: format '%d' expects argument of type 'int', but argument 6 has type 'double' [-Werror=format=] 290 | #define LOG_COLOR(COLOR) "\033[0;" COLOR "m" | ^~~~~~~~~ C:/Espressif/frameworks/esp-idf-v5.3.1/components/log/include/esp_log.h:294:27: note: in expansion of macro 'LOG_COLOR' 294 | #define LOG_COLOR_W LOG_COLOR(LOG_COLOR_BROWN) | ^~~~~~~~~ C:/Espressif/frameworks/esp-idf-v5.3.1/components/log/include/esp_log.h:307:37: note: in expansion of macro 'LOG_COLOR_W' 307 | #define LOG_FORMAT(letter, format) LOG_COLOR_ ## letter #letter " (%" PRIu32 ") %s: " format LOG_RESET_COLOR "\n" | ^~~~~~~~~~ C:/Espressif/frameworks/esp-idf-v5.3.1/components/log/include/esp_log.h:436:86: note: in expansion of macro 'LOG_FORMAT' 436 | else if (level==ESP_LOG_WARN ) { esp_log_write(ESP_LOG_WARN, tag, LOG_FORMAT(W, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } \ | ^~~~~~~~~~ C:/Espressif/frameworks/esp-idf-v5.3.1/components/log/include/esp_log.h:463:41: note: in expansion of macro 'ESP_LOG_LEVEL' 463 | if ( LOG_LOCAL_LEVEL >= level ) ESP_LOG_LEVEL(level, tag, format, ##__VA_ARGS__); \ | ^~~~~~~~~~~~~ C:/Espressif/frameworks/esp-idf-v5.3.1/components/log/include/esp_log.h:367:38: note: in expansion of macro 'ESP_LOG_LEVEL_LOCAL' 367 | #define ESP_LOGI( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_INFO, tag, format, ##__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~ E:/espdemo/LED/components/BLE/ble_service.c:165:17: note: in expansion of macro 'ESP_LOGI' 165 | ESP_LOGI(TAG, "Conn interval=%dms latency=%d timeout=%dms", | ^~~~~~~~ E:/espdemo/LED/components/BLE/ble_service.c:168:1: error: format '%d' expects argument of type 'int', but argument 6 has type 'double' [-Werror=format=] 168 | desc.supervision_timeout * 10); | ^ C:/Espressif/frameworks/esp-idf-v5.3.1/components/log/include/esp_log.h:307:59: note: in definition of macro 'LOG_FORMAT' 307 | #define LOG_FORMAT(letter, format) LOG_COLOR_ ## letter #letter " (%" PRIu32 ") %s: " format LOG_RESET_COLOR "\n" | ^~~~~~ C:/Espressif/frameworks/esp-idf-v5.3.1/components/log/include/esp_log.h:463:41: note: in expansion of macro 'ESP_LOG_LEVEL' 463 | if ( LOG_LOCAL_LEVEL >= level ) ESP_LOG_LEVEL(level, tag, format, ##__VA_ARGS__); \ | ^~~~~~~~~~~~~ C:/Espressif/frameworks/esp-idf-v5.3.1/components/log/include/esp_log.h:367:38: note: in expansion of macro 'ESP_LOG_LEVEL_LOCAL' 367 | #define ESP_LOGI( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_INFO, tag, format, ##__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~ E:/espdemo/LED/components/BLE/ble_service.c:165:17: note: in expansion of macro 'ESP_LOGI' 165 | ESP_LOGI(TAG, "Conn interval=%dms latency=%d timeout=%dms", | ^~~~~~~~ E:/espdemo/LED/components/BLE/ble_service.c:168:1: error: format '%d' expects argument of type 'int', but argument 6 has type 'double' [-Werror=format=] 168 | desc.supervision_timeout * 10); | ^ C:/Espressif/frameworks/esp-idf-v5.3.1/components/log/include/esp_log.h:307:59: note: in definition of macro 'LOG_FORMAT' 307 | #define LOG_FORMAT(letter, format) LOG_COLOR_ ## letter #letter " (%" PRIu32 ") %s: " format LOG_RESET_COLOR "\n" | ^~~~~~ C:/Espressif/frameworks/esp-idf-v5.3.1/components/log/include/esp_log.h:463:41: note: in expansion of macro 'ESP_LOG_LEVEL' 463 | if ( LOG_LOCAL_LEVEL >= level ) ESP_LOG_LEVEL(level, tag, format, ##__VA_ARGS__); \ | ^~~~~~~~~~~~~ C:/Espressif/frameworks/esp-idf-v5.3.1/components/log/include/esp_log.h:367:38: note: in expansion of macro 'ESP_LOG_LEVEL_LOCAL' 367 | #define ESP_LOGI( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_INFO, tag, format, ##__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~ E:/espdemo/LED/components/BLE/ble_service.c:165:17: note: in expansion of macro 'ESP_LOGI' 165 | ESP_LOGI(TAG, "Conn interval=%dms latency=%d timeout=%dms", | ^~~~~~~~ C:/Espressif/frameworks/esp-idf-v5.3.1/components/log/include/esp_log.h:290:27: error: format '%d' expects argument of type 'int', but argument 6 has type 'double' [-Werror=format=] 290 | #define LOG_COLOR(COLOR) "\033[0;" COLOR "m" | ^~~~~~~~~ C:/Espressif/frameworks/esp-idf-v5.3.1/components/log/include/esp_log.h:295:27: note: in expansion of macro 'LOG_COLOR' 295 | #define LOG_COLOR_I LOG_COLOR(LOG_COLOR_GREEN) | ^~~~~~~~~ C:/Espressif/frameworks/esp-idf-v5.3.1/components/log/include/esp_log.h:307:37: note: in expansion of macro 'LOG_COLOR_I' 307 | #define LOG_FORMAT(letter, format) LOG_COLOR_ ## letter #letter " (%" PRIu32 ") %s: " format LOG_RESET_COLOR "\n" | ^~~~~~~~~~ C:/Espressif/frameworks/esp-idf-v5.3.1/components/log/include/esp_log.h:439:86: note: in expansion of macro 'LOG_FORMAT' 439 | else { esp_log_write(ESP_LOG_INFO, tag, LOG_FORMAT(I, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } \ | ^~~~~~~~~~ C:/Espressif/frameworks/esp-idf-v5.3.1/components/log/include/esp_log.h:463:41: note: in expansion of macro 'ESP_LOG_LEVEL' 463 | if ( LOG_LOCAL_LEVEL >= level ) ESP_LOG_LEVEL(level, tag, format, ##__VA_ARGS__); \ | ^~~~~~~~~~~~~ C:/Espressif/frameworks/esp-idf-v5.3.1/components/log/include/esp_log.h:367:38: note: in expansion of macro 'ESP_LOG_LEVEL_LOCAL' 367 | #define ESP_LOGI( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_INFO, tag, format, ##__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~ E:/espdemo/LED/components/BLE/ble_service.c:165:17: note: in expansion of macro 'ESP_LOGI' 165 | ESP_LOGI(TAG, "Conn interval=%dms latency=%d timeout=%dms", | ^~~~~~~~ E:/espdemo/LED/components/BLE/ble_service.c: In function 'ble_on_sync': E:/espdemo/LED/components/BLE/ble_service.c:243:36: error: 'BLE_OWN_ADDR_TYPE_PUBLIC' undeclared (first use in this function); did you mean 'BLE_OWN_ADDR_PUBLIC'? 243 | int rc = ble_gap_adv_start(BLE_OWN_ADDR_TYPE_PUBLIC, NULL, BLE_HS_FOREVER, | ^~~~~~~~~~~~~~~~~~~~~~~~ | BLE_OWN_ADDR_PUBLIC E:/espdemo/LED/components/BLE/ble_service.c:243:36: note: each undeclared identifier is reported only once for each function it appears in E:/espdemo/LED/components/BLE/ble_service.c: In function 'ble_service_init': E:/espdemo/LED/components/BLE/ble_service.c:286:21: error: implicit declaration of function 'esp_nimble_hci_and_controller_init' [-Werror=implicit-function-declaration] 286 | esp_err_t ret = esp_nimble_hci_and_controller_init(); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ E:/espdemo/LED/components/BLE/ble_service.c:319:5: error: implicit declaration of function 'esp_nimble_hci_and_controller_deinit' [-Werror=implicit-function-declaration] 319 | esp_nimble_hci_and_controller_deinit(); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ E:/espdemo/LED/components/BLE/ble_service.c: In function 'ble_service_send_data': E:/espdemo/LED/components/BLE/ble_service.c:372:70: warning: passing argument 3 of 'ble_gattc_notify_custom' makes pointer from integer without a cast [-Wint-conversion] 372 | int rc = ble_gattc_notify_custom(g_conn_handle, g_tx_val_handle, length, (uint8_t *)data); | ^~~~~~ | | | size_t {aka unsigned int} In file included from C:/Espressif/frameworks/esp-idf-v5.3.1/components/bt/host/nimble/nimble/nimble/host/include/host/ble_hs.h:34: C:/Espressif/frameworks/esp-idf-v5.3.1/components/bt/host/nimble/nimble/nimble/host/include/host/ble_gatt.h:858:45: note: expected 'struct os_mbuf *' but argument is of type 'size_t' {aka 'unsigned int'} 858 | struct os_mbuf *om); | ~~~~~~~~~~~~~~~~^~ E:/espdemo/LED/components/BLE/ble_service.c:372:14: error: too many arguments to function 'ble_gattc_notify_custom' 372 | int rc = ble_gattc_notify_custom(g_conn_handle, g_tx_val_handle, length, (uint8_t *)data); | ^~~~~~~~~~~~~~~~~~~~~~~ C:/Espressif/frameworks/esp-idf-v5.3.1/components/bt/host/nimble/nimble/nimble/host/include/host/ble_gatt.h:857:5: note: declared here 857 | int ble_gattc_notify_custom(uint16_t conn_handle, uint16_t att_handle, | ^~~~~~~~~~~~~~~~~~~~~~~ E:/espdemo/LED/components/BLE/ble_service.c: At top level: E:/espdemo/LED/components/BLE/ble_service.c:50:17:
10-24
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值