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
3,504 changes: 0 additions & 3,504 deletions nmrs/src/api/models.rs

This file was deleted.

192 changes: 192 additions & 0 deletions nmrs/src/api/models/bluetooth.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
use std::fmt::{Display, Formatter};

use crate::util::validation::validate_bluetooth_address;

use super::device::DeviceState;
use super::error::ConnectionError;

/// Bluetooth network role.
///
/// Specifies the role of the Bluetooth device in the network connection.
///
/// # Stability
///
/// This enum is marked as `#[non_exhaustive]` so as to assume that new Bluetooth roles may be
/// added in future versions. When pattern matching, always include a wildcard arm.
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum BluetoothNetworkRole {
PanU, // Personal Area Network User
Dun, // Dial-Up Networking
}

/// Bluetooth device identity information.
///
/// Relevant info for Bluetooth devices managed by NetworkManager.
///
/// # Example
///```rust
/// use nmrs::models::{BluetoothIdentity, BluetoothNetworkRole};
///
/// let bt_settings = BluetoothIdentity::new(
/// "00:1A:7D:DA:71:13".into(),
/// BluetoothNetworkRole::Dun,
/// ).unwrap();
/// ```
#[non_exhaustive]
#[derive(Debug, Clone)]
pub struct BluetoothIdentity {
/// MAC address of Bluetooth device
pub bdaddr: String,
/// Bluetooth device type (DUN or PANU)
pub bt_device_type: BluetoothNetworkRole,
}

impl BluetoothIdentity {
/// Creates a new `BluetoothIdentity`.
///
/// # Arguments
///
/// * `bdaddr` - Bluetooth MAC address (e.g., "00:1A:7D:DA:71:13")
/// * `bt_device_type` - Bluetooth network role (PanU or Dun)
///
/// # Errors
///
/// Returns a `ConnectionError` if the provided `bdaddr` is not a
/// valid Bluetooth MAC address format.
///
/// # Example
///
/// ```rust
/// use nmrs::models::{BluetoothIdentity, BluetoothNetworkRole};
///
/// let identity = BluetoothIdentity::new(
/// "00:1A:7D:DA:71:13".into(),
/// BluetoothNetworkRole::PanU,
/// ).unwrap();
/// ```
pub fn new(
bdaddr: String,
bt_device_type: BluetoothNetworkRole,
) -> Result<Self, ConnectionError> {
validate_bluetooth_address(&bdaddr)?;
Ok(Self {
bdaddr,
bt_device_type,
})
}
}

/// Bluetooth device with friendly name from BlueZ.
///
/// Contains information about a Bluetooth device managed by NetworkManager,
/// proxying data from BlueZ.
///
/// This is a specialized struct for Bluetooth devices, separate from the
/// general `Device` struct.
///
/// # Example
///
/// # Example
///
/// ```rust
/// use nmrs::models::{BluetoothDevice, BluetoothNetworkRole, DeviceState};
///
/// let role = BluetoothNetworkRole::PanU as u32;
/// let device = BluetoothDevice::new(
/// "00:1A:7D:DA:71:13".into(),
/// Some("My Phone".into()),
/// Some("Phone".into()),
/// role,
/// DeviceState::Activated,
/// );
/// ```
#[non_exhaustive]
#[derive(Debug, Clone)]
pub struct BluetoothDevice {
/// Bluetooth MAC address
pub bdaddr: String,
/// Friendly device name from BlueZ
pub name: Option<String>,
/// Device alias from BlueZ
pub alias: Option<String>,
/// Bluetooth device type (DUN or PANU)
pub bt_caps: u32,
/// Current device state
pub state: DeviceState,
}

impl BluetoothDevice {
/// Creates a new `BluetoothDevice`.
///
/// # Arguments
///
/// * `bdaddr` - Bluetooth MAC address
/// * `name` - Friendly device name from BlueZ
/// * `alias` - Device alias from BlueZ
/// * `bt_caps` - Bluetooth device capabilities/type
/// * `state` - Current device state
///
/// # Example
///
/// ```rust
/// use nmrs::models::{BluetoothDevice, BluetoothNetworkRole, DeviceState};
///
/// let role = BluetoothNetworkRole::PanU as u32;
/// let device = BluetoothDevice::new(
/// "00:1A:7D:DA:71:13".into(),
/// Some("My Phone".into()),
/// Some("Phone".into()),
/// role,
/// DeviceState::Activated,
/// );
/// ```
#[must_use]
pub fn new(
bdaddr: String,
name: Option<String>,
alias: Option<String>,
bt_caps: u32,
state: DeviceState,
) -> Self {
Self {
bdaddr,
name,
alias,
bt_caps,
state,
}
}
}

impl Display for BluetoothDevice {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let role = BluetoothNetworkRole::from(self.bt_caps);
write!(
f,
"{} ({}) [{}]",
self.alias.as_deref().unwrap_or("unknown"),
role,
self.bdaddr
)
}
}

impl Display for BluetoothNetworkRole {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
BluetoothNetworkRole::Dun => write!(f, "DUN"),
BluetoothNetworkRole::PanU => write!(f, "PANU"),
}
}
}

impl From<u32> for BluetoothNetworkRole {
fn from(value: u32) -> Self {
match value {
0 => Self::PanU,
1 => Self::Dun,
_ => Self::PanU,
}
}
}
188 changes: 188 additions & 0 deletions nmrs/src/api/models/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
use std::time::Duration;

/// Timeout configuration for NetworkManager operations.
///
/// Controls how long NetworkManager will wait for various network operations
/// to complete before timing out. This allows customization for different
/// network environments (slow networks, enterprise auth, etc.).
///
/// # Examples
///
/// ```rust
/// use nmrs::TimeoutConfig;
/// use std::time::Duration;
///
/// // Use default timeouts (30s connect, 10s disconnect)
/// let config = TimeoutConfig::default();
///
/// // Custom timeouts for slow networks
/// let config = TimeoutConfig::new()
/// .with_connection_timeout(Duration::from_secs(60))
/// .with_disconnect_timeout(Duration::from_secs(20));
///
/// // Quick timeouts for fast networks
/// let config = TimeoutConfig::new()
/// .with_connection_timeout(Duration::from_secs(15))
/// .with_disconnect_timeout(Duration::from_secs(5));
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy)]
pub struct TimeoutConfig {
/// Timeout for connection activation (default: 30 seconds)
pub connection_timeout: Duration,
/// Timeout for device disconnection (default: 10 seconds)
pub disconnect_timeout: Duration,
}

impl Default for TimeoutConfig {
/// Returns the default timeout configuration.
///
/// Defaults:
/// - `connection_timeout`: 30 seconds
/// - `disconnect_timeout`: 10 seconds
fn default() -> Self {
Self {
connection_timeout: Duration::from_secs(30),
disconnect_timeout: Duration::from_secs(10),
}
}
}

impl TimeoutConfig {
/// Creates a new `TimeoutConfig` with default values.
///
/// # Examples
///
/// ```rust
/// use nmrs::TimeoutConfig;
///
/// let config = TimeoutConfig::new();
/// ```
#[must_use]
pub fn new() -> Self {
Self::default()
}

/// Sets the connection activation timeout.
///
/// This controls how long to wait for a network connection to activate
/// before giving up. Increase this for slow networks or enterprise
/// authentication that may take longer.
///
/// # Examples
///
/// ```rust
/// use nmrs::TimeoutConfig;
/// use std::time::Duration;
///
/// let config = TimeoutConfig::new()
/// .with_connection_timeout(Duration::from_secs(60));
/// ```
#[must_use]
pub fn with_connection_timeout(mut self, timeout: Duration) -> Self {
self.connection_timeout = timeout;
self
}

/// Sets the disconnection timeout.
///
/// This controls how long to wait for a device to disconnect before
/// giving up.
///
/// # Examples
///
/// ```rust
/// use nmrs::TimeoutConfig;
/// use std::time::Duration;
///
/// let config = TimeoutConfig::new()
/// .with_disconnect_timeout(Duration::from_secs(20));
/// ```
#[must_use]
pub fn with_disconnect_timeout(mut self, timeout: Duration) -> Self {
self.disconnect_timeout = timeout;
self
}
}

/// Connection options for saved NetworkManager connections.
///
/// Controls how NetworkManager handles saved connection profiles,
/// including automatic connection behavior.
///
/// # Examples
///
/// ```rust
/// use nmrs::ConnectionOptions;
///
/// // Basic auto-connect (using defaults)
/// let opts = ConnectionOptions::default();
///
/// // High-priority connection with retry limit
/// let opts_priority = ConnectionOptions::new(true)
/// .with_priority(10) // Higher = more preferred
/// .with_retries(3); // Retry up to 3 times
///
/// // Manual connection only
/// let opts_manual = ConnectionOptions::new(false);
/// ```
#[non_exhaustive]
#[derive(Debug, Clone)]
pub struct ConnectionOptions {
/// Whether to automatically connect when available
pub autoconnect: bool,
/// Priority for auto-connection (higher = more preferred)
pub autoconnect_priority: Option<i32>,
/// Maximum number of auto-connect retry attempts
pub autoconnect_retries: Option<i32>,
}

impl Default for ConnectionOptions {
/// Returns the default connection options.
///
/// Defaults:
/// - `autoconnect`: `true`
/// - `autoconnect_priority`: `None` (uses NetworkManager's default of 0)
/// - `autoconnect_retries`: `None` (unlimited retries)
fn default() -> Self {
Self {
autoconnect: true,
autoconnect_priority: None,
autoconnect_retries: None,
}
}
}

impl ConnectionOptions {
/// Creates new `ConnectionOptions` with the specified autoconnect setting.
///
/// # Examples
///
/// ```rust
/// use nmrs::ConnectionOptions;
///
/// let opts = ConnectionOptions::new(true);
/// ```
#[must_use]
pub fn new(autoconnect: bool) -> Self {
Self {
autoconnect,
autoconnect_priority: None,
autoconnect_retries: None,
}
}

/// Sets the auto-connection priority.
#[must_use]
pub fn with_priority(mut self, priority: i32) -> Self {
self.autoconnect_priority = Some(priority);
self
}

/// Sets the maximum number of auto-connect retry attempts.
#[must_use]
pub fn with_retries(mut self, retries: i32) -> Self {
self.autoconnect_retries = Some(retries);
self
}
}
Loading
Loading