nkolban / esp32-snippets

Sample ESP32 snippets and code fragments
https://leanpub.com/kolban-ESP32
Apache License 2.0
2.35k stars 710 forks source link

BLE classes - write to characteristic fails #374

Open robpelu opened 6 years ago

robpelu commented 6 years ago

Hi, I'm interfacing to some smart bracelet with the BLE clases and I got it to almost work, except for the following. I noticed with a sniffer that at least once I have to write 0x0100 to one characteristic named handle: 0x000f, uuid: 00002902-0000-1000-8000-00805f9b34fb but when I try to do that it fails. I debugged it a bit, and noticed that the service in which that characteristic is located, only has 2 characteristics, but this one is not included (as detected by the ESP32)

On the other hand, using a linux box and gatttool I can write to it just with the handle id, and works.

Some questions I have: Could I link to a characteristics only by it's handle as in gatttool ? Here are the characteristics and services of the bracelet.

BR, Robert.

[FB:83:26:65:D4:74][LE]> primary services attr handle: 0x0001, end grp handle: 0x0007 uuid: 00001800-0000-1000-8000-00805f9b34fb attr handle: 0x0008, end grp handle: 0x000b uuid: 00001801-0000-1000-8000-00805f9b34fb attr handle: 0x000c, end grp handle: 0x0011 uuid: 6e40fff0-b5a3-f393-e0a9-e50e24dcca9e attr handle: 0x0012, end grp handle: 0x0019 uuid: 00001530-1212-efde-1523-785feabcd123 attr handle: 0x001a, end grp handle: 0x001f uuid: 0000fee7-0000-1000-8000-00805f9b34fb attr handle: 0x0020, end grp handle: 0x0026 uuid: 0000180a-0000-1000-8000-00805f9b34fb attr handle: 0x0027, end grp handle: 0xffff uuid: de5bf728-d711-4e47-af26-65e3012a5dc7

char-desc handle: 0x0001, uuid: 00002800-0000-1000-8000-00805f9b34fb handle: 0x0002, uuid: 00002803-0000-1000-8000-00805f9b34fb handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb handle: 0x0004, uuid: 00002803-0000-1000-8000-00805f9b34fb handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb handle: 0x0006, uuid: 00002803-0000-1000-8000-00805f9b34fb handle: 0x0007, uuid: 00002a04-0000-1000-8000-00805f9b34fb handle: 0x0008, uuid: 00002800-0000-1000-8000-00805f9b34fb handle: 0x0009, uuid: 00002803-0000-1000-8000-00805f9b34fb handle: 0x000a, uuid: 00002a05-0000-1000-8000-00805f9b34fb handle: 0x000b, uuid: 00002902-0000-1000-8000-00805f9b34fb handle: 0x000c, uuid: 00002800-0000-1000-8000-00805f9b34fb handle: 0x000d, uuid: 00002803-0000-1000-8000-00805f9b34fb handle: 0x000e, uuid: 6e400003-b5a3-f393-e0a9-e50e24dcca9e handle: 0x000f, uuid: 00002902-0000-1000-8000-00805f9b34fb handle: 0x0010, uuid: 00002803-0000-1000-8000-00805f9b34fb handle: 0x0011, uuid: 6e400002-b5a3-f393-e0a9-e50e24dcca9e handle: 0x0012, uuid: 00002800-0000-1000-8000-00805f9b34fb handle: 0x0013, uuid: 00002803-0000-1000-8000-00805f9b34fb handle: 0x0014, uuid: 00001532-1212-efde-1523-785feabcd123 handle: 0x0015, uuid: 00002803-0000-1000-8000-00805f9b34fb handle: 0x0016, uuid: 00001531-1212-efde-1523-785feabcd123 handle: 0x0017, uuid: 00002902-0000-1000-8000-00805f9b34fb handle: 0x0018, uuid: 00002803-0000-1000-8000-00805f9b34fb handle: 0x0019, uuid: 00001534-1212-efde-1523-785feabcd123 handle: 0x001a, uuid: 00002800-0000-1000-8000-00805f9b34fb handle: 0x001b, uuid: 00002803-0000-1000-8000-00805f9b34fb handle: 0x001c, uuid: 0000fec9-0000-1000-8000-00805f9b34fb handle: 0x001d, uuid: 00002803-0000-1000-8000-00805f9b34fb handle: 0x001e, uuid: 0000fea1-0000-1000-8000-00805f9b34fb handle: 0x001f, uuid: 00002902-0000-1000-8000-00805f9b34fb handle: 0x0020, uuid: 00002800-0000-1000-8000-00805f9b34fb handle: 0x0021, uuid: 00002803-0000-1000-8000-00805f9b34fb handle: 0x0022, uuid: 00002a27-0000-1000-8000-00805f9b34fb handle: 0x0023, uuid: 00002803-0000-1000-8000-00805f9b34fb handle: 0x0024, uuid: 00002a26-0000-1000-8000-00805f9b34fb handle: 0x0025, uuid: 00002803-0000-1000-8000-00805f9b34fb handle: 0x0026, uuid: 00002a23-0000-1000-8000-00805f9b34fb handle: 0x0027, uuid: 00002800-0000-1000-8000-00805f9b34fb handle: 0x0028, uuid: 00002803-0000-1000-8000-00805f9b34fb handle: 0x0029, uuid: de5bf729-d711-4e47-af26-65e3012a5dc7 handle: 0x002a, uuid: 00002902-0000-1000-8000-00805f9b34fb handle: 0x002b, uuid: 00002803-0000-1000-8000-00805f9b34fb handle: 0x002c, uuid: de5bf72a-d711-4e47-af26-65e3012a5dc7

chegewara commented 6 years ago

What you need is this example https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLETests/SampleClient_Notify.cpp

robpelu commented 6 years ago

Yes, I've used that example as a reference and writing/reading to most of the register works. The thing is that if I want to write to characteristic handle 0x000f, but if I replace the service and characteristic in the example by the values:

static BLEUUID serviceUUID("6e40fff0-b5a3-f393-e0a9-e50e24dcca9e"); // The characteristic of the remote service we are interested in. static BLEUUID charUUID("00002902-0000-1000-8000-00805f9b34fb");

and try to write the values "0x01 0x00" to it fails while trying to link to the characteristic, because it's not found in the service.

This is the error log when it fails:

I (6852) helper_functions: RAM left 81108 I (7014) BLERemoteService: >> getCharacteristics() for service: 6e40fff0-b5a3-f393-e0a9-e50e24dcca9e I (7018) BLERemoteService: Found a characteristic: Handle: 14, UUID: 6e400003-b5a3-f393-e0a9-e50e24dcca9e E (7028) BLERemoteCharacteristic: I (7036) BLERemoteService: Found a characteristic: Handle: 17, UUID: 6e400002-b5a3-f393-e0a9-e50e24dcca9e E (7042) BLERemoteCharacteristic: esp_ble_gattc_get_all_descr: ESP_GATT_NOT_FOUND I (7050) BLERemoteService: << getCharacteristics() abort() was called at PC 0x401187e7 on core 0 0x401187e7: cxxabiv1::terminate(void (*)()) at /Volumes/build/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/eh_terminate.cc:112

Backtrace: 0x4008af27:0x3ffe8400 0x4008af53:0x3ffe8420 0x401187e7:0x3ffe8440 0x4011882e:0x3ffe8460 0x401188db:0x3ffe8480 0x4013ba81:0x3ffe84a0 0x4010d32a:0x3ffe8500 0x4010d89e:0x3ffe8520 0x4010e005:0x3ffe8580 0x4013dda6:0x3ffe8610 0x4008af27: invoke_abort at /Users/Robert/esp/esp-idf/components/esp32/./panic.c:572

0x4008af53: abort at /Users/Robert/esp/esp-idf/components/esp32/./panic.c:572

0x401187e7: cxxabiv1::terminate(void (*)()) at /Volumes/build/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/eh_terminate.cc:112

0x4011882e: std::terminate() at /Volumes/build/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/eh_terminate.cc:112

0x401188db: __cxa_throw at /Volumes/build/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/eh_throw.cc:87

0x4013ba81: BLERemoteService::getCharacteristic(BLEUUID) at /Users/Robert/esp/xtensa-esp32-elf/xtensa-esp32-elf/include/c++/5.2.0/bits/ios_base.h:1014

0x4010d32a: MyClient::init_charasteristic(int) at /Users/Robert/esp/esp32-ota-https2/main/./BLE_client.cpp:297

0x4010d89e: MyClient::init_commands() at /Users/Robert/esp/esp32-ota-https2/main/./BLE_client.cpp:474

0x4010e005: MyClient::run(void*) at /Users/Robert/esp/esp32-ota-https2/main/./BLE_client.cpp:736

0x4013dda6: Task::runTask(void*) at /Users/Robert/esp/esp-idf/components/cpp_utils/./Task.cpp:58

I tried some ugly modification to the write function of the charasteristic, since I "know" the characteristic should be in this service (6e40fff0-b5a3-f393-e0a9-e50e24dcca9e) but handle 0x000f.

I've generated a copy of the write function in BLERemoteCharasteristic.cpp and named something else, but replaced the handle by 0x000f manually.

// Invoke the ESP-IDF API to perform the write. esp_err_t errRc = ::esp_ble_gattc_write_char( m_pRemoteService->getClient()->getGattcIf(), m_pRemoteService->getClient()->getConnId(), 0x000f, newValue.length(), (uint8_t*)newValue.data(), response?ESP_GATT_WRITE_TYPE_RSP:ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE );

That "works" in the sense that the bracelet then behaves as expected, but the ESP freezes after that write. This is some command the bracelet needs but it's not registered in the services as far as the ESP knows. But I can find it and write to it with gatttool.

chegewara commented 6 years ago

00002902-0000-1000-8000-00805f9b34fb this is not characteristic, its descriptor that lets you register for notify. If you can try with nRF connect on android device, then you can see which UUID's are services, characteristics and descriptors.

robpelu commented 6 years ago

OK, I will have to read more about that :-)

I tried with the example, register to be notified on that characteristic (6e400003-b5a3-f393-e0a9-e50e24dcca9e) but it doesn't have the same effect.

I will try to put the sniffer as well while I do that with the ESP32 and see what's being sent.

It's supposed that when I call pRemoteCharacteristic->registerForNotify(notifyCallback); it will write 0x100 to 00002902-0000-1000-8000-00805f9b34fb ???

chegewara commented 6 years ago

yes, it supose to write to this descriptor with handle, because as you can see there is more descriptors with uuid 2902. Each belongs to different characteristic.

robpelu commented 6 years ago

Hi, sorry I didn't comment about the solution that found in the forums from a reply from chegewara. This is what worked for me:

const uint8_t v[]={0x1,0x0};

pRemoteCharacteristic->registerForNotify(notifyCallback); pRemoteCharacteristic->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)v, 2, true);

You guys can close this. BR, Robert.