1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
use std:: {
string::String,
io:: {
Result, Error, ErrorKind
},
collections::HashMap
};
/// This function is called once all command line a
/// rguments have been successfully parsed, and tries
/// to establish a TCP connection against a front-end
/// if configured by command line parameters.
pub fn app(arg_hash: HashMap<String, String>) -> Result<()> {
use cmdline;
let addr = arg_hash.get(&String::from(cmdline::TCP_ARG));
if let Some(addr) = addr {
setup_tcp(addr)?
}
// Since this should never return None, always unwrap() it.
let port_name = arg_hash.get(&String::from(cmdline::PORT_NAME_ARG)).unwrap();
// Extract baud rate from command line parameters,
// but don't process it yet.
let baud_rate = arg_hash.get(&String::from(cmdline::BAUDRATE_ARG));
// Extract folder where CD-ROM file system is mounted.
let folder = arg_hash.get(&String::from(cmdline::CDIMG_FOLDER)).expect("Invalid given folder");
serial_comm(addr, port_name, baud_rate, folder)?;
Ok(())
}
fn setup_tcp(tcp_addr : &String) -> Result<()> {
use std::net::{TcpListener};
let listener = TcpListener::bind(tcp_addr)?;
println!("Awaiting for connection on address {}", tcp_addr);
//~ for stream in listener.incoming() {
//~ match stream {
//~ Ok(s) => {
//~ // do something with the TcpStream
//~ }
//~ Err(ref e) if e.kind() == ErrorKind::WouldBlock => {
//~ // wait until network socket is ready, typically implemented
//~ // via platform-specific APIs such as epoll or IOCP
//~ continue;
//~ }
//~ Err(e) => panic!("encountered IO error: {}", e),
//~ }
//~ }
Ok(())
}
fn serial_comm(addr : Option<&String>, port_name : &String, baud_rate : Option<&String>, folder : &String) -> Result<()> {
use transfer;
use transfer::TransferState;
let mut port = serial_init(addr, port_name, baud_rate).unwrap();
let mut state = TransferState::FirstContact;
let mut prev_state = state;
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 {
TransferState::FirstContact => transfer::first_contact(&mut port),
TransferState::WaitAck => {
state = transfer::wait_ack_default(&mut port, prev_state);
prev_state = state;
state
},
TransferState::SendHeader => transfer::send_header(&mut port, &exe_data),
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 => {
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,
&mut requested_file,
&mut file_data,
&mut file_size),
TransferState::Finished => break
};
}
Ok(())
}
/// This function initializes a serial device.
/// Command line parameters are extracted and parsed here.
fn serial_init(addr : Option<&String>, port_name : &String, baud_rate : Option<&String>) -> Result<serial::SystemPort> {
use serial::SerialPort;
// Try to open the serial device. If opened,
// a SystemPort instance will be returned.
let port = serial::open(port_name);
let baud = match baud_rate {
// Assign default baud rate if no
// option was specified.
None => serial::Baud115200,
Some(b) => {
match b.parse() {
// Parse user-specific baud rate.
Ok(s) => serial::BaudRate::from_speed(s),
// Could not parse input baud rate.
Err(_) => return Err(Error::new(ErrorKind::Other, "Invalid baudrate")),
}
}
};
match port {
Err(_) => {
Err(Error::new(ErrorKind::NotFound, "Could not open serial device"))
},
Ok(mut p) => {
let settings =
serial::PortSettings {
baud_rate: baud,
char_size: serial::Bits8,
parity: serial::ParityNone,
stop_bits: serial::Stop1,
flow_control: serial::FlowNone
};
p.configure(&settings)?;
// Return SystemPort instance if successful.
Ok(p)
}
}
}
|