From 263279e714f84199a0e5d81a22037db162903d78 Mon Sep 17 00:00:00 2001 From: ivmarkov Date: Tue, 18 Jul 2023 10:20:40 +0000 Subject: [PATCH] Make multicast ipv6 optional --- examples/onoff_light/src/main.rs | 3 +- matter/Cargo.toml | 15 +++---- matter/src/data_model/core.rs | 2 +- matter/src/mdns/astro.rs | 3 +- matter/src/mdns/builtin.rs | 70 +++++++++++++++++++------------- 5 files changed, 53 insertions(+), 40 deletions(-) diff --git a/examples/onoff_light/src/main.rs b/examples/onoff_light/src/main.rs index 1b882ac..3f2d890 100644 --- a/examples/onoff_light/src/main.rs +++ b/examples/onoff_light/src/main.rs @@ -101,8 +101,7 @@ fn run() -> Result<(), Error> { 0, "matter-demo", ipv4_addr.octets(), - Some(ipv6_addr.octets()), - interface, + Some((ipv6_addr.octets(), interface)), &dev_det, matter::MATTER_PORT, ); diff --git a/matter/Cargo.toml b/matter/Cargo.toml index 46e16c9..05fd6b8 100644 --- a/matter/Cargo.toml +++ b/matter/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "matter-iot" version = "0.1.0" -edition = "2018" +edition = "2021" authors = ["Kedar Sovani "] description = "Native RUST implementation of the Matter (Smart-Home) ecosystem" repository = "https://github.com/kedars/matter-rs" @@ -17,7 +17,8 @@ path = "src/lib.rs" [features] default = ["os", "crypto_rustcrypto"] os = ["std", "backtrace", "env_logger", "nix", "critical-section/std", "embassy-sync/std", "embassy-time/std"] -std = ["alloc", "rand", "qrcode", "async-io", "esp-idf-sys/std"] +esp-idf = ["std", "crypto_rustcrypto", "esp-idf-sys", "esp-idf-hal", "esp-idf-svc"] +std = ["alloc", "rand", "qrcode", "async-io", "esp-idf-sys?/std", "embassy-time/generic-queue-16"] backtrace = [] alloc = [] nightly = [] @@ -43,10 +44,11 @@ owo-colors = "3" time = { version = "0.3", default-features = false } verhoeff = { version = "1", default-features = false } embassy-futures = "0.1" -embassy-time = { version = "0.1.1", features = ["generic-queue-8"] } +embassy-time = "0.1.1" embassy-sync = "0.2" critical-section = "1.1.1" domain = { version = "0.7.2", default_features = false, features = ["heapless"] } +portable-atomic = "1" # embassy-net dependencies embassy-net = { version = "0.1", features = ["udp", "igmp", "proto-ipv6", "medium-ethernet", "medium-ip"], optional = true } @@ -84,10 +86,9 @@ env_logger = { version = "0.10.0", optional = true } nix = { version = "0.26", features = ["net"], optional = true } [target.'cfg(target_os = "espidf")'.dependencies] -esp-idf-sys = { version = "0.33", default-features = false, features = ["native", "binstart"] } -esp-idf-hal = { version = "0.41", features = ["embassy-sync", "critical-section"] } -esp-idf-svc = { version = "0.46", features = ["embassy-time-driver"] } -embedded-svc = "0.25" +esp-idf-sys = { version = "0.33", optional = true, default-features = false, features = ["native", "binstart"] } +esp-idf-hal = { version = "0.41", optional = true, features = ["embassy-sync", "critical-section"] } # TODO: Only necessary for the examples +esp-idf-svc = { version = "0.46", optional = true, features = ["embassy-time-driver"] } # TODO: Only necessary for the examples [build-dependencies] embuild = "0.31.2" diff --git a/matter/src/data_model/core.rs b/matter/src/data_model/core.rs index 69935c5..0a4e99a 100644 --- a/matter/src/data_model/core.rs +++ b/matter/src/data_model/core.rs @@ -15,7 +15,7 @@ * limitations under the License. */ -use core::sync::atomic::{AtomicU32, Ordering}; +use portable_atomic::{AtomicU32, Ordering}; use super::objects::*; use crate::{ diff --git a/matter/src/mdns/astro.rs b/matter/src/mdns/astro.rs index 857fb46..1ac4331 100644 --- a/matter/src/mdns/astro.rs +++ b/matter/src/mdns/astro.rs @@ -23,8 +23,7 @@ impl<'a> MdnsService<'a> { _id: u16, _hostname: &str, _ip: [u8; 4], - _ipv6: Option<[u8; 16]>, - _interface: u32, + _ipv6: Option<([u8; 16], u32)>, dev_det: &'a BasicInfoConfig<'a>, matter_port: u16, ) -> Self { diff --git a/matter/src/mdns/builtin.rs b/matter/src/mdns/builtin.rs index c3049a5..9845b20 100644 --- a/matter/src/mdns/builtin.rs +++ b/matter/src/mdns/builtin.rs @@ -25,7 +25,7 @@ const PORT: u16 = 5353; pub struct MdnsService<'a> { host: Host<'a>, #[allow(unused)] - interface: u32, + interface: Option, dev_det: &'a BasicInfoConfig<'a>, matter_port: u16, services: RefCell, ServiceMode), 4>>, @@ -38,8 +38,7 @@ impl<'a> MdnsService<'a> { id: u16, hostname: &'a str, ip: [u8; 4], - ipv6: Option<[u8; 16]>, - interface: u32, + ipv6: Option<([u8; 16], u32)>, dev_det: &'a BasicInfoConfig<'a>, matter_port: u16, ) -> Self { @@ -48,9 +47,17 @@ impl<'a> MdnsService<'a> { id, hostname, ip, - ipv6, + ipv6: if let Some((ipv6, _)) = ipv6 { + Some(ipv6) + } else { + None + }, + }, + interface: if let Some((_, interface)) = ipv6 { + Some(interface) + } else { + None }, - interface, dev_det, matter_port, services: RefCell::new(heapless::Vec::new()), @@ -137,8 +144,13 @@ impl<'a> MdnsRunner<'a> { ) .await?; - udp.join_multicast_v6(IPV6_BROADCAST_ADDR, self.0.interface) - .await?; + // V6 multicast does not work with smoltcp yet (see https://github.com/smoltcp-rs/smoltcp/pull/602) + #[cfg(not(feature = "embassy-net"))] + if let Some(interface) = self.0.interface { + udp.join_multicast_v6(IPV6_BROADCAST_ADDR, interface) + .await?; + } + udp.join_multicast_v4( IP_BROADCAST_ADDR, crate::transport::network::Ipv4Addr::from(self.0.host.ip), @@ -217,35 +229,37 @@ impl<'a> MdnsRunner<'a> { IpAddr::V4(IP_BROADCAST_ADDR), IpAddr::V6(IPV6_BROADCAST_ADDR), ] { - loop { - let sent = { - let mut data = tx_pipe.data.lock().await; + if self.0.interface.is_some() || addr == IpAddr::V4(IP_BROADCAST_ADDR) { + loop { + let sent = { + let mut data = tx_pipe.data.lock().await; - if data.chunk.is_none() { - let len = self.0.host.broadcast(&self.0, data.buf, 60)?; + if data.chunk.is_none() { + let len = self.0.host.broadcast(&self.0, data.buf, 60)?; - if len > 0 { - info!("Broadasting mDNS entry to {}:{}", addr, PORT); + if len > 0 { + info!("Broadasting mDNS entry to {}:{}", addr, PORT); - data.chunk = Some(Chunk { - start: 0, - end: len, - addr: Address::Udp(SocketAddr::new(addr, PORT)), - }); + data.chunk = Some(Chunk { + start: 0, + end: len, + addr: Address::Udp(SocketAddr::new(addr, PORT)), + }); - tx_pipe.data_supplied_notification.signal(()); + tx_pipe.data_supplied_notification.signal(()); + } + + true + } else { + false } + }; - true + if sent { + break; } else { - false + tx_pipe.data_consumed_notification.wait().await; } - }; - - if sent { - break; - } else { - tx_pipe.data_consumed_notification.wait().await; } } }