From f1a4b4b251124b98e1f610e04fd8e986d68d400f Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Mon, 19 Jun 2023 13:42:26 -0400 Subject: [PATCH 01/62] Add notes for auto-serial check --- notes.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/notes.md b/notes.md index 9c5d16e..db3d9d9 100644 --- a/notes.md +++ b/notes.md @@ -1,8 +1,7 @@ -Boot time isn't static. -Boot time can (in theory) be sped up by forcing a clearing of the screen of all vitals before rebooting. -Clearing the screen of all vitals is theoretically possible in the UI menu, with a Spoof Touch, but I don't know the object name of the 'clear' button. +Auto-serial: -Can check for reboot completed by reading in serial, check for `reboot: Restarting System` -once done, read for `login:` - -First command sent to shell gets dropped (possibly due to timing issue?) +`echo 'y1q' | python3 -m debugmenu` contains the serial number. Search keyword is: "DtCtrlCfgDeviceSerialNum" +split on `\n`, collect into Vec<&str>. Iterate over Vec: + if doesn't contain colon, continue + split_once on colon + if first half is keyword, trim second half, remove `"` characters, save as serial From 9a7700dee4d5f22f1c446ea7d4abc4e43d16ff9f Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Mon, 19 Jun 2023 14:16:14 -0400 Subject: [PATCH 02/62] First rough shot at using built-in serial --- src/device.rs | 36 +++++++++++++++++++++++++++--------- src/main.rs | 17 ++++++----------- src/tty.rs | 30 ++++++++++++++++++++---------- 3 files changed, 53 insertions(+), 30 deletions(-) diff --git a/src/device.rs b/src/device.rs index 5f07a5d..076aaf8 100755 --- a/src/device.rs +++ b/src/device.rs @@ -8,6 +8,7 @@ const BP_SECTION: &str = "Successful BP tests: "; const TEMP_SECTION: &str = "Successful temp tests: "; const OUTPUT_FOLDER: &str = "output/"; const UNINITIALISED_SERIAL: &str = "uninitialised"; +const SERIAL_HEADER: &str = "DtCtrlCfgDeviceSerialNum"; #[derive(PartialEq,Debug)] pub enum State{ Shutdown, @@ -130,7 +131,7 @@ impl Device{ } }; }, - Response::EmptyNewline => { + Response::Serial(_) | Response::EmptyNewline => { log::error!("Unknown state for TTY {:?}!!! Consult logs immediately.",usb_port); return Err("Failed TTY init. Unknown state, cannot trust.".to_string()); }, @@ -345,8 +346,25 @@ impl Device{ } return true } - pub fn set_serial(&mut self, serial:&str) -> &mut Self{ - self.serial = serial.to_string(); + pub fn set_serial(&mut self) -> &mut Self{ + self.reboot(); + self.usb_tty.write_to_device(Command::Login); + while self.usb_tty.read_from_device(None) != Response::ShellPrompt {} + self.usb_tty.write_to_device(Command::GetSerial); + match self.usb_tty.read_from_device(None){ + Response::Serial(Some(contains_serial)) =>{ + for line in contains_serial.split("\n").collect::>(){ + if !line.contains(':') { continue; } + let (section,value) = line.split_once(':').unwrap(); + if section.contains(SERIAL_HEADER){ + self.serial = value.replace("\"",""); + } + } + }, + _ => todo!(), + } + self.reboot(); + //self.serial = serial.to_string(); self.load_values(); self.save_values(); return self; @@ -405,14 +423,14 @@ impl Device{ self.usb_tty.write_to_device(Command::ReadTemp); for _ in 0..10 { match self.usb_tty.read_from_device(None){ - Response::TempCount(count) => return count != self.init_temps , + Response::TempCount(Some(count)) => return count != self.init_temps , _ => {}, } } self.usb_tty.write_to_device(Command::ReadTemp); for _ in 0..10{ match self.usb_tty.read_from_device(None){ - Response::TempCount(count) => return count != self.init_temps , + Response::TempCount(Some(count)) => return count != self.init_temps , _ => {}, } } @@ -425,7 +443,7 @@ impl Device{ self.usb_tty.write_to_device(Command::ReadTemp); for _ in 0..10 { match self.usb_tty.read_from_device(None){ - Response::TempCount(count) => { + Response::TempCount(Some(count)) => { log::trace!("Count for device {} updated to {}",self.serial,count); self.temps = count; return count @@ -436,7 +454,7 @@ impl Device{ self.usb_tty.write_to_device(Command::ReadTemp); for _ in 0..10{ match self.usb_tty.read_from_device(None){ - Response::TempCount(count) => { + Response::TempCount(Some(count)) => { log::trace!("Count for device {} updated to {}",self.serial,count); self.temps = count; return count @@ -453,7 +471,7 @@ impl Device{ self.usb_tty.write_to_device(Command::ReadTemp); for _ in 0..10 { match self.usb_tty.read_from_device(None){ - Response::TempCount(count) => { + Response::TempCount(Some(count)) => { log::trace!("init temp count set to {} on device {}",count,self.serial); self.init_temps = count; return @@ -464,7 +482,7 @@ impl Device{ self.usb_tty.write_to_device(Command::ReadTemp); for _ in 0..10{ match self.usb_tty.read_from_device(None){ - Response::TempCount(count) => { + Response::TempCount(Some(count)) => { log::trace!("init temp count set to {} on device {}",count,self.serial); self.init_temps = count; return diff --git a/src/main.rs b/src/main.rs index 3505a67..665204b 100755 --- a/src/main.rs +++ b/src/main.rs @@ -115,20 +115,15 @@ fn main(){ log::info!("--------------------------------------\n\n"); for device in devices.iter_mut(){ - device.brighten_screen(); - if args.debug{ - let location = device.get_location(); - log::info!("Init device {}...", location); - device.set_serial(&location); - } - else{ - device.set_serial(&input_filtering(Some("Enter the serial of the device with the bright screen: ")).to_string()); - } - device.darken_screen(); + //device.brighten_screen(); + device.set_serial(); + //device.darken_screen(); log::debug!("Number of unassigned addresses: {}",gpio.get_unassigned_addresses().len()); if !find_gpio(device, gpio){ device.set_pin_address(21); - log::error!("Unable to find GPIO for device {}. Please ensure that the probe well is installed properly, and the calibration key is plugged in.",device.get_location()); + log::error!("Unable to find GPIO for device with bright screen. Please ensure that the probe well is installed properly, and the calibration key is plugged in."); + device.brighten_screen(); + return; } } diff --git a/src/tty.rs b/src/tty.rs index 335f69f..d9156d5 100755 --- a/src/tty.rs +++ b/src/tty.rs @@ -1,4 +1,7 @@ -use std::{collections::HashMap, io::{BufReader, Write, Read}, time::Duration}; +use std::{collections::HashMap, + io::{BufReader, Write, Read}, + boxed::Box, + time::Duration}; use once_cell::sync::Lazy; use serialport::SerialPort; use derivative::Derivative; @@ -24,16 +27,17 @@ pub enum Command{ DebugMenu, Newline, Shutdown, + GetSerial, } #[derive(Clone,Eq,Derivative,Debug)] -#[derivative(Copy,PartialEq, Hash)] +#[derivative(PartialEq, Hash)] pub enum Response{ PasswordPrompt, ShellPrompt, BPOn, BPOff, - TempCount(u64), + TempCount(Option), LoginPrompt, DebugMenu, Rebooting, @@ -44,6 +48,7 @@ pub enum Response{ PreShellPrompt, EmptyNewline, DebugInit, + Serial(Option), } @@ -62,21 +67,23 @@ const COMMAND_MAP:Lazy> = Lazy::new(||HashMap::from([ (Command::DebugMenu," python3 -m debugmenu; shutdown -r now\n"), (Command::Newline,"\n"), (Command::Shutdown,"shutdown -r now\n"), + (Command::GetSerial,"echo 'y1q' | python3 -m debugmenu\n"), ])); -const RESPONSES:[(&str,Response);12] = [ +const RESPONSES:[(&str,Response);13] = [ ("Last login:",Response::PreShellPrompt), ("reboot: Restarting",Response::Rebooting), ("command not found",Response::FailedDebugMenu), ("login:",Response::LoginPrompt), ("Password:",Response::PasswordPrompt), - ("EXIT Debug menu",Response::ShuttingDown), ("root@",Response::ShellPrompt), + ("DtCtrlCfgDeviceSerialNum",Response::Serial(None)), + ("EXIT Debug menu",Response::ShuttingDown), ("Check NIBP In Progress: True",Response::BPOn), ("Check NIBP In Progress: False",Response::BPOff), - ("SureTemp Probe Pulls:",Response::TempCount(0)), + ("SureTemp Probe Pulls:",Response::TempCount(None)), (">",Response::DebugMenu), - ("Loading App-Framework",Response::DebugInit) + ("Loading App-Framework",Response::DebugInit), ]; pub struct TTY{ @@ -144,7 +151,7 @@ impl TTY{ log::trace!("Successful read of {:?} from tty {}, which matches pattern {:?}",read_line,self.tty.name().unwrap_or("unknown shell".to_string()),enum_value); }; self.failed_read_count = 0; - if enum_value == Response::TempCount(0){ + if enum_value == Response::TempCount(None){ let mut lines = read_line.lines(); while let Some(single_line) = lines.next(){ if single_line.contains(string){ @@ -155,12 +162,12 @@ impl TTY{ match temp_count.trim().parse::(){ Err(_) => { log::error!("String {} from device {} unable to be parsed!",temp_count,self.tty.name().unwrap_or("unknown shell".to_string())); - return Response::TempCount(0) + return Response::TempCount(None) }, Ok(parsed_temp_count) => { //log::trace!("Header: {}",header); log::trace!("parsed temp count for device {}: {}",self.tty.name().unwrap_or("unknown shell".to_string()),temp_count); - return Response::TempCount(parsed_temp_count) + return Response::TempCount(Some(parsed_temp_count)) } } } @@ -168,6 +175,9 @@ impl TTY{ } } } + else if enum_value == Response::Serial(None) { + return Response::Serial(Some(read_line)); + } else if enum_value == Response::PasswordPrompt { log::error!("Recieved password prompt on device {}! Something fell apart here. Check preceeding log lines.",self.tty.name().unwrap_or("unknown shell".to_string())); self.write_to_device(Command::Newline); From 3070e429451d2abe55352fca45779b1e4f317bf8 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Mon, 19 Jun 2023 14:19:09 -0400 Subject: [PATCH 03/62] Remember to trim string to remove whitespace --- src/device.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device.rs b/src/device.rs index 076aaf8..8c117d3 100755 --- a/src/device.rs +++ b/src/device.rs @@ -357,7 +357,7 @@ impl Device{ if !line.contains(':') { continue; } let (section,value) = line.split_once(':').unwrap(); if section.contains(SERIAL_HEADER){ - self.serial = value.replace("\"",""); + self.serial = value.trim().replace("\"",""); } } }, From ebda011bc7dbb0b87915d8a5a8b7d12294e83ba4 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Mon, 19 Jun 2023 14:28:03 -0400 Subject: [PATCH 04/62] Add parsing for DebugInit --- src/device.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/device.rs b/src/device.rs index 8c117d3..0cf30b8 100755 --- a/src/device.rs +++ b/src/device.rs @@ -351,17 +351,21 @@ impl Device{ self.usb_tty.write_to_device(Command::Login); while self.usb_tty.read_from_device(None) != Response::ShellPrompt {} self.usb_tty.write_to_device(Command::GetSerial); - match self.usb_tty.read_from_device(None){ - Response::Serial(Some(contains_serial)) =>{ - for line in contains_serial.split("\n").collect::>(){ - if !line.contains(':') { continue; } - let (section,value) = line.split_once(':').unwrap(); - if section.contains(SERIAL_HEADER){ - self.serial = value.trim().replace("\"",""); + loop{ + match self.usb_tty.read_from_device(None){ + Response::Serial(Some(contains_serial)) =>{ + for line in contains_serial.split("\n").collect::>(){ + if !line.contains(':') { continue; } + let (section,value) = line.split_once(':').unwrap(); + if section.contains(SERIAL_HEADER){ + self.serial = value.trim().replace("\"",""); + } } - } - }, - _ => todo!(), + break; + }, + Response::DebugInit => { continue; } + _ => todo!(), + } } self.reboot(); //self.serial = serial.to_string(); From 5773952538504d6ab03fa3cb79530ecfeb3282db Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Mon, 19 Jun 2023 14:31:14 -0400 Subject: [PATCH 05/62] Multithread serial acquisition --- src/device.rs | 2 +- src/main.rs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/device.rs b/src/device.rs index 0cf30b8..7f8acd5 100755 --- a/src/device.rs +++ b/src/device.rs @@ -361,6 +361,7 @@ impl Device{ self.serial = value.trim().replace("\"",""); } } + log::info!("Serial found for device {}",self.serial); break; }, Response::DebugInit => { continue; } @@ -368,7 +369,6 @@ impl Device{ } } self.reboot(); - //self.serial = serial.to_string(); self.load_values(); self.save_values(); return self; diff --git a/src/main.rs b/src/main.rs index 665204b..70ec3ec 100755 --- a/src/main.rs +++ b/src/main.rs @@ -81,6 +81,7 @@ fn main(){ match new_device{ Ok(mut device) => { device.darken_screen(); + device.set_serial(); Some(device) }, Err(_) => None @@ -116,7 +117,7 @@ fn main(){ for device in devices.iter_mut(){ //device.brighten_screen(); - device.set_serial(); + //device.set_serial(); //device.darken_screen(); log::debug!("Number of unassigned addresses: {}",gpio.get_unassigned_addresses().len()); if !find_gpio(device, gpio){ From 94cbba27cf8f20f945e2a886b6adef85daf295fc Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Mon, 19 Jun 2023 14:35:09 -0400 Subject: [PATCH 06/62] Change priority of serial --- src/tty.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tty.rs b/src/tty.rs index d9156d5..42a680c 100755 --- a/src/tty.rs +++ b/src/tty.rs @@ -76,8 +76,8 @@ const RESPONSES:[(&str,Response);13] = [ ("command not found",Response::FailedDebugMenu), ("login:",Response::LoginPrompt), ("Password:",Response::PasswordPrompt), - ("root@",Response::ShellPrompt), ("DtCtrlCfgDeviceSerialNum",Response::Serial(None)), + ("root@",Response::ShellPrompt), ("EXIT Debug menu",Response::ShuttingDown), ("Check NIBP In Progress: True",Response::BPOn), ("Check NIBP In Progress: False",Response::BPOff), From d24b0edcb00b372cb03af9af24b88378aa468a86 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Mon, 19 Jun 2023 14:45:58 -0400 Subject: [PATCH 07/62] Start debugging partial function --- src/device.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/device.rs b/src/device.rs index 7f8acd5..2005a7e 100755 --- a/src/device.rs +++ b/src/device.rs @@ -352,7 +352,8 @@ impl Device{ while self.usb_tty.read_from_device(None) != Response::ShellPrompt {} self.usb_tty.write_to_device(Command::GetSerial); loop{ - match self.usb_tty.read_from_device(None){ + let return_value = self.usb_tty.read_from_device(None); + match return_value{ Response::Serial(Some(contains_serial)) =>{ for line in contains_serial.split("\n").collect::>(){ if !line.contains(':') { continue; } @@ -365,7 +366,10 @@ impl Device{ break; }, Response::DebugInit => { continue; } - _ => todo!(), + _ => { + log::error!("Bad value: {:?}",return_value); + todo!(); + }, } } self.reboot(); From ab560b926a9559f7131e3f7d86250323a64609ae Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Mon, 19 Jun 2023 14:47:28 -0400 Subject: [PATCH 08/62] Properly exit get_serial --- src/device.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/device.rs b/src/device.rs index 2005a7e..2787b54 100755 --- a/src/device.rs +++ b/src/device.rs @@ -372,6 +372,7 @@ impl Device{ }, } } + self.usb_tty.write_to_device(Command::DebugMenu); self.reboot(); self.load_values(); self.save_values(); From 6280603232f8ce30b82f218c228ffa757dcd91db Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Mon, 19 Jun 2023 14:52:24 -0400 Subject: [PATCH 09/62] Add parsing for blank lines --- src/device.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device.rs b/src/device.rs index 2787b54..5cc49a7 100755 --- a/src/device.rs +++ b/src/device.rs @@ -365,7 +365,7 @@ impl Device{ log::info!("Serial found for device {}",self.serial); break; }, - Response::DebugInit => { continue; } + Response::DebugInit | Response::Empty | Response::EmptyNewline => { continue; } _ => { log::error!("Bad value: {:?}",return_value); todo!(); From f1d8af8e3d37e822102e7bfd819219ea497cc988 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Mon, 19 Jun 2023 14:58:15 -0400 Subject: [PATCH 10/62] Add end handling --- src/device.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/device.rs b/src/device.rs index 5cc49a7..a0b2f78 100755 --- a/src/device.rs +++ b/src/device.rs @@ -373,6 +373,8 @@ impl Device{ } } self.usb_tty.write_to_device(Command::DebugMenu); + while self.usb_tty.read_from_device(None) != Response::DebugMenu {} + self.current_state = State::DebugMenu; self.reboot(); self.load_values(); self.save_values(); From d522fac9b82607370758ae70b02015a3b34a8495 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Mon, 19 Jun 2023 15:09:56 -0400 Subject: [PATCH 11/62] Move iteration count ask to beginning of loop --- src/main.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main.rs b/src/main.rs index 70ec3ec..ff5ab88 100755 --- a/src/main.rs +++ b/src/main.rs @@ -56,6 +56,16 @@ fn main(){ log::debug!("Debug enabled!"); } loop{ + let mut iteration_count:u64 = 0; + if args.debug { + iteration_count = 10000; + } + else { + while iteration_count < 1{ + iteration_count = int_input_filtering(Some("Enter the number of iterations to complete: ")); + } + } + let gpio = &mut GpioPins::new(); match std::fs::read_dir("/dev/serial/by-path"){ Ok(available_ttys)=>{ @@ -128,16 +138,6 @@ fn main(){ } } - let mut iteration_count:u64 = 0; - if args.debug { - iteration_count = 10000; - } - else { - while iteration_count < 1{ - iteration_count = int_input_filtering(Some("Enter the number of iterations to complete: ")); - } - } - let mut iteration_threads = Vec::new(); while let Some(mut device) = devices.pop(){ iteration_threads.push(thread::spawn(move||{ From b935fdf043afd77ffce489de7b59b113bc2c8365 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Mon, 19 Jun 2023 15:18:40 -0400 Subject: [PATCH 12/62] Increase verbosity in initialisation Also, version number bump --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/main.rs | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dc445d8..a2c6c09 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -639,7 +639,7 @@ dependencies = [ [[package]] name = "seymour_life_rust" -version = "2.2.0" +version = "2.3.0" dependencies = [ "chrono", "clap", diff --git a/Cargo.toml b/Cargo.toml index ab9d269..ddf2de1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "seymour_life_rust" -version = "2.2.0" +version = "2.3.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/main.rs b/src/main.rs index ff5ab88..de52323 100755 --- a/src/main.rs +++ b/src/main.rs @@ -15,7 +15,7 @@ struct Args{ debug:bool } -const VERSION:&str="2.2.0"; +const VERSION:&str="2.3.0"; fn int_input_filtering(prompt:Option<&str>) -> u64{ let internal_prompt = prompt.unwrap_or(">>>"); @@ -129,10 +129,11 @@ fn main(){ //device.brighten_screen(); //device.set_serial(); //device.darken_screen(); + log::info!("Checking probe well of device {}",device.get_serial()); log::debug!("Number of unassigned addresses: {}",gpio.get_unassigned_addresses().len()); if !find_gpio(device, gpio){ device.set_pin_address(21); - log::error!("Unable to find GPIO for device with bright screen. Please ensure that the probe well is installed properly, and the calibration key is plugged in."); + log::error!("Unable to find probe-well for device {}. Please ensure that the probe well is installed properly, and the calibration key is plugged in.",device.get_serial()); device.brighten_screen(); return; } From 10606b14edce796425dd6cc39f93bceffaffbd69 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Tue, 20 Jun 2023 09:43:04 -0400 Subject: [PATCH 13/62] Add additional CLI arguments, serial fallback --- src/device.rs | 12 +++++++++--- src/main.rs | 34 ++++++++++++++++++++++++++++------ 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/device.rs b/src/device.rs index a0b2f78..8c563dc 100755 --- a/src/device.rs +++ b/src/device.rs @@ -346,7 +346,7 @@ impl Device{ } return true } - pub fn set_serial(&mut self) -> &mut Self{ + pub fn auto_set_serial(&mut self) -> bool{ self.reboot(); self.usb_tty.write_to_device(Command::Login); while self.usb_tty.read_from_device(None) != Response::ShellPrompt {} @@ -368,7 +368,7 @@ impl Device{ Response::DebugInit | Response::Empty | Response::EmptyNewline => { continue; } _ => { log::error!("Bad value: {:?}",return_value); - todo!(); + return false }, } } @@ -378,9 +378,15 @@ impl Device{ self.reboot(); self.load_values(); self.save_values(); + return true + } + pub fn manual_set_serial(&mut self, serial:&str) -> &mut Self{ + self.serial = serial.to_string(); + self.load_values(); + self.save_values(); return self; } - pub fn get_serial(&mut self) -> &str{ + pub fn get_serial(&self) -> &str{ &self.serial } pub fn get_location(&mut self) -> String{ diff --git a/src/main.rs b/src/main.rs index de52323..3577796 100755 --- a/src/main.rs +++ b/src/main.rs @@ -11,11 +11,22 @@ use clap::Parser; #[derive(Parser,Debug)] #[command(author,version,about)] struct Args{ + /// Print all logs to screen. Sets iteration count to 50000 #[arg(short,long,action)] - debug:bool + debug:bool, + + /// Force manually setting serial numbers + #[arg(short,long,action)] + manual:bool, + + /// Set iteration count from command line + #[arg(short,long)] + iterations:Option + } const VERSION:&str="2.3.0"; +const DEBUG_ITERATION_COUNT:u64=50000; fn int_input_filtering(prompt:Option<&str>) -> u64{ let internal_prompt = prompt.unwrap_or(">>>"); @@ -58,7 +69,10 @@ fn main(){ loop{ let mut iteration_count:u64 = 0; if args.debug { - iteration_count = 10000; + iteration_count = DEBUG_ITERATION_COUNT; + } + else if let Some(value) = args.iterations{ + iteration_count = value; } else { while iteration_count < 1{ @@ -91,7 +105,9 @@ fn main(){ match new_device{ Ok(mut device) => { device.darken_screen(); - device.set_serial(); + if !args.manual { + device.auto_set_serial(); + } Some(device) }, Err(_) => None @@ -114,9 +130,13 @@ fn main(){ possible_devices.push(output); } + let mut serials_set:bool = true; let mut devices:Vec = Vec::new(); for possible_device in possible_devices.into_iter(){ if let Some(device) = possible_device{ + if device.get_serial().eq("uninitialised"){ + serials_set = false; + } devices.push(device); } } @@ -126,9 +146,11 @@ fn main(){ log::info!("--------------------------------------\n\n"); for device in devices.iter_mut(){ - //device.brighten_screen(); - //device.set_serial(); - //device.darken_screen(); + if !serials_set || args.manual { + device.brighten_screen(); + device.manual_set_serial(&input_filtering(Some("Enter the serial of the device with the bright screen: ")).to_string()); + device.darken_screen(); + } log::info!("Checking probe well of device {}",device.get_serial()); log::debug!("Number of unassigned addresses: {}",gpio.get_unassigned_addresses().len()); if !find_gpio(device, gpio){ From c501f6c5e6e197b0052d2985c77d280fe331c69a Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Tue, 20 Jun 2023 10:31:36 -0400 Subject: [PATCH 14/62] Add readme --- README.md | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..1cadee5 --- /dev/null +++ b/README.md @@ -0,0 +1,71 @@ +# Seymour Life + +This is a personal/professional project, which makes use of serial communications (tty over USB via UART) and Raspberry Pi GPIO to simulate long term use of a Seymour device. + +Note that this project will ONLY run properly on a Raspberry Pi. It is developed on, and tested for, the Raspberry Pi 400. This should also be compatible with the Raspberry Pi 4, and Raspberry Pi 3, although they have not been explicitly tested. Older models of Raspberry Pi may work properly, however as this project is originally intended for the `aarch64`/`ARM64` architecture, and older compatibility will not be tested. + +## Install + +### Precompiled Binary + +Pre-compiled binaries can be found in the [releases tab](https://git.blizzard.systems/blizzardfinnegan/seymourLifeRust/releases/latest). Download the preferred version to your preferred directory, then run the following command to make the code executable: + +```bash +sudo chmod u+x ./seymour_life +``` + +To run the binary, simply run: +```bash +sudo ./seymour_life +``` + +Note that this command MUST be run as `sudo`/root, due to the way it interacts with GPIO. For more information, please see [the GPIO documentation](https://github.com/golemparts/rppal). + +## Build From Source + +Note: *At this time, this project can only reliably be built on Linux. Build instructions for Windows will be written eventually.* + +To build this project from source, first, download the repository. This can be done by using the Download ZIP button, or running the following command in a terminal where `git` is installed: +```bash +git clone https://git.blizzard.systems/blizzardfinnegan/seymourLifeRust +``` + +Once the repository has been downloaded, the project can be built with `cargo`. This can be done using any of the listed install methods on [the Rust install website](https://rustup.rs/). + +Once cargo has been installed, run the following to build the project: +```bash +cargo build --release +``` + +The runnable command can then be run by the following: +```bash +sudo ./target/release/seymour_life +``` + +You can also build without the `--release` flag, which wil take less time, but will be less optimised for the hardware. If you do this, substitue `./target/release/seymour_life` for `./target/debug/seymour_life` in the above command. + +### Build Dependencies + +The following dependencies are also necessary for building this project: +- `pkg-config` +- `libudev` + +See below for platform specific requirements. + +#### Debian-based +This applies for all distributions of Linux using the `apt` package manager, including but not limited to Debian, Ubuntu, Raspbian/Raspberry Pi OS, and Linux Mint. + +```bash +sudo apt-get install librust-libudev-sys-dev librust-pkg-config-dev +``` + +#### Fedora-based +This applies for all distributions of Linux using the `dnf` package manager, including but not limited to CentOS, Redhat Enterprise Linux (RHEL), and Fedora. +```bash +sudo dnf install rust-libudev-sys-devel rust-pkg-config-devel +``` + +#### Nix +This applies to both NixOS, and any distribution where the [Nix package manager](https://nixos.org/download.html) can be installed. + +If you have the Nix package manager installed, this project comes with a `shell.nix` package containing the necessary build dependencies. Simply run `nix-shell` to download the necessary dependencies. From e73dac51f5641e82b7460d2c2602a5eb031835b1 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Tue, 20 Jun 2023 10:59:09 -0400 Subject: [PATCH 15/62] Version bump Also, fix readme typo --- Cargo.lock | 4 ++-- Cargo.toml | 4 ++-- README.md | 2 +- src/main.rs | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a2c6c09..3c9061b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -638,8 +638,8 @@ dependencies = [ ] [[package]] -name = "seymour_life_rust" -version = "2.3.0" +name = "seymour_life" +version = "2.3.1" dependencies = [ "chrono", "clap", diff --git a/Cargo.toml b/Cargo.toml index ddf2de1..a8598f7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,8 @@ #cargo-features = ["per-package-target"] [package] -name = "seymour_life_rust" -version = "2.3.0" +name = "seymour_life" +version = "2.3.1" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/README.md b/README.md index 1cadee5..ec1f967 100644 --- a/README.md +++ b/README.md @@ -68,4 +68,4 @@ sudo dnf install rust-libudev-sys-devel rust-pkg-config-devel #### Nix This applies to both NixOS, and any distribution where the [Nix package manager](https://nixos.org/download.html) can be installed. -If you have the Nix package manager installed, this project comes with a `shell.nix` package containing the necessary build dependencies. Simply run `nix-shell` to download the necessary dependencies. +If you have the Nix package manager installed, this project comes with a `shell.nix` containing the necessary build dependencies. Simply run `nix-shell` to download the necessary dependencies. diff --git a/src/main.rs b/src/main.rs index 3577796..04e76f3 100755 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ -use seymour_life_rust::{device::Device, - tty::{self,TTY,Response}, - gpio_facade::GpioPins}; +use seymour_life::{device::Device, + tty::{self,TTY,Response}, + gpio_facade::GpioPins}; use std::{io::{stdin,stdout,Write}, thread::{self, JoinHandle}, path::Path, @@ -25,7 +25,7 @@ struct Args{ } -const VERSION:&str="2.3.0"; +const VERSION:&str="2.3.1"; const DEBUG_ITERATION_COUNT:u64=50000; fn int_input_filtering(prompt:Option<&str>) -> u64{ From 62995f8429918da98c5b33cd8563394f1ca57b1f Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Tue, 20 Jun 2023 12:25:44 -0400 Subject: [PATCH 16/62] Remove temporary notes files Moving to Forgejo Issues for notetaking --- build_requirements.md | 2 -- notes.md | 7 ------- 2 files changed, 9 deletions(-) delete mode 100644 build_requirements.md delete mode 100644 notes.md diff --git a/build_requirements.md b/build_requirements.md deleted file mode 100644 index d957683..0000000 --- a/build_requirements.md +++ /dev/null @@ -1,2 +0,0 @@ -librust-udev-sys-dev -pkg-config diff --git a/notes.md b/notes.md deleted file mode 100644 index db3d9d9..0000000 --- a/notes.md +++ /dev/null @@ -1,7 +0,0 @@ -Auto-serial: - -`echo 'y1q' | python3 -m debugmenu` contains the serial number. Search keyword is: "DtCtrlCfgDeviceSerialNum" -split on `\n`, collect into Vec<&str>. Iterate over Vec: - if doesn't contain colon, continue - split_once on colon - if first half is keyword, trim second half, remove `"` characters, save as serial From e63ea625123863b884eb86c8719ce2837357d845 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Wed, 21 Jun 2023 10:32:44 -0400 Subject: [PATCH 17/62] remove dependencies, version bump First attempt at fixing bug #11 --- Cargo.lock | 29 +---------------------------- Cargo.toml | 6 ++++-- src/device.rs | 8 ++++---- src/main.rs | 2 +- 4 files changed, 10 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3c9061b..f61b6a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -382,26 +382,6 @@ version = "0.2.142" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" -[[package]] -name = "libudev" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b324152da65df7bb95acfcaab55e3097ceaab02fb19b228a9eb74d55f135e0" -dependencies = [ - "libc", - "libudev-sys", -] - -[[package]] -name = "libudev-sys" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324" -dependencies = [ - "libc", - "pkg-config", -] - [[package]] name = "link-cplusplus" version = "1.0.8" @@ -486,12 +466,6 @@ version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" -[[package]] -name = "pkg-config" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" - [[package]] name = "proc-macro-hack" version = "0.5.20+deprecated" @@ -630,7 +604,6 @@ dependencies = [ "IOKit-sys", "bitflags", "cfg-if", - "libudev", "mach 0.3.2", "nix", "regex", @@ -639,7 +612,7 @@ dependencies = [ [[package]] name = "seymour_life" -version = "2.3.1" +version = "2.3.2" dependencies = [ "chrono", "clap", diff --git a/Cargo.toml b/Cargo.toml index a8598f7..5642c85 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,14 +2,16 @@ [package] name = "seymour_life" -version = "2.3.1" +version = "2.3.2" edition = "2021" +#For cross-compilation, uncomment this and line 1. +#forced-target="aarch64-unknown-linux-gnu" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] rppal = "0.14.1" -serialport = "4.2.0" +serialport = { version = "4.2.0", default-features = false } log = "0.4" fern = "0.6.2" chrono = "0.4.24" diff --git a/src/device.rs b/src/device.rs index 8c563dc..dfa9341 100755 --- a/src/device.rs +++ b/src/device.rs @@ -195,7 +195,7 @@ impl Device{ log::error!("Unexpected response from device {}!",self.serial); log::debug!("brightness menu, catch-all, first loop, {}, {:?}",self.serial,self.usb_tty); log::error!("Unsure how to continue. Expect data from device {} to be erratic until next cycle.",self.serial); - break; + //break; }, }; }; @@ -222,7 +222,7 @@ impl Device{ log::error!("Unexpected response from device {}!", self.serial); log::debug!("brightness menu, catch-all, second loop, {}, {:?}",self.serial,self.usb_tty); log::error!("Unsure how to continue. Expect data from device {} to be erratic until next cycle.",self.serial); - break; + //break; }, }; }; @@ -266,7 +266,7 @@ impl Device{ log::error!("Unexpected response from device {}!",self.serial); log::debug!("lifecycle menu, catch-all, first loop, {}, {:?}",self.serial,self.usb_tty); log::error!("Unsure how to continue. Expect data from device {} to be erratic until next cycle.",self.serial); - break; + //break; }, }; }; @@ -293,7 +293,7 @@ impl Device{ log::error!("Unexpected response from device {}! {:?}", self.serial, read_in); log::debug!("lifecycle menu, catch-all, second loop, {}, {:?}",self.serial,self.usb_tty); log::error!("Unsure how to continue. Expect data from device {} to be erratic until next cycle.",self.serial); - break; + //break; }, }; }; diff --git a/src/main.rs b/src/main.rs index 04e76f3..bdf33d2 100755 --- a/src/main.rs +++ b/src/main.rs @@ -25,7 +25,7 @@ struct Args{ } -const VERSION:&str="2.3.1"; +const VERSION:&str="2.3.2"; const DEBUG_ITERATION_COUNT:u64=50000; fn int_input_filtering(prompt:Option<&str>) -> u64{ From e0e8562d2341b890f2ef590223a852edbd3788c2 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Wed, 21 Jun 2023 10:41:07 -0400 Subject: [PATCH 18/62] Update documentation re: dependencies --- README.md | 25 ------------------------- shell.nix | 2 +- 2 files changed, 1 insertion(+), 26 deletions(-) diff --git a/README.md b/README.md index ec1f967..f166280 100644 --- a/README.md +++ b/README.md @@ -44,28 +44,3 @@ sudo ./target/release/seymour_life You can also build without the `--release` flag, which wil take less time, but will be less optimised for the hardware. If you do this, substitue `./target/release/seymour_life` for `./target/debug/seymour_life` in the above command. -### Build Dependencies - -The following dependencies are also necessary for building this project: -- `pkg-config` -- `libudev` - -See below for platform specific requirements. - -#### Debian-based -This applies for all distributions of Linux using the `apt` package manager, including but not limited to Debian, Ubuntu, Raspbian/Raspberry Pi OS, and Linux Mint. - -```bash -sudo apt-get install librust-libudev-sys-dev librust-pkg-config-dev -``` - -#### Fedora-based -This applies for all distributions of Linux using the `dnf` package manager, including but not limited to CentOS, Redhat Enterprise Linux (RHEL), and Fedora. -```bash -sudo dnf install rust-libudev-sys-devel rust-pkg-config-devel -``` - -#### Nix -This applies to both NixOS, and any distribution where the [Nix package manager](https://nixos.org/download.html) can be installed. - -If you have the Nix package manager installed, this project comes with a `shell.nix` containing the necessary build dependencies. Simply run `nix-shell` to download the necessary dependencies. diff --git a/shell.nix b/shell.nix index 9d75c26..42ef54a 100644 --- a/shell.nix +++ b/shell.nix @@ -1,4 +1,4 @@ {pkgs ? import {} }: pkgs.mkShell { - nativeBuildInputs = with pkgs; [ cargo rustc pkg-config libudev-zero ]; + nativeBuildInputs = with pkgs; [ cargo rustc ]; } From 5a7183b154a65559bf1582e0fbb077d071f4f4fd Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Wed, 21 Jun 2023 12:24:22 -0400 Subject: [PATCH 19/62] Attempt smarter handling of init reboot sequence --- src/device.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/device.rs b/src/device.rs index dfa9341..dcae053 100755 --- a/src/device.rs +++ b/src/device.rs @@ -113,10 +113,8 @@ impl Device{ Response::BPOn | Response::BPOff | Response::TempCount(_) | Response::DebugMenu=>{ usb_port.write_to_device(Command::Quit); - _ = usb_port.read_from_device(None); - usb_port.write_to_device(Command::Newline); match usb_port.read_from_device(None){ - Response::Rebooting => { + Response::ShuttingDown | Response::Rebooting => { while usb_port.read_from_device(None) != Response::LoginPrompt {} initial_state = State::LoginPrompt; }, From 877b8538eb4367a9a924ee50c2f8502fe48ff2ad Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Wed, 21 Jun 2023 12:35:26 -0400 Subject: [PATCH 20/62] Attempt to start debugging data loading --- src/device.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/device.rs b/src/device.rs index dcae053..f91e645 100755 --- a/src/device.rs +++ b/src/device.rs @@ -30,6 +30,7 @@ pub struct Device{ reboots: u64, temps: u64, init_temps: u64, + temp_offset: u64, bps: u64 } @@ -76,7 +77,7 @@ impl Device{ self.bps = value; }, TEMP_SECTION => { - self.temps = value; + self.temp_offset = value; }, _ => () }; @@ -150,6 +151,7 @@ impl Device{ current_state: initial_state, reboots: 0, temps: 0, + temp_offset: 0, init_temps: 0, bps: 0 }; @@ -328,9 +330,10 @@ impl Device{ output_data.push_str(TEMP_SECTION); log::trace!("Current temps: [{}]",self.temps); log::trace!("Initial temps: [{}]",self.init_temps); - let saved_temps = self.temps - self.init_temps; + let saved_temps = (self.temps - self.init_temps) + self.temp_offset; output_data.push_str(&saved_temps.to_string()); output_data.push_str("\n"); + log::trace!("final data to write: [{:?}]",output_data); let temp = file_name.write_all(output_data.as_bytes()); match temp{ Err(error) => { From ad887a536e196c9e804d526dc9d6a392938199e0 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Wed, 21 Jun 2023 12:52:02 -0400 Subject: [PATCH 21/62] Continue debugging failed imports --- src/device.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/device.rs b/src/device.rs index f91e645..7fb1a41 100755 --- a/src/device.rs +++ b/src/device.rs @@ -72,12 +72,15 @@ impl Device{ match section { REBOOTS_SECTION => { self.reboots = value; + log::trace!("Reboots set to {:?}",self.reboots); }, BP_SECTION => { - self.bps = value; + self.bps = value.clone(); + log::trace!("BPS set to {:?}",self.bps); }, TEMP_SECTION => { self.temp_offset = value; + log::trace!("Temp offset set to {:?}",self.temp_offset); }, _ => () }; @@ -525,18 +528,20 @@ impl Device{ pub fn reboot(&mut self) -> () { self.usb_tty.write_to_device(Command::Quit); let mut successful_reboot:bool = false; - let mut exited_menu:bool = false; + //let mut exited_menu:bool = false; loop{ match self.usb_tty.read_from_device(None){ Response::LoginPrompt => break, Response::Rebooting => { log::trace!("Successful reboot detected for device {}.",self.serial); successful_reboot = true; - if !exited_menu { log::info!("Unusual reboot detected for device {}. Please check logs.",self.serial); } + //This error message is turning out to be more false positive than anything + //else. Reboots can sometimes dump both reboot flag and shutdown flag at once. + //if !exited_menu { log::info!("Unusual reboot detected for device {}. Please check logs.",self.serial); } }, Response::ShuttingDown => { log::trace!("Exiting debug menu on device {}.",self.serial); - exited_menu = true; + //exited_menu = true; }, _ => {} } From 9fe4197e52fa12b06fb8d3192075daf209322af8 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Wed, 21 Jun 2023 13:00:33 -0400 Subject: [PATCH 22/62] Determined source of failed imports Matching a split against a value that contains the split character will never work. --- src/device.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/device.rs b/src/device.rs index 7fb1a41..0d60284 100755 --- a/src/device.rs +++ b/src/device.rs @@ -3,9 +3,9 @@ use crate::tty::{TTY, Response,Command}; use rppal::gpio::{Gpio,OutputPin}; const TEMP_WAIT:Duration = Duration::from_secs(3); -const REBOOTS_SECTION: &str = "Reboots: "; -const BP_SECTION: &str = "Successful BP tests: "; -const TEMP_SECTION: &str = "Successful temp tests: "; +const REBOOTS_SECTION: &str = "Reboots"; +const BP_SECTION: &str = "Successful BP tests"; +const TEMP_SECTION: &str = "Successful temp tests"; const OUTPUT_FOLDER: &str = "output/"; const UNINITIALISED_SERIAL: &str = "uninitialised"; const SERIAL_HEADER: &str = "DtCtrlCfgDeviceSerialNum"; @@ -82,7 +82,9 @@ impl Device{ self.temp_offset = value; log::trace!("Temp offset set to {:?}",self.temp_offset); }, - _ => () + _ => { + log::info!("Invalid import value: [{:?}]. Please ensure that the output directory is clean.",section_and_data); + } }; } Err(_) => { From 0cc47955aff84e3c4f01c2b65ca56c24b2c80259 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Wed, 21 Jun 2023 13:13:38 -0400 Subject: [PATCH 23/62] Modify default print statements --- src/main.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index bdf33d2..135f258 100755 --- a/src/main.rs +++ b/src/main.rs @@ -80,6 +80,7 @@ fn main(){ } } + log::info!("Testing all available USB ports for connected devices. This may take several minutes, and devices may reboot several times."); let gpio = &mut GpioPins::new(); match std::fs::read_dir("/dev/serial/by-path"){ Ok(available_ttys)=>{ @@ -93,7 +94,7 @@ fn main(){ Ok(tty_real_ref)=>{ let tty_path = tty_real_ref.path(); let tty_name = tty_path.to_string_lossy(); - log::info!("Testing port {}. This may take a moment...",&tty_name); + log::debug!("Testing port {}",&tty_name); let possible_port = TTY::new(&tty_name); match possible_port{ Some(mut port) =>{ @@ -145,6 +146,7 @@ fn main(){ log::info!("Number of devices detected: {}",devices.len()); log::info!("--------------------------------------\n\n"); + log::info!("Setting up probe wells for all devices. This may take several minutes..."); for device in devices.iter_mut(){ if !serials_set || args.manual { device.brighten_screen(); @@ -157,7 +159,7 @@ fn main(){ device.set_pin_address(21); log::error!("Unable to find probe-well for device {}. Please ensure that the probe well is installed properly, and the calibration key is plugged in.",device.get_serial()); device.brighten_screen(); - return; + panic!(); } } From bb1dcbe4a12d14738be3c2d49cc5583fb9e9f965 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Wed, 21 Jun 2023 13:24:23 -0400 Subject: [PATCH 24/62] Fix saving so that data can be re-imported --- src/device.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/device.rs b/src/device.rs index 0d60284..c016f88 100755 --- a/src/device.rs +++ b/src/device.rs @@ -7,6 +7,7 @@ const REBOOTS_SECTION: &str = "Reboots"; const BP_SECTION: &str = "Successful BP tests"; const TEMP_SECTION: &str = "Successful temp tests"; const OUTPUT_FOLDER: &str = "output/"; +const SECTION_SEPARATOR: &str = ": "; const UNINITIALISED_SERIAL: &str = "uninitialised"; const SERIAL_HEADER: &str = "DtCtrlCfgDeviceSerialNum"; #[derive(PartialEq,Debug)] @@ -63,7 +64,7 @@ impl Device{ for line in file_lines { if line.len() > 0{ log::trace!("{:?}",line); - let section_and_data:Vec<&str> = line.split(": ").collect(); + let section_and_data:Vec<&str> = line.split(SECTION_SEPARATOR).collect(); let section:&str = section_and_data[0]; let possible_value:Result = section_and_data[1].trim().parse::(); match possible_value{ @@ -327,12 +328,15 @@ impl Device{ if let Some(ref mut file_name) = self.output_file{ log::debug!("Writing to file!"); let mut output_data = REBOOTS_SECTION.to_string(); + output_data.push_str(SECTION_SEPARATOR); output_data.push_str(&self.reboots.to_string()); output_data.push_str("\n"); output_data.push_str(BP_SECTION); + output_data.push_str(SECTION_SEPARATOR); output_data.push_str(&self.bps.to_string()); output_data.push_str("\n"); output_data.push_str(TEMP_SECTION); + output_data.push_str(SECTION_SEPARATOR); log::trace!("Current temps: [{}]",self.temps); log::trace!("Initial temps: [{}]",self.init_temps); let saved_temps = (self.temps - self.init_temps) + self.temp_offset; From c0d13009a4f058328a7b0c3083deb29a34bd9707 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Wed, 21 Jun 2023 16:11:41 -0400 Subject: [PATCH 25/62] Update documentation re: cross-compilation --- Cargo.toml | 5 +++-- README.md | 36 +++++++++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5642c85..81c36cf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,11 +1,12 @@ +#This feature is currently limited to nightly versions of cargo. #cargo-features = ["per-package-target"] [package] name = "seymour_life" version = "2.3.2" edition = "2021" -#For cross-compilation, uncomment this and line 1. -#forced-target="aarch64-unknown-linux-gnu" +#This feature is currently limited to nightly versions of cargo. +#forced-target="aarch64-unknown-linux-musl" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/README.md b/README.md index f166280..4830efd 100644 --- a/README.md +++ b/README.md @@ -23,9 +23,7 @@ Note that this command MUST be run as `sudo`/root, due to the way it interacts w ## Build From Source -Note: *At this time, this project can only reliably be built on Linux. Build instructions for Windows will be written eventually.* - -To build this project from source, first, download the repository. This can be done by using the Download ZIP button, or running the following command in a terminal where `git` is installed: +To build this project from source *ON A RASPBERRY PI*, first, download the repository. This can be done by using the Download ZIP button, or running the following command in a terminal where `git` is installed: ```bash git clone https://git.blizzard.systems/blizzardfinnegan/seymourLifeRust ``` @@ -44,3 +42,35 @@ sudo ./target/release/seymour_life You can also build without the `--release` flag, which wil take less time, but will be less optimised for the hardware. If you do this, substitue `./target/release/seymour_life` for `./target/debug/seymour_life` in the above command. + +## Cross-Compilation + +Cross compilation is possible with this project, if you do not have a Raspberry Pi available specifically for compilation. Compilation directly on the Pi is rather intensive, and takes significantly longer than cross-compiling. However, cross-compiling by default will fail, due to a bad linker. + +To resolve this issue, find the `.cargo` folder. For Windows users, it is located in `C:\Users\[username]`, and for Linux users it is located in `~` or `$HOME`. If you are on Linux, you will need to be sure to show hidden files. + +In this `.cargo` folder, create a new file, named `config`. In it, add the following lines in the relevant sections below. + +Once this file is added, you can then run one of the following commands to create the executable. Note that the final executable will be in `target/aarch64-unknown-linux-musl`, rather than `target`. + +```bash +cargo build --target aarch64-unknown-linux-musl +# OR +cargo build --release --target aarch64-unknown-linux-musl +``` + +#### Windows +```toml +[target.aarch64-unknown-linux-musl] +linker = rust-lld +``` + +#### Linux + +```toml +[target.aarch64-unknown-linux-musl] +linker = lld +``` +Make sure `lld` is installed as well. This can be found in your distribution's package manager, or directly distributed by LLVM. + + From 7aa23f40153026d82c2807edda0a83d184cc2ee9 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Thu, 22 Jun 2023 07:08:59 -0400 Subject: [PATCH 26/62] Add repo-relative linker config --- .cargo/config.toml | 2 ++ README.md | 22 +++------------------- 2 files changed, 5 insertions(+), 19 deletions(-) create mode 100644 .cargo/config.toml diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..6fad019 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[target.aarch64-unknown-linux-musl] +linker = "lld" diff --git a/README.md b/README.md index 4830efd..7a71ce0 100644 --- a/README.md +++ b/README.md @@ -45,13 +45,11 @@ You can also build without the `--release` flag, which wil take less time, but w ## Cross-Compilation -Cross compilation is possible with this project, if you do not have a Raspberry Pi available specifically for compilation. Compilation directly on the Pi is rather intensive, and takes significantly longer than cross-compiling. However, cross-compiling by default will fail, due to a bad linker. +Cross compilation is possible with this project, if you do not have a Raspberry Pi available specifically for compilation. Compilation directly on the Pi is rather intensive, and takes significantly longer than cross-compiling. -To resolve this issue, find the `.cargo` folder. For Windows users, it is located in `C:\Users\[username]`, and for Linux users it is located in `~` or `$HOME`. If you are on Linux, you will need to be sure to show hidden files. +If you are compiling on Linux, cross-compilation has a dependency of `lld`. This can be found in your distribution's package manager, or directly distributed by LLVM. -In this `.cargo` folder, create a new file, named `config`. In it, add the following lines in the relevant sections below. - -Once this file is added, you can then run one of the following commands to create the executable. Note that the final executable will be in `target/aarch64-unknown-linux-musl`, rather than `target`. +If you are compiling on Windows, to safely cross-compile, you must modify the `.cargo/config.toml` file. Replace `lld` with `rust-lld`, then cross-compilation should work properly. ```bash cargo build --target aarch64-unknown-linux-musl @@ -59,18 +57,4 @@ cargo build --target aarch64-unknown-linux-musl cargo build --release --target aarch64-unknown-linux-musl ``` -#### Windows -```toml -[target.aarch64-unknown-linux-musl] -linker = rust-lld -``` - -#### Linux - -```toml -[target.aarch64-unknown-linux-musl] -linker = lld -``` -Make sure `lld` is installed as well. This can be found in your distribution's package manager, or directly distributed by LLVM. - From 260c166ce95b0606cb940ebcf7798d15ada7aa77 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Thu, 22 Jun 2023 07:38:58 -0400 Subject: [PATCH 27/62] Update cross-compile documentation Also, add initial CI test --- .gitignore | 4 +++- .woodpecker.yml | 19 +++++++++++++++++++ README.md | 2 +- shell.nix | 15 +++++++++++++-- 4 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 .woodpecker.yml diff --git a/.gitignore b/.gitignore index 806522a..1f4a548 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ /target /logs -/output \ No newline at end of file +/output +.cargo +.rustup diff --git a/.woodpecker.yml b/.woodpecker.yml new file mode 100644 index 0000000..2f60e03 --- /dev/null +++ b/.woodpecker.yml @@ -0,0 +1,19 @@ +pipeline: + build: + image: rust:bookworm + commands: + - cargo check + - apt update && apt install -y lld + - cargo build --release --target aarch64-unknown-linux-musl + publish: + image: woodpeckerci/plugin-gitea-release + settings: + base_url: https://git.blizzard.systems + files: + - "target/aarch64-unknown-linux-musl/release/seymour_life" + api_key: + from_secret: API_KEY + target: devel + draft: true + prerelease: true + title: diff --git a/README.md b/README.md index 7a71ce0..9546c93 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ You can also build without the `--release` flag, which wil take less time, but w Cross compilation is possible with this project, if you do not have a Raspberry Pi available specifically for compilation. Compilation directly on the Pi is rather intensive, and takes significantly longer than cross-compiling. -If you are compiling on Linux, cross-compilation has a dependency of `lld`. This can be found in your distribution's package manager, or directly distributed by LLVM. +If you are compiling on Linux, cross-compilation has a dependency of `lld`. This can be found in your distribution's package manager, or directly distributed by LLVM. For Nix users, a predefined `shell.nix` file has been provided for your convenience. If you are compiling on Windows, to safely cross-compile, you must modify the `.cargo/config.toml` file. Replace `lld` with `rust-lld`, then cross-compilation should work properly. diff --git a/shell.nix b/shell.nix index 42ef54a..478c392 100644 --- a/shell.nix +++ b/shell.nix @@ -1,4 +1,15 @@ {pkgs ? import {} }: - pkgs.mkShell { - nativeBuildInputs = with pkgs; [ cargo rustc ]; + pkgs.mkShell rec { + buildInputs = with pkgs; [ lld rustup ]; + RUSTUP_HOME = toString ./.rustup; + CARGO_HOME = toString ./.cargo; + RUSTUP_TOOLCHAIN = "stable"; + HOST_ARCH = "x86_64-unknown-linux-gnu"; + CARGO_BUILD_TARGET = "aarch64-unknown-linux-musl"; + shellHook = '' + export PATH=$PATH:${CARGO_HOME}/bin + export PATH=$PATH:${RUSTUP_HOME}/toolchains/${RUSTUP_TOOLCHAIN}-${HOST_ARCH}/bin/ + + rustup target add "${CARGO_BUILD_TARGET}" + ''; } From b78e6bb2785ac23ef92df1e7d0a8f9581c16435c Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Thu, 22 Jun 2023 07:43:28 -0400 Subject: [PATCH 28/62] Transition CI to Nix Since I've already got the shell there anyways... --- .woodpecker.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index 2f60e03..4aa08ab 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -1,9 +1,9 @@ pipeline: build: - image: rust:bookworm + image: nixos/nix:latest commands: + - nix-shell - cargo check - - apt update && apt install -y lld - cargo build --release --target aarch64-unknown-linux-musl publish: image: woodpeckerci/plugin-gitea-release From 2a51417b80b3d8413baa9c7a78070dce6bbda221 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Thu, 22 Jun 2023 07:47:42 -0400 Subject: [PATCH 29/62] Modify CI to actually run build --- .woodpecker.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index 4aa08ab..978366a 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -2,9 +2,7 @@ pipeline: build: image: nixos/nix:latest commands: - - nix-shell - - cargo check - - cargo build --release --target aarch64-unknown-linux-musl + - nix-shell --run cargo build --release --target aarch64-unknown-linux-musl publish: image: woodpeckerci/plugin-gitea-release settings: From 0430a37cd21e17c0c8f72b4800fabc862b2c5fb3 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Thu, 22 Jun 2023 07:49:14 -0400 Subject: [PATCH 30/62] Escape CI command using single quotes --- .woodpecker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index 978366a..a7c6a2a 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -2,7 +2,7 @@ pipeline: build: image: nixos/nix:latest commands: - - nix-shell --run cargo build --release --target aarch64-unknown-linux-musl + - nix-shell --run 'cargo build --release --target aarch64-unknown-linux-musl' publish: image: woodpeckerci/plugin-gitea-release settings: From 8566de3f7063ec5b79aaf3dbc025e08ac418c67a Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Thu, 22 Jun 2023 07:57:28 -0400 Subject: [PATCH 31/62] Reduce CI releases to tag events only --- .woodpecker.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.woodpecker.yml b/.woodpecker.yml index a7c6a2a..3249195 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -4,6 +4,8 @@ pipeline: commands: - nix-shell --run 'cargo build --release --target aarch64-unknown-linux-musl' publish: + when: + event: tag image: woodpeckerci/plugin-gitea-release settings: base_url: https://git.blizzard.systems From 6855ef7ed7fc47cc49562ea5d21d5d1f9f3b4106 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Thu, 22 Jun 2023 08:00:08 -0400 Subject: [PATCH 32/62] Remove manual runners in favour of automated CI --- .forgejo/workflows/buildcheck.yaml | 43 ------------------------------ 1 file changed, 43 deletions(-) delete mode 100644 .forgejo/workflows/buildcheck.yaml diff --git a/.forgejo/workflows/buildcheck.yaml b/.forgejo/workflows/buildcheck.yaml deleted file mode 100644 index dc1b053..0000000 --- a/.forgejo/workflows/buildcheck.yaml +++ /dev/null @@ -1,43 +0,0 @@ -name: Basic Cargo Checks -run-name: ${{ github.actor }} is testing -on: [push] -jobs: - docker-check: - runs-on: docker - steps: - - name: Grab misc. dependencies - run: | - apt update && apt install -y librust-libudev-sys-dev build-essential - - name: Check out repository code - uses: actions/checkout@v3 - - name: Grab Rust toolchain - uses: https://github.com/actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - target: aarch64-unknown-linux-gnu - override: true - - name: Run check - uses: https://github.com/actions-rs/cargo@v1 - with: - command: check - docker-build: - runs-on: docker - steps: - - name: Grab misc. dependencies - run: | - apt update && apt install -y librust-libudev-sys-dev build-essential - - name: Check out repository code - uses: actions/checkout@v3 - - name: Grab Rust toolchain - uses: https://github.com/actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - target: aarch64-unknown-linux-gnu - override: true - - name: Run check - uses: https://github.com/actions-rs/cargo@v1 - with: - command: build - args: --release From 982e17933c6b9bd0079ccdd35d7eab39b2d3c05e Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Thu, 22 Jun 2023 09:45:29 -0400 Subject: [PATCH 33/62] Add build badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9546c93..ec8a458 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +[![status-badge](https://ci.blizzard.systems/api/badges/blizzardfinnegan/seymourLifeRust/status.svg)](https://ci.blizzard.systems/blizzardfinnegan/seymourLifeRust) # Seymour Life This is a personal/professional project, which makes use of serial communications (tty over USB via UART) and Raspberry Pi GPIO to simulate long term use of a Seymour device. From fcacee8fd7d7255c1882f17b6a5cbc60b703d0af Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Thu, 22 Jun 2023 10:09:32 -0400 Subject: [PATCH 34/62] Test if CI agents are working properly --- .woodpecker.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.woodpecker.yml b/.woodpecker.yml index 3249195..5366a12 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -3,6 +3,8 @@ pipeline: image: nixos/nix:latest commands: - nix-shell --run 'cargo build --release --target aarch64-unknown-linux-musl' + when: + platform: linux/arm* publish: when: event: tag From bde028d1957ba87a64ca99cb6330c799c879c2de Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Thu, 22 Jun 2023 10:11:28 -0400 Subject: [PATCH 35/62] Test CI with known-good value --- .woodpecker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index 5366a12..7497cd7 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -4,7 +4,7 @@ pipeline: commands: - nix-shell --run 'cargo build --release --target aarch64-unknown-linux-musl' when: - platform: linux/arm* + platform: linux/amd64 publish: when: event: tag From b95fb2713a7ccc48ec769774baafe6e4f39bf3b9 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Thu, 22 Jun 2023 10:24:38 -0400 Subject: [PATCH 36/62] Try new CI again --- .woodpecker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index 7497cd7..5366a12 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -4,7 +4,7 @@ pipeline: commands: - nix-shell --run 'cargo build --release --target aarch64-unknown-linux-musl' when: - platform: linux/amd64 + platform: linux/arm* publish: when: event: tag From c7b99764e196a8f5a783b909d5deaf46a060076e Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Thu, 22 Jun 2023 10:27:24 -0400 Subject: [PATCH 37/62] Add branch-specific build badge --- .woodpecker.yml | 2 -- README.md | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index 5366a12..3249195 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -3,8 +3,6 @@ pipeline: image: nixos/nix:latest commands: - nix-shell --run 'cargo build --release --target aarch64-unknown-linux-musl' - when: - platform: linux/arm* publish: when: event: tag diff --git a/README.md b/README.md index ec8a458..e7b7b16 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![status-badge](https://ci.blizzard.systems/api/badges/blizzardfinnegan/seymourLifeRust/status.svg)](https://ci.blizzard.systems/blizzardfinnegan/seymourLifeRust) +[![status-badge](https://ci.blizzard.systems/api/badges/blizzardfinnegan/seymourLifeRust/status.svg?branch=devel)](https://ci.blizzard.systems/blizzardfinnegan/seymourLifeRust) # Seymour Life This is a personal/professional project, which makes use of serial communications (tty over USB via UART) and Raspberry Pi GPIO to simulate long term use of a Seymour device. From 76f3599d24f3375bdb16988177f2d9dc059a3ff5 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Fri, 23 Jun 2023 11:12:48 -0400 Subject: [PATCH 38/62] Improve logging verbosity the -i flag now overrides debug cycle count --- src/device.rs | 22 +++++++++------------- src/main.rs | 36 +++++++++++++++++++----------------- src/tty.rs | 20 ++------------------ 3 files changed, 30 insertions(+), 48 deletions(-) diff --git a/src/device.rs b/src/device.rs index c016f88..b453e96 100755 --- a/src/device.rs +++ b/src/device.rs @@ -40,7 +40,7 @@ impl Device{ if ! Path::new(&OUTPUT_FOLDER).is_dir(){ _ = fs::create_dir(&OUTPUT_FOLDER); }; - log::debug!("{:?}",&self.serial); + //log::debug!("{:?}",&self.serial); let output_path:String = OUTPUT_FOLDER.to_owned() + &self.serial + ".txt"; if ! Path::new(&output_path).exists(){ log::debug!("Creating file {}",&output_path); @@ -63,28 +63,28 @@ impl Device{ log::trace!("{:?}",file_contents); for line in file_lines { if line.len() > 0{ - log::trace!("{:?}",line); + //log::trace!("{:?}",line); let section_and_data:Vec<&str> = line.split(SECTION_SEPARATOR).collect(); let section:&str = section_and_data[0]; let possible_value:Result = section_and_data[1].trim().parse::(); match possible_value{ Ok(value) => { - log::trace!("{:?} value: [{:?}]",section,value); + //log::trace!("{:?} value: [{:?}]",section,value); match section { REBOOTS_SECTION => { self.reboots = value; - log::trace!("Reboots set to {:?}",self.reboots); + //log::trace!("Reboots set to {:?}",self.reboots); }, BP_SECTION => { self.bps = value.clone(); - log::trace!("BPS set to {:?}",self.bps); + //log::trace!("BPS set to {:?}",self.bps); }, TEMP_SECTION => { self.temp_offset = value; - log::trace!("Temp offset set to {:?}",self.temp_offset); + //log::trace!("Temp offset set to {:?}",self.temp_offset); }, _ => { - log::info!("Invalid import value: [{:?}]. Please ensure that the output directory is clean.",section_and_data); + log::warn!("Invalid import value: [{:?}]. Please ensure that the output directory is clean.",section_and_data); } }; } @@ -324,9 +324,7 @@ impl Device{ return false } } - log::trace!("Writing to file: {:?}",self.output_file); if let Some(ref mut file_name) = self.output_file{ - log::debug!("Writing to file!"); let mut output_data = REBOOTS_SECTION.to_string(); output_data.push_str(SECTION_SEPARATOR); output_data.push_str(&self.reboots.to_string()); @@ -337,12 +335,10 @@ impl Device{ output_data.push_str("\n"); output_data.push_str(TEMP_SECTION); output_data.push_str(SECTION_SEPARATOR); - log::trace!("Current temps: [{}]",self.temps); - log::trace!("Initial temps: [{}]",self.init_temps); let saved_temps = (self.temps - self.init_temps) + self.temp_offset; output_data.push_str(&saved_temps.to_string()); output_data.push_str("\n"); - log::trace!("final data to write: [{:?}]",output_data); + log::trace!("final data to write to '{:?}': [{:?}]",file_name,output_data); let temp = file_name.write_all(output_data.as_bytes()); match temp{ Err(error) => { @@ -582,7 +578,7 @@ impl Device{ log::trace!("Has bp ended on device {}? : {:?}",self.serial,bp_end); if bp_start != bp_end { self.bps +=1; - log::debug!("Increasing bp count for device {} to {}",self.serial,self.bps); + log::trace!("Increasing bp count for device {} to {}",self.serial,self.bps); self.save_values(); } } diff --git a/src/main.rs b/src/main.rs index 135f258..c307afc 100755 --- a/src/main.rs +++ b/src/main.rs @@ -11,7 +11,7 @@ use clap::Parser; #[derive(Parser,Debug)] #[command(author,version,about)] struct Args{ - /// Print all logs to screen. Sets iteration count to 50000 + /// Print all logs to screen, improves log verbosity. Sets iteration count to 50000 #[arg(short,long,action)] debug:bool, @@ -19,7 +19,7 @@ struct Args{ #[arg(short,long,action)] manual:bool, - /// Set iteration count from command line + /// Set iteration count from command line. Overrides debug iteration count. #[arg(short,long)] iterations:Option @@ -63,17 +63,15 @@ fn main(){ let args = Args::parse(); setup_logs(&args.debug); log::info!("Seymour Life Testing version: {}",VERSION); - if args.debug{ - log::debug!("Debug enabled!"); - } + log::trace!("Debug enabled!"); loop{ let mut iteration_count:u64 = 0; - if args.debug { - iteration_count = DEBUG_ITERATION_COUNT; - } - else if let Some(value) = args.iterations{ + if let Some(value) = args.iterations{ iteration_count = value; } + else if args.debug { + iteration_count = DEBUG_ITERATION_COUNT; + } else { while iteration_count < 1{ iteration_count = int_input_filtering(Some("Enter the number of iterations to complete: ")); @@ -219,14 +217,18 @@ pub fn setup_logs(debug:&bool){ message )) }) - .chain( - fern::Dispatch::new() - .level(log::LevelFilter::Trace) - .chain(fern::log_file( - format!("logs/{0}.log", - chrono_now.format("%Y-%m-%d_%H.%M").to_string() - )).unwrap()), - ) + .chain({ + let mut file_logger = fern::Dispatch::new(); + let date_format = chrono_now.format("%Y-%m-%d_%H.%M").to_string(); + let local_log_file = fern::log_file(format!("logs/{}.log",date_format)).unwrap(); + if *debug{ + file_logger = file_logger.level(log::LevelFilter::Trace); + } + else { + file_logger = file_logger.level(log::LevelFilter::Debug); + } + file_logger.chain(local_log_file) + }) .chain({ let mut stdout_logger = fern::Dispatch::new(); if *debug { diff --git a/src/tty.rs b/src/tty.rs index 42a680c..4e298f6 100755 --- a/src/tty.rs +++ b/src/tty.rs @@ -87,8 +87,7 @@ const RESPONSES:[(&str,Response);13] = [ ]; pub struct TTY{ - tty: Box, - failed_read_count: u8 + tty: Box } impl std::fmt::Debug for TTY{ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result{ @@ -114,10 +113,7 @@ impl TTY{ pub fn new(serial_location:&str) -> Option{ let possible_tty = serialport::new(serial_location,BAUD_RATE).timeout(SERIAL_READ_TIMEOUT).open(); if let Ok(tty) = possible_tty{ - Some(TTY { - tty, - failed_read_count: 0 - }) + Some(TTY{tty,}) } else{ None } @@ -150,7 +146,6 @@ impl TTY{ else{ log::trace!("Successful read of {:?} from tty {}, which matches pattern {:?}",read_line,self.tty.name().unwrap_or("unknown shell".to_string()),enum_value); }; - self.failed_read_count = 0; if enum_value == Response::TempCount(None){ let mut lines = read_line.lines(); while let Some(single_line) = lines.next(){ @@ -165,7 +160,6 @@ impl TTY{ return Response::TempCount(None) }, Ok(parsed_temp_count) => { - //log::trace!("Header: {}",header); log::trace!("parsed temp count for device {}: {}",self.tty.name().unwrap_or("unknown shell".to_string()),temp_count); return Response::TempCount(Some(parsed_temp_count)) } @@ -193,16 +187,6 @@ impl TTY{ } else { log::debug!("Read an empty string from device {:?}. Possible read error.", self); - //Due to a linux kernel power-saving setting that is overly complicated to fix, - //Serial connections will drop for a moment before re-opening, at seemingly-random - //intervals. The below is an attempt to catch and recover from this behaviour. - self.failed_read_count += 1; - if self.failed_read_count >= 15{ - self.failed_read_count = 0; - let tty_location = self.tty.name().expect("Unable to read tty name!"); - self.tty = serialport::new(tty_location,BAUD_RATE).timeout(SERIAL_READ_TIMEOUT).open().expect("Unable to open serial connection!"); - return self.read_from_device(_break_char); - } return Response::Empty; }; } From f5ca4bd2f78fb8cd1f7c0999567650a2ed0aa003 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Fri, 23 Jun 2023 11:19:41 -0400 Subject: [PATCH 39/62] Exchange read logs for write logs --- src/tty.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tty.rs b/src/tty.rs index 4e298f6..5e90bae 100755 --- a/src/tty.rs +++ b/src/tty.rs @@ -120,7 +120,7 @@ impl TTY{ } pub fn write_to_device(&mut self,command:Command) -> bool { - log::trace!("writing {:?} to tty {}...", command, self.tty.name().unwrap_or("unknown".to_string())); + log::debug!("writing {:?} to tty {}...", command, self.tty.name().unwrap_or("unknown".to_string())); let output = self.tty.write_all(COMMAND_MAP.get(&command).unwrap().as_bytes()).is_ok(); _ = self.tty.flush(); if command == Command::Login { std::thread::sleep(std::time::Duration::from_secs(2)); } @@ -186,7 +186,7 @@ impl TTY{ return Response::Other; } else { - log::debug!("Read an empty string from device {:?}. Possible read error.", self); + log::trace!("Read an empty string from device {:?}. Possible read error.", self); return Response::Empty; }; } From f34356da10746c48167fabf75c5ba6481d901f71 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Fri, 23 Jun 2023 11:25:39 -0400 Subject: [PATCH 40/62] Log data written to file --- src/device.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device.rs b/src/device.rs index b453e96..975f4f8 100755 --- a/src/device.rs +++ b/src/device.rs @@ -338,7 +338,7 @@ impl Device{ let saved_temps = (self.temps - self.init_temps) + self.temp_offset; output_data.push_str(&saved_temps.to_string()); output_data.push_str("\n"); - log::trace!("final data to write to '{:?}': [{:?}]",file_name,output_data); + log::debug!("final data to write to '{:?}': [{:?}]",file_name,output_data); let temp = file_name.write_all(output_data.as_bytes()); match temp{ Err(error) => { From abc0c5fb5494a1fb5c5413077fd2f995e96189a1 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Fri, 23 Jun 2023 13:02:27 -0400 Subject: [PATCH 41/62] Modify badge for PR to 2.3.2 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e7b7b16..b720aa5 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![status-badge](https://ci.blizzard.systems/api/badges/blizzardfinnegan/seymourLifeRust/status.svg?branch=devel)](https://ci.blizzard.systems/blizzardfinnegan/seymourLifeRust) +[![status-badge](https://ci.blizzard.systems/api/badges/blizzardfinnegan/seymourLifeRust/status.svg?branch=stable)](https://ci.blizzard.systems/blizzardfinnegan/seymourLifeRust) # Seymour Life This is a personal/professional project, which makes use of serial communications (tty over USB via UART) and Raspberry Pi GPIO to simulate long term use of a Seymour device. From 7f8d0a83979b969d3b5494eaa43da05fda1057ce Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Fri, 23 Jun 2023 13:12:08 -0400 Subject: [PATCH 42/62] Try to further clean up logging --- src/tty.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/tty.rs b/src/tty.rs index 5e90bae..e4ac505 100755 --- a/src/tty.rs +++ b/src/tty.rs @@ -87,7 +87,8 @@ const RESPONSES:[(&str,Response);13] = [ ]; pub struct TTY{ - tty: Box + tty: Box, + last: Command, } impl std::fmt::Debug for TTY{ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result{ @@ -113,18 +114,22 @@ impl TTY{ pub fn new(serial_location:&str) -> Option{ let possible_tty = serialport::new(serial_location,BAUD_RATE).timeout(SERIAL_READ_TIMEOUT).open(); if let Ok(tty) = possible_tty{ - Some(TTY{tty,}) + Some(TTY{tty,last:Command::Quit}) } else{ None } } pub fn write_to_device(&mut self,command:Command) -> bool { - log::debug!("writing {:?} to tty {}...", command, self.tty.name().unwrap_or("unknown".to_string())); + if command == self.last{ + log::trace!("retry send {}",self.tty.name().unwrap_or("unknown".to_string())); + }else{ + log::debug!("writing {:?} to tty {}...", command, self.tty.name().unwrap_or("unknown".to_string())); + }; let output = self.tty.write_all(COMMAND_MAP.get(&command).unwrap().as_bytes()).is_ok(); + self.last = command; _ = self.tty.flush(); - if command == Command::Login { std::thread::sleep(std::time::Duration::from_secs(2)); } - std::thread::sleep(std::time::Duration::from_millis(500)); + //std::thread::sleep(std::time::Duration::from_millis(500)); return output; } From 9bd3fc067de695d77d240fd66036c116eac9c74b Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Fri, 23 Jun 2023 13:32:42 -0400 Subject: [PATCH 43/62] Re-add write-wait The wait on login is no longer necessary, but the wait for write is still necessary for communication. --- src/tty.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tty.rs b/src/tty.rs index e4ac505..6efc46e 100755 --- a/src/tty.rs +++ b/src/tty.rs @@ -129,7 +129,7 @@ impl TTY{ let output = self.tty.write_all(COMMAND_MAP.get(&command).unwrap().as_bytes()).is_ok(); self.last = command; _ = self.tty.flush(); - //std::thread::sleep(std::time::Duration::from_millis(500)); + std::thread::sleep(std::time::Duration::from_millis(500)); return output; } From 72946386810ae65dfe37486854564092790474db Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Fri, 23 Jun 2023 13:39:50 -0400 Subject: [PATCH 44/62] Use single constant for TTY timers --- src/tty.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tty.rs b/src/tty.rs index 6efc46e..c1e8afe 100755 --- a/src/tty.rs +++ b/src/tty.rs @@ -7,7 +7,7 @@ use serialport::SerialPort; use derivative::Derivative; const BAUD_RATE:u32 = 115200; -const SERIAL_READ_TIMEOUT: std::time::Duration = Duration::from_millis(500); +const SERIAL_TIMEOUT: std::time::Duration = Duration::from_millis(500); #[derive(Eq,Derivative,Debug)] @@ -112,7 +112,7 @@ impl std::fmt::Debug for TTY{ impl TTY{ pub fn new(serial_location:&str) -> Option{ - let possible_tty = serialport::new(serial_location,BAUD_RATE).timeout(SERIAL_READ_TIMEOUT).open(); + let possible_tty = serialport::new(serial_location,BAUD_RATE).timeout(SERIAL_TIMEOUT).open(); if let Ok(tty) = possible_tty{ Some(TTY{tty,last:Command::Quit}) } else{ @@ -129,7 +129,7 @@ impl TTY{ let output = self.tty.write_all(COMMAND_MAP.get(&command).unwrap().as_bytes()).is_ok(); self.last = command; _ = self.tty.flush(); - std::thread::sleep(std::time::Duration::from_millis(500)); + std::thread::sleep(SERIAL_TIMEOUT); return output; } From 31099ebdcb0b3768c6dee910f1885a6c3cfbc2e0 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Fri, 23 Jun 2023 13:52:50 -0400 Subject: [PATCH 45/62] Finish CI release pipeline (hopefully) --- .woodpecker.yml | 6 ++++-- .woodpecker/title.txt | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 .woodpecker/title.txt diff --git a/.woodpecker.yml b/.woodpecker.yml index 3249195..cc08785 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -11,9 +11,11 @@ pipeline: base_url: https://git.blizzard.systems files: - "target/aarch64-unknown-linux-musl/release/seymour_life" + checksum: + - "target/aarch64-unknown-linux-musl/release/seymour_life" api_key: from_secret: API_KEY - target: devel + target: stable draft: true prerelease: true - title: + title: .woodpecker/title.txt diff --git a/.woodpecker/title.txt b/.woodpecker/title.txt new file mode 100644 index 0000000..f706a60 --- /dev/null +++ b/.woodpecker/title.txt @@ -0,0 +1 @@ +v2.3.2 From 820712ef4c3800062d0e8e2fa2a8779c8a274702 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Fri, 23 Jun 2023 13:56:21 -0400 Subject: [PATCH 46/62] Use env variable for target --- .woodpecker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index cc08785..9a514ad 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -15,7 +15,7 @@ pipeline: - "target/aarch64-unknown-linux-musl/release/seymour_life" api_key: from_secret: API_KEY - target: stable + target: ${CI_COMMIT_TAG} draft: true prerelease: true title: .woodpecker/title.txt From c5bfbc9adb4b723aa3e55cb4b53f38f6f618c4fb Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Fri, 23 Jun 2023 14:21:47 -0400 Subject: [PATCH 47/62] Modify CI to use secrets --- .woodpecker.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index 9a514ad..d1e0c67 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -13,8 +13,7 @@ pipeline: - "target/aarch64-unknown-linux-musl/release/seymour_life" checksum: - "target/aarch64-unknown-linux-musl/release/seymour_life" - api_key: - from_secret: API_KEY + api_key: ${FORGEJO_API_KEY} target: ${CI_COMMIT_TAG} draft: true prerelease: true From f7b9da508626e66bc929e5b5e8bb55265e1dc733 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Fri, 23 Jun 2023 14:27:05 -0400 Subject: [PATCH 48/62] add "from secrets" denotation --- .woodpecker.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.woodpecker.yml b/.woodpecker.yml index d1e0c67..62ea18d 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -14,6 +14,7 @@ pipeline: checksum: - "target/aarch64-unknown-linux-musl/release/seymour_life" api_key: ${FORGEJO_API_KEY} + secrets: [ FORGEJO_API_KEY ] target: ${CI_COMMIT_TAG} draft: true prerelease: true From d4b47c109fb24c171d3f9cb8b8db3c9708fece66 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Fri, 23 Jun 2023 14:32:45 -0400 Subject: [PATCH 49/62] secrets take 2 --- .woodpecker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index 62ea18d..4ad25b2 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -14,7 +14,7 @@ pipeline: checksum: - "target/aarch64-unknown-linux-musl/release/seymour_life" api_key: ${FORGEJO_API_KEY} - secrets: [ FORGEJO_API_KEY ] + secrets: [ forgejo_api_key ] target: ${CI_COMMIT_TAG} draft: true prerelease: true From 41e1f8eda30dd7cf6f22f50208101d5d58e1bae2 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Fri, 23 Jun 2023 14:47:48 -0400 Subject: [PATCH 50/62] third time's the charm? --- .woodpecker.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index 4ad25b2..db6fac1 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -13,8 +13,8 @@ pipeline: - "target/aarch64-unknown-linux-musl/release/seymour_life" checksum: - "target/aarch64-unknown-linux-musl/release/seymour_life" - api_key: ${FORGEJO_API_KEY} - secrets: [ forgejo_api_key ] + api_key: ${FORGEJO_API} + secrets: [ forgejo_api ] target: ${CI_COMMIT_TAG} draft: true prerelease: true From 5d42a34f1636094ad1b33e722316f1104700c97e Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Fri, 23 Jun 2023 14:52:54 -0400 Subject: [PATCH 51/62] once again, I am asking for your api key --- .woodpecker.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index db6fac1..58a5d5a 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -14,7 +14,9 @@ pipeline: checksum: - "target/aarch64-unknown-linux-musl/release/seymour_life" api_key: ${FORGEJO_API} - secrets: [ forgejo_api ] + secrets: + - source: forgejo_api + target: FORGEJO_API target: ${CI_COMMIT_TAG} draft: true prerelease: true From 108132ef9e8b3cf8bafc320d74a29a23b4463066 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Fri, 23 Jun 2023 15:01:41 -0400 Subject: [PATCH 52/62] Comment out releases for now Clearly, I don't really know what's going on here. So rather than further pollute the public repo, I'm going to set up another repo to play with. --- .woodpecker.yml | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index 58a5d5a..6d21a7a 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -3,21 +3,21 @@ pipeline: image: nixos/nix:latest commands: - nix-shell --run 'cargo build --release --target aarch64-unknown-linux-musl' - publish: - when: - event: tag - image: woodpeckerci/plugin-gitea-release - settings: - base_url: https://git.blizzard.systems - files: - - "target/aarch64-unknown-linux-musl/release/seymour_life" - checksum: - - "target/aarch64-unknown-linux-musl/release/seymour_life" - api_key: ${FORGEJO_API} - secrets: - - source: forgejo_api - target: FORGEJO_API - target: ${CI_COMMIT_TAG} - draft: true - prerelease: true - title: .woodpecker/title.txt + # publish: + # when: + # event: tag + # image: woodpeckerci/plugin-gitea-release + # settings: + # base_url: https://git.blizzard.systems + # files: + # - "target/aarch64-unknown-linux-musl/release/seymour_life" + # checksum: + # - "target/aarch64-unknown-linux-musl/release/seymour_life" + # api_key: ${FORGEJO_API} + # secrets: + # - source: forgejo_api + # target: FORGEJO_API + # target: ${CI_COMMIT_TAG} + # draft: true + # prerelease: true + # title: .woodpecker/title.txt From 5d96f6cb2d980b42a6d0e2c1cbe598947cc537a4 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Fri, 23 Jun 2023 15:04:03 -0400 Subject: [PATCH 53/62] v2.3.2 take 2 (#18) Reviewed-on: https://git.blizzard.systems/blizzardfinnegan/seymourLifeRust/pulls/18 --- .woodpecker.yml | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index d1e0c67..6d21a7a 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -3,18 +3,21 @@ pipeline: image: nixos/nix:latest commands: - nix-shell --run 'cargo build --release --target aarch64-unknown-linux-musl' - publish: - when: - event: tag - image: woodpeckerci/plugin-gitea-release - settings: - base_url: https://git.blizzard.systems - files: - - "target/aarch64-unknown-linux-musl/release/seymour_life" - checksum: - - "target/aarch64-unknown-linux-musl/release/seymour_life" - api_key: ${FORGEJO_API_KEY} - target: ${CI_COMMIT_TAG} - draft: true - prerelease: true - title: .woodpecker/title.txt + # publish: + # when: + # event: tag + # image: woodpeckerci/plugin-gitea-release + # settings: + # base_url: https://git.blizzard.systems + # files: + # - "target/aarch64-unknown-linux-musl/release/seymour_life" + # checksum: + # - "target/aarch64-unknown-linux-musl/release/seymour_life" + # api_key: ${FORGEJO_API} + # secrets: + # - source: forgejo_api + # target: FORGEJO_API + # target: ${CI_COMMIT_TAG} + # draft: true + # prerelease: true + # title: .woodpecker/title.txt From c403dfa7c1ccaec5f7b93fdfb39e719fa0c4cda6 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Mon, 26 Jun 2023 11:04:01 -0400 Subject: [PATCH 54/62] Attempt to reduce init time To be tested --- src/device.rs | 32 ++++++++++++++++---------------- src/tty.rs | 14 ++++++++------ 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/device.rs b/src/device.rs index 975f4f8..c44860b 100755 --- a/src/device.rs +++ b/src/device.rs @@ -16,7 +16,8 @@ pub enum State{ LoginPrompt, DebugMenu, LifecycleMenu, - BrightnessMenu + BrightnessMenu, + ShellPrompt } #[derive(Debug)] @@ -112,6 +113,10 @@ impl Device{ usb_port.write_to_device(Command::Newline); _ = usb_port.read_from_device(None); initial_state = State::LoginPrompt; + }, + Response::UBoot=>{ + log::error!("A device was interrupted during the boot process! Please ensure all devices are completely booted and on the main screen, then restart this program."); + return Err("Failed TTY init. Device in u-boot state, must be manually rebooted.".to_string()); }, //Response::Empty parsing here is potentially in bad faith Response::Other | Response::Empty | Response::ShellPrompt | Response::FailedDebugMenu | Response::DebugInit | @@ -126,9 +131,7 @@ impl Device{ initial_state = State::LoginPrompt; }, Response::ShellPrompt => { - usb_port.write_to_device(Command::Shutdown); - while usb_port.read_from_device(None) != Response::LoginPrompt {} - initial_state = State::LoginPrompt; + initial_state = State::ShellPrompt; }, _ => { log::error!("Unknown state for TTY {:?}!!! Consult logs immediately.",usb_port); @@ -199,13 +202,15 @@ impl Device{ Response::ShellPrompt => break, _ => { log::error!("Unexpected response from device {}!",self.serial); - log::debug!("brightness menu, catch-all, first loop, {}, {:?}",self.serial,self.usb_tty); + log::debug!("brightness menu, catch-all, login loop, {}, {:?}",self.serial,self.usb_tty); log::error!("Unsure how to continue. Expect data from device {} to be erratic until next cycle.",self.serial); //break; }, }; }; - //_ = self.usb_tty.read_from_device(None); + self.current_state = State::ShellPrompt; + }, + State::ShellPrompt => { self.usb_tty.write_to_device(Command::DebugMenu); loop { match self.usb_tty.read_from_device(None) { @@ -219,14 +224,11 @@ impl Device{ Response::DebugMenu => break, Response::FailedDebugMenu => { - while self.usb_tty.read_from_device(None) != Response::LoginPrompt {}; - self.usb_tty.write_to_device(Command::Login); - while self.usb_tty.read_from_device(None) != Response::ShellPrompt {}; self.usb_tty.write_to_device(Command::DebugMenu); }, _ => { log::error!("Unexpected response from device {}!", self.serial); - log::debug!("brightness menu, catch-all, second loop, {}, {:?}",self.serial,self.usb_tty); + log::debug!("brightness menu, catch-all, shell prompt loop, {}, {:?}",self.serial,self.usb_tty); log::error!("Unsure how to continue. Expect data from device {} to be erratic until next cycle.",self.serial); //break; }, @@ -276,6 +278,9 @@ impl Device{ }, }; }; + self.current_state = State::ShellPrompt; + }, + State::ShellPrompt => { self.usb_tty.write_to_device(Command::DebugMenu); loop { let read_in = self.usb_tty.read_from_device(None); @@ -283,16 +288,11 @@ impl Device{ Response::PreShellPrompt | Response::Empty | Response::ShuttingDown | Response::DebugInit | Response::EmptyNewline | Response::Rebooting => {}, Response::LoginPrompt => { - self.usb_tty.write_to_device(Command::Login); - while self.usb_tty.read_from_device(None) != Response::ShellPrompt {}; self.usb_tty.write_to_device(Command::DebugMenu); }, Response::DebugMenu => break, Response::FailedDebugMenu => { - while self.usb_tty.read_from_device(None) != Response::LoginPrompt {}; - self.usb_tty.write_to_device(Command::Login); - while self.usb_tty.read_from_device(None) != Response::ShellPrompt {}; self.usb_tty.write_to_device(Command::DebugMenu); }, _ => { @@ -381,7 +381,6 @@ impl Device{ self.usb_tty.write_to_device(Command::DebugMenu); while self.usb_tty.read_from_device(None) != Response::DebugMenu {} self.current_state = State::DebugMenu; - self.reboot(); self.load_values(); self.save_values(); return true @@ -529,6 +528,7 @@ impl Device{ } pub fn reboot(&mut self) -> () { self.usb_tty.write_to_device(Command::Quit); + self.usb_tty.write_to_device(Command::Reboot); let mut successful_reboot:bool = false; //let mut exited_menu:bool = false; loop{ diff --git a/src/tty.rs b/src/tty.rs index c1e8afe..414d5a8 100755 --- a/src/tty.rs +++ b/src/tty.rs @@ -26,7 +26,7 @@ pub enum Command{ Login, DebugMenu, Newline, - Shutdown, + Reboot, GetSerial, } @@ -49,6 +49,7 @@ pub enum Response{ EmptyNewline, DebugInit, Serial(Option), + UBoot, } @@ -64,26 +65,27 @@ const COMMAND_MAP:Lazy> = Lazy::new(||HashMap::from([ (Command::UpMenuLevel, "\\"), (Command::Login,"root\n"), (Command::RedrawMenu,"?"), - (Command::DebugMenu," python3 -m debugmenu; shutdown -r now\n"), + (Command::DebugMenu,"python3 -m debugmenu\n"), (Command::Newline,"\n"), - (Command::Shutdown,"shutdown -r now\n"), + (Command::Reboot,"shutdown -r now\n"), (Command::GetSerial,"echo 'y1q' | python3 -m debugmenu\n"), ])); -const RESPONSES:[(&str,Response);13] = [ +const RESPONSES:[(&str,Response);14] = [ + ("uboot=>",Response::UBoot), ("Last login:",Response::PreShellPrompt), ("reboot: Restarting",Response::Rebooting), ("command not found",Response::FailedDebugMenu), ("login:",Response::LoginPrompt), ("Password:",Response::PasswordPrompt), ("DtCtrlCfgDeviceSerialNum",Response::Serial(None)), + (">",Response::DebugMenu), + ("Loading App-Framework",Response::DebugInit), ("root@",Response::ShellPrompt), ("EXIT Debug menu",Response::ShuttingDown), ("Check NIBP In Progress: True",Response::BPOn), ("Check NIBP In Progress: False",Response::BPOff), ("SureTemp Probe Pulls:",Response::TempCount(None)), - (">",Response::DebugMenu), - ("Loading App-Framework",Response::DebugInit), ]; pub struct TTY{ From a59a3c590d3ee5bd1025955056b6f23b440deff0 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Mon, 26 Jun 2023 11:12:40 -0400 Subject: [PATCH 55/62] Catch first major error go_to_* functions fell to catch-all for bad debug command response; should treat as shell --- src/device.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/device.rs b/src/device.rs index c44860b..9745eea 100755 --- a/src/device.rs +++ b/src/device.rs @@ -199,7 +199,7 @@ impl Device{ Response::PreShellPrompt | Response::Empty | Response::ShuttingDown | Response::DebugInit | Response::EmptyNewline | Response::Rebooting => {}, Response::PasswordPrompt => {self.usb_tty.write_to_device(Command::Newline);}, - Response::ShellPrompt => break, + Response::FailedDebugMenu | Response::ShellPrompt => break, _ => { log::error!("Unexpected response from device {}!",self.serial); log::debug!("brightness menu, catch-all, login loop, {}, {:?}",self.serial,self.usb_tty); @@ -269,7 +269,7 @@ impl Device{ Response::PreShellPrompt | Response::Empty | Response::ShuttingDown | Response::DebugInit | Response::EmptyNewline | Response::Rebooting => {}, Response::PasswordPrompt => {self.usb_tty.write_to_device(Command::Newline);}, - Response::ShellPrompt => break, + Response::FailedDebugMenu | Response::ShellPrompt => break, _ => { log::error!("Unexpected response from device {}!",self.serial); log::debug!("lifecycle menu, catch-all, first loop, {}, {:?}",self.serial,self.usb_tty); From 1300e040d78690d02c697610353f9507409d258e Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Mon, 26 Jun 2023 11:29:47 -0400 Subject: [PATCH 56/62] Remove reboot from auto_serial We have a whole state machine here. Might as well use it. --- src/device.rs | 70 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/src/device.rs b/src/device.rs index 9745eea..2ff90f3 100755 --- a/src/device.rs +++ b/src/device.rs @@ -353,38 +353,56 @@ impl Device{ return true } pub fn auto_set_serial(&mut self) -> bool{ - self.reboot(); - self.usb_tty.write_to_device(Command::Login); - while self.usb_tty.read_from_device(None) != Response::ShellPrompt {} - self.usb_tty.write_to_device(Command::GetSerial); - loop{ - let return_value = self.usb_tty.read_from_device(None); - match return_value{ - Response::Serial(Some(contains_serial)) =>{ - for line in contains_serial.split("\n").collect::>(){ - if !line.contains(':') { continue; } - let (section,value) = line.split_once(':').unwrap(); - if section.contains(SERIAL_HEADER){ - self.serial = value.trim().replace("\"",""); + loop { + match self.current_state { + State::LoginPrompt => { + self.usb_tty.write_to_device(Command::Login); + while self.usb_tty.read_from_device(None) != Response::ShellPrompt {}; + self.current_state = State::ShellPrompt; + }, + State::Shutdown => { + while self.usb_tty.read_from_device(None) != Response::LoginPrompt{}; + self.current_state = State::LoginPrompt; + }, + State::DebugMenu | State::LifecycleMenu | State::BrightnessMenu => { + self.usb_tty.write_to_device(Command::Quit); + _ = self.usb_tty.read_from_device(None); + self.current_state = State::ShellPrompt; + }, + State::ShellPrompt => { + self.usb_tty.write_to_device(Command::GetSerial); + loop{ + let return_value = self.usb_tty.read_from_device(None); + match return_value{ + Response::Serial(Some(contains_serial)) =>{ + for line in contains_serial.split("\n").collect::>(){ + if !line.contains(':') { continue; } + let (section,value) = line.split_once(':').unwrap(); + if section.contains(SERIAL_HEADER){ + self.serial = value.trim().replace("\"",""); + } + } + log::info!("Serial found for device {}",self.serial); + break; + }, + Response::DebugInit | Response::Empty | Response::EmptyNewline => { continue; } + _ => { + log::error!("Bad value: {:?}",return_value); + return false + }, } } - log::info!("Serial found for device {}",self.serial); - break; - }, - Response::DebugInit | Response::Empty | Response::EmptyNewline => { continue; } - _ => { - log::error!("Bad value: {:?}",return_value); - return false + self.usb_tty.write_to_device(Command::DebugMenu); + while self.usb_tty.read_from_device(None) != Response::DebugMenu {} + self.current_state = State::DebugMenu; + self.load_values(); + self.save_values(); + return true }, } } - self.usb_tty.write_to_device(Command::DebugMenu); - while self.usb_tty.read_from_device(None) != Response::DebugMenu {} - self.current_state = State::DebugMenu; - self.load_values(); - self.save_values(); - return true } + pub fn manual_set_serial(&mut self, serial:&str) -> &mut Self{ self.serial = serial.to_string(); self.load_values(); From e92b0522b82b05fd8d262bee77ef89bf87f0962e Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Mon, 26 Jun 2023 11:44:58 -0400 Subject: [PATCH 57/62] Increase complexity of read tree --- src/device.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/device.rs b/src/device.rs index 2ff90f3..9357d91 100755 --- a/src/device.rs +++ b/src/device.rs @@ -133,14 +133,32 @@ impl Device{ Response::ShellPrompt => { initial_state = State::ShellPrompt; }, + Response::DebugMenu => { + usb_port.write_to_device(Command::Newline); + match usb_port.read_from_device(None) { + Response::DebugMenu | Response::ShellPrompt => { + initial_state = State::ShellPrompt; + }, + _ => { + log::error!("Unknown state for TTY {:?}!!! Consult logs immediately.",usb_port); + log::debug!("Last known state: DebugMenu."); + log::debug!("Assumed but incorrect current state: successfully exited debug menu"); + return Err("Failed TTY init. Unknown state, cannot trust.".to_string()); + } + }; + }, _ => { log::error!("Unknown state for TTY {:?}!!! Consult logs immediately.",usb_port); + log::debug!("Last known state: DebugMenu."); + log::debug!("Assumed but incorrect current state: attempted to exit debug menu"); return Err("Failed TTY init. Unknown state, cannot trust.".to_string()); } }; }, + //Serial response shouldn't exist, emptynewline is already filtered in main Response::Serial(_) | Response::EmptyNewline => { log::error!("Unknown state for TTY {:?}!!! Consult logs immediately.",usb_port); + log::debug!("How did I get here???"); return Err("Failed TTY init. Unknown state, cannot trust.".to_string()); }, }; From 0a0f502410b1af31c67ac3fa8f67ba4b0294360b Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Mon, 26 Jun 2023 11:48:54 -0400 Subject: [PATCH 58/62] Adjust priority so temp checks don't fail --- src/tty.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tty.rs b/src/tty.rs index 414d5a8..a4297b6 100755 --- a/src/tty.rs +++ b/src/tty.rs @@ -79,13 +79,13 @@ const RESPONSES:[(&str,Response);14] = [ ("login:",Response::LoginPrompt), ("Password:",Response::PasswordPrompt), ("DtCtrlCfgDeviceSerialNum",Response::Serial(None)), + ("Check NIBP In Progress: True",Response::BPOn), + ("Check NIBP In Progress: False",Response::BPOff), + ("SureTemp Probe Pulls:",Response::TempCount(None)), (">",Response::DebugMenu), ("Loading App-Framework",Response::DebugInit), ("root@",Response::ShellPrompt), ("EXIT Debug menu",Response::ShuttingDown), - ("Check NIBP In Progress: True",Response::BPOn), - ("Check NIBP In Progress: False",Response::BPOff), - ("SureTemp Probe Pulls:",Response::TempCount(None)), ]; pub struct TTY{ From c6c34462bbf549810c97d6694f92f0f809daa37e Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Mon, 26 Jun 2023 13:00:16 -0400 Subject: [PATCH 59/62] Attempt to resolve #10 --- src/tty.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/tty.rs b/src/tty.rs index a4297b6..87076d5 100755 --- a/src/tty.rs +++ b/src/tty.rs @@ -71,6 +71,12 @@ const COMMAND_MAP:Lazy> = Lazy::new(||HashMap::from([ (Command::GetSerial,"echo 'y1q' | python3 -m debugmenu\n"), ])); +const COMMAND_RESPONSES: [&str;3] = [ + "python3 -m debugmenu", + "q", + "root", +]; + const RESPONSES:[(&str,Response);14] = [ ("uboot=>",Response::UBoot), ("Last login:",Response::PreShellPrompt), @@ -143,7 +149,12 @@ impl TTY{ let read_line:String = String::from_utf8_lossy(read_buffer.as_slice()).to_string(); if read_line.eq("\r\n") { return Response::EmptyNewline; - } + } + for command in COMMAND_RESPONSES{ + if read_line.trim().eq(command.trim()){ + return self.read_from_device(None); + } + }; for (string,enum_value) in RESPONSES{ if read_line.contains(string){ if(enum_value == Response::BPOn) || (enum_value == Response::BPOff) { From 32789a4546e9121e27ade9b4aed2a98f281002ba Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Tue, 27 Jun 2023 09:00:06 -0400 Subject: [PATCH 60/62] Add catch for uboot Apparently, you can just run "boot" in a uboot prompt to get to the login prompt. --- src/device.rs | 5 +++-- src/tty.rs | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/device.rs b/src/device.rs index 9357d91..0f48f61 100755 --- a/src/device.rs +++ b/src/device.rs @@ -115,8 +115,9 @@ impl Device{ initial_state = State::LoginPrompt; }, Response::UBoot=>{ - log::error!("A device was interrupted during the boot process! Please ensure all devices are completely booted and on the main screen, then restart this program."); - return Err("Failed TTY init. Device in u-boot state, must be manually rebooted.".to_string()); + usb_port.write_to_device(Command::Boot); + while usb_port.read_from_device(None) != Response::LoginPrompt {} + initial_state = State::LoginPrompt; }, //Response::Empty parsing here is potentially in bad faith Response::Other | Response::Empty | Response::ShellPrompt | Response::FailedDebugMenu | Response::DebugInit | diff --git a/src/tty.rs b/src/tty.rs index 87076d5..876532b 100755 --- a/src/tty.rs +++ b/src/tty.rs @@ -28,6 +28,7 @@ pub enum Command{ Newline, Reboot, GetSerial, + Boot, } #[derive(Clone,Eq,Derivative,Debug)] @@ -68,6 +69,7 @@ const COMMAND_MAP:Lazy> = Lazy::new(||HashMap::from([ (Command::DebugMenu,"python3 -m debugmenu\n"), (Command::Newline,"\n"), (Command::Reboot,"shutdown -r now\n"), + (Command::Boot,"boot\n"), (Command::GetSerial,"echo 'y1q' | python3 -m debugmenu\n"), ])); From b27da2155e97a42933fc0767b444125823eafbda Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Thu, 29 Jun 2023 09:58:20 -0400 Subject: [PATCH 61/62] Attempt to generalise serial init --- Cargo.lock | 7 ++ Cargo.toml | 1 + src/main.rs | 212 +++++++++++++++++++++++++++++----------------------- 3 files changed, 126 insertions(+), 94 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f61b6a0..45ef427 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -302,6 +302,12 @@ dependencies = [ "log", ] +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + [[package]] name = "heck" version = "0.4.1" @@ -618,6 +624,7 @@ dependencies = [ "clap", "derivative", "fern", + "glob", "log", "once_cell", "rppal", diff --git a/Cargo.toml b/Cargo.toml index 81c36cf..b54fcb6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ once_cell = "1.17.1" derivative = "2.2.0" time = "0.2.23" clap = { version = "4.3.2", features = ["derive"] } +glob = "0.3.1" [dev-dependencies] time = "0.2.23" diff --git a/src/main.rs b/src/main.rs index c307afc..61b49c1 100755 --- a/src/main.rs +++ b/src/main.rs @@ -58,7 +58,7 @@ fn input_filtering(prompt:Option<&str>) -> String{ log::debug!("{}:{}",internal_prompt,user_input); return user_input; } - +//Path::new(&&str).is_dir() -> bool fn main(){ let args = Args::parse(); setup_logs(&args.debug); @@ -80,106 +80,130 @@ fn main(){ log::info!("Testing all available USB ports for connected devices. This may take several minutes, and devices may reboot several times."); let gpio = &mut GpioPins::new(); - match std::fs::read_dir("/dev/serial/by-path"){ - Ok(available_ttys)=>{ - let mut possible_devices:Vec> = Vec::new(); - let mut tty_test_threads:Vec>> = Vec::new(); - for possible_tty in available_ttys.into_iter(){ - tty_test_threads.push( - thread::spawn(move ||{ - let tty_ref = possible_tty.as_ref(); - match tty_ref{ - Ok(tty_real_ref)=>{ - let tty_path = tty_real_ref.path(); - let tty_name = tty_path.to_string_lossy(); - log::debug!("Testing port {}",&tty_name); - let possible_port = TTY::new(&tty_name); - match possible_port{ - Some(mut port) =>{ - port.write_to_device(tty::Command::Newline); - let response = port.read_from_device(Some(":")); - if response != Response::Empty{ - log::debug!("{} is valid port!",tty_name); - let new_device = Device::new(port,Some(response)); - match new_device{ - Ok(mut device) => { - device.darken_screen(); - if !args.manual { - device.auto_set_serial(); - } - Some(device) - }, - Err(_) => None - } - } - else { None } - }, - None=>{None} - } - }, - Err(error)=>{ - log::debug!("{}",error); - None + let mut available_ttys:Vec> = Vec::new(); + for entry in glob::glob("/dev/serial/*").expect("Failed to read glob pattern"){ + match entry{ + Ok(real_path) =>{ + match fs::read_dir::<&Path>(real_path.as_ref()){ + Ok(possible_ttys) =>{ + possible_ttys.into_iter().for_each(|tty| { + if let Ok(single_tty) = tty { + available_ttys.push(single_tty.path().into()); + } + }); + break; + } + Err(error) =>{ + log::error!("Invalid permissions to /dev directory... did you run with sudo?"); + log::error!("{}",error); + return; + } + } + } + Err(error) =>{ + log::error!("{}",error); + } + } + } + if available_ttys.is_empty(){ + for entry in glob::glob("/dev/ttyUSB*").expect("Unable to read glob"){ + match entry{ + Ok(possible_tty) => available_ttys.push(Path::new(&possible_tty).into()), + Err(error) => { + log::error!("Invalid permissions to /dev directory... did you run with sudo?"); + log::error!("{}",error); + return; + } + }; + } + } + + if available_ttys.is_empty(){ + log::error!("No serial devices detected! Please ensure all connections."); + return; + } + let mut possible_devices:Vec> = Vec::new(); + let mut tty_test_threads:Vec>> = Vec::new(); + for possible_tty in available_ttys.into_iter(){ + tty_test_threads.push( + thread::spawn(move ||{ + let tty_name = possible_tty.to_string_lossy(); + log::debug!("Testing port {}",&tty_name); + let possible_port = TTY::new(&tty_name); + match possible_port{ + Some(mut port) =>{ + port.write_to_device(tty::Command::Newline); + let response = port.read_from_device(Some(":")); + if response != Response::Empty{ + log::debug!("{} is valid port!",tty_name); + let new_device = Device::new(port,Some(response)); + match new_device{ + Ok(mut device) => { + device.darken_screen(); + if !args.manual { + device.auto_set_serial(); + } + Some(device) + }, + Err(_) => None } } - })); - } - for thread in tty_test_threads{ - let output = thread.join().unwrap_or_else(|x|{log::trace!("{:?}",x); None}); - possible_devices.push(output); - } - - let mut serials_set:bool = true; - let mut devices:Vec = Vec::new(); - for possible_device in possible_devices.into_iter(){ - if let Some(device) = possible_device{ - if device.get_serial().eq("uninitialised"){ - serials_set = false; - } - devices.push(device); + else { None } + }, + None=>{None} } - } + })); + } + for thread in tty_test_threads{ + let output = thread.join().unwrap_or_else(|x|{log::trace!("{:?}",x); None}); + possible_devices.push(output); + } - log::info!("--------------------------------------"); - log::info!("Number of devices detected: {}",devices.len()); - log::info!("--------------------------------------\n\n"); - - log::info!("Setting up probe wells for all devices. This may take several minutes..."); - for device in devices.iter_mut(){ - if !serials_set || args.manual { - device.brighten_screen(); - device.manual_set_serial(&input_filtering(Some("Enter the serial of the device with the bright screen: ")).to_string()); - device.darken_screen(); - } - log::info!("Checking probe well of device {}",device.get_serial()); - log::debug!("Number of unassigned addresses: {}",gpio.get_unassigned_addresses().len()); - if !find_gpio(device, gpio){ - device.set_pin_address(21); - log::error!("Unable to find probe-well for device {}. Please ensure that the probe well is installed properly, and the calibration key is plugged in.",device.get_serial()); - device.brighten_screen(); - panic!(); - } - } - - let mut iteration_threads = Vec::new(); - while let Some(mut device) = devices.pop(){ - iteration_threads.push(thread::spawn(move||{ - device.init_temp_count(); - for i in 1..=iteration_count{ - log::info!("Starting iteration {} of {} for device {}...", - i,iteration_count,device.get_serial()); - device.test_cycle(None); - } - })); - } - for thread in iteration_threads{ - thread.join().unwrap(); + let mut serials_set:bool = true; + let mut devices:Vec = Vec::new(); + for possible_device in possible_devices.into_iter(){ + if let Some(device) = possible_device{ + if device.get_serial().eq("uninitialised"){ + serials_set = false; } + devices.push(device); } - Err(_)=>{ - log::error!("Invalid serial location! Please make sure that /dev/serial/by-path exists."); - break; + } + + log::info!("--------------------------------------"); + log::info!("Number of devices detected: {}",devices.len()); + log::info!("--------------------------------------\n\n"); + + log::info!("Setting up probe wells for all devices. This may take several minutes..."); + for device in devices.iter_mut(){ + if !serials_set || args.manual { + device.brighten_screen(); + device.manual_set_serial(&input_filtering(Some("Enter the serial of the device with the bright screen: ")).to_string()); + device.darken_screen(); } + log::info!("Checking probe well of device {}",device.get_serial()); + log::debug!("Number of unassigned addresses: {}",gpio.get_unassigned_addresses().len()); + if !find_gpio(device, gpio){ + device.set_pin_address(21); + log::error!("Unable to find probe-well for device {}. Please ensure that the probe well is installed properly, and the calibration key is plugged in.",device.get_serial()); + device.brighten_screen(); + panic!(); + } + } + + let mut iteration_threads = Vec::new(); + while let Some(mut device) = devices.pop(){ + iteration_threads.push(thread::spawn(move||{ + device.init_temp_count(); + for i in 1..=iteration_count{ + log::info!("Starting iteration {} of {} for device {}...", + i,iteration_count,device.get_serial()); + device.test_cycle(None); + } + })); + } + for thread in iteration_threads{ + thread.join().unwrap(); } if input_filtering(Some("Would you like to run the tests again? (y/N): ")).to_string().contains("y") {} else { break; } From 04e79dca2b525ecc7316b140e2ab91a5c7e0ed10 Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Thu, 29 Jun 2023 10:04:47 -0400 Subject: [PATCH 62/62] Version bump --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/main.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 45ef427..b91d292 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -618,7 +618,7 @@ dependencies = [ [[package]] name = "seymour_life" -version = "2.3.2" +version = "2.3.3" dependencies = [ "chrono", "clap", diff --git a/Cargo.toml b/Cargo.toml index b54fcb6..02a5089 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "seymour_life" -version = "2.3.2" +version = "2.3.3" edition = "2021" #This feature is currently limited to nightly versions of cargo. #forced-target="aarch64-unknown-linux-musl" diff --git a/src/main.rs b/src/main.rs index 61b49c1..2b5522a 100755 --- a/src/main.rs +++ b/src/main.rs @@ -25,7 +25,7 @@ struct Args{ } -const VERSION:&str="2.3.2"; +const VERSION:&str="2.3.3"; const DEBUG_ITERATION_COUNT:u64=50000; fn int_input_filtering(prompt:Option<&str>) -> u64{