diff options
| author | XaviDCR92 <xavi.dcr@gmail.com> | 2019-01-14 23:44:01 +0100 |
|---|---|---|
| committer | XaviDCR92 <xavi.dcr@gmail.com> | 2019-01-14 23:44:01 +0100 |
| commit | 136d9f5a37d5dfd72e6c1486065de4d96611c523 (patch) | |
| tree | e6ca710c8d9b94346f22ad182c16a2af2cf0c77a | |
| parent | 4d0f0e6021778b2917960bef978fe69c0fe1b327 (diff) | |
Files are finally being sent from a PC.
However, file transmission often gets stucked.
| -rw-r--r-- | src/app.rs | 15 | ||||
| -rw-r--r-- | src/transfer.rs | 105 |
2 files changed, 115 insertions, 5 deletions
@@ -71,6 +71,8 @@ fn serial_comm(addr : Option<&String>, port_name : &String, baud_rate : Option<& let mut sent_bytes = 0 as usize; let mut requested_file = String::new(); let exe_data = transfer::get_exe_data(&folder).unwrap(); + let mut file_data : Vec<u8> = Vec::new(); + let mut file_size : Option<usize> = None; loop { state = match state { @@ -84,8 +86,17 @@ fn serial_comm(addr : Option<&String>, port_name : &String, baud_rate : Option<& TransferState::SendExeSize => transfer::send_exe_size(&mut port, &exe_data), TransferState::CleaningRAM => transfer::wait_ack_default(&mut port, prev_state), TransferState::SendExeData => transfer::send_exe_data(&mut port, &mut sent_bytes, &exe_data), - TransferState::WaitFileRequest => transfer::wait_file_request(&mut port, &mut requested_file), - TransferState::SendFile => transfer::send_file(&mut port, &mut sent_bytes, &requested_file), + TransferState::WaitFileRequest => { + state = transfer::wait_file_request(&mut port, &mut requested_file); + prev_state = state; + state + }, + TransferState::SendFile => transfer::send_file(&mut port, + &folder, + &mut sent_bytes, + &requested_file, + &mut file_data, + &mut file_size), TransferState::Finished => break }; } diff --git a/src/transfer.rs b/src/transfer.rs index 36cd23f..c441fd0 100644 --- a/src/transfer.rs +++ b/src/transfer.rs @@ -60,6 +60,7 @@ pub fn wait_ack_default(port : &mut serial::SystemPort, prev_state: TransferStat TransferState::SendExeSize => TransferState::CleaningRAM, TransferState::CleaningRAM => TransferState::SendExeData, TransferState::SendExeData => TransferState::SendExeData, + TransferState::SendFile => TransferState::SendFile, _ => TransferState::Finished } } @@ -204,9 +205,107 @@ fn get_file_name(buffer : &Vec<u8>, requested_file: &mut String) -> TransferStat } } -pub fn send_file(port : &mut serial::SystemPort, sent_bytes: &mut usize, requested_file: &String) -> TransferState { - println!("Requested file: {}", requested_file); - TransferState::Finished +pub fn send_file(port : &mut serial::SystemPort, + folder: &String, + sent_bytes: &mut usize, + requested_file: &String, + file_data : &mut Vec<u8>, + file_size : &mut Option<usize>) -> TransferState { + use std::fs; + use regex::Regex; + + lazy_static! { + static ref RX: Regex = Regex::new(r"^cdrom:\\(.+);1$").expect("Could not compile regex"); + } + + match *file_size { + None => { + match RX.captures(&requested_file) { + None => { + println!("{} is not a valid file path", requested_file); + TransferState::WaitFileRequest + }, + Some(s) => { + match s.get(1) { + None => { + println!("Internal error"); + TransferState::Finished + }, + Some(s_) => { + let mut path = String::from(s_.as_str()).replace('\\', "/"); + + let absolute_path = format!("{}/{}", folder, path); + + println!("Absolute file path: {}", absolute_path); + + *file_data = fs::read(&absolute_path).unwrap(); + + *file_size = Some(file_data.len()); + + let size = (*file_size).unwrap(); + + println!("File size: {:?} bytes", size); + + let file_size_vec : [u8; 4] = [(size & 0xFF) as u8, + ((size & 0xFF00) >> 8) as u8, + ((size & 0xFF0000) >> 16) as u8, + ((size & 0xFF000000) >> 24) as u8]; + use std::io::Write; + (*port).write(&file_size_vec).expect("Could not write EXE size into the device"); + + return TransferState::WaitAck + } + } + } + } + }, + Some(size) => { + if *sent_bytes < size { + match file_data.get(*sent_bytes..(*sent_bytes + PACKET_SIZE)) { + None => { + match file_data.get(*sent_bytes..size) { + None => TransferState::Finished, + Some(chunk) => { + use std::io::Write; + (*port).write(&chunk).expect("Could not file data chunk into the device"); + + *sent_bytes = size; + + if *sent_bytes % 32 == 0 { + print!("\rSent {:?}/{:?} bytes...", *sent_bytes, size); + } + + TransferState::WaitAck + } + } + } + Some(chunk) => { + use std::io::Write; + (*port).write(&chunk).expect("Could not file data chunk into the device"); + + *sent_bytes += PACKET_SIZE; + + if *sent_bytes % 32 == 0 { + print!("\rSent {:?}/{:?} bytes...", *sent_bytes, size); + } + + TransferState::WaitAck + } + } + } + else + { + println!("{} has been completely sent.", requested_file); + + // Reset information. + *sent_bytes = 0; + *file_size = None; + file_data.clear(); + + TransferState::WaitFileRequest + } + } + } } pub fn get_exe_data(folder: &String) -> Option<Vec<u8>> { |
