taks / esp32-nimble

A wrapper for the ESP32 NimBLE Bluetooth stack.
Apache License 2.0
118 stars 35 forks source link

Sending Characteristic between threads #17

Closed Skizy closed 1 year ago

Skizy commented 1 year ago

Hey, I was trying to create a separate thread to send notifications as a server, but was unable to, because BLECharacteristic is not Send and not Sync. Hence I have a question: what is the point of wrapping characteristics in Arc Mutex if you can't share them between threads?

taks commented 1 year ago

Please use Arc::clone. See https://doc.rust-lang.org/book/ch16-03-shared-state.html#atomic-reference-counting-with-arct for details. If it still doesn't work, please paste the source code.

Skizy commented 1 year ago

Something like this for example does not compile. BLECharacteristic doesn't implement Sync and Send because Vec does not, since ble_gatt_sdc_def contains *mut c_void.

use esp32_nimble::*;
use std::sync::Arc;

let ble_dev = BLEDevice::take();

let server = ble_dev.get_server();

let service = server.create_service(utilities::BleUuid::from_uuid16(9234u16));
let notify_characteristic = service.lock().create_characteristic(
    utilities::BleUuid::from_uuid16(1642u16),
    NimbleProperties::NOTIFY | NimbleProperties::READ,
);
notify_characteristic.lock().set_value(&[125]);

let char_clone = Arc::clone(&notify_characteristic);

std::thread::spawn(move || {
    char_clone.lock().notify();
});
taks commented 1 year ago

Sorry for the lack of confirmation. I marked BLECharacteristic as Send. This change should resolve the issue.

Skizy commented 1 year ago

Thanks a lot! You should also mark BLEService as Send, as it has the same problem.