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

IOException: read failed, socket might closed or timeout, read ret: -1 #164

Open
vaibhiarora03 opened this issue Feb 9, 2022 · 5 comments

Comments

@vaibhiarora03
Copy link

I've been facing this issue while connecting OBDII devices. This issue's occurrence is very random varied across cheap Chinese OBD devices to expensive branded ones.

For Bluetooth communication in flutter, I'm using the Flutter Bluetooth Serial package https://pub.dev/packages/flutter_bluetooth_serial

What I'm doing is initially creating a socket via createRfcommSocketToServiceRecord method. When IOException occurs, then the socket is created via createRfcommSocket reflection method. If still, the IOException occurs, then the Input and Output streams and socket are closed manually and then the connection is tried again. I try connection a total of 3 times.

Here is the connect function which I changed in the package.

public void connect() throws IOException {
        if (isConnected()) {
            throw new IOException("already connected");
        }

        BluetoothSocket fallbackSocket = null;
        boolean isConnectionEstablished = false;

        BluetoothDevice device = bluetoothAdapter.getRemoteDevice(mRemoteAddress);
        if (device == null) {
            throw new IOException("device not found");
        }

        mBluetoothSocket = device.createRfcommSocketToServiceRecord(DEFAULT_UUID); // @TODO . introduce ConnectionMethod
        if (mBluetoothSocket == null) {
            throw new IOException("socket connection not established");
        }

        // Cancel discovery, even though we didn't start it
        bluetoothAdapter.cancelDiscovery();

        if (mFirstConnection == 0)
            mFirstConnection = 1;
        try {
            mBluetoothSocket.connect();
            isConnectionEstablished = true;
        } catch (IOException ioException) {
            Log.e(TAG, "IO exception: " + ioException.getMessage());
          
            try {
                Class<?> clazz = mBluetoothSocket.getRemoteDevice().getClass();
                Class<?>[] paramTypes = new Class<?>[] {Integer.TYPE};
                Method m = clazz.getMethod("createRfcommSocket", paramTypes);
                Object[] params = new Object[] {Integer.valueOf(1)};
                mFallBackSocket = (BluetoothSocket)m.invoke(mBluetoothSocket.getRemoteDevice(), params);
                mBluetoothSocket = mFallBackSocket;
                if (mBluetoothSocket != null) {
                    mBluetoothSocket.connect();
                    isConnectionEstablished = true;
                }else{
                    Log.d(TAG, "fallback_socket received null....: " + mBluetoothSocket);
                }
            } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException | IOException e) {
                Log.e(TAG, "exception_in_code....: " + e);
                e.printStackTrace();
            }
        }

        if (isConnectionEstablished) {
            connectionThread = new ConnectionThread(mBluetoothSocket);
            connectionThread.start();
        } else {
            if (mFirstConnection == 1) {
                mFirstConnection = 2;
                resetFallBackSocket();
                reconnectSocket();
            } else if (mFirstConnection == 2) {
                mFirstConnection = 3;
                resetFallBackSocket();
                reconnectSocket();
            } else {
                mFirstConnection = 0;
                resetFallBackSocket();
                throw new IOException("socket connection not established...");
            }
        }
    }

public void resetFallBackSocket() {
        mFallBackSocket = null;
    }

reconnectSocket is the function in which the Input and Output streams and Socket is closed manually and connection is tried again.

public void reconnectSocket() throws IOException  {
        Log.e(TAG, "debug13. Reconnection Bluetooth socket..");
        dataLogsFinal = dataLogsFinal + "debug13. Reconnection Bluetooth socket..$";
        Log.d(TAG, "Reconnection Bluetooth socket...");
        if (mBluetoothSocket == null)
            throw new IOException("Bluetooth Socket is NULL!" + dataLogsFinal);

        StringBuilder errorBuilder = new StringBuilder();

        try {
            mBluetoothSocket.getInputStream().close();
        } catch (IOException | NullPointerException e) {
            e.printStackTrace();
            Log.e(TAG, "Error closing input stream: " + e.getMessage());
            errorBuilder.append("Error closing input stream: ").append(e.getMessage()).append(" | ");
        }

        try {
            mBluetoothSocket.getOutputStream().close();
        } catch (IOException | NullPointerException e) {
            e.printStackTrace();
            Log.e(TAG, "Error closing output stream: " + e.getMessage());
            errorBuilder.append("Error closing output stream: ").append(e.getMessage()).append(" | ");
        }

        try {
            mBluetoothSocket.close();
            Thread.sleep(1000);
        } catch (IOException | InterruptedException | NullPointerException e) {
            e.printStackTrace();
            Log.e(TAG, "Error closing bluetooth socket: " + e.getMessage());
            errorBuilder.append("Error closing bluetooth socket: ").append(e.getMessage()).append(" | ");
        }
        try {
            connect();
        } catch (IOException e) {
            e.printStackTrace();
            Log.e(TAG, "Error starting service: " + e.getMessage());
            errorBuilder.append("Error starting service: ").append(e.getMessage());
            throw new IOException(errorBuilder.toString());
        }
    }

I've tried changing the channel value for the port ranging from 1-5 for the reflection method.

Port-1:- Most of the time the connection gets created.
Port-2:- As soon as the device gets connected, it gets disconnected.
Port-3:- Device gets connected but unexpected responses are received.
Port-4:- java.io.IOException: bt socket closed, read return: -1
Port-5:- java.io.IOException: bt socket closed, read return: -1
How do we figure out that port number has to be used for creating the connection via the reflection method?

Previously we had faced a similar kind of issue with the native android app and the issue was resolved with the help of the exact same methods which I've mentioned above.

With all the possible tries, now ran out of ideas. Any help will be very much appreciated.

Thanks

@vaibhiarora03
Copy link
Author

@AgainPsychoX can you please help me out in this? Any help will be highly appreciated.

Thanks

@RRohitM
Copy link

RRohitM commented Jun 16, 2022

@AgainPsychoX can you please help me out in this? Any help will be highly appreciated.

Thanks

@vaibhiarora03
Copy link
Author

@RRohitM are you also facing the same issue? What's the occurrence pattern of the issue?

@RRohitM
Copy link

RRohitM commented Jun 17, 2022

Hello @vaibhiarora03 please replace this code i have resolve this error

You can change BluetoothConnection.java class
you can replace connect method

/// Connects to given device by hardware address (default UUID used)
public void connect(String address) throws IOException {
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice device = btAdapter.getRemoteDevice(address);
ParcelUuid[] uuids = (ParcelUuid[]) device.getUuids();
connect(address, uuids[0].getUuid());
}

@vaibhiarora03
Copy link
Author

Hi @RRohitM thanks for sharing your input.

The nature and occurrence of this issue is something different for me.
1.For some users the code was working perfectly fine without any disconnection issue.
2.For some users, this error occurred randomly, sometime it worked and sometime if got error. After multiple tries it started working.
3.For some users, it was a complete blockage. Each time they attempted connection, this error occurred. Not even a single time the connection was made for them.
The bluetooth devices used by all 3 user-type were almost similar and in some cases the devices were from the same manufacturer as well.

Were you facing a complete blockage with this error or was the error-case like mine?

Regards
Vaibhav

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

2 participants