Reading raw data via Bluetooth

13,900

Solution 1

Try this:

var client = new BluetoothClient();
var dlg = new SelectBluetoothDeviceDialog();
DialogResult result = dlg.ShowDialog(this);
if (result != DialogResult.OK)
{
    return;
}
BluetoothDeviceInfo device = dlg.SelectedDevice;
BluetoothAddress addr = device.DeviceAddress;
Console.WriteLine(device.DeviceName);
BluetoothSecurity.PairRequest(addr, "Whatever pin");
device.SetServiceState(BluetoothService.HumanInterfaceDevice, true);
Thread.Sleep(100); // Just in case
if (device.InstalledServices.Length == 0)
{
    // I wouldn't know why it doesn't install the service
}
client.Connect(addr, BluetoothService.HumanInterfaceDevice);

I am no expert by any means, but for me:

  1. I need to pair the device if the device doesn't show in the Bluetooth devices. You just need to do this once with every new device you discover with the Bluetooth radio, or if you uninstall it, I do it every time anyway just in case a new device is selected.
  2. Start the service, once I do this the device will show that a serial port (in your case HID) is available under "Services" in the device's properties.
  3. Connect

In every stage something needs to happen:

  1. Make sure the device appears in "Bluetooth devices" in the "Control panel".
  2. Under the "Services" tab inside the device's "Properties" it should say "Human Interface" or something.
  3. That service should be ticked.

On another note, the exception that you get is really cryptic, but it just made me think if the device is not already connected to something. If you check "device.Connected" it must return false or you won't ever be able to connect.

Solution 2

Arturo's answer is correct. Use SetServiceState (or maybe BluetoothSecurity.PairRequest will do it automatically) to have the Bluetooth stack handle the low-level HID comms and expose the HID events through Windows' HID API. Then your code can use that API.

In more details:

a) HID on Bluetooth doesn't use RFCOMM and that's what BluetoothClient uses. See Bluetooth Profiles and 32feet.NET for more info on what protocol each profile/services uses. There's no simple L2CAP API to use with the Microsoft stack so there's no support (yet?) for L2CapClient there.

b) If one (could) use L2CapClient then one would need to read and write the raw HID data and decode and parse the HID frames. Instead you should get the Bluetooth stack to connect to the device and use the Windows HID APIs to see the button presses. In my 32feet.NET documentation that's point 3 at http://32feet.codeplex.com/documentation

c) The is apparently some fault in e.g. the PS3 Bluetooth controller which means that the Windows HID service can't use it. In that case people do have to connect to the device directly. Apparently...

Share:
13,900
SoloDeveloper
Author by

SoloDeveloper

Updated on June 05, 2022

Comments

  • SoloDeveloper
    SoloDeveloper almost 2 years

    I have a digital Human Interface Device that I'm trying to connect to using 32feet.net so I can read input data from it and process an output in my application. I've never programmed with bluetooth before and am learning as I go.

    I can connect my device to Windows 7 using the microsoft/broadcom stack no problem. I can also discover the device using 32feet.net but when I try to connect it I get an error. I made sure my stack was supported using BluetoothRadio.IsSupported Here is a code snippet:

     var client = new BluetoothClient();
     var dlg = new SelectBluetoothDeviceDialog();
     DialogResult result = dlg.ShowDialog(this);
     if (result != DialogResult.OK)
     {
         return;
     }
     BluetoothDeviceInfo device = dlg.SelectedDevice;
     BluetoothAddress addr = device.DeviceAddress;
     Console.WriteLine(device.DeviceName);
     Guid serviceClass = BluetoothService.HumanInterfaceDevice;
     client.Connect(new BluetoothEndPoint(addr, serviceClass));
    

    The last line causes the following error: A first chance exception of type 'System.Net.Sockets.SocketException' occurred in System.dll

    I've tried some other methods as well with client.Connect. I've tried using DiscoverDevices to get a DeviceInfo array and manually choosing the device out of that array and connecting to it. I've tried setting the serviceClass as Empty because that is what shows up when I use DeviceInfo.ClassOfDevice.Service. I've been able to connect the device to windows using DeviceInfo.SetServiceState(BluetoothService.HumanInterfaceDevice, true) but not able to get a stream from it.

    Even if I can get a data stream from the device after it's been connected in Windows, that would be fine. My goal here is simple to be able to read input from the device like a button press.

  • SoloDeveloper
    SoloDeveloper over 11 years
    Thanks for helping but the exception still occurs. A pairing code isn't needed, I've tried it without the line, with the line, and with the line with an empty string as the pin. The SetServiceState function connects it to the windows stack, is that supposed to happen?
  • Arturo Gurrola
    Arturo Gurrola over 11 years
    I don't really know what "connects it to the windows stack" means. Check out the updates in my answer, they might help