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", None, 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

  • A new profile requires a non-empty password. An empty PSK requests the stored password only when a saved profile already exists; otherwise nmrs returns ConnectionError::MissingPassword.
  • 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", None, WifiSecurity::WpaPsk {
        psk: password,
    }).await?;

    Ok(())
}

Reconnecting to Saved Networks

After the first successful connection, NetworkManager saves the credentials in a connection profile. Request its stored password with an empty PSK:

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

if nm.has_saved_connection("HomeWiFi").await? {
    nm.connect("HomeWiFi", None, WifiSecurity::WpaPsk {
        psk: String::new(),
    }).await?;
}
}

WifiSecurity::Open also reuses an existing saved profile. A non-empty PSK is not ignored: it asks nmrs to build a fresh profile with that password. If activation with the empty-PSK stored-secret request fails, the original saved profile is preserved.

Error Handling

The most common errors for WPA-PSK connections:

ErrorMeaning
ConnectionError::AuthFailedWrong password
ConnectionError::MissingPasswordEmpty password string and no saved profile to reuse
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", None, WifiSecurity::WpaPsk {
    psk: "password".into(),
}).await {
    Ok(_) => println!("Connected!"),
    Err(ConnectionError::AuthFailed) => {
        eprintln!("Wrong password — check and try again");
    }
    Err(ConnectionError::MissingPassword) => {
        eprintln!("No saved password is available; provide a non-empty PSK");
    }
    Err(e) => eprintln!("Error: {}", e),
}
}

Next Steps