如何以编程方式配对蓝牙设备

How to programmatically pair a bluetooth device

我最近买了一个 Lilypad Simblee BLE Board and I'd like to pair it programmatically to my computer (using the 32feet.NET C# 库。

我知道 Whosebug 上已经有人问过“如何以编程方式配对蓝牙设备”(here),但是出于某种原因,我尝试以编程方式 配对设备的所有尝试都失败了。事实上,我成功地将设备与Windows 10 设置面板 中的“管理蓝牙设备”window 配对(设置 > 设备 > 蓝牙).

首先,我不知道 pairing methodlegacySSP)可用于我的设备。 Windows 从未要求我提供 PIN 或其他信息,所以我猜这是 SSP,但我不确定。

我在 Google 上搜索了如何与 32feet.NET 进行 SSP 配对请求:我找到了 this

但是,一旦它发现了我的设备(设备发现工作正常),配对请求立即失败。

我的代码:

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
        }
    }
}

为什么配对请求失败?

您链接的问题的答案有一个似是而非的建议...您读过了吗?

你也应该看看this question as well

32feet library is built around legacy pairing, so that you either need to know the pin of the device you are connecting to, or you supply it with a null to get a popup window to enter a pin.

它还说 32feet 使用的 windows 函数在较新版本的 windows 中已弃用。如果这是真的,它立即失败的原因是因为您在配对请求中传递了一个空 pin 并且要继续进行 windows 需要显示一个不再存在的对话框。

如果您尝试连接引脚“0000”或“1234”会怎样?

我正在查看 32feet.net 中 WindowsBluetoothSecurity.cs 的源代码,我查看配对请求是否失败,它会将错误代码记录到 Debug.WriteLine,任何机会post 错误代码在这里?

解决此问题的一个好方法可能是导入 BluetoothAuthenticateDeviceEx 并手动使用它来完成配对请求。如果您不想手动执行此操作,看起来在最新版本的 32feet 源代码中,实际上有一个 SSP 配对方法使用了此方法,但它不是 public 并且没有在任何地方使用,所以您'我需要通过反射访问它:

typeof(BluetoothSecurity)
    .GetMethod("PairRequest", BindingFlags.Static | BindingFlags.NonPublic)
    .Invoke(null, new object[] { _hlkBoardDevice.DeviceAddress, BluetoothAuthenticationRequirements.MITMProtectionNotRequired });