Regular disconnects on Parrot Mambo


#1

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 js.

Everything is working really great except that I got 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.

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.

I’m able to detect 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 to 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)
    }
  })
}

What is very strange is that we I run the same code on my Airborne Cargo ,everything works perfect. Connection is rock solid even after a disconnect/reconnect.
On the Mambo, once I’ve been disconnected, connection is unstable.

I already submitted this issue to Noble js team to get their opinion but as it works well on Airborne Cargo, I think their may be a difference between Maabo and Airborne Cargo firmware that create this strange behaviors.

Here is an HCI dump of a connect / disconnect :

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

Any idea would be welcome :smiley:

Thanks,
Gauthier


#2

Really ? Nobody has an idea ?
Any Parrot engineer ?


#3

Bumping this as I am seeing the same thing using python BLE libraries! It is disconnecting quite regularly after 2 commands.


#4

I figured it out, at least for my code, so I’ll share in case it is happening to yours also. Turns out you can’t use regular sleep. You have to wake for notifications or it decides you are not alive anymore and disconnects.