1

I'm trying to get Wifi P2P (also known as "Wifi Direct") working on some devices. My goal is for them to be a "Group Owner" (i.e., acting like an access point). However, I'm getting very different results on different systems. Note that I'm talking about different hardware devices, but I think my issue is Linux-based.

I have gotten success with Raspberry Pi OS on a Pi 4B. However, when I try the same commands on a Banana Pi running Arabian I get very different results. However, I think the ultimate issue is system-level, which is why I'm asking here.

So, here's what works on the RPi OS (device_name is set in /etc/wpa_supplicant/wpa_supplicant.conf):

wpa_cli p2p_group_add
ifconfig p2p-wlan0-0 192.168.0.34 metmask 255.255.0.0
dnsmasq -i p2p-wlan0-0 -F192.168.0.40,192.168.0.250 -p0 -z
wpa_cli set p2p_go_intent 15
ifconfig wlan0 down
wpa_cli wps_pbc

From here, if I connect from my Android device, it works, and receives a DHCP response. Unfortunately, there's not much logging, so I can't compare well with other things. Additionally, from trial-and-error, I have determined that this DOESN'T work if my netmask is 255.255.255.0!?!? Weird, but whatever.

If I try the same sequence of commands on my Banana Pi (with a variety of operating systems - Raspbian, Ubuntu, and Armbian), there are several differences. First, if I take down wlan0, nothing after that works. So, leaving it in, it doesn't start advertising unless I issue a "wpa_cli p2p_find". or "wpa_cli p2p_listen". I found that strange, but whatever. However, here, the Android device finds the network, initiates, but the negotiation is never completed and a DHCP lease is never given. The log (which is better on Armbian than on RPiOS) gives the sequence: "P2P-DEVICE-FOUND, P2P-PROV-DISC-PBC-REQ", and "P2P-GO-NEG-REQUEST", but nothing after that.

In any case, I've tried lots of variations, different kernels, different versions of operating systems, etc. It's possibly a hardware issue with my Banana Pi, but I'm not sure why that would be - it's doing Wifi generally just fine, and P2P I think is just a new frame type, which the driver says it supports (uses brcmfmac).

It's possible it's a weird interaction with NetworkManager as well, but I have been unable to turn NetworkManager off and still have wpa_cli still work. Earlier in the syslog, when I enable the P2P group, I get some messages in my syslog which state:

wpa_supplicant: p2p-wlan0-0: interface state UNINITIALIZED->ENABLED
wpa_supplicant: p2p-wlan0-0: AP-ENABLED
wpa_supplicant: p2p-wlan0-0: CTRL-EVENT_CONNECTED
wpa_supplicant: P2P-GROUP-STARTED p2p-wlan0-0 GO .....
wpa_supplicant: bus: Register group object....
NetworkManager: <warn> device (p2p-dev-wlan0): P2P: WPA supplicant notified a group start but we are not trying to connect! Ignoring the event
wpa_supplicant: p2p-wlan0-0: interface state ENABLED->DISABLED
wpa_supplicant: p2p-wlan0-0: AP-DISABLED
wpa_supplicant: p2p-wlan0-0: CTRL-EVENT-DISCONNECTED

I don't know if these are normal (since the RPi 4 isn't logging at this level), but it seems that after enabled AP mode, it then disables it. However, I thought that it should probably stay in AP mode since it is a group owner. I didn't know if NetworkManager ignoring the event was causing anything weird. I'm really unsure how these interactions are supposed to go.

I've also tried a lot of variations on these, like setting the default route, but to no avail. If anyone has suggestions on where to go, I would greatly appreciate it. Sadly, right now my only Linux machines are my Pis, so I can't try this out on a regular PC either.

I also didn't know if there was something I could try at a lower level (using iw or something), because I'm really not familiar with how all of the layers work together, and there isn't great documentation on it either, especially regarding Wifi P2P. Any advice is appreciated.

Also, I've tried turning off NetworkManager, but, anytime I do that, wpa_cli seems to fail entirely.

2
  • Also, I've tried turning off NetworkManager, but, anytime I do that, wpa_cli seems to fail entirely.
    – johnnyb
    Commented Feb 24, 2023 at 16:26
  • 1
    Welcome to U&L. If you have further info like above, or if someone asks for clarification or something in the comments, it's better to edit the question and add directly there. That way the relevant info is readily available. Commented Feb 24, 2023 at 18:21

2 Answers 2

1

So, it turns out the answer was pretty simple. I did need to turn off NetworkManager. However, when turning off NetworkManager, it requires that you have a config file specified for wpa_supplicant (say, supplicant.conf), and that the file contain the line:

ctrl_interface=/run/wpa_supplicant

I don't know much about it, so I don't know if the directory is distribution-specific.

You then start wpa_supplicant with this (I put it in rc.local):

nohup wpa_supplicant -i wlan0 -c /path/to/supplicant.conf &

Then you can run your Wifi Direct / Wifi P2P commands without NetworkManager shutting your groups down.

1

I'm using DBus apis.

There are two steps required:

  • Set the wlan0 device to unmanaged in NetworkManager.

  • Reconfigure wpa_supplicant to bring up p2p-dev-wlan0

To set the wlan0 interface to unmanaged in NetManager:

nmcli device set wlan0 managed no

This temporarily sets the wlan0 interface to unmanaged.

You can permanently set the wlan0 interface to unmanaged by adding the following file:

/etc/NetworkManager/conf.d/50-wlan-management-off.conf

unmanaged-devices=interface-name:wlan0

You then need to convince wpa_supplicant to bring up the p2p-dev-wlan0 interface. By default, NetworkManager configures wpa_supplicant to not have any interfaces, and brings up the p2p-dev-wlan0 interface using DBus apis. That's why wpa_cli fails with the default configuration of wpa_supplicant as set by NetworkManager.

You can correct this by running WPA supplicant with the following options:

wpa_supplicant -i wlan0 -c /path/to/your/supplicant.conf

Your supplicant.conf file needs to include at least the following two lines:

ctrl-interface=DIR=/run/wpa_supplicant GROUP=netdev
update_config=1

If you are using DBUs APIs, no other lines are required, as wpa_supplicant tracks Dbus settings and mirrors them to your supplicant.conf file as required.

You may or may not need to add -s and -u options as well. (haven't tried it).

To make this change permanent, modify cd /e

/usr/lib/systemd/system/wpa_supplicant.service

or disable the wpa_supplicant service, and invoke wpa_supplicant yourself Fairly complicated to do. I wouldn't recommend this path. wpa_supplicant has complicated interactions with systemd, and dbus, and requires root privileges to run.

Alternately, you can leave NetworkManager's configuration of the wpa_supplicant service alone, and use wpa_supplicant1 Dbus apis to create the default p2p-dev-wlan0 interface.

I'm using C++. Notes on how to use DBus API's in c++ are too long to fit in the margins of this post. But the following code fragment captures the essence of what needs to be done, using sdbus-c++ interface wrappers.

std::map<std::string,sdbus::Variant> createArgs;
createArgs["Ifname"] = "wlan0";
createArgs["Driver"] = "nl80211";
createArgs["ConfigFile"] = "/path/to/your/supplicant.conf";
wpaSupplicant->CreateInterface(createArgs);

where the wpasupplicant object is the dbus wrapper for the DBus object at

fi.w1.wpa_supplicant1 /fi/w1/wpa_supplicant1

You may be able to relocate the Driver parameter to the config file. But this is what I'm doing currently.

This creates the p2p-dev-wlan0 interface (in wpa_cli), and the /f1/w1/wpa_supplicant/Interfaces/0 object in DBus, and connects it to your supplicant.conf file. Your supplicant.conf file must at least start with the two lines given above.

I think wpa_cli should work as before from there.

The root cause of the problem is that

  • NetworkManager provides absolutely no way to create a P2P GO group. I rummaged through sources to verify that's true. There is absolutely no way to create a P2P connection that doesn't have a GO Intent of 7, and absolutely no implementation of the remainder of the group formation actions. Disheartening, to say the least.

  • When wlan0 is managed, NetworkManager knows that any new P2P group interface (related to p2p-dev-wlan0) doesn't belong to it, but calls RemoveInterface on the DBus object anyway, thereby borking any attempt to establish P2P connections via wpa_supplicant Dbus APIs, or via wpa_cli.This is unavoidable.

Also required, and beyond the scope of this article:

  • Android Wi-Fi Direct connections require a dhcp server to be connected to the GO's network interface in order to make a connection. Kea doesn't allow wildcard matching of interfaces (you need to match p2p_wlan0-*). And kea uses a very sinister "subscription required for advanced features" funding model, which is profoundly aversion-inducing. The older, supposedly deprecated dnsmaq and dhcpcd components do allow wild-card matching, and is therefore fit for purpose.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .