ipmi_rs/storage/sel/
get_entry.rs

1use std::num::NonZeroU16;
2
3use nonmax::NonMaxU8;
4
5use crate::{
6    connection::{CompletionCode, IpmiCommand, Message, NetFn, ParseResponseError},
7    Loggable,
8};
9
10use super::{Entry, ParseEntryError, RecordId};
11
12#[derive(Clone, Debug, PartialEq)]
13pub struct GetEntry {
14    reservation_id: Option<NonZeroU16>,
15    record_id: RecordId,
16    offset: u8,
17    bytes_to_read: Option<NonMaxU8>,
18}
19
20impl GetEntry {
21    pub fn new(reservation_id: Option<NonZeroU16>, record_id: RecordId) -> Self {
22        Self {
23            reservation_id,
24            record_id,
25            // Always read all bytes
26            offset: 0,
27            bytes_to_read: None,
28        }
29    }
30}
31
32#[derive(Clone, Debug, PartialEq)]
33pub struct EntryInfo {
34    pub next_entry: RecordId,
35    pub entry: Entry,
36}
37
38impl Loggable for EntryInfo {
39    fn as_log(&self) -> Vec<crate::fmt::LogItem> {
40        let mut log_output = self.entry.as_log();
41
42        let value = format!("0x{:04X}", self.next_entry.value());
43        log_output.push((1, "Next entry", value).into());
44        log_output
45    }
46}
47
48impl IpmiCommand for GetEntry {
49    type Output = EntryInfo;
50
51    type Error = ParseEntryError;
52
53    fn parse_response(
54        completion_code: CompletionCode,
55        data: &[u8],
56    ) -> Result<Self::Output, ParseResponseError<Self::Error>> {
57        Self::check_cc_success(completion_code)?;
58
59        if data.len() < 2 {
60            return Err(ParseResponseError::NotEnoughData);
61        }
62
63        let next_entry = RecordId::new_raw(u16::from_le_bytes([data[0], data[1]]));
64        let entry = Entry::parse(&data[2..]).map_err(ParseResponseError::Parse)?;
65        Ok(EntryInfo { next_entry, entry })
66    }
67}
68
69impl From<GetEntry> for Message {
70    fn from(value: GetEntry) -> Self {
71        let GetEntry {
72            reservation_id,
73            record_id,
74            offset,
75            bytes_to_read,
76        } = value;
77
78        let mut data = vec![0u8; 6];
79
80        data[0..2].copy_from_slice(&reservation_id.map(|v| v.get()).unwrap_or(0).to_le_bytes());
81        data[2..4].copy_from_slice(&record_id.value().to_le_bytes());
82        data[4] = offset;
83        data[5] = bytes_to_read.map(|v| v.get()).unwrap_or(0xFF);
84
85        Message::new_request(NetFn::Storage, 0x43, data)
86    }
87}