如何通过编程配对蓝牙设备

5
我最近购买了一个Lilypad Simblee BLE Board,我想用编程的方式将其与我的计算机配对(使用C#中的32feet.NET库)。
我知道“如何以编程方式配对蓝牙设备”已经在StackOverflow上被问过(例如这里),但出于某种原因,我所有尝试以编程方式配对设备的尝试都失败了。实际上,我成功地将设备与Windows 10设置面板中的“管理蓝牙设备”窗口进行了配对(设置>设备>蓝牙)。
首先,我不知道我的设备应该使用配对方法(传统的或SSP)。Windows从未要求我输入PIN码之类的东西,所以我猜是SSP,但我不确定。
我在Google上搜索如何使用32feet.NET进行SSP配对请求:我找到了这个
然而,一旦它发现我的设备(设备发现正常工作),配对请求立即失败。
我的代码:
using InTheHand.Net.Bluetooth;
using InTheHand.Net.Sockets;
using System;
using System.Collections.Generic;

namespace HLK_Client
{
    class HLKBoard
    {
        public event HLKBoardEventHandler HLKBoardConnectionComplete;
        public delegate void HLKBoardEventHandler(object sender, HLKBoardEventArgs e);

        private BluetoothClient _bluetoothClient;
        private BluetoothComponent _bluetoothComponent;
        private List<BluetoothDeviceInfo> _inRangeBluetoothDevices;
        private BluetoothDeviceInfo _hlkBoardDevice;
        private EventHandler<BluetoothWin32AuthenticationEventArgs> _bluetoothAuthenticatorHandler;
        private BluetoothWin32Authentication _bluetoothAuthenticator;


        public HLKBoard()
        {
            _bluetoothClient = new BluetoothClient();
            _bluetoothComponent = new BluetoothComponent(_bluetoothClient);
            _inRangeBluetoothDevices = new List<BluetoothDeviceInfo>();
            _bluetoothAuthenticatorHandler = new EventHandler<BluetoothWin32AuthenticationEventArgs>(_bluetoothAutenticator_handlePairingRequest);
            _bluetoothAuthenticator = new BluetoothWin32Authentication(_bluetoothAuthenticatorHandler);

            _bluetoothComponent.DiscoverDevicesProgress += _bluetoothComponent_DiscoverDevicesProgress;
            _bluetoothComponent.DiscoverDevicesComplete += _bluetoothComponent_DiscoverDevicesComplete;
        }


        public void ConnectAsync()
        {
            _inRangeBluetoothDevices.Clear();
            _hlkBoardDevice = null;
            _bluetoothComponent.DiscoverDevicesAsync(255, true, true, true, false, null);
        }


        private void PairWithBoard()
        {
            Console.WriteLine("Pairing...");

            bool pairResult = BluetoothSecurity.PairRequest(_hlkBoardDevice.DeviceAddress, null);

            if (pairResult)
            {
                Console.WriteLine("Success");
            }

            else
            {
                Console.WriteLine("Fail"); // Instantly fails
            }
        }


        private void _bluetoothComponent_DiscoverDevicesProgress(object sender, DiscoverDevicesEventArgs e)
        {
            _inRangeBluetoothDevices.AddRange(e.Devices);
        }

        private void _bluetoothComponent_DiscoverDevicesComplete(object sender, DiscoverDevicesEventArgs e)
        {
            for (int i = 0; i < _inRangeBluetoothDevices.Count; ++i)
            {
                if (_inRangeBluetoothDevices[i].DeviceName == "HLK")
                {
                    _hlkBoardDevice = _inRangeBluetoothDevices[i];
                    PairWithBoard();

                    return;
                }
            }

            HLKBoardConnectionComplete(this, new HLKBoardEventArgs(false, "Didn't found any \"HLK\" discoverable device"));
        }

        private void _bluetoothAutenticator_handlePairingRequest(object sender, BluetoothWin32AuthenticationEventArgs e)
        {
            e.Confirm = true; // Never reach this line
        }
    }
}

为什么配对请求失败?
1个回答

2
你链接的问题的答案提出了一个合理的建议...你看过它吗?
此外,你还应该查看这个问题
32feet库是围绕传统配对构建的,因此你需要知道连接到的设备的PIN码,或者提供一个空值以弹出窗口输入PIN码。
它还说32feet使用的Windows函数在新版本的Windows中已经不推荐使用。如果是真的,那么它立即失败的原因是你在配对请求中传递了一个空的PIN码,而为了继续进行,Windows需要显示一个对话框,但这个对话框已经不存在了。
如果你尝试使用PIN码“0000”或“1234”连接会发生什么?
我正在查看32feet.net中的WindowsBluetoothSecurity.cs源代码,如果配对请求失败,它会将错误代码记录到Debug.WriteLine,你能否在这里发布该错误代码?
解决这个问题的一个好方法可能是导入BluetoothAuthenticateDeviceEx并手动使用它来完成配对请求。如果你不想手动进行操作,最新版本的32feet源代码中实际上有一种SSP配对方法,它利用了这种方法,但它不是公开的,也没有在任何地方使用,因此你需要通过反射来访问它:
typeof(BluetoothSecurity)
    .GetMethod("PairRequest", BindingFlags.Static | BindingFlags.NonPublic)
    .Invoke(null, new object[] { _hlkBoardDevice.DeviceAddress, BluetoothAuthenticationRequirements.MITMProtectionNotRequired });

如果我尝试使用“0000”或“1234”这个PIN码进行连接,它也会立即失败。此外,在调试器输出中没有打印错误代码。我尝试直接使用BluetoothAuthenticateDeviceEx()(在C++中避免在C#中出现编组错误),但它失败并显示错误代码1450,即ERROR_NO_SYSTEM_RESOURCES(代码:https://dev59.com/uWXWa4cB1Zd3GeqPMWAd#18466409)。此外,我尝试了你的代码,但是`GetMethod()`返回`null`。然而,我能够通过反射获取到`WindowsBluetoothSecurity`类。我使用的是32feet.NET稳定版本3.5.0。有什么想法吗? - GuiTeK
1
对于那些有兴趣在Windows上使用BLE的人:请使用UWP API和Windows.Devices.Bluetooth.GenericAttributeProfile命名空间。 - GuiTeK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接