artiq/artiq/firmware/libproto_artiq/moninj_proto.rs

97 lines
2.8 KiB
Rust

use io::{Read, ProtoRead, Write, ProtoWrite, Error as IoError};
#[derive(Fail, Debug)]
pub enum Error<T> {
#[fail(display = "incorrect magic")]
WrongMagic,
#[fail(display = "unknown packet {:#02x}", _0)]
UnknownPacket(u8),
#[fail(display = "{}", _0)]
Io(#[cause] IoError<T>)
}
impl<T> From<IoError<T>> for Error<T> {
fn from(value: IoError<T>) -> Error<T> {
Error::Io(value)
}
}
pub fn read_magic<R>(reader: &mut R) -> Result<(), Error<R::ReadError>>
where R: Read + ?Sized
{
const MAGIC: &'static [u8] = b"ARTIQ moninj\n";
let mut magic: [u8; 13] = [0; 13];
reader.read_exact(&mut magic)?;
if magic != MAGIC {
Err(Error::WrongMagic)
} else {
Ok(())
}
}
#[derive(Debug)]
pub enum HostMessage {
MonitorProbe { enable: bool, channel: u32, probe: u8 },
MonitorInjection { enable: bool, channel: u32, overrd: u8 },
Inject { channel: u32, overrd: u8, value: u8 },
GetInjectionStatus { channel: u32, overrd: u8 }
}
#[derive(Debug)]
pub enum DeviceMessage {
MonitorStatus { channel: u32, probe: u8, value: u64 },
InjectionStatus { channel: u32, overrd: u8, value: u8 }
}
impl HostMessage {
pub fn read_from<R>(reader: &mut R) -> Result<Self, Error<R::ReadError>>
where R: Read + ?Sized
{
Ok(match reader.read_u8()? {
0 => HostMessage::MonitorProbe {
enable: if reader.read_u8()? == 0 { false } else { true },
channel: reader.read_u32()?,
probe: reader.read_u8()?
},
1 => HostMessage::Inject {
channel: reader.read_u32()?,
overrd: reader.read_u8()?,
value: reader.read_u8()?
},
2 => HostMessage::GetInjectionStatus {
channel: reader.read_u32()?,
overrd: reader.read_u8()?
},
3 => HostMessage::MonitorInjection {
enable: if reader.read_u8()? == 0 { false } else { true },
channel: reader.read_u32()?,
overrd: reader.read_u8()?
},
ty => return Err(Error::UnknownPacket(ty))
})
}
}
impl DeviceMessage {
pub fn write_to<W>(&self, writer: &mut W) -> Result<(), IoError<W::WriteError>>
where W: Write + ?Sized
{
match *self {
DeviceMessage::MonitorStatus { channel, probe, value } => {
writer.write_u8(0)?;
writer.write_u32(channel)?;
writer.write_u8(probe)?;
writer.write_u64(value)?;
},
DeviceMessage::InjectionStatus { channel, overrd, value } => {
writer.write_u8(1)?;
writer.write_u32(channel)?;
writer.write_u8(overrd)?;
writer.write_u8(value)?;
}
}
Ok(())
}
}