matc/clusters/codec/
diagnostics_general.rs

1//! Generated Matter TLV encoders and decoders for General Diagnostics Cluster
2//! Cluster ID: 0x0033
3//! 
4//! This file is automatically generated from DiagnosticsGeneral.xml
5
6use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11// Struct definitions
12
13#[derive(Debug, serde::Serialize)]
14pub struct NetworkInterface {
15    pub name: Option<String>,
16    pub is_operational: Option<bool>,
17    pub off_premise_services_reachable_i_pv4: Option<bool>,
18    pub off_premise_services_reachable_i_pv6: Option<bool>,
19    pub hardware_address: Option<u8>,
20    pub i_pv4_addresses: Option<Vec<u8>>,
21    pub i_pv6_addresses: Option<Vec<u8>>,
22    pub type_: Option<u8>,
23}
24
25// Command encoders
26
27/// Encode TestEventTrigger command (0x00)
28pub fn encode_test_event_trigger(enable_key: Vec<u8>, event_trigger: u64) -> anyhow::Result<Vec<u8>> {
29    let tlv = tlv::TlvItemEnc {
30        tag: 0,
31        value: tlv::TlvItemValueEnc::StructInvisible(vec![
32        (0, tlv::TlvItemValueEnc::OctetString(enable_key)).into(),
33        (1, tlv::TlvItemValueEnc::UInt64(event_trigger)).into(),
34        ]),
35    };
36    Ok(tlv.encode()?)
37}
38
39/// Encode PayloadTestRequest command (0x03)
40pub fn encode_payload_test_request(enable_key: Vec<u8>, value: u8, count: u16) -> anyhow::Result<Vec<u8>> {
41    let tlv = tlv::TlvItemEnc {
42        tag: 0,
43        value: tlv::TlvItemValueEnc::StructInvisible(vec![
44        (0, tlv::TlvItemValueEnc::OctetString(enable_key)).into(),
45        (1, tlv::TlvItemValueEnc::UInt8(value)).into(),
46        (2, tlv::TlvItemValueEnc::UInt16(count)).into(),
47        ]),
48    };
49    Ok(tlv.encode()?)
50}
51
52// Attribute decoders
53
54/// Decode NetworkInterfaces attribute (0x0000)
55pub fn decode_network_interfaces(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<NetworkInterface>> {
56    let mut res = Vec::new();
57    if let tlv::TlvItemValue::List(v) = inp {
58        for item in v {
59            res.push(NetworkInterface {
60                name: item.get_string_owned(&[0]),
61                is_operational: item.get_bool(&[1]),
62                off_premise_services_reachable_i_pv4: item.get_bool(&[2]),
63                off_premise_services_reachable_i_pv6: item.get_bool(&[3]),
64                hardware_address: item.get_int(&[4]).map(|v| v as u8),
65                i_pv4_addresses: {
66                    if let Some(tlv::TlvItemValue::List(l)) = item.get(&[5]) {
67                        let items: Vec<u8> = l.iter().filter_map(|e| { if let tlv::TlvItemValue::Int(v) = &e.value { Some(*v as u8) } else { None } }).collect();
68                        Some(items)
69                    } else {
70                        None
71                    }
72                },
73                i_pv6_addresses: {
74                    if let Some(tlv::TlvItemValue::List(l)) = item.get(&[6]) {
75                        let items: Vec<u8> = l.iter().filter_map(|e| { if let tlv::TlvItemValue::Int(v) = &e.value { Some(*v as u8) } else { None } }).collect();
76                        Some(items)
77                    } else {
78                        None
79                    }
80                },
81                type_: item.get_int(&[7]).map(|v| v as u8),
82            });
83        }
84    }
85    Ok(res)
86}
87
88/// Decode RebootCount attribute (0x0001)
89pub fn decode_reboot_count(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
90    if let tlv::TlvItemValue::Int(v) = inp {
91        Ok(*v as u16)
92    } else {
93        Err(anyhow::anyhow!("Expected Integer"))
94    }
95}
96
97/// Decode UpTime attribute (0x0002)
98pub fn decode_up_time(inp: &tlv::TlvItemValue) -> anyhow::Result<u64> {
99    if let tlv::TlvItemValue::Int(v) = inp {
100        Ok(*v)
101    } else {
102        Err(anyhow::anyhow!("Expected Integer"))
103    }
104}
105
106/// Decode TotalOperationalHours attribute (0x0003)
107pub fn decode_total_operational_hours(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
108    if let tlv::TlvItemValue::Int(v) = inp {
109        Ok(*v as u32)
110    } else {
111        Err(anyhow::anyhow!("Expected Integer"))
112    }
113}
114
115/// Decode BootReason attribute (0x0004)
116pub fn decode_boot_reason(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
117    if let tlv::TlvItemValue::Int(v) = inp {
118        Ok(*v as u8)
119    } else {
120        Err(anyhow::anyhow!("Expected Integer"))
121    }
122}
123
124/// Decode ActiveHardwareFaults attribute (0x0005)
125pub fn decode_active_hardware_faults(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<u8>> {
126    let mut res = Vec::new();
127    if let tlv::TlvItemValue::List(v) = inp {
128        for item in v {
129            if let tlv::TlvItemValue::Int(i) = &item.value {
130                res.push(*i as u8);
131            }
132        }
133    }
134    Ok(res)
135}
136
137/// Decode ActiveRadioFaults attribute (0x0006)
138pub fn decode_active_radio_faults(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<u8>> {
139    let mut res = Vec::new();
140    if let tlv::TlvItemValue::List(v) = inp {
141        for item in v {
142            if let tlv::TlvItemValue::Int(i) = &item.value {
143                res.push(*i as u8);
144            }
145        }
146    }
147    Ok(res)
148}
149
150/// Decode ActiveNetworkFaults attribute (0x0007)
151pub fn decode_active_network_faults(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<u8>> {
152    let mut res = Vec::new();
153    if let tlv::TlvItemValue::List(v) = inp {
154        for item in v {
155            if let tlv::TlvItemValue::Int(i) = &item.value {
156                res.push(*i as u8);
157            }
158        }
159    }
160    Ok(res)
161}
162
163/// Decode TestEventTriggersEnabled attribute (0x0008)
164pub fn decode_test_event_triggers_enabled(inp: &tlv::TlvItemValue) -> anyhow::Result<bool> {
165    if let tlv::TlvItemValue::Bool(v) = inp {
166        Ok(*v)
167    } else {
168        Err(anyhow::anyhow!("Expected Bool"))
169    }
170}
171
172/// Decode DoNotUse attribute (0x0009)
173pub fn decode_do_not_use(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
174    if let tlv::TlvItemValue::Int(v) = inp {
175        Ok(*v as u8)
176    } else {
177        Err(anyhow::anyhow!("Expected Integer"))
178    }
179}
180
181
182// JSON dispatcher function
183
184/// Decode attribute value and return as JSON string
185/// 
186/// # Parameters
187/// * `cluster_id` - The cluster identifier
188/// * `attribute_id` - The attribute identifier
189/// * `tlv_value` - The TLV value to decode
190/// 
191/// # Returns
192/// JSON string representation of the decoded value or error
193pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
194    // Verify this is the correct cluster
195    if cluster_id != 0x0033 {
196        return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0033, got {}\"}}", cluster_id);
197    }
198    
199    match attribute_id {
200        0x0000 => {
201            match decode_network_interfaces(tlv_value) {
202                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
203                Err(e) => format!("{{\"error\": \"{}\"}}", e),
204            }
205        }
206        0x0001 => {
207            match decode_reboot_count(tlv_value) {
208                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
209                Err(e) => format!("{{\"error\": \"{}\"}}", e),
210            }
211        }
212        0x0002 => {
213            match decode_up_time(tlv_value) {
214                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
215                Err(e) => format!("{{\"error\": \"{}\"}}", e),
216            }
217        }
218        0x0003 => {
219            match decode_total_operational_hours(tlv_value) {
220                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
221                Err(e) => format!("{{\"error\": \"{}\"}}", e),
222            }
223        }
224        0x0004 => {
225            match decode_boot_reason(tlv_value) {
226                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
227                Err(e) => format!("{{\"error\": \"{}\"}}", e),
228            }
229        }
230        0x0005 => {
231            match decode_active_hardware_faults(tlv_value) {
232                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
233                Err(e) => format!("{{\"error\": \"{}\"}}", e),
234            }
235        }
236        0x0006 => {
237            match decode_active_radio_faults(tlv_value) {
238                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
239                Err(e) => format!("{{\"error\": \"{}\"}}", e),
240            }
241        }
242        0x0007 => {
243            match decode_active_network_faults(tlv_value) {
244                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
245                Err(e) => format!("{{\"error\": \"{}\"}}", e),
246            }
247        }
248        0x0008 => {
249            match decode_test_event_triggers_enabled(tlv_value) {
250                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
251                Err(e) => format!("{{\"error\": \"{}\"}}", e),
252            }
253        }
254        0x0009 => {
255            match decode_do_not_use(tlv_value) {
256                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
257                Err(e) => format!("{{\"error\": \"{}\"}}", e),
258            }
259        }
260        _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
261    }
262}
263
264/// Get list of all attributes supported by this cluster
265/// 
266/// # Returns
267/// Vector of tuples containing (attribute_id, attribute_name)
268pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
269    vec![
270        (0x0000, "NetworkInterfaces"),
271        (0x0001, "RebootCount"),
272        (0x0002, "UpTime"),
273        (0x0003, "TotalOperationalHours"),
274        (0x0004, "BootReason"),
275        (0x0005, "ActiveHardwareFaults"),
276        (0x0006, "ActiveRadioFaults"),
277        (0x0007, "ActiveNetworkFaults"),
278        (0x0008, "TestEventTriggersEnabled"),
279        (0x0009, "DoNotUse"),
280    ]
281}
282