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

2024-04-30

这个问题的回答大多是:Windows UWP 发现后连接到 BLE 设备 https://stackoverflow.com/questions/35420940/windows-uwp-connect-to-ble-device-after-discovery/41413736#41413736

我正在编写自定义服务并进行测试,目前使用 Windows 10 上的 C#.NET WinForm 连接到蓝牙低功耗 (BLE) 设备。我使用的是框架4.6.1。我们正在使用一个TI SmartRF06 评估板 http://www.ti.com/tool/smartrf06ebk with a TI CC2650 BLE http://www.ti.com/product/cc2650女儿卡。另一位开发人员正在处理主板的固件。

目前使用的方法与参考答案类似above https://stackoverflow.com/questions/35420940/windows-uwp-connect-to-ble-device-after-discovery/41413736#41413736我能够连接到已绑定的 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 设备没有安全性。基本上应该是敞开的。我觉得我错过了一些简单的东西,或者这根本不可能(我看到一些帖子声称是这种情况。其中大多数已经有很多年了)。

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

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


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

连接后使用:

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • ASP.NET Core Serilog 未将属性推送到其自定义列

    我有这个设置appsettings json对于我的 Serilog 安装 Serilog MinimumLevel Information Enrich LogUserName Override Microsoft Critical Wr
  • Qt-Qlist 检查包含自定义类

    有没有办法覆盖加载自定义类的 Qt QList 的比较机制 即在 java 中你只需要重写一个比较方法 我有一个带有我的自定义类模型的 QList QList
  • UML类图:抽象方法和属性是这样写的吗?

    当我第一次为一个小型 C 项目创建 uml 类图时 我在属性方面遇到了一些麻烦 最后我只是将属性添加为变量 lt
  • 从父类调用子类方法

    a doStuff 方法是否可以在不编辑 A 类的情况下打印 B did stuff 如果是这样 我该怎么做 class Program static void Main string args A a new A B b new B a
  • linux perf:如何解释和查找热点

    我尝试了linux perf https perf wiki kernel org index php Main Page今天很实用 但在解释其结果时遇到了困难 我习惯了 valgrind 的 callgrind 这当然是与基于采样的 pe
  • Newtonsoft JSON PreserveReferences处理自定义等于用法

    我目前在使用 Newtonsoft Json 时遇到一些问题 我想要的很简单 将要序列化的对象与所有属性和子属性进行比较以确保相等 我现在尝试创建自己的 EqualityComparer 但它仅与父对象的属性进行比较 另外 我尝试编写自己的
  • 为什么#pragma optimize("", off)

    我正在审查一个 C MFC 项目 在某些文件的开头有这样一行 pragma optimize off 我知道这会关闭所有以下功能的优化 但这样做的动机通常是什么 我专门使用它来在一组特定代码中获得更好的调试信息 并在优化的情况下编译应用程序
  • 指针问题(仅在发布版本中)

    不确定如何描述这一点 但我在这里 由于某种原因 当尝试创建我的游戏的发布版本进行测试时 它的敌人创建方面不起作用 Enemies e level1 3 e level1 0 Enemies sdlLib 500 2 3 128 250 32
  • C#:如何防止主窗体过早显示

    在我的 main 方法中 我像往常一样启动主窗体 Application EnableVisualStyles Application SetCompatibleTextRenderingDefault false Application
  • 如果使用 SingleOrDefault() 并在数字列表中搜索不在列表中的数字,如何返回 null?

    使用查询正数列表时SingleOrDefault 当在列表中找不到数字时 如何返回 null 或像 1 这样的自定义值 而不是类型的默认值 在本例中为 0 你可以使用 var first theIntegers Cast
  • Qt moc 在头文件中实现?

    是否可以告诉 Qt MOC 我想声明该类并在单个文件中实现它 而不是将它们拆分为 h 和 cpp 文件 如果要在 cpp 文件中声明并实现 QObject 子类 则必须手动包含 moc 文件 例如 文件main cpp struct Sub
  • 指针减法混乱

    当我们从另一个指针中减去一个指针时 差值不等于它们相距多少字节 而是等于它们相距多少个整数 如果指向整数 为什么这样 这个想法是你指向内存块 06 07 08 09 10 11 mem 18 24 17 53 7 14 data 如果你有i
  • Github Action 在运行可执行文件时卡住

    我正在尝试设置运行google tests on a C repository using Github Actions正在运行的Windows Latest 构建过程完成 但是当运行测试时 它被卡住并且不执行从生成的可执行文件Visual
  • Qt表格小部件,删除行的按钮

    我有一个 QTableWidget 对于所有行 我将一列的 setCellWidget 设置为按钮 我想将此按钮连接到删除该行的函数 我尝试了这段代码 它不起作用 因为如果我只是单击按钮 我不会将当前行设置为按钮的行 ui gt table
  • 将 xml 反序列化为类,list<> 出现问题

    我有以下 XML
  • C++ fmt 库,仅使用格式说明符格式化单个参数

    使用 C fmt 库 并给定一个裸格式说明符 有没有办法使用它来格式化单个参数 example std string str magic format 2f 1 23 current method template
  • 在 Dynamics CRM 插件中访问电子邮件发件人地址

    我正在编写一个 Dynamics CRM 2011 插件 该插件挂钩到电子邮件实体的更新后事件 阶段 40 pipeline http msdn microsoft com en us library gg327941 aspx 并且在此阶
  • 有没有办法禁用 .NET 标签的“双击复制”功能?

    这真的很烦人 我使用标签作为列表项用户控件的一部分 用户可以单击它来选择列表项 然后双击它来重命名它 但是 如果剪贴板中有名称 双击标签会将其替换为标签文本 我还检查了应用程序中的其他标签 双击它们也会将其复制到剪贴板 我没有在这个程序中编
  • 为什么我收到“找不到编译动态表达式所需的一种或多种类型。”?

    我有一个已更新的项目 NET 3 5 MVC v2 到 NET 4 0 MVC v3 当我尝试使用或设置时编译出现错误 ViewBag Title财产 找不到编译动态表达式所需的一种或多种类型 您是否缺少对 Microsoft CSharp
  • 防止索引超出范围错误

    我想编写对某些条件的检查 而不必使用 try catch 并且我想避免出现 Index Out of Range 错误的可能性 if array Element 0 Object Length gt 0 array Element 1 Ob

随机推荐