Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WiFiDirect cppwinrt can not get "PairingRequested" callback after GO/GC calls PairingRequested() #1406

Open
yanfangliu-google opened this issue Feb 14, 2024 · 5 comments
Labels

Comments

@yanfangliu-google
Copy link

Which sample are you reporting a bug in?

WifiDirect/cppwinrt

Describe the bug
I am using the above sample code to build a WifiDirect GO and GC command line utilities. When the GO and GC utilities do pairing with WiFiDirectConnectionParameters::PairAsync(...).get(), GC always returns "The device object has already been paired" and GO always returns "An unknown failure occurred." WiFiDirectConnectionParameters::PairingRequested call back handler never get called.
The interesting thing is that they are already paired even with the error result. They can even ping/iperf each other.
The problem is that the pairing event handler which processes the WiFiDirectConfigurationMethod(ProvidePin/DisplayPin/PushButton) won't get called. This will expose security problems. I saw people post same problem here: https://learn.microsoft.com/en-us/answers/questions/827554/i-use-pairasync-method-to-pair-another-wifidirect .
I wonder if anyone saw this problem and have any idea of it.

To Reproduce

Expected behavior
WiFiDirectConnectionParameters::PairingRequested call back handler should be called after pairing.

Screenshots

Configuration

Additional context

@yanfangliu-google
Copy link
Author

I just realize that only GC needs to do DeviceInformationCustomPairing::PairAsync(...), then both side can get a valid IP address and ping each other. But the problem is that how to use WiFiDirectConfigurationMethod::DisplayPin and ProvidePin? PushButton is kind of unsafe.
I don't see WiFiDirectConnectionParameters::PairingRequested call back handler get called at any situation.

@orineman
Copy link

I believe you have to set one computer to Display Pin and the other to Provide Pin.

The order of:

            co_await ShowPinToUserAsync(dispatcher, e.Pin());
            e.Accept();

and deferral handling are problematic. One tends to leave the dialog up, type the pin in on the other computer and it doesn't work as e.Accept() hasn't been called and the deferral hasn't been completed.

I changed the C# code to and I'd suggest similar changes to the C++ version:

            // using (Deferral deferral = args.GetDeferral())
           //  {
            switch (args.PairingKind)
            {
                case DevicePairingKinds.DisplayPin:
                    args.Accept();
                    await ShowPinToUserAsync(dispatcher, args.Pin);
                    break;

                case DevicePairingKinds.ConfirmOnly:
                    args.Accept();
                    break;

                case DevicePairingKinds.ProvidePin:
                    {
                        Deferral deferral = args.GetDeferral();
                        string pin = await GetPinFromUserAsync(dispatcher);
                        if (!string.IsNullOrEmpty(pin))
                        {
                            args.Accept(pin);
                        }
                        deferral.Complete();
                    }
                    break;
            }
            // }

In other words, only get the deferral if we are asking the user for the Pin. If we are displaying the pin, do it asynchronously.

Using a Pin did work, but only if I did things in the right order and again, only if the devices aren't already paired.

@yanfangliu-google
Copy link
Author

@orineman
The problem is that the following WiFiDirectConnectionParameters::PairingRequested handler never get called in my utility:
ConnectionSettingsPanel.cpp line 106-109
void ConnectionSettingsPanel::OnPairingRequested(DeviceInformationCustomPairing const&, DevicePairingRequestedEventArgs const& e)
{
HandlePairing(Dispatcher(), e);
}

When my GC side utility is trying to pair with GO for the first time, the result always shows "The device object has already been paired". I don't know when it was paired before.
I don't have a GUI for my utility as it is not needed in my application. But I am using same code as the sample. I wonder if I could send my code to you to take a look. Thanks.

@orineman
Copy link

For Windows 11 at least, check Settings/Bluetooth & devices on both computers. The WiFi Direct paired devices appear under "Other devices". If the other device appears, remove it. That should fix the already paired problem.

Yes, OnPairingRequested won't be called if it thinks you are already paired.

I too am working without a GUI - in a C++/winrt Universal Windows dll called from a WCF service.

If you can find a private way of sharing your code, I can take a quick look.

(Yes, it's under Bluetooth - confusing!)

@yanfangliu-google
Copy link
Author

@orineman
After some debug and try, I finally make the pairing event handler which processes the WiFiDirectConfigurationMethod(ProvidePin/DisplayPin/PushButton) get called. PushButton works and I am going to try ProvidePin/DisplayPin.
What you mentioned the last post is good clue to figure out the problem. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants