1use crate::mion::proto::cgis::MionCGIErrors;
2#[cfg(feature = "clients")]
3use mac_address::MacAddress;
4use std::fmt::{Display, Formatter, Result as FmtResult};
5use std::net::Ipv4Addr;
6
7#[allow(
17 clippy::struct_excessive_bools,
19)]
20#[cfg_attr(docsrs, doc(cfg(feature = "clients")))]
21#[cfg(feature = "clients")]
22#[derive(Clone, Debug, Hash, PartialEq, Eq)]
23pub struct SetupParameters {
24 static_ip_address: Ipv4Addr,
30 subnet_mask: Ipv4Addr,
34 default_gateway: Ipv4Addr,
39 dhcp: bool,
43 dns: bool,
47 primary_dns_server: Ipv4Addr,
52 secondary_dns_server: Ipv4Addr,
57 jumbo_frame: bool,
61 host_pc_ip: Ipv4Addr,
65 bank_size: CatDevBankSize,
69 hdd_bank_no: u8,
74 atapi_emulator_port: u16,
78 sdio_printf_port: u16,
82 sdio_block_port: u16,
86 exi_port: u16,
90 parameter_space_port: u16,
98 drive_timing_emulation: bool,
103 operational_mode_is_reader: bool,
108 drive_product_revision: String,
112 drive_vendor_code: String,
116 drive_device_code: String,
120 drive_release_date: String,
124 device_name: String,
128 mac_address: MacAddress,
132}
133
134#[cfg_attr(docsrs, doc(cfg(feature = "clients")))]
135#[cfg(feature = "clients")]
136impl SetupParameters {
137 #[allow(
139 clippy::too_many_arguments,
141 clippy::fn_params_excessive_bools,
143 )]
144 #[must_use]
145 pub const fn new(
146 static_ip_address: Ipv4Addr,
147 subnet_mask: Ipv4Addr,
148 default_gateway: Ipv4Addr,
149 dhcp: bool,
150 dns: bool,
151 primary_dns_server: Ipv4Addr,
152 secondary_dns_server: Ipv4Addr,
153 jumbo_frame: bool,
154 host_pc_ip: Ipv4Addr,
155 bank_size: CatDevBankSize,
156 hdd_bank_no: u8,
157 atapi_emulator_port: u16,
158 sdio_printf_port: u16,
159 sdio_block_port: u16,
160 exi_port: u16,
161 parameter_space_port: u16,
162 drive_timing_emulation: bool,
163 operational_mode_is_reader: bool,
164 drive_product_revision: String,
165 drive_vendor_code: String,
166 drive_device_code: String,
167 drive_release_date: String,
168 device_name: String,
169 mac_address: MacAddress,
170 ) -> Self {
171 Self {
172 static_ip_address,
173 subnet_mask,
174 default_gateway,
175 dhcp,
176 dns,
177 primary_dns_server,
178 secondary_dns_server,
179 jumbo_frame,
180 host_pc_ip,
181 bank_size,
182 hdd_bank_no,
183 atapi_emulator_port,
184 sdio_printf_port,
185 sdio_block_port,
186 exi_port,
187 parameter_space_port,
188 drive_timing_emulation,
189 operational_mode_is_reader,
190 drive_product_revision,
191 drive_vendor_code,
192 drive_device_code,
193 drive_release_date,
194 device_name,
195 mac_address,
196 }
197 }
198
199 #[must_use]
201 pub fn default_settings(device_name: String, mac_address: MacAddress) -> Self {
202 Self {
203 static_ip_address: Ipv4Addr::new(192, 168, 0, 1),
204 subnet_mask: Ipv4Addr::new(255, 255, 255, 0),
205 default_gateway: Ipv4Addr::UNSPECIFIED,
206 dhcp: true,
207 dns: false,
208 primary_dns_server: Ipv4Addr::UNSPECIFIED,
209 secondary_dns_server: Ipv4Addr::UNSPECIFIED,
210 jumbo_frame: true,
211 host_pc_ip: Ipv4Addr::UNSPECIFIED,
212 bank_size: CatDevBankSize::Blank,
213 hdd_bank_no: 0,
214 atapi_emulator_port: 7974,
215 sdio_printf_port: 7975,
216 sdio_block_port: 7976,
217 exi_port: 7977,
218 parameter_space_port: 7978,
219 drive_timing_emulation: false,
220 operational_mode_is_reader: false,
221 drive_product_revision: String::with_capacity(0),
222 drive_vendor_code: String::with_capacity(0),
223 drive_device_code: String::with_capacity(0),
224 drive_release_date: String::with_capacity(0),
225 device_name,
226 mac_address,
227 }
228 }
229
230 #[must_use]
234 pub const fn static_ip_address(&self) -> Option<Ipv4Addr> {
235 if self.dhcp {
236 None
237 } else {
238 Some(self.static_ip_address)
239 }
240 }
241 #[must_use]
245 pub const fn raw_static_ip_address(&self) -> Ipv4Addr {
246 self.static_ip_address
247 }
248
249 #[must_use]
251 pub const fn subnet_mask(&self) -> Ipv4Addr {
252 self.subnet_mask
253 }
254
255 #[must_use]
257 pub const fn default_gateway(&self) -> Ipv4Addr {
258 self.default_gateway
259 }
260
261 #[must_use]
263 pub const fn using_dhcp(&self) -> bool {
264 self.dhcp
265 }
266
267 #[must_use]
269 pub const fn using_self_managed_dns(&self) -> bool {
270 self.dns
271 }
272 #[must_use]
277 pub const fn primary_dns(&self) -> Option<Ipv4Addr> {
278 if self.dns {
279 Some(self.primary_dns_server)
280 } else {
281 None
282 }
283 }
284 #[must_use]
288 pub const fn raw_primary_dns(&self) -> Ipv4Addr {
289 self.primary_dns_server
290 }
291 #[must_use]
296 pub const fn secondary_dns(&self) -> Option<Ipv4Addr> {
297 if self.dns {
298 Some(self.secondary_dns_server)
299 } else {
300 None
301 }
302 }
303 #[must_use]
307 pub const fn raw_secondary_dns(&self) -> Ipv4Addr {
308 self.secondary_dns_server
309 }
310
311 #[must_use]
313 pub const fn jumbo_frame(&self) -> bool {
314 self.jumbo_frame
315 }
316
317 #[must_use]
319 pub const fn host_pc_ip_address(&self) -> Ipv4Addr {
320 self.host_pc_ip
321 }
322
323 #[must_use]
325 pub const fn hdd_bank_size(&self) -> CatDevBankSize {
326 self.bank_size
327 }
328
329 #[must_use]
331 pub const fn hdd_bank_no(&self) -> u8 {
332 self.hdd_bank_no
333 }
334
335 #[must_use]
337 pub const fn atapi_emulator_port(&self) -> u16 {
338 self.atapi_emulator_port
339 }
340
341 #[must_use]
343 pub const fn sdio_printf_port(&self) -> u16 {
344 self.sdio_printf_port
345 }
346
347 #[must_use]
349 pub const fn sdio_block_port(&self) -> u16 {
350 self.sdio_block_port
351 }
352
353 #[must_use]
355 pub const fn exi_port(&self) -> u16 {
356 self.exi_port
357 }
358
359 #[must_use]
361 pub const fn parameter_space_port(&self) -> u16 {
362 self.parameter_space_port
363 }
364
365 #[must_use]
367 pub const fn drive_timing_emulation_enabled(&self) -> bool {
368 self.drive_timing_emulation
369 }
370
371 #[must_use]
373 pub const fn is_cat_dev_mode(&self) -> bool {
374 !self.operational_mode_is_reader
375 }
376 #[must_use]
378 pub const fn is_h_reader_mode(&self) -> bool {
379 self.operational_mode_is_reader
380 }
381
382 #[must_use]
384 pub const fn drive_product_revision(&self) -> &String {
385 &self.drive_product_revision
386 }
387
388 #[must_use]
390 pub const fn drive_vendor_code(&self) -> &String {
391 &self.drive_vendor_code
392 }
393
394 #[must_use]
396 pub const fn drive_device_code(&self) -> &String {
397 &self.drive_device_code
398 }
399
400 #[must_use]
402 pub const fn drive_release_date(&self) -> &String {
403 &self.drive_release_date
404 }
405
406 #[must_use]
408 pub const fn device_name(&self) -> &String {
409 &self.device_name
410 }
411
412 #[must_use]
413 pub const fn mac_address(&self) -> MacAddress {
414 self.mac_address
415 }
416}
417
418#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
424pub enum CatDevBankSize {
425 Blank,
427 TwentyFiveGbs,
429 FiveGbs,
431 NineGbs,
433 TwelveGbs,
435 FourteenGbs,
437 SixteenGbs,
439 EighteenGbs,
441 TwentyOneGbs,
443}
444impl From<&CatDevBankSize> for u32 {
445 fn from(size: &CatDevBankSize) -> u32 {
446 match *size {
447 CatDevBankSize::Blank => 4_294_967_295,
448 CatDevBankSize::TwentyFiveGbs => 0,
449 CatDevBankSize::FiveGbs => 1,
450 CatDevBankSize::NineGbs => 2,
451 CatDevBankSize::TwelveGbs => 3,
452 CatDevBankSize::FourteenGbs => 4,
453 CatDevBankSize::SixteenGbs => 5,
454 CatDevBankSize::EighteenGbs => 6,
455 CatDevBankSize::TwentyOneGbs => 7,
456 }
457 }
458}
459impl From<CatDevBankSize> for u32 {
460 fn from(value: CatDevBankSize) -> Self {
461 Self::from(&value)
462 }
463}
464impl TryFrom<u32> for CatDevBankSize {
465 type Error = MionCGIErrors;
466
467 fn try_from(value: u32) -> Result<Self, Self::Error> {
468 match value {
469 u32::MAX => Ok(Self::Blank),
470 0 => Ok(Self::TwentyFiveGbs),
471 1 => Ok(Self::FiveGbs),
472 2 => Ok(Self::NineGbs),
473 3 => Ok(Self::TwelveGbs),
474 4 => Ok(Self::FourteenGbs),
475 5 => Ok(Self::SixteenGbs),
476 6 => Ok(Self::EighteenGbs),
477 7 => Ok(Self::TwentyOneGbs),
478 _ => Err(MionCGIErrors::UnknownCatDevBankSizeId(value)),
479 }
480 }
481}
482impl Display for CatDevBankSize {
483 fn fmt(&self, fmt: &mut Formatter<'_>) -> FmtResult {
484 write!(
485 fmt,
486 "{}",
487 match *self {
488 Self::Blank => " ",
489 Self::TwentyFiveGbs => "25GB",
490 Self::FiveGbs => "5GB",
491 Self::NineGbs => "9GB",
492 Self::TwelveGbs => "12GB",
493 Self::FourteenGbs => "14GB",
494 Self::SixteenGbs => "16GB",
495 Self::EighteenGbs => "18GB",
496 Self::TwentyOneGbs => "21GB",
497 }
498 )
499 }
500}
501
502#[cfg(test)]
503mod unit_tests {
504 use super::*;
505
506 #[test]
507 pub fn convert_bank_size() {
508 for bank_size in vec![
509 CatDevBankSize::Blank,
510 CatDevBankSize::TwentyFiveGbs,
511 CatDevBankSize::FiveGbs,
512 CatDevBankSize::NineGbs,
513 CatDevBankSize::TwelveGbs,
514 CatDevBankSize::FourteenGbs,
515 CatDevBankSize::SixteenGbs,
516 CatDevBankSize::EighteenGbs,
517 CatDevBankSize::TwentyOneGbs,
518 ] {
519 assert_eq!(
520 Ok(bank_size),
521 CatDevBankSize::try_from(u32::from(bank_size)),
522 "bank size: {} was not the same after converting it back & forth",
523 bank_size,
524 );
525 }
526 }
527}