1use crate::connection::{Channel, IpmiCommand, Message, NetFn, NotEnoughData};
2
3pub struct GetChannelInfo {
7 channel: Channel,
8}
9
10impl GetChannelInfo {
11 pub fn new(channel: Channel) -> Self {
13 Self { channel }
14 }
15}
16
17impl From<GetChannelInfo> for Message {
18 fn from(value: GetChannelInfo) -> Self {
19 let channel = value.channel.value() & 0x0F;
20 Message::new_request(NetFn::App, 0x42, vec![channel])
21 }
22}
23
24impl IpmiCommand for GetChannelInfo {
25 type Output = ChannelInfo;
26 type Error = NotEnoughData;
27
28 fn parse_success_response(data: &[u8]) -> Result<Self::Output, Self::Error> {
29 ChannelInfo::parse(data).ok_or(NotEnoughData)
30 }
31}
32
33#[derive(Clone, Debug, PartialEq)]
35pub struct ChannelInfo {
36 pub channel: Channel,
37 pub medium_type: ChannelMediumType,
38 pub protocol_type: ChannelProtocolType,
39 pub session_support: ChannelSessionSupport,
40 pub active_sessions: u8,
41 pub vendor_id: u32,
42 pub aux_info: AuxChannelInfo,
43}
44
45impl ChannelInfo {
46 pub fn parse(data: &[u8]) -> Option<Self> {
50 if data.len() < 9 {
51 return None;
52 }
53
54 let channel_raw = data[0] & 0x0F;
55 let channel = Channel::new(channel_raw)?;
56
57 let medium_type = ChannelMediumType::from(data[1] & 0x7F);
58 let protocol_type = ChannelProtocolType::from(data[2] & 0x1F);
59
60 let session_support = ChannelSessionSupport::from((data[3] >> 6) & 0x03);
61 let active_sessions = data[3] & 0x3F;
62
63 let vendor_id = u32::from_le_bytes([data[4], data[5], data[6], 0]);
64 let aux_info = AuxChannelInfo {
65 byte1: data[7],
66 byte2: data[8],
67 };
68
69 Some(Self {
70 channel,
71 medium_type,
72 protocol_type,
73 session_support,
74 active_sessions,
75 vendor_id,
76 aux_info,
77 })
78 }
79}
80
81#[derive(Clone, Copy, Debug, PartialEq)]
83pub struct AuxChannelInfo {
84 pub byte1: u8,
85 pub byte2: u8,
86}
87
88#[derive(Clone, Copy, Debug, PartialEq)]
92pub enum ChannelMediumType {
93 Reserved,
94 Ipmb,
95 IcmbV1_0,
96 IcmbV0_9,
97 Lan802_3,
98 AsynchSerialModem,
99 OtherLan,
100 PciSmbus,
101 SmbusV1_0,
102 SmbusV2_0,
103 Usb1X,
104 Usb2X,
105 SystemInterface,
106 Oem(u8),
107 ReservedValue(u8),
108}
109
110impl From<u8> for ChannelMediumType {
111 fn from(value: u8) -> Self {
112 match value {
113 0x00 => Self::Reserved,
114 0x01 => Self::Ipmb,
115 0x02 => Self::IcmbV1_0,
116 0x03 => Self::IcmbV0_9,
117 0x04 => Self::Lan802_3,
118 0x05 => Self::AsynchSerialModem,
119 0x06 => Self::OtherLan,
120 0x07 => Self::PciSmbus,
121 0x08 => Self::SmbusV1_0,
122 0x09 => Self::SmbusV2_0,
123 0x0A => Self::Usb1X,
124 0x0B => Self::Usb2X,
125 0x0C => Self::SystemInterface,
126 0x60..=0x7F => Self::Oem(value),
127 _ => Self::ReservedValue(value),
128 }
129 }
130}
131
132impl core::fmt::Display for ChannelMediumType {
133 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
134 match self {
135 ChannelMediumType::Reserved => write!(f, "Reserved"),
136 ChannelMediumType::Ipmb => write!(f, "IPMB (I2C)"),
137 ChannelMediumType::IcmbV1_0 => write!(f, "ICMB v1.0"),
138 ChannelMediumType::IcmbV0_9 => write!(f, "ICMB v0.9"),
139 ChannelMediumType::Lan802_3 => write!(f, "802.3 LAN"),
140 ChannelMediumType::AsynchSerialModem => write!(f, "Asynchronous Serial/Modem"),
141 ChannelMediumType::OtherLan => write!(f, "Other LAN"),
142 ChannelMediumType::PciSmbus => write!(f, "PCI SMBus"),
143 ChannelMediumType::SmbusV1_0 => write!(f, "SMBus v1.0/1.1"),
144 ChannelMediumType::SmbusV2_0 => write!(f, "SMBus v2.0"),
145 ChannelMediumType::Usb1X => write!(f, "USB 1.x (reserved)"),
146 ChannelMediumType::Usb2X => write!(f, "USB 2.x (reserved)"),
147 ChannelMediumType::SystemInterface => write!(f, "System Interface"),
148 ChannelMediumType::Oem(value) => write!(f, "OEM (0x{value:02X})"),
149 ChannelMediumType::ReservedValue(value) => write!(f, "Reserved (0x{value:02X})"),
150 }
151 }
152}
153
154#[derive(Clone, Copy, Debug, PartialEq)]
158pub enum ChannelProtocolType {
159 Reserved,
160 IpmbV1_0,
161 IcmbV1_0,
162 IpmiSmbus,
163 Kcs,
164 Smic,
165 Bt10,
166 Bt15,
167 TerminalMode,
168 Oem(u8),
169 ReservedValue(u8),
170}
171
172impl From<u8> for ChannelProtocolType {
173 fn from(value: u8) -> Self {
174 match value {
175 0x00 => Self::Reserved,
176 0x01 => Self::IpmbV1_0,
177 0x02 => Self::IcmbV1_0,
178 0x04 => Self::IpmiSmbus,
179 0x05 => Self::Kcs,
180 0x06 => Self::Smic,
181 0x07 => Self::Bt10,
182 0x08 => Self::Bt15,
183 0x09 => Self::TerminalMode,
184 0x1C..=0x1F => Self::Oem(value),
185 _ => Self::ReservedValue(value),
186 }
187 }
188}
189
190impl core::fmt::Display for ChannelProtocolType {
191 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
192 match self {
193 ChannelProtocolType::Reserved => write!(f, "Reserved"),
194 ChannelProtocolType::IpmbV1_0 => write!(f, "IPMB-1.0"),
195 ChannelProtocolType::IcmbV1_0 => write!(f, "ICMB-1.0"),
196 ChannelProtocolType::IpmiSmbus => write!(f, "IPMI-SMBus"),
197 ChannelProtocolType::Kcs => write!(f, "KCS"),
198 ChannelProtocolType::Smic => write!(f, "SMIC"),
199 ChannelProtocolType::Bt10 => write!(f, "BT-10"),
200 ChannelProtocolType::Bt15 => write!(f, "BT-15"),
201 ChannelProtocolType::TerminalMode => write!(f, "Terminal Mode"),
202 ChannelProtocolType::Oem(value) => write!(f, "OEM (0x{value:02X})"),
203 ChannelProtocolType::ReservedValue(value) => write!(f, "Reserved (0x{value:02X})"),
204 }
205 }
206}
207
208#[derive(Clone, Copy, Debug, PartialEq)]
210pub enum ChannelSessionSupport {
211 Sessionless,
212 SingleSession,
213 MultiSession,
214 SessionBased,
215 Reserved(u8),
216}
217
218impl From<u8> for ChannelSessionSupport {
219 fn from(value: u8) -> Self {
220 match value {
221 0x00 => Self::Sessionless,
222 0x01 => Self::SingleSession,
223 0x02 => Self::MultiSession,
224 0x03 => Self::SessionBased,
225 v => Self::Reserved(v),
226 }
227 }
228}
229
230impl core::fmt::Display for ChannelSessionSupport {
231 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
232 match self {
233 ChannelSessionSupport::Sessionless => write!(f, "Session-less"),
234 ChannelSessionSupport::SingleSession => write!(f, "Single-session"),
235 ChannelSessionSupport::MultiSession => write!(f, "Multi-session"),
236 ChannelSessionSupport::SessionBased => write!(f, "Session-based"),
237 ChannelSessionSupport::Reserved(value) => write!(f, "Reserved (0x{value:02X})"),
238 }
239 }
240}