React-native-ble-plx: Cannot reconnect device after being disconnected.

Created on 9 Dec 2017  路  4Comments  路  Source: Polidea/react-native-ble-plx

I've written a BLE app and it basically worked,with connecting, discovering and reading/writing characteristics features. But when connection is interrupted for some reasons (switching BLE on/off on phone, or resetting peripheral, or just disconnecting by distance), it cannot reconnect again, though peripheral is still visible via scanning process.

I could not run the demo Sniffator code (is it compatible with RN 0.44.0? And the version on Appstore works fine), so I read the source and tried to implement this flow:

  1. Start scanning for some serviceIds & allowDuplicates = false.
  2. Meet specific device --> connect to it + Register to onDisconnected event to trigger cancelDeviceConnection.

I tested:

  1. After first connection succeed, move the peripheral far away to disconnect --> console log shows that cancelDeviceConnection fails with Cancelled message.
  2. Move peripheral in again --> console log shows the connectToDevice is called twice, and connection is rejected with Cancelled message.

When I kill and restart app, it will work again but still only success for the first time connecting.

Please give me some advices to solve this problem.

Most helpful comment

I think current behaviour is correct.

First of all when error happens in scanning you don't have to stop it explicitly.

It is possible that scanning will emit multiple scanned devices before advertisement is stopped by real device. It is your responsibility to stopScanning before connecting, or making sure you are calling connect only once.

When connection is in progress and next connectDevice function is called for the same device, previous promise will be cancelled. Also it may lead to situation that previous connection is not fully disconnected yet and new one cannot properly finish as well.

All 4 comments

Update
Here're my codes:

    scanAndConnect() {
        this._bleManager.startDeviceScan([SOME_SERVICE_IDS], { allowDuplicates: false }, (error, device) => {
            if (error) {
                // Handle error (scanning will be stopped automatically)
                this._bleManager.stopDeviceScan();

                return;
            }

            // Check if it is a device you are looking for based on advertisement data
            // or other criteria.
            if (device.name && device.name === SOME_NAME) {

                // Proceed with connection.
                this.connectDevice(device);
            }
        });
    }


    connectDevice(device) {
        this._bleManager.connectToDevice(device.id)
            .then((device) => {
                console.log("success");
            },
            (rejected) => {
                console.log("connection rejected: ", rejected.message);
            });
    }

Observations:

  1. Running code without debugging, in case of failure, will log connection rejected twice.
  2. When I place a breakpoint at this._bleManager.connectToDevice(device.id), the re-connection will always success (console logs success). Remove that breakpoint or place it somewhere else, reconnect will fail (console logs connection rejected: ...).
  3. I thought the breakpoint stops will give BLE module time to do something, so that the next connection will be succeed. So, I tried to delay the connectDevice like this: setTimeout(this.connectDevice.bind(this, device), 10000);, but still, it fails.

Update
I figured out the case of my code: after disconnecting, if peripheral re-appears in phone's scanning range, the phone tries to connect to peripheral immediately. While connection is not established yet, peripheral is discovered once again --> my phone call connectToDevice one more time. Since 2 connections are trying to be made simultaneously, BLEmodule rejects them. Is my thought correct?

After adding code to check status of connection (DISCONNECTED/CONNECTING/CONNECTED), my app works normally.

If that's truly the reason, I think we could improve by implementing the checking code right in BleModule, or at least, dont reject both connections.

I think current behaviour is correct.

First of all when error happens in scanning you don't have to stop it explicitly.

It is possible that scanning will emit multiple scanned devices before advertisement is stopped by real device. It is your responsibility to stopScanning before connecting, or making sure you are calling connect only once.

When connection is in progress and next connectDevice function is called for the same device, previous promise will be cancelled. Also it may lead to situation that previous connection is not fully disconnected yet and new one cannot properly finish as well.

Thanks for this clarification

It is your responsibility to stopScanning before connecting, or making sure you are calling connect only once.

I'm gonna close this issue.

Nevertheless, I think that pp can encounter this problem quite frequently, do you think you could make an enhancement for this library?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

brycejacobs picture brycejacobs  路  5Comments

JordanKlaers picture JordanKlaers  路  5Comments

cltsang picture cltsang  路  4Comments

rottenoats picture rottenoats  路  4Comments

juanjo-ramos picture juanjo-ramos  路  3Comments