ArduinoBLE icon indicating copy to clipboard operation
ArduinoBLE copied to clipboard

disconnect() does not trigger callback

Open rmlearney-digicatapult opened this issue 6 years ago • 5 comments

Example:

  1. Initialise BLE
  2. Create callbacks for central connection and disconnection to turn LED on and off
  3. Connect to central
  4. disconnect() after 10 seconds

Expected behaviour - disconnection from central should trigger callback and turn off LED Actual behaviour - disconnection from central with disconnect() method does not trigger callback

#include <ArduinoBLE.h>

BLEService TestService("DEAD");
BLECharacteristic TestData("BEEF", BLEIndicate | BLENotify, 2, true);
BLEDescriptor TestDescriptor("BEEF", "Test");

uint32_t genericTimer = 0;

void setup(){

  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);

  initBLE();
}

void loop(){
  BLEDevice central = BLE.central(); // begin listening for centrals to connect

  if(central){
    genericTimer = millis();
    while(central.connected()){
      if(millis() - genericTimer >= 10000){ // Wait 10 seconds
        BLE.disconnect(); // Disconnect BLE - LED should go out
      }
    }
  }
}

void initBLE(void){ 
  BLE.begin();
  BLE.setEventHandler(BLEConnected, blePeripheralConnectHandler);
  BLE.setEventHandler(BLEDisconnected, blePeripheralDisconnectHandler);
  BLE.setLocalName("TestName");
  BLE.setDeviceName("Test Device Name");
  TestService.addCharacteristic(TestData);
  TestData.addDescriptor(TestDescriptor);
  BLE.addService(TestService);
  BLE.setAdvertisedService(TestService);
  BLE.advertise();
}

void blePeripheralConnectHandler(BLEDevice central){
    // turn on the LED to indicate the connection:
    digitalWrite(LED_BUILTIN, HIGH);
}

void blePeripheralDisconnectHandler(BLEDevice central){
    // when the central disconnects, turn off the LED:
    digitalWrite(LED_BUILTIN, LOW);
}

rmlearney-digicatapult avatar Apr 07 '20 16:04 rmlearney-digicatapult

Looks like the BLEDisconnected callback is triggered from ATTClass::removeConnection() but not ATTClass::disconnect()

rmlearney-digicatapult avatar Apr 07 '20 19:04 rmlearney-digicatapult

Hi @rmlearney-digicatapult , actually the callback is expected to be triggered only by disconnection events coming from the HCI (i.e. caused by other devices). If it was triggered even upon user side disconnection, the two events would not be distinguishable. So, if You want to react to a disconnection under your control, You can directly check the return value of the disconnect call with something like:

if (BLE.disconnect()) {
    digitalWrite(LED_BUILTIN, LOW);
}

Similarly, the same approach is used for connection callbacks. If the connection is coming from other devices the callback is triggered, while if the connection is requested by our device the callback is not triggered.

polldo avatar Jul 08 '20 07:07 polldo

Hi @Polldo may I suggest you deprecate blePeripheralDisconnectHandler in that case?

I don't understand why the user would care about the source of disconnection when wanting to trigger a callback to handle disconnections.

Could you maybe give me a use case, because as a user I just want to use the blePeripheralDisconnectHandler callback function that is designed to handle disconnections in order to handle disconnections.

rmlearney-digicatapult avatar Jul 08 '20 09:07 rmlearney-digicatapult

Hi @rmlearney-digicatapult , distinguishing between disconnection sources could be very useful. For example, a central could react to a disconnection due to a too weak signal by alerting the user in some way or by trying to reconnect. However, I see your point. One way to have both features could be to propagate a disconnection reason. Anyway, thanks for pointing this out. I'll think about it.

polldo avatar Jul 09 '20 15:07 polldo

Thank you @Polldo - I completely agree that the reason for disconnection would be useful information

rmlearney-digicatapult avatar Jul 09 '20 16:07 rmlearney-digicatapult