use crate::tlv;
use anyhow;
use crate::clusters::helpers::{serialize_opt_bytes_as_hex};
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[repr(u8)]
pub enum Intent {
Endusersupport = 0,
Networkdiag = 1,
Crashlogs = 2,
}
impl Intent {
pub fn from_u8(value: u8) -> Option<Self> {
match value {
0 => Some(Intent::Endusersupport),
1 => Some(Intent::Networkdiag),
2 => Some(Intent::Crashlogs),
_ => None,
}
}
pub fn to_u8(self) -> u8 {
self as u8
}
}
impl From<Intent> for u8 {
fn from(val: Intent) -> Self {
val as u8
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[repr(u8)]
pub enum Status {
Success = 0,
Exhausted = 1,
Nologs = 2,
Busy = 3,
Denied = 4,
}
impl Status {
pub fn from_u8(value: u8) -> Option<Self> {
match value {
0 => Some(Status::Success),
1 => Some(Status::Exhausted),
2 => Some(Status::Nologs),
3 => Some(Status::Busy),
4 => Some(Status::Denied),
_ => None,
}
}
pub fn to_u8(self) -> u8 {
self as u8
}
}
impl From<Status> for u8 {
fn from(val: Status) -> Self {
val as u8
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[repr(u8)]
pub enum TransferProtocol {
Responsepayload = 0,
Bdx = 1,
}
impl TransferProtocol {
pub fn from_u8(value: u8) -> Option<Self> {
match value {
0 => Some(TransferProtocol::Responsepayload),
1 => Some(TransferProtocol::Bdx),
_ => None,
}
}
pub fn to_u8(self) -> u8 {
self as u8
}
}
impl From<TransferProtocol> for u8 {
fn from(val: TransferProtocol) -> Self {
val as u8
}
}
pub fn encode_retrieve_logs_request(intent: Intent, requested_protocol: TransferProtocol, transfer_file_designator: String) -> anyhow::Result<Vec<u8>> {
let tlv = tlv::TlvItemEnc {
tag: 0,
value: tlv::TlvItemValueEnc::StructInvisible(vec![
(0, tlv::TlvItemValueEnc::UInt8(intent.to_u8())).into(),
(1, tlv::TlvItemValueEnc::UInt8(requested_protocol.to_u8())).into(),
(2, tlv::TlvItemValueEnc::String(transfer_file_designator)).into(),
]),
};
Ok(tlv.encode()?)
}
#[derive(Debug, serde::Serialize)]
pub struct RetrieveLogsResponse {
pub status: Option<Status>,
#[serde(serialize_with = "serialize_opt_bytes_as_hex")]
pub log_content: Option<Vec<u8>>,
pub utc_time_stamp: Option<u64>,
pub time_since_boot: Option<u8>,
}
pub fn decode_retrieve_logs_response(inp: &tlv::TlvItemValue) -> anyhow::Result<RetrieveLogsResponse> {
if let tlv::TlvItemValue::List(_fields) = inp {
let item = tlv::TlvItem { tag: 0, value: inp.clone() };
Ok(RetrieveLogsResponse {
status: item.get_int(&[0]).and_then(|v| Status::from_u8(v as u8)),
log_content: item.get_octet_string_owned(&[1]),
utc_time_stamp: item.get_int(&[2]),
time_since_boot: item.get_int(&[3]).map(|v| v as u8),
})
} else {
Err(anyhow::anyhow!("Expected struct fields"))
}
}