首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >对C++/winRT BLE连接尝试的计时问题?

对C++/winRT BLE连接尝试的计时问题?
EN

Stack Overflow用户
提问于 2019-04-20 05:37:23
回答 2查看 963关注 0票数 1

我正在使用C++/winRT UWP来发现和连接蓝牙低能耗设备。我正在使用广告观察器来查找来自我可以支持的设备的广告。这是可行的。

然后我选择一个来连接。连接过程在我看来有点奇怪,但根据微软文档,一个人用BluetoothAddress调用这个FromBluetoothAddressAsync(),就会发生两件事;一个是获得BluetoothLEDevice,然后进行连接尝试。需要为connection status changed事件注册一个处理程序,但在获得BluetoothLEDevice之前不能这样做。

是否存在导致异常的时间问题?在我获得BluetoothLEDevice对象之前,连接已经发生了吗?下面是代码,下面是日志:

代码语言:javascript
运行
复制
void BtleHandler::connectToDevice(BluetoothLEAdvertisementReceivedEventArgs eventArgs)
{
    OutputDebugStringA("Connect to device called\n");
    // My God this async stuff took me a while to figure out! See https://msdn.microsoft.com/en-us/magazine/mt846728.aspx

    IAsyncOperation<Windows::Devices::Bluetooth::BluetoothLEDevice> async =  // assuming the address type is how I am to behave ..
     BluetoothLEDevice::FromBluetoothAddressAsync(eventArgs.BluetoothAddress(), BluetoothAddressType::Random);
    bluetoothLEDevice = async.get();
    OutputDebugStringA("BluetoothLEDevice returned\n");
    bluetoothLEDevice.ConnectionStatusChanged({ this, &BtleHandler::onConnectionStatusChanged });

    // This method not only gives you the device but it also initiates a connection
}

上面的代码生成以下日志:

代码语言:javascript
运行
复制
New advertisment/scanResponse with UUID 00001809-0000-1000-8000-00805F9B34FB
New ad/scanResponse with name Philips ear thermometer and UUID 00001809-0000-1000-8000-00805F9B34FB
Connect to device called 
ERROR here--> onecoreuap\drivers\wdm\bluetooth\user\winrt\common\bluetoothutilities.cpp(509)\Windows.Devices.Bluetooth.dll!03BEFDD6: (caller: 03BFB977) ReturnHr(1) tid(144) 80070490 Element not found.
ERROR here--> onecoreuap\drivers\wdm\bluetooth\user\winrt\device\bluetoothledevice.cpp(428)\Windows.Devices.Bluetooth.dll!03BFB9B7: (caller: 03BFAF01) ReturnHr(2) tid(144) 80070490 Element not found.
BluetoothLEDevice returned
Exception thrown at 0x0F5CDF2F (WindowsBluetoothAdapter.dll) in BtleScannerTest.exe: 0xC0000005: Access violation reading location 0x00000000.

看起来肯定是时间上的问题。但如果它是,我不知道如何解决它。如果我没有BluetoothLEDevice对象,我就不能注册该事件!我想不出在不调用连接的情况下获取BluetoothLEDevice对象的方法。

================================更新=============================

根据@IInspectable的建议,将方法更改为IAsyncAction并使用co_await。没什么区别。问题很明显是注册的处理程序超出了作用域,或者它出了问题。我在注册中尝试了get_strong()而不是'this‘,但是编译器不接受它(所说的标识符'get_strong()’是未定义的)。但是,如果我注释掉了注册,则不会抛出异常,但我仍然会收到这些日志消息

代码语言:javascript
运行
复制
onecoreuap\drivers\wdm\bluetooth\user\winrt\common\bluetoothutilities.cpp(509)\Windows.Devices.Bluetooth.dll!0F27FDD6: (caller: 0F28B977) ReturnHr(3) tid(253c) 80070490 Element not found.
onecoreuap\drivers\wdm\bluetooth\user\winrt\device\bluetoothledevice.cpp(428)\Windows.Devices.Bluetooth.dll!0F28B9B7: (caller: 0F28AF01) ReturnHr(4) tid(253c) 80070490 Element not found.

但是程序会继续运行,我也会继续发现和连接。但是因为我不能获得连接事件,所以在这个阶段它是无用的。

EN

回答 2

Stack Overflow用户

发布于 2019-04-22 22:54:18

我讨厌我的回答。但在异步和共同例程了天下的一切之后,这个问题对我来说是无法解决的:

此方法

代码语言:javascript
运行
复制
bluetoothLEDevice = co_await BluetoothLEDevice::FromBluetoothAddressAsync(eventArgs.BluetoothAddress(), BluetoothAddressType::Random);

返回NULL。这不应该发生,我对此无能为力。我认为这是一个坏掉的BLE API。

BTLE Central应该能够执行以下操作

  • 发现设备如果是新设备,则:
  • 如果用户选择连接,请连接到设备
  • 根据需要执行服务处理特征
  • handle indications/notifications

如果在任何时候外围设备发送安全请求或身份验证不足错误,则开始配对

重复导致身份验证不足的操作。

断开连接时,如果设备可配对,请保存配对和绑定状态。

重新发现设备时,如果未配对(不是可配对的设备)

在上重复

如果配对并绑定

使用设备启动encryption

  • work;无需重新启用或执行

=========================更多信息===================================

这是调用该方法时日志显示的内容

代码语言:javascript
运行
复制
Connect to device called
onecoreuap\drivers\wdm\bluetooth\user\winrt\common\bluetoothutilities.cpp(509)\Windows.Devices.Bluetooth.dll!0496FDD6: (caller: 0497B977) ReturnHr(1) tid(3b1c) 80070490 Element not found.
onecoreuap\drivers\wdm\bluetooth\user\winrt\device\bluetoothledevice.cpp(428)\Windows.Devices.Bluetooth.dll!0497B9B7: (caller: 0497AF01) ReturnHr(2) tid(3b1c) 80070490 Element not found.
BluetoothLEDevice returned is NULL. Can't register

由于BluetoothLEDevice为空,因此我不会尝试注册。

=================更多信息===================

我还应该补充说,进行空中嗅探表明永远不会有连接事件。尽管该方法应该初始化一个连接并返回BluetoothLEDevice对象,但它最终都没有执行这两项操作。我的猜测是,该方法比只有DeviceWatcher需要更多的系统使用前设置。AdvertisementWatcher可能不会。

票数 0
EN

Stack Overflow用户

发布于 2019-04-20 16:08:13

在BLE中,您必须始终等待每个操作完成。

我不是C++方面的专家,但在C#中,如果异步连接过程成功,则会返回一个布尔值。

在C++中,IAsyncOperation没有返回类型,因此无法知道连接过程是否成功或完成。

在附加事件处理程序之前,必须等待IAsyncOperation并确保具有BluetoothLEDevice对象。

等待IAsyncOperation有一个关于如何等待anIAsyncOperation的问题/答案: how To wait for an IAsyncAction?How to wait for an IAsyncAction?

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55768125

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档