diff --git a/examples/onoff_light/src/main.rs b/examples/onoff_light/src/main.rs index ad36f07..000bc0e 100644 --- a/examples/onoff_light/src/main.rs +++ b/examples/onoff_light/src/main.rs @@ -37,6 +37,7 @@ fn main() { pid: 0x8002, hw_ver: 2, sw_ver: 1, + device_name: "OnOff Light".to_string(), }; let dev_att = Box::new(dev_att::HardCodedDevAtt::new()); diff --git a/matter/src/core.rs b/matter/src/core.rs index 6aee3ce..30dcf9d 100644 --- a/matter/src/core.rs +++ b/matter/src/core.rs @@ -62,7 +62,12 @@ impl Matter { dev_comm: &CommissioningData, ) -> Result, Error> { let mdns = Mdns::get()?; - mdns.set_values(dev_det.vid, dev_det.pid, dev_comm.discriminator); + mdns.set_values( + dev_det.vid, + dev_det.pid, + dev_comm.discriminator, + &dev_det.device_name, + ); let fabric_mgr = Arc::new(FabricMgr::new()?); let acl_mgr = Arc::new(AclMgr::new()?); diff --git a/matter/src/data_model/cluster_basic_information.rs b/matter/src/data_model/cluster_basic_information.rs index c480f48..10a2b34 100644 --- a/matter/src/data_model/cluster_basic_information.rs +++ b/matter/src/data_model/cluster_basic_information.rs @@ -31,6 +31,8 @@ pub struct BasicInfoConfig { pub pid: u16, pub hw_ver: u16, pub sw_ver: u32, + /// Device name; up to 32 characters + pub device_name: String, } fn attr_vid_new(vid: u16) -> Result { diff --git a/matter/src/lib.rs b/matter/src/lib.rs index ad677b5..2d2bee2 100644 --- a/matter/src/lib.rs +++ b/matter/src/lib.rs @@ -51,6 +51,7 @@ //! pid: 0xFFF1, //! hw_ver: 2, //! sw_ver: 1, +//! device_name: "OnOff Light".to_string(), //! }; //! //! /// Get the Matter Object diff --git a/matter/src/mdns.rs b/matter/src/mdns.rs index c1180a6..07f464a 100644 --- a/matter/src/mdns.rs +++ b/matter/src/mdns.rs @@ -1,20 +1,3 @@ -/* - * - * 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::sync::{Arc, Mutex, Once}; use crate::{ @@ -32,19 +15,20 @@ pub struct MdnsInner { pid: u16, /// Discriminator discriminator: u16, + /// Device name + device_name: String, } pub struct Mdns { inner: Mutex, } -const SHORT_DISCRIMINATOR_MASK: u16 = 0x700; +const SHORT_DISCRIMINATOR_MASK: u16 = 0xF00; const SHORT_DISCRIMINATOR_SHIFT: u16 = 8; static mut G_MDNS: Option> = None; static INIT: Once = Once::new(); -#[derive(Clone, Copy)] pub enum ServiceMode { Commissioned, Commissionable, @@ -72,16 +56,18 @@ impl Mdns { /// Set mDNS service specific values /// Values like vid, pid, discriminator etc // TODO: More things like device-type etc can be added here - pub fn set_values(&self, vid: u16, pid: u16, discriminator: u16) { + pub fn set_values(&self, vid: u16, pid: u16, discriminator: u16, device_name: &str) { let mut inner = self.inner.lock().unwrap(); inner.vid = vid; inner.pid = pid; inner.discriminator = discriminator; + inner.device_name = device_name.chars().take(32).collect(); } /// Publish a mDNS service /// name - is the service name (comma separated subtypes may follow) /// mode - the current service mode + #[allow(clippy::needless_pass_by_value)] pub fn publish_service(&self, name: &str, mode: ServiceMode) -> Result { match mode { ServiceMode::Commissioned => { @@ -89,14 +75,43 @@ impl Mdns { } ServiceMode::Commissionable => { let inner = self.inner.lock().unwrap(); - let short = - (inner.discriminator & SHORT_DISCRIMINATOR_MASK) >> SHORT_DISCRIMINATOR_SHIFT; + let short = compute_short_discriminator(inner.discriminator); let serv_type = format!("_matterc._udp,_S{},_L{}", short, inner.discriminator); let str_discriminator = format!("{}", inner.discriminator); - let txt_kvs = [["D", &str_discriminator], ["CM", "1"]]; + let txt_kvs = [ + ["D", &str_discriminator], + ["CM", "1"], + ["DN", &inner.device_name], + ["VP", &format!("{}+{}", inner.vid, inner.pid)], + ["SII", "5000"], /* Sleepy Idle Interval */ + ["SAI", "300"], /* Sleepy Active Interval */ + ["T", "1"], /* TCP supported */ + ["PH", "33"], /* Pairing Hint */ + ["PI", ""], /* Pairing Instruction */ + ]; sys_publish_service(name, &serv_type, MATTER_PORT, &txt_kvs) } } } } + +fn compute_short_discriminator(discriminator: u16) -> u16 { + (discriminator & SHORT_DISCRIMINATOR_MASK) >> SHORT_DISCRIMINATOR_SHIFT +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn can_compute_short_discriminator() { + let discriminator: u16 = 0b0000_1111_0000_0000; + let short = compute_short_discriminator(discriminator); + assert_eq!(short, 0b1111); + + let discriminator: u16 = 840; + let short = compute_short_discriminator(discriminator); + assert_eq!(short, 3); + } +} diff --git a/matter/tests/common/im_engine.rs b/matter/tests/common/im_engine.rs index 81c2c74..19cb6af 100644 --- a/matter/tests/common/im_engine.rs +++ b/matter/tests/common/im_engine.rs @@ -93,7 +93,9 @@ impl ImEngine { pid: 11, hw_ver: 12, sw_ver: 13, + device_name: "Test Device".to_string(), }; + let dev_att = Box::new(DummyDevAtt {}); let fabric_mgr = Arc::new(FabricMgr::new().unwrap()); let acl_mgr = Arc::new(AclMgr::new_with(false).unwrap());