matc/clusters/codec/
thread_network_directory.rs

1//! Generated Matter TLV encoders and decoders for Thread Network Directory Cluster
2//! Cluster ID: 0x0453
3//! 
4//! This file is automatically generated from ThreadNetworkDirectory.xml
5
6use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11// Struct definitions
12
13#[derive(Debug, serde::Serialize)]
14pub struct ThreadNetwork {
15    pub extended_pan_id: Option<Vec<u8>>,
16    pub network_name: Option<String>,
17    pub channel: Option<u16>,
18    pub active_timestamp: Option<u64>,
19}
20
21// Command encoders
22
23/// Encode AddNetwork command (0x00)
24pub fn encode_add_network(operational_dataset: Vec<u8>) -> anyhow::Result<Vec<u8>> {
25    let tlv = tlv::TlvItemEnc {
26        tag: 0,
27        value: tlv::TlvItemValueEnc::StructInvisible(vec![
28        (0, tlv::TlvItemValueEnc::OctetString(operational_dataset)).into(),
29        ]),
30    };
31    Ok(tlv.encode()?)
32}
33
34/// Encode RemoveNetwork command (0x01)
35pub fn encode_remove_network(extended_pan_id: Vec<u8>) -> anyhow::Result<Vec<u8>> {
36    let tlv = tlv::TlvItemEnc {
37        tag: 0,
38        value: tlv::TlvItemValueEnc::StructInvisible(vec![
39        (0, tlv::TlvItemValueEnc::OctetString(extended_pan_id)).into(),
40        ]),
41    };
42    Ok(tlv.encode()?)
43}
44
45/// Encode GetOperationalDataset command (0x02)
46pub fn encode_get_operational_dataset(extended_pan_id: Vec<u8>) -> anyhow::Result<Vec<u8>> {
47    let tlv = tlv::TlvItemEnc {
48        tag: 0,
49        value: tlv::TlvItemValueEnc::StructInvisible(vec![
50        (0, tlv::TlvItemValueEnc::OctetString(extended_pan_id)).into(),
51        ]),
52    };
53    Ok(tlv.encode()?)
54}
55
56// Attribute decoders
57
58/// Decode PreferredExtendedPanID attribute (0x0000)
59pub fn decode_preferred_extended_pan_id(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<Vec<u8>>> {
60    if let tlv::TlvItemValue::OctetString(v) = inp {
61        Ok(Some(v.clone()))
62    } else {
63        Ok(None)
64    }
65}
66
67/// Decode ThreadNetworks attribute (0x0001)
68pub fn decode_thread_networks(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<ThreadNetwork>> {
69    let mut res = Vec::new();
70    if let tlv::TlvItemValue::List(v) = inp {
71        for item in v {
72            res.push(ThreadNetwork {
73                extended_pan_id: item.get_octet_string_owned(&[0]),
74                network_name: item.get_string_owned(&[1]),
75                channel: item.get_int(&[2]).map(|v| v as u16),
76                active_timestamp: item.get_int(&[3]),
77            });
78        }
79    }
80    Ok(res)
81}
82
83/// Decode ThreadNetworkTableSize attribute (0x0002)
84pub fn decode_thread_network_table_size(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
85    if let tlv::TlvItemValue::Int(v) = inp {
86        Ok(*v as u8)
87    } else {
88        Err(anyhow::anyhow!("Expected Integer"))
89    }
90}
91
92
93// JSON dispatcher function
94
95/// Decode attribute value and return as JSON string
96/// 
97/// # Parameters
98/// * `cluster_id` - The cluster identifier
99/// * `attribute_id` - The attribute identifier
100/// * `tlv_value` - The TLV value to decode
101/// 
102/// # Returns
103/// JSON string representation of the decoded value or error
104pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
105    // Verify this is the correct cluster
106    if cluster_id != 0x0453 {
107        return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0453, got {}\"}}", cluster_id);
108    }
109    
110    match attribute_id {
111        0x0000 => {
112            match decode_preferred_extended_pan_id(tlv_value) {
113                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
114                Err(e) => format!("{{\"error\": \"{}\"}}", e),
115            }
116        }
117        0x0001 => {
118            match decode_thread_networks(tlv_value) {
119                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
120                Err(e) => format!("{{\"error\": \"{}\"}}", e),
121            }
122        }
123        0x0002 => {
124            match decode_thread_network_table_size(tlv_value) {
125                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
126                Err(e) => format!("{{\"error\": \"{}\"}}", e),
127            }
128        }
129        _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
130    }
131}
132
133/// Get list of all attributes supported by this cluster
134/// 
135/// # Returns
136/// Vector of tuples containing (attribute_id, attribute_name)
137pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
138    vec![
139        (0x0000, "PreferredExtendedPanID"),
140        (0x0001, "ThreadNetworks"),
141        (0x0002, "ThreadNetworkTableSize"),
142    ]
143}
144