简体   繁体   中英

Syntax for BluetoothLEDevice::RequestPreferredConnectionParameters()

Using C++/WinRT, Win10, VS2019, SDK 10.0.22621.0, NuGet CppWinRT 2.0.220608.4

I'm trying to get the RequestPreferredConnectionParameters to work. At this point I am wondering if maybe I have the syntax wrong or maybe something else about it that I am not aware of. The MS docs for the function are here and the link to the various parameters are here .

The command line, as I have it, with pubDevice being the BLE device object, is:

BluetoothLEPreferredConnectionParametersRequest rcoConnect = pubDevice.RequestPreferredConnectionParameters(BluetoothLEPreferredConnectionParameters::ThroughputOptimized());

Just to mention, I am able to run

auto statusTest = co_await pubDevice.RequestAccessAsync();

before the RequestPreferredConnectionParameters without problems so, obviously, the device object is good and can be connected to.

What is happening is this. I have a function, OpenDevice(), that opens the device based on the address. If, after getting the device object, I issue the command above while still in the OpenDevice function, the code will not crash but it will immediately jump to the end of the OpenDevice() function bypassing all other lines of code below it and there will be no connection at all after that.

If I run the RequestPreferredConnectionParameters outside of the OpenDevice() function it errors out with a An unhandled exception was encountered during a user callback and the line referenced is in base.h line 4942 if (result == impl::error_changed_state)

I had assumed that the callback refered to was the Rx Characteristic ValueChanged Callback that is set in OpenDevice(). So I tested by first revoking that callback with

pubRxCharacteristic.ValueChanged(etValueChangeToken);

and then running the RequestPreferredConnectionParameters but I still got the An unhandled exception error.

The only other callback that I have is the BluetoothLEAdvertisementWatcher advert received callback but that was stopped after the device was found.

Can anyone verify that my syntax seems correct and/or have any clue as to what is causing my problems?

EDIT to show more code in a console app------------
@IInspectable
Again for the record:
Using C++/WinRT, Win10, VS2019 - Console App, SDK 10.0.22621.0, NuGet CppWinRT 2.0.220608.4

Pertinent includes in the pch.h file:

// 2022/9/10 -- for WHCAR and apparently GUID
#include <Windows.h>
#include <tchar.h>

#include <winrt\Windows.Foundation.h>
#include <winrt\Windows.Storage.Streams.h>
#include <winrt\Windows.Devices.Bluetooth.h>
#include <winrt\Windows.Devices.Bluetooth.Advertisement.h>
#include <winrt\Windows.Devices.Bluetooth.GenericAttributeProfile.h>
// 2022/9/10
#include <winrt\Windows.Devices.Enumeration.h>
#include <winrt/Windows.Foundation.Collections.h>

Pertinent name spaces at top of Main.cpp:

using namespace winrt;
using namespace Windows::Foundation;
using namespace winrt::Windows::Foundation;
using namespace Windows::Storage::Streams;
using namespace Windows::Devices::Bluetooth;
using namespace Windows::Foundation::Collections;
using namespace Windows::Devices::Bluetooth::Advertisement;
using namespace Windows::Devices::Bluetooth::GenericAttributeProfile;
// 2022/9/10 for RequestConnectionAsync
using namespace Windows::Devices::Enumeration;

I assume that the code to watch for and find the device is not pertinent here. Needless to say the device is found and the address is passed to OpenDevice to create the device object.

Here is the top portion of OpenDevice:

IAsyncAction OpenDevice(unsigned long long deviceAddress)
{
    auto device = co_await BluetoothLEDevice::FromBluetoothAddressAsync(deviceAddress);

    // 2022/9/10 test code
    auto statusTest = co_await device.RequestAccessAsync();
    // Allowed, DeniedBySystem, Unspecified
    if (statusTest != DeviceAccessStatus::Allowed) {            
        std::cout << "Access to device is not allowed...." << std::endl;
    }
    else {
        std::cout << "Access to device is allowed...." << std::endl;
    }

    // Next line ends without error but immediately goes to the end of OpenDevice()
    std::cout << "Asking for ThroughputOptimized...." << std::endl;
    auto statusConnection = device.RequestPreferredConnectionParameters(BluetoothLEPreferredConnectionParameters::ThroughputOptimized());
    std::cout << "Line after Request ThroughputOptimized...." << std::endl;
    Beep(500, 500);<br/> // function never gets to this cout or Beep<br/>
// More code follows to get Rx and TxCharacteristics etc.<br/>
} // end OpenDevice

Here is the console output: Notice the last cout is the line Asking for ThroughputOptimized . No cout for Line after Request ThroughputOptimized and no Beep .

Trying to locate the TENS device: Waiting for device: AdvertisementReceived:
LocalName: []
AdvertisementType: [ConnectableUndirected]
BluetoothAddress: [0x300000e59630]
RawSignalStrengthInDBm: [-60] ServiceUUID: [0000fff0-0000-1000-8000-00805f9b34fb]
Found TENS Device Main Service....
TENS device found. Access to device is allowed....
Asking for ThroughputOptimized....

WinRTBle.exe (process 15576) exited with code -1073740791.
Press any key to close this window.

Barring a problem in syntax or a missing header. the only other thing that I can think of is that it needs Win11. The docs for RequestPreferredConnectionParameters Method say

Windows requirements Device family Windows 11 (introduced in 10.0.22000.0)

Does that mean that regardless of the SDK it needs Win11?

@IInspectable As much as I was dreading this, apparently the answer is that it needs Win11. The console app code mentioned above in the edit to the original question was compiled into an exe. I have Win11 on a VM VirtualBox and I ran that exe on that Win11 and the code continued past the ThroughputOptimized() line in question and finished the rest of the app as expected. So that's ashamed. I don't have Win11 on a real box yet (call me paranoid) but I guess I could bracket the code for the Win11 OS and only run it when a user happens to be running Win11

Always something.......

EDIT 2............................... And the "Always something" comes up immediately. As far as I can tell from what I have been able to find, there is no way to tell if the OS is Win10 or Win11. It was recommended to use RtlGetVersion but that returned 10 for both Win10 and Win11. Another poster suggested to use the File version of the System32 kernal32.dll file but they also both reported major number 10 and minor number 0. The MS docs for adding a version manifest had the UUIDs for both OSs as the same.

This is ridiculous that MS would come up with a function that only runs in Win11 and then not have to ability to tell you which OS you are running in....Jeeeeeeze.....

EDIT 3.........................
Spoke too soon. I was messing around with the console app and forgot that in my MFC app I use the WMI IWbemClassObject Caption property to get the OS.
For Windows 10 I get
Microsoft Windows 10 Pro
and for Win11 I get
Microsoft Windows 11 Home
So apparently that is really the only way to do it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM