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

Regular disconnect #19

Open
gotleg opened this issue Aug 28, 2017 · 0 comments
Open

Regular disconnect #19

gotleg opened this issue Aug 28, 2017 · 0 comments

Comments

@gotleg
Copy link
Contributor

gotleg commented Aug 28, 2017

Hello,

I work for many month on a node/electron application to control Parrot Mambo mini-drone via BLE using npm-parrot-minidrone lib on top of noble.

Everything is working really great except that I got a two strange beahaviors when the drone is disconnected/powered off.
Note that this behavior has been reproduced on both my dev env. (Ubuntu 16.04 in Virtual Box) and my production env. (Raspberry pi 3). I'm using Sena UD-100 Bluetooth dongle that allows me to achieve very good range.

1/ using npm-parrot-minidrone
With this implementation there is no disconnect handler on the peripheral and when the drone is disconnected, noble sends me a poweredOff event (not for the drone but for the bluetooth dongle). Then noble is not able to do anything else as it doesn't detect the dongle anymore. Note that my host windows also detects a USB unplug/replug. I also reproduced that PoweredOff event on my RPI3.

Whith this code my connection with to drone is rock solid but I can't reconnect if it get disconnected...

Here is the interesting part of the code :


onPeripheralDiscovery(peripheral) {
        if (!this.validatePeripheral(peripheral)) {
            return;
        }
        Logger.info('Peripheral found ${peripheral.advertisement.localName}');
        this.noble.stopScanning();
        peripheral.connect((error) => {
            if (error) {
                throw error;
            }
            this.peripheral = peripheral;
            this.setupPeripheral();
        });
    }

2/ As I wanted to have a clean test code (outside of electron and npm-parrot-minirone) I decided to test a simple noble connection to my drone.

This time i'm able to detects when peripheral is disconnected, startScanning, re-discover my peripheral and reconnect. This would be perfect except that once my peripheral has be disconnected the first time, when it reconnects it loose connection after a few seconds and then reconnects, ...
On this test it happens only one time but after many tests I feel like if I add listeners on characteristics change the connection is more and more unstable.

Here is the code, most interesting part is at the bottom (connect and disconnect listeners) :

var noble = require('noble');
var peripheral = null
var loaded = false

noble.on('stateChange', function(state) {
  console.log('## stateChange : ' + state + ' ##')
  if (state === 'poweredOn') {
    console.log("start scanning")
    noble.startScanning();
  } else {
    console.log("stop scanning")
    noble.stopScanning();
  }
});

noble.on('warning', function (warning) {
  console.log('warning : ' + warning)
})

noble.on('stateChange', function (data) { log('stateChange', data)});
noble.on('addressChange', function (data) { log('addressChange', data)});
noble.on('scanStart', function (data) { log('scanStart', data)});
noble.on('scanStop', function (data) { log('scanStop', data)});
noble.on('discover', function (data) { log('discover', data)});
noble.on('connect', function (data) { log('connect', data)});
noble.on('disconnect', function (data) { log('disconnect', data)});
noble.on('rssiUpdate', function (data) { log('rssiUpdate', data)});
noble.on('servicesDiscover', function (data) { log('servicesDiscover', data)});
noble.on('includedServicesDiscover', function (data) { log('includedServicesDiscover', data)});
noble.on('characteristicsDiscover', function (data) { log('characteristicsDiscover', data)});
noble.on('read', function (data) { log('read', data)});
noble.on('write', function (data) { log('write', data)});
noble.on('broadcast', function (data) { log('broadcast', data)});
noble.on('notify', function (data) { log('notify', data)});
noble.on('descriptorsDiscover', function (data) { log('descriptorsDiscover', data)});
noble.on('valueRead', function (data) { log('valueRead', data)});
noble.on('valueWrite', function (data) { log('valueWrite', data)});
noble.on('handleRead', function (data) { log('handleRead', data)});
noble.on('handleWrite', function (data) { log('handleWrite', data)});
noble.on('handleNotify', function (data) { log('handleNotify', data)});

function log(message, data) {
  console.log(message + ' : ' + data)
}

noble.on('discover', function(peripheral) {
  console.log('## discover ' + peripheral + ' ##')
    noble.stopScanning();

    console.log('peripheral with ID ' + peripheral.id + ' found');

    var advertisement = peripheral.advertisement;
    var localName = advertisement.localName;
    var txPowerLevel = advertisement.txPowerLevel;
    var manufacturerData = advertisement.manufacturerData;
    var serviceData = advertisement.serviceData;
    var serviceUuids = advertisement.serviceUuids;

    if (localName) {
      console.log('  Local Name        = ' + localName);
    }
    if (txPowerLevel) {
      console.log('  TX Power Level    = ' + txPowerLevel);
    }
    if (manufacturerData) {
      console.log('  Manufacturer Data = ' + manufacturerData.toString('hex'));
    }
    if (serviceData) {
      console.log('  Service Data      = ' + serviceData);
    }
    if (serviceUuids) {
      console.log('  Service UUIDs     = ' + serviceUuids);
    }
    init(peripheral);
});

function init(peripheral) {
  console.log('## init ##')
  if (!loaded) {
    loaded = true
    peripheral.on('disconnect', function() {
      console.log("disconnected")
      noble.startScanning();
    });

    peripheral.on("connect", function() {
      console.log("Connected")
    })
  }

  peripheral.connect(function(error) {
    if (error) {
      console.log(error)
    }
  })
}

As you can see I tried to get the maximum of info from noble but in the app log I just get : Connected -> Disconnected.

I already submited this issue to noblejs and parrot dev forum some weeks ago but no answer at all.

Any idea would be welcome ?

We made some tests today on MacOS and the behavior was not exactly the same, maybe differences between linux BlueZ and OSX... or in the dongle driver ...

I also discovered that I don't have this behavior using an older Parrot drone (Airborne Cargo) vs my actual Mambo.

I don't think parrot-minidrone as something to deal with it but as this feature could be very usefull to everybody, I hope that you can maybe give me some help :p

To complete this issue here is an HCI dump :

HCI sniffer - Bluetooth packet analyzer ver 5.41
device: hci0 snap_len: 1500 filter: 0xffffffffffffffff
2017-08-14 19:55:36.229784 > HCI Event: Command Complete (0x0e) plen 4
    Set Event Mask (0x03|0x0001) ncmd 1
    status 0x00
2017-08-14 19:55:36.234220 > HCI Event: Command Complete (0x0e) plen 4
    LE Set Event Mask (0x08|0x0001) ncmd 1
    status 0x00
2017-08-14 19:55:36.248258 > HCI Event: Command Complete (0x0e) plen 12
    Read Local Version Information (0x04|0x0001) ncmd 1
    status 0x00
    HCI Version: 4.0 (0x6) HCI Revision: 0x2031
    LMP Version: 4.0 (0x6) LMP Subversion: 0x2031
    Manufacturer: Cambridge Silicon Radio (10)
2017-08-14 19:55:36.251325 > HCI Event: Command Complete (0x0e) plen 4
    Write LE Host Supported (0x03|0x006d) ncmd 1
    0000: 00                                                .
2017-08-14 19:55:36.254733 > HCI Event: Command Complete (0x0e) plen 6
    Read LE Host Supported (0x03|0x006c) ncmd 1
    0000: 00 01 00                                          ...
2017-08-14 19:55:36.258264 > HCI Event: Command Complete (0x0e) plen 10
    Read BD ADDR (0x04|0x0009) ncmd 1
    status 0x00 bdaddr 00:01:95:39:8E:C4
2017-08-14 19:55:36.272827 > HCI Event: Command Complete (0x0e) plen 4
    LE Set Scan Enable (0x08|0x000c) ncmd 1
    status 0x00
2017-08-14 19:55:36.276847 > HCI Event: Command Complete (0x0e) plen 4
    LE Set Scan Parameters (0x08|0x000b) ncmd 1
    status 0x00
2017-08-14 19:55:36.286465 > HCI Event: Command Complete (0x0e) plen 4
    LE Set Scan Enable (0x08|0x000c) ncmd 1
    status 0x00
2017-08-14 19:55:41.907871 > HCI Event: Command Complete (0x0e) plen 4
    LE Set Scan Enable (0x08|0x000c) ncmd 1
    status 0x00
2017-08-14 19:55:41.914836 > HCI Event: Command Status (0x0f) plen 4
    LE Create Connection (0x08|0x000d) status 0x00 ncmd 1
2017-08-14 19:55:42.075836 > HCI Event: Command Status (0x0f) plen 4
    LE Read Remote Used Features (0x08|0x0016) status 0x00 ncmd 1
2017-08-14 19:55:44.210032 > HCI Event: Command Status (0x0f) plen 4
    LE Connection Update (0x08|0x0013) status 0x00 ncmd 1
2017-08-14 19:55:49.170312 > HCI Event: Disconn Complete (0x05) plen 4
    status 0x00 handle 76 reason 0x13
    Reason: Remote User Terminated Connection
2017-08-14 19:55:49.229181 > HCI Event: Command Complete (0x0e) plen 4
    LE Set Scan Enable (0x08|0x000c) ncmd 1
    status 0x00
2017-08-14 19:55:49.818580 > HCI Event: Command Complete (0x0e) plen 4
    LE Set Scan Enable (0x08|0x000c) ncmd 1
    status 0x00
2017-08-14 19:55:49.824035 > HCI Event: Command Status (0x0f) plen 4
    LE Create Connection (0x08|0x000d) status 0x00 ncmd 1
2017-08-14 19:55:49.984442 > HCI Event: Command Status (0x0f) plen 4
    LE Read Remote Used Features (0x08|0x0016) status 0x00 ncmd 1
2017-08-14 19:55:52.002888 > HCI Event: Command Status (0x0f) plen 4
    LE Connection Update (0x08|0x0013) status 0x00 ncmd 1
2017-08-14 19:56:03.011474 > HCI Event: Command Complete (0x0e) plen 4
    LE Set Scan Enable (0x08|0x000c) ncmd 1
    status 0x0c
    Error: Command Disallowed
2017-08-14 19:56:03.013783 > HCI Event: Command Status (0x0f) plen 4
    Disconnect (0x01|0x0006) status 0x00 ncmd 1
2017-08-14 19:56:03.020437 > HCI Event: Disconn Complete (0x05) plen 4
    status 0x00 handle 74 reason 0x16
    Reason: Connection Terminated by Local Host
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

1 participant