Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions nmrs/src/api/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2132,6 +2132,14 @@ pub enum ConnectionError {
/// Bluetooth device not found
#[error("Bluetooth device not found")]
NoBluetoothDevice,

/// A D-Bus operation failed with context about what was being attempted
#[error("{context}: {source}")]
DbusOperation {
context: String,
#[source]
source: zbus::Error,
},
}

/// NetworkManager device state reason codes.
Expand Down
36 changes: 32 additions & 4 deletions nmrs/src/core/connection_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use std::collections::HashMap;
use zbus::Connection;
use zvariant::{OwnedObjectPath, Value};

use crate::api::models::ConnectionError;
use crate::util::utils::{connection_settings_proxy, settings_proxy};
use crate::util::validation::validate_ssid;
use crate::Result;
Expand Down Expand Up @@ -39,13 +40,26 @@ pub(crate) async fn get_saved_connection_path(

let settings = settings_proxy(conn).await?;

let reply = settings.call_method("ListConnections", &()).await?;
let reply = settings
.call_method("ListConnections", &())
.await
.map_err(|e| ConnectionError::DbusOperation {
context: "failed to list saved connections".to_string(),
source: e,
})?;

let conns: Vec<OwnedObjectPath> = reply.body().deserialize()?;

for cpath in conns {
let cproxy = connection_settings_proxy(conn, cpath.clone()).await?;

let msg = cproxy.call_method("GetSettings", &()).await?;
let msg = cproxy.call_method("GetSettings", &()).await.map_err(|e| {
ConnectionError::DbusOperation {
context: format!("failed to get settings for {}", cpath.as_str()),
source: e,
}
})?;

let body = msg.body();
let all: HashMap<String, HashMap<String, Value>> = body.deserialize()?;

Expand Down Expand Up @@ -75,7 +89,14 @@ pub(crate) async fn has_saved_connection(conn: &Connection, ssid: &str) -> Resul
pub(crate) async fn delete_connection(conn: &Connection, conn_path: OwnedObjectPath) -> Result<()> {
let cproxy = connection_settings_proxy(conn, conn_path.clone()).await?;

cproxy.call_method("Delete", &()).await?;
cproxy
.call_method("Delete", &())
.await
.map_err(|e| ConnectionError::DbusOperation {
context: format!("failed to delete connection {}", conn_path.as_str()),
source: e,
})?;

debug!("Deleted connection: {}", conn_path.as_str());
Ok(())
}
Expand All @@ -87,7 +108,14 @@ pub(crate) async fn delete_connection(conn: &Connection, conn_path: OwnedObjectP
pub(crate) async fn list_saved_connections(conn: &Connection) -> Result<Vec<String>> {
let settings = settings_proxy(conn).await?;

let reply = settings.call_method("ListConnections", &()).await?;
let reply = settings
.call_method("ListConnections", &())
.await
.map_err(|e| ConnectionError::DbusOperation {
context: "failed to list saved connections".to_string(),
source: e,
})?;

let conns: Vec<OwnedObjectPath> = reply.body().deserialize()?;

let mut connection_names = Vec::new();
Expand Down
39 changes: 35 additions & 4 deletions nmrs/src/core/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,13 @@ use crate::Result;
/// type (Ethernet, Wi-Fi, etc.), current state, and driver.
pub(crate) async fn list_devices(conn: &Connection) -> Result<Vec<Device>> {
let proxy = NMProxy::new(conn).await?;
let paths = proxy.get_devices().await?;
let paths = proxy
.get_devices()
.await
.map_err(|e| ConnectionError::DbusOperation {
context: "failed to get device paths from NetworkManager".to_string(),
source: e,
})?;

let mut devices = Vec::new();
for p in paths {
Expand All @@ -30,8 +36,21 @@ pub(crate) async fn list_devices(conn: &Connection) -> Result<Vec<Device>> {
.build()
.await?;

let interface = d_proxy.interface().await?;
let raw_type = d_proxy.device_type().await?;
let interface = d_proxy
.interface()
.await
.map_err(|e| ConnectionError::DbusOperation {
context: format!("failed to get interface name for device {}", p.as_str()),
source: e,
})?;

let raw_type = d_proxy
.device_type()
.await
.map_err(|e| ConnectionError::DbusOperation {
context: format!("failed to get device type for {}", interface),
source: e,
})?;
let current_mac = match d_proxy.hw_address().await {
Ok(addr) => addr,
Err(e) => {
Expand Down Expand Up @@ -128,9 +147,21 @@ pub(crate) async fn list_bluetooth_devices(conn: &Connection) -> Result<Vec<Blue
.await?;

// Only process Bluetooth devices
if d_proxy.device_type().await? != device_type::BLUETOOTH {
let dev_type = d_proxy
.device_type()
.await
.map_err(|e| ConnectionError::DbusOperation {
context: format!(
"failed to get device type for {} during Bluetooth scan",
p.as_str()
),
source: e,
})?;

if dev_type != device_type::BLUETOOTH {
continue;
}

// Bluetooth-specific proxy
// to get BD_ADDR and capabilities
let bd_proxy = NMBluetoothProxy::builder(conn)
Expand Down
22 changes: 19 additions & 3 deletions nmrs/src/core/scan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use std::collections::HashMap;
use zbus::Connection;

use crate::api::models::Network;
use crate::api::models::{ConnectionError, Network};
use crate::dbus::{NMAccessPointProxy, NMDeviceProxy, NMProxy, NMWirelessProxy};
use crate::monitoring::info::current_ssid;
use crate::types::constants::{device_type, security_flags};
Expand All @@ -30,7 +30,18 @@ pub(crate) async fn scan_networks(conn: &Connection) -> Result<()> {
.build()
.await?;

if d_proxy.device_type().await? != device_type::WIFI {
let dev_type = d_proxy
.device_type()
.await
.map_err(|e| ConnectionError::DbusOperation {
context: format!(
"failed to get device type for {} during Wi-Fi scan",
dp.as_str()
),
source: e,
})?;

if dev_type != device_type::WIFI {
continue;
}

Expand All @@ -40,7 +51,12 @@ pub(crate) async fn scan_networks(conn: &Connection) -> Result<()> {
.await?;

let opts = std::collections::HashMap::new();
wifi.request_scan(opts).await?;
wifi.request_scan(opts)
.await
.map_err(|e| ConnectionError::DbusOperation {
context: format!("failed to request Wi-Fi scan on device {}", dp.as_str()),
source: e,
})?;
}

Ok(())
Expand Down
20 changes: 16 additions & 4 deletions nmrs/src/core/vpn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ use zbus::Connection;
use zvariant::OwnedObjectPath;

use crate::api::models::{
ConnectionOptions, DeviceState, TimeoutConfig, VpnConnection, VpnConnectionInfo,
VpnCredentials, VpnType,
ConnectionError, ConnectionOptions, DeviceState, TimeoutConfig, VpnConnection,
VpnConnectionInfo, VpnCredentials, VpnType,
};
use crate::builders::build_wireguard_connection;
use crate::core::state_wait::wait_for_connection_activation;
Expand Down Expand Up @@ -273,7 +273,14 @@ pub(crate) async fn list_vpn_connections(conn: &Connection) -> Result<Vec<VpnCon
)
.await?;

let list_reply = settings.call_method("ListConnections", &()).await?;
let list_reply = settings
.call_method("ListConnections", &())
.await
.map_err(|e| ConnectionError::DbusOperation {
context: "failed to list saved connections".to_string(),
source: e,
})?;

let saved_conns: Vec<OwnedObjectPath> = list_reply.body().deserialize()?;

// Map active WireGuard connection id -> (state, interface)
Expand Down Expand Up @@ -563,7 +570,12 @@ pub(crate) async fn forget_vpn(conn: &Connection, name: &str) -> Result<()> {

if id_ok && type_ok {
debug!("Found WireGuard connection, deleting: {name}");
cproxy.call_method("Delete", &()).await?;
cproxy.call_method("Delete", &()).await.map_err(|e| {
ConnectionError::DbusOperation {
context: format!("failed to delete VPN connection '{}'", name),
source: e,
}
})?;
info!("Successfully deleted VPN connection: {name}");
return Ok(());
}
Expand Down
Loading