matc/clusters/codec/
messages.rs

1//! Generated Matter TLV encoders and decoders for Messages Cluster
2//! Cluster ID: 0x0097
3//! 
4//! This file is automatically generated from Messages.xml
5
6use crate::tlv;
7use anyhow;
8use serde_json;
9
10
11// Struct definitions
12
13#[derive(Debug, serde::Serialize)]
14pub struct MessageResponseOption {
15    pub message_response_id: Option<u32>,
16    pub label: Option<String>,
17}
18
19#[derive(Debug, serde::Serialize)]
20pub struct Message {
21    pub message_id: Option<u8>,
22    pub priority: Option<u8>,
23    pub message_control: Option<u8>,
24    pub start_time: Option<u64>,
25    pub duration: Option<u64>,
26    pub message_text: Option<String>,
27    pub responses: Option<Vec<MessageResponseOption>>,
28}
29
30// Command encoders
31
32/// Encode PresentMessagesRequest command (0x00)
33pub fn encode_present_messages_request(message_id: u8, priority: u8, message_control: u8, start_time: Option<u64>, duration: Option<u64>, message_text: String, responses: Vec<u8>) -> anyhow::Result<Vec<u8>> {
34    let tlv = tlv::TlvItemEnc {
35        tag: 0,
36        value: tlv::TlvItemValueEnc::StructInvisible(vec![
37        (0, tlv::TlvItemValueEnc::UInt8(message_id)).into(),
38        (1, tlv::TlvItemValueEnc::UInt8(priority)).into(),
39        (2, tlv::TlvItemValueEnc::UInt8(message_control)).into(),
40        (3, tlv::TlvItemValueEnc::UInt64(start_time.unwrap_or(0))).into(),
41        (4, tlv::TlvItemValueEnc::UInt64(duration.unwrap_or(0))).into(),
42        (5, tlv::TlvItemValueEnc::String(message_text)).into(),
43        (6, tlv::TlvItemValueEnc::StructAnon(responses.into_iter().map(|v| (0, tlv::TlvItemValueEnc::UInt8(v)).into()).collect())).into(),
44        ]),
45    };
46    Ok(tlv.encode()?)
47}
48
49/// Encode CancelMessagesRequest command (0x01)
50pub fn encode_cancel_messages_request(message_i_ds: Vec<u8>) -> anyhow::Result<Vec<u8>> {
51    let tlv = tlv::TlvItemEnc {
52        tag: 0,
53        value: tlv::TlvItemValueEnc::StructInvisible(vec![
54        (0, tlv::TlvItemValueEnc::StructAnon(message_i_ds.into_iter().map(|v| (0, tlv::TlvItemValueEnc::UInt8(v)).into()).collect())).into(),
55        ]),
56    };
57    Ok(tlv.encode()?)
58}
59
60// Attribute decoders
61
62/// Decode Messages attribute (0x0000)
63pub fn decode_messages(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<Message>> {
64    let mut res = Vec::new();
65    if let tlv::TlvItemValue::List(v) = inp {
66        for item in v {
67            res.push(Message {
68                message_id: item.get_int(&[0]).map(|v| v as u8),
69                priority: item.get_int(&[1]).map(|v| v as u8),
70                message_control: item.get_int(&[2]).map(|v| v as u8),
71                start_time: item.get_int(&[3]),
72                duration: item.get_int(&[4]),
73                message_text: item.get_string_owned(&[5]),
74                responses: {
75                    if let Some(tlv::TlvItemValue::List(l)) = item.get(&[6]) {
76                        let mut items = Vec::new();
77                        for list_item in l {
78                            items.push(MessageResponseOption {
79                message_response_id: list_item.get_int(&[0]).map(|v| v as u32),
80                label: list_item.get_string_owned(&[1]),
81                            });
82                        }
83                        Some(items)
84                    } else {
85                        None
86                    }
87                },
88            });
89        }
90    }
91    Ok(res)
92}
93
94/// Decode ActiveMessageIDs attribute (0x0001)
95pub fn decode_active_message_i_ds(inp: &tlv::TlvItemValue) -> anyhow::Result<Vec<u8>> {
96    let mut res = Vec::new();
97    if let tlv::TlvItemValue::List(v) = inp {
98        for item in v {
99            if let tlv::TlvItemValue::Int(i) = &item.value {
100                res.push(*i as u8);
101            }
102        }
103    }
104    Ok(res)
105}
106
107
108// JSON dispatcher function
109
110/// Decode attribute value and return as JSON string
111/// 
112/// # Parameters
113/// * `cluster_id` - The cluster identifier
114/// * `attribute_id` - The attribute identifier
115/// * `tlv_value` - The TLV value to decode
116/// 
117/// # Returns
118/// JSON string representation of the decoded value or error
119pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
120    // Verify this is the correct cluster
121    if cluster_id != 0x0097 {
122        return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0097, got {}\"}}", cluster_id);
123    }
124    
125    match attribute_id {
126        0x0000 => {
127            match decode_messages(tlv_value) {
128                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
129                Err(e) => format!("{{\"error\": \"{}\"}}", e),
130            }
131        }
132        0x0001 => {
133            match decode_active_message_i_ds(tlv_value) {
134                Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
135                Err(e) => format!("{{\"error\": \"{}\"}}", e),
136            }
137        }
138        _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
139    }
140}
141
142/// Get list of all attributes supported by this cluster
143/// 
144/// # Returns
145/// Vector of tuples containing (attribute_id, attribute_name)
146pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
147    vec![
148        (0x0000, "Messages"),
149        (0x0001, "ActiveMessageIDs"),
150    ]
151}
152