╦ ╔═╗╔╦╗╔═╗╦ ╦
║ ╠═╣ ║ ║ ╠═╣
╩═╝╩ ╩ ╩ ╚═╝╩ ╩
Wi-Fi Direct client CLI for Linux
Latch onto phones, TVs, printers — any Wi-Fi Direct device
A robust command-line tool for Wi-Fi Direct client-mode operations on Linux. Designed for Ubuntu 22/24+ and OpenWrt-like environments.
Note: This tool supports client mode only — it connects to existing Wi-Fi Direct Group Owners (phones, TVs, printers, etc.) but does not host P2P groups.
- 🧙 Interactive wizard mode — guided step-by-step interface
- 🔒 Reliable wpa_supplicant lifecycle management
- 🎯 Per-interface process control (no global
pkill) - 🤝 NetworkManager coexistence
- 📡 P2P capability detection
- 📋 JSON output for scripting
- 🔍 Detailed diagnostics
- 💡 Meaningful error hints
# Required packages (Ubuntu/Debian)
sudo apt install wpasupplicant wireless-tools iw rfkill
# Build from source
git clone https://github.com/example/latch.git
cd latch
go build -o latch .
sudo install -m 755 latch /usr/local/bin/The easiest way to use latch is the interactive wizard:
sudo latch wizardThis launches a menu-driven interface:
┌───────────────────────────────────────────────────────────────┐
│ │
│ ██╗ █████╗ ████████╗ ██████╗██╗ ██╗ │
│ ██║ ██╔══██╗╚══██╔══╝██╔════╝██║ ██║ │
│ ██║ ███████║ ██║ ██║ ███████║ │
│ ██║ ██╔══██║ ██║ ██║ ██╔══██║ │
│ ███████╗██║ ██║ ██║ ╚██████╗██║ ██║ │
│ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ │
│ │
│ Wi-Fi Direct Client · Interactive Mode │
│ Latch onto any device │
│ │
└───────────────────────────────────────────────────────────────┘
[ Status ]
──────────────────────────────────────────────────
Interface: wlp3s0
P2P Mode: Active
WPA State: DISCONNECTED
[ Main Menu ]
──────────────────────────────────────────────────
1) Discover Peers
2) List Peers
3) Connect to Peer
4) Show Status
5) Disconnect
6) Run Diagnostics
7) Stop P2P Mode
q) Quit
Select option:
# 1. Start P2P mode (stop NetworkManager to avoid conflicts)
sudo latch start -i wlp3s0 --nm-stop
# 2. Discover nearby Wi-Fi Direct devices
sudo latch find -i wlp3s0 --timeout 15
# 3. List discovered peers
sudo latch peers -i wlp3s0
# 4. Connect to a peer (replace with actual MAC address)
sudo latch connect-pbc -i wlp3s0 aa:bb:cc:dd:ee:ff --wait 30
# 5. Check connection status
sudo latch status -i wlp3s0
# 6. Disconnect and restore NetworkManager
sudo latch disconnect -i wlp3s0
sudo latch stop -i wlp3s0 --nm-start-
On your Android phone:
- Go to Settings → Wi-Fi → Wi-Fi Direct
- Your phone will start broadcasting as a Group Owner
-
On your Linux machine:
# Start P2P
sudo latch start -i wlp3s0 --nm-stop
# Discover the phone
sudo latch find -i wlp3s0 --timeout 15
# List peers (you should see your phone)
sudo latch peers -i wlp3s0
# Output:
# MAC ADDRESS DEVICE NAME FREQ
# ----------------- ----------- ------
# aa:bb:cc:dd:ee:ff Galaxy S21 2412
# Connect using Push Button Config
sudo latch connect-pbc -i wlp3s0 aa:bb:cc:dd:ee:ff --wait 30
# Accept the connection prompt on your phone!
# Verify connection
sudo latch status -i wlp3s0- After connection:
- A P2P interface (e.g.,
p2p-wlp3s0-0) will be created - You'll receive an IP address via DHCP from the phone
- You can now communicate with the phone over this interface
- A P2P interface (e.g.,
sudo latch wizardAliases: interactive, i
Launches a menu-driven interactive interface that guides you through all P2P operations. Features:
- Automatic interface detection with P2P capability indicators
- Visual progress indicators
- Real-time status display
- Guided connection workflow
- Automatic cleanup on exit
sudo latch start -i <interface> [--nm-stop] [-v|--verbose]Starts wpa_supplicant with a control socket for P2P operations.
| Option | Description |
|---|---|
-i <iface> |
Wi-Fi interface (required) |
--nm-stop |
Stop NetworkManager to avoid conflicts |
-v, --verbose |
Enable verbose output |
sudo latch stop -i <interface> [--nm-start] [-v]Stops the wpa_supplicant instance for the specified interface only.
| Option | Description |
|---|---|
-i <iface> |
Wi-Fi interface (required) |
--nm-start |
Start NetworkManager after stopping |
sudo latch find -i <interface> [--timeout <seconds>] [-v]Starts P2P peer discovery.
| Option | Description |
|---|---|
--timeout N |
Stop discovery after N seconds (0 = manual stop) |
sudo latch stop-find -i <interface>sudo latch peers -i <interface> [--json]Lists all discovered P2P peers with device names and frequencies.
JSON output example:
{
"count": 2,
"peers": [
{"address": "aa:bb:cc:dd:ee:ff", "device_name": "Galaxy S21", "listen_freq": "2412"},
{"address": "11:22:33:44:55:66", "device_name": "Chromecast", "listen_freq": "5180"}
]
}sudo latch peer -i <interface> <mac_address> [--json]Shows detailed information about a specific peer.
sudo latch connect-pbc -i <interface> <mac_address> [--wait <seconds>]Initiates a P2P connection using Push Button Configuration.
| Option | Description |
|---|---|
--wait N |
Wait up to N seconds for connection, showing progress |
sudo latch connect-pin -i <interface> <mac_address> <pin> [--wait <seconds>]Initiates a P2P connection using a PIN code.
sudo latch disconnect -i <interface>Disconnects from the current P2P group and cleans up state.
sudo latch status -i <interface> [--json]Shows current P2P connection status.
JSON output example:
{
"status": {
"wpa_state": "COMPLETED",
"p2p_device_address": "aa:bb:cc:dd:ee:ff",
"ssid": "DIRECT-ab-Galaxy S21",
"mode": "station",
"ip_address": "192.168.49.100"
},
"p2p_interface": "p2p-wlp3s0-0",
"p2p_ip": "192.168.49.100"
}sudo latch diag -i <interface> [--json]Runs comprehensive diagnostics and displays debug information.
Cause: The Wi-Fi adapter is already performing an operation.
Fix:
sudo latch stop-find -i wlp3s0
sudo latch disconnect -i wlp3s0Cause: wpa_supplicant isn't running or the control socket is missing.
Fix:
# Restart P2P mode
sudo latch stop -i wlp3s0
sudo latch start -i wlp3s0 --nm-stopCause: Physical wireless switch is off, or rfkill is blocking.
Fix:
# Check rfkill status
rfkill list
# Unblock wireless
sudo rfkill unblock wifiCause: NetworkManager is competing for control of the interface.
Fix:
# Use --nm-stop flag
sudo latch start -i wlp3s0 --nm-stopCause: Your Wi-Fi adapter doesn't support Wi-Fi Direct.
Check:
# Run diagnostics
sudo latch diag -i wlp3s0
# Check supported modes
iw list | grep -A 10 "Supported interface modes"
# Look for "P2P-client" in the outputCauses:
- Peer device not accepting the connection
- Peer not in Wi-Fi Direct mode
- Distance too far / signal weak
Fixes:
- Ensure you tap "Accept" on the peer device (phone/TV)
- Verify peer is actively broadcasting Wi-Fi Direct
- Move closer to the peer device
- Try discovery again:
latch find -i wlp3s0 --timeout 15
Causes:
- Discovery time too short
- Peer not in Wi-Fi Direct mode
- Different channels
Fixes:
# Run longer discovery
sudo latch find -i wlp3s0 --timeout 30
sudo latch peers -i wlp3s0
# Check if your phone/TV is broadcasting:
# - Android: Settings → Wi-Fi → Wi-Fi Direct → Make visible
# - TV: Check TV settings for Wi-Fi Direct/Miracastlatch/
├── main.go # CLI commands and main entry point
├── interactive.go # Interactive wizard mode
├── shell.go # All shell command wrappers
├── parser.go # Output parsing and JSON serialization
├── parser_test.go # Unit tests for parsers
├── go.mod # Go module definition
├── Makefile # Build instructions
└── README.md # This file
# Clone the repository
git clone https://github.com/example/latch.git
cd latch
# Build
make build
# Run tests
make test
# Install system-wide
sudo make install| Target | Description |
|---|---|
make build |
Build the binary |
make build-static |
Build statically linked binary |
make build-all |
Build for multiple architectures |
make test |
Run unit tests |
make install |
Install to /usr/local/bin |
make clean |
Remove build artifacts |
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | General error (see stderr for details) |
All commands return meaningful exit codes suitable for scripting.
#!/bin/bash
set -e
IFACE="wlp3s0"
PEER_MAC="$1"
if [ -z "$PEER_MAC" ]; then
echo "Usage: $0 <peer_mac_address>"
exit 1
fi
# Start P2P
sudo latch start -i "$IFACE" --nm-stop
# Discover peers
sudo latch find -i "$IFACE" --timeout 10
# Get peer list as JSON and check if our peer is there
if sudo latch peers -i "$IFACE" --json | grep -q "$PEER_MAC"; then
echo "Peer found, connecting..."
sudo latch connect-pbc -i "$IFACE" "$PEER_MAC" --wait 60
# Get connection info
STATUS=$(sudo latch status -i "$IFACE" --json)
IP=$(echo "$STATUS" | jq -r '.p2p_ip')
echo "Connected! IP: $IP"
else
echo "Peer not found"
exit 1
fi- Client-only: This tool does not support hosting P2P groups (GO mode). It connects to existing Group Owners.
- Single interface: Designed for one interface at a time.
- Linux only: Requires Linux kernel with nl80211 and P2P support.
MIT License
Issues and PRs welcome! Please ensure go test ./... passes before submitting.
Made with ❤️ for the Linux community