Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Direct call "start" on service, stop processing subscription and notifications/indications #27

Closed
mbv opened this issue Oct 3, 2023 · 1 comment

Comments

@mbv
Copy link
Contributor

mbv commented Oct 3, 2023

First of all, thanks for the great job you did migrating nimble to rust.

I am moving project which used nimble-arduino, and found odd thing:

I we directly call start on BleService, we didn't receive any updates about subscription and notifications/indications, here example:

use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported
use log::*;
use esp32_nimble::{uuid128, BLEDevice, NimbleProperties};

fn main() {
    // It is necessary to call this function once. Otherwise some patches to the runtime
    // implemented by esp-idf-sys might not link properly. See /~https://github.com/esp-rs/esp-idf-template/issues/71
    esp_idf_sys::link_patches();
    // Bind the log crate to the ESP Logging facilities
    esp_idf_svc::log::EspLogger::initialize_default();

    info!("Hello, world!");
    let ble_device = BLEDevice::take();

    ble_device
        .security()
        .set_auth(false, false, false);

    let server = ble_device.get_server();
    server.on_connect(|server, desc| {
        ::log::info!("Client connected");

        server
            .update_conn_params(desc.conn_handle, 24, 48, 0, 60)
            .unwrap();

        ::log::info!("Multi-connect support: start advertising");
        ble_device.get_advertising().start().unwrap();
    });
    let service = server.create_service(uuid128!("fafafafa-fafa-fafa-fafa-fafafafafafa"));

    // A characteristic that notifies every second.
    let notifying_characteristic = service.lock().create_characteristic(
        uuid128!("a3c87500-8ed3-4bdf-8a39-a01bebede295"),
        NimbleProperties::WRITE
            | NimbleProperties::WRITE_NO_RSP
            | NimbleProperties::WRITE_ENC
            | NimbleProperties::NOTIFY,
    );

    notifying_characteristic.lock()
        .on_read(move |_, _| {
            ::log::info!("Read from writable characteristic.");
        })
        .on_write(move |args| {
            ::log::info!("Wrote to writable characteristic: {:?}", args.recv_data);
        })
        .on_subscribe(move |desc, sub_value| {
            ::log::info!("Client ID: {:?} sub_value: {:?}", desc.conn_handle, sub_value);
        })
        .on_notify_tx(move |args| {
            ::log::info!("on_notify_tx {:?}", args.status());
        });

    notifying_characteristic.lock().set_value(b"Initial value.");

    service.lock().start().unwrap();


    let ble_advertising = ble_device.get_advertising();
    ble_advertising
        .name("ESP32-GATT-Server")
        .add_service_uuid(uuid128!("fafafafa-fafa-fafa-fafa-fafafafafafa"));

    ble_advertising.start().unwrap();

    let mut counter = 0;
    loop {
        esp_idf_hal::delay::FreeRtos::delay_ms(1000);
        notifying_characteristic
            .lock()
            .set_value(format!("Counter: {counter}").as_bytes())
            .notify();

        counter += 1;
    }
}

After connect via any ble scanner and subsribe on notifications on notifying_characteristic, I don't see any logs.

If I comment service.lock().start().unwrap(); everthing work as expected, and I see in logs:

....
I (81692) test_ble_2: Client ID: 1 sub_value: NOTIFY
I (82652) NimBLE: GATT procedure initiated: notify; 
I (82652) NimBLE: att_handle=12

I (82652) test_ble_2: on_notify_tx SuccessNotify
I (83652) NimBLE: GATT procedure initiated: notify; 
I (83652) NimBLE: att_handle=12
....

I found that on server start we have calls "start" for every ble services, and seems we have issue when we call "start" two times. As I see nimble-arduino contains logic to handle multiple calls of start on services.

@taks
Copy link
Owner

taks commented Oct 4, 2023

I checked nimble-arduino.
The nimble-arduino also seemed to have a bug where if I manually call start service twice, it would be registered twice.
※ The nimble-arduino does not invoke service start when the server is started, It is no problem to call service start manually.

This library calls service start when the server is started, and if you call service start manually, it will be registered twice.
Therefore, there is no need to manually invoke the service start.
※ The problem is that the service start is public and I will change the program.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants