matc/clusters/codec/
diagnostic_logs_cluster.rs1use crate::tlv;
7use anyhow;
8
9
10use crate::clusters::helpers::{serialize_opt_bytes_as_hex};
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
16#[repr(u8)]
17pub enum Intent {
18 Endusersupport = 0,
20 Networkdiag = 1,
22 Crashlogs = 2,
24}
25
26impl Intent {
27 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 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 Success = 0,
54 Exhausted = 1,
56 Nologs = 2,
58 Busy = 3,
60 Denied = 4,
62}
63
64impl Status {
65 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 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 Responsepayload = 0,
94 Bdx = 1,
96}
97
98impl TransferProtocol {
99 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 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
120pub 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
144pub 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