# rpi-host
A Rust library for controlling the Raspberry Pi wireless interface, enabling easy switching between WiFi client mode and hotspot (access point) mode.
[](https://crates.io/crates/rpi-host)
[](https://docs.rs/rpi-host)
[](https://opensource.org/licenses/MIT)
## Features
- **Client Mode**: Connect to WiFi networks with SSID and optional password
- **Hotspot Mode**: Create a WiFi access point for other devices to connect to
- **Network Scanning**: Discover available WiFi networks with signal strength and security info
- **Internet Connectivity Validation**: Check and wait for internet access
- **Automatic Mode Switching**: Seamlessly switch between client and hotspot modes
- **Easy-to-use API**: High-level interface designed for simplicity
## Requirements
### Hardware
- Raspberry Pi with wireless interface (tested on Pi 5, should work on Pi 3/4/Zero W)
- Built-in WiFi or compatible USB WiFi adapter
### Software
- **NetworkManager** - must be installed and running
- **Root/sudo permissions** - required for WiFi operations
#### Raspberry Pi OS (Bookworm+)
NetworkManager is included by default. Verify it's running:
```bash
systemctl status NetworkManager
```
If not installed (older versions):
```bash
sudo apt update
sudo apt install network-manager
sudo systemctl enable NetworkManager
sudo systemctl start NetworkManager
```
#### Ubuntu Server for Raspberry Pi
Ubuntu Server uses `netplan` with `systemd-networkd` by default, not NetworkManager. You'll need to install and configure NetworkManager:
```bash
# Install NetworkManager
sudo apt update
sudo apt install network-manager
# Disable systemd-networkd (optional, but recommended to avoid conflicts)
sudo systemctl disable systemd-networkd
sudo systemctl stop systemd-networkd
# Enable NetworkManager
sudo systemctl enable NetworkManager
sudo systemctl start NetworkManager
```
Configure netplan to use NetworkManager by editing `/etc/netplan/50-cloud-init.yaml` (or similar):
```yaml
network:
version: 2
renderer: NetworkManager
```
Apply the changes:
```bash
sudo netplan generate
sudo netplan apply
```
Verify NetworkManager is managing your WiFi interface:
```bash
nmcli device status
# Should show wlan0 as "wifi" with state "connected" or "disconnected"
# If it shows "unmanaged", reboot or check netplan configuration
```
#### Checking Your Wireless Interface
```bash
# List wireless interfaces
nmcli device status
# Should show something like:
# DEVICE TYPE STATE CONNECTION
# wlan0 wifi connected MyNetwork
```
## Installation
Add to your `Cargo.toml`:
```toml
[dependencies]
rpi-host = "0.1"
```
## Quick Start
### Connect to a WiFi Network
```rust
use rpi_host::WifiManager;
fn main() -> Result<(), rpi_host::WifiError> {
let wifi = WifiManager::new()?;
// Connect to a secured network
wifi.connect("MyNetwork", Some("password123"))?;
// Or connect to an open network
wifi.connect("OpenNetwork", None)?;
// Check if we have internet
if wifi.has_internet()? {
println!("Connected to the internet!");
}
Ok(())
}
```
### Create a Hotspot
```rust
use rpi_host::WifiManager;
fn main() -> Result<(), rpi_host::WifiError> {
let wifi = WifiManager::new()?;
// Start a secured hotspot (password must be 8+ characters)
wifi.start_hotspot("Pi-Hotspot", Some("mypassword"))?;
// Or an open hotspot
wifi.start_hotspot("Pi-Hotspot-Open", None)?;
println!("Hotspot is running!");
Ok(())
}
```
### Scan for Networks
```rust
use rpi_host::WifiManager;
fn main() -> Result<(), rpi_host::WifiError> {
let wifi = WifiManager::new()?;
for network in wifi.scan()? {
println!(
"{:3}% | {:20} | {} {}",
network.signal_strength,
network.ssid,
network.security,
if network.is_connected { "(connected)" } else { "" }
);
}
Ok(())
}
```
### Advanced Hotspot Configuration
```rust
use rpi_host::{WifiManager, HotspotConfig, HotspotBand};
fn main() -> Result<(), rpi_host::WifiError> {
let wifi = WifiManager::new()?;
// Create a 5GHz hotspot with custom settings
let config = HotspotConfig::new("My5GHotspot")
.with_password("securepassword")
.with_band(HotspotBand::A) // 5GHz band
.with_channel(36);
wifi.start_hotspot_with_config(config)?;
Ok(())
}
```
### Check Connection Status
```rust
use rpi_host::WifiManager;
fn main() -> Result<(), rpi_host::WifiError> {
let wifi = WifiManager::new()?;
let status = wifi.status()?;
println!("Mode: {}", status.mode);
println!("Connection: {:?}", status.connection_name);
println!("IP Address: {:?}", status.ip_address);
println!("Has Internet: {}", status.has_internet);
Ok(())
}
```
### Connect and Wait for Internet
```rust
use rpi_host::WifiManager;
use std::time::Duration;
fn main() -> Result<(), rpi_host::WifiError> {
let wifi = WifiManager::new()?;
// Connect and wait up to 30 seconds for internet
wifi.connect_with_internet(
"MyNetwork",
Some("password"),
Duration::from_secs(30)
)?;
println!("Connected with internet access!");
Ok(())
}
```
## API Overview
### WifiManager Methods
| `new()` | Create manager for default interface (wlan0) |
| `with_interface(name)` | Create manager for specific interface |
| `connect(ssid, password)` | Connect to WiFi network as client |
| `connect_with_internet(ssid, password, timeout)` | Connect and wait for internet |
| `start_hotspot(ssid, password)` | Start WiFi access point |
| `start_hotspot_with_config(config)` | Start AP with custom configuration |
| `stop_hotspot()` | Stop the hotspot |
| `disconnect()` | Disconnect from current network |
| `scan()` | Scan for available networks |
| `get_mode()` | Get current mode (Client/Hotspot/Disconnected) |
| `status()` | Get detailed connection status |
| `has_internet()` | Quick internet connectivity check |
| `check_connectivity()` | Detailed connectivity check with latency |
| `wait_for_internet(timeout)` | Wait for internet access |
| `enable_wifi()` / `disable_wifi()` | Control WiFi radio |
| `forget_network(ssid)` | Delete saved network profile |
### Types
- **`WifiMode`**: `Client`, `Hotspot`, or `Disconnected`
- **`NetworkInfo`**: Scanned network details (SSID, signal, security, etc.)
- **`HotspotConfig`**: Hotspot configuration builder
- **`HotspotBand`**: `Bg` (2.4GHz) or `A` (5GHz)
- **`SecurityType`**: Network security (Open, WPA2, WPA3, etc.)
- **`ConnectionStatus`**: Current connection details
- **`ConnectivityResult`**: Internet check results with latency
## Running the Example
```bash
# Build the example
cargo build --example basic
# Run with sudo (required for WiFi operations)
sudo ./target/debug/examples/basic scan
sudo ./target/debug/examples/basic connect MyNetwork mypassword
sudo ./target/debug/examples/basic hotspot PiAP password123
sudo ./target/debug/examples/basic status
sudo ./target/debug/examples/basic stop
```
## Error Handling
All operations return `Result<T, WifiError>`. Common errors include:
- `WifiError::InterfaceNotFound` - Wireless interface doesn't exist
- `WifiError::ConnectionFailed` - Failed to connect to network
- `WifiError::HotspotCreationFailed` - Failed to create hotspot
- `WifiError::NoInternetConnectivity` - No internet access
- `WifiError::InvalidConfiguration` - Invalid settings (e.g., password too short)
- `WifiError::WifiDisabled` - WiFi radio is disabled
- `WifiError::Timeout` - Operation timed out
## Logging
The library uses the `log` crate. Enable logging with `env_logger` or your preferred logger:
```rust
fn main() {
env_logger::init();
// ... your code
}
```
```bash
RUST_LOG=debug sudo ./your_program
```
## Troubleshooting
### "Interface not found"
Ensure your wireless interface exists:
```bash
nmcli device status
ip link show
```
### "Permission denied"
WiFi operations require root permissions:
```bash
sudo ./your_program
```
### NetworkManager not controlling WiFi
**On Raspberry Pi OS:** WiFi might be managed by `wpa_supplicant` instead:
```bash
# Check what's managing WiFi
nmcli device status
# If it shows "unmanaged", edit /etc/NetworkManager/NetworkManager.conf
# and ensure [ifupdown] managed=true
sudo systemctl restart NetworkManager
```
**On Ubuntu Server:** Ensure netplan is configured to use NetworkManager:
```bash
# Check current renderer
cat /etc/netplan/*.yaml
# If renderer is not NetworkManager, update the file:
# renderer: NetworkManager
# Then apply
sudo netplan apply
sudo reboot
```
### Hotspot not visible to other devices
- Ensure no other connection is active
- Try 2.4GHz band (`HotspotBand::Bg`) for better compatibility
- Check that the password is at least 8 characters
## License
MIT License - see [LICENSE](LICENSE) for details.
## Contributing
Contributions are welcome! Please feel free to submit issues and pull requests.