# at-ble-client **Repository Path**: XiaoPb/at-ble-client ## Basic Information - **Project Name**: at-ble-client - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-03-30 - **Last Updated**: 2026-04-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # AT BLE Client A C++17 library for controlling BLE devices using AT commands, providing a high-level abstraction over ESP-AT BLE command set. ## Features - **High-level BLE API**: Device management, GATT operations, connection management - **AT Command Engine**: Asynchronous command execution with timeout and retry - **Event-driven**: Asynchronous event handling for BLE notifications - **Cross-platform**: Windows and Linux support - **Extensible**: Easy to add new AT commands and chip variants ## Architecture ``` ┌─────────────────────────────────────────────────────────────┐ │ User Application │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ High-level API Layer │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │ │ │DeviceManager│ │GattManager │ │ConnectionManager │ │ │ │- Scan │ │- Services │ │- Connect/Disconnect │ │ │ │- Advertise │ │- Read/Write│ │- MTU/Parameters │ │ │ │- Address │ │- Notify │ │- PHY/RSSI │ │ │ └─────────────┘ └─────────────┘ └─────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ Protocol Mapping Layer │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ AT Command <-> BLE Operation Mapping │ │ │ │ - Command templates and parameter encoding │ │ │ │ - Response parsing and event generation │ │ │ │ - Asynchronous notification handling │ │ │ └──────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ AT Command Execution Engine │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │ │ │Command Queue│ │Response │ │Timeout & Retry │ │ │ │- Priority │ │Matching │ │- Configurable │ │ │ │- Sequential │ │- Async │ │- Backoff Strategy │ │ │ └─────────────┘ └─────────────┘ └─────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ Transport Layer (Pluggable) │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ Serial/UART/USB/Socket Transport │ │ │ │ - Configurable baud rate, ports │ │ │ │ - Platform-specific implementations │ │ │ └──────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ ``` ### 模块交互图 ``` ┌──────────────────────────────────────────┐ │ AtBleHost │ │ (主入口,协调各模块) │ └──────────────────────────────────────────┘ │ ┌───────────────────────────┼───────────────────────────┐ │ │ │ ▼ ▼ ▼ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ BleDeviceManager │ │BleConnectionManager│ │ BleGattManager │ │ │ │ │ │ │ │ - initBle() │ │ - connect() │ │ - discoverServices() │ │ - startScan() │ │ - disconnect() │ │ - readCharacteristic() │ │ - stopScan() │ │ - updateParams() │ │ - writeCharacteristic() │ │ - setName() │ │ - getMtu() │ │ - enableNotification() │ │ - getAddress() │ │ - getRssi() │ │ - disableNotification() │ └──────────────────┘ └──────────────────┘ └──────────────────┘ │ │ │ └───────────────────────────┼───────────────────────────┘ │ ▼ ┌──────────────────┐ │ AtCommandEngine │ │ │ │ - sendCommand() │ │ - sendCommandAsync() │ │ - setRetryPolicy() │ └──────────────────┘ │ ▼ ┌──────────────────┐ │ ITransport │ │ (传输抽象接口) │ └──────────────────┘ │ ┌────────────┴────────────┐ ▼ ▼ ┌──────────────────┐ ┌──────────────────┐ │ SerialTransport │ │ 自定义 Transport │ │ (串口实现) │ │ (用户扩展) │ └──────────────────┘ └──────────────────┘ ``` ### 数据流说明 #### 命令发送流程(同步) ``` 用户调用 API │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ 1. Manager 方法(如 gattMgr.readCharacteristic()) │ │ - 参数验证 │ │ - 构建 AT 命令字符串 │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ 2. AtCommandEngine::sendCommand() │ │ - 设置命令状态为 SENT │ │ - 发送命令到 Transport │ │ - 等待响应(带超时) │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ 3. Transport::sendData() │ │ - 将数据写入串口/套接字 │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ 4. ESP-AT 模块处理并返回响应 │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ 5. Transport 读取线程接收数据 │ │ - 触发 DataReceivedCallback │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ 6. AtBleHost::onDataReceived() │ │ - 数据转换为字符串 │ │ - 按行分割并解析 │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ 7. AtParser::parseLine() │ │ - 解析 AT 响应格式 │ │ - 返回 AtParseResult │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ 8. AtCommandEngine 匹配响应 │ │ - 设置命令状态为 COMPLETED │ │ - 返回 AtCommandResult │ └─────────────────────────────────────────────────────────────┘ │ ▼ 返回结果给用户 ``` #### 事件通知流程(异步) ``` ESP-AT 模块主动发送事件 │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ 1. Transport 读取线程接收数据 │ │ - 触发 DataReceivedCallback │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ 2. AtBleHost::onDataReceived() │ │ - 解析事件类型 │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ 3. AtBleHost::dispatchEvent() │ │ - 分发到对应的 Manager │ │ - 触发用户注册的回调 │ └─────────────────────────────────────────────────────────────┘ │ ▼ 用户回调函数执行 ``` ### 线程模型说明 ``` ┌─────────────────────────────────────────────────────────────┐ │ 用户线程 (Main Thread) │ │ │ │ - 调用 API 方法 │ │ - 同步等待命令响应 │ │ - 处理业务逻辑 │ │ │ │ 注意:同步 API 会阻塞当前线程直到收到响应或超时 │ └─────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────┐ │ 传输读取线程 (Read Thread) │ │ │ │ - 由 SerialTransport 创建和管理 │ │ - 持续读取串口/套接字数据 │ │ - 触发 DataReceivedCallback │ │ │ │ 注意:回调函数在此线程执行,需注意线程安全 │ └─────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────┐ │ 回调执行上下文 │ │ │ │ 扫描回调、连接状态回调、通知回调等在读取线程中执行 │ │ │ │ 建议: │ │ - 回调中避免耗时操作 │ │ - 使用队列将事件传递到用户线程处理 │ │ - 注意共享数据的同步访问 │ └─────────────────────────────────────────────────────────────┘ ``` #### 线程安全注意事项 | 组件 | 线程安全性 | 说明 | |------|-----------|------| | AtCommandEngine | 部分安全 | 命令发送有互斥保护,但同一时间只能执行一个命令 | | Transport | 安全 | 读写操作有线程保护 | | Manager 类 | 非线程安全 | 回调在读取线程执行,与主线程并发访问需加锁 | | 回调函数 | 用户负责 | 回调在读取线程执行,访问共享数据需同步 | #### 推荐的线程模型 ```cpp std::mutex dataMutex; std::queue eventQueue; std::condition_variable eventCv; void onNotification(ConnectionIndex connIdx, CharacteristicHandle handle, const std::vector& data) { std::lock_guard lock(dataMutex); eventQueue.push(BleEvent{connIdx, handle, data}); eventCv.notify_one(); } void processEvents() { while (running) { std::unique_lock lock(dataMutex); eventCv.wait(lock, []{ return !eventQueue.empty(); }); auto event = eventQueue.front(); eventQueue.pop(); lock.unlock(); processEvent(event); } } ``` ## Requirements - C++17 compatible compiler - CMake 3.16+ - Windows: Visual Studio 2019+ or MinGW - Linux: GCC 7+ or Clang 5+ ## Building ```bash mkdir build cd build cmake .. make ``` ## Usage ### Basic Setup ```cpp #include "at_ble_host.h" // Create transport (e.g., serial port) auto transport = std::make_unique("COM3", 115200); // Create BLE host AtBleHost bleHost(std::move(transport)); bleHost.initialize(); // Get managers auto& deviceMgr = bleHost.getDeviceManager(); auto& connMgr = bleHost.getConnectionManager(); auto& gattMgr = bleHost.getGattManager(); ``` ### Device Management ```cpp // Initialize as client deviceMgr.initBle(BleRole::CLIENT); // Set device name deviceMgr.setName("My BLE Device"); // Start scanning ScanParameters scanParams{1, BleAddressType::PUBLIC, 0, 100, 50}; deviceMgr.startScan(scanParams, [](const BleDeviceInfo& device) { std::cout << "Found device: " << device.name.value_or("Unknown") << " RSSI: " << (int)device.rssi << std::endl; }); // Stop scanning deviceMgr.stopScan(); ``` ### Connection Management ```cpp // Connect to device BleAddress targetAddr = {0xf8, 0x7f, 0x24, 0x87, 0x1c, 0x7b}; connMgr.connect(targetAddr); // Set connection callback connMgr.setConnectionStateCallback([](ConnectionIndex connIdx, bool connected, const BleAddress& addr) { if (connected) { std::cout << "Connected to device" << std::endl; } else { std::cout << "Disconnected" << std::endl; } }); // Update connection parameters ConnectionParameters params{6, 12, 0, 500}; connMgr.updateConnectionParameters(0, params); ``` ### GATT Operations ```cpp // Discover services gattMgr.discoverServices(0); // Set discovery callbacks gattMgr.setServiceDiscoveredCallback([](ConnectionIndex connIdx, const GattService& service) { std::cout << "Service discovered: " << service.uuid.toString() << std::endl; }); gattMgr.setCharacteristicDiscoveredCallback([](ConnectionIndex connIdx, const GattCharacteristic& characteristic) { std::cout << "Characteristic discovered: " << characteristic.uuid.toString() << std::endl; }); // Read characteristic auto data = gattMgr.readCharacteristic(0, 0x002A); std::cout << "Read data: " << bytesToHexString(data) << std::endl; // Write characteristic std::vector writeData = {0x01, 0x02, 0x03}; gattMgr.writeCharacteristic(0, 0x002A, writeData); // Enable notifications gattMgr.enableNotification(0, 0x002A); gattMgr.setDataReceivedCallback([](ConnectionIndex connIdx, CharacteristicHandle handle, const std::vector& data) { std::cout << "Notification received on handle " << handle << ": " << bytesToHexString(data) << std::endl; }); ``` ### Raw AT Commands ```cpp // Send raw AT command auto result = bleHost.sendRawCommand("AT+BLEINIT?"); if (result.success) { std::cout << "Response: " << result.response << std::endl; } ``` ## API Reference ### AtBleHost Main entry point for BLE operations. - `AtBleHost(std::unique_ptr)`: Constructor - `void initialize()`: Initialize the BLE host - `IBleDeviceManager& getDeviceManager()`: Get device manager - `IBleConnectionManager& getConnectionManager()`: Get connection manager - `IBleGattManager& getGattManager()`: Get GATT manager - `AtCommandResult sendRawCommand(const std::string&)`: Send raw AT command ### IBleDeviceManager Device management interface. - `void initBle(BleRole)`: Initialize BLE role - `BleAddress getAddress()`: Get device address - `void setAddress(BleAddressType, BleAddress)`: Set device address - `std::string getName()`: Get device name - `void setName(const std::string&)`: Set device name - `void startScan(ScanParameters, DeviceFoundCallback)`: Start scanning - `void stopScan()`: Stop scanning - `void startAdvertising(AdvertisementParameters, AdvertisementData)`: Start advertising - `void stopAdvertising()`: Stop advertising ### IBleConnectionManager Connection management interface. - `void connect(BleAddress, BleAddressType, int timeout)`: Connect to device - `void disconnect(ConnectionIndex)`: Disconnect - `std::vector> getConnections()`: Get active connections - `ConnectionParameters getConnectionParameters(ConnectionIndex)`: Get connection parameters - `void updateConnectionParameters(ConnectionIndex, ConnectionParameters)`: Update parameters - `MtuSize getMtu(ConnectionIndex)`: Get MTU - `void setMtu(ConnectionIndex, MtuSize)`: Set MTU - `BlePhy getPhy(ConnectionIndex)`: Get PHY - `void setPhy(ConnectionIndex, BlePhy)`: Set PHY - `RssiValue getRssi(ConnectionIndex)`: Get RSSI ### IBleGattManager GATT operations interface. - `void discoverServices(ConnectionIndex)`: Discover services - `void discoverCharacteristics(ConnectionIndex, ServiceHandle)`: Discover characteristics - `std::vector readCharacteristic(ConnectionIndex, CharacteristicHandle)`: Read characteristic - `void writeCharacteristic(ConnectionIndex, CharacteristicHandle, const std::vector&)`: Write characteristic - `void enableNotification(ConnectionIndex, CharacteristicHandle)`: Enable notifications - `void disableNotification(ConnectionIndex, CharacteristicHandle)`: Disable notifications - `void enableIndication(ConnectionIndex, CharacteristicHandle)`: Enable indications - `void disableIndication(ConnectionIndex, CharacteristicHandle)`: Disable indications ## Testing ### Unit Tests ```bash cd build ctest ``` ### Hardware Validation Test A comprehensive hardware validation test program is provided to verify BLE functionality with real hardware. #### Building the Test Program ```bash cmake --build build --config Release --target test_ble_validation ``` #### Running the Test ```bash # Default: COM4 at 921600 baud build\test\Release\test_ble_validation.exe # Custom port and baud rate build\test\Release\test_ble_validation.exe COM3 115200 ``` #### Test Commands The test program provides an interactive menu: | Command | Description | |---------|-------------| | `init` | Initialize BLE module (Client mode) and display module info | | `scan` | Scan BLE devices for 10 seconds | | `connect` | Connect to a BLE device | | `disconnect` | Disconnect current connection | | `info` | Display current connection information | | `help` | Show available commands | | `quit` | Exit program | #### Test Log The test program automatically saves all output to a log file with timestamp: - **Format**: `ble_test_YYYYMMDD_HHMMSS.log` - **Location**: Same directory as the executable - **Content**: All test output including commands, responses, and events #### Example Test Session ``` BLE Module Test Validation Program =================================== Log File: ble_test_20260331_160226.log Serial Port: COM4 Baud Rate: 921600 [Serial] Opening port COM4 at 921600 baud... [Serial] Port COM4 opened successfully [Serial] Connected to COM4 at 921600 baud Enter command: init [BLE] Initializing BLE module... [BLE] Module initialized (Client mode) [Module Info] AT Version: 4.1.1.0(ba4dd0e - ESP32C3 - Jul 31 2025 08:38:07) SDK Version: v5.4.1-643-g8ad0d3d8f2-dirty Compile Time: Aug 1 2025 05:35:19 Bin Version: v4.1.1.0(MINI-1) BLE Address: 60:55:f9:79:65:1a Device Name: ESP-AT Free Heap: 66428 bytes Enter command: scan [BLE] Starting device scan (10 seconds)... [Device 1] Address: 75:eb:f2:c3:c4:f2, RSSI: -75 dBm [Device 2] Address: 80:3e:4f:7f:79:d9, RSSI: -70 dBm [SCAN] Complete! Found 2 device(s). [Discovered Devices] [1] 75:eb:f2:c3:c4:f2 (RSSI: -75 dBm) [2] 80:3e:4f:7f:79:d9 (RSSI: -70 dBm) ``` ## Recent Updates ### v1.1.0 (2026-03-31) #### Fixed Issues 1. **AT Command Response Parsing** - Fixed AT+GMR multi-line version information parsing - Fixed AT+BLEADDR address parsing with quoted format - Fixed AT+BLENAME name parsing - Fixed AT+SYSRAM heap memory parsing - Added `\r` character removal in response parsing 2. **BLE Event Dispatching** - Enabled event dispatching in `AtBleHost::dispatchEvent` - Fixed scan result callback notification - Fixed connection event callback notification - Fixed GATT event callback notification 3. **Regular Expression Improvements** - Updated regex patterns to support quoted addresses in responses - Fixed line ending handling in AT parser #### New Features 1. **Test Validation Program** - Interactive BLE hardware validation tool - Automatic log file generation with timestamps - Comprehensive test coverage for all BLE operations 2. **Enhanced Logging** - Serial port status logging - Received data logging with `[RX]` prefix - Event dispatching logging - English language log output for internationalization ## License MIT License ## Contributing 1. Fork the repository 2. Create a feature branch 3. Make changes 4. Add tests 5. Submit a pull request ## Supported ESP-AT Versions - ESP32 AT v2.2+ - ESP32-C2 AT v1.0+ - ESP32-C3 AT v2.0+ - ESP32-C5 AT v1.0+ - ESP32-C6 AT v1.0+ - ESP32-C61 AT v1.0+