Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BluetoothSocket.connect() throwing exception "read failed"

I have a project that connects to a device over Bluetooth. It used to work fairly reliably, but now it fails the BluetoothSocket.connect() call every time. (Well, I got it to connect once during the thousands of attempts over a 4 hour period.) Most of the code has been taken from the standard sample chat code in the API, with the exception of the common modification in getting the BluetoothSocket device itself:

Method m = device.getClass().getMethod(
              "createRfcommSocket", new Class[] { int.class });
tmp = (BluetoothSocket) m.invoke(device, Integer.valueOf(1));

Here's the method of interest, which gets run once a BluetoothSocket is obtained:

public void run() {
  setName("ConnectThread" + mSocketType);

  // Always cancel discovery because it will slow down a connection
  mAdapter.cancelDiscovery();

  // Make a connection to the BluetoothSocket
  try {
    mmSocket.connect();
  } catch (Exception e) {
    Log.e(TAG, "Connection to " + mmDevice.getName() + " at "
                + mmDevice.getAddress() + " failed:" + e.getMessage());
    // Close the socket
    try {
        mmSocket.close();
    } catch (Exception e2) {
        Log.e(TAG, "unable to close() " + mSocketType
                + " socket during connection failure", e2);
    }
    connectionFailed(e.getMessage());
    return;
  }

  // Reset the ConnectThread because we're done
  synchronized (BluetoothChatService.this) {
    mConnectThread = null;
  }

      // Start the connected thread
  connected(mmSocket, mmDevice, mSocketType);
}

The relevant log entry (printed when the exception is caught while calling connect()) is this:

11-30 10:23:51.685: E/BluetoothChatService(2870): Connection to ZYNO-700091 at 00:06:66:42:8E:01 failed:read failed, socket might closed, read ret: -1

This error used to come up once in a while. I have an aggressive reconnect system - it basically hammers the connection over and over until it connects, and if it were ever to disconnect, it starts hammering it again. So, it kills the connection thread and starts from scratch constantly. I had considered that there might be an issue there - maybe a multithreading one, or maybe in handling the socket cleanup/initialization. However, if that were the case, I'd still expect the first connection attempt to succeed, since that system doesn't kick in until there's a failed connection attempt.

I looked into the source code throwing the exception. The issue seems to be that the underlying InputStream has no data. Of course, that's not really an answer, just a step towards it. Why would the stream have no data?

I'm trying to keep an open mind about the potential issue. Am I getting the BluetoothSocket properly? The fact that it was once an intermittent issue and is now nearly constant makes me suspect multithreading, but that's a relatively simple topic in Java compared to C++ - hard to screw up if you know what you're doing. Plus, the majority of this code (in particular, the parts dealing with synchronizing the threads) is straight out of the sample code.

The device on the other end is an embedded Bluetooth device, so there's not much hope of debugging the problem from that end.

UPDATE ===========================

It occurred to me that it might be due to an OS upgrade (I'm running on Galaxy Nexus phones - I have several to test with). So I unpacked a new phone with 4.0.4 and it worked! So then went back and tested on the two original test phones, both running 4.2, expecting the failure I've been seeing all this time. Strangely, now it works on those phones too. I'd like to say I did something to make this work again, but I didn't. I'm still mystified, and now also suspicious that this thing is going to work when I really need it to.

I wonder if there's a possibility that somehow connecting using 4.0.4 could have properly set the state of the server module, making it receptive to the 4.2 devices? Just a shot in the dark, I suppose...

UPDATE 2 ===========================

I've found that unpairing and re-pairing will allow the devices to connect. It's a workaround, but it's better than nothing.

like image 995
Todd Sjolander Avatar asked Nov 30 '12 15:11

Todd Sjolander


3 Answers

In my case it was due to bad UUID in createRfcommSocketToServiceRecord() function. I want to connect to SPP serial profile in raspberry pi 3 and I used this UUID:

private static final UUID MY_UUID_SECURE =
            UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

I found somewhere in android documents' page for SPP.

like image 145
sbsohrabi Avatar answered Nov 01 '22 02:11

sbsohrabi


Jellybean has a completely different Bluetooth stack, so version differences could certainly be triggering something, but that in itself wouldn't explain why it stays working or not-working after connecting with an older device. Could it be to do with pairing? If it happens again, try unpairing from the device and pairing again.

like image 10
Dan Hulme Avatar answered Nov 01 '22 02:11

Dan Hulme


I know this is kind of an old question. But as I was not able to find any solution on the web, here is a workaround I recently have created: IOException: read failed, socket might closed - Bluetooth on Android 4.3

like image 2
matthes Avatar answered Nov 01 '22 01:11

matthes