0

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.

  1. Port-1:- Most of the time the connection gets created.
  2. Port-2:- As soon as the device gets connected, it gets disconnected.
  3. Port-3:- Device gets connected but unexpected responses are received.
  4. Port-4:- java.io.IOException: bt socket closed, read return: -1
  5. 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

vibu
  • 77
  • 1
  • 8

0 Answers0