1use crate::mion::cgis::MIONCGIApiError;
2use mac_address::MacAddress;
3use std::{
4 fmt::{Display, Formatter, Result as FmtResult},
5 net::Ipv4Addr,
6};
7
8#[allow(
18 clippy::struct_excessive_bools,
20)]
21#[derive(Clone, Debug, Hash, PartialEq, Eq)]
22pub struct SetupParameters {
23 static_ip_address: Ipv4Addr,
29 subnet_mask: Ipv4Addr,
33 default_gateway: Ipv4Addr,
38 dhcp: bool,
42 dns: bool,
46 primary_dns_server: Ipv4Addr,
51 secondary_dns_server: Ipv4Addr,
56 jumbo_frame: bool,
60 host_pc_ip: Ipv4Addr,
64 bank_size: CatDevBankSize,
68 hdd_bank_no: u8,
73 atapi_emulator_port: u16,
77 sdio_printf_port: u16,
81 sdio_block_port: u16,
85 exi_port: u16,
89 parameter_space_port: u16,
97 drive_timing_emulation: bool,
102 operational_mode_is_reader: bool,
107 drive_product_revision: String,
111 drive_vendor_code: String,
115 drive_device_code: String,
119 drive_release_date: String,
123 device_name: String,
127 mac_address: MacAddress,
131}
132
133impl SetupParameters {
134 #[allow(
136 clippy::too_many_arguments,
138 clippy::fn_params_excessive_bools,
140 )]
141 #[must_use]
142 pub const fn new(
143 static_ip_address: Ipv4Addr,
144 subnet_mask: Ipv4Addr,
145 default_gateway: Ipv4Addr,
146 dhcp: bool,
147 dns: bool,
148 primary_dns_server: Ipv4Addr,
149 secondary_dns_server: Ipv4Addr,
150 jumbo_frame: bool,
151 host_pc_ip: Ipv4Addr,
152 bank_size: CatDevBankSize,
153 hdd_bank_no: u8,
154 atapi_emulator_port: u16,
155 sdio_printf_port: u16,
156 sdio_block_port: u16,
157 exi_port: u16,
158 parameter_space_port: u16,
159 drive_timing_emulation: bool,
160 operational_mode_is_reader: bool,
161 drive_product_revision: String,
162 drive_vendor_code: String,
163 drive_device_code: String,
164 drive_release_date: String,
165 device_name: String,
166 mac_address: MacAddress,
167 ) -> Self {
168 Self {
169 static_ip_address,
170 subnet_mask,
171 default_gateway,
172 dhcp,
173 dns,
174 primary_dns_server,
175 secondary_dns_server,
176 jumbo_frame,
177 host_pc_ip,
178 bank_size,
179 hdd_bank_no,
180 atapi_emulator_port,
181 sdio_printf_port,
182 sdio_block_port,
183 exi_port,
184 parameter_space_port,
185 drive_timing_emulation,
186 operational_mode_is_reader,
187 drive_product_revision,
188 drive_vendor_code,
189 drive_device_code,
190 drive_release_date,
191 device_name,
192 mac_address,
193 }
194 }
195
196 #[must_use]
198 pub fn default_settings(device_name: String, mac_address: MacAddress) -> Self {
199 Self {
200 static_ip_address: Ipv4Addr::new(192, 168, 0, 1),
201 subnet_mask: Ipv4Addr::new(255, 255, 255, 0),
202 default_gateway: Ipv4Addr::new(0, 0, 0, 0),
203 dhcp: true,
204 dns: false,
205 primary_dns_server: Ipv4Addr::new(0, 0, 0, 0),
206 secondary_dns_server: Ipv4Addr::new(0, 0, 0, 0),
207 jumbo_frame: true,
208 host_pc_ip: Ipv4Addr::new(0, 0, 0, 0),
209 bank_size: CatDevBankSize::Blank,
210 hdd_bank_no: 0,
211 atapi_emulator_port: 7974,
212 sdio_printf_port: 7975,
213 sdio_block_port: 7976,
214 exi_port: 7977,
215 parameter_space_port: 7978,
216 drive_timing_emulation: false,
217 operational_mode_is_reader: false,
218 drive_product_revision: String::with_capacity(0),
219 drive_vendor_code: String::with_capacity(0),
220 drive_device_code: String::with_capacity(0),
221 drive_release_date: String::with_capacity(0),
222 device_name,
223 mac_address,
224 }
225 }
226
227 #[must_use]
231 pub const fn static_ip_address(&self) -> Option<Ipv4Addr> {
232 if self.dhcp {
233 None
234 } else {
235 Some(self.static_ip_address)
236 }
237 }
238 #[must_use]
242 pub const fn raw_static_ip_address(&self) -> Ipv4Addr {
243 self.static_ip_address
244 }
245
246 #[must_use]
248 pub const fn subnet_mask(&self) -> Ipv4Addr {
249 self.subnet_mask
250 }
251
252 #[must_use]
254 pub const fn default_gateway(&self) -> Ipv4Addr {
255 self.default_gateway
256 }
257
258 #[must_use]
260 pub const fn using_dhcp(&self) -> bool {
261 self.dhcp
262 }
263
264 #[must_use]
266 pub const fn using_self_managed_dns(&self) -> bool {
267 self.dns
268 }
269 #[must_use]
274 pub const fn primary_dns(&self) -> Option<Ipv4Addr> {
275 if self.dns {
276 Some(self.primary_dns_server)
277 } else {
278 None
279 }
280 }
281 #[must_use]
285 pub const fn raw_primary_dns(&self) -> Ipv4Addr {
286 self.primary_dns_server
287 }
288 #[must_use]
293 pub const fn secondary_dns(&self) -> Option<Ipv4Addr> {
294 if self.dns {
295 Some(self.secondary_dns_server)
296 } else {
297 None
298 }
299 }
300 #[must_use]
304 pub const fn raw_secondary_dns(&self) -> Ipv4Addr {
305 self.secondary_dns_server
306 }
307
308 #[must_use]
310 pub const fn jumbo_frame(&self) -> bool {
311 self.jumbo_frame
312 }
313
314 #[must_use]
316 pub const fn host_pc_ip_address(&self) -> Ipv4Addr {
317 self.host_pc_ip
318 }
319
320 #[must_use]
322 pub const fn hdd_bank_size(&self) -> CatDevBankSize {
323 self.bank_size
324 }
325
326 #[must_use]
328 pub const fn hdd_bank_no(&self) -> u8 {
329 self.hdd_bank_no
330 }
331
332 #[must_use]
334 pub const fn atapi_emulator_port(&self) -> u16 {
335 self.atapi_emulator_port
336 }
337
338 #[must_use]
340 pub const fn sdio_printf_port(&self) -> u16 {
341 self.sdio_printf_port
342 }
343
344 #[must_use]
346 pub const fn sdio_block_port(&self) -> u16 {
347 self.sdio_block_port
348 }
349
350 #[must_use]
352 pub const fn exi_port(&self) -> u16 {
353 self.exi_port
354 }
355
356 #[must_use]
358 pub const fn parameter_space_port(&self) -> u16 {
359 self.parameter_space_port
360 }
361
362 #[must_use]
364 pub const fn drive_timing_emulation_enabled(&self) -> bool {
365 self.drive_timing_emulation
366 }
367
368 #[must_use]
370 pub const fn is_cat_dev_mode(&self) -> bool {
371 !self.operational_mode_is_reader
372 }
373 #[must_use]
375 pub const fn is_h_reader_mode(&self) -> bool {
376 self.operational_mode_is_reader
377 }
378
379 #[must_use]
381 pub const fn drive_product_revision(&self) -> &String {
382 &self.drive_product_revision
383 }
384
385 #[must_use]
387 pub const fn drive_vendor_code(&self) -> &String {
388 &self.drive_vendor_code
389 }
390
391 #[must_use]
393 pub const fn drive_device_code(&self) -> &String {
394 &self.drive_device_code
395 }
396
397 #[must_use]
399 pub const fn drive_release_date(&self) -> &String {
400 &self.drive_release_date
401 }
402
403 #[must_use]
405 pub const fn device_name(&self) -> &String {
406 &self.device_name
407 }
408
409 #[must_use]
410 pub const fn mac_address(&self) -> MacAddress {
411 self.mac_address
412 }
413}
414
415#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
421pub enum CatDevBankSize {
422 Blank,
424 TwentyFiveGbs,
426 FiveGbs,
428 NineGbs,
430 TwelveGbs,
432 FourteenGbs,
434 SixteenGbs,
436 EighteenGbs,
438 TwentyOneGbs,
440}
441impl From<&CatDevBankSize> for u32 {
442 fn from(size: &CatDevBankSize) -> u32 {
443 match *size {
444 CatDevBankSize::Blank => 4_294_967_295,
445 CatDevBankSize::TwentyFiveGbs => 0,
446 CatDevBankSize::FiveGbs => 1,
447 CatDevBankSize::NineGbs => 2,
448 CatDevBankSize::TwelveGbs => 3,
449 CatDevBankSize::FourteenGbs => 4,
450 CatDevBankSize::SixteenGbs => 5,
451 CatDevBankSize::EighteenGbs => 6,
452 CatDevBankSize::TwentyOneGbs => 7,
453 }
454 }
455}
456impl From<CatDevBankSize> for u32 {
457 fn from(value: CatDevBankSize) -> Self {
458 Self::from(&value)
459 }
460}
461impl TryFrom<u32> for CatDevBankSize {
462 type Error = MIONCGIApiError;
463
464 fn try_from(value: u32) -> Result<Self, Self::Error> {
465 match value {
466 u32::MAX => Ok(Self::Blank),
467 0 => Ok(Self::TwentyFiveGbs),
468 1 => Ok(Self::FiveGbs),
469 2 => Ok(Self::NineGbs),
470 3 => Ok(Self::TwelveGbs),
471 4 => Ok(Self::FourteenGbs),
472 5 => Ok(Self::SixteenGbs),
473 6 => Ok(Self::EighteenGbs),
474 7 => Ok(Self::TwentyOneGbs),
475 _ => Err(MIONCGIApiError::UnknownCatDevBankSizeId(value)),
476 }
477 }
478}
479impl Display for CatDevBankSize {
480 fn fmt(&self, fmt: &mut Formatter<'_>) -> FmtResult {
481 write!(
482 fmt,
483 "{}",
484 match *self {
485 Self::Blank => " ",
486 Self::TwentyFiveGbs => "25GB",
487 Self::FiveGbs => "5GB",
488 Self::NineGbs => "9GB",
489 Self::TwelveGbs => "12GB",
490 Self::FourteenGbs => "14GB",
491 Self::SixteenGbs => "16GB",
492 Self::EighteenGbs => "18GB",
493 Self::TwentyOneGbs => "21GB",
494 }
495 )
496 }
497}
498
499#[cfg(test)]
500mod unit_tests {
501 use super::*;
502
503 #[test]
504 pub fn convert_bank_size() {
505 for bank_size in vec![
506 CatDevBankSize::Blank,
507 CatDevBankSize::TwentyFiveGbs,
508 CatDevBankSize::FiveGbs,
509 CatDevBankSize::NineGbs,
510 CatDevBankSize::TwelveGbs,
511 CatDevBankSize::FourteenGbs,
512 CatDevBankSize::SixteenGbs,
513 CatDevBankSize::EighteenGbs,
514 CatDevBankSize::TwentyOneGbs,
515 ] {
516 assert_eq!(
517 Ok(bank_size),
518 CatDevBankSize::try_from(u32::from(bank_size)),
519 "bank size: {} was not the same after converting it back & forth",
520 bank_size,
521 );
522 }
523 }
524}