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;
    }
}

/// 创建一个UDP链路实例,并连接到指定地址端口
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);
}