Bluetooth link disconnect detection issue

Topics: Bluetooth - Microsoft
Mar 29, 2012 at 6:20 AM

Hi

I'm using InTheHand.Net.Personal.dll (version 3.3.909.0) in my C# application to connect to a device with a Bluetooth module.

My laptop has a Broadcom Bluetooth module that I believe is using Microsoft stack.

I can connect to device using BluetoothClient class and send and receive data packets to and from device using  NetworkStream class.

I need to find out if the Bluetooth link to the device has been disconnected so I can reconnect to the device again.

I use the Connected property of the BluetoothClient class.  

Unfortunately this property returns false every time my read operation (from  NetworkStream class) times out.

This time out could be because my device is busy and cannot reply however the Bluetooth link is still connected and I can communicate with the device after device is free with no need to reconnect to it.

Is there any way I can find out the link is disconnected or just the read operation timed out?

Here is the part of my code:

        internal override void RawRead(ref byte[] data, int startIndex, int numberOfBytesToRead, out int totalNumberOfBytesActuallyRead, int timeout_ms)
        {
            totalNumberOfBytesActuallyRead = 0;

            bluetooth_Stream.ReadTimeout = timeout_ms;
            DateTime startTime = DateTime.Now;
            TimeSpan ts = TimeSpan.Zero;

            while ((ts.TotalMilliseconds <= timeout_ms) && (numberOfBytesToRead > 0))
            {
                int bytesReadThisTime;
                try
                {
                    bytesReadThisTime = bluetooth_Stream.Read(data, startIndex, numberOfBytesToRead);
                }
                catch
                {
                    if (!bluetoothConnection.Connected)
                        deviceIsConnected = false;
                    else
                        AddError("bluetooth_Stream.Read timed out!");
                    bytesReadThisTime = 0;
                }
                totalNumberOfBytesActuallyRead += bytesReadThisTime;
                startIndex += bytesReadThisTime;
                numberOfBytesToRead -= bytesReadThisTime;
                ts = DateTime.Now - startTime;
            }

            if (numberOfBytesToRead == 0)
            {
                // Read is done successfully!
                return;
            }
            if (totalNumberOfBytesActuallyRead == 0)
            {
                // No Data!
                throw new Exception("No data available to read (Stopped after " + ts.TotalMilliseconds + "ms)");
            }
            else
            {
                // Not enough data!
                throw new Exception("Insufficient data (" + totalNumberOfBytesActuallyRead + " bytes) to read: (Stopped after " + ts.TotalMilliseconds + "ms)");
            }
        }

where:

        BluetoothClient bluetoothConnection = null;
        NetworkStream bluetooth_Stream = null;
        BluetoothDeviceInfo currentDevice = null;

and of course they have been assigned to an object in other parts of the code.

Developer
Apr 10, 2012 at 8:39 AM

Hopefully you've solved this already.

NetworkStream.ReadTimeout and WriteTimeout cause an error to occur on the socket when the timeout occurs. Thus the socket is closed and can't be used again.  That's the case whether its a TCP/IP or Bluetooth socket.

You'll have to find some other way to handle the situation, perhaps: using the BeginRead and EndRead methods and IAsyncResult.AsyncWaitHandle.WaitOne(timeout) to implement your own timeout.

Apr 10, 2012 at 11:19 PM

Thanks for the reply.

I'll use your advice to handle it in a different way.