matc/clusters/codec/
group_key_management_cluster.rs

1//! Generated Matter TLV encoders and decoders for Group Key Management Cluster
2//! Cluster ID: 0x003F
3//! 
4//! This file is automatically generated from Group-Key-Management-Cluster.xml
5
6use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11// Struct definitions
12
13#[derive(Debug, serde::Serialize)]
14pub struct GroupInfoMap {
15    pub group_id: Option<u8>,
16    pub endpoints: Option<Vec<u16>>,
17    pub group_name: Option<String>,
18}
19
20#[derive(Debug, serde::Serialize)]
21pub struct GroupKeyMap {
22    pub group_id: Option<u8>,
23    pub group_key_set_id: Option<u16>,
24}
25
26#[derive(Debug, serde::Serialize)]
27pub struct GroupKeySet {
28    pub group_key_set_id: Option<u16>,
29    pub group_key_security_policy: Option<u8>,
30    pub epoch_key0: Option<Vec<u8>>,
31    pub epoch_start_time0: Option<u8>,
32    pub epoch_key1: Option<Vec<u8>>,
33    pub epoch_start_time1: Option<u8>,
34    pub epoch_key2: Option<Vec<u8>>,
35    pub epoch_start_time2: Option<u8>,
36    pub group_key_multicast_policy: Option<u8>,
37}
38
39// Command encoders
40
41/// Encode KeySetWrite command (0x00)
42pub fn encode_key_set_write(group_key_set: u8) -> anyhow::Result<Vec<u8>> {
43    let tlv = tlv::TlvItemEnc {
44        tag: 0,
45        value: tlv::TlvItemValueEnc::StructInvisible(vec![
46        (0, tlv::TlvItemValueEnc::UInt8(group_key_set)).into(),
47        ]),
48    };
49    Ok(tlv.encode()?)
50}
51
52/// Encode KeySetRead command (0x01)
53pub fn encode_key_set_read(group_key_set_id: u16) -> anyhow::Result<Vec<u8>> {
54    let tlv = tlv::TlvItemEnc {
55        tag: 0,
56        value: tlv::TlvItemValueEnc::StructInvisible(vec![
57        (0, tlv::TlvItemValueEnc::UInt16(group_key_set_id)).into(),
58        ]),
59    };
60    Ok(tlv.encode()?)
61}
62
63/// Encode KeySetRemove command (0x03)
64pub fn encode_key_set_remove(group_key_set_id: u16) -> anyhow::Result<Vec<u8>> {
65    let tlv = tlv::TlvItemEnc {
66        tag: 0,
67        value: tlv::TlvItemValueEnc::StructInvisible(vec![
68        (0, tlv::TlvItemValueEnc::UInt16(group_key_set_id)).into(),
69        ]),
70    };
71    Ok(tlv.encode()?)
72}
73
74/// Encode KeySetReadAllIndices command (0x04)
75pub fn encode_key_set_read_all_indices(do_not_use: u8) -> anyhow::Result<Vec<u8>> {
76    let tlv = tlv::TlvItemEnc {
77        tag: 0,
78        value: tlv::TlvItemValueEnc::StructInvisible(vec![
79        (0, tlv::TlvItemValueEnc::UInt8(do_not_use)).into(),
80        ]),
81    };
82    Ok(tlv.encode()?)
83}
84
85// Attribute decoders
86
87/// Decode GroupKeyMap attribute (0x0000)
88pub fn decode_group_key_map(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<GroupKeyMap>> {
89    let mut res = Vec::new();
90    if let tlv::TlvItemValue::List(v) = inp {
91        for item in v {
92            res.push(GroupKeyMap {
93                group_id: item.get_int(&[1]).map(|v| v as u8),
94                group_key_set_id: item.get_int(&[2]).map(|v| v as u16),
95            });
96        }
97    }
98    Ok(res)
99}
100
101/// Decode GroupTable attribute (0x0001)
102pub fn decode_group_table(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<GroupInfoMap>> {
103    let mut res = Vec::new();
104    if let tlv::TlvItemValue::List(v) = inp {
105        for item in v {
106            res.push(GroupInfoMap {
107                group_id: item.get_int(&[1]).map(|v| v as u8),
108                endpoints: {
109                    if let Some(tlv::TlvItemValue::List(l)) = item.get(&[2]) {
110                        let items: Vec<u16> = l.iter().filter_map(|e| { if let tlv::TlvItemValue::Int(v) = &e.value { Some(*v as u16) } else { None } }).collect();
111                        Some(items)
112                    } else {
113                        None
114                    }
115                },
116                group_name: item.get_string_owned(&[3]),
117            });
118        }
119    }
120    Ok(res)
121}
122
123/// Decode MaxGroupsPerFabric attribute (0x0002)
124pub fn decode_max_groups_per_fabric(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
125    if let tlv::TlvItemValue::Int(v) = inp {
126        Ok(*v as u16)
127    } else {
128        Err(anyhow::anyhow!("Expected Integer"))
129    }
130}
131
132/// Decode MaxGroupKeysPerFabric attribute (0x0003)
133pub fn decode_max_group_keys_per_fabric(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
134    if let tlv::TlvItemValue::Int(v) = inp {
135        Ok(*v as u16)
136    } else {
137        Err(anyhow::anyhow!("Expected Integer"))
138    }
139}
140
141
142// JSON dispatcher function
143
144/// Decode attribute value and return as JSON string
145/// 
146/// # Parameters
147/// * `cluster_id` - The cluster identifier
148/// * `attribute_id` - The attribute identifier
149/// * `tlv_value` - The TLV value to decode
150/// 
151/// # Returns
152/// JSON string representation of the decoded value or error
153pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
154    // Verify this is the correct cluster
155    if cluster_id != 0x003F {
156        return format!("{{\"error\": \"Invalid cluster ID. Expected 0x003F, got {}\"}}", cluster_id);
157    }
158    
159    match attribute_id {
160        0x0000 => {
161            match decode_group_key_map(tlv_value) {
162                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
163                Err(e) => format!("{{\"error\": \"{}\"}}", e),
164            }
165        }
166        0x0001 => {
167            match decode_group_table(tlv_value) {
168                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
169                Err(e) => format!("{{\"error\": \"{}\"}}", e),
170            }
171        }
172        0x0002 => {
173            match decode_max_groups_per_fabric(tlv_value) {
174                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
175                Err(e) => format!("{{\"error\": \"{}\"}}", e),
176            }
177        }
178        0x0003 => {
179            match decode_max_group_keys_per_fabric(tlv_value) {
180                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
181                Err(e) => format!("{{\"error\": \"{}\"}}", e),
182            }
183        }
184        _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
185    }
186}
187
188/// Get list of all attributes supported by this cluster
189/// 
190/// # Returns
191/// Vector of tuples containing (attribute_id, attribute_name)
192pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
193    vec![
194        (0x0000, "GroupKeyMap"),
195        (0x0001, "GroupTable"),
196        (0x0002, "MaxGroupsPerFabric"),
197        (0x0003, "MaxGroupKeysPerFabric"),
198    ]
199}
200