kenjdavidson / react-native-bluetooth-classic

⚛ Bluetooth classic Android(Bluetooth)/IOS(ExternalAccessory) module for serial communication
https://kenjdavidson.github.io/react-native-bluetooth-classic
MIT License
249 stars 93 forks source link

We need to call cancelAccept, after a connection is made, if we want to accept and connect again #245

Closed zpinto123 closed 1 year ago

zpinto123 commented 1 year ago

Mobile Device Environment Provide a list of operating systems on which this issue is relevant.

Application Environment Provide information about your development environment:

Describe the bug To be able to accept a new connection, after already having been connected and then disconnected, we need to actually cancelAccept, before being able to connect again.

To Reproduce Steps to reproduce the behavior: 1- device1 and device2 are paired. 2- device2 is set into accept mode. 3- device1 connects to device2 (device2.connect()) 4- we then disconnect the devices (device1/2.disconnect()) 5- we set device2 into accept mode again and we get an error saying it's already in accept mode (but it's not) 6- we try and connect device1 to device2 (device2.connect()), and we actually get device1 connected to device2, but the accept from device2 never gets triggered. 7- we run getConnectedDevices on device1 and we get device2 8- we run getConnectedDevices on device2 and we get nothing.

Expected behavior We should be able to connect and disconnect by just setting a device to accept mode, without needing to cancelAccept after a connection.

I'm creating this "issue", because I've made some changes to the native code and it fixed the problem, and wanted to know if the solution looks good to you and if I should go ahead with a PR. Though I'm only looking at Android, so I don't know if iOS has the same issue, nor do I have iOS devices to test if it has the same issue.

The issue lies in the accept method, inside the RNBluetoothClassicModule.java file. inside the success method, when you're adding the acceptor.addListener.

After the promise.resolve(nativeDevice.map()), we need to clear the mAcceptor, otherwise the next time we run accept, it will check if mAcceptor is != null, and since we never cleared it, when the connection was accepted, it will always fall inside that if condition and reject with Exceptions.BLUETOOTH_IN_ACCEPTING.message().

To solve this issue, I've just added these two lines, after promise.resolve(nativeDevice().map())

mAcceptor.cancel();
mAcceptor = null;

After doing this change, I am now able to accept -> connect -> disconnect and then accept again, without having to manually cancelAccept after every connection is made.

kenjdavidson commented 1 year ago

Would you like to submit a PR?

jpinto321 commented 1 year ago

Sure. I'll do that starting next week.