use std::time::Duration;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ConnectionType {
EthernetServer,
WifiServer,
EthernetClient,
WifiClient,
Unknown(u8),
}
impl ConnectionType {
pub fn from_status_byte(raw: u8) -> Self {
match raw {
0 => Self::EthernetServer,
1 => Self::WifiServer,
2 => Self::EthernetClient,
3 => Self::WifiClient,
other => Self::Unknown(other),
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ProfileSource {
DesktopNetworkDefault,
UnknownConservative,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct ConnectionProfile {
pub source: ProfileSource,
pub connection_type: ConnectionType,
pub remote_buffer_cutoff: usize,
pub wait_buffer_sleep: Duration,
pub max_udp_samples_per_packet: usize,
pub buffer_total: usize,
}
impl ConnectionProfile {
pub fn for_connection(connection_type: ConnectionType, buffer_total: usize) -> Self {
match connection_type {
ConnectionType::WifiServer => {
Self::desktop(connection_type, 2000, 4, 140, buffer_total)
}
ConnectionType::EthernetServer
| ConnectionType::EthernetClient
| ConnectionType::WifiClient => {
Self::desktop(connection_type, 1800, 6, 80, buffer_total)
}
ConnectionType::Unknown(_) => Self::unknown_conservative(buffer_total),
}
}
pub fn unknown_conservative(buffer_total: usize) -> Self {
Self {
source: ProfileSource::UnknownConservative,
connection_type: ConnectionType::Unknown(0),
remote_buffer_cutoff: 1800.min(buffer_total),
wait_buffer_sleep: Duration::from_millis(6),
max_udp_samples_per_packet: 80,
buffer_total,
}
}
fn desktop(
connection_type: ConnectionType,
remote_buffer_cutoff: usize,
wait_buffer_sleep_ms: u64,
max_udp_samples_per_packet: usize,
buffer_total: usize,
) -> Self {
Self {
source: ProfileSource::DesktopNetworkDefault,
connection_type,
remote_buffer_cutoff: remote_buffer_cutoff.min(buffer_total),
wait_buffer_sleep: Duration::from_millis(wait_buffer_sleep_ms),
max_udp_samples_per_packet,
buffer_total,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn selects_desktop_network_profiles() {
assert_eq!(
ConnectionProfile::for_connection(ConnectionType::EthernetServer, 6000)
.max_udp_samples_per_packet,
80
);
assert_eq!(
ConnectionProfile::for_connection(ConnectionType::WifiServer, 6000)
.max_udp_samples_per_packet,
140
);
assert_eq!(
ConnectionProfile::for_connection(ConnectionType::WifiClient, 6000)
.max_udp_samples_per_packet,
80
);
}
#[test]
fn unknown_uses_conservative_80_sample_packets() {
let profile = ConnectionProfile::for_connection(ConnectionType::Unknown(99), 6000);
assert_eq!(profile.source, ProfileSource::UnknownConservative);
assert_eq!(profile.max_udp_samples_per_packet, 80);
}
#[test]
fn full_info_connection_type_is_zero_based() {
assert_eq!(
ConnectionType::from_status_byte(0),
ConnectionType::EthernetServer
);
assert_eq!(
ConnectionType::from_status_byte(1),
ConnectionType::WifiServer
);
assert_eq!(
ConnectionType::from_status_byte(2),
ConnectionType::EthernetClient
);
assert_eq!(
ConnectionType::from_status_byte(3),
ConnectionType::WifiClient
);
assert_eq!(
ConnectionType::from_status_byte(4),
ConnectionType::Unknown(4)
);
}
}