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
use eds::consts::FRAME_LEN;
use eds::{Reader, Writer};
use log::*;
use serial;
use serial::prelude::*;
use spin::Mutex;
use std::collections::BTreeMap;
use std::io::{Read, Write};
use std::sync::Arc;
use std::thread;
use std::time::Duration;
use unmp::consts::*;
use unmp::net;
use unmp_link::{Driver, ErrorKind, Link, ResultFuture};
static LINKS: Mutex<BTreeMap<String, Link>> = Mutex::new(BTreeMap::new());
struct SerialDriver {
identifier: String,
serial: Mutex<serial::SystemPort>,
}
unsafe impl Send for SerialDriver {}
unsafe impl Sync for SerialDriver {}
impl Driver for SerialDriver {
fn name(&self) -> &str {
&self.identifier
}
fn send(self: Arc<Self>, buf: &[u8]) -> ResultFuture {
trace!("serial send: {:02X?}.", buf);
let (result_future, sender) = ResultFuture::new();
let buf = VecPacket::from(buf);
let mut writer = Writer::new(4);
match self.serial.lock().write(writer.get_frame(&buf)) {
Ok(_) => {
let _err = sender.send(Ok(()));
}
Err(_) => {
warn!("serial send error.");
let _err = sender.send(Err(ErrorKind::TimedOut));
}
};
return result_future;
}
}
pub fn start(name: &str, speed: usize) -> Result<Link, ()> {
let identifier = format!("{}", name);
if let Some(_) = LINKS.lock().get(&identifier) {
return Err(());
}
let mut port = serial::open(name).unwrap();
port.reconfigure(&|settings| {
settings
.set_baud_rate(serial::BaudRate::from_speed(speed))
.unwrap();
settings.set_char_size(serial::Bits8);
settings.set_parity(serial::ParityNone);
settings.set_stop_bits(serial::Stop1);
settings.set_flow_control(serial::FlowNone);
Ok(())
})
.unwrap();
port.set_timeout(Duration::from_millis(300)).unwrap();
let driver = Arc::new(SerialDriver {
identifier: identifier.clone(),
serial: Mutex::new(port),
});
let link_driver = Arc::downgrade(&driver);
let link = Link::new(link_driver);
info!("serial new {:?}.", link);
LINKS.lock().insert(identifier.clone(), link.clone());
let link_tmp = link.clone();
thread::spawn(move || {
let link = link_tmp;
let mut reader = Reader::new();
let mut buf = [0; FRAME_LEN];
loop {
thread::sleep(Duration::from_millis(10));
match driver.serial.lock().read(&mut buf) {
Ok(len) => {
let buf: &[u8] = &buf[..len];
trace!("serial recv: {:02X?}.", buf);
reader.recv(buf);
if reader.is_ready() {
net::when_recv(&link, reader.get_load());
}
while !reader.is_finish() {
reader.recv(&[]);
if reader.is_ready() {
net::when_recv(&link, reader.get_load());
}
}
}
Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => {}
Err(ref e) if e.kind() == std::io::ErrorKind::TimedOut => {}
Err(ref e) => {
warn!("serial {:?} recv error: {:?}", link, e.kind());
LINKS.lock().remove(&identifier);
link.destroy();
return;
}
}
}
});
return Ok(link);
}