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
182 stars 62 forks source link

Proper shutdown #149

Closed mickeyl closed 8 months ago

mickeyl commented 8 months ago

In my application for ESP32S3, we offer similar services both through BLE/L2CAP and WiFi. In order to make things smoothly coexist, upon connection setup, we want to shutdown the respective "other" service.

What's the preferred way to shutdown the stack using esp-nimble-cpp? Here is how I set it up:

// L2CAP
    auto cocServer = new BLEL2CapServer();
    auto l2capServiceCallbacks = new L2CAPServiceCallbacks();
    auto canCoc = cocServer->createService(DeviceInformation::shared().psmForCan(), 5000, l2capServiceCallbacks);
    auto server = BLEDevice::createServer();
    auto gattServerCallbacks = new GATTServerCallbacks();
    server->setCallbacks(gattServerCallbacks);

    // FFF1 for detection & info
    auto service = server->createService(SERVICE_UUID);
    auto psmForCanCharacteristics = service->createCharacteristic(DeviceInformation::shared().psmForCan(), NIMBLE_PROPERTY::READ);
    psmForCanCharacteristics->setValue("L2CAP PSM for CANController");
    auto psmForEnetCharacteristics = service->createCharacteristic(DeviceInformation::shared().psmForEnet(), NIMBLE_PROPERTY::READ);
    psmForEnetCharacteristics->setValue("L2CAP PSM for ENET");
    service->start();

    // 180A for device information
    auto deviceInformationService = server->createService(DEVICE_INFORMATION_SERVICE_UUID);
    auto manufacturerNameCharacteristics = deviceInformationService->createCharacteristic(MANUFACTURER_NAME_UUID, NIMBLE_PROPERTY::READ);
    manufacturerNameCharacteristics->setValue(DeviceInformation::shared().manufacturerName());
    auto modelNumberCharacteristics = deviceInformationService->createCharacteristic(MODEL_NUMBER_UUID, NIMBLE_PROPERTY::READ);
    modelNumberCharacteristics->setValue(DeviceInformation::shared().modelName());
    auto serialNumberCharacteristics = deviceInformationService->createCharacteristic(SERIAL_NUMBER_UUID, NIMBLE_PROPERTY::READ);
    serialNumberCharacteristics->setValue(DeviceInformation::shared().serialNumber());
    auto hardwareRevisionCharacteristics = deviceInformationService->createCharacteristic(HARDWARE_REVISION_UUID, NIMBLE_PROPERTY::READ);
    hardwareRevisionCharacteristics->setValue(DeviceInformation::shared().hardwareRevision());
    auto firmwareRevisionCharacteristics = deviceInformationService->createCharacteristic(FIRMWARE_REVISION_UUID, NIMBLE_PROPERTY::READ);
    firmwareRevisionCharacteristics->setValue(DeviceInformation::shared().firmwareRevision());
    deviceInformationService->start();

    // Enable Advertising
    auto advertising = BLEDevice::getAdvertising();
    advertising->addServiceUUID(SERVICE_UUID);
    advertising->setScanResponse(true);
    BLEDevice::startAdvertising();

Do I need to remove the callbacks and do I need to keep the handles for the services around so I can stop them?

Or is there a more simple way to cleanup where all the registered services are shut down automatically?

Update: I have found BLEDevice::deinit -- is that a coordinated shutdown?

mickeyl commented 8 months ago

It looks like this is it. There's a problem with l2cap servers, but this I'm trying to address upstream.

h2zero commented 8 months ago

Sorry for the delay, looks like you found the solution though. Interesting issue with the l2cap servers.