matc/clusters/codec/
general_commissioning_cluster.rs

1//! Generated Matter TLV encoders and decoders for General Commissioning Cluster
2//! Cluster ID: 0x0030
3//! 
4//! This file is automatically generated from GeneralCommissioningCluster.xml
5
6use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11// Struct definitions
12
13#[derive(Debug, serde::Serialize)]
14pub struct BasicCommissioningInfo {
15    pub fail_safe_expiry_length_seconds: Option<u16>,
16    pub max_cumulative_failsafe_seconds: Option<u16>,
17}
18
19// Command encoders
20
21/// Encode ArmFailSafe command (0x00)
22pub fn encode_arm_fail_safe(expiry_length_seconds: u16, breadcrumb: u64) -> anyhow::Result<Vec<u8>> {
23    let tlv = tlv::TlvItemEnc {
24        tag: 0,
25        value: tlv::TlvItemValueEnc::StructInvisible(vec![
26        (0, tlv::TlvItemValueEnc::UInt16(expiry_length_seconds)).into(),
27        (1, tlv::TlvItemValueEnc::UInt64(breadcrumb)).into(),
28        ]),
29    };
30    Ok(tlv.encode()?)
31}
32
33/// Encode SetRegulatoryConfig command (0x02)
34pub fn encode_set_regulatory_config(new_regulatory_config: u8, country_code: String, breadcrumb: u64) -> anyhow::Result<Vec<u8>> {
35    let tlv = tlv::TlvItemEnc {
36        tag: 0,
37        value: tlv::TlvItemValueEnc::StructInvisible(vec![
38        (0, tlv::TlvItemValueEnc::UInt8(new_regulatory_config)).into(),
39        (1, tlv::TlvItemValueEnc::String(country_code)).into(),
40        (2, tlv::TlvItemValueEnc::UInt64(breadcrumb)).into(),
41        ]),
42    };
43    Ok(tlv.encode()?)
44}
45
46/// Encode SetTCAcknowledgements command (0x06)
47pub fn encode_set_tc_acknowledgements(tc_version: u16, tc_user_response: u8) -> anyhow::Result<Vec<u8>> {
48    let tlv = tlv::TlvItemEnc {
49        tag: 0,
50        value: tlv::TlvItemValueEnc::StructInvisible(vec![
51        (0, tlv::TlvItemValueEnc::UInt16(tc_version)).into(),
52        (1, tlv::TlvItemValueEnc::UInt8(tc_user_response)).into(),
53        ]),
54    };
55    Ok(tlv.encode()?)
56}
57
58// Attribute decoders
59
60/// Decode Breadcrumb attribute (0x0000)
61pub fn decode_breadcrumb(inp: &tlv::TlvItemValue) -> anyhow::Result<u64> {
62    if let tlv::TlvItemValue::Int(v) = inp {
63        Ok(*v)
64    } else {
65        Err(anyhow::anyhow!("Expected Integer"))
66    }
67}
68
69/// Decode BasicCommissioningInfo attribute (0x0001)
70pub fn decode_basic_commissioning_info(inp: &tlv::TlvItemValue) -> anyhow::Result<BasicCommissioningInfo> {
71    if let tlv::TlvItemValue::List(_fields) = inp {
72        // Struct with fields
73        let item = tlv::TlvItem { tag: 0, value: inp.clone() };
74        Ok(BasicCommissioningInfo {
75                fail_safe_expiry_length_seconds: item.get_int(&[0]).map(|v| v as u16),
76                max_cumulative_failsafe_seconds: item.get_int(&[1]).map(|v| v as u16),
77        })
78    } else {
79        Err(anyhow::anyhow!("Expected struct fields"))
80    }
81}
82
83/// Decode RegulatoryConfig attribute (0x0002)
84pub fn decode_regulatory_config(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/// Decode LocationCapability attribute (0x0003)
93pub fn decode_location_capability(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
94    if let tlv::TlvItemValue::Int(v) = inp {
95        Ok(*v as u8)
96    } else {
97        Err(anyhow::anyhow!("Expected Integer"))
98    }
99}
100
101/// Decode SupportsConcurrentConnection attribute (0x0004)
102pub fn decode_supports_concurrent_connection(inp: &tlv::TlvItemValue) -> anyhow::Result<bool> {
103    if let tlv::TlvItemValue::Bool(v) = inp {
104        Ok(*v)
105    } else {
106        Err(anyhow::anyhow!("Expected Bool"))
107    }
108}
109
110/// Decode TCAcceptedVersion attribute (0x0005)
111pub fn decode_tc_accepted_version(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
112    if let tlv::TlvItemValue::Int(v) = inp {
113        Ok(*v as u16)
114    } else {
115        Err(anyhow::anyhow!("Expected Integer"))
116    }
117}
118
119/// Decode TCMinRequiredVersion attribute (0x0006)
120pub fn decode_tc_min_required_version(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
121    if let tlv::TlvItemValue::Int(v) = inp {
122        Ok(*v as u16)
123    } else {
124        Err(anyhow::anyhow!("Expected Integer"))
125    }
126}
127
128/// Decode TCAcknowledgements attribute (0x0007)
129pub fn decode_tc_acknowledgements(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
130    if let tlv::TlvItemValue::Int(v) = inp {
131        Ok(*v as u8)
132    } else {
133        Err(anyhow::anyhow!("Expected Integer"))
134    }
135}
136
137/// Decode TCAcknowledgementsRequired attribute (0x0008)
138pub fn decode_tc_acknowledgements_required(inp: &tlv::TlvItemValue) -> anyhow::Result<bool> {
139    if let tlv::TlvItemValue::Bool(v) = inp {
140        Ok(*v)
141    } else {
142        Err(anyhow::anyhow!("Expected Bool"))
143    }
144}
145
146/// Decode TCUpdateDeadline attribute (0x0009)
147pub fn decode_tc_update_deadline(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u32>> {
148    if let tlv::TlvItemValue::Int(v) = inp {
149        Ok(Some(*v as u32))
150    } else {
151        Ok(None)
152    }
153}
154
155
156// JSON dispatcher function
157
158/// Decode attribute value and return as JSON string
159/// 
160/// # Parameters
161/// * `cluster_id` - The cluster identifier
162/// * `attribute_id` - The attribute identifier
163/// * `tlv_value` - The TLV value to decode
164/// 
165/// # Returns
166/// JSON string representation of the decoded value or error
167pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
168    // Verify this is the correct cluster
169    if cluster_id != 0x0030 {
170        return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0030, got {}\"}}", cluster_id);
171    }
172    
173    match attribute_id {
174        0x0000 => {
175            match decode_breadcrumb(tlv_value) {
176                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
177                Err(e) => format!("{{\"error\": \"{}\"}}", e),
178            }
179        }
180        0x0001 => {
181            match decode_basic_commissioning_info(tlv_value) {
182                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
183                Err(e) => format!("{{\"error\": \"{}\"}}", e),
184            }
185        }
186        0x0002 => {
187            match decode_regulatory_config(tlv_value) {
188                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
189                Err(e) => format!("{{\"error\": \"{}\"}}", e),
190            }
191        }
192        0x0003 => {
193            match decode_location_capability(tlv_value) {
194                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
195                Err(e) => format!("{{\"error\": \"{}\"}}", e),
196            }
197        }
198        0x0004 => {
199            match decode_supports_concurrent_connection(tlv_value) {
200                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
201                Err(e) => format!("{{\"error\": \"{}\"}}", e),
202            }
203        }
204        0x0005 => {
205            match decode_tc_accepted_version(tlv_value) {
206                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
207                Err(e) => format!("{{\"error\": \"{}\"}}", e),
208            }
209        }
210        0x0006 => {
211            match decode_tc_min_required_version(tlv_value) {
212                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
213                Err(e) => format!("{{\"error\": \"{}\"}}", e),
214            }
215        }
216        0x0007 => {
217            match decode_tc_acknowledgements(tlv_value) {
218                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
219                Err(e) => format!("{{\"error\": \"{}\"}}", e),
220            }
221        }
222        0x0008 => {
223            match decode_tc_acknowledgements_required(tlv_value) {
224                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
225                Err(e) => format!("{{\"error\": \"{}\"}}", e),
226            }
227        }
228        0x0009 => {
229            match decode_tc_update_deadline(tlv_value) {
230                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
231                Err(e) => format!("{{\"error\": \"{}\"}}", e),
232            }
233        }
234        _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
235    }
236}
237
238/// Get list of all attributes supported by this cluster
239/// 
240/// # Returns
241/// Vector of tuples containing (attribute_id, attribute_name)
242pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
243    vec![
244        (0x0000, "Breadcrumb"),
245        (0x0001, "BasicCommissioningInfo"),
246        (0x0002, "RegulatoryConfig"),
247        (0x0003, "LocationCapability"),
248        (0x0004, "SupportsConcurrentConnection"),
249        (0x0005, "TCAcceptedVersion"),
250        (0x0006, "TCMinRequiredVersion"),
251        (0x0007, "TCAcknowledgements"),
252        (0x0008, "TCAcknowledgementsRequired"),
253        (0x0009, "TCUpdateDeadline"),
254    ]
255}
256