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

Connection will be closed after catching an Error with onErrorResumeNext #26

Closed
tatewaki opened this issue Jun 3, 2016 · 11 comments
Closed
Assignees
Milestone

Comments

@tatewaki
Copy link

tatewaki commented Jun 3, 2016

Summary


On each error the connection get closed. If i will catch an Error with onErrorResumeNext or something, the Connection also get closed.

Preconditions


In some cases, it makes no sense to close the connection.

e.g. BleGattException{status=137, bleGattOperation=BleGattOperation{description='CHARACTERISTIC_READ'}}.

On some devices it is necessary to retry the action without disconnect.

@dariuszseweryn
Copy link
Owner

Hello there. Sorry for no response - we're discussing how to address this issue. Usually any error during communication means the connection is no longer active and usable. We will get back to you.

@tatewaki
Copy link
Author

The problem is: Bonding for BLE on Android is pain in the ass.
Each producer (like htc, Samsung or Xiaomi) has implement this procedure on a different way.
Some devices you can bond, others will bond automatically if you access an encrypted characteristic. If they will bond automatically, on some devices it works in background without you have to do something. Other devices throws an error (like status 137) and you have to repeat it.
And I thought Bluetooth is a standard :-D.

Thanks for the good work so far.

@farmazon3000
Copy link

@tatewaki I have the feeling you're mixing bonding with connecting, I believe those are not the same.

@tatewaki
Copy link
Author

I know that bonding and connection is not the same. And because of that, I reported the issue.
RxAndroidBle will disconnect on an error relating to bonding. But there is no need to disconnect.

@dariuszseweryn dariuszseweryn modified the milestone: 1.1.0 Jul 27, 2016
@asmirsabanovic
Copy link

I have the same issue, is there any work around for now without needing to reconnect after bonding is successful?

@dariuszseweryn
Copy link
Owner

Hello @asmirsabanovic
A workaround would be not to pass status to observables different than the one that emitted it.

@asmirsabanovic
Copy link

@dariuszseweryn thanks for the fast response, but I don't follow completely. Here is how I do it now:

//Read uuid that needs bonding
RxBleConnection.readCharacteristic(AUTH_REQ_UUID)...subscribe(..);

User enters correct PIN -> Bonding Successful

I get: BleGattException{status=137, bleGattOperation=BleGattOperation{description='CHARACTERISTIC_READ'}}

And this disconnects the connection. I do a reconnect and this time the read will work.

How can I do this with your suggestion to avoid the disconnect after bonding is successful?

Thanks again.

@dariuszseweryn
Copy link
Owner

You would need to make some changes in the RxBleGattCallback class. The point is not to pass the status error around via statusBehaviourSubject.

I don't have any experience with bonded devices. Can you confirm that the RxBleGattCallback.onCharacteristicRead() is postponed after the user enters pin? Can you share what device are you using (or is it possible to get one to test the library myself)

@asmirsabanovic
Copy link

If I don't pass the status through statusErrorSubject the connection stays alive after a successful bond.

Yes, the onCharacteristicRead is postponed after the user enters pin or the pin entry is cancelled. I'm currently testing on Samsung S7 Edge and Sony Xperia Z4

@dariuszseweryn
Copy link
Owner

Could you be so kind and paste these two classes to your project:

public class DeviceBondingResult {

    public final BluetoothDevice device;

    public final int previousBondState;

    public final int currentBondState;

    public DeviceBondingResult(BluetoothDevice device, int previousBondState, int currentBondState) {
        this.device = device;
        this.previousBondState = previousBondState;
        this.currentBondState = currentBondState;
    }

    private String bondStateString(int bondState) {
        switch (bondState) {
            case 10:
                return "BOND_NONE";
            case 11:
                return "BOND_BONDING";
            case 12:
                return "BOND_BONDED";
        }
        return "UNKNOWN";
    }

    @Override
    public String toString() {
        return "DeviceBondingResult{" +
                "device=" + device +
                ", previousBondState=" + bondStateString(previousBondState) +
                ", currentBondState=" + bondStateString(currentBondState) +
                '}';
    }
}

and an Observable

public class DeviceBondingObservable extends Observable<DeviceBondingResult> {

    protected DeviceBondingObservable(Context context) {
        super(
                new OnSubscribeFromEmitter<>(emitter -> {
                    final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {

                        @Override
                        public void onReceive(Context context, Intent intent) {
                            final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                            final int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1);
                            final int previousBondState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, -1);
                            final DeviceBondingResult result = new DeviceBondingResult(device, previousBondState, bondState);
                            Log.d("TEST", result.toString());
                            emitter.onNext(result);
                        }
                    };
                    context.registerReceiver(broadcastReceiver, new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED));
                    emitter.setCancellation(() -> context.unregisterReceiver(broadcastReceiver));
                },
                        Emitter.BackpressureMode.BUFFER)
        );
    }
}

Subscribe to DeviceBondingObservable and paste the logs from a bonding procedure that you execute? I then will have some material to think about how to integrate bonding support into the library.

@literator literator removed this from the 2.0.0 milestone Feb 2, 2017
@dariuszseweryn dariuszseweryn self-assigned this May 16, 2017
@dariuszseweryn dariuszseweryn added this to the 1.3.0 milestone May 24, 2017
dariuszseweryn added a commit that referenced this issue Jun 5, 2017
…nection if they are not related directly to `onConnectionStateChanged()`.

Summary: #26

Reviewers: michal.zielinski, pawel.urban

Reviewed By: pawel.urban

Differential Revision: https://phabricator.polidea.com/D2347
@dariuszseweryn
Copy link
Owner

Finally this should be fixed / available in 1.3.0 somewhere this week. Is available on 1.3.0-SNAPSHOT now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants