gateway_mm/src/modem/mod.rs

116 lines
3.4 KiB
Rust

// Copyright (C) 2022 Maxime “pep” Buquet <pep@bouah.net>
//
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU Affero General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
// for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
mod introspect;
use crate::error::Error;
use crate::modem::introspect::{ModemProxy, MessagingProxy, VoiceProxy};
use std::fmt;
use zbus::{fdo::ObjectManagerProxy, zvariant::ObjectPath, Connection};
const MM_NAME: &str = "org.freedesktop.ModemManager1";
const MM_PATH: &str = "/org/freedesktop/ModemManager1";
#[derive(Clone)]
pub struct ModemManager<'a> {
connection: Connection,
modems: Vec<Modem<'a>>,
}
impl<'a> ModemManager<'a> {
pub async fn connect() -> Result<ModemManager<'a>, Error> {
let connection = Connection::system().await?;
Ok(ModemManager {
modems: ModemManager::modems(&connection).await?,
connection,
})
}
pub async fn modems(conn: &Connection) -> Result<Vec<Modem<'a>>, Error> {
let proxy = ObjectManagerProxy::builder(&conn)
.destination(MM_NAME)?
.path(MM_PATH)?
.build()
.await?;
let mut res = vec![];
for (path, _) in proxy.get_managed_objects().await? {
res.push(Modem::new(&conn, path.into()).await?)
}
Ok(res)
}
}
impl fmt::Debug for ModemManager<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ModemManager")
.field("modems", &self.modems)
.finish_non_exhaustive()
}
}
impl<'a> IntoIterator for ModemManager<'a> {
type Item = Modem<'a>;
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.modems.into_iter()
}
}
#[derive(Clone)]
pub struct Modem<'a> {
modem: ModemProxy<'a>,
messaging: MessagingProxy<'a>,
voice: VoiceProxy<'a>,
path: ObjectPath<'a>,
}
impl<'a> Modem<'a> {
pub async fn new(connection: &Connection, path: ObjectPath<'a>) -> Result<Modem<'a>, Error> {
Ok(Modem {
modem: ModemProxy::builder(connection).path(path.clone())?.build().await?,
messaging: MessagingProxy::builder(connection).path(path.clone())?.build().await?,
voice: VoiceProxy::builder(connection).path(path.clone())?.build().await?,
path,
})
}
pub fn foo(&self) -> &ModemProxy<'a> {
&self.modem
}
pub fn messaging(&self) -> &MessagingProxy<'a> {
&self.messaging
}
pub fn voice(&self) -> &VoiceProxy<'a> {
&self.voice
}
}
impl fmt::Debug for Modem<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Modem")
.field("destination", &self.foo().destination())
.field("path", &self.foo().inner().path())
.field("interface", &self.foo().inner().interface())
.finish_non_exhaustive()
}
}