1use crate::connection::{Channel, IpmiCommand, Message, NetFn, NotEnoughData};
2
3pub struct GetChannelAccess {
11 channel: Channel,
12 access_type: ChannelAccessType,
13}
14
15impl GetChannelAccess {
16 pub fn new(channel: Channel, access_type: ChannelAccessType) -> Self {
21 Self {
22 channel,
23 access_type,
24 }
25 }
26
27 pub fn non_volatile(channel: Channel) -> Self {
29 Self::new(channel, ChannelAccessType::NonVolatile)
30 }
31
32 pub fn volatile(channel: Channel) -> Self {
34 Self::new(channel, ChannelAccessType::Volatile)
35 }
36}
37
38impl From<GetChannelAccess> for Message {
39 fn from(value: GetChannelAccess) -> Self {
40 let channel = value.channel.value() & 0x0F;
41 let access_type = match value.access_type {
42 ChannelAccessType::NonVolatile => 0x40, ChannelAccessType::Volatile => 0x80, };
45 Message::new_request(NetFn::App, 0x41, vec![channel, access_type])
46 }
47}
48
49impl IpmiCommand for GetChannelAccess {
50 type Output = ChannelAccess;
51 type Error = NotEnoughData;
52
53 fn parse_success_response(data: &[u8]) -> Result<Self::Output, Self::Error> {
54 ChannelAccess::parse(data).ok_or(NotEnoughData)
55 }
56}
57
58#[derive(Clone, Copy, Debug, PartialEq)]
60pub enum ChannelAccessType {
61 NonVolatile,
63 Volatile,
65}
66
67#[derive(Clone, Debug, PartialEq)]
69pub struct ChannelAccess {
70 pub access_mode: ChannelAccessMode,
72 pub alerting_disabled: bool,
74 pub per_msg_auth_disabled: bool,
76 pub user_level_auth_disabled: bool,
78 pub privilege_level_limit: ChannelPrivilegeLevel,
80}
81
82impl ChannelAccess {
83 pub fn parse(data: &[u8]) -> Option<Self> {
87 if data.len() < 2 {
88 return None;
89 }
90
91 let access_mode = ChannelAccessMode::from(data[0] & 0x07);
92 let alerting_disabled = (data[0] & 0x20) == 0x20;
93 let per_msg_auth_disabled = (data[0] & 0x10) == 0x10;
94 let user_level_auth_disabled = (data[0] & 0x08) == 0x08;
95
96 let privilege_level_limit = ChannelPrivilegeLevel::from(data[1] & 0x0F);
97
98 Some(Self {
99 access_mode,
100 alerting_disabled,
101 per_msg_auth_disabled,
102 user_level_auth_disabled,
103 privilege_level_limit,
104 })
105 }
106
107 pub fn is_disabled(&self) -> bool {
109 matches!(self.access_mode, ChannelAccessMode::Disabled)
110 }
111}
112
113#[derive(Clone, Copy, Debug, PartialEq)]
117pub enum ChannelAccessMode {
118 Disabled,
120 PreBootOnly,
122 AlwaysAvailable,
124 Shared,
126 Unknown(u8),
128}
129
130impl From<u8> for ChannelAccessMode {
131 fn from(value: u8) -> Self {
132 match value {
133 0x00 => Self::Disabled,
134 0x01 => Self::PreBootOnly,
135 0x02 => Self::AlwaysAvailable,
136 0x03 => Self::Shared,
137 v => Self::Unknown(v),
138 }
139 }
140}
141
142impl core::fmt::Display for ChannelAccessMode {
143 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
144 match self {
145 ChannelAccessMode::Disabled => write!(f, "Disabled"),
146 ChannelAccessMode::PreBootOnly => write!(f, "Pre-boot Only"),
147 ChannelAccessMode::AlwaysAvailable => write!(f, "Always Available"),
148 ChannelAccessMode::Shared => write!(f, "Shared"),
149 ChannelAccessMode::Unknown(value) => write!(f, "Unknown (0x{value:02X})"),
150 }
151 }
152}
153
154#[derive(Clone, Copy, Debug, PartialEq)]
158pub enum ChannelPrivilegeLevel {
159 Reserved,
161 Callback,
163 User,
165 Operator,
167 Administrator,
169 Oem,
171 Unknown(u8),
173}
174
175impl From<u8> for ChannelPrivilegeLevel {
176 fn from(value: u8) -> Self {
177 match value {
178 0x00 => Self::Reserved,
179 0x01 => Self::Callback,
180 0x02 => Self::User,
181 0x03 => Self::Operator,
182 0x04 => Self::Administrator,
183 0x05 => Self::Oem,
184 v => Self::Unknown(v),
185 }
186 }
187}
188
189impl core::fmt::Display for ChannelPrivilegeLevel {
190 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
191 match self {
192 ChannelPrivilegeLevel::Reserved => write!(f, "Reserved"),
193 ChannelPrivilegeLevel::Callback => write!(f, "Callback"),
194 ChannelPrivilegeLevel::User => write!(f, "User"),
195 ChannelPrivilegeLevel::Operator => write!(f, "Operator"),
196 ChannelPrivilegeLevel::Administrator => write!(f, "Administrator"),
197 ChannelPrivilegeLevel::Oem => write!(f, "OEM"),
198 ChannelPrivilegeLevel::Unknown(value) => write!(f, "Unknown (0x{value:02X})"),
199 }
200 }
201}