diff --git a/src/runtime/src/comms.rs b/src/runtime/src/comms.rs index 8b482146..dc844e38 100644 --- a/src/runtime/src/comms.rs +++ b/src/runtime/src/comms.rs @@ -384,7 +384,7 @@ pub fn main(timer: GlobalTimer, cfg: &Config) { Sockets::init(32); - mgmt::start(); + mgmt::start(*cfg); analyzer::start(); moninj::start(timer); diff --git a/src/runtime/src/mgmt.rs b/src/runtime/src/mgmt.rs index 8af35b0e..f1aa8604 100644 --- a/src/runtime/src/mgmt.rs +++ b/src/runtime/src/mgmt.rs @@ -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 { @@ -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>) -> Result<()> { +async fn get_config_bytes<'a>(stream: &mut TcpStream) -> Result> { + let len :i32 = read_i32(stream).await.unwrap(); + let mut buffer: Vec = 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 { + Ok(String::from_utf8(get_config_bytes(stream).await?).unwrap()) +} + +async fn handle_connection(stream: &mut TcpStream, pull_id: Rc>, 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>) -> } write_i8(stream, Reply::Success as i8).await?; } + + Request::ConfigRead => { + let key: &str = &*(get_config_key(stream).await.unwrap()); + + let data: Vec = 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 = 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;