matc/clusters/codec/
group_key_management_cluster.rs1use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11#[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
39pub 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
52pub 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
63pub 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
74pub 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
85pub 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
101pub 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
123pub 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
132pub 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
142pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
154 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
188pub 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