如何使用 C# 在 WinForm 中手动绑定到蓝牙低功耗设备?

Posted

技术标签:

【中文标题】如何使用 C# 在 WinForm 中手动绑定到蓝牙低功耗设备?【英文标题】:How to Bind manually to a BlueTooth Low Energy Device in a WinForm using C#? 【发布时间】:2017-01-01 23:54:47 【问题描述】:

这个问题的回答者大多是:Windows UWP connect to BLE device after discovery

目前,我正在编写自定义服务并进行测试,使用 Windows 10 上的 C#.NET WinForm 连接到蓝牙低功耗 (BLE) 设备。我正在使用框架 4.6.1。我们使用TI SmartRF06 Evaluation Board 和TI CC2650 BLE 子卡。另一位开发人员正在处理主板的固件。

目前使用类似于参考答案above 的方法,我能够连接到已经绑定的 BLE 设备。此设备是手动绑定的,Windows 确实要求我输入 PIN。由于设备没有 PIN,只需输入“0”即可连接设备。以这种方式连接后,我可以访问所有 GATT 服务并做我需要做的事情。因此,我在查找和获取广告 BLE 设备方面没有任何问题。

问题是如何连接到尚未配对的 BLE 设备?我浏览了网络并找到了许多 BLE 代码示例,但没有具体说明代码中的配对是如何完成的。不确定我什至需要它来配对,但 Windows 似乎只在配对设备上显示我的 GATT 服务。

当我使用未配对的设备执行此操作时:

private void BleWatcherOnReceived(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
       
    var dev = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);
    // dev.DeviceInformation.Pairing.CanPair is true
    // dpr.Status is Failed
    DevicePairingResult dpr = await dev.DeviceInformation.Pairing.PairAsync(DevicePairingProtectionLevel.None);
    var service = await GattDeviceService.FromIdAsync(dev.DeviceInformation.Id);

设备未手动配对时,dpr 的结果总是失败。这导致GattDeviceServices 为空。但我可以得到 BLE 设备的广告和属性。

也有这种连接方式,但是不知道怎么用:

var prslt = await device.DeviceInformation.Pairing.Custom.PairAsync(DevicePairingKinds.ProvidePin, DevicePairingProtectionLevel.None,IDevicePairingSettings);

IdeviceParingSettings 是一个接口。不确定要使用什么类。我在想这是我可以设置我可能需要的“O”的 PIN 码的地方吗?

有没有人在 Windows 中使用 C# 与 BLE 设备配对成功,而 BLE 设备没有安全性。基本上它应该是敞开的。我觉得我错过了一些简单的东西,或者这根本不可能(我已经看到一些帖子声称是这种情况。其中大多数都是多年前的)。

我确实尝试了上述帖子中描述的方法,结果没有任何差异。

感谢任何帮助。如果您需要更多代码,请查看我在顶部提供的链接,因为这是我开始的。如果有可能我做的序列不合适,我会很乐意提供我所有的实际代码。

【问题讨论】:

我包含了数据表链接。如果这些不正确,如果你能修复它们会很棒。 【参考方案1】:

我想通了。我是在正确的轨道上。

连接后使用:

var dev = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);

您需要进行自定义配对:

var prslt = await device.DeviceInformation.Pairing.Custom.PairAsync(DevicePairingKinds.ProvidePin, DevicePairingProtectionLevel.None);

但这只会给你一个错误。您还必须创建一个device.DeviceInformation.Pairing.Custom.PairingRequested 事件处理程序。

所以我创建了这个处理程序:

private void handlerPairingReq(DeviceInformationCustomPairing CP, DevicePairingRequestedEventArgs DPR)
        
            //so we get here for custom pairing request.
            //this is the magic place where your pin goes.
            //my device actually does not require a pin but
            //windows requires at least a "0".  So this solved 
            //it.  This does not pull up the Windows UI either.
            DPR.Accept("0");



在 PairAsync 调用之前将其连接起来喜欢:

device.DeviceInformation.Pairing.Custom.PairingRequested += handlerPairingRequested;

完成我的连接的BlueToothAdvertisementWatcher 代码的示例代码:

    private BluetoothLEAdvertisementWatcher BTWatch = new BluetoothLEAdvertisementWatcher();

    private void Inits() 
        
           BTWatch.Received += new TypedEventHandler<BluetoothLEAdvertisementWatcher, BluetoothLEAdvertisementReceivedEventArgs>(BtAddRx);
           BTWatch.Start();
        

    private async void BtAddRx(BluetoothLEAdvertisementWatcher bw, BluetoothLEAdvertisementReceivedEventArgs args)
        
            GattCommunicationStatus srslt;
            GattReadResult rslt;
            bw.Stop();//Stop this while inside.

            device = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);
                if (device.DeviceInformation.Pairing.IsPaired == false)
                   

                    /* Optional Below - Some examples say use FromIdAsync
                    to get the device. I don't think that it matters.   */            
                    var did = device.DeviceInformation.Id; //I reuse did to reload later.
                    device.Dispose();
                    device = null;
                    device = await BluetoothLEDevice.FromIdAsync(did);
                    /* end optional */
                    var handlerPairingRequested = new TypedEventHandler<DeviceInformationCustomPairing, DevicePairingRequestedEventArgs>(handlerPairingReq);
                    device.DeviceInformation.Pairing.Custom.PairingRequested += handlerPairingRequested;
                    log("Pairing to device now...."); 

                    var prslt = await device.DeviceInformation.Pairing.Custom.PairAsync(DevicePairingKinds.ProvidePin, DevicePairingProtectionLevel.None);                  
                    log("Custom PAIR complete status: " + prslt.Status.ToString() + " Connection Status: " + device.ConnectionStatus.ToString());

                    device.DeviceInformation.Pairing.Custom.PairingRequested -= handlerPairingRequested; //Don't need it anymore once paired.


                    if (prslt.Status != DevicePairingResultStatus.Paired)
                     //This should not happen. If so we exit to try again.
                        log("prslt exiting.  prslt.status=" + prslt.Status.ToString());// so the status may have updated.  lets drop out of here and get the device again.  should be paired the 2nd time around?
                        bw.Start();//restart this watcher.
                        return;
                    
                    else
                    
                        // The pairing takes some time to complete. If you don't wait you may have issues. 5 seconds seems to do the trick.

                        System.Threading.Thread.Sleep(5000); //try 5 second lay.
                        device.Dispose();
                       //Reload device so that the GATT services are there. This is why we wait.                     
                       device = await BluetoothLEDevice.FromIdAsync(did);

                    
 var services = device.GattServices;
//then more code to finish it up.

如果您想断开连接,请使用:

await device.DeviceInformation.Pairing.UnpairAsync();

抱歉,代码混乱。如果有人发现有用或有疑问,请告诉我。我在任何地方都找不到此代码的任何 WinForm 示例。实际上我找不到任何代码来显示如何在没有 UI 的情况下与 PIN 配对。所以我希望这可以帮助任何可能陷入困境的人。

【讨论】:

在github.com/Microsoft/Windows-universal-samples/tree/master/…查看场景8和9 谢谢 - 我找到了这样的例子。正在寻找更多窗口形式和更直接的东西。这些信息似乎真的被埋没了。 @MichaelFrederick 帮了大忙,谢谢!不过,我的实施存在一个问题。已配对的设备不会显示在 Windows UI 中(例如,如果您想在没有我的应用的情况下取消配对)。你有问题吗? 这方面仍有问题。我可以启动观察程序,找到设备,通过 await BluetoothLEDevice.FromBluetoothAddressAsync(addres) 但未调用 handlerPairingReq,因此配对失败。我按照你的说法添加了它,但它对我不起作用:( @MichaelFrederick 你的代码对我帮助很大,谢谢

以上是关于如何使用 C# 在 WinForm 中手动绑定到蓝牙低功耗设备?的主要内容,如果未能解决你的问题,请参考以下文章

C#,Winform绑定实体框架(Entity Framework)的实体,如何去掉或隐藏导航属性?

C# winform 类似于如下图显示用啥控件绑定并实现分页

C# winform datagridview 里的下拉框中 既可以从下拉框里选择数据,也可以让客户自己手动往里输入数据,怎

C# Winform Combox的绑定问题

C# winform DataGridView控件DataSource 绑定一个表后修改cell值的问题

C# winform中 界面加载时datagridview绑定了数据源(datatable),修改datagridview的内容后,如何更新数