This repo is a public archive documenting my experiments in getting wireless zero-conf connectivity working for regular user applications in mind, mainly targetting linux devices, with some experiments conducted on android.
The goal is to allow regular user applications on nearby devices to easily communicate over a fast wireless channel, requiring little to no setup. Say between 2 laptops, or a laptop and a phone. Use cases:
-
File share - two devices may discover each other and, after a brief confirmation from user, send files without needing to manually setup an AP.
-
Screen sharing - similar to the point above with an advantage that regular network connectivity isn't interrupted, i.e. Android devices always prefer a wifi connection to a cellular.
-
Other apps - anything that works over network stack and would benefit from a fast zero-conf connection.
-
The primary transmission channel is wifi-direct (aka wifi-p2p), which is actually quite old, supported on all modern devices. It used in wifi-display (aka miracast). We're interacting with NetworkManager directly via it's DBus interface.
-
An optional integration with Bluetooth LE to allow nearby devices to be efficiently notified about incoming connections via advertising packets. This may be useful because wifi-p2p itself doesn't have a comparable passive mode, besides constantly keeping a full discovery process active. We're interacting with Bluez directly via it's DBus interface.
Here's a shell snippet establishing wifi-p2p connecting from a linux device. When connection 2 linux devices, these steps are just mirrored on both sides. To connect to an Android device use their official wifi-p2p example.
# Start wifi-p2p peer discovery
busctl call org.freedesktop.NetworkManager /org/freedesktop/NetworkManager/Devices/<num> org.freedesktop.NetworkManager.Device.WifiP2P StartFind 'a{sv}' 1 timeout i 60
# Show discovered devices
busctl get-property org.freedesktop.NetworkManager /org/freedesktop/NetworkManager/Devices/<num> org.freedesktop.NetworkManager.Device.WifiP2P Peers
# Check name and mac address of discovered devices
busctl introspect org.freedesktop.NetworkManager /org/freedesktop/NetworkManager/WifiP2PPeer/<num>
# Tell network manager to setup a connection
nmcli connection add type wifi-p2p peer 11:22:33:44:55:66 con-name conn connection.permissions user ipv4.method auto-
Pair with a remote device. This can be handled externally.
-
Temporarily enable ble advertisements. Receiving an ad packet from a paired device causes bluez to automatically attempt a connection. It's also should be possible to listen for these packets directly via a still experimental api.
-
Write a special GATT to notify a peer about a wifi-p2p connection attempt. Both peers are configured to expose this attribute.
-
Do wifi-p2p discovery. We just need to periodically renew a discovery by calling a StartFind on Network manager device, while listening for update of the property containing discovered peers.
-
Connect to a device upon receiving a confirmation from user, or if the device is paired via bluetooth. This step just creates a network manager connection with certain parameters.
-
Monitor the link liveness.
- Network manager reports connection status updates from wpa-supplicant.
- We can just poll remote device using a UDP socket. Doing this from both sides will bypass firewall, so no extra configuration required.
There're some unsolved problems related to how to actually utilize a close-range connectivity, since constantly maintaining peer discovery and wifi connections is probably suboptimal. So we need some way to known when to start a wifi-p2p connection. For example, we could:
-
Add a button on task bar to quickly emit an advertisement packet and connect to paired nearby devices.
-
Directly integrate with services, for example, create a specialized UI to start file sharing, screen sharing, etc.
-
Listen for ipv4 broadcast packets or ipv4/v6 mDNS requests used by services like kdeconnect to discover other network devices.
While I did manage to setup wifi-p2p connections, I still ran into some issues related to the fact that wifi-p2p stack is quite underutilized on linux. These include:
-
Network manager not supporting multiple concurrent connections on the same wifi-p2p interface.
-
Wifi-p2p connection (more precisely nmcli step from the example) may fail for no apparent reason. I recon it's because of some bug in either Network manager or wpa supplicant incorrectly blocking wifi-p2p peers after timed out connection.
-
Wifi-p2p peer discovery sometimes failing to find peers/announce itself:
- After a timed-out connection attempt when retrying.
- If there're multiple network interfaces associated with a physical device.
-
Neither Network manager nor wpa supplicant expose a way to adjust connection speed and latency, leading to traffic being sent in 100ms windows and bandwidth subpar to what's achieved with regular routers.