rpi-host 0.1.1

A library to control Raspberry Pi 5 wireless interface for switching between hotspot and client modes
Documentation
# rpi-host

A Rust library for controlling the Raspberry Pi wireless interface, enabling easy switching between WiFi client mode and hotspot (access point) mode.

[![Crates.io](https://img.shields.io/crates/v/rpi-host.svg)](https://crates.io/crates/rpi-host)
[![Documentation](https://docs.rs/rpi-host/badge.svg)](https://docs.rs/rpi-host)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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

| Method | Description |
|--------|-------------|
| `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.