Skip to content

Commit

Permalink
Removed a couple TODOs that were actually already complete.
Browse files Browse the repository at this point in the history
  • Loading branch information
liamhays committed Aug 15, 2022
1 parent e9b0214 commit ee46ff6
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 36 deletions.
66 changes: 36 additions & 30 deletions src/kermit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,14 @@ fn make_generic_packet(seq: &mut u32, ptype: char) -> Vec<u8> {
// do with how we read the packet (3 bytes then rest of packet).
fn read_packet(port: &mut Box<dyn serialport::SerialPort>) -> Result<KermitPacket, String> {
// have to sleep, probably because the calculator is slow
std::thread::sleep(std::time::Duration::from_millis(300));
std::thread::sleep(std::time::Duration::from_millis(400));
// it seems we have to read 3 bytes, then the rest of the packet
let mut header: [u8; 3] = [0; 3];
match port.read(header.as_mut_slice()) {
Ok(_) => {},
Err(e) => return Err("failed to read header of packet: ".to_owned() + &e.to_string()),
}

//println!("header is {:x?}", header);
if header[0] != SOH {
return Err("malformed Kermit packet (SOH missing)".to_owned());
}
Expand All @@ -174,12 +174,12 @@ fn read_packet(port: &mut Box<dyn serialport::SerialPort>) -> Result<KermitPacke
let len = unchar(header[1]);
// this would be len - 1, but we want to also read the CR at the end of the packet.
let mut rest_of_packet = vec![0 as u8; len as usize];

match port.read(rest_of_packet.as_mut_slice()) {
Ok(_) => {},
Err(e) => return Err("failed to read packet data: ".to_owned() + &e.to_string()),
}

//println!("rest of packet is {:x?}", rest_of_packet);
// subtract 2 to drop 0x0d and check field, to isolate just data
// portion and assemble KermitPacket struct.
let data_field = rest_of_packet[1..(len as usize - 2)].to_vec();
Expand Down Expand Up @@ -210,7 +210,7 @@ fn send_packet(p: KermitPacket, bar: &ProgressBar, port: &mut Box<dyn serialport
Ok(_) => {},
Err(e) => {
bar.abandon();
crate::helpers::error_handler(format!("Error: failed to write data packet: {:?}", e));
crate::helpers::error_handler(format!("Error: failed to write data packet: {}", e));
},
}
match read_packet(port) {
Expand All @@ -223,7 +223,7 @@ fn send_packet(p: KermitPacket, bar: &ProgressBar, port: &mut Box<dyn serialport
},
Err(e) => {
bar.abandon();
crate::helpers::error_handler(format!("Error: bad \"D\" packet response: {:?}.", e));
crate::helpers::error_handler(format!("Error: bad \"D\" packet response: {}.", e));
},
}
}
Expand Down Expand Up @@ -286,6 +286,29 @@ fn make_packet_list(f: Vec<u8>, seq: &mut u32) -> Vec<KermitPacket> {
return packet_list;
}

fn finish_server(port: &mut Box<dyn serialport::SerialPort>) {
// "I" packet is identical to "S" except for the packet type.

// seq can and probably should be 0, and Rust lets you do `&mut 0`
// legally. Funky, for sure.
let i_packet = make_init_packet(&mut 0, 'I');
match port.write(&i_packet) {
Ok(_) => {},
Err(e) => crate::helpers::error_handler(format!("Error: failed to write \"I\" packet: {}", e)),
}
// could wait for ack but probably don't need to.
std::thread::sleep(std::time::Duration::from_millis(300));

// we are sending a 'G' packet with 'F' in the data field,
// which tells the server to finish.
// we use 0 as the seq number even though the I packet was also 0.
let f_packet = vec![SOH, 0x24, tochar(0), 'G' as u8, 'F' as u8, 0x34, CR]; // hardcoded CRC
match port.write(&f_packet) {
Ok(_) => {},
Err(e) => crate::helpers::error_handler(format!("Error: failed to write \"GF\" packet: {}", e)),
}
}

// TODO: this is pretty unreliable and doesn't work with x48 at full
// speed. It has to do with the read_packet() function.

Expand All @@ -300,29 +323,29 @@ pub fn send_file(path: &PathBuf, port: &mut Box<dyn serialport::SerialPort>, fin
let s_packet = make_init_packet(&mut seq, 'S');
match port.write(&s_packet) {
Ok(_) => {},
Err(e) => crate::helpers::error_handler(format!("Error: failed to write \"S\" packet: {:?}", e)),
Err(e) => crate::helpers::error_handler(format!("Error: failed to write \"S\" packet: {}", e)),
}
match read_packet(port) {
Ok(packet) => {
if packet.ptype != 'Y' as u8 {
crate::helpers::error_handler("Error: no ACK for \"S\" packet. Try sending again.".to_string());
}
},
Err(e) => crate::helpers::error_handler(format!("Error: bad \"S\" packet response: {:?}.", e)),
Err(e) => crate::helpers::error_handler(format!("Error: bad \"S\" packet response: {}.", e)),
}

let f_packet = make_f_packet(&mut seq, path.file_name().unwrap());
match port.write(&f_packet) {
Ok(_) => {},
Err(e) => crate::helpers::error_handler(format!("Error: failed to write \"F\" packet: {:?}", e)),
Err(e) => crate::helpers::error_handler(format!("Error: failed to write \"F\" packet: {}", e)),
}
match read_packet(port) {
Ok(packet) => {
if packet.ptype != 'Y' as u8 {
crate::helpers::error_handler("Error: no ACK for \"F\" packet. Try sending again.".to_string());
}
},
Err(e) => crate::helpers::error_handler(format!("Error: bad \"F\" packet response: {:?}", e)),
Err(e) => crate::helpers::error_handler(format!("Error: bad \"F\" packet response: {}", e)),
}

let packet_list = make_packet_list(file_contents, &mut seq);
Expand All @@ -340,7 +363,7 @@ pub fn send_file(path: &PathBuf, port: &mut Box<dyn serialport::SerialPort>, fin
// abondon() leaves the progress bar in place, finish() clears it.
bar.abandon();
crate::helpers::error_handler(
format!("Error: failed to write \"Z\" (end-of-file) packet: {:?}", e));
format!("Error: failed to write \"Z\" (end-of-file) packet: {}", e));
},
}

Expand All @@ -353,29 +376,12 @@ pub fn send_file(path: &PathBuf, port: &mut Box<dyn serialport::SerialPort>, fin
Err(e) => {
bar.abandon();
crate::helpers::error_handler(
format!("Error: failed to write \"B\" (end-of-transmission) packet: {:?}", e));
format!("Error: failed to write \"B\" (end-of-transmission) packet: {}", e));
},
}
bar.finish();

if finish {
// "I" packet is identical to "S" except for the packet type.
let i_packet = make_init_packet(&mut seq, 'I');
match port.write(&i_packet) {
Ok(_) => {},
Err(e) => crate::helpers::error_handler(format!("Error: failed to write \"I\" packet: {:?}", e)),
}
// could wait for ack but probably don't need to.
std::thread::sleep(std::time::Duration::from_millis(300));
// note: sending the I packet resets the seq number.

// we are sending a 'G' packet with 'F' in the data field,
// which tells the server to finish.
let f_packet = vec![SOH, 0x24, tochar(0), 'G' as u8, 'F' as u8, 0x34, CR]; // hardcoded CRC
match port.write(&f_packet) {
Ok(_) => {},
Err(e) => crate::helpers::error_handler(format!("Error: failed to write \"GF\" packet: {:?}", e)),
}

finish_server(port);
}
}
9 changes: 4 additions & 5 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,14 @@ enum Commands {
}


// TODO: this needs to find USB serial ports, because other ports
// might be present. On Windows, I think they're generated by Intel ME
// or other hardware.
fn get_serial_port(cli_port: Option<PathBuf>, cli_baud: Option<u32>) -> Box<dyn serialport::SerialPort> {
let discovered_ports = serialport::available_ports().expect("No ports found!");

let mut usb_serial_ports: Vec<serialport::SerialPortInfo> = Vec::new();

// Sort through the ports and find only USB serial ports.
// Sort through the ports and find only USB serial
// ports. Sometimes other ports are present, and it's quite
// unlikely that they would be for the calculator
for p in &discovered_ports {
match p.port_type {
serialport::SerialPortType::UsbPort(..) => {
Expand Down Expand Up @@ -172,7 +171,7 @@ fn main() {
// send file directly to XRECV
if cli.finish {
println!("{}: {}{}{}",
style("warning").on_yellow().bold(),
style("warning").yellow().bright(),
"ignoring flag ", style("-f").green(),
" (finish) used in XModem direct mode");
}
Expand Down
1 change: 0 additions & 1 deletion src/xmodem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,6 @@ pub fn get_file(path: &PathBuf, port: &mut Box<dyn serialport::SerialPort>, dire
}

let pb = crate::helpers::get_spinner(
// TODO: this should say the actual file being written to
format!("Receiving {} as {} on {}...",
style(original_fname).yellow().bright(),
style(final_fname).yellow().bright(),
Expand Down

0 comments on commit ee46ff6

Please sign in to comment.