ipmi-rs-core 0.5.0

A pure rust implementation of the core primitives of the IPMI spec
Documentation
use crate::{
    connection::{IpmiCommand, Message, NetFn, NotEnoughData},
    storage::Timestamp,
};

pub struct GetInfo;

impl IpmiCommand for GetInfo {
    type Output = Info;

    type Error = NotEnoughData;

    fn parse_success_response(data: &[u8]) -> Result<Self::Output, Self::Error> {
        Info::from_data(data).ok_or(NotEnoughData)
    }
}

impl From<GetInfo> for Message {
    fn from(_: GetInfo) -> Self {
        Message::new_request(NetFn::Storage, 0x40, Vec::new())
    }
}

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Command {
    Clear,
    PartialAddEntry,
    Reserve,
    GetAllocInfo,
}

#[derive(Debug, Clone)]
pub struct Info {
    pub version_maj: u8,
    pub version_min: u8,
    pub entries: u16,
    pub bytes_free: u16,
    pub last_add_time: Timestamp,
    pub last_del_time: Timestamp,
    pub overflow: bool,
    pub supported_cmds: Vec<Command>,
}

impl Info {
    pub fn from_data(data: &[u8]) -> Option<Self> {
        if data.len() != 14 {
            return None;
        }

        let version_maj = data[0] & 0xF;
        let version_min = (data[0] >> 4) & 0xF;

        let entries = u16::from_le_bytes([data[1], data[2]]);
        let free = u16::from_le_bytes([data[3], data[4]]);

        let last_add_time = u32::from_le_bytes([data[5], data[6], data[7], data[8]]);
        let last_del_time = u32::from_le_bytes([data[9], data[10], data[11], data[12]]);
        let overflow = data[13] & 0x80 == 0x80;

        let mut supported_cmds = Vec::with_capacity(4);

        if data[13] & 0x08 == 0x08 {
            supported_cmds.push(Command::Clear);
        }
        if data[13] & 0x04 == 0x04 {
            supported_cmds.push(Command::PartialAddEntry);
        }
        if data[13] & 0x02 == 0x02 {
            supported_cmds.push(Command::Reserve);
        }
        if data[13] & 0x01 == 0x01 {
            supported_cmds.push(Command::GetAllocInfo);
        }

        Some(Info {
            version_maj,
            version_min,
            entries,
            bytes_free: free,
            last_add_time: Timestamp(last_add_time),
            last_del_time: Timestamp(last_del_time),
            overflow,
            supported_cmds,
        })
    }
}