matc/clusters/codec/
application_basic.rs1use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11#[derive(Debug, serde::Serialize)]
14pub struct Application {
15 pub catalog_vendor_id: Option<u16>,
16 pub application_id: Option<String>,
17}
18
19pub fn decode_vendor_name(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
23 if let tlv::TlvItemValue::String(v) = inp {
24 Ok(v.clone())
25 } else {
26 Err(anyhow::anyhow!("Expected String"))
27 }
28}
29
30pub fn decode_vendor_id(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
32 if let tlv::TlvItemValue::Int(v) = inp {
33 Ok(*v as u16)
34 } else {
35 Err(anyhow::anyhow!("Expected Integer"))
36 }
37}
38
39pub fn decode_application_name(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
41 if let tlv::TlvItemValue::String(v) = inp {
42 Ok(v.clone())
43 } else {
44 Err(anyhow::anyhow!("Expected String"))
45 }
46}
47
48pub fn decode_product_id(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
50 if let tlv::TlvItemValue::Int(v) = inp {
51 Ok(*v as u16)
52 } else {
53 Err(anyhow::anyhow!("Expected Integer"))
54 }
55}
56
57pub fn decode_application(inp: &tlv::TlvItemValue) -> anyhow::Result<Application> {
59 if let tlv::TlvItemValue::List(_fields) = inp {
60 let item = tlv::TlvItem { tag: 0, value: inp.clone() };
62 Ok(Application {
63 catalog_vendor_id: item.get_int(&[0]).map(|v| v as u16),
64 application_id: item.get_string_owned(&[1]),
65 })
66 } else {
67 Err(anyhow::anyhow!("Expected struct fields"))
68 }
69}
70
71pub fn decode_status(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
73 if let tlv::TlvItemValue::Int(v) = inp {
74 Ok(*v as u8)
75 } else {
76 Err(anyhow::anyhow!("Expected Integer"))
77 }
78}
79
80pub fn decode_application_version(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
82 if let tlv::TlvItemValue::String(v) = inp {
83 Ok(v.clone())
84 } else {
85 Err(anyhow::anyhow!("Expected String"))
86 }
87}
88
89pub fn decode_allowed_vendor_list(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<u16>> {
91 let mut res = Vec::new();
92 if let tlv::TlvItemValue::List(v) = inp {
93 for item in v {
94 if let tlv::TlvItemValue::Int(i) = &item.value {
95 res.push(*i as u16);
96 }
97 }
98 }
99 Ok(res)
100}
101
102
103pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
115 if cluster_id != 0x050D {
117 return format!("{{\"error\": \"Invalid cluster ID. Expected 0x050D, got {}\"}}", cluster_id);
118 }
119
120 match attribute_id {
121 0x0000 => {
122 match decode_vendor_name(tlv_value) {
123 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
124 Err(e) => format!("{{\"error\": \"{}\"}}", e),
125 }
126 }
127 0x0001 => {
128 match decode_vendor_id(tlv_value) {
129 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
130 Err(e) => format!("{{\"error\": \"{}\"}}", e),
131 }
132 }
133 0x0002 => {
134 match decode_application_name(tlv_value) {
135 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
136 Err(e) => format!("{{\"error\": \"{}\"}}", e),
137 }
138 }
139 0x0003 => {
140 match decode_product_id(tlv_value) {
141 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
142 Err(e) => format!("{{\"error\": \"{}\"}}", e),
143 }
144 }
145 0x0004 => {
146 match decode_application(tlv_value) {
147 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
148 Err(e) => format!("{{\"error\": \"{}\"}}", e),
149 }
150 }
151 0x0005 => {
152 match decode_status(tlv_value) {
153 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
154 Err(e) => format!("{{\"error\": \"{}\"}}", e),
155 }
156 }
157 0x0006 => {
158 match decode_application_version(tlv_value) {
159 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
160 Err(e) => format!("{{\"error\": \"{}\"}}", e),
161 }
162 }
163 0x0007 => {
164 match decode_allowed_vendor_list(tlv_value) {
165 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
166 Err(e) => format!("{{\"error\": \"{}\"}}", e),
167 }
168 }
169 _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
170 }
171}
172
173pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
178 vec![
179 (0x0000, "VendorName"),
180 (0x0001, "VendorID"),
181 (0x0002, "ApplicationName"),
182 (0x0003, "ProductID"),
183 (0x0004, "Application"),
184 (0x0005, "Status"),
185 (0x0006, "ApplicationVersion"),
186 (0x0007, "AllowedVendorList"),
187 ]
188}
189