ipmi_rs_core/app/
get_device_id.rs1use crate::connection::{IpmiCommand, Message, NetFn, NotEnoughData};
2
3pub struct GetDeviceId;
5
6impl From<GetDeviceId> for Message {
7 fn from(_: GetDeviceId) -> Self {
8 Message::new_request(NetFn::App, 0x01, Vec::new())
9 }
10}
11
12impl IpmiCommand for GetDeviceId {
13 type Output = DeviceId;
14
15 type Error = NotEnoughData;
16
17 fn parse_success_response(data: &[u8]) -> Result<Self::Output, Self::Error> {
18 DeviceId::from_data(data).ok_or(NotEnoughData)
19 }
20}
21
22#[derive(Clone, Debug, PartialEq)]
25pub struct DeviceId {
26 pub device_id: u8,
28 pub device_revision: u8,
30 pub provides_device_sdrs: bool,
32 pub device_available: bool,
35 pub major_fw_revision: u8,
37 pub minor_fw_revision: u8,
39 pub major_version: u8,
41 pub minor_version: u8,
43 pub chassis_support: bool,
45 pub bridge_support: bool,
47 pub ipmb_event_generator_support: bool,
49 pub ipmb_event_receiver_support: bool,
51 pub fru_inventory_support: bool,
53 pub sel_device_support: bool,
55 pub sdr_repository_support: bool,
57 pub sensor_device_support: bool,
59 pub manufacturer_id: u32,
61 pub product_id: u16,
63 pub aux_revision: Option<[u8; 4]>,
65}
66
67impl DeviceId {
68 pub fn from_data(data: &[u8]) -> Option<Self> {
70 if data.len() < 11 {
71 return None;
72 }
73
74 let aux_revision = if data.len() < 15 {
75 None
76 } else {
77 Some([data[11], data[12], data[13], data[14]])
78 };
79
80 let fw_min = {
81 let min_nib_low = data[3] & 0xF;
82 let min_nib_high = (data[3] >> 4) & 0xF;
83
84 min_nib_low + min_nib_high * 10
85 };
86
87 let me = Self {
88 device_id: data[0],
89 device_revision: data[1] & 0xF,
90 provides_device_sdrs: (data[1] & 0x80) == 0x80,
91 device_available: (data[2] & 0x80) != 0x80,
92 major_fw_revision: (data[2] & 0x7F),
93 minor_fw_revision: fw_min,
94 major_version: data[4] & 0xF,
95 minor_version: (data[4] >> 4) & 0xF,
96 chassis_support: (data[5] & 0x80) == 0x80,
97 bridge_support: (data[5] & 0x40) == 0x40,
98 ipmb_event_generator_support: (data[5] & 0x20) == 0x20,
99 ipmb_event_receiver_support: (data[5] & 0x10) == 0x10,
100 fru_inventory_support: (data[5] & 0x08) == 0x08,
101 sel_device_support: (data[5] & 0x04) == 0x04,
102 sdr_repository_support: (data[5] & 0x02) == 0x02,
103 sensor_device_support: (data[5] & 0x01) == 0x01,
104 manufacturer_id: u32::from_le_bytes([data[6], data[7], data[8], 0]),
105 product_id: u16::from_le_bytes([data[9], data[10]]),
106 aux_revision,
107 };
108
109 Some(me)
110 }
111}