pub mod packet_type;
pub use packet_type::PacketType;
use std::time::Instant;
use std::fmt;
pub use crate::monitoring::{
RBMoniData,
PBMoniData,
LTBMoniData,
PAMoniData,
MtbMoniData,
CPUMoniData
};
use crate::serialization::{
Serialization,
Packable,
parse_u8,
parse_u16,
parse_u32
};
use crate::errors::{
SerializationError,
};
use crate::events::{
RBEventHeader,
RBEvent,
MasterTriggerEvent,
TofEvent,
RBWaveform,
TofEventSummary,
};
use crate::commands::{
TofCommand,
};
use crate::calibrations::RBCalibrations;
#[cfg(feature = "random")]
use crate::FromRandom;
#[cfg(feature = "random")]
use rand::Rng;
#[derive(Debug, Clone)]
pub struct TofPacket {
pub packet_type : PacketType,
pub payload : Vec<u8>,
pub no_write_to_disk : bool,
pub no_send_over_nw : bool,
pub creation_time : Instant,
pub valid : bool, }
impl fmt::Display for TofPacket {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let p_len = self.payload.len();
if p_len < 4 {
write!(f, "<TofPacket: type {:?}, payload size {}>", self.packet_type, p_len)
} else {
write!(f, "<TofPacket: type {:?}, payload [ {} {} {} {} .. {} {} {} {}] of size {} >",
self.packet_type,
self.payload[0], self.payload[1], self.payload[2], self.payload[3],
self.payload[p_len-4], self.payload[p_len-3], self.payload[p_len - 2], self.payload[p_len-1], p_len )
}
}
}
impl Default for TofPacket {
fn default() -> Self {
Self::new()
}
}
impl PartialEq for TofPacket {
fn eq(&self, other: &Self) -> bool {
(self.packet_type == other.packet_type) &&
(self.payload == other.payload) &&
(self.no_write_to_disk == other.no_write_to_disk) &&
(self.no_send_over_nw == other.no_send_over_nw) &&
(self.valid == other.valid)
}
}
impl TofPacket {
pub fn new() -> Self {
let creation_time = Instant::now();
Self {
packet_type : PacketType::Unknown,
payload : Vec::<u8>::new(),
no_write_to_disk : false,
no_send_over_nw : false,
creation_time : creation_time,
valid : true,
}
}
pub fn zmq_payload_brdcast(&self) -> Vec<u8> {
let mut payload = String::from("BRCT").into_bytes();
let mut stream = self.to_bytestream();
payload.append(&mut stream);
payload
}
pub fn zmq_payload_rb(&self, rb_id : u8) -> Vec<u8> {
let mut payload = format!("RB{:02}", rb_id).into_bytes();
let mut stream = self.to_bytestream();
payload.append(&mut stream);
payload
}
pub fn unpack<T>(&self) -> Result<T, SerializationError>
where T: Packable + Serialization {
if T::PACKET_TYPE != self.packet_type {
error!("This bytestream is not for a {} packet!", self.packet_type);
return Err(SerializationError::IncorrectPacketType);
}
let unpacked : T = T::from_bytestream(&self.payload, &mut 0)?;
Ok(unpacked)
}
pub fn age(&self) -> u64 {
self.creation_time.elapsed().as_secs()
}
}
#[cfg(feature="random")]
impl FromRandom for TofPacket {
fn from_random() -> Self {
let choices = [
PacketType::TofEvent,
PacketType::TofEvent,
PacketType::TofEvent,
PacketType::TofEvent,
PacketType::TofEvent,
PacketType::TofEvent,
PacketType::TofEvent,
PacketType::RBWaveform,
PacketType::RBWaveform,
PacketType::TofEventSummary,
PacketType::TofEventSummary,
PacketType::TofEventSummary,
PacketType::TofEventSummary,
PacketType::TofEventSummary,
PacketType::TofEventSummary,
PacketType::MasterTrigger,
PacketType::MasterTrigger,
PacketType::MasterTrigger,
PacketType::RBMoniData,
PacketType::PBMoniData,
PacketType::LTBMoniData,
PacketType::PAMoniData,
PacketType::CPUMoniData,
PacketType::MonitorMtb,
];
let mut rng = rand::thread_rng();
let idx = rng.gen_range(0..choices.len());
let packet_type = choices[idx];
match packet_type {
PacketType::TofEvent => {
let te = TofEvent::from_random();
return te.pack()
}
PacketType::TofEventSummary => {
let te = TofEventSummary::from_random();
return te.pack()
}
PacketType::RBWaveform => {
let te = RBWaveform::from_random();
return te.pack()
}
PacketType::MasterTrigger => {
let te = MasterTriggerEvent::from_random();
return te.pack()
}
PacketType::RBMoniData => {
let te = RBMoniData::from_random();
return te.pack()
}
PacketType::PAMoniData => {
let te = PAMoniData::from_random();
return te.pack()
}
PacketType::LTBMoniData => {
let te = LTBMoniData::from_random();
return te.pack()
}
PacketType::PBMoniData => {
let te = PBMoniData::from_random();
return te.pack()
}
PacketType::CPUMoniData => {
let te = CPUMoniData::from_random();
return te.pack()
}
PacketType::MonitorMtb => {
let te = MtbMoniData::from_random();
return te.pack()
}
_ => {
let te = TofEvent::from_random();
return te.pack()
}
}
}
}
impl From<&RBWaveform> for TofPacket {
fn from(rbwave : &RBWaveform) -> Self {
let mut tp = Self::new();
tp.packet_type = PacketType::RBWaveform;
tp.payload = rbwave.to_bytestream();
tp
}
}
impl From<&TofEventSummary> for TofPacket {
fn from(tsum : &TofEventSummary) -> Self {
let mut tp = Self::new();
tp.packet_type = PacketType::TofEventSummary;
tp.payload = tsum.to_bytestream();
tp
}
}
impl From<&TofEvent> for TofPacket {
fn from(event : &TofEvent) -> Self {
let mut tp = Self::new();
tp.packet_type = PacketType::TofEvent;
tp.payload = event.to_bytestream();
tp
}
}
impl From<&mut TofEvent> for TofPacket {
fn from(event : &mut TofEvent) -> Self {
let mut tp = Self::new();
tp.packet_type = PacketType::TofEvent;
tp.payload = event.to_bytestream();
tp
}
}
impl From<&TofCommand> for TofPacket {
fn from(cmd : &TofCommand) -> Self {
let mut tp = Self::new();
tp.packet_type = PacketType::TofCommand;
tp.payload = cmd.to_bytestream();
tp
}
}
impl From<&RBCalibrations> for TofPacket {
fn from(calib : &RBCalibrations) -> Self {
let mut tp = Self::new();
tp.packet_type = PacketType::RBCalibration;
tp.payload = calib.to_bytestream();
tp
}
}
impl From<&CPUMoniData> for TofPacket {
fn from(moni : &CPUMoniData) -> Self {
let mut tp = Self::new();
tp.packet_type = PacketType::CPUMoniData;
tp.payload = moni.to_bytestream();
tp
}
}
impl From<&mut RBCalibrations> for TofPacket {
fn from(calib : &mut RBCalibrations) -> Self {
let mut tp = Self::new();
tp.packet_type = PacketType::RBCalibration;
tp.payload = calib.to_bytestream();
tp
}
}
impl From<&RBEvent> for TofPacket {
fn from(event : &RBEvent) -> Self {
let mut tp = Self::new();
tp.packet_type = PacketType::RBEvent;
tp.payload = event.to_bytestream();
tp
}
}
impl From<&MasterTriggerEvent> for TofPacket {
fn from(mt : &MasterTriggerEvent) -> TofPacket {
let mut tp = TofPacket::new();
tp.packet_type = PacketType::MasterTrigger;
tp.payload = mt.to_bytestream();
tp
}
}
impl From<&MtbMoniData> for TofPacket {
fn from(moni : &MtbMoniData) -> TofPacket {
let mut tp = TofPacket::new();
tp.packet_type = PacketType::MonitorMtb;
tp.payload = moni.to_bytestream();
tp
}
}
impl From<&RBEventHeader> for TofPacket {
fn from(ev_header : &RBEventHeader) -> TofPacket {
let mut tp = TofPacket::new();
tp.packet_type = PacketType::RBEventHeader;
tp.payload = ev_header.to_bytestream();
tp
}
}
impl Serialization for TofPacket {
const HEAD : u16 = 0xaaaa;
const TAIL : u16 = 0x5555;
const SIZE : usize = 0; fn from_bytestream(stream : &Vec<u8>, pos : &mut usize)
-> Result<Self, SerializationError> {
if stream.len() < 2 {
return Err(SerializationError::HeadInvalid {});
}
let head = parse_u16(stream, pos);
if Self::HEAD != head {
error!("Packet does not start with HEAD signature");
return Err(SerializationError::HeadInvalid {});
}
let packet_type : PacketType;
let packet_type_enc = parse_u8(stream, pos);
match PacketType::try_from(packet_type_enc) {
Ok(pt) => packet_type = pt,
Err(_) => {
error!("Can not decode packet with packet type {}", packet_type_enc);
return Err(SerializationError::UnknownPayload);}
}
let payload_size = parse_u32(stream, pos);
*pos += payload_size as usize;
let tail = parse_u16(stream, pos);
if Self::TAIL != tail {
error!("Packet does not end with TAIL signature");
return Err(SerializationError::TailInvalid {});
}
*pos -= 2; *pos -= payload_size as usize;
let mut tp = TofPacket::new();
tp.packet_type = packet_type;
tp.payload.extend_from_slice(&stream[*pos..*pos+payload_size as usize]);
Ok(tp)
}
fn to_bytestream(&self)
-> Vec<u8> {
let mut bytestream = Vec::<u8>::with_capacity(6 + self.payload.len());
bytestream.extend_from_slice(&TofPacket::HEAD.to_le_bytes());
let p_type = self.packet_type as u8;
bytestream.push(p_type);
let payload_len = self.payload.len() as u32;
bytestream.extend_from_slice(&payload_len.to_le_bytes());
bytestream.extend_from_slice(self.payload.as_slice());
bytestream.extend_from_slice(&TofPacket::TAIL.to_le_bytes());
bytestream
}
}