Extend service discovery information

This commit is contained in:
Marcel 2023-01-10 13:14:20 +01:00
parent b477a871e9
commit ba524e1190
6 changed files with 50 additions and 24 deletions

View file

@ -37,6 +37,7 @@ fn main() {
pid: 0x8002, pid: 0x8002,
hw_ver: 2, hw_ver: 2,
sw_ver: 1, sw_ver: 1,
device_name: "OnOff Light".to_string(),
}; };
let dev_att = Box::new(dev_att::HardCodedDevAtt::new()); let dev_att = Box::new(dev_att::HardCodedDevAtt::new());

View file

@ -62,7 +62,12 @@ impl Matter {
dev_comm: &CommissioningData, dev_comm: &CommissioningData,
) -> Result<Box<Matter>, Error> { ) -> Result<Box<Matter>, Error> {
let mdns = Mdns::get()?; 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 fabric_mgr = Arc::new(FabricMgr::new()?);
let acl_mgr = Arc::new(AclMgr::new()?); let acl_mgr = Arc::new(AclMgr::new()?);

View file

@ -31,6 +31,8 @@ pub struct BasicInfoConfig {
pub pid: u16, pub pid: u16,
pub hw_ver: u16, pub hw_ver: u16,
pub sw_ver: u32, pub sw_ver: u32,
/// Device name; up to 32 characters
pub device_name: String,
} }
fn attr_vid_new(vid: u16) -> Result<Attribute, Error> { fn attr_vid_new(vid: u16) -> Result<Attribute, Error> {

View file

@ -51,6 +51,7 @@
//! pid: 0xFFF1, //! pid: 0xFFF1,
//! hw_ver: 2, //! hw_ver: 2,
//! sw_ver: 1, //! sw_ver: 1,
//! device_name: "OnOff Light".to_string(),
//! }; //! };
//! //!
//! /// Get the Matter Object //! /// Get the Matter Object

View file

@ -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 std::sync::{Arc, Mutex, Once};
use crate::{ use crate::{
@ -32,19 +15,20 @@ pub struct MdnsInner {
pid: u16, pid: u16,
/// Discriminator /// Discriminator
discriminator: u16, discriminator: u16,
/// Device name
device_name: String,
} }
pub struct Mdns { pub struct Mdns {
inner: Mutex<MdnsInner>, inner: Mutex<MdnsInner>,
} }
const SHORT_DISCRIMINATOR_MASK: u16 = 0x700; const SHORT_DISCRIMINATOR_MASK: u16 = 0xF00;
const SHORT_DISCRIMINATOR_SHIFT: u16 = 8; const SHORT_DISCRIMINATOR_SHIFT: u16 = 8;
static mut G_MDNS: Option<Arc<Mdns>> = None; static mut G_MDNS: Option<Arc<Mdns>> = None;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
#[derive(Clone, Copy)]
pub enum ServiceMode { pub enum ServiceMode {
Commissioned, Commissioned,
Commissionable, Commissionable,
@ -72,16 +56,18 @@ impl Mdns {
/// Set mDNS service specific values /// Set mDNS service specific values
/// Values like vid, pid, discriminator etc /// Values like vid, pid, discriminator etc
// TODO: More things like device-type etc can be added here // 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(); let mut inner = self.inner.lock().unwrap();
inner.vid = vid; inner.vid = vid;
inner.pid = pid; inner.pid = pid;
inner.discriminator = discriminator; inner.discriminator = discriminator;
inner.device_name = device_name.chars().take(32).collect();
} }
/// Publish a mDNS service /// Publish a mDNS service
/// name - is the service name (comma separated subtypes may follow) /// name - is the service name (comma separated subtypes may follow)
/// mode - the current service mode /// mode - the current service mode
#[allow(clippy::needless_pass_by_value)]
pub fn publish_service(&self, name: &str, mode: ServiceMode) -> Result<SysMdnsService, Error> { pub fn publish_service(&self, name: &str, mode: ServiceMode) -> Result<SysMdnsService, Error> {
match mode { match mode {
ServiceMode::Commissioned => { ServiceMode::Commissioned => {
@ -89,14 +75,43 @@ impl Mdns {
} }
ServiceMode::Commissionable => { ServiceMode::Commissionable => {
let inner = self.inner.lock().unwrap(); let inner = self.inner.lock().unwrap();
let short = let short = compute_short_discriminator(inner.discriminator);
(inner.discriminator & SHORT_DISCRIMINATOR_MASK) >> SHORT_DISCRIMINATOR_SHIFT;
let serv_type = format!("_matterc._udp,_S{},_L{}", short, inner.discriminator); let serv_type = format!("_matterc._udp,_S{},_L{}", short, inner.discriminator);
let str_discriminator = format!("{}", 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) 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);
}
}

View file

@ -93,7 +93,9 @@ impl ImEngine {
pid: 11, pid: 11,
hw_ver: 12, hw_ver: 12,
sw_ver: 13, sw_ver: 13,
device_name: "Test Device".to_string(),
}; };
let dev_att = Box::new(DummyDevAtt {}); let dev_att = Box::new(DummyDevAtt {});
let fabric_mgr = Arc::new(FabricMgr::new().unwrap()); let fabric_mgr = Arc::new(FabricMgr::new().unwrap());
let acl_mgr = Arc::new(AclMgr::new_with(false).unwrap()); let acl_mgr = Arc::new(AclMgr::new_with(false).unwrap());