pub struct Device<Io: IoImpl<UdpSocket, TcpStream, TcpListener, TlsStream>, UdpSocket: UdpSocketImpl, TcpStream: TcpStreamImpl, TcpListener: TcpListenerImpl<TcpStream>, TlsStream: TlsStreamImpl> { /* private fields */ }Expand description
Structure representing the host device.
To make one, you need to make a configuration with DeviceConfig,
to choose plugins to use, you need a trust handler i.e a structure implementing
TrustHandler and an IO implementation of your choice (you can use
TokioIoImpl as a default).
§Example
This code snippet launches a new device with no plugin defined and the trust handler
defined in the example of TrustHandler, assuming that an X.509 certificate exists at
cert.pem and an X.509 private key exists at private_key.pem (see DeviceConfig to learn
how to create them).
To learn how to make plugins, check Plugin.
use std::{fs, collections::HashMap, path::{Path, PathBuf}};
use kdeconnect_proto::{
config::DeviceConfig,
device::{Device, DeviceType},
trust::TrustHandler,
io::TokioIoImpl,
};
struct TrustHandlerImpl {
path: PathBuf,
trusted_devices: HashMap<String, Vec<u8>>,
}
impl TrustHandlerImpl {
pub fn new<P: AsRef<Path>>(path: P) -> Self {
let path = path.as_ref();
let trusted_devices = if path.exists() {
HashMap::from_iter(fs::read_dir(path).unwrap().filter_map(Result::ok).map(|f| {
let device_id = f.path().file_stem().unwrap().to_string_lossy().to_string();
let cert = fs::read(f.path()).expect("failed to read certificate");
(device_id, cert)
}))
} else {
fs::create_dir_all(path).expect("failed to create directory for trusted devices");
HashMap::new()
};
Self {
path: path.to_path_buf(),
trusted_devices,
}
}
}
#[kdeconnect_proto::async_trait]
impl TrustHandler for TrustHandlerImpl {
async fn trust_device(&mut self, device_id: String, cert: Vec<u8>) {
fs::write(self.path.join(device_id.clone() + ".pem"), &cert).unwrap();
self.trusted_devices.insert(device_id, cert);
}
async fn untrust_device(&mut self, device_id: &str) {
fs::remove_file(self.path.join(device_id.to_string() + ".pem")).unwrap();
self.trusted_devices.remove(device_id);
}
async fn get_certificate(&mut self, device_id: &str) -> Option<&[u8]> {
self.trusted_devices.get(device_id).map(|v| &**v)
}
}
let config = DeviceConfig {
name: String::from("kdeconnect client"),
device_type: DeviceType::Desktop,
cert: fs::read("cert.pem").expect("failed to read certificate"),
private_key: fs::read("private_key.pem").expect("failed to read private key"),
};
let device = Device::new(config, vec![], TrustHandlerImpl::new("trusted_devices"), TokioIoImpl);
device.start();§Pairing
You need to manually accept each pair request coming from a peer device using the
Device::accept_pair method. You can use a background asynchronous task to do that.
Implementations§
Source§impl<Io: IoImpl<UdpSocket, TcpStream, TcpListener, TlsStream> + Unpin + 'static, UdpSocket: UdpSocketImpl + Unpin + 'static, TcpStream: TcpStreamImpl + Unpin + 'static, TcpListener: TcpListenerImpl<TcpStream> + Unpin + 'static, TlsStream: TlsStreamImpl + Unpin + 'static> Device<Io, UdpSocket, TcpStream, TcpListener, TlsStream>
impl<Io: IoImpl<UdpSocket, TcpStream, TcpListener, TlsStream> + Unpin + 'static, UdpSocket: UdpSocketImpl + Unpin + 'static, TcpStream: TcpStreamImpl + Unpin + 'static, TcpListener: TcpListenerImpl<TcpStream> + Unpin + 'static, TlsStream: TlsStreamImpl + Unpin + 'static> Device<Io, UdpSocket, TcpStream, TcpListener, TlsStream>
Sourcepub fn new<T: TrustHandler + Send + Sync + 'static>(
config: DeviceConfig,
plugins: Vec<Box<dyn Plugin + Send + Sync>>,
trust_handler: T,
io_impl: Io,
) -> Self
pub fn new<T: TrustHandler + Send + Sync + 'static>( config: DeviceConfig, plugins: Vec<Box<dyn Plugin + Send + Sync>>, trust_handler: T, io_impl: Io, ) -> Self
Make a new Device.
Sourcepub fn links(&self) -> &Arc<Mutex<HashMap<String, Link>>>
pub fn links(&self) -> &Arc<Mutex<HashMap<String, Link>>>
Get an arc mutex’d map of (Device ID, Link) pairs.
Sourcepub async fn pair_with(&self, link_id: &str)
pub async fn pair_with(&self, link_id: &str)
Pair with a peer device.
In most cases, the pair state will be advanced from PairState::Unpaired to
PairState::Requested.
Sourcepub async fn unpair_with(&self, link_id: &str)
pub async fn unpair_with(&self, link_id: &str)
Unpair from a peer device.
In most cases, the pair state will be advanced from PairState::Paired to
PairState::Unpaired.
Sourcepub async fn accept_pair(&self, link_id: &str)
pub async fn accept_pair(&self, link_id: &str)
Accept the pairing with a peer device which has already requested pairing.
In most cases, the pair state will be advanced from PairState::RequestedByPeer to
PairState::Paired.
Sourcepub async fn wait_for_connection(&self) -> String
pub async fn wait_for_connection(&self) -> String
Wait for a peer device to connect and return its device ID.
The connected device may or may not be paired.
Sourcepub fn start_arced(self: Arc<Self>)
pub fn start_arced(self: Arc<Self>)
Start an internal task responsible for handling connections and managing state.
This function takes an Arc of self for easier usage of the Device structure.