matc/clusters/codec/
basic_information_cluster.rs

1//! Generated Matter TLV encoders and decoders for Basic Information Cluster
2//! Cluster ID: 0x0028
3//! 
4//! This file is automatically generated from BasicInformationCluster.xml
5
6use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11// Struct definitions
12
13#[derive(Debug, serde::Serialize)]
14pub struct CapabilityMinima {
15    pub case_sessions_per_fabric: Option<u16>,
16    pub subscriptions_per_fabric: Option<u16>,
17}
18
19#[derive(Debug, serde::Serialize)]
20pub struct ProductAppearance {
21    pub finish: Option<u8>,
22    pub primary_color: Option<u8>,
23}
24
25// Attribute decoders
26
27/// Decode DataModelRevision attribute (0x0000)
28pub fn decode_data_model_revision(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
29    if let tlv::TlvItemValue::Int(v) = inp {
30        Ok(*v as u16)
31    } else {
32        Err(anyhow::anyhow!("Expected Integer"))
33    }
34}
35
36/// Decode VendorName attribute (0x0001)
37pub fn decode_vendor_name(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
38    if let tlv::TlvItemValue::String(v) = inp {
39        Ok(v.clone())
40    } else {
41        Err(anyhow::anyhow!("Expected String"))
42    }
43}
44
45/// Decode VendorID attribute (0x0002)
46pub fn decode_vendor_id(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
47    if let tlv::TlvItemValue::Int(v) = inp {
48        Ok(*v as u16)
49    } else {
50        Err(anyhow::anyhow!("Expected Integer"))
51    }
52}
53
54/// Decode ProductName attribute (0x0003)
55pub fn decode_product_name(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
56    if let tlv::TlvItemValue::String(v) = inp {
57        Ok(v.clone())
58    } else {
59        Err(anyhow::anyhow!("Expected String"))
60    }
61}
62
63/// Decode ProductID attribute (0x0004)
64pub fn decode_product_id(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
65    if let tlv::TlvItemValue::Int(v) = inp {
66        Ok(*v as u16)
67    } else {
68        Err(anyhow::anyhow!("Expected Integer"))
69    }
70}
71
72/// Decode NodeLabel attribute (0x0005)
73pub fn decode_node_label(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
74    if let tlv::TlvItemValue::String(v) = inp {
75        Ok(v.clone())
76    } else {
77        Err(anyhow::anyhow!("Expected String"))
78    }
79}
80
81/// Decode Location attribute (0x0006)
82pub fn decode_location(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
83    if let tlv::TlvItemValue::String(v) = inp {
84        Ok(v.clone())
85    } else {
86        Err(anyhow::anyhow!("Expected String"))
87    }
88}
89
90/// Decode HardwareVersion attribute (0x0007)
91pub fn decode_hardware_version(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
92    if let tlv::TlvItemValue::Int(v) = inp {
93        Ok(*v as u16)
94    } else {
95        Err(anyhow::anyhow!("Expected Integer"))
96    }
97}
98
99/// Decode HardwareVersionString attribute (0x0008)
100pub fn decode_hardware_version_string(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
101    if let tlv::TlvItemValue::String(v) = inp {
102        Ok(v.clone())
103    } else {
104        Err(anyhow::anyhow!("Expected String"))
105    }
106}
107
108/// Decode SoftwareVersion attribute (0x0009)
109pub fn decode_software_version(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
110    if let tlv::TlvItemValue::Int(v) = inp {
111        Ok(*v as u32)
112    } else {
113        Err(anyhow::anyhow!("Expected Integer"))
114    }
115}
116
117/// Decode SoftwareVersionString attribute (0x000A)
118pub fn decode_software_version_string(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
119    if let tlv::TlvItemValue::String(v) = inp {
120        Ok(v.clone())
121    } else {
122        Err(anyhow::anyhow!("Expected String"))
123    }
124}
125
126/// Decode ManufacturingDate attribute (0x000B)
127pub fn decode_manufacturing_date(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
128    if let tlv::TlvItemValue::String(v) = inp {
129        Ok(v.clone())
130    } else {
131        Err(anyhow::anyhow!("Expected String"))
132    }
133}
134
135/// Decode PartNumber attribute (0x000C)
136pub fn decode_part_number(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
137    if let tlv::TlvItemValue::String(v) = inp {
138        Ok(v.clone())
139    } else {
140        Err(anyhow::anyhow!("Expected String"))
141    }
142}
143
144/// Decode ProductURL attribute (0x000D)
145pub fn decode_product_url(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
146    if let tlv::TlvItemValue::String(v) = inp {
147        Ok(v.clone())
148    } else {
149        Err(anyhow::anyhow!("Expected String"))
150    }
151}
152
153/// Decode ProductLabel attribute (0x000E)
154pub fn decode_product_label(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
155    if let tlv::TlvItemValue::String(v) = inp {
156        Ok(v.clone())
157    } else {
158        Err(anyhow::anyhow!("Expected String"))
159    }
160}
161
162/// Decode SerialNumber attribute (0x000F)
163pub fn decode_serial_number(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
164    if let tlv::TlvItemValue::String(v) = inp {
165        Ok(v.clone())
166    } else {
167        Err(anyhow::anyhow!("Expected String"))
168    }
169}
170
171/// Decode LocalConfigDisabled attribute (0x0010)
172pub fn decode_local_config_disabled(inp: &tlv::TlvItemValue) -> anyhow::Result<bool> {
173    if let tlv::TlvItemValue::Bool(v) = inp {
174        Ok(*v)
175    } else {
176        Err(anyhow::anyhow!("Expected Bool"))
177    }
178}
179
180/// Decode Reachable attribute (0x0011)
181pub fn decode_reachable(inp: &tlv::TlvItemValue) -> anyhow::Result<bool> {
182    if let tlv::TlvItemValue::Bool(v) = inp {
183        Ok(*v)
184    } else {
185        Err(anyhow::anyhow!("Expected Bool"))
186    }
187}
188
189/// Decode UniqueID attribute (0x0012)
190pub fn decode_unique_id(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
191    if let tlv::TlvItemValue::String(v) = inp {
192        Ok(v.clone())
193    } else {
194        Err(anyhow::anyhow!("Expected String"))
195    }
196}
197
198/// Decode CapabilityMinima attribute (0x0013)
199pub fn decode_capability_minima(inp: &tlv::TlvItemValue) -> anyhow::Result<CapabilityMinima> {
200    if let tlv::TlvItemValue::List(_fields) = inp {
201        // Struct with fields
202        let item = tlv::TlvItem { tag: 0, value: inp.clone() };
203        Ok(CapabilityMinima {
204                case_sessions_per_fabric: item.get_int(&[0]).map(|v| v as u16),
205                subscriptions_per_fabric: item.get_int(&[1]).map(|v| v as u16),
206        })
207    } else {
208        Err(anyhow::anyhow!("Expected struct fields"))
209    }
210}
211
212/// Decode ProductAppearance attribute (0x0014)
213pub fn decode_product_appearance(inp: &tlv::TlvItemValue) -> anyhow::Result<ProductAppearance> {
214    if let tlv::TlvItemValue::List(_fields) = inp {
215        // Struct with fields
216        let item = tlv::TlvItem { tag: 0, value: inp.clone() };
217        Ok(ProductAppearance {
218                finish: item.get_int(&[0]).map(|v| v as u8),
219                primary_color: item.get_int(&[1]).map(|v| v as u8),
220        })
221    } else {
222        Err(anyhow::anyhow!("Expected struct fields"))
223    }
224}
225
226/// Decode SpecificationVersion attribute (0x0015)
227pub fn decode_specification_version(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
228    if let tlv::TlvItemValue::Int(v) = inp {
229        Ok(*v as u32)
230    } else {
231        Err(anyhow::anyhow!("Expected Integer"))
232    }
233}
234
235/// Decode MaxPathsPerInvoke attribute (0x0016)
236pub fn decode_max_paths_per_invoke(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
237    if let tlv::TlvItemValue::Int(v) = inp {
238        Ok(*v as u16)
239    } else {
240        Err(anyhow::anyhow!("Expected Integer"))
241    }
242}
243
244/// Decode ConfigurationVersion attribute (0x0018)
245pub fn decode_configuration_version(inp: &tlv::TlvItemValue) -> anyhow::Result<u32> {
246    if let tlv::TlvItemValue::Int(v) = inp {
247        Ok(*v as u32)
248    } else {
249        Err(anyhow::anyhow!("Expected Integer"))
250    }
251}
252
253
254// JSON dispatcher function
255
256/// Decode attribute value and return as JSON string
257/// 
258/// # Parameters
259/// * `cluster_id` - The cluster identifier
260/// * `attribute_id` - The attribute identifier
261/// * `tlv_value` - The TLV value to decode
262/// 
263/// # Returns
264/// JSON string representation of the decoded value or error
265pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
266    // Verify this is the correct cluster
267    if cluster_id != 0x0028 {
268        return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0028, got {}\"}}", cluster_id);
269    }
270    
271    match attribute_id {
272        0x0000 => {
273            match decode_data_model_revision(tlv_value) {
274                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
275                Err(e) => format!("{{\"error\": \"{}\"}}", e),
276            }
277        }
278        0x0001 => {
279            match decode_vendor_name(tlv_value) {
280                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
281                Err(e) => format!("{{\"error\": \"{}\"}}", e),
282            }
283        }
284        0x0002 => {
285            match decode_vendor_id(tlv_value) {
286                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
287                Err(e) => format!("{{\"error\": \"{}\"}}", e),
288            }
289        }
290        0x0003 => {
291            match decode_product_name(tlv_value) {
292                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
293                Err(e) => format!("{{\"error\": \"{}\"}}", e),
294            }
295        }
296        0x0004 => {
297            match decode_product_id(tlv_value) {
298                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
299                Err(e) => format!("{{\"error\": \"{}\"}}", e),
300            }
301        }
302        0x0005 => {
303            match decode_node_label(tlv_value) {
304                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
305                Err(e) => format!("{{\"error\": \"{}\"}}", e),
306            }
307        }
308        0x0006 => {
309            match decode_location(tlv_value) {
310                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
311                Err(e) => format!("{{\"error\": \"{}\"}}", e),
312            }
313        }
314        0x0007 => {
315            match decode_hardware_version(tlv_value) {
316                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
317                Err(e) => format!("{{\"error\": \"{}\"}}", e),
318            }
319        }
320        0x0008 => {
321            match decode_hardware_version_string(tlv_value) {
322                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
323                Err(e) => format!("{{\"error\": \"{}\"}}", e),
324            }
325        }
326        0x0009 => {
327            match decode_software_version(tlv_value) {
328                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
329                Err(e) => format!("{{\"error\": \"{}\"}}", e),
330            }
331        }
332        0x000A => {
333            match decode_software_version_string(tlv_value) {
334                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
335                Err(e) => format!("{{\"error\": \"{}\"}}", e),
336            }
337        }
338        0x000B => {
339            match decode_manufacturing_date(tlv_value) {
340                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
341                Err(e) => format!("{{\"error\": \"{}\"}}", e),
342            }
343        }
344        0x000C => {
345            match decode_part_number(tlv_value) {
346                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
347                Err(e) => format!("{{\"error\": \"{}\"}}", e),
348            }
349        }
350        0x000D => {
351            match decode_product_url(tlv_value) {
352                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
353                Err(e) => format!("{{\"error\": \"{}\"}}", e),
354            }
355        }
356        0x000E => {
357            match decode_product_label(tlv_value) {
358                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
359                Err(e) => format!("{{\"error\": \"{}\"}}", e),
360            }
361        }
362        0x000F => {
363            match decode_serial_number(tlv_value) {
364                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
365                Err(e) => format!("{{\"error\": \"{}\"}}", e),
366            }
367        }
368        0x0010 => {
369            match decode_local_config_disabled(tlv_value) {
370                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
371                Err(e) => format!("{{\"error\": \"{}\"}}", e),
372            }
373        }
374        0x0011 => {
375            match decode_reachable(tlv_value) {
376                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
377                Err(e) => format!("{{\"error\": \"{}\"}}", e),
378            }
379        }
380        0x0012 => {
381            match decode_unique_id(tlv_value) {
382                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
383                Err(e) => format!("{{\"error\": \"{}\"}}", e),
384            }
385        }
386        0x0013 => {
387            match decode_capability_minima(tlv_value) {
388                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
389                Err(e) => format!("{{\"error\": \"{}\"}}", e),
390            }
391        }
392        0x0014 => {
393            match decode_product_appearance(tlv_value) {
394                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
395                Err(e) => format!("{{\"error\": \"{}\"}}", e),
396            }
397        }
398        0x0015 => {
399            match decode_specification_version(tlv_value) {
400                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
401                Err(e) => format!("{{\"error\": \"{}\"}}", e),
402            }
403        }
404        0x0016 => {
405            match decode_max_paths_per_invoke(tlv_value) {
406                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
407                Err(e) => format!("{{\"error\": \"{}\"}}", e),
408            }
409        }
410        0x0018 => {
411            match decode_configuration_version(tlv_value) {
412                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
413                Err(e) => format!("{{\"error\": \"{}\"}}", e),
414            }
415        }
416        _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
417    }
418}
419
420/// Get list of all attributes supported by this cluster
421/// 
422/// # Returns
423/// Vector of tuples containing (attribute_id, attribute_name)
424pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
425    vec![
426        (0x0000, "DataModelRevision"),
427        (0x0001, "VendorName"),
428        (0x0002, "VendorID"),
429        (0x0003, "ProductName"),
430        (0x0004, "ProductID"),
431        (0x0005, "NodeLabel"),
432        (0x0006, "Location"),
433        (0x0007, "HardwareVersion"),
434        (0x0008, "HardwareVersionString"),
435        (0x0009, "SoftwareVersion"),
436        (0x000A, "SoftwareVersionString"),
437        (0x000B, "ManufacturingDate"),
438        (0x000C, "PartNumber"),
439        (0x000D, "ProductURL"),
440        (0x000E, "ProductLabel"),
441        (0x000F, "SerialNumber"),
442        (0x0010, "LocalConfigDisabled"),
443        (0x0011, "Reachable"),
444        (0x0012, "UniqueID"),
445        (0x0013, "CapabilityMinima"),
446        (0x0014, "ProductAppearance"),
447        (0x0015, "SpecificationVersion"),
448        (0x0016, "MaxPathsPerInvoke"),
449        (0x0018, "ConfigurationVersion"),
450    ]
451}
452