|
|
|
@ -1,8 +1,9 @@
|
|
|
|
|
use futures::{future::poll_fn, task::Poll};
|
|
|
|
|
use libasync::{smoltcp::TcpStream, task};
|
|
|
|
|
use libboard_zynq::smoltcp;
|
|
|
|
|
use core::cell::RefCell;
|
|
|
|
|
use alloc::rc::Rc;
|
|
|
|
|
use libconfig::Config;
|
|
|
|
|
use core::{cell::RefCell, convert::TryInto};
|
|
|
|
|
use alloc::{vec::Vec, rc::Rc, str, string::String};
|
|
|
|
|
use log::{self, info, warn, LevelFilter};
|
|
|
|
|
|
|
|
|
|
use crate::logger::{BufferLogger, LogBufferRef};
|
|
|
|
@ -44,12 +45,19 @@ pub enum Request {
|
|
|
|
|
PullLog = 7,
|
|
|
|
|
SetLogFilter = 3,
|
|
|
|
|
SetUartLogFilter = 6,
|
|
|
|
|
|
|
|
|
|
ConfigRead = 12,
|
|
|
|
|
ConfigWrite = 13,
|
|
|
|
|
ConfigRemove = 14,
|
|
|
|
|
ConfigErase = 15,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[repr(i8)]
|
|
|
|
|
pub enum Reply {
|
|
|
|
|
Success = 1,
|
|
|
|
|
LogContent = 2,
|
|
|
|
|
|
|
|
|
|
ConfigData = 7,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async fn read_log_level_filter(stream: &mut TcpStream) -> Result<log::LevelFilter> {
|
|
|
|
@ -85,7 +93,18 @@ async fn get_logger_buffer() -> LogBufferRef<'static> {
|
|
|
|
|
get_logger_buffer_pred(|_| true).await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async fn handle_connection(stream: &mut TcpStream, pull_id: Rc<RefCell<u32>>) -> Result<()> {
|
|
|
|
|
async fn get_config_bytes<'a>(stream: &mut TcpStream) -> Result<Vec<u8>> {
|
|
|
|
|
let len :i32 = read_i32(stream).await.unwrap();
|
|
|
|
|
let mut buffer: Vec<u8> = Vec::with_capacity(len.try_into().unwrap());
|
|
|
|
|
|
|
|
|
|
read_chunk(stream, &mut buffer).await;
|
|
|
|
|
return Ok(buffer);
|
|
|
|
|
}
|
|
|
|
|
async fn get_config_key<'a>(stream: &mut TcpStream) -> Result<String> {
|
|
|
|
|
Ok(String::from_utf8(get_config_bytes(stream).await?).unwrap())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async fn handle_connection(stream: &mut TcpStream, pull_id: Rc<RefCell<u32>>, cfg: Config) -> Result<()> {
|
|
|
|
|
if !expect(&stream, b"ARTIQ management\n").await? {
|
|
|
|
|
return Err(Error::UnexpectedPattern);
|
|
|
|
|
}
|
|
|
|
@ -150,11 +169,36 @@ async fn handle_connection(stream: &mut TcpStream, pull_id: Rc<RefCell<u32>>) ->
|
|
|
|
|
}
|
|
|
|
|
write_i8(stream, Reply::Success as i8).await?;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Request::ConfigRead => {
|
|
|
|
|
let key: &str = &*(get_config_key(stream).await.unwrap());
|
|
|
|
|
|
|
|
|
|
let data: Vec<u8> = cfg.read(key).unwrap();
|
|
|
|
|
write_i8(stream, Reply::ConfigData as i8).await?;
|
|
|
|
|
write_chunk(stream, &data).await?;
|
|
|
|
|
}
|
|
|
|
|
Request::ConfigWrite => {
|
|
|
|
|
let key: &str = &*(get_config_key(stream).await.unwrap());
|
|
|
|
|
let value: Vec<u8> = get_config_bytes(stream).await?;
|
|
|
|
|
|
|
|
|
|
cfg.write_str(key, str::from_utf8(&value).unwrap())?;
|
|
|
|
|
write_i8(stream, Reply::Success as i8).await?;
|
|
|
|
|
}
|
|
|
|
|
Request::ConfigRemove => {
|
|
|
|
|
let key: &str = &*(get_config_key(stream).await.unwrap());
|
|
|
|
|
|
|
|
|
|
cfg.remove(key)?;
|
|
|
|
|
write_i8(stream, Reply::Success as i8).await?;
|
|
|
|
|
}
|
|
|
|
|
Request::ConfigErase => {
|
|
|
|
|
cfg.erase()?;
|
|
|
|
|
write_i8(stream, Reply::Success as i8).await?;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn start() {
|
|
|
|
|
pub fn start(cfg: Config) {
|
|
|
|
|
task::spawn(async move {
|
|
|
|
|
let pull_id = Rc::new(RefCell::new(0u32));
|
|
|
|
|
loop {
|
|
|
|
@ -162,7 +206,7 @@ pub fn start() {
|
|
|
|
|
let pull_id = pull_id.clone();
|
|
|
|
|
task::spawn(async move {
|
|
|
|
|
info!("received connection");
|
|
|
|
|
let _ = handle_connection(&mut stream, pull_id)
|
|
|
|
|
let _ = handle_connection(&mut stream, pull_id, cfg)
|
|
|
|
|
.await
|
|
|
|
|
.map_err(|e| warn!("connection terminated: {:?}", e));
|
|
|
|
|
let _ = stream.flush().await;
|
|
|
|
|