5

这个问题的答案主要是:Windows UWP connect to BLE device after discovery

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

目前使用类似于上面参考答案的方法,我能够连接到已经绑定的 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 设备没有安全性。基本上它应该是敞开的。我觉得我错过了一些简单的东西,或者这根本不可能(我已经看到一些帖子声称是这种情况。其中大多数都是多年前的)。

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

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

4

1 回答 1

7

我想到了。我走在正确的轨道上。

连接后使用:

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 配对。所以我希望这可以帮助任何可能陷入困境的人。

于 2017-01-02T08:57:29.727 回答