如何使用BluetoothDeviceInfo中的信息识别HID设备,反之亦然 [英] How to identify HID Device with information from BluetoothDeviceInfo or vice-versa

查看:95
本文介绍了如何使用BluetoothDeviceInfo中的信息识别HID设备,反之亦然的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个程序,使与Windows配对的Wiimotes的管理更加简单和自动化.该程序使用 WiimoteLib (使用 32英尺 (使用 Wiipair .目前,该过程有些颠簸且缓慢,但是可以正常工作. (但仅适用于一个Wiimote)

I'm trying to write a program that makes management of Wiimotes paired with Windows a lot simpler and automated. The program uses WiimoteLib (which uses hidsdi.h and setupapi.h) to connect to Wiimote devices, and 32feet (uses Windows Bluetooth API) to automatically pair/unpair devices. The code for the pairer/unpairer is based off of Wiipair. At the moment, the process is a little bumpy and slow, but it works. (But only for one Wiimote)

问题是我的蓝牙设备配对/取消配对模块没有有关如何识别HID设备(由Wiimote类使用)是否为同一设备的信息.如果蓝牙设备已被强制关闭或未配对,我希望能够向Wiimote类发出警报,以便它可以正常断开连接.反之亦然,当HID设备断开连接时,我希望Wiimote提醒配对器/取消配对器,以便可以有选择地取消蓝牙设备的配对(假设您计划关闭Wiimote).

The problem is that my module to pair/unpair Bluetooth devices has no information on how to identify if the HID device (used by the Wiimote class) is the same device. I want to be able to alert the Wiimote class if the Bluetooth device has been forcefully shutdown or unpaired so that it can gracefully disconnect itself. And vice-versa, I'd like the Wiimote to alert the pairer/unpairer when the HID device is disconnected so that the Bluetooth device can optionally be unpaired (assuming you plan on shutting down the Wiimote).

如果我只想访问一个Wiimote,那么这不是什么大问题,但是我希望能够访问多个Wiimotes,并能够通过使用其HID信息和蓝牙信息来区分它们.我已经在使用自己的P/Invoke来弥补32feet所欠缺的区域,因此再使用也不是问题.

If I only wanted access to one Wiimote then this wouldn't be much of a problem, but I'd like to be able to access multiple Wiimotes and be able to differentiate them by using their HID info and Bluetooth Info. I'm already using plenty of my own P/Invoke to cover for areas that 32feet lacks in so using any more isn't a problem.

这是我的配对器的主要代码. (尽管我不确定是否真的必要):

Here's the main code for my pairer. (Although I'm not sure if it's really necessary):

(注意:IsDiscoverable()ToPin()ToMacAddress()都是扩展方法.)

(Note: IsDiscoverable(), ToPin(), and ToMacAddress() are all extension methods.)

// Once this is true, the Wiimote will
// attempt to connect to an HID device.
public bool IsAnyDeviceAvailable { get; private set; }

private void PairTask(CancellationToken token) {
    // Setup automatic authentication
    BluetoothWin32Authentication auth = new BluetoothWin32Authentication(OnHandleRequests);

    while (!token.IsCancellationRequested)
        PairLoop(token);
}

private void PairLoop(CancellationToken token) {
    // Get a copy of known addresses since
    // these are added to in another task.
    BluetoothAddress[] addresses;
    lock (knownAddresses)
        addresses = KnownAddresses.ToArray();

    bool available = false;
    foreach (BluetoothAddress address in addresses) {
        if (token.IsCancellationRequested)
            return;
        BluetoothDeviceInfo device = new BluetoothDeviceInfo(address);

        if (device.Connected) {
            if (!available && !IsAnyDeviceAvailable) {
                lock (knownAddresses)
                    IsAnyDeviceAvailable = true;
            }
            available = true;
            continue;
        }
        if (device.Remembered) {
            RemoveDevice(device, token);
        }
        else if (device.IsDiscoverable() && !device.Authenticated) {
            if (PairDevice(device, token, available))
                available = true;
        }
        token.WaitHandle.WaitOne(500);
    }
    if (!available && IsAnyDeviceAvailable) {
        Trace.WriteLine("No more devices connected");
        lock (knownAddresses)
            IsAnyDeviceAvailable = false;
    }
}

private void RemoveDevice(BluetoothDeviceInfo device, CancellationToken token) {
    token.WaitHandle.WaitOne(1000);
    if (BluetoothSecurity.RemoveDevice(device.DeviceAddress)) {
        Trace.WriteLine($"Wiimote removed: {device.DeviceAddress.ToMacAddress()}");
        token.WaitHandle.WaitOne(2000);
    }
}

private bool PairDevice(BluetoothDeviceInfo device, CancellationToken token,
    bool available)
{
    string pin = device.DeviceAddress.ToPin();

    try {
        if (BluetoothSecurity.PairRequest(device.DeviceAddress, pin)) {
            Trace.WriteLine($"Wiimote authenticated: {device.DeviceAddress.ToMacAddress()}");
            token.WaitHandle.WaitOne(1000);
            // Calling this before and after seems to help unsure
            // the device works when paired programmatically.
            Guid[] services = device.InstalledServices;
            device.SetServiceState(Uuids.HumanInterfaceDeviceServiceClass_UUID, true, true);
            services = device.InstalledServices;
            Trace.WriteLine($"Wiimote paired: {device.DeviceAddress.ToMacAddress()}");

            token.WaitHandle.WaitOne(8000);

            if (!available && !IsAnyDeviceAvailable) {
                Trace.WriteLine("First device has been connected");
                lock (knownAddresses)
                    IsAnyDeviceAvailable = true;
            }
            return true;
        }
        else {
            Trace.WriteLine($"Wiimote authentication failed: {device.DeviceAddress.ToMacAddress()}");
        }
    }
    catch {
        Trace.WriteLine($"Wiimote pairing failed: {device.DeviceAddress.ToMacAddress()}");
    }
    return false;
}

private void OnHandleRequests(object sender, BluetoothWin32AuthenticationEventArgs e) {
    e.Confirm = true;
}

推荐答案

  1. 您不需要与Wiimote配对.与Wiimote配对仅做一件事:Wiimote记住配对设备的MAC,然后可以将其运行并连接到它(太Wii或其他设备).但是,它在Windows上无法使用,因此不需要配对.如果您需要配对,请使用旧版PIN配对. PIN是按反向字节顺序的Wiimote MAC.

  1. You do not need to pair with your Wiimote. Pairing with Wiimote does only one thing: Wiimote remembers MAC of paired device and then can trun it ON and connect to it (too Wii or other device). However it doe snot work with Windows so pairing is not required. If you need pairing then use legacy PIN pairing. PIN is wiimote MAC in reversed bytes order.

使用BluetoothSetServiceState将您的Wiimote作为HID设备添加到系统中.

Use BluetoothSetServiceState to add your wiimote as HID device into the system.

以下代码显示了如何通过其MAC查找Wiimote HID(代码摘自我们的无线通信库,其中包括对Wiimote的支持.

Here is code shows how to find Wiimote HID by its MAC (the code is taken from our Wireless Communication Library that includes support for Wiimote).

m_fInstalled = true;

    Sleep(1000);

    CwclStringList* Wiis = new CwclStringList();

    m_sDevicePath = WCL_EMPTY_STR;
    DWORD dwTik = GetTickCount();
    while (m_sDevicePath == WCL_EMPTY_STR && GetTickCount() - dwTik < 20000)
        if (EnumHID(*Wiis) == WCL_E_SUCCESS)
        {
            CwclString sAddress = GetBluetoothParams()->GetAddress();
            CwclString sAdr = sAddress.Mid(1, 2) + sAddress.Mid(4, 2) + sAddress.Mid(7, 2) + sAddress.Mid(10, 2) + sAddress.Mid(13, 2) + sAddress.Mid(16, 2);
            HKEY hKey;
            CwclString aRegKey(WCL_WII_REG_KEY);
            DWORD dwRes = RegOpenKey(HKEY_LOCAL_MACHINE, aRegKey, &hKey);
            if (dwRes != ERROR_SUCCESS)
                aRegKey = CwclString(WCL_WII_REG_KEY_NEW);
            dwRes = RegOpenKey(HKEY_LOCAL_MACHINE, aRegKey, &hKey);
            if (dwRes == ERROR_SUCCESS)
            {
                DWORD dwNdx = 0;
                WCHAR szSubKeyName[512];
                DWORD dwSubKeySize = sizeof(szSubKeyName);
                ZeroMemory(szSubKeyName, dwSubKeySize);
                while (RegEnumKeyEx(hKey, dwNdx, szSubKeyName, &dwSubKeySize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
                {
                    CwclString sSubKeyStr = CwclString(szSubKeyName);
                    if (sSubKeyStr.Find(sAdr) >= 0)
                    {
                        CwclString sSubKeyPath = aRegKey + L"\\" + sSubKeyStr;
                        HKEY hSubKey;
                        dwRes = RegOpenKey(HKEY_LOCAL_MACHINE, sSubKeyPath, &hSubKey);
                        if (dwRes == ERROR_SUCCESS)
                        {
                            WCHAR szValue[512];
                            DWORD dwValueSize = sizeof(szValue);
                            ZeroMemory(szValue, dwValueSize);
                            dwRes = RegQueryValueEx(hSubKey, L"ParentIdPrefix", NULL, NULL, (LPBYTE)szValue, &dwValueSize);
                            if (dwRes == ERROR_SUCCESS)
                            {
                                CwclString sValueStr = CwclString(szValue);
                                for (INT_PTR i = 0; i < Wiis->GetCount(); i++)
                                    if (Wiis->GetItems(i).Find(sValueStr) >= 0)
                                    {
                                        m_sDevicePath = Wiis->GetItems(i);
                                        break;
                                    }
                            }
                            RegCloseKey(hSubKey);
                        }
                    }

                    if (m_sDevicePath != WCL_EMPTY_STR)
                        break;

                    dwSubKeySize = sizeof(szSubKeyName);
                    ZeroMemory(szSubKeyName, dwSubKeySize);
                    dwNdx++;
                }
                RegCloseKey(hKey);
            }
        }

一旦获得DevicePath,就可以使用CreateFile打开HID设备的句柄.

Once you get DevicePath you can use CreateFile to open HID device's handle.

这篇关于如何使用BluetoothDeviceInfo中的信息识别HID设备,反之亦然的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆