WPA-PSK Networks

WPA-PSK (Wi-Fi Protected Access with Pre-Shared Key) is the most common security type for home and small-office Wi-Fi networks. You provide a password, and nmrs handles the WPA handshake.

Connecting with a Password

use nmrs::{NetworkManager, WifiSecurity};

#[tokio::main]
async fn main() -> nmrs::Result<()> {
    let nm = NetworkManager::new().await?;

    nm.connect("HomeWiFi", WifiSecurity::WpaPsk {
        psk: "my_secure_password".into(),
    }).await?;

    println!("Connected!");
    Ok(())
}

The WifiSecurity::WpaPsk variant works with WPA, WPA2, and WPA3 Personal networks. NetworkManager negotiates the strongest supported protocol automatically.

Password Requirements

  • Must not be empty — ConnectionError::MissingPassword is returned for empty strings
  • WPA-PSK passwords are typically 8–63 characters (ASCII passphrase) or exactly 64 hex characters (raw PSK)
  • nmrs passes the password directly to NetworkManager, which handles validation

Reading the Password at Runtime

Avoid hardcoding passwords. Read them from environment variables, user input, or a secrets manager:

use nmrs::{NetworkManager, WifiSecurity};

#[tokio::main]
async fn main() -> nmrs::Result<()> {
    let nm = NetworkManager::new().await?;

    let password = std::env::var("WIFI_PASSWORD")
        .expect("Set WIFI_PASSWORD environment variable");

    nm.connect("HomeWiFi", WifiSecurity::WpaPsk {
        psk: password,
    }).await?;

    Ok(())
}

Reconnecting to Saved Networks

After the first successful connection, NetworkManager saves the credentials in a connection profile. Subsequent connections to the same SSID will reuse the saved profile automatically — you don't need to provide the password again:

#![allow(unused)]
fn main() {
let nm = NetworkManager::new().await?;

if nm.has_saved_connection("HomeWiFi").await? {
    // Saved profile exists; password is stored in it.
    // The WifiSecurity value is ignored when a saved profile exists.
    nm.connect("HomeWiFi", WifiSecurity::Open).await?;
}
}

Error Handling

The most common errors for WPA-PSK connections:

ErrorMeaning
ConnectionError::AuthFailedWrong password
ConnectionError::MissingPasswordEmpty password string
ConnectionError::NotFoundNetwork not in range
ConnectionError::TimeoutConnection took too long
ConnectionError::DhcpFailedConnected to AP but DHCP failed
#![allow(unused)]
fn main() {
use nmrs::{NetworkManager, WifiSecurity, ConnectionError};

let nm = NetworkManager::new().await?;

match nm.connect("HomeWiFi", WifiSecurity::WpaPsk {
    psk: "password".into(),
}).await {
    Ok(_) => println!("Connected!"),
    Err(ConnectionError::AuthFailed) => {
        eprintln!("Wrong password — check and try again");
    }
    Err(ConnectionError::MissingPassword) => {
        eprintln!("Password cannot be empty");
    }
    Err(e) => eprintln!("Error: {}", e),
}
}

Next Steps