mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-22 05:59:15 +01:00
Debug/server cleanup
This commit is contained in:
parent
d9456bcd14
commit
5d5d743f05
@ -1,6 +1,7 @@
|
||||
use crate::sc64;
|
||||
use chrono::Local;
|
||||
use colored::Colorize;
|
||||
use encoding_rs::EUC_JP;
|
||||
use panic_message::panic_message;
|
||||
use std::{
|
||||
fs::File,
|
||||
@ -116,74 +117,99 @@ impl TryFrom<Vec<u8>> for ScreenshotMetadata {
|
||||
}
|
||||
}
|
||||
|
||||
const MAX_FILE_LENGTH: u64 = 8 * 1024 * 1024;
|
||||
macro_rules! success {
|
||||
($($a: tt)*) => {
|
||||
println!("{}", format!($($a)*).bright_blue());
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! error {
|
||||
($($a: tt)*) => {{
|
||||
println!("{}", format!("Error: {}", format!($($a)*)).bright_red());
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! stop {
|
||||
($r: expr, $($a: tt)*) => {{
|
||||
error!($($a)*);
|
||||
$r
|
||||
}};
|
||||
}
|
||||
|
||||
const MAX_PACKET_LENGTH: usize = 8 * 1024 * 1024;
|
||||
|
||||
impl Handler {
|
||||
pub fn process_user_input(&self) -> Option<sc64::DebugPacket> {
|
||||
if let Ok(line) = self.line_rx.try_recv() {
|
||||
if line.len() == 0 {
|
||||
return None;
|
||||
}
|
||||
let mut data: Vec<u8> = Vec::new();
|
||||
if line.matches("@").count() != 2 {
|
||||
data.append(&mut line.as_bytes().to_vec());
|
||||
data.append(&mut [b'\0'].to_vec());
|
||||
return Some(sc64::DebugPacket {
|
||||
datatype: DataType::Text.into(),
|
||||
data,
|
||||
});
|
||||
} else {
|
||||
let start = line.find("@").unwrap();
|
||||
let end = line.rfind("@").unwrap();
|
||||
let path = &line[start + 1..end];
|
||||
if path.len() == 0 {
|
||||
println!("Invalid path provided");
|
||||
let line = match self.line_rx.try_recv() {
|
||||
Ok(line) => {
|
||||
if line.len() == 0 {
|
||||
return None;
|
||||
}
|
||||
let mut file = match File::open(path) {
|
||||
Ok(file) => file,
|
||||
Err(error) => {
|
||||
println!("Couldn't open file: {error}");
|
||||
return None;
|
||||
}
|
||||
};
|
||||
let length = match file.metadata() {
|
||||
Ok(metadata) => metadata.len(),
|
||||
Err(error) => {
|
||||
println!("Couldn't get file length: {error}");
|
||||
return None;
|
||||
}
|
||||
};
|
||||
if length > MAX_FILE_LENGTH {
|
||||
println!("File too big ({length} bytes), exceeding max size of {MAX_FILE_LENGTH} bytes");
|
||||
return None;
|
||||
}
|
||||
let mut data = vec![0u8; length as usize];
|
||||
if let Err(error) = file.read_exact(&mut data) {
|
||||
println!("Couldn't read file contents: {error}");
|
||||
return None;
|
||||
}
|
||||
if line.starts_with("@") && line.ends_with("@") {
|
||||
return Some(sc64::DebugPacket {
|
||||
datatype: DataType::RawBinary.into(),
|
||||
data,
|
||||
});
|
||||
} else {
|
||||
let mut combined_data: Vec<u8> = Vec::new();
|
||||
combined_data.append(&mut line[0..start].as_bytes().to_vec());
|
||||
combined_data.append(&mut [b'@'].to_vec());
|
||||
combined_data.append(&mut format!("{length}").into_bytes());
|
||||
combined_data.append(&mut [b'@'].to_vec());
|
||||
combined_data.append(&mut data);
|
||||
combined_data.append(&mut [b'\0'].to_vec());
|
||||
return Some(sc64::DebugPacket {
|
||||
datatype: DataType::Text.into(),
|
||||
data: combined_data,
|
||||
});
|
||||
line
|
||||
}
|
||||
}
|
||||
Err(_) => return None,
|
||||
};
|
||||
|
||||
let token_count = line.matches("@").count();
|
||||
|
||||
if (token_count % 2) != 0 {
|
||||
return stop!(None, "Missing closing '@' token");
|
||||
}
|
||||
None
|
||||
|
||||
let packet = if token_count == 2 && line.starts_with("@") && line.ends_with("@") {
|
||||
sc64::DebugPacket {
|
||||
datatype: DataType::RawBinary.into(),
|
||||
data: match load_file(line.trim_matches('@')) {
|
||||
Ok(data) => data,
|
||||
Err(error) => return stop!(None, "{error}"),
|
||||
},
|
||||
}
|
||||
} else {
|
||||
let mut is_text = true;
|
||||
let mut path = String::new();
|
||||
let mut character_buffer = vec![0u8; 4];
|
||||
let mut data = vec![0u8; 0];
|
||||
for character in line.chars() {
|
||||
if character == '@' {
|
||||
if is_text {
|
||||
is_text = false;
|
||||
} else {
|
||||
let mut file = match load_file(&path) {
|
||||
Ok(data) => data,
|
||||
Err(error) => return stop!(None, "{error}"),
|
||||
};
|
||||
let length = file.len();
|
||||
data.append(&mut format!("@{length}@").into_bytes());
|
||||
data.append(&mut file);
|
||||
is_text = true;
|
||||
path = String::new();
|
||||
}
|
||||
} else {
|
||||
if is_text {
|
||||
let encoded = character.encode_utf8(&mut character_buffer);
|
||||
data.append(&mut encoded.as_bytes().to_vec());
|
||||
} else {
|
||||
path.push(character);
|
||||
}
|
||||
}
|
||||
}
|
||||
sc64::DebugPacket {
|
||||
datatype: DataType::Text.into(),
|
||||
data,
|
||||
}
|
||||
};
|
||||
|
||||
if packet.data.len() > MAX_PACKET_LENGTH {
|
||||
return stop!(
|
||||
None,
|
||||
"Debug packet size too big ({}), exceeding maximum size of {}",
|
||||
packet.data.len(),
|
||||
MAX_PACKET_LENGTH
|
||||
);
|
||||
}
|
||||
|
||||
Some(packet)
|
||||
}
|
||||
|
||||
pub fn handle_debug_packet(&mut self, debug_packet: sc64::DebugPacket) {
|
||||
@ -194,9 +220,53 @@ impl Handler {
|
||||
DataType::Header => self.handle_datatype_header(&data),
|
||||
DataType::Screenshot => self.handle_datatype_screenshot(&data),
|
||||
DataType::GDB => self.handle_datatype_gdb(&data),
|
||||
_ => {
|
||||
println!("Unknown debug packet datatype: 0x{datatype:02X}");
|
||||
_ => error!("Received unknown debug packet datatype: 0x{datatype:02X}"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_is_viewer_64(&self, message: Vec<u8>) {
|
||||
print!("{}", EUC_JP.decode(&message).0)
|
||||
}
|
||||
|
||||
pub fn handle_save_writeback(
|
||||
&self,
|
||||
save_writeback: sc64::SaveWriteback,
|
||||
path: &Option<PathBuf>,
|
||||
) {
|
||||
let filename = &if let Some(path) = path {
|
||||
path.to_string_lossy().to_string()
|
||||
} else {
|
||||
generate_filename(
|
||||
"save",
|
||||
match save_writeback.save {
|
||||
sc64::SaveType::Eeprom4k | sc64::SaveType::Eeprom16k => "eep",
|
||||
sc64::SaveType::Sram | sc64::SaveType::SramBanked | sc64::SaveType::Sram1m => {
|
||||
"srm"
|
||||
}
|
||||
sc64::SaveType::Flashram => "fla",
|
||||
_ => "sav",
|
||||
},
|
||||
)
|
||||
};
|
||||
match File::create(filename) {
|
||||
Ok(mut file) => {
|
||||
if let Err(error) = file.write_all(&save_writeback.data) {
|
||||
error!("Couldn't write save [{filename}]: {error}");
|
||||
}
|
||||
success!("Wrote [{}] save to [{filename}]", save_writeback.save);
|
||||
}
|
||||
Err(error) => error!("Couldn't create save writeback file [{filename}]: {error}"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn receive_gdb_packet(&self) -> Option<sc64::DebugPacket> {
|
||||
if let Some(data) = self.gdb_rx.try_recv().ok() {
|
||||
Some(sc64::DebugPacket {
|
||||
datatype: DataType::GDB.into(),
|
||||
data,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,17 +275,15 @@ impl Handler {
|
||||
}
|
||||
|
||||
fn handle_datatype_raw_binary(&self, data: &[u8]) {
|
||||
let filename = &self.generate_filename("binaryout", "bin");
|
||||
let filename = &generate_filename("binaryout", "bin");
|
||||
match File::create(filename) {
|
||||
Ok(mut file) => {
|
||||
if let Err(error) = file.write_all(data) {
|
||||
println!("Error during raw binary write: {error}");
|
||||
error!("Couldn't write raw binary [{filename}]: {error}");
|
||||
}
|
||||
println!("Wrote [{}] bytes to [{}]", data.len(), filename);
|
||||
}
|
||||
Err(error) => {
|
||||
println!("Error during raw binary file creation: {error}");
|
||||
success!("Wrote [{}] bytes to [{filename}]", data.len());
|
||||
}
|
||||
Err(error) => error!("Couldn't create raw binary file [{filename}]: {error}"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,10 +294,7 @@ impl Handler {
|
||||
fn handle_datatype_screenshot(&mut self, data: &[u8]) {
|
||||
let header = match self.header.take() {
|
||||
Some(header) => header,
|
||||
None => {
|
||||
println!("Got screenshot packet without header data");
|
||||
return;
|
||||
}
|
||||
None => return error!("Got screenshot packet without header data"),
|
||||
};
|
||||
let ScreenshotMetadata {
|
||||
format,
|
||||
@ -237,15 +302,11 @@ impl Handler {
|
||||
width,
|
||||
} = match header.try_into() {
|
||||
Ok(data) => data,
|
||||
Err(error) => {
|
||||
println!("{error}");
|
||||
return;
|
||||
}
|
||||
Err(error) => return error!("{error}"),
|
||||
};
|
||||
let format_size: u32 = format.into();
|
||||
if data.len() as u32 != format_size * width * height {
|
||||
println!("Data length did not match header data for screenshot datatype");
|
||||
return;
|
||||
return error!("Data length did not match header data for screenshot datatype");
|
||||
}
|
||||
let mut image = image::RgbaImage::new(width, height);
|
||||
for (x, y, pixel) in image.enumerate_pixels_mut() {
|
||||
@ -262,68 +323,45 @@ impl Handler {
|
||||
ScreenshotPixelFormat::Rgba32 => [p[0], p[1], p[2], p[3]],
|
||||
}
|
||||
}
|
||||
let filename = &self.generate_filename("screenshot", "png");
|
||||
let filename = &generate_filename("screenshot", "png");
|
||||
if let Some(error) = image.save(filename).err() {
|
||||
println!("Error during image save: {error}");
|
||||
return;
|
||||
return error!("Couldn't save screenshot [{filename}]: {error}");
|
||||
}
|
||||
println!("Wrote {width}x{height} pixels to [{filename}]");
|
||||
success!("Wrote {width}x{height} pixels to [{filename}]");
|
||||
}
|
||||
|
||||
fn handle_datatype_gdb(&self, data: &[u8]) {
|
||||
self.gdb_tx.send(data.to_vec()).ok();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_save_writeback(
|
||||
&self,
|
||||
save_writeback: sc64::SaveWriteback,
|
||||
path: &Option<PathBuf>,
|
||||
) {
|
||||
let filename = &if let Some(path) = path {
|
||||
path.to_string_lossy().to_string()
|
||||
} else {
|
||||
self.generate_filename(
|
||||
"save",
|
||||
match save_writeback.save {
|
||||
sc64::SaveType::Eeprom4k | sc64::SaveType::Eeprom16k => "eep",
|
||||
sc64::SaveType::Sram | sc64::SaveType::SramBanked | sc64::SaveType::Sram1m => {
|
||||
"srm"
|
||||
}
|
||||
sc64::SaveType::Flashram => "fla",
|
||||
_ => "sav",
|
||||
},
|
||||
)
|
||||
};
|
||||
match File::create(filename) {
|
||||
Ok(mut file) => {
|
||||
if let Err(error) = file.write_all(&save_writeback.data) {
|
||||
println!("Error during save write: {error}");
|
||||
}
|
||||
println!("Wrote [{}] save to [{}]", save_writeback.save, filename);
|
||||
}
|
||||
Err(error) => {
|
||||
println!("Error during save writeback file creation: {error}");
|
||||
}
|
||||
}
|
||||
fn load_file(path: &str) -> Result<Vec<u8>, String> {
|
||||
if path.len() == 0 {
|
||||
return Err(format!("Couldn't open file: Specified path is empty"));
|
||||
}
|
||||
let mut file = match File::open(path) {
|
||||
Ok(file) => file,
|
||||
Err(error) => return Err(format!("Couldn't open file [{path}]: {error}")),
|
||||
};
|
||||
let length = match file.metadata() {
|
||||
Ok(metadata) => metadata.len(),
|
||||
Err(error) => return Err(format!("Couldn't get file [{path}] length: {error}")),
|
||||
};
|
||||
if length > MAX_PACKET_LENGTH as u64 {
|
||||
return Err(format!("File [{path}] size too big"));
|
||||
}
|
||||
let mut data = vec![0u8; length as usize];
|
||||
match file.read_exact(&mut data) {
|
||||
Ok(()) => Ok(data),
|
||||
Err(error) => Err(format!("Couldn't read file [{path}] contents: {error}")),
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_filename(&self, prefix: &str, extension: &str) -> String {
|
||||
format!(
|
||||
"{prefix}-{}.{extension}",
|
||||
Local::now().format("%y%m%d%H%M%S.%f")
|
||||
)
|
||||
}
|
||||
|
||||
pub fn receive_gdb_packet(&self) -> Option<sc64::DebugPacket> {
|
||||
if let Some(data) = self.gdb_rx.try_recv().ok() {
|
||||
Some(sc64::DebugPacket {
|
||||
datatype: DataType::GDB.into(),
|
||||
data,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn generate_filename(prefix: &str, extension: &str) -> String {
|
||||
format!(
|
||||
"{prefix}-{}.{extension}",
|
||||
Local::now().format("%y%m%d%H%M%S.%f")
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new(gdb_port: Option<u16>) -> Result<Handler, sc64::Error> {
|
||||
|
@ -504,22 +504,22 @@ fn handle_64dd_command(connection: Connection, args: &_64DDArgs) -> Result<(), s
|
||||
while !exit.load(Ordering::Relaxed) {
|
||||
if let Some(data_packet) = sc64.receive_data_packet()? {
|
||||
match data_packet {
|
||||
sc64::DataPacket::Disk(mut packet) => {
|
||||
let track = packet.info.track;
|
||||
let head = packet.info.head;
|
||||
let block = packet.info.block;
|
||||
sc64::DataPacket::DiskRequest(mut disk_packet) => {
|
||||
let track = disk_packet.info.track;
|
||||
let head = disk_packet.info.head;
|
||||
let block = disk_packet.info.block;
|
||||
if let Some(ref mut disk) = selected_disk {
|
||||
let (reply_packet, rw) = match packet.kind {
|
||||
let (reply_packet, rw) = match disk_packet.kind {
|
||||
sc64::DiskPacketKind::Read => (
|
||||
disk.read_block(track, head, block)?.map(|data| {
|
||||
packet.info.set_data(&data);
|
||||
packet
|
||||
disk_packet.info.set_data(&data);
|
||||
disk_packet
|
||||
}),
|
||||
"[R]".bright_blue(),
|
||||
),
|
||||
sc64::DiskPacketKind::Write => (
|
||||
disk.write_block(track, head, block, &packet.info.data)?
|
||||
.map(|_| packet),
|
||||
disk.write_block(track, head, block, &disk_packet.info.data)?
|
||||
.map(|_| disk_packet),
|
||||
"[W]".bright_yellow(),
|
||||
),
|
||||
};
|
||||
@ -595,11 +595,11 @@ fn handle_debug_command(connection: Connection, args: &DebugArgs) -> Result<(),
|
||||
while !exit.load(Ordering::Relaxed) {
|
||||
if let Some(data_packet) = sc64.receive_data_packet()? {
|
||||
match data_packet {
|
||||
sc64::DataPacket::IsViewer64(message) => {
|
||||
print!("{message}")
|
||||
sc64::DataPacket::DebugData(debug_packet) => {
|
||||
debug_handler.handle_debug_packet(debug_packet);
|
||||
}
|
||||
sc64::DataPacket::Debug(debug_packet) => {
|
||||
debug_handler.handle_debug_packet(debug_packet)
|
||||
sc64::DataPacket::IsViewer64(message) => {
|
||||
debug_handler.handle_is_viewer_64(message);
|
||||
}
|
||||
sc64::DataPacket::SaveWriteback(save_writeback) => {
|
||||
debug_handler.handle_save_writeback(save_writeback, &args.save);
|
||||
|
@ -39,10 +39,10 @@ impl TryFrom<u32> for DataType {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Command<'a> {
|
||||
pub struct Command {
|
||||
pub id: u8,
|
||||
pub args: [u32; 2],
|
||||
pub data: &'a [u8],
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
pub struct Response {
|
||||
|
@ -103,7 +103,7 @@ impl SC64 {
|
||||
let data = self.link.execute_command(&Command {
|
||||
id: b'v',
|
||||
args: [0, 0],
|
||||
data: &[],
|
||||
data: vec![],
|
||||
})?;
|
||||
if data.len() != 4 {
|
||||
return Err(Error::new(
|
||||
@ -117,7 +117,7 @@ impl SC64 {
|
||||
let data = self.link.execute_command(&Command {
|
||||
id: b'V',
|
||||
args: [0, 0],
|
||||
data: &[],
|
||||
data: vec![],
|
||||
})?;
|
||||
if data.len() != 8 {
|
||||
return Err(Error::new(
|
||||
@ -134,7 +134,7 @@ impl SC64 {
|
||||
self.link.execute_command(&Command {
|
||||
id: b'R',
|
||||
args: [0, 0],
|
||||
data: &[],
|
||||
data: vec![],
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
@ -152,7 +152,7 @@ impl SC64 {
|
||||
self.link.execute_command(&Command {
|
||||
id: b'B',
|
||||
args,
|
||||
data: &[],
|
||||
data: vec![],
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
@ -161,7 +161,7 @@ impl SC64 {
|
||||
let data = self.link.execute_command(&Command {
|
||||
id: b'c',
|
||||
args: [config_id.into(), 0],
|
||||
data: &[],
|
||||
data: vec![],
|
||||
})?;
|
||||
if data.len() != 4 {
|
||||
return Err(Error::new(
|
||||
@ -176,7 +176,7 @@ impl SC64 {
|
||||
self.link.execute_command(&Command {
|
||||
id: b'C',
|
||||
args: config.into(),
|
||||
data: &[],
|
||||
data: vec![],
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
@ -185,7 +185,7 @@ impl SC64 {
|
||||
let data = self.link.execute_command(&Command {
|
||||
id: b'a',
|
||||
args: [setting_id.into(), 0],
|
||||
data: &[],
|
||||
data: vec![],
|
||||
})?;
|
||||
if data.len() != 4 {
|
||||
return Err(Error::new(
|
||||
@ -200,7 +200,7 @@ impl SC64 {
|
||||
self.link.execute_command(&Command {
|
||||
id: b'A',
|
||||
args: setting.into(),
|
||||
data: &[],
|
||||
data: vec![],
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
@ -209,7 +209,7 @@ impl SC64 {
|
||||
let data = self.link.execute_command(&Command {
|
||||
id: b't',
|
||||
args: [0, 0],
|
||||
data: &[],
|
||||
data: vec![],
|
||||
})?;
|
||||
if data.len() != 8 {
|
||||
return Err(Error::new(
|
||||
@ -223,7 +223,7 @@ impl SC64 {
|
||||
self.link.execute_command(&Command {
|
||||
id: b'T',
|
||||
args: convert_from_datetime(datetime),
|
||||
data: &[],
|
||||
data: vec![],
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
@ -232,7 +232,7 @@ impl SC64 {
|
||||
let data = self.link.execute_command(&Command {
|
||||
id: b'm',
|
||||
args: [address, length as u32],
|
||||
data: &[],
|
||||
data: vec![],
|
||||
})?;
|
||||
if data.len() != length {
|
||||
return Err(Error::new(
|
||||
@ -246,7 +246,7 @@ impl SC64 {
|
||||
self.link.execute_command(&Command {
|
||||
id: b'M',
|
||||
args: [address, data.len() as u32],
|
||||
data,
|
||||
data: data.to_vec(),
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
@ -256,7 +256,7 @@ impl SC64 {
|
||||
&Command {
|
||||
id: b'U',
|
||||
args: [datatype as u32, data.len() as u32],
|
||||
data,
|
||||
data: data.to_vec(),
|
||||
},
|
||||
true,
|
||||
false,
|
||||
@ -268,7 +268,7 @@ impl SC64 {
|
||||
self.link.execute_command(&Command {
|
||||
id: b'D',
|
||||
args: [error as u32, 0],
|
||||
data: &[],
|
||||
data: vec![],
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
@ -277,7 +277,7 @@ impl SC64 {
|
||||
self.link.execute_command(&Command {
|
||||
id: b'W',
|
||||
args: [0, 0],
|
||||
data: &[],
|
||||
data: vec![],
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
@ -286,7 +286,7 @@ impl SC64 {
|
||||
let data = self.link.execute_command(&Command {
|
||||
id: b'p',
|
||||
args: [wait as u32, 0],
|
||||
data: &[],
|
||||
data: vec![],
|
||||
})?;
|
||||
if data.len() != 4 {
|
||||
return Err(Error::new(
|
||||
@ -301,7 +301,7 @@ impl SC64 {
|
||||
self.link.execute_command(&Command {
|
||||
id: b'P',
|
||||
args: [address, 0],
|
||||
data: &[],
|
||||
data: vec![],
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
@ -311,7 +311,7 @@ impl SC64 {
|
||||
&Command {
|
||||
id: b'f',
|
||||
args: [address, 0],
|
||||
data: &[],
|
||||
data: vec![],
|
||||
},
|
||||
false,
|
||||
true,
|
||||
@ -335,7 +335,7 @@ impl SC64 {
|
||||
&Command {
|
||||
id: b'F',
|
||||
args: [address, length as u32],
|
||||
data: &[],
|
||||
data: vec![],
|
||||
},
|
||||
false,
|
||||
true,
|
||||
@ -352,7 +352,7 @@ impl SC64 {
|
||||
let data = self.link.execute_command(&Command {
|
||||
id: b'?',
|
||||
args: [0, 0],
|
||||
data: &[],
|
||||
data: vec![],
|
||||
})?;
|
||||
Ok(data.try_into()?)
|
||||
}
|
||||
@ -361,7 +361,7 @@ impl SC64 {
|
||||
let data = self.link.execute_command(&Command {
|
||||
id: b'%',
|
||||
args: [0, 0],
|
||||
data: &[],
|
||||
data: vec![],
|
||||
})?;
|
||||
Ok(data.try_into()?)
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ pub fn run_server(
|
||||
}
|
||||
|
||||
enum Event {
|
||||
Command((u8, [u32; 2], Vec<u8>)),
|
||||
Command(Command),
|
||||
Response(Response),
|
||||
Packet(Packet),
|
||||
KeepAlive,
|
||||
@ -114,12 +114,8 @@ fn server_process_events(
|
||||
) -> Result<(), Error> {
|
||||
for event in event_receiver.into_iter() {
|
||||
match event {
|
||||
Event::Command((id, args, data)) => {
|
||||
serial_writer.send_command(&Command {
|
||||
id,
|
||||
args,
|
||||
data: &data,
|
||||
})?;
|
||||
Event::Command(command) => {
|
||||
serial_writer.send_command(&command)?;
|
||||
}
|
||||
Event::Response(response) => {
|
||||
stream_writer.write_all(&u32::to_be_bytes(DataType::Response.into()))?;
|
||||
@ -188,10 +184,12 @@ fn server_stream_thread(
|
||||
}
|
||||
|
||||
let mut buffer = [0u8; 4];
|
||||
let mut id = [0u8; 1];
|
||||
let mut id_buffer = [0u8; 1];
|
||||
let mut args = [0u32; 2];
|
||||
|
||||
stream_reader.read_exact(&mut id)?;
|
||||
stream_reader.read_exact(&mut id_buffer)?;
|
||||
let id = id_buffer[0];
|
||||
|
||||
stream_reader.read_exact(&mut buffer)?;
|
||||
args[0] = u32::from_be_bytes(buffer);
|
||||
stream_reader.read_exact(&mut buffer)?;
|
||||
@ -202,8 +200,10 @@ fn server_stream_thread(
|
||||
let mut data = vec![0u8; command_data_length];
|
||||
stream_reader.read_exact(&mut data)?;
|
||||
|
||||
let event = Event::Command((id[0], args, data));
|
||||
if event_sender.send(event).is_err() {
|
||||
if event_sender
|
||||
.send(Event::Command(Command { id, args, data }))
|
||||
.is_err()
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -222,15 +222,13 @@ fn server_serial_thread(
|
||||
let response = serial_reader.process_incoming_data(DataType::Packet, &mut packets)?;
|
||||
|
||||
if let Some(response) = response {
|
||||
let event = Event::Response(response);
|
||||
if event_sender.send(event).is_err() {
|
||||
if event_sender.send(Event::Response(response)).is_err() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(packet) = packets.pop_front() {
|
||||
let event = Event::Packet(packet);
|
||||
if event_sender.send(event).is_err() {
|
||||
if event_sender.send(Event::Packet(packet)).is_err() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -245,8 +243,7 @@ fn server_keepalive_thread(event_sender: Sender<Event>, exit_flag: Arc<AtomicBoo
|
||||
while !exit_flag.load(Ordering::Relaxed) {
|
||||
if keepalive.elapsed() >= Duration::from_secs(5) {
|
||||
keepalive = Instant::now();
|
||||
let event = Event::KeepAlive;
|
||||
if event_sender.send(event).is_err() {
|
||||
if event_sender.send(Event::KeepAlive).is_err() {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
@ -1,5 +1,4 @@
|
||||
use super::{link::Packet, Error};
|
||||
use encoding_rs::EUC_JP;
|
||||
use std::fmt::Display;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
@ -581,9 +580,9 @@ impl From<Setting> for [u32; 2] {
|
||||
|
||||
pub enum DataPacket {
|
||||
Button,
|
||||
Debug(DebugPacket),
|
||||
Disk(DiskPacket),
|
||||
IsViewer64(String),
|
||||
DebugData(DebugPacket),
|
||||
DiskRequest(DiskPacket),
|
||||
IsViewer64(Vec<u8>),
|
||||
SaveWriteback(SaveWriteback),
|
||||
UpdateStatus(UpdateStatus),
|
||||
}
|
||||
@ -593,9 +592,9 @@ impl TryFrom<Packet> for DataPacket {
|
||||
fn try_from(value: Packet) -> Result<Self, Self::Error> {
|
||||
Ok(match value.id {
|
||||
b'B' => Self::Button,
|
||||
b'U' => Self::Debug(value.data.try_into()?),
|
||||
b'D' => Self::Disk(value.data.try_into()?),
|
||||
b'I' => Self::IsViewer64(EUC_JP.decode(&value.data).0.into()),
|
||||
b'U' => Self::DebugData(value.data.try_into()?),
|
||||
b'D' => Self::DiskRequest(value.data.try_into()?),
|
||||
b'I' => Self::IsViewer64(value.data),
|
||||
b'S' => Self::SaveWriteback(value.data.try_into()?),
|
||||
b'F' => {
|
||||
if value.data.len() != 4 {
|
||||
|
Loading…
Reference in New Issue
Block a user