Debug/server cleanup

This commit is contained in:
Mateusz Faderewski 2023-04-02 18:34:24 +02:00
parent d9456bcd14
commit 5d5d743f05
6 changed files with 224 additions and 190 deletions

View File

@ -1,6 +1,7 @@
use crate::sc64; use crate::sc64;
use chrono::Local; use chrono::Local;
use colored::Colorize; use colored::Colorize;
use encoding_rs::EUC_JP;
use panic_message::panic_message; use panic_message::panic_message;
use std::{ use std::{
fs::File, 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 { impl Handler {
pub fn process_user_input(&self) -> Option<sc64::DebugPacket> { pub fn process_user_input(&self) -> Option<sc64::DebugPacket> {
if let Ok(line) = self.line_rx.try_recv() { let line = match self.line_rx.try_recv() {
if line.len() == 0 { Ok(line) => {
return None; if line.len() == 0 {
}
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");
return None; 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 { } else {
let mut combined_data: Vec<u8> = Vec::new(); line
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,
});
} }
} }
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) { 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::Header => self.handle_datatype_header(&data),
DataType::Screenshot => self.handle_datatype_screenshot(&data), DataType::Screenshot => self.handle_datatype_screenshot(&data),
DataType::GDB => self.handle_datatype_gdb(&data), DataType::GDB => self.handle_datatype_gdb(&data),
_ => { _ => error!("Received unknown debug packet datatype: 0x{datatype:02X}"),
println!("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]) { 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) { match File::create(filename) {
Ok(mut file) => { Ok(mut file) => {
if let Err(error) = file.write_all(data) { 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); success!("Wrote [{}] bytes to [{filename}]", data.len());
}
Err(error) => {
println!("Error during raw binary file creation: {error}");
} }
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]) { fn handle_datatype_screenshot(&mut self, data: &[u8]) {
let header = match self.header.take() { let header = match self.header.take() {
Some(header) => header, Some(header) => header,
None => { None => return error!("Got screenshot packet without header data"),
println!("Got screenshot packet without header data");
return;
}
}; };
let ScreenshotMetadata { let ScreenshotMetadata {
format, format,
@ -237,15 +302,11 @@ impl Handler {
width, width,
} = match header.try_into() { } = match header.try_into() {
Ok(data) => data, Ok(data) => data,
Err(error) => { Err(error) => return error!("{error}"),
println!("{error}");
return;
}
}; };
let format_size: u32 = format.into(); let format_size: u32 = format.into();
if data.len() as u32 != format_size * width * height { if data.len() as u32 != format_size * width * height {
println!("Data length did not match header data for screenshot datatype"); return error!("Data length did not match header data for screenshot datatype");
return;
} }
let mut image = image::RgbaImage::new(width, height); let mut image = image::RgbaImage::new(width, height);
for (x, y, pixel) in image.enumerate_pixels_mut() { 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]], 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() { if let Some(error) = image.save(filename).err() {
println!("Error during image save: {error}"); return error!("Couldn't save screenshot [{filename}]: {error}");
return;
} }
println!("Wrote {width}x{height} pixels to [{filename}]"); success!("Wrote {width}x{height} pixels to [{filename}]");
} }
fn handle_datatype_gdb(&self, data: &[u8]) { fn handle_datatype_gdb(&self, data: &[u8]) {
self.gdb_tx.send(data.to_vec()).ok(); self.gdb_tx.send(data.to_vec()).ok();
} }
}
pub fn handle_save_writeback( fn load_file(path: &str) -> Result<Vec<u8>, String> {
&self, if path.len() == 0 {
save_writeback: sc64::SaveWriteback, return Err(format!("Couldn't open file: Specified path is empty"));
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}");
}
}
} }
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 { fn generate_filename(prefix: &str, extension: &str) -> String {
format!( format!(
"{prefix}-{}.{extension}", "{prefix}-{}.{extension}",
Local::now().format("%y%m%d%H%M%S.%f") 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
}
}
} }
pub fn new(gdb_port: Option<u16>) -> Result<Handler, sc64::Error> { pub fn new(gdb_port: Option<u16>) -> Result<Handler, sc64::Error> {

View File

@ -504,22 +504,22 @@ fn handle_64dd_command(connection: Connection, args: &_64DDArgs) -> Result<(), s
while !exit.load(Ordering::Relaxed) { while !exit.load(Ordering::Relaxed) {
if let Some(data_packet) = sc64.receive_data_packet()? { if let Some(data_packet) = sc64.receive_data_packet()? {
match data_packet { match data_packet {
sc64::DataPacket::Disk(mut packet) => { sc64::DataPacket::DiskRequest(mut disk_packet) => {
let track = packet.info.track; let track = disk_packet.info.track;
let head = packet.info.head; let head = disk_packet.info.head;
let block = packet.info.block; let block = disk_packet.info.block;
if let Some(ref mut disk) = selected_disk { 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 => ( sc64::DiskPacketKind::Read => (
disk.read_block(track, head, block)?.map(|data| { disk.read_block(track, head, block)?.map(|data| {
packet.info.set_data(&data); disk_packet.info.set_data(&data);
packet disk_packet
}), }),
"[R]".bright_blue(), "[R]".bright_blue(),
), ),
sc64::DiskPacketKind::Write => ( sc64::DiskPacketKind::Write => (
disk.write_block(track, head, block, &packet.info.data)? disk.write_block(track, head, block, &disk_packet.info.data)?
.map(|_| packet), .map(|_| disk_packet),
"[W]".bright_yellow(), "[W]".bright_yellow(),
), ),
}; };
@ -595,11 +595,11 @@ fn handle_debug_command(connection: Connection, args: &DebugArgs) -> Result<(),
while !exit.load(Ordering::Relaxed) { while !exit.load(Ordering::Relaxed) {
if let Some(data_packet) = sc64.receive_data_packet()? { if let Some(data_packet) = sc64.receive_data_packet()? {
match data_packet { match data_packet {
sc64::DataPacket::IsViewer64(message) => { sc64::DataPacket::DebugData(debug_packet) => {
print!("{message}") debug_handler.handle_debug_packet(debug_packet);
} }
sc64::DataPacket::Debug(debug_packet) => { sc64::DataPacket::IsViewer64(message) => {
debug_handler.handle_debug_packet(debug_packet) debug_handler.handle_is_viewer_64(message);
} }
sc64::DataPacket::SaveWriteback(save_writeback) => { sc64::DataPacket::SaveWriteback(save_writeback) => {
debug_handler.handle_save_writeback(save_writeback, &args.save); debug_handler.handle_save_writeback(save_writeback, &args.save);

View File

@ -39,10 +39,10 @@ impl TryFrom<u32> for DataType {
} }
} }
pub struct Command<'a> { pub struct Command {
pub id: u8, pub id: u8,
pub args: [u32; 2], pub args: [u32; 2],
pub data: &'a [u8], pub data: Vec<u8>,
} }
pub struct Response { pub struct Response {

View File

@ -103,7 +103,7 @@ impl SC64 {
let data = self.link.execute_command(&Command { let data = self.link.execute_command(&Command {
id: b'v', id: b'v',
args: [0, 0], args: [0, 0],
data: &[], data: vec![],
})?; })?;
if data.len() != 4 { if data.len() != 4 {
return Err(Error::new( return Err(Error::new(
@ -117,7 +117,7 @@ impl SC64 {
let data = self.link.execute_command(&Command { let data = self.link.execute_command(&Command {
id: b'V', id: b'V',
args: [0, 0], args: [0, 0],
data: &[], data: vec![],
})?; })?;
if data.len() != 8 { if data.len() != 8 {
return Err(Error::new( return Err(Error::new(
@ -134,7 +134,7 @@ impl SC64 {
self.link.execute_command(&Command { self.link.execute_command(&Command {
id: b'R', id: b'R',
args: [0, 0], args: [0, 0],
data: &[], data: vec![],
})?; })?;
Ok(()) Ok(())
} }
@ -152,7 +152,7 @@ impl SC64 {
self.link.execute_command(&Command { self.link.execute_command(&Command {
id: b'B', id: b'B',
args, args,
data: &[], data: vec![],
})?; })?;
Ok(()) Ok(())
} }
@ -161,7 +161,7 @@ impl SC64 {
let data = self.link.execute_command(&Command { let data = self.link.execute_command(&Command {
id: b'c', id: b'c',
args: [config_id.into(), 0], args: [config_id.into(), 0],
data: &[], data: vec![],
})?; })?;
if data.len() != 4 { if data.len() != 4 {
return Err(Error::new( return Err(Error::new(
@ -176,7 +176,7 @@ impl SC64 {
self.link.execute_command(&Command { self.link.execute_command(&Command {
id: b'C', id: b'C',
args: config.into(), args: config.into(),
data: &[], data: vec![],
})?; })?;
Ok(()) Ok(())
} }
@ -185,7 +185,7 @@ impl SC64 {
let data = self.link.execute_command(&Command { let data = self.link.execute_command(&Command {
id: b'a', id: b'a',
args: [setting_id.into(), 0], args: [setting_id.into(), 0],
data: &[], data: vec![],
})?; })?;
if data.len() != 4 { if data.len() != 4 {
return Err(Error::new( return Err(Error::new(
@ -200,7 +200,7 @@ impl SC64 {
self.link.execute_command(&Command { self.link.execute_command(&Command {
id: b'A', id: b'A',
args: setting.into(), args: setting.into(),
data: &[], data: vec![],
})?; })?;
Ok(()) Ok(())
} }
@ -209,7 +209,7 @@ impl SC64 {
let data = self.link.execute_command(&Command { let data = self.link.execute_command(&Command {
id: b't', id: b't',
args: [0, 0], args: [0, 0],
data: &[], data: vec![],
})?; })?;
if data.len() != 8 { if data.len() != 8 {
return Err(Error::new( return Err(Error::new(
@ -223,7 +223,7 @@ impl SC64 {
self.link.execute_command(&Command { self.link.execute_command(&Command {
id: b'T', id: b'T',
args: convert_from_datetime(datetime), args: convert_from_datetime(datetime),
data: &[], data: vec![],
})?; })?;
Ok(()) Ok(())
} }
@ -232,7 +232,7 @@ impl SC64 {
let data = self.link.execute_command(&Command { let data = self.link.execute_command(&Command {
id: b'm', id: b'm',
args: [address, length as u32], args: [address, length as u32],
data: &[], data: vec![],
})?; })?;
if data.len() != length { if data.len() != length {
return Err(Error::new( return Err(Error::new(
@ -246,7 +246,7 @@ impl SC64 {
self.link.execute_command(&Command { self.link.execute_command(&Command {
id: b'M', id: b'M',
args: [address, data.len() as u32], args: [address, data.len() as u32],
data, data: data.to_vec(),
})?; })?;
Ok(()) Ok(())
} }
@ -256,7 +256,7 @@ impl SC64 {
&Command { &Command {
id: b'U', id: b'U',
args: [datatype as u32, data.len() as u32], args: [datatype as u32, data.len() as u32],
data, data: data.to_vec(),
}, },
true, true,
false, false,
@ -268,7 +268,7 @@ impl SC64 {
self.link.execute_command(&Command { self.link.execute_command(&Command {
id: b'D', id: b'D',
args: [error as u32, 0], args: [error as u32, 0],
data: &[], data: vec![],
})?; })?;
Ok(()) Ok(())
} }
@ -277,7 +277,7 @@ impl SC64 {
self.link.execute_command(&Command { self.link.execute_command(&Command {
id: b'W', id: b'W',
args: [0, 0], args: [0, 0],
data: &[], data: vec![],
})?; })?;
Ok(()) Ok(())
} }
@ -286,7 +286,7 @@ impl SC64 {
let data = self.link.execute_command(&Command { let data = self.link.execute_command(&Command {
id: b'p', id: b'p',
args: [wait as u32, 0], args: [wait as u32, 0],
data: &[], data: vec![],
})?; })?;
if data.len() != 4 { if data.len() != 4 {
return Err(Error::new( return Err(Error::new(
@ -301,7 +301,7 @@ impl SC64 {
self.link.execute_command(&Command { self.link.execute_command(&Command {
id: b'P', id: b'P',
args: [address, 0], args: [address, 0],
data: &[], data: vec![],
})?; })?;
Ok(()) Ok(())
} }
@ -311,7 +311,7 @@ impl SC64 {
&Command { &Command {
id: b'f', id: b'f',
args: [address, 0], args: [address, 0],
data: &[], data: vec![],
}, },
false, false,
true, true,
@ -335,7 +335,7 @@ impl SC64 {
&Command { &Command {
id: b'F', id: b'F',
args: [address, length as u32], args: [address, length as u32],
data: &[], data: vec![],
}, },
false, false,
true, true,
@ -352,7 +352,7 @@ impl SC64 {
let data = self.link.execute_command(&Command { let data = self.link.execute_command(&Command {
id: b'?', id: b'?',
args: [0, 0], args: [0, 0],
data: &[], data: vec![],
})?; })?;
Ok(data.try_into()?) Ok(data.try_into()?)
} }
@ -361,7 +361,7 @@ impl SC64 {
let data = self.link.execute_command(&Command { let data = self.link.execute_command(&Command {
id: b'%', id: b'%',
args: [0, 0], args: [0, 0],
data: &[], data: vec![],
})?; })?;
Ok(data.try_into()?) Ok(data.try_into()?)
} }

View File

@ -51,7 +51,7 @@ pub fn run_server(
} }
enum Event { enum Event {
Command((u8, [u32; 2], Vec<u8>)), Command(Command),
Response(Response), Response(Response),
Packet(Packet), Packet(Packet),
KeepAlive, KeepAlive,
@ -114,12 +114,8 @@ fn server_process_events(
) -> Result<(), Error> { ) -> Result<(), Error> {
for event in event_receiver.into_iter() { for event in event_receiver.into_iter() {
match event { match event {
Event::Command((id, args, data)) => { Event::Command(command) => {
serial_writer.send_command(&Command { serial_writer.send_command(&command)?;
id,
args,
data: &data,
})?;
} }
Event::Response(response) => { Event::Response(response) => {
stream_writer.write_all(&u32::to_be_bytes(DataType::Response.into()))?; 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 buffer = [0u8; 4];
let mut id = [0u8; 1]; let mut id_buffer = [0u8; 1];
let mut args = [0u32; 2]; 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)?; stream_reader.read_exact(&mut buffer)?;
args[0] = u32::from_be_bytes(buffer); args[0] = u32::from_be_bytes(buffer);
stream_reader.read_exact(&mut buffer)?; stream_reader.read_exact(&mut buffer)?;
@ -202,8 +200,10 @@ fn server_stream_thread(
let mut data = vec![0u8; command_data_length]; let mut data = vec![0u8; command_data_length];
stream_reader.read_exact(&mut data)?; stream_reader.read_exact(&mut data)?;
let event = Event::Command((id[0], args, data)); if event_sender
if event_sender.send(event).is_err() { .send(Event::Command(Command { id, args, data }))
.is_err()
{
break; break;
} }
} }
@ -222,15 +222,13 @@ fn server_serial_thread(
let response = serial_reader.process_incoming_data(DataType::Packet, &mut packets)?; let response = serial_reader.process_incoming_data(DataType::Packet, &mut packets)?;
if let Some(response) = response { if let Some(response) = response {
let event = Event::Response(response); if event_sender.send(Event::Response(response)).is_err() {
if event_sender.send(event).is_err() {
break; break;
} }
} }
if let Some(packet) = packets.pop_front() { if let Some(packet) = packets.pop_front() {
let event = Event::Packet(packet); if event_sender.send(Event::Packet(packet)).is_err() {
if event_sender.send(event).is_err() {
break; break;
} }
} }
@ -245,8 +243,7 @@ fn server_keepalive_thread(event_sender: Sender<Event>, exit_flag: Arc<AtomicBoo
while !exit_flag.load(Ordering::Relaxed) { while !exit_flag.load(Ordering::Relaxed) {
if keepalive.elapsed() >= Duration::from_secs(5) { if keepalive.elapsed() >= Duration::from_secs(5) {
keepalive = Instant::now(); keepalive = Instant::now();
let event = Event::KeepAlive; if event_sender.send(Event::KeepAlive).is_err() {
if event_sender.send(event).is_err() {
break; break;
} }
} else { } else {

View File

@ -1,5 +1,4 @@
use super::{link::Packet, Error}; use super::{link::Packet, Error};
use encoding_rs::EUC_JP;
use std::fmt::Display; use std::fmt::Display;
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
@ -581,9 +580,9 @@ impl From<Setting> for [u32; 2] {
pub enum DataPacket { pub enum DataPacket {
Button, Button,
Debug(DebugPacket), DebugData(DebugPacket),
Disk(DiskPacket), DiskRequest(DiskPacket),
IsViewer64(String), IsViewer64(Vec<u8>),
SaveWriteback(SaveWriteback), SaveWriteback(SaveWriteback),
UpdateStatus(UpdateStatus), UpdateStatus(UpdateStatus),
} }
@ -593,9 +592,9 @@ impl TryFrom<Packet> for DataPacket {
fn try_from(value: Packet) -> Result<Self, Self::Error> { fn try_from(value: Packet) -> Result<Self, Self::Error> {
Ok(match value.id { Ok(match value.id {
b'B' => Self::Button, b'B' => Self::Button,
b'U' => Self::Debug(value.data.try_into()?), b'U' => Self::DebugData(value.data.try_into()?),
b'D' => Self::Disk(value.data.try_into()?), b'D' => Self::DiskRequest(value.data.try_into()?),
b'I' => Self::IsViewer64(EUC_JP.decode(&value.data).0.into()), b'I' => Self::IsViewer64(value.data),
b'S' => Self::SaveWriteback(value.data.try_into()?), b'S' => Self::SaveWriteback(value.data.try_into()?),
b'F' => { b'F' => {
if value.data.len() != 4 { if value.data.len() != 4 {