h2zero / esp-nimble-cpp

C++ library for the esp32 NimBLE stack based on and mostly compatible with @nkolban cpp_utils BLE library.
https://h2zero.github.io/esp-nimble-cpp/
Apache License 2.0
181 stars 62 forks source link

setValue(std::vector<uint8_t>&) fails #200

Closed finger563 closed 1 month ago

finger563 commented 1 month ago

NimBLEAttrValue::setValue(std::vector<uint8_t> s) fails, likely because it is casting v improperly, using reinterpret_cast<const uint8_t*>(&s).

I found this out because my HID code (where I manually create the characteristics) was using this API, though it is disabled on the NimBLEHIDDevice class. If you re-enable it (as I have mentioned in the code here), then the call to setValue ends up pushing garbage data into the attribute value.

I'd suggest having a code path which checks if the type / container has a data() method, similarly to how you check the c_str() method, so that you can properly access the data for the container since right now the code will compile with std::vector, but will break.

Note: the link above goes to a simple example repo which has some very basic instructions (comments at the linked part of the code) you should be able to follow to show the failure mode, which is present even on the NimBLEHIDDevice implementation.

Note: data() is probably a safer / more general check than c_str(), so may be better to replace with that anyway.

h2zero commented 1 month ago

I think this can be fixed by adding [0] after &s here: reinterpret_cast<const uint8_t*>(&s)

finger563 commented 1 month ago

That wouldn't work since the use of sizeof(T) would be incorrect. I think there needs to a meta-case which handles the data/size, falling back to c_str/length if that's not available, and falling back to cast/sizeof if neither is available.