summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXaviDCR92 <xavi.dcr@gmail.com>2019-01-14 23:44:01 +0100
committerXaviDCR92 <xavi.dcr@gmail.com>2019-01-14 23:44:01 +0100
commit136d9f5a37d5dfd72e6c1486065de4d96611c523 (patch)
treee6ca710c8d9b94346f22ad182c16a2af2cf0c77a
parent4d0f0e6021778b2917960bef978fe69c0fe1b327 (diff)
Files are finally being sent from a PC.
However, file transmission often gets stucked.
-rw-r--r--src/app.rs15
-rw-r--r--src/transfer.rs105
2 files changed, 115 insertions, 5 deletions
diff --git a/src/app.rs b/src/app.rs
index 4447df2..3cea4ce 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -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>> {