微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ESP32 作为 BLE 服务器,无法配对 CyclicComputer

如何解决ESP32 作为 BLE 服务器,无法配对 CyclicComputer

我正在尝试使用 PlatformIO 和 NimBLE-Arduino 库在 ESP32 上创建循环供电服务。

当客户端是nRF Connect Android应用程序时,连接、绑定、订阅通知和接收功率数据都可以工作,但我的Lezyne GPS Mini Cyclic Computer无法完成配对过程。我正在寻找一种方法来解密日志并了解通信中的问题。

我的代码,减少到最低限度:

#include <Arduino.h>
#include <NimBLEDevice.h>

#define CYCLING_POWER_SERVICE_UUID ((uint16_t) 0x1818)
#define CYCLING_POWER_FEATURE_CHAR_UUID ((uint16_t) 0x2A65)
#define SENSOR_LOCATION_CHAR_UUID ((uint16_t) 0x2A5D)
#define SENSOR_LOCATION_RIGHT_CRANK ((uint8_t) 6)
#define CYCLING_POWER_MEASUREMENT_CHAR_UUID ((uint16_t) 0x2A63)

class BLE : public BLEServerCallbacks {
    public:
    BLEServer *server;
    BLECharacteristic *measurementCharacteristic;
    bool connected = false;
    bool oldConnected = false;
    
    short power = 0;
    unsigned short revolutions = 0;
    unsigned short timestamp = 0;
    const unsigned short flags = 0x20; // Todo

    unsigned char bufMeasurent[8];
    unsigned char bufSensorLocation[1];
    unsigned char bufControlPoint[1];
    unsigned char bufFeature[4];

    void setup() {
        BLEDevice::init("PM");
        server = BLEDevice::createServer();
        server->setCallbacks(this);
        bleuUID serviceUUID = bleuUID(CYCLING_POWER_SERVICE_UUID);
        BLEService *service = server->createService(serviceUUID);

        BLECharacteristic *featureCharasteristic = service->createCharacteristic(
            bleuUID(CYCLING_POWER_FEATURE_CHAR_UUID),NIMBLE_PROPERTY::READ
        );
        bufFeature[0] = 0xff;
        bufFeature[1] = 0xff;
        bufFeature[2] = 0xff;
        bufFeature[3] = 0xff; // Todo
        featureCharasteristic->setValue((uint8_t *)&bufFeature,4);
        
        BLECharacteristic *sensorLocationCharasteristic = service->createCharacteristic(
            bleuUID(SENSOR_LOCATION_CHAR_UUID),NIMBLE_PROPERTY::READ
        );
        bufSensorLocation[0] = SENSOR_LOCATION_RIGHT_CRANK & 0xff;
        sensorLocationCharasteristic->setValue((uint8_t *)bufSensorLocation,1);

        measurementCharacteristic = service->createCharacteristic(
            bleuUID(CYCLING_POWER_MEASUREMENT_CHAR_UUID),NIMBLE_PROPERTY::READ 
            | NIMBLE_PROPERTY::NOTIFY
            | NIMBLE_PROPERTY::INDICATE
        );
        
        service->start();
        BLEAdvertising *advertising = BLEDevice::getAdvertising();
        advertising->addServiceUUID(serviceUUID);
        BLEDevice::startAdvertising();
    }

    void loop() {
        // notify changed value
        if (connected) {
            bufMeasurent[0] = flags & 0xff;
            bufMeasurent[1] = (flags >> 8) & 0xff;
            bufMeasurent[2] = power & 0xff;
            bufMeasurent[3] = (power >> 8) & 0xff;
            bufMeasurent[4] = revolutions & 0xff;
            bufMeasurent[5] = (revolutions >> 8) & 0xff;
            bufMeasurent[6] = timestamp & 0xff;
            bufMeasurent[7] = (timestamp >> 8) & 0xff;

            measurementCharacteristic->setValue((uint8_t *)&bufMeasurent,8);
            measurementCharacteristic->notify();
            delay(1000); 
        }
        // disconnecting
        if (!connected && oldConnected) {
            delay(500); 
            server->startAdvertising();
            Serial.println("start advertising");
            oldConnected = connected;
        }
        // connecting
        if (connected && !oldConnected) {
            oldConnected = connected;
        }
    }

    void onConnect(BLEServer *pServer,ble_gap_conn_desc* desc) {
        connected = true;
        Serial.println("Server onConnect");
    }

    void ondisconnect(BLEServer *pServer) {
        connected = false;
        Serial.println("Server ondisconnect");
    }
};

BLE ble;

void setup() {
    Serial.begin(115200);
    ble.setup();
}

void loop() {
    if (ble.connected) {
        ble.power = random(300);
        ble.revolutions = random(2); 
        ble.timestamp = (ushort)millis();
        delay(100);
    }
    ble.loop();
}

启用 NimBLE 调试日志的日志:

entry 0x400806a8
ble_hs_hci_cmd_send: ogf=0x03 ocf=0x0003 len=0
0x03 0x0c 0x00 
ble_hs_hci_cmd_send: ogf=0x04 ocf=0x0001 len=0
0x01 0x10 0x00 
ble_hs_hci_cmd_send: ogf=0x04 ocf=0x0003 len=0
0x03 0x10 0x00 
ble_hs_hci_cmd_send: ogf=0x03 ocf=0x0001 len=8
0x01 0x0c 0x08 0x90 0x80 0x00 0x02 0x00 0x80 0x00 0x20 
ble_hs_hci_cmd_send: ogf=0x03 ocf=0x0063 len=8
0x63 0x0c 0x08 0x00 0x00 0x80 0x00 0x00 0x00 0x00 0x00 
ble_hs_hci_cmd_send: ogf=0x08 ocf=0x0001 len=8
0x01 0x20 0x08 0x7f 0x06 0x00 0x00 0x00 0x00 0x00 0x00 
ble_hs_hci_cmd_send: ogf=0x08 ocf=0x0002 len=0
0x02 0x20 0x00 
ble_hs_hci_cmd_send: ogf=0x08 ocf=0x0003 len=0
0x03 0x20 0x00 
ble_hs_hci_cmd_send: ogf=0x04 ocf=0x0009 len=0
0x09 0x10 0x00 
ble_hs_hci_cmd_send: ogf=0x08 ocf=0x0018 len=0
0x18 0x20 0x00 
ble_hs_hci_cmd_send: ogf=0x08 ocf=0x0018 len=0
0x18 0x20 0x00 
Device added to RL,Resolving list count = 1
ble_hs_hci_cmd_send: ogf=0x03 ocf=0x0031 len=1
0x31 0x0c 0x01 0x01 
ble_hs_hci_cmd_send: ogf=0x03 ocf=0x0033 len=7
0x33 0x0c 0x07 0xff 0x00 0x00 0x0c 0x00 0x00 0x00 
ble_hs_hci_cmd_send: ogf=0x03 ocf=0x0031 len=1
0x31 0x0c 0x01 0x00 
looking up peer sec; 
ble_hs_hci_cmd_send: ogf=0x08 ocf=0x0018 len=0
0x18 0x20 0x00 
ble_hs_hci_cmd_send: ogf=0x08 ocf=0x0018 len=0
0x18 0x20 0x00 
Device added to RL,Resolving list count = 2
looking up peer sec; 
ble_hs_hci_cmd_send: ogf=0x08 ocf=0x0009 len=32
0x09 0x20 0x20 0x00 0xa9 0xfb 0x3f 0x02 0x00 0x00 0x00 0x3c 0x1f 0xfc 0x3f 0xc0 0x46 0xfc 0x3f 0x01 0x24 0xf4 0x02 0xfd 0x1f 0x0d 0x80 0xe0 0x64 0xfc 0x3f 0xbc 0xbd 0xfb 0x3f 
ble_hs_hci_cmd_send: ogf=0x08 ocf=0x0008 len=32
0x08 0x20 0x20 0x0b 0x02 0x01 0x06 0x03 0x03 0x18 0x18 0x03 0x09 0x50 0x4d 0xc0 0x46 0xfc 0x3f 0x01 0x24 0xf4 0x02 0xfd 0x1f 0x0d 0x80 0xe0 0x64 0xfc 0x3f 0xbc 0xbd 0xfb 0x3f 
GAP procedure initiated: advertise; disc_mode=2 adv_channel_map=0 own_addr_type=0 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0
ble_hs_hci_cmd_send: ogf=0x08 ocf=0x0006 len=15
0x06 0x20 0x0f 0x30 0x00 0x60 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x07 0x00 
ble_hs_hci_cmd_send: ogf=0x08 ocf=0x000a len=1
0x0a 0x20 0x01 0x01 
Server onConnect
ble_hs_hci_cmd_send: ogf=0x08 ocf=0x0016 len=2
0x16 0x20 0x02 0x00 0x00 
ble_hs_hci_evt_acl_process(): conn_handle=0 pb=2 len=11 data=0x07 0x00 0x04 0x00 0x10 0x01 0x00 0xff 0xff 0x00 0x28 
host tx hci data; handle=0 length=24
ble_hs_hci_acl_tx(): 0x00 0x00 0x18 0x00 0x14 0x00 0x04 0x00 0x11 0x06 0x01 0x00 0x05 0x00 0x00 0x18 0x06 0x00 0x09 0x00 0x01 0x18 0x0a 0x00 0xff 0xff 0x18 0x18 
ble_hs_hci_evt_acl_process(): conn_handle=0 pb=2 len=11 data=0x07 0x00 0x04 0x00 0x10 0x06 0x00 0xff 0xff 0x00 0x28 
host tx hci data; handle=0 length=18
ble_hs_hci_acl_tx(): 0x00 0x00 0x12 0x00 0x0e 0x00 0x04 0x00 0x11 0x06 0x06 0x00 0x09 0x00 0x01 0x18 0x0a 0x00 0xff 0xff 0x18 0x18 
ble_hs_hci_evt_acl_process(): conn_handle=0 pb=2 len=11 data=0x07 0x00 0x04 0x00 0x10 0x0a 0x00 0xff 0xff 0x00 0x28 
host tx hci data; handle=0 length=12
ble_hs_hci_acl_tx(): 0x00 0x00 0x0c 0x00 0x08 0x00 0x04 0x00 0x11 0x06 0x0a 0x00 0xff 0xff 0x18 0x18 
ble_hs_hci_evt_acl_process(): conn_handle=0 pb=2 len=11 data=0x07 0x00 0x04 0x00 0x10 0x00 0x00 0xff 0xff 0x00 0x28 
host tx hci data; handle=0 length=9
ble_hs_hci_acl_tx(): 0x00 0x00 0x09 0x00 0x05 0x00 0x04 0x00 0x01 0x10 0x00 0x00 0x01 
ble_hs_hci_evt_acl_process(): conn_handle=0 pb=2 len=11 data=0x07 0x00 0x04 0x00 0x10 0x00 0x00 0xff 0xff 0x00 0x28 
host tx hci data; handle=0 length=9
ble_hs_hci_acl_tx(): 0x00 0x00 0x09 0x00 0x05 0x00 0x04 0x00 0x01 0x10 0x00 0x00 0x01 
ble_hs_hci_evt_acl_process(): conn_handle=0 pb=2 len=11 data=0x07 0x00 0x04 0x00 0x10 0x00 0x00 0xff 0xff 0x00 0x28 
host tx hci data; handle=0 length=9
ble_hs_hci_acl_tx(): 0x00 0x00 0x09 0x00 0x05 0x00 0x04 0x00 0x01 0x10 0x00 0x00 0x01 
ble_hs_hci_evt_acl_process(): conn_handle=0 pb=2 len=11 data=0x07 0x00 0x04 0x00 0x10 0x00 0x00 0xff 0xff 0x00 0x28 
host tx hci data; handle=0 length=9
ble_hs_hci_acl_tx(): 0x00 0x00 0x09 0x00 0x05 0x00 0x04 0x00 0x01 0x10 0x00 0x00 0x01 
ble_hs_hci_evt_acl_process(): conn_handle=0 pb=2 len=11 data=0x07 0x00 0x04 0x00 0x10 0x00 0x00 0xff 0xff 0x00 0x28 
host tx hci data; handle=0 length=9
ble_hs_hci_acl_tx(): 0x00 0x00 0x09 0x00 0x05 0x00 0x04 0x00 0x01 0x10 0x00 0x00 0x01 
ble_hs_hci_evt_acl_process(): conn_handle=0 pb=2 len=11 data=0x07 0x00 0x04 0x00 0x10 0x42 0x4e 0xff 0xff 0x00 0x28 
host tx hci data; handle=0 length=9
ble_hs_hci_acl_tx(): 0x00 0x00 0x09 0x00 0x05 0x00 0x04 0x00 0x01 0x10 0x42 0x4e 0x0a 
ble_hs_hci_evt_acl_process(): conn_handle=0 pb=2 len=11 data=0x07 0x00 0x04 0x00 0x10 0x42 0x4e 0xff 0xff 0x00 0x28 
host tx hci data; handle=0 length=9
ble_hs_hci_acl_tx(): 0x00 0x00 0x09 0x00 0x05 0x00 0x04 0x00 0x01 0x10 0x42 0x4e 0x0a 
ble_hs_hci_evt_acl_process(): conn_handle=0 pb=2 len=11 data=0x07 0x00 0x04 0x00 0x10 0x42 0x4e 0xff 0xff 0x00 0x28 
host tx hci data; handle=0 length=9
ble_hs_hci_acl_tx(): 0x00 0x00 0x09 0x00 0x05 0x00 0x04 0x00 0x01 0x10 0x42 0x4e 0x0a 
ble_hs_hci_evt_acl_process(): conn_handle=0 pb=2 len=11 data=0x07 0x00 0x04 0x00 0x10 0x42 0x4e 0xff 0xff 0x00 0x28 
host tx hci data; handle=0 length=9
ble_hs_hci_acl_tx(): 0x00 0x00 0x09 0x00 0x05 0x00 0x04 0x00 0x01 0x10 0x42 0x4e 0x0a 
ble_hs_hci_evt_acl_process(): conn_handle=0 pb=2 len=11 data=0x07 0x00 0x04 0x00 0x10 0x42 0x4e 0xff 0xff 0x00 0x28 
host tx hci data; handle=0 length=9
ble_hs_hci_acl_tx(): 0x00 0x00 0x09 0x00 0x05 0x00 0x04 0x00 0x01 0x10 0x42 0x4e 0x0a 
ble_hs_hci_evt_acl_process(): conn_handle=0 pb=2 len=11 data=0x07 0x00 0x04 0x00 0x10 0x42 0x4e 0xff 0xff 0x00 0x28 
host tx hci data; handle=0 length=9
ble_hs_hci_acl_tx(): 0x00 0x00 0x09 0x00 0x05 0x00 0x04 0x00 0x01 0x10 0x42 0x4e 0x0a 
ble_hs_hci_evt_acl_process(): conn_handle=0 pb=2 len=11 data=0x07 0x00 0x04 0x00 0x10 0x42 0x4e 0xff 0xff 0x00 0x28 
host tx hci data; handle=0 length=9
ble_hs_hci_acl_tx(): 0x00 0x00 0x09 0x00 0x05 0x00 0x04 0x00 0x01 0x10 0x42 0x4e 0x0a 
ble_hs_hci_evt_acl_process(): conn_handle=0 pb=2 len=11 data=0x07 0x00 0x04 0x00 0x10 0x42 0x4e 0xff 0xff 0x00 0x28 
host tx hci data; handle=0 length=9
ble_hs_hci_acl_tx(): 0x00 0x00 0x09 0x00 0x05 0x00 0x04 0x00 0x01 0x10 0x42 0x4e 0x0a 
ble_hs_hci_evt_acl_process(): conn_handle=0 pb=2 len=11 data=0x07 0x00 0x04 0x00 0x10 0x42 0x4e 0xff 0xff 0x00 0x28 
host tx hci data; handle=0 length=9
ble_hs_hci_acl_tx(): 0x00 0x00 0x09 0x00 0x05 0x00 0x04 0x00 0x01 0x10 0x42 0x4e 0x0a 
ble_hs_hci_evt_acl_process(): conn_handle=0 pb=2 len=11 data=0x07 0x00 0x04 0x00 0x10 0x42 0x4e 0xff 0xff 0x00 0x28 
host tx hci data; handle=0 length=9
ble_hs_hci_acl_tx(): 0x00 0x00 0x09 0x00 0x05 0x00 0x04 0x00 0x01 0x10 0x42 0x4e 0x0a 
ble_hs_hci_evt_acl_process(): conn_handle=0 pb=2 len=11 data=0x07 0x00 0x04 0x00 0x10 0x42 0x4e 0xff 0xff 0x00 0x28 
host tx hci data; handle=0 length=9
ble_hs_hci_acl_tx(): 0x00 0x00 0x09 0x00 0x05 0x00 0x04 0x00 0x01 0x10 0x42 0x4e 0x0a 
ble_hs_hci_evt_acl_process(): conn_handle=0 pb=2 len=11 data=0x07 0x00 0x04 0x00 0x10 0x42 0x4e 0xff 0xff 0x00 0x28 
host tx hci data; handle=0 length=9
ble_hs_hci_acl_tx(): 0x00 0x00 0x09 0x00 0x05 0x00 0x04 0x00 0x01 0x10 0x42 0x4e 0x0a 
Server ondisconnect
GAP procedure initiated: advertise; disc_mode=2 adv_channel_map=0 own_addr_type=0 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0
ble_hs_hci_cmd_send: ogf=0x08 ocf=0x0006 len=15
0x06 0x20 0x0f 0x30 0x00 0x60 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x07 0x00 
ble_hs_hci_cmd_send: ogf=0x08 ocf=0x000a len=1
0x0a 0x20 0x01 0x01 
start advertising

更新 遵循 Youssif SAEed 富有洞察力的建议,我想我取得了一些进展。在连接到 ESP32 时观察来自 nRF Connect 移动应用程序的日志并没有真正的帮助,因为配对或绑定过程中没有错误。但是,在克隆服务并在 nRF Connect 中设置 GATT 服务器后,我能够捕获 HCI 通信。这需要使用有根的旧 Android 手机。现在我正在 Wireshark 中查看 the btsnoop_hci.log file,试图了解出了什么问题,感谢任何指点。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。