diff --git a/matter/Cargo.toml b/matter/Cargo.toml index 9b9d5444..7fee77fa 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 7aa760c7..bd9fb1e8 100644 --- a/matter/src/sys/sys_linux.rs +++ b/matter/src/sys/sys_linux.rs @@ -16,17 +16,50 @@ */ use crate::error::Error; -use log::error; +use std::vec::Vec; +use log::info; +use lazy_static::lazy_static; +use std::sync::{Arc, Mutex}; +use libmdns::{Service, Responder}; #[allow(dead_code)] -pub struct 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 { - error!("Linux is not yet supported for MDNS Service"); - Ok(SysMdnsService {}) -} + 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}) + } \ No newline at end of file