matc/clusters/codec/
application_basic.rs

1//! Matter TLV encoders and decoders for Application Basic Cluster
2//! Cluster ID: 0x050D
3//!
4//! This file is automatically generated from ApplicationBasic.xml
5
6use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11// Enum definitions
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
14#[repr(u8)]
15pub enum ApplicationStatus {
16    /// Application is not running.
17    Stopped = 0,
18    /// Application is running, is visible to the user, and is the active target for input.
19    Activevisiblefocus = 1,
20    /// Application is running but not visible to the user.
21    Activehidden = 2,
22    /// Application is running and visible, but is not the active target for input.
23    Activevisiblenotfocus = 3,
24}
25
26impl ApplicationStatus {
27    /// Convert from u8 value
28    pub fn from_u8(value: u8) -> Option<Self> {
29        match value {
30            0 => Some(ApplicationStatus::Stopped),
31            1 => Some(ApplicationStatus::Activevisiblefocus),
32            2 => Some(ApplicationStatus::Activehidden),
33            3 => Some(ApplicationStatus::Activevisiblenotfocus),
34            _ => None,
35        }
36    }
37
38    /// Convert to u8 value
39    pub fn to_u8(self) -> u8 {
40        self as u8
41    }
42}
43
44impl From<ApplicationStatus> for u8 {
45    fn from(val: ApplicationStatus) -> Self {
46        val as u8
47    }
48}
49
50// Struct definitions
51
52#[derive(Debug, serde::Serialize)]
53pub struct Application {
54    pub catalog_vendor_id: Option<u16>,
55    pub application_id: Option<String>,
56}
57
58// Attribute decoders
59
60/// Decode VendorName attribute (0x0000)
61pub fn decode_vendor_name(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
62    if let tlv::TlvItemValue::String(v) = inp {
63        Ok(v.clone())
64    } else {
65        Err(anyhow::anyhow!("Expected String"))
66    }
67}
68
69/// Decode VendorID attribute (0x0001)
70pub fn decode_vendor_id(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
71    if let tlv::TlvItemValue::Int(v) = inp {
72        Ok(*v as u16)
73    } else {
74        Err(anyhow::anyhow!("Expected UInt16"))
75    }
76}
77
78/// Decode ApplicationName attribute (0x0002)
79pub fn decode_application_name(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
80    if let tlv::TlvItemValue::String(v) = inp {
81        Ok(v.clone())
82    } else {
83        Err(anyhow::anyhow!("Expected String"))
84    }
85}
86
87/// Decode ProductID attribute (0x0003)
88pub fn decode_product_id(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
89    if let tlv::TlvItemValue::Int(v) = inp {
90        Ok(*v as u16)
91    } else {
92        Err(anyhow::anyhow!("Expected UInt16"))
93    }
94}
95
96/// Decode Application attribute (0x0004)
97pub fn decode_application(inp: &tlv::TlvItemValue) -> anyhow::Result<Application> {
98    if let tlv::TlvItemValue::List(_fields) = inp {
99        // Struct with fields
100        let item = tlv::TlvItem { tag: 0, value: inp.clone() };
101        Ok(Application {
102                catalog_vendor_id: item.get_int(&[0]).map(|v| v as u16),
103                application_id: item.get_string_owned(&[1]),
104        })
105    } else {
106        Err(anyhow::anyhow!("Expected struct fields"))
107    }
108}
109
110/// Decode Status attribute (0x0005)
111pub fn decode_status(inp: &tlv::TlvItemValue) -> anyhow::Result<ApplicationStatus> {
112    if let tlv::TlvItemValue::Int(v) = inp {
113        ApplicationStatus::from_u8(*v as u8).ok_or_else(|| anyhow::anyhow!("Invalid enum value"))
114    } else {
115        Err(anyhow::anyhow!("Expected Integer"))
116    }
117}
118
119/// Decode ApplicationVersion attribute (0x0006)
120pub fn decode_application_version(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
121    if let tlv::TlvItemValue::String(v) = inp {
122        Ok(v.clone())
123    } else {
124        Err(anyhow::anyhow!("Expected String"))
125    }
126}
127
128/// Decode AllowedVendorList attribute (0x0007)
129pub fn decode_allowed_vendor_list(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<u16>> {
130    let mut res = Vec::new();
131    if let tlv::TlvItemValue::List(v) = inp {
132        for item in v {
133            if let tlv::TlvItemValue::Int(i) = &item.value {
134                res.push(*i as u16);
135            }
136        }
137    }
138    Ok(res)
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 != 0x050D {
156        return format!("{{\"error\": \"Invalid cluster ID. Expected 0x050D, got {}\"}}", cluster_id);
157    }
158
159    match attribute_id {
160        0x0000 => {
161            match decode_vendor_name(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_vendor_id(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_application_name(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_product_id(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        0x0004 => {
185            match decode_application(tlv_value) {
186                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
187                Err(e) => format!("{{\"error\": \"{}\"}}", e),
188            }
189        }
190        0x0005 => {
191            match decode_status(tlv_value) {
192                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
193                Err(e) => format!("{{\"error\": \"{}\"}}", e),
194            }
195        }
196        0x0006 => {
197            match decode_application_version(tlv_value) {
198                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
199                Err(e) => format!("{{\"error\": \"{}\"}}", e),
200            }
201        }
202        0x0007 => {
203            match decode_allowed_vendor_list(tlv_value) {
204                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
205                Err(e) => format!("{{\"error\": \"{}\"}}", e),
206            }
207        }
208        _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
209    }
210}
211
212/// Get list of all attributes supported by this cluster
213///
214/// # Returns
215/// Vector of tuples containing (attribute_id, attribute_name)
216pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
217    vec![
218        (0x0000, "VendorName"),
219        (0x0001, "VendorID"),
220        (0x0002, "ApplicationName"),
221        (0x0003, "ProductID"),
222        (0x0004, "Application"),
223        (0x0005, "Status"),
224        (0x0006, "ApplicationVersion"),
225        (0x0007, "AllowedVendorList"),
226    ]
227}
228