4

我有一个数字人机接口设备,我正在尝试使用 32feet.net 连接它,这样我就可以从中读取输入数据并在我的应用程序中处理输出。我以前从未用蓝牙编程过,我边走边学。

我可以使用 microsoft/broadcom 堆栈将我的设备连接到 Windows 7 没问题。我也可以使用 32feet.net 发现该设备,但是当我尝试连接它时出现错误。我确保使用 BluetoothRadio.IsSupported 支持我的堆栈这是一个代码片段:

 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));

最后一行导致以下错误: System.dll 中发生“System.Net.Sockets.SocketException”类型的第一次机会异常

我也用client.Connect尝试了其他一些方法。我尝试使用 DiscoverDevices 获取 DeviceInfo 数组并手动从该数组中选择设备并连接到它。我尝试将 serviceClass 设置为 Empty,因为这是在我使用 DeviceInfo.ClassOfDevice.Service 时出现的。我已经能够使用 DeviceInfo.SetServiceState(BluetoothService.HumanInterfaceDevice, true) 将设备连接到 Windows,但无法从中获取流。

即使我可以在设备连接到 Windows 后从设备获取数据流,那也没问题。我的目标很简单,就是能够像按下按钮一样读取设备的输入。

4

2 回答 2

1

试试这个:

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);

无论如何,我都不是专家,但对我来说:

  1. 如果设备未显示在蓝牙设备中,我需要配对设备。您只需对通过蓝牙无线电发现的每台新设备执行一次此操作,或者如果您卸载它,我每次都会执行此操作,以防选择了新设备。
  2. 启动服务,一旦我这样做,设备将显示串行端口(在您的情况下为 HID)在设备属性的“服务”下可用。
  3. 连接

在每个阶段都需要发生一些事情:

  1. 确保设备出现在“控制面板”的“蓝牙设备”中。
  2. 在设备“属性”内的“服务”选项卡下,它应该显示“人机界面”或其他内容。
  3. 该服务应该打勾。

另一方面,您得到的异常确实很神秘,但这只是让我想到设备是否尚未连接到某些东西。如果您检查“device.Connected”,它必须返回 false,否则您将永远无法连接。

于 2012-11-29T23:21:55.263 回答
1

阿图罗的回答是正确的。使用SetServiceState(或者BluetoothSecurity.PairRequest会自动执行)让蓝牙堆栈处理低级 HID 通信并通过 Windows 的 HID API 公开 HID 事件。然后您的代码可以使用该 API。

详细信息:

a) 蓝牙上的 HID 不使用 RFCOMM,而这正是 BluetoothClient 使用的。有关每个配置文件/服务使用的协议的更多信息,请参阅蓝牙配置文件和 32feet.NET。没有简单的 L2CAP API 可以与 Microsoft 堆栈一起使用,因此那里没有对 L2CapClient 的支持(还没有?)。

b) 如果(可能)使用 L2CapClient,则需要读取和写入原始 HID 数据并解码和解析 HID 帧。相反,您应该让蓝牙堆栈连接到设备并使用 Windows HID API 来查看按钮按下情况。在我的 32feet.NET 文档中,第 3 点位于http://32feet.codeplex.com/documentation

c) 这显然是一些故障,例如 PS3 蓝牙控制器,这意味着 Windows HID 服务无法使用它。在这种情况下,人们必须直接连接到设备。 显然...

于 2012-12-02T21:08:50.433 回答