gondola_core/tof/
tof_response.rs

1// This file is part of gaps-online-software and published 
2// under the GPLv3 license
3
4use std::fmt;
5use crate::packets::{
6  TofPackable,
7  TofPacketType
8};
9use crate::io::serialization::Serialization;
10use crate::errors::SerializationError;
11use crate::io::parsers::*;
12
13#[cfg(feature="random")]
14use crate::random::FromRandom;
15#[cfg(feature="random")]
16use rand::Rng;
17
18#[cfg(feature="pybindings")]
19use pyo3::prelude::*; 
20
21//use crate::prelude::*;
22
23#[derive(Debug, Copy, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
24#[cfg_attr(feature = "pybindings", pyclass(eq, eq_int))]
25#[repr(u8)]
26pub enum TofReturnCode {
27  Unknown        = 0,
28  GeneralFail    = 1,
29  GarbledCommand = 2,
30  Success        = 200,
31}
32
33impl fmt::Display for TofReturnCode {
34  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
35    let r = serde_json::to_string(self).unwrap_or(
36      String::from("Error: cannot unwrap this TofCommandCode"));
37    write!(f, "<TofReturnCode: {}>", r)
38  }
39}
40
41impl From<u8> for TofReturnCode {
42  fn from(value: u8) -> Self {
43    match value {
44      0   => TofReturnCode::Unknown,
45      1   => TofReturnCode::GeneralFail,
46      2   => TofReturnCode::GarbledCommand,
47      200 => TofReturnCode::Success,
48      _   => {
49        error!("Can not understand {}", value);
50        TofReturnCode::Unknown
51      }
52    }
53  }
54}
55
56#[cfg(feature = "random")]
57impl FromRandom for TofReturnCode {
58  fn from_random() -> Self {
59    let choices = [
60      TofReturnCode::Unknown,
61      TofReturnCode::GarbledCommand,
62      TofReturnCode::Success,
63      TofReturnCode::GeneralFail,
64    ];
65    let mut rng  = rand::rng();
66    let idx = rng.random_range(0..choices.len());
67    choices[idx]
68  }
69}
70
71
72
73/// Each `TofCommand` triggers a `TofResponse` in reply
74///
75/// The responses are general classes, which carry a more
76/// specific 32-bit response code.
77#[derive(Debug, Copy, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
78pub enum TofResponse {
79  Success(u32),
80  /// A unknown problem led to a non-execution
81  /// of the command. The error code should tell
82  /// more. A re-issue of the command might 
83  /// solve the problem.
84  GeneralFail(u32),
85  /// The requested event is not ready yet. This 
86  /// means, it is still lingering in the caches
87  /// of the readout boards. If this problem 
88  /// occurs many times, it might be helpful to 
89  /// reduce the cache size of the readoutboards 
90  /// to be more responsive.
91  /// The response code is the specific event id
92  /// we initially requested.
93  EventNotReady(u32),
94  /// Somehwere, a serialization error happened. 
95  /// It might be worth trying to execute that 
96  /// command again.
97  SerializationIssue(u32),
98  ZMQProblem(u32),
99  TimeOut(u32),
100  NotImplemented(u32),
101  AccessDenied(u32),
102  Unknown
103}
104
105impl TofPackable for TofResponse {
106  const TOF_PACKET_TYPE : TofPacketType = TofPacketType::TofResponse;
107}
108
109impl fmt::Display for TofResponse {
110  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
111    let r = serde_json::to_string(self).unwrap_or(
112      String::from("Error: cannot unwrap this TofResponse"));
113    write!(f, "<TofResponse: {}>", r)
114  }
115}
116
117#[cfg(feature = "random")]
118impl FromRandom for TofResponse {
119  
120  fn from_random() -> Self {
121    let mut rng  = rand::rng();
122    let val = rng.random::<u32>();
123    let choices = [
124      TofResponse::Success(val),
125      TofResponse::GeneralFail(val),
126      TofResponse::EventNotReady(val),
127      TofResponse::SerializationIssue(val),
128      TofResponse::ZMQProblem(val),
129      TofResponse::TimeOut(val),
130      TofResponse::NotImplemented(val),
131      TofResponse::AccessDenied(val),
132      TofResponse::Unknown,
133    ];
134    let idx = rng.random_range(0..choices.len());
135    choices[idx]
136  }
137}
138
139
140impl Serialization for TofResponse {
141  const HEAD : u16   = 0xAAAA;
142  const TAIL : u16   = 0x5555;
143  const SIZE : usize = 9; //FIXME
144  
145  fn to_bytestream(&self) -> Vec<u8> {
146    let mut bytestream = Vec::<u8>::with_capacity(9);
147    bytestream.extend_from_slice(&Self::HEAD.to_le_bytes());
148    let cc = u8::from(*self);
149    bytestream.push(cc);
150    let mut value : u32 = 0;
151    match self {
152      TofResponse::Success(data)            => value = *data,
153      TofResponse::GeneralFail(data)        => value = *data,
154      TofResponse::EventNotReady(data)      => value = *data,
155      TofResponse::SerializationIssue(data) => value = *data,
156      TofResponse::ZMQProblem(data)         => value = *data,
157      TofResponse::TimeOut(data)            => value = *data,
158      TofResponse::NotImplemented(data)     => value = *data,
159      TofResponse::AccessDenied(data)       => value = *data,
160      TofResponse::Unknown => ()
161    }
162    bytestream.extend_from_slice(&value.to_le_bytes());
163    bytestream.extend_from_slice(&TofResponse::TAIL.to_le_bytes());
164    bytestream
165  }
166
167  fn from_bytestream(stream    : &Vec<u8>, 
168                     pos       : &mut usize) 
169    -> Result<TofResponse, SerializationError>{
170    Self::verify_fixed(stream, pos)?;  
171    let cc       = parse_u8(stream, pos);
172    let value    = parse_u32(stream, pos);
173    let pair     = (cc, value);
174    let response = TofResponse::from(pair);
175    *pos += 2; // acccount for TAIL
176    Ok(response)
177  }
178}
179
180impl From<TofResponse> for u8 {
181  fn from(input : TofResponse) -> u8 {
182    match input {
183      TofResponse::Success(_)            => 1,
184      TofResponse::GeneralFail(_)        => 2,
185      TofResponse::EventNotReady(_)      => 3,
186      TofResponse::SerializationIssue(_) => 4,
187      TofResponse::ZMQProblem(_)         => 5,
188      TofResponse::TimeOut(_)            => 6,
189      TofResponse::NotImplemented(_)     => 7,
190      TofResponse::AccessDenied(_)       => 8,
191      TofResponse::Unknown => 0
192    }
193  }
194}
195
196impl From<(u8, u32)> for TofResponse {
197  fn from(pair : (u8, u32)) -> TofResponse {
198    let (input, value) = pair;
199    match input {
200      1 => TofResponse::Success(value),
201      2 => TofResponse::GeneralFail(value),
202      3 => TofResponse::EventNotReady(value),
203      4 => TofResponse::SerializationIssue(value),
204      5 => TofResponse::ZMQProblem(value),
205      6 => TofResponse::TimeOut(value),
206      7 => TofResponse::NotImplemented(value),
207      8 => TofResponse::AccessDenied(value),
208      _ => TofResponse::Unknown
209    }
210  }
211}
212
213#[cfg(feature = "random")]
214#[test]
215fn pack_tofresponse() {
216  let resp = TofResponse::from_random();
217  let test : TofResponse = resp.pack().unpack().unwrap();
218  assert_eq!(resp, test);
219}
220