use packed_struct::prelude::PackedStruct;
use crate::network::util::checksum;
#[derive(Debug)]
pub enum WirelessConnection<'a> {
None(&'a str),
WEP(&'a str, &'a str),
WPA1(&'a str, &'a str),
WPA2(&'a str, &'a str),
WPA(&'a str, &'a str),
}
#[derive(PackedStruct, Debug)]
#[packed_struct(bit_numbering = "msb0", endian = "lsb", size_bytes = "136")]
pub struct WirelessConnectionMessage {
#[packed_field(bytes = "32:33")]
checksum: u16,
#[packed_field(bytes = "38")]
magic_constant: i8,
#[packed_field(bytes = "68:99")]
ssid: [u8; 32],
#[packed_field(bytes = "100:131")]
password: [u8; 32],
#[packed_field(bytes = "132")]
ssid_length: u8,
#[packed_field(bytes = "133")]
password_length: u8,
#[packed_field(bytes = "134")]
security_mode: u8,
}
impl WirelessConnection<'_> {
pub fn to_message(&self) -> Result<WirelessConnectionMessage, String> {
let empty_pass = "";
let (ssid, pass, security_mode) = match self {
WirelessConnection::None(ssid) => (ssid, &empty_pass, 0),
WirelessConnection::WEP(ssid, pass) => (ssid, pass, 1),
WirelessConnection::WPA1(ssid, pass) => (ssid, pass, 2),
WirelessConnection::WPA2(ssid, pass) => (ssid, pass, 3),
WirelessConnection::WPA(ssid, pass) => (ssid, pass, 4),
};
if ssid.len() > 32 {
return Err("Could not use provided SSID! SSID longer than 32 characters.".into());
}
let mut ssid_fixed = [0u8; 32];
let mut pass_fixed = [0u8; 32];
for (i, c) in ssid.as_bytes().iter().enumerate() {
ssid_fixed[i] = *c;
}
for (i, c) in pass.as_bytes().iter().enumerate() {
pass_fixed[i] = *c;
}
let mut msg = WirelessConnectionMessage {
checksum: 0,
magic_constant: 0x14,
ssid: ssid_fixed,
password: pass_fixed,
ssid_length: u8::try_from(ssid.len()).map_err(|e| {
format!(
"Could not use provided SSID! SSID is too long (max 32 characters). {}",
e
)
})?,
password_length: u8::try_from(pass.len()).map_err(|e| {
format!(
"Could not use provided password! Password is too long (max 32 characters). {}",
e
)
})?,
security_mode: security_mode,
};
msg.checksum = checksum(
&msg.pack()
.map_err(|e| format!("Could not pack WirelessConnectionMessage! {}", e))?,
);
return Ok(msg);
}
}