This commit is contained in:
@@ -31,6 +31,38 @@ fn exec(tool: &str, args: &[&str]) -> Result<String, String> {
|
||||
Err(format!("{tool} ({})\n{log}", out.status))
|
||||
}
|
||||
}
|
||||
fn mobile_chassis(value: &str) -> bool {
|
||||
matches!(
|
||||
value.trim(),
|
||||
"8" | "9" | "10" | "11" | "14" | "30" | "31" | "32"
|
||||
)
|
||||
}
|
||||
fn mobile_device() -> bool {
|
||||
let chassis = fs::read_to_string("/sys/class/dmi/id/chassis_type")
|
||||
.or_else(|_| fs::read_to_string("/run/csr-intake/chassis_type"))
|
||||
.unwrap_or_default();
|
||||
if mobile_chassis(&chassis) {
|
||||
return true;
|
||||
}
|
||||
fs::read_dir("/sys/class/power_supply").is_ok_and(|entries| {
|
||||
entries.flatten().any(|entry| {
|
||||
fs::read_to_string(entry.path().join("type")).is_ok_and(|kind| kind.trim() == "Battery")
|
||||
})
|
||||
})
|
||||
}
|
||||
fn wired_link_active() -> bool {
|
||||
fs::read_dir("/sys/class/net").is_ok_and(|entries| {
|
||||
entries.flatten().any(|entry| {
|
||||
let path = entry.path();
|
||||
entry.file_name() != "lo"
|
||||
&& !path.join("wireless").exists()
|
||||
&& fs::read_to_string(path.join("carrier")).is_ok_and(|v| v.trim() == "1")
|
||||
})
|
||||
})
|
||||
}
|
||||
pub fn needs_lan_disconnect() -> bool {
|
||||
mobile_device() && wired_link_active()
|
||||
}
|
||||
fn temps() -> Vec<(String, f64)> {
|
||||
let mut values = Vec::new();
|
||||
let Ok(chips) = fs::read_dir("/sys/class/hwmon") else {
|
||||
@@ -316,7 +348,12 @@ fn run_legacy(tool: &str, settings: &crate::workflow::Settings) -> (bool, String
|
||||
&["-f", "IN-USE,SSID,SIGNAL", "device", "wifi", "list"],
|
||||
)
|
||||
.unwrap_or_else(|e| e);
|
||||
(true,format!("Status:\n{status}\nGeräte:\n{dev}\nNetze:\n{scan}\nLAN trennen und WLAN-Verbindung aktiv testen; Sichtbarkeit ist noch kein PASS."))
|
||||
let lan = if needs_lan_disconnect() {
|
||||
"\nWARNUNG: Mobiles Gerät mit aktiver LAN-Verbindung. LAN-Kabel vor dem WLAN-Test entfernen."
|
||||
} else {
|
||||
""
|
||||
};
|
||||
(true,format!("Status:\n{status}\nGeräte:\n{dev}\nNetze:\n{scan}{lan}\nWLAN-Verbindung aktiv testen; Sichtbarkeit ist noch kein PASS."))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -479,4 +516,14 @@ mod tests {
|
||||
);
|
||||
assert_eq!(peak_temperature("PEAK_TEMPERATURE_C=NaN"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn portable_chassis_types_are_recognized() {
|
||||
for value in ["8", "9", "10", "11", "14", "30", "31", "32"] {
|
||||
assert!(mobile_chassis(value));
|
||||
}
|
||||
for value in ["3", "7", "13", "15", "unknown"] {
|
||||
assert!(!mobile_chassis(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -650,6 +650,15 @@ impl App {
|
||||
));
|
||||
if let Some(d) = &self.station_device {
|
||||
ui.heading(format!("#{}", d["number"]));
|
||||
match d["_registration"].as_str() {
|
||||
Some("NEW") => {
|
||||
ui.colored_label(GREEN, tr(en, "Neu im Inventory registriert", "Newly registered in inventory"));
|
||||
}
|
||||
Some("EXISTING") => {
|
||||
ui.label(tr(en, "Bereits im Inventory vorhanden", "Existing inventory device"));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
let stage = match d["stage"].as_str().unwrap_or("") {
|
||||
"INTAKE" => "Eingang",
|
||||
"INSPECTION" => "Inspektion",
|
||||
@@ -912,6 +921,16 @@ impl App {
|
||||
}
|
||||
ui.add_enabled_ui(!conflict, |ui| {
|
||||
if key == "wifi" {
|
||||
if diagnostics::needs_lan_disconnect() {
|
||||
ui.colored_label(
|
||||
ORANGE,
|
||||
tr(
|
||||
en,
|
||||
"LAN-Kabel entfernen: Bei diesem mobilen Gerät muss der WLAN-Test ohne aktive Kabelverbindung erfolgen.",
|
||||
"Disconnect Ethernet: test Wi-Fi on this mobile device without an active wired connection.",
|
||||
),
|
||||
);
|
||||
}
|
||||
self.wifi.set_language(en);
|
||||
let was_busy = self.wifi.busy();
|
||||
self.wifi.ui(ui, self.receiver.is_some());
|
||||
@@ -1437,6 +1456,29 @@ impl App {
|
||||
ui.selectable_value(&mut self.settings_draft.language, "de".into(), "Deutsch");
|
||||
ui.selectable_value(&mut self.settings_draft.language, "en".into(), "English");
|
||||
});
|
||||
ui.label(tr(en, "Tastaturbelegung", "Keyboard layout"));
|
||||
egui::ComboBox::from_id_salt("keyboard-layout")
|
||||
.selected_text(match self.settings_draft.keyboard_layout.as_str() {
|
||||
"us" => "English (US)",
|
||||
_ => "Deutsch (DE)",
|
||||
})
|
||||
.show_ui(ui, |ui| {
|
||||
ui.selectable_value(
|
||||
&mut self.settings_draft.keyboard_layout,
|
||||
"de".into(),
|
||||
"Deutsch (DE)",
|
||||
);
|
||||
ui.selectable_value(
|
||||
&mut self.settings_draft.keyboard_layout,
|
||||
"us".into(),
|
||||
"English (US)",
|
||||
);
|
||||
});
|
||||
ui.small(tr(
|
||||
en,
|
||||
"Die Tastaturbelegung wird beim nächsten Start des USB-Systems angewendet.",
|
||||
"The keyboard layout is applied on the next USB-system boot.",
|
||||
));
|
||||
ui.label(tr(en, "WLAN-Testserver", "Wi-Fi test server"));
|
||||
ui.text_edit_singleline(&mut self.settings_draft.test_url);
|
||||
ui.horizontal(|ui| {
|
||||
|
||||
@@ -86,6 +86,7 @@ pub fn init_index(data: &Path) -> Result<(), String> {
|
||||
#[serde(default)]
|
||||
pub struct Settings {
|
||||
pub language: String,
|
||||
pub keyboard_layout: String,
|
||||
pub test_url: String,
|
||||
pub stress_seconds: u64,
|
||||
pub recording_seconds: u64,
|
||||
@@ -98,6 +99,7 @@ impl Default for Settings {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
language: "de".into(),
|
||||
keyboard_layout: "de".into(),
|
||||
test_url: "https://example.com".into(),
|
||||
stress_seconds: 120,
|
||||
recording_seconds: 5,
|
||||
@@ -113,6 +115,9 @@ impl Settings {
|
||||
if !["de", "en"].contains(&self.language.as_str()) {
|
||||
return Err("Language must be de or en".into());
|
||||
}
|
||||
if !["de", "us"].contains(&self.keyboard_layout.as_str()) {
|
||||
return Err("Keyboard layout must be de or us".into());
|
||||
}
|
||||
if !(self.test_url.starts_with("https://") || self.test_url.starts_with("http://"))
|
||||
|| self.test_url.contains(['\n', '\r'])
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user