matc/clusters/codec/
diagnostic_logs_cluster.rs

1//! Matter TLV encoders and decoders for Diagnostic Logs Cluster
2//! Cluster ID: 0x0032
3//!
4//! This file is automatically generated from DiagnosticLogsCluster.xml
5
6use crate::tlv;
7use anyhow;
8
9
10// Import serialization helpers for octet strings
11use crate::clusters::helpers::{serialize_opt_bytes_as_hex};
12
13// Enum definitions
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
16#[repr(u8)]
17pub enum Intent {
18    /// Logs to be used for end-user support
19    Endusersupport = 0,
20    /// Logs to be used for network diagnostics
21    Networkdiag = 1,
22    /// Obtain crash logs from the Node
23    Crashlogs = 2,
24}
25
26impl Intent {
27    /// Convert from u8 value
28    pub fn from_u8(value: u8) -> Option<Self> {
29        match value {
30            0 => Some(Intent::Endusersupport),
31            1 => Some(Intent::Networkdiag),
32            2 => Some(Intent::Crashlogs),
33            _ => None,
34        }
35    }
36
37    /// Convert to u8 value
38    pub fn to_u8(self) -> u8 {
39        self as u8
40    }
41}
42
43impl From<Intent> for u8 {
44    fn from(val: Intent) -> Self {
45        val as u8
46    }
47}
48
49#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
50#[repr(u8)]
51pub enum Status {
52    /// Successful transfer of logs
53    Success = 0,
54    /// All logs have been transferred
55    Exhausted = 1,
56    /// No logs of the requested type available
57    Nologs = 2,
58    /// Unable to handle request, retry later
59    Busy = 3,
60    /// The request is denied, no logs being transferred
61    Denied = 4,
62}
63
64impl Status {
65    /// Convert from u8 value
66    pub fn from_u8(value: u8) -> Option<Self> {
67        match value {
68            0 => Some(Status::Success),
69            1 => Some(Status::Exhausted),
70            2 => Some(Status::Nologs),
71            3 => Some(Status::Busy),
72            4 => Some(Status::Denied),
73            _ => None,
74        }
75    }
76
77    /// Convert to u8 value
78    pub fn to_u8(self) -> u8 {
79        self as u8
80    }
81}
82
83impl From<Status> for u8 {
84    fn from(val: Status) -> Self {
85        val as u8
86    }
87}
88
89#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
90#[repr(u8)]
91pub enum TransferProtocol {
92    /// Logs to be returned as a response
93    Responsepayload = 0,
94    /// Logs to be returned using BDX
95    Bdx = 1,
96}
97
98impl TransferProtocol {
99    /// Convert from u8 value
100    pub fn from_u8(value: u8) -> Option<Self> {
101        match value {
102            0 => Some(TransferProtocol::Responsepayload),
103            1 => Some(TransferProtocol::Bdx),
104            _ => None,
105        }
106    }
107
108    /// Convert to u8 value
109    pub fn to_u8(self) -> u8 {
110        self as u8
111    }
112}
113
114impl From<TransferProtocol> for u8 {
115    fn from(val: TransferProtocol) -> Self {
116        val as u8
117    }
118}
119
120// Command encoders
121
122/// Encode RetrieveLogsRequest command (0x00)
123pub fn encode_retrieve_logs_request(intent: Intent, requested_protocol: TransferProtocol, transfer_file_designator: String) -> anyhow::Result<Vec<u8>> {
124    let tlv = tlv::TlvItemEnc {
125        tag: 0,
126        value: tlv::TlvItemValueEnc::StructInvisible(vec![
127        (0, tlv::TlvItemValueEnc::UInt8(intent.to_u8())).into(),
128        (1, tlv::TlvItemValueEnc::UInt8(requested_protocol.to_u8())).into(),
129        (2, tlv::TlvItemValueEnc::String(transfer_file_designator)).into(),
130        ]),
131    };
132    Ok(tlv.encode()?)
133}
134
135#[derive(Debug, serde::Serialize)]
136pub struct RetrieveLogsResponse {
137    pub status: Option<Status>,
138    #[serde(serialize_with = "serialize_opt_bytes_as_hex")]
139    pub log_content: Option<Vec<u8>>,
140    pub utc_time_stamp: Option<u64>,
141    pub time_since_boot: Option<u8>,
142}
143
144// Command response decoders
145
146/// Decode RetrieveLogsResponse command response (01)
147pub fn decode_retrieve_logs_response(inp: &tlv::TlvItemValue) -> anyhow::Result<RetrieveLogsResponse> {
148    if let tlv::TlvItemValue::List(_fields) = inp {
149        let item = tlv::TlvItem { tag: 0, value: inp.clone() };
150        Ok(RetrieveLogsResponse {
151                status: item.get_int(&[0]).and_then(|v| Status::from_u8(v as u8)),
152                log_content: item.get_octet_string_owned(&[1]),
153                utc_time_stamp: item.get_int(&[2]),
154                time_since_boot: item.get_int(&[3]).map(|v| v as u8),
155        })
156    } else {
157        Err(anyhow::anyhow!("Expected struct fields"))
158    }
159}
160