Don R
Don R

Reputation: 623

How does one get BluetoothSocket.Connect() to succeed? (read failed, socket might closed or timeout, read ret: -1)

I've seen many versions of this question, and I've tried all the proposed answers but I, like what seems like most of the posters, have had no joy with any of them. I am getting a BluetoothDevice from a scan filtered on a known UUID with no apparent problem, but when I try to connect a socket created on that device the connection attempt times out (seemingly; it tries for about 10 seconds first) and throws an IOException with the message read failed, socket might closed or timeout, read ret: -1. As you can see in the code for the function where I'm trying to test making a connection, this happens with both CreateRfcommSocketToServiceRecord and createRfcommSocket. I have also tried the "Insecure" versions of both with the same results.

I've tried confirming that the device offers the expected UUID, but calling GetUuids() returns null; maybe that's a clue? FetchUuidsWithSdp() returns true, so I'm guessing the scanned device is still visible at that point. Also, both devices prompt to confirm pairing, so that supports the idea that they are communicating OK. I don't understand how I can successfully scan the device filtered on that service UUID if it doesn't actually offer it, though?

Here's the function that tries to make the connection:

public void Connect(BluetoothDevice device)
{
    if (device.BondState != Bond.Bonded)
    {
        device.CreateBond();
    }

    ParcelUuid[] uuids = null;
    if (device.FetchUuidsWithSdp())
    {
        uuids = device.GetUuids();
    }
    //if (null == uuids || 0 == uuids.GetLength(0))
    //{
    //    throw new System.Exception("No service UUIDs found for peripheral device");
    //}
    //UUID uuid = uuids[0].Uuid; // There should be only one service offered by one of our devices
    BluetoothSocket socket;
    try
    {
        socket = device.CreateRfcommSocketToServiceRecord(UUID.FromString(BluetoothConstants.MY_SERVICE_UUID));
        if (null == socket)
        {
            throw new Exception("Failed to create socket");
        }
        socket.Connect();
    }
    catch (IOException x)
    {
        Method method = device.Class.GetMethod("createRfcommSocket", Integer.Type);
        socket = (BluetoothSocket)method.Invoke(device, 1);
        if (null == socket)
        {
            throw new Exception("Failed to create socket");
        }
        socket.Connect();
    }
    if (false == socket.IsConnected)
    {
        throw new System.Exception(string.Format("Failed to connect to service {0}", device.Name));
    }
}

Here's the code that starts the filtered scan:

    List<ScanFilter> filters = new List<ScanFilter>();
    filters.Add(new ScanFilter.Builder()
        .SetServiceUuid(new ParcelUuid(UUID.FromString(BluetoothConstants.MY_SERVICE_UUID)))
        .Build()
    );

    ScannerCallback callback = new ScannerCallback(); // inherits from ScanCallback

    BluetoothLeScanner scanner = BluetoothAdapter.DefaultAdapter.BluetoothLeScanner;

    scanner.StartScan(filters, new ScanSettings.Builder().Build(), callback);

                                                          

I'm grateful for any advice that might help.

EDIT: The device I'm connecting to is also a (very simple) test app that I created myself, rather than a standard peripheral like a heart rate monitor or headphones. Is it likely that matters?

Upvotes: 1

Views: 370

Answers (1)

Thom
Thom

Reputation: 15072

For me it was the UUID. I don't understand these things, but I tried connecting with one in an example 00001101-0000-1000-8000-00805F9B34FB. This was connecting to an HC-05 based module on my Arduino and it is working.

Upvotes: 0

Related Questions