diff --git a/matter/Cargo.toml b/matter/Cargo.toml index 9b9d544..7fee77f 100644 --- a/matter/Cargo.toml +++ b/matter/Cargo.toml @@ -56,6 +56,12 @@ qrcode = { version = "0.12", default-features = false } [target.'cfg(target_os = "macos")'.dependencies] astro-dnssd = "0.3" +# MDNS support +[target.'cfg(target_os = "linux")'.dependencies] +lazy_static = "1.4.0" +# Patched copy of libmdns +libmdns = { git = "https://github.com/angelybo/libmdns.git", branch = "return_all_on_query" } + [[example]] name = "onoff_light" path = "../examples/onoff_light/src/main.rs" diff --git a/matter/src/sys/sys_linux.rs b/matter/src/sys/sys_linux.rs index 7aa760c..881764d 100644 --- a/matter/src/sys/sys_linux.rs +++ b/matter/src/sys/sys_linux.rs @@ -16,17 +16,43 @@ */ use crate::error::Error; -use log::error; +use lazy_static::lazy_static; +use libmdns::{Responder, Service}; +use log::info; +use std::sync::{Arc, Mutex}; +use std::vec::Vec; #[allow(dead_code)] -pub struct SysMdnsService {} - -pub fn sys_publish_service( - _name: &str, - _regtype: &str, - _port: u16, - _txt_kvs: &[[&str; 2]], -) -> Result { - error!("Linux is not yet supported for MDNS Service"); - Ok(SysMdnsService {}) +pub struct SysMdnsService { + service: Service, +} + +lazy_static! { + static ref RESPONDER: Arc> = Arc::new(Mutex::new(Responder::new().unwrap())); +} + +/// Publish a mDNS service +/// name - can be a service name (comma separate subtypes may follow) +/// regtype - registration type (e.g. _matter_.tcp etc) +/// port - the port +pub fn sys_publish_service( + name: &str, + regtype: &str, + port: u16, + txt_kvs: &[[&str; 2]], +) -> Result { + info!("mDNS Registration Type {}", regtype); + info!("mDNS properties {:?}", txt_kvs); + + let mut properties = Vec::new(); + for kvs in txt_kvs { + info!("mDNS TXT key {} val {}", kvs[0], kvs[1]); + properties.push(format!("{}={}", kvs[0], kvs[1])); + } + let properties: Vec<&str> = properties.iter().map(|entry| entry.as_str()).collect(); + + let responder = RESPONDER.lock().map_err(|_| Error::MdnsError)?; + let service = responder.register(regtype.to_owned(), name.to_owned(), port, &properties); + + Ok(SysMdnsService { service }) }