Cleanup a bit the mDns story
This commit is contained in:
parent
a7ca17fabc
commit
52185ec9a4
9 changed files with 429 additions and 284 deletions
|
@ -48,7 +48,8 @@ fn main() {
|
||||||
device_name: "OnOff Light",
|
device_name: "OnOff Light",
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut mdns = matter::sys::LinuxMdns::new().unwrap();
|
//let mut mdns = matter::mdns::bonjour::BonjourMdns::new().unwrap();
|
||||||
|
let mut mdns = matter::mdns::libmdns::LibMdns::new().unwrap();
|
||||||
|
|
||||||
let matter = Matter::new_default(&dev_info, &mut mdns);
|
let matter = Matter::new_default(&dev_info, &mut mdns);
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ path = "src/lib.rs"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std", "crypto_mbedtls", "nightly"]
|
default = ["std", "crypto_mbedtls", "nightly"]
|
||||||
std = ["alloc", "env_logger", "chrono", "rand", "qrcode", "smol"]
|
std = ["alloc", "env_logger", "chrono", "rand", "qrcode", "libmdns", "simple-mdns", "simple-dns", "smol"]
|
||||||
alloc = []
|
alloc = []
|
||||||
nightly = []
|
nightly = []
|
||||||
crypto_openssl = ["openssl", "foreign-types", "hmac", "sha2"]
|
crypto_openssl = ["openssl", "foreign-types", "hmac", "sha2"]
|
||||||
|
@ -43,8 +43,12 @@ colored = "2.0.0" # TODO: Requires STD
|
||||||
env_logger = { version = "0.10.0", default-features = false, optional = true }
|
env_logger = { version = "0.10.0", default-features = false, optional = true }
|
||||||
chrono = { version = "0.4.23", optional = true, default-features = false, features = ["clock", "std"] }
|
chrono = { version = "0.4.23", optional = true, default-features = false, features = ["clock", "std"] }
|
||||||
rand = { version = "0.8.5", optional = true }
|
rand = { version = "0.8.5", optional = true }
|
||||||
smol = { version = "1.3.0", optional = true}
|
|
||||||
qrcode = { version = "0.12", default-features = false, optional = true } # Print QR code
|
qrcode = { version = "0.12", default-features = false, optional = true } # Print QR code
|
||||||
|
libmdns = { version = "0.7", optional = true }
|
||||||
|
simple-mdns = { version = "0.4", features = ["sync"], optional = true }
|
||||||
|
simple-dns = { version = "0.5", optional = true }
|
||||||
|
astro-dnssd = { version = "0.3", optional = true }
|
||||||
|
smol = { version = "1.3.0", optional = true}
|
||||||
|
|
||||||
# crypto
|
# crypto
|
||||||
openssl = { git = "https://github.com/sfackler/rust-openssl", optional = true }
|
openssl = { git = "https://github.com/sfackler/rust-openssl", optional = true }
|
||||||
|
@ -66,13 +70,6 @@ x509-cert = { version = "0.2.0", default-features = false, features = ["pem", "s
|
||||||
# to compute the check digit
|
# to compute the check digit
|
||||||
verhoeff = "1"
|
verhoeff = "1"
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
|
||||||
astro-dnssd = "0.3"
|
|
||||||
|
|
||||||
# MDNS support
|
|
||||||
[target.'cfg(target_os = "linux")'.dependencies]
|
|
||||||
libmdns = { version = "0.7.4" }
|
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "onoff_light"
|
name = "onoff_light"
|
||||||
path = "../examples/onoff_light/src/main.rs"
|
path = "../examples/onoff_light/src/main.rs"
|
||||||
|
|
|
@ -25,6 +25,7 @@ pub trait Mdns {
|
||||||
name: &str,
|
name: &str,
|
||||||
service_type: &str,
|
service_type: &str,
|
||||||
port: u16,
|
port: u16,
|
||||||
|
service_subtypes: &[&str],
|
||||||
txt_kvs: &[(&str, &str)],
|
txt_kvs: &[(&str, &str)],
|
||||||
) -> Result<(), Error>;
|
) -> Result<(), Error>;
|
||||||
|
|
||||||
|
@ -40,9 +41,10 @@ where
|
||||||
name: &str,
|
name: &str,
|
||||||
service_type: &str,
|
service_type: &str,
|
||||||
port: u16,
|
port: u16,
|
||||||
|
service_subtypes: &[&str],
|
||||||
txt_kvs: &[(&str, &str)],
|
txt_kvs: &[(&str, &str)],
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
(**self).add(name, service_type, port, txt_kvs)
|
(**self).add(name, service_type, port, service_subtypes, txt_kvs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove(&mut self, name: &str, service_type: &str, port: u16) -> Result<(), Error> {
|
fn remove(&mut self, name: &str, service_type: &str, port: u16) -> Result<(), Error> {
|
||||||
|
@ -58,6 +60,7 @@ impl Mdns for DummyMdns {
|
||||||
_name: &str,
|
_name: &str,
|
||||||
_service_type: &str,
|
_service_type: &str,
|
||||||
_port: u16,
|
_port: u16,
|
||||||
|
_service_subtypes: &[&str],
|
||||||
_txt_kvs: &[(&str, &str)],
|
_txt_kvs: &[(&str, &str)],
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -112,11 +115,12 @@ impl<'a> MdnsMgr<'a> {
|
||||||
#[allow(clippy::needless_pass_by_value)]
|
#[allow(clippy::needless_pass_by_value)]
|
||||||
pub fn publish_service(&mut self, name: &str, mode: ServiceMode) -> Result<(), Error> {
|
pub fn publish_service(&mut self, name: &str, mode: ServiceMode) -> Result<(), Error> {
|
||||||
match mode {
|
match mode {
|
||||||
ServiceMode::Commissioned => self.mdns.add(name, "_matter._tcp", self.matter_port, &[]),
|
ServiceMode::Commissioned => {
|
||||||
|
self.mdns
|
||||||
|
.add(name, "_matter._tcp", self.matter_port, &[], &[])
|
||||||
|
}
|
||||||
ServiceMode::Commissionable(discriminator) => {
|
ServiceMode::Commissionable(discriminator) => {
|
||||||
let discriminator_str = Self::get_discriminator_str(discriminator);
|
let discriminator_str = Self::get_discriminator_str(discriminator);
|
||||||
|
|
||||||
let serv_type = self.get_service_type(discriminator);
|
|
||||||
let vp = self.get_vp();
|
let vp = self.get_vp();
|
||||||
|
|
||||||
let txt_kvs = [
|
let txt_kvs = [
|
||||||
|
@ -129,7 +133,17 @@ impl<'a> MdnsMgr<'a> {
|
||||||
("PH", "33"), /* Pairing Hint */
|
("PH", "33"), /* Pairing Hint */
|
||||||
("PI", ""), /* Pairing Instruction */
|
("PI", ""), /* Pairing Instruction */
|
||||||
];
|
];
|
||||||
self.mdns.add(name, &serv_type, self.matter_port, &txt_kvs)
|
|
||||||
|
self.mdns.add(
|
||||||
|
name,
|
||||||
|
"_matter._udp",
|
||||||
|
self.matter_port,
|
||||||
|
&[
|
||||||
|
&self.get_long_service_subtype(discriminator),
|
||||||
|
&self.get_short_service_type(discriminator),
|
||||||
|
],
|
||||||
|
&txt_kvs,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,28 +151,32 @@ impl<'a> MdnsMgr<'a> {
|
||||||
pub fn unpublish_service(&mut self, name: &str, mode: ServiceMode) -> Result<(), Error> {
|
pub fn unpublish_service(&mut self, name: &str, mode: ServiceMode) -> Result<(), Error> {
|
||||||
match mode {
|
match mode {
|
||||||
ServiceMode::Commissioned => self.mdns.remove(name, "_matter._tcp", self.matter_port),
|
ServiceMode::Commissioned => self.mdns.remove(name, "_matter._tcp", self.matter_port),
|
||||||
ServiceMode::Commissionable(discriminator) => {
|
ServiceMode::Commissionable(_) => {
|
||||||
let serv_type = self.get_service_type(discriminator);
|
self.mdns.remove(name, "_matter._udp", self.matter_port)
|
||||||
|
|
||||||
self.mdns.remove(name, &serv_type, self.matter_port)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_service_type(&self, discriminator: u16) -> heapless::String<32> {
|
fn get_long_service_subtype(&self, discriminator: u16) -> heapless::String<32> {
|
||||||
let short = Self::compute_short_discriminator(discriminator);
|
|
||||||
let mut serv_type = heapless::String::new();
|
let mut serv_type = heapless::String::new();
|
||||||
|
write!(&mut serv_type, "_L{}", discriminator).unwrap();
|
||||||
write!(
|
|
||||||
&mut serv_type,
|
|
||||||
"_matterc._udp,_S{},_L{}",
|
|
||||||
short, discriminator
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
serv_type
|
serv_type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_short_service_type(&self, discriminator: u16) -> heapless::String<32> {
|
||||||
|
let short = Self::compute_short_discriminator(discriminator);
|
||||||
|
|
||||||
|
let mut serv_type = heapless::String::new();
|
||||||
|
write!(&mut serv_type, "_S{}", short).unwrap();
|
||||||
|
|
||||||
|
serv_type
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_discriminator_str(discriminator: u16) -> heapless::String<5> {
|
||||||
|
discriminator.into()
|
||||||
|
}
|
||||||
|
|
||||||
fn get_vp(&self) -> heapless::String<11> {
|
fn get_vp(&self) -> heapless::String<11> {
|
||||||
let mut vp = heapless::String::new();
|
let mut vp = heapless::String::new();
|
||||||
|
|
||||||
|
@ -167,10 +185,6 @@ impl<'a> MdnsMgr<'a> {
|
||||||
vp
|
vp
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_discriminator_str(discriminator: u16) -> heapless::String<5> {
|
|
||||||
discriminator.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn compute_short_discriminator(discriminator: u16) -> u16 {
|
fn compute_short_discriminator(discriminator: u16) -> u16 {
|
||||||
const SHORT_DISCRIMINATOR_MASK: u16 = 0xF00;
|
const SHORT_DISCRIMINATOR_MASK: u16 = 0xF00;
|
||||||
const SHORT_DISCRIMINATOR_SHIFT: u16 = 8;
|
const SHORT_DISCRIMINATOR_SHIFT: u16 = 8;
|
||||||
|
@ -179,6 +193,353 @@ impl<'a> MdnsMgr<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(all(feature = "std", feature = "bonjour"))]
|
||||||
|
pub mod bonjour {
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use super::Mdns;
|
||||||
|
use crate::error::Error;
|
||||||
|
use astro_dnssd::{DNSServiceBuilder, RegisteredDnsService};
|
||||||
|
use log::info;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||||
|
pub struct ServiceId {
|
||||||
|
name: String,
|
||||||
|
service_type: String,
|
||||||
|
port: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct BonjourMdns {
|
||||||
|
services: HashMap<RegisteredDnsService, RegisteredDnsService>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BonjourMdns {
|
||||||
|
pub fn new() -> Result<Self, Error> {
|
||||||
|
Ok(Self {
|
||||||
|
services: HashMap::new(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add(
|
||||||
|
&mut self,
|
||||||
|
name: &str,
|
||||||
|
service_type: &str,
|
||||||
|
port: u16,
|
||||||
|
service_subtypes: &[&str],
|
||||||
|
txt_kvs: &[(&str, &str)],
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
info!(
|
||||||
|
"Registering mDNS service {}/{}/{}",
|
||||||
|
name, service_type, port
|
||||||
|
);
|
||||||
|
|
||||||
|
let _ = self.remove(name, service_type, port);
|
||||||
|
|
||||||
|
let composite_service_type = if !service_subtypes.is_empty() {
|
||||||
|
format!("{}{}", service_type, service_subtypes.join(","))
|
||||||
|
} else {
|
||||||
|
service_type
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut builder = DNSServiceBuilder::new(composite_service_type, port).with_name(name);
|
||||||
|
|
||||||
|
for kvs in txt_kvs {
|
||||||
|
info!("mDNS TXT key {} val {}", kvs.0, kvs.1);
|
||||||
|
builder = builder.with_key_value(kvs.0.to_string(), kvs.1.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
let service = builder.register().map_err(|_| Error::MdnsError)?;
|
||||||
|
|
||||||
|
self.services.insert(
|
||||||
|
ServiceId {
|
||||||
|
name: name.into(),
|
||||||
|
service_type: service_type.into(),
|
||||||
|
port,
|
||||||
|
},
|
||||||
|
service,
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove(&mut self, name: &str, service_type: &str, port: u16) -> Result<(), Error> {
|
||||||
|
let id = ServiceId {
|
||||||
|
name: name.into(),
|
||||||
|
service_type: service_type.into(),
|
||||||
|
port,
|
||||||
|
};
|
||||||
|
|
||||||
|
if self.services.remove(&id).is_some() {
|
||||||
|
info!(
|
||||||
|
"Deregistering mDNS service {}/{}/{}",
|
||||||
|
name, service_type, port
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mdns for BonjourMdns {
|
||||||
|
fn add(
|
||||||
|
&mut self,
|
||||||
|
name: &str,
|
||||||
|
service_type: &str,
|
||||||
|
port: u16,
|
||||||
|
service_subtypes: &[&str],
|
||||||
|
txt_kvs: &[(&str, &str)],
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
BonjourMdns::add(self, name, service_type, port, service_subtypes, txt_kvs)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove(&mut self, name: &str, service_type: &str, port: u16) -> Result<(), Error> {
|
||||||
|
BonjourMdns::remove(self, name, service_type, port)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
pub mod libmdns {
|
||||||
|
use super::Mdns;
|
||||||
|
use crate::error::Error;
|
||||||
|
use libmdns::{Responder, Service};
|
||||||
|
use log::info;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||||
|
pub struct ServiceId {
|
||||||
|
name: String,
|
||||||
|
service_type: String,
|
||||||
|
port: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct LibMdns {
|
||||||
|
responder: Responder,
|
||||||
|
services: HashMap<ServiceId, Service>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LibMdns {
|
||||||
|
pub fn new() -> Result<Self, Error> {
|
||||||
|
let responder = Responder::new()?;
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
responder,
|
||||||
|
services: HashMap::new(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add(
|
||||||
|
&mut self,
|
||||||
|
name: &str,
|
||||||
|
service_type: &str,
|
||||||
|
port: u16,
|
||||||
|
txt_kvs: &[(&str, &str)],
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
info!(
|
||||||
|
"Registering mDNS service {}/{}/{}",
|
||||||
|
name, service_type, port
|
||||||
|
);
|
||||||
|
|
||||||
|
let _ = self.remove(name, service_type, port);
|
||||||
|
|
||||||
|
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 service = self.responder.register(
|
||||||
|
service_type.to_owned(),
|
||||||
|
name.to_owned(),
|
||||||
|
port,
|
||||||
|
&properties,
|
||||||
|
);
|
||||||
|
|
||||||
|
self.services.insert(
|
||||||
|
ServiceId {
|
||||||
|
name: name.into(),
|
||||||
|
service_type: service_type.into(),
|
||||||
|
port,
|
||||||
|
},
|
||||||
|
service,
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove(&mut self, name: &str, service_type: &str, port: u16) -> Result<(), Error> {
|
||||||
|
let id = ServiceId {
|
||||||
|
name: name.into(),
|
||||||
|
service_type: service_type.into(),
|
||||||
|
port,
|
||||||
|
};
|
||||||
|
|
||||||
|
if self.services.remove(&id).is_some() {
|
||||||
|
info!(
|
||||||
|
"Deregistering mDNS service {}/{}/{}",
|
||||||
|
name, service_type, port
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mdns for LibMdns {
|
||||||
|
fn add(
|
||||||
|
&mut self,
|
||||||
|
name: &str,
|
||||||
|
service_type: &str,
|
||||||
|
port: u16,
|
||||||
|
_service_subtypes: &[&str],
|
||||||
|
txt_kvs: &[(&str, &str)],
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
LibMdns::add(self, name, service_type, port, txt_kvs)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove(&mut self, name: &str, service_type: &str, port: u16) -> Result<(), Error> {
|
||||||
|
LibMdns::remove(self, name, service_type, port)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// #[cfg(feature = "std")]
|
||||||
|
// pub mod simplemdns {
|
||||||
|
// use std::net::Ipv4Addr;
|
||||||
|
|
||||||
|
// use crate::error::Error;
|
||||||
|
// use super::Mdns;
|
||||||
|
// use log::info;
|
||||||
|
// use simple_dns::{
|
||||||
|
// rdata::{RData, A, SRV, TXT, PTR},
|
||||||
|
// CharacterString, Name, ResourceRecord, CLASS,
|
||||||
|
// };
|
||||||
|
// use simple_mdns::sync_discovery::SimpleMdnsResponder;
|
||||||
|
|
||||||
|
// #[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||||
|
// pub struct ServiceId {
|
||||||
|
// name: String,
|
||||||
|
// service_type: String,
|
||||||
|
// port: u16,
|
||||||
|
// }
|
||||||
|
|
||||||
|
// pub struct SimpleMdns {
|
||||||
|
// responder: SimpleMdnsResponder,
|
||||||
|
// }
|
||||||
|
|
||||||
|
// impl SimpleMdns {
|
||||||
|
// pub fn new() -> Result<Self, Error> {
|
||||||
|
// Ok(Self {
|
||||||
|
// responder: Default::default(),
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
|
// pub fn add(
|
||||||
|
// &mut self,
|
||||||
|
// name: &str,
|
||||||
|
// service_type: &str,
|
||||||
|
// port: u16,
|
||||||
|
// txt_kvs: &[(&str, &str)],
|
||||||
|
// ) -> Result<(), Error> {
|
||||||
|
// info!(
|
||||||
|
// "Registering mDNS service {}/{}/{}",
|
||||||
|
// name, service_type, port
|
||||||
|
// );
|
||||||
|
|
||||||
|
// let _ = self.remove(name, service_type, port);
|
||||||
|
|
||||||
|
// let mut txt = TXT::new();
|
||||||
|
// for kvs in txt_kvs {
|
||||||
|
// info!("mDNS TXT key {} val {}", kvs.0, kvs.1);
|
||||||
|
|
||||||
|
// let string = format!("{}={}", kvs.0, kvs.1);
|
||||||
|
// txt.add_char_string(
|
||||||
|
// CharacterString::new(string.as_bytes())
|
||||||
|
// .unwrap()
|
||||||
|
// .into_owned(),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// let name = Name::new_unchecked(name).into_owned();
|
||||||
|
// let service_type = Name::new_unchecked(service_type).into_owned();
|
||||||
|
|
||||||
|
// self.responder.add_resource(ResourceRecord::new(
|
||||||
|
// name.clone(),
|
||||||
|
// CLASS::IN,
|
||||||
|
// 10,
|
||||||
|
// RData::A(A {
|
||||||
|
// address: Ipv4Addr::new(192, 168, 10, 189).into(),
|
||||||
|
// }),
|
||||||
|
// ));
|
||||||
|
|
||||||
|
// self.responder.add_resource(ResourceRecord::new(
|
||||||
|
// name.clone(),
|
||||||
|
// CLASS::IN,
|
||||||
|
// 10,
|
||||||
|
// RData::SRV(SRV {
|
||||||
|
// port: port,
|
||||||
|
// priority: 0,
|
||||||
|
// weight: 0,
|
||||||
|
// target: service_type.clone(),
|
||||||
|
// }),
|
||||||
|
// ));
|
||||||
|
|
||||||
|
// self.responder.add_resource(ResourceRecord::new(
|
||||||
|
// srv_name.clone(),
|
||||||
|
// CLASS::IN,
|
||||||
|
// 10,
|
||||||
|
// RData::PTR(PTR(srv_name.clone()),
|
||||||
|
// )));
|
||||||
|
|
||||||
|
// self.responder.add_resource(ResourceRecord::new(
|
||||||
|
// srv_name,
|
||||||
|
// CLASS::IN,
|
||||||
|
// 10,
|
||||||
|
// RData::TXT(txt),
|
||||||
|
// ));
|
||||||
|
|
||||||
|
// Ok(())
|
||||||
|
// }
|
||||||
|
|
||||||
|
// pub fn remove(&mut self, name: &str, service_type: &str, port: u16) -> Result<(), Error> {
|
||||||
|
// // TODO
|
||||||
|
// // let id = ServiceId {
|
||||||
|
// // name: name.into(),
|
||||||
|
// // service_type: service_type.into(),
|
||||||
|
// // port,
|
||||||
|
// // };
|
||||||
|
|
||||||
|
// // if self.responder.remove_resource_record(resource).remove(&id).is_some() {
|
||||||
|
// // info!(
|
||||||
|
// // "Deregistering mDNS service {}/{}/{}",
|
||||||
|
// // name, service_type, port
|
||||||
|
// // );
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// Ok(())
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// impl Mdns for SimpleMdns {
|
||||||
|
// fn add(
|
||||||
|
// &mut self,
|
||||||
|
// name: &str,
|
||||||
|
// service_type: &str,
|
||||||
|
// port: u16,
|
||||||
|
// _service_subtypes: &[&str],
|
||||||
|
// txt_kvs: &[(&str, &str)],
|
||||||
|
// ) -> Result<(), Error> {
|
||||||
|
// SimpleMdns::add(self, name, service_type, port, txt_kvs)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn remove(&mut self, name: &str, service_type: &str, port: u16) -> Result<(), Error> {
|
||||||
|
// SimpleMdns::remove(self, name, service_type, port)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -315,10 +315,7 @@ fn estimate_struct_overhead(first_field_size: usize) -> usize {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn print_qr_code(qr_data: &str) {
|
pub(super) fn print_qr_code(qr_data: &str) {
|
||||||
#[cfg(not(feature = "std"))]
|
info!("QR Code: {}", qr_data);
|
||||||
{
|
|
||||||
info!("\n QR CODE DATA: {}", qr_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
crypto::{self, HmacSha256},
|
crypto::{self, HmacSha256},
|
||||||
sys,
|
|
||||||
utils::rand::Rand,
|
utils::rand::Rand,
|
||||||
};
|
};
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
|
@ -31,7 +30,7 @@ use crate::{
|
||||||
|
|
||||||
use super::{common::SCStatusCodes, crypto::CryptoSpake2};
|
use super::{common::SCStatusCodes, crypto::CryptoSpake2};
|
||||||
|
|
||||||
// This file handle Spake2+ specific instructions. In itself, this file is
|
// This file handles Spake2+ specific instructions. In itself, this file is
|
||||||
// independent from the BigNum and EC operations that are typically required
|
// independent from the BigNum and EC operations that are typically required
|
||||||
// Spake2+. We use the CryptoSpake2 trait object that allows us to abstract
|
// Spake2+. We use the CryptoSpake2 trait object that allows us to abstract
|
||||||
// out the specific implementations.
|
// out the specific implementations.
|
||||||
|
@ -39,6 +38,8 @@ use super::{common::SCStatusCodes, crypto::CryptoSpake2};
|
||||||
// In the case of the verifier, we don't actually release the Ke until we
|
// In the case of the verifier, we don't actually release the Ke until we
|
||||||
// validate that the cA is confirmed.
|
// validate that the cA is confirmed.
|
||||||
|
|
||||||
|
pub const SPAKE2_ITERATION_COUNT: u32 = 2000;
|
||||||
|
|
||||||
#[derive(PartialEq, Copy, Clone, Debug)]
|
#[derive(PartialEq, Copy, Clone, Debug)]
|
||||||
pub enum Spake2VerifierState {
|
pub enum Spake2VerifierState {
|
||||||
// Initialised - w0, L are set
|
// Initialised - w0, L are set
|
||||||
|
@ -104,7 +105,7 @@ impl VerifierData {
|
||||||
pub fn new_with_pw(pw: u32, rand: Rand) -> Self {
|
pub fn new_with_pw(pw: u32, rand: Rand) -> Self {
|
||||||
let mut s = Self {
|
let mut s = Self {
|
||||||
salt: [0; MAX_SALT_SIZE_BYTES],
|
salt: [0; MAX_SALT_SIZE_BYTES],
|
||||||
count: sys::SPAKE2_ITERATION_COUNT,
|
count: SPAKE2_ITERATION_COUNT,
|
||||||
data: VerifierOption::Password(pw),
|
data: VerifierOption::Password(pw),
|
||||||
};
|
};
|
||||||
rand(&mut s.salt);
|
rand(&mut s.salt);
|
||||||
|
|
|
@ -15,18 +15,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#[cfg(all(feature = "std", target_os = "macos"))]
|
|
||||||
mod sys_macos;
|
|
||||||
#[cfg(all(feature = "std", target_os = "macos"))]
|
|
||||||
pub use self::sys_macos::*;
|
|
||||||
|
|
||||||
#[cfg(all(feature = "std", target_os = "linux"))]
|
|
||||||
mod sys_linux;
|
|
||||||
#[cfg(all(feature = "std", target_os = "linux"))]
|
|
||||||
pub use self::sys_linux::*;
|
|
||||||
|
|
||||||
pub const SPAKE2_ITERATION_COUNT: u32 = 2000;
|
|
||||||
|
|
||||||
// The Packet Pool that is allocated from. POSIX systems can use
|
// The Packet Pool that is allocated from. POSIX systems can use
|
||||||
// higher values unlike embedded systems
|
// higher values unlike embedded systems
|
||||||
pub const MAX_PACKET_POOL_SIZE: usize = 25;
|
pub const MAX_PACKET_POOL_SIZE: usize = 25;
|
||||||
|
|
|
@ -1,116 +0,0 @@
|
||||||
/*
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020-2022 Project CHIP Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
use crate::error::Error;
|
|
||||||
use crate::mdns::Mdns;
|
|
||||||
use libmdns::{Responder, Service};
|
|
||||||
use log::info;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::vec::Vec;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
|
||||||
pub struct ServiceId {
|
|
||||||
name: String,
|
|
||||||
service_type: String,
|
|
||||||
port: u16,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct LinuxMdns {
|
|
||||||
responder: Responder,
|
|
||||||
services: HashMap<ServiceId, Service>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LinuxMdns {
|
|
||||||
pub fn new() -> Result<Self, Error> {
|
|
||||||
let responder = Responder::new()?;
|
|
||||||
|
|
||||||
Ok(Self {
|
|
||||||
responder,
|
|
||||||
services: HashMap::new(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add(
|
|
||||||
&mut self,
|
|
||||||
name: &str,
|
|
||||||
service_type: &str,
|
|
||||||
port: u16,
|
|
||||||
txt_kvs: &[(&str, &str)],
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
info!(
|
|
||||||
"Registering mDNS service {}/{}/{}",
|
|
||||||
name, service_type, port
|
|
||||||
);
|
|
||||||
|
|
||||||
let _ = self.remove(name, service_type, port);
|
|
||||||
|
|
||||||
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 service =
|
|
||||||
self.responder
|
|
||||||
.register(service_type.to_owned(), name.to_owned(), port, &properties);
|
|
||||||
|
|
||||||
self.services.insert(
|
|
||||||
ServiceId {
|
|
||||||
name: name.into(),
|
|
||||||
service_type: service_type.into(),
|
|
||||||
port,
|
|
||||||
},
|
|
||||||
service,
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn remove(&mut self, name: &str, service_type: &str, port: u16) -> Result<(), Error> {
|
|
||||||
let id = ServiceId {
|
|
||||||
name: name.into(),
|
|
||||||
service_type: service_type.into(),
|
|
||||||
port,
|
|
||||||
};
|
|
||||||
|
|
||||||
if self.services.remove(&id).is_some() {
|
|
||||||
info!(
|
|
||||||
"Deregistering mDNS service {}/{}/{}",
|
|
||||||
name, service_type, port
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Mdns for LinuxMdns {
|
|
||||||
fn add(
|
|
||||||
&mut self,
|
|
||||||
name: &str,
|
|
||||||
service_type: &str,
|
|
||||||
port: u16,
|
|
||||||
txt_kvs: &[(&str, &str)],
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
LinuxMdns::add(self, name, service_type, port, txt_kvs)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove(&mut self, name: &str, service_type: &str, port: u16) -> Result<(), Error> {
|
|
||||||
LinuxMdns::remove(self, name, service_type, port)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,109 +0,0 @@
|
||||||
/*
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020-2022 Project CHIP Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use crate::{error::Error, mdns::Mdns};
|
|
||||||
use astro_dnssd::{DNSServiceBuilder, RegisteredDnsService};
|
|
||||||
use log::info;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
|
||||||
pub struct ServiceId {
|
|
||||||
name: String,
|
|
||||||
service_type: String,
|
|
||||||
port: u16,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct MacOsMdns {
|
|
||||||
services: HashMap<RegisteredDnsService, RegisteredDnsService>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MacOsMdns {
|
|
||||||
pub fn new() -> Result<Self, Error> {
|
|
||||||
Ok(Self {
|
|
||||||
services: HashMap::new(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add(
|
|
||||||
&mut self,
|
|
||||||
name: &str,
|
|
||||||
service_type: &str,
|
|
||||||
port: u16,
|
|
||||||
txt_kvs: &[(&str, &str)],
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
info!(
|
|
||||||
"Registering mDNS service {}/{}/{}",
|
|
||||||
name, service_type, port
|
|
||||||
);
|
|
||||||
|
|
||||||
let _ = self.remove(name, service_type, port);
|
|
||||||
|
|
||||||
let mut builder = DNSServiceBuilder::new(service_type, port).with_name(name);
|
|
||||||
|
|
||||||
for kvs in txt_kvs {
|
|
||||||
info!("mDNS TXT key {} val {}", kvs.0, kvs.1);
|
|
||||||
builder = builder.with_key_value(kvs.0.to_string(), kvs.1.to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
let service = builder.register().map_err(|_| Error::MdnsError)?;
|
|
||||||
|
|
||||||
self.services.insert(
|
|
||||||
ServiceId {
|
|
||||||
name: name.into(),
|
|
||||||
service_type: service_type.into(),
|
|
||||||
port,
|
|
||||||
},
|
|
||||||
service,
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn remove(&mut self, name: &str, service_type: &str, port: u16) -> Result<(), Error> {
|
|
||||||
let id = ServiceId {
|
|
||||||
name: name.into(),
|
|
||||||
service_type: service_type.into(),
|
|
||||||
port,
|
|
||||||
};
|
|
||||||
|
|
||||||
if self.services.remove(&id).is_some() {
|
|
||||||
info!(
|
|
||||||
"Deregistering mDNS service {}/{}/{}",
|
|
||||||
name, service_type, port
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Mdns for MacOsMdns {
|
|
||||||
fn add(
|
|
||||||
&mut self,
|
|
||||||
name: &str,
|
|
||||||
service_type: &str,
|
|
||||||
port: u16,
|
|
||||||
txt_kvs: &[(&str, &str)],
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
MacOsMdns::add(self, name, service_type, port, txt_kvs)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove(&mut self, name: &str, service_type: &str, port: u16) -> Result<(), Error> {
|
|
||||||
MacOsMdns::remove(self, name, service_type, port)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -16,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::error::*;
|
use crate::error::*;
|
||||||
use log::info;
|
use log::{info, warn};
|
||||||
use smol::net::{Ipv6Addr, UdpSocket};
|
use smol::net::{Ipv6Addr, UdpSocket};
|
||||||
|
|
||||||
use super::network::Address;
|
use super::network::Address;
|
||||||
|
@ -35,25 +35,50 @@ pub const MATTER_PORT: u16 = 5540;
|
||||||
|
|
||||||
impl UdpListener {
|
impl UdpListener {
|
||||||
pub async fn new() -> Result<UdpListener, Error> {
|
pub async fn new() -> Result<UdpListener, Error> {
|
||||||
Ok(UdpListener {
|
let listener = UdpListener {
|
||||||
socket: UdpSocket::bind((Ipv6Addr::UNSPECIFIED, MATTER_PORT)).await?,
|
socket: UdpSocket::bind((Ipv6Addr::UNSPECIFIED, MATTER_PORT)).await?,
|
||||||
})
|
};
|
||||||
|
|
||||||
|
info!(
|
||||||
|
"Listening on {:?} port {}",
|
||||||
|
Ipv6Addr::UNSPECIFIED,
|
||||||
|
MATTER_PORT
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn recv(&self, in_buf: &mut [u8]) -> Result<(usize, Address), Error> {
|
pub async fn recv(&self, in_buf: &mut [u8]) -> Result<(usize, Address), Error> {
|
||||||
|
info!("Waiting for incoming packets");
|
||||||
|
|
||||||
let (size, addr) = self.socket.recv_from(in_buf).await.map_err(|e| {
|
let (size, addr) = self.socket.recv_from(in_buf).await.map_err(|e| {
|
||||||
info!("Error on the network: {:?}", e);
|
warn!("Error on the network: {:?}", e);
|
||||||
Error::Network
|
Error::Network
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
info!("Got packet: {:?} from addr {:?}", in_buf, addr);
|
||||||
|
|
||||||
Ok((size, Address::Udp(addr)))
|
Ok((size, Address::Udp(addr)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send(&self, addr: Address, out_buf: &[u8]) -> Result<usize, Error> {
|
pub async fn send(&self, addr: Address, out_buf: &[u8]) -> Result<usize, Error> {
|
||||||
match addr {
|
match addr {
|
||||||
Address::Udp(addr) => self.socket.send_to(out_buf, addr).await.map_err(|e| {
|
Address::Udp(addr) => {
|
||||||
info!("Error on the network: {:?}", e);
|
let len = self.socket.send_to(out_buf, addr).await.map_err(|e| {
|
||||||
Error::Network
|
warn!("Error on the network: {:?}", e);
|
||||||
}),
|
Error::Network
|
||||||
|
})?;
|
||||||
|
|
||||||
|
info!(
|
||||||
|
"Send packet: {:?} ({}/{}) to addr {:?}",
|
||||||
|
out_buf,
|
||||||
|
out_buf.len(),
|
||||||
|
len,
|
||||||
|
addr
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(len)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue