2016-09-27 21:36:55 +08:00
|
|
|
use std::prelude::v1::*;
|
2016-09-29 02:25:25 +08:00
|
|
|
use std::str;
|
|
|
|
use std::io::{self, Read, ErrorKind};
|
2016-09-30 02:54:08 +08:00
|
|
|
use config;
|
2016-09-27 21:36:55 +08:00
|
|
|
use self::protocol::*;
|
|
|
|
|
|
|
|
mod protocol;
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
|
|
enum KernelState {
|
|
|
|
Absent,
|
|
|
|
Loaded,
|
|
|
|
Running,
|
|
|
|
RpcWait
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct Session {
|
|
|
|
kernel_state: KernelState,
|
|
|
|
}
|
|
|
|
|
|
|
|
extern {
|
|
|
|
fn kloader_stop();
|
|
|
|
fn watchdog_init();
|
|
|
|
fn kloader_start_idle_kernel();
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Session {
|
|
|
|
pub fn start() -> Session {
|
|
|
|
unsafe { kloader_stop(); }
|
|
|
|
Session {
|
|
|
|
kernel_state: KernelState::Absent
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn end(self) {
|
|
|
|
unsafe {
|
|
|
|
kloader_stop();
|
|
|
|
watchdog_init();
|
|
|
|
kloader_start_idle_kernel();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn check_magic(stream: &mut ::io::TcpStream) -> io::Result<()> {
|
|
|
|
const MAGIC: &'static [u8] = b"ARTIQ coredev\n";
|
|
|
|
|
|
|
|
let mut magic: [u8; 14] = [0; 14];
|
|
|
|
try!(stream.read_exact(&mut magic));
|
|
|
|
if magic != MAGIC {
|
|
|
|
Err(io::Error::new(io::ErrorKind::InvalidData, "unrecognized magic"))
|
|
|
|
} else {
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-29 02:25:25 +08:00
|
|
|
fn handle_request(stream: &mut ::io::TcpStream,
|
|
|
|
logger: &::buffer_logger::BufferLogger) -> io::Result<()> {
|
2016-09-27 21:36:55 +08:00
|
|
|
fn read_request(stream: &mut ::io::TcpStream) -> io::Result<Request> {
|
|
|
|
let request = try!(Request::read_from(stream));
|
2016-09-29 02:25:25 +08:00
|
|
|
trace!("comm<-host {:?}", request);
|
2016-09-27 21:36:55 +08:00
|
|
|
Ok(request)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn write_reply(stream: &mut ::io::TcpStream, reply: Reply) -> io::Result<()> {
|
2016-09-29 02:25:25 +08:00
|
|
|
trace!("comm->host {:?}", reply);
|
2016-09-27 21:36:55 +08:00
|
|
|
reply.write_to(stream)
|
|
|
|
}
|
|
|
|
|
|
|
|
match try!(read_request(stream)) {
|
2016-09-30 02:54:08 +08:00
|
|
|
Request::Ident =>
|
|
|
|
write_reply(stream, Reply::Ident(::board::ident(&mut [0; 64]))),
|
2016-09-29 02:25:25 +08:00
|
|
|
|
|
|
|
Request::Log => {
|
|
|
|
// Logging the packet with the log is inadvisable
|
|
|
|
trace!("comm->host Log(...)");
|
|
|
|
logger.extract(move |log| {
|
|
|
|
Reply::Log(log).write_to(stream)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
Request::LogClear => {
|
|
|
|
logger.clear();
|
|
|
|
write_reply(stream, Reply::Log(""))
|
|
|
|
}
|
|
|
|
|
2016-09-30 02:54:08 +08:00
|
|
|
Request::FlashRead { ref key } => {
|
|
|
|
let value = config::read_to_end(key);
|
|
|
|
write_reply(stream, Reply::FlashRead(&value))
|
|
|
|
}
|
|
|
|
|
|
|
|
Request::FlashWrite { ref key, ref value } => {
|
|
|
|
match config::write(key, value) {
|
|
|
|
Ok(_) => write_reply(stream, Reply::FlashOk),
|
|
|
|
Err(_) => write_reply(stream, Reply::FlashError)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Request::FlashRemove { ref key } => {
|
|
|
|
config::remove(key);
|
|
|
|
write_reply(stream, Reply::FlashOk)
|
|
|
|
}
|
|
|
|
|
|
|
|
Request::FlashErase => {
|
|
|
|
config::erase();
|
|
|
|
write_reply(stream, Reply::FlashOk)
|
|
|
|
}
|
|
|
|
|
2016-09-27 21:36:55 +08:00
|
|
|
_ => unreachable!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-29 02:25:25 +08:00
|
|
|
fn handle_requests(stream: &mut ::io::TcpStream,
|
|
|
|
logger: &::buffer_logger::BufferLogger) -> io::Result<()> {
|
2016-09-27 21:36:55 +08:00
|
|
|
try!(check_magic(stream));
|
|
|
|
loop {
|
2016-09-29 02:25:25 +08:00
|
|
|
try!(handle_request(stream, logger))
|
2016-09-27 21:36:55 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-29 02:25:25 +08:00
|
|
|
pub fn handler(waiter: ::io::Waiter,
|
|
|
|
logger: &::buffer_logger::BufferLogger) {
|
2016-09-27 21:36:55 +08:00
|
|
|
let addr = ::io::SocketAddr::new(::io::IP_ANY, 1381);
|
|
|
|
let listener = ::io::TcpListener::bind(waiter, addr).unwrap();
|
|
|
|
loop {
|
2016-09-29 02:25:25 +08:00
|
|
|
let (mut stream, addr) = listener.accept().unwrap();
|
|
|
|
info!("new connection from {:?}", addr);
|
|
|
|
|
|
|
|
match handle_requests(&mut stream, logger) {
|
2016-09-27 21:36:55 +08:00
|
|
|
Ok(()) => (),
|
|
|
|
Err(err) => {
|
2016-09-29 02:25:25 +08:00
|
|
|
if err.kind() == ErrorKind::UnexpectedEof {
|
|
|
|
info!("connection closed");
|
|
|
|
} else {
|
|
|
|
error!("cannot handle network request: {:?}", err);
|
|
|
|
}
|
2016-09-27 21:36:55 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|