1pub mod factory;
9pub mod config;
10
11use std::fmt;
12
13#[cfg(feature = "pybindings")]
14use pyo3::pyclass;
15
16use crate::serialization::{
17 Serialization,
18 Packable,
19 SerializationError,
20 parse_u8,
21 parse_u16,
22 parse_u32
23};
24
25use crate::packets::{
26 TofPacket,
27 PacketType
28};
29
30cfg_if::cfg_if! {
31 if #[cfg(feature = "random")] {
32 use crate::FromRandom;
33 extern crate rand;
34 use rand::Rng;
35 }
36}
37
38pub use factory::*;
39
40#[derive(Debug, Copy, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
41#[cfg_attr(feature = "pybindings", pyclass(eq, eq_int))]
42#[repr(u8)]
43pub enum TofReturnCode {
44 Unknown = 0,
45 GeneralFail = 1,
46 GarbledCommand = 2,
47 Success = 200,
48}
49
50impl fmt::Display for TofReturnCode {
51 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
52 let r = serde_json::to_string(self).unwrap_or(
53 String::from("Error: cannot unwrap this TofCommandCode"));
54 write!(f, "<TofReturnCode: {}>", r)
55 }
56}
57
58impl From<u8> for TofReturnCode {
59 fn from(value: u8) -> Self {
60 match value {
61 0 => TofReturnCode::Unknown,
62 1 => TofReturnCode::GeneralFail,
63 2 => TofReturnCode::GarbledCommand,
64 200 => TofReturnCode::Success,
65 _ => {
66 error!("Can not understand {}", value);
67 TofReturnCode::Unknown
68 }
69 }
70 }
71}
72
73#[cfg(feature = "random")]
74impl FromRandom for TofReturnCode {
75 fn from_random() -> Self {
76 let choices = [
77 TofReturnCode::Unknown,
78 TofReturnCode::GarbledCommand,
79 TofReturnCode::Success,
80 TofReturnCode::GeneralFail,
81 ];
82 let mut rng = rand::thread_rng();
83 let idx = rng.gen_range(0..choices.len());
84 choices[idx]
85 }
86}
87
88#[derive(Debug, Copy, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
89#[cfg_attr(feature = "pybindings", pyclass(eq, eq_int))]
90#[repr(u8)]
91pub enum TofCommandCode {
92 Unknown = 0u8,
93 Ping = 1u8,
95 Moni = 2u8,
97 Kill = 4u8, ResetConfigWDefault = 5u8,
101 SubmitConfig = 6u8,
103 SetDataPublisherConfig = 20u8,
105 SetLTBThresholds = 21u8,
107 SetMTConfig = 22u8,
109 SetTofRunConfig = 23u8,
111 SetTofRBConfig = 24u8,
113 SetAnalysisEngineConfig = 27u8,
115 SetPreampBias = 28u8,
117 SetTOFEventBuilderConfig = 29u8,
119 DataRunStop = 30u8,
121 DataRunStart = 31u8,
123 StartValidationRun = 32u8,
125 GetFullWaveforms = 41u8,
127 UnspoolEventCache = 44u8,
129 RBCalibration = 53u8,
131 RestartLiftofRBClients = 60u8,
133 Listen = 70u8,
135 Staging = 71u8,
137 Lock = 80u8,
139 Unlock = 81u8,
141 SendTofEvents = 90u8,
143 NoSendTofEvents = 91u8,
145 SendRBWaveforms = 92u8,
147 NoSendRBWaveforms = 93u8,
149 SetRBChannelMask = 99u8,
151 ShutdownRB = 100u8,
153 ChangeNextRunConfig = 101u8,
155 ShutdownRAT = 102u8,
157 ShutdownRATPair = 103u8,
160 ShutdownCPU = 104u8,
162 UploadConfig = 105u8,
164}
165
166impl fmt::Display for TofCommandCode {
167 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
168 let r = serde_json::to_string(self).unwrap_or(
169 String::from("Error: cannot unwrap this TofCommandCode"));
170 write!(f, "<TofCommandCode: {}>", r)
171 }
172}
173
174impl From<u8> for TofCommandCode {
175 fn from(value: u8) -> Self {
176 match value {
177 0 => TofCommandCode::Unknown,
178 1 => TofCommandCode::Ping,
179 2 => TofCommandCode::Moni,
180 4 => TofCommandCode::Kill,
181 5 => TofCommandCode::ResetConfigWDefault,
182 6 => TofCommandCode::SubmitConfig,
183 20 => TofCommandCode::SetDataPublisherConfig,
184 21 => TofCommandCode::SetLTBThresholds,
185 22 => TofCommandCode::SetMTConfig,
186 23 => TofCommandCode::SetTofRunConfig,
187 24 => TofCommandCode::SetTofRBConfig,
188 28 => TofCommandCode::SetPreampBias,
189 29 => TofCommandCode::SetTOFEventBuilderConfig,
190 30 => TofCommandCode::DataRunStop,
191 31 => TofCommandCode::DataRunStart,
192 32 => TofCommandCode::StartValidationRun,
193 41 => TofCommandCode::GetFullWaveforms,
194 53 => TofCommandCode::RBCalibration,
195 44 => TofCommandCode::UnspoolEventCache,
196 60 => TofCommandCode::RestartLiftofRBClients,
197 70 => TofCommandCode::Listen,
198 71 => TofCommandCode::Staging,
199 80 => TofCommandCode::Lock,
200 81 => TofCommandCode::Unlock,
201 90 => TofCommandCode::SendTofEvents,
202 91 => TofCommandCode::NoSendTofEvents,
203 92 => TofCommandCode::SendRBWaveforms,
204 93 => TofCommandCode::NoSendRBWaveforms,
205 100 => TofCommandCode::ShutdownRB,
206 101 => TofCommandCode::ChangeNextRunConfig,
207 102 => TofCommandCode::ShutdownRAT,
208 103 => TofCommandCode::ShutdownRATPair,
209 104 => TofCommandCode::ShutdownCPU,
210 105 => TofCommandCode::UploadConfig,
211 _ => TofCommandCode::Unknown
212 }
213 }
214}
215
216#[cfg(feature = "random")]
217impl FromRandom for TofCommandCode {
218 fn from_random() -> Self {
219 let choices = [
220 TofCommandCode::Unknown,
221 TofCommandCode::Ping,
222 TofCommandCode::Moni,
223 TofCommandCode::ResetConfigWDefault,
224 TofCommandCode::SubmitConfig,
225 TofCommandCode::SetDataPublisherConfig,
226 TofCommandCode::SetLTBThresholds,
227 TofCommandCode::SetMTConfig,
228 TofCommandCode::SetTofRunConfig,
229 TofCommandCode::SetTofRBConfig,
230 TofCommandCode::SetTOFEventBuilderConfig,
231 TofCommandCode::SetPreampBias,
232 TofCommandCode::DataRunStop,
233 TofCommandCode::DataRunStart,
234 TofCommandCode::StartValidationRun,
235 TofCommandCode::GetFullWaveforms,
236 TofCommandCode::RBCalibration,
237 TofCommandCode::UnspoolEventCache,
238 TofCommandCode::RestartLiftofRBClients,
239 TofCommandCode::Listen,
240 TofCommandCode::Staging,
241 TofCommandCode::Lock,
242 TofCommandCode::Unlock,
243 TofCommandCode::SendTofEvents,
244 TofCommandCode::NoSendTofEvents,
245 TofCommandCode::SendRBWaveforms,
246 TofCommandCode::NoSendRBWaveforms,
247 TofCommandCode::Kill,
248 TofCommandCode::ShutdownRB,
249 TofCommandCode::ChangeNextRunConfig,
250 TofCommandCode::ShutdownRAT,
251 TofCommandCode::ShutdownRATPair,
252 TofCommandCode::ShutdownCPU,
253 TofCommandCode::UploadConfig,
254 ];
255 let mut rng = rand::thread_rng();
256 let idx = rng.gen_range(0..choices.len());
257 choices[idx]
258 }
259}
260
261#[derive(Debug, Clone, PartialEq)]
272pub struct TofCommandV2 {
273 pub command_code : TofCommandCode,
274 pub payload : Vec<u8>,
275}
276
277impl TofCommandV2 {
278 pub fn new() -> Self {
280 Self {
281 command_code : TofCommandCode::Unknown,
282 payload : Vec::<u8>::new(),
283 }
284 }
285
286 pub fn forge_changerunconfig(key_value : &Vec<String>) -> Self {
300 let mut cmd = TofCommandV2::new();
301 cmd.command_code = TofCommandCode::ChangeNextRunConfig;
302 if key_value.len() == 0 {
303 error!("Empty command!");
304 return cmd;
305 }
306 let mut payload_string = String::from("");
307 for k in 0..key_value.len() - 1 {
308 payload_string += &format!("{}::", key_value[k]);
309 }
310 payload_string += key_value.last().unwrap();
311 let mut payload = Vec::<u8>::new();
312 payload.extend_from_slice(payload_string.as_bytes());
313 cmd.payload = payload;
314 cmd
315 }
316
317 pub fn extract_changerunconfig(&self) -> Option<Vec<String>> {
320 if self.command_code != TofCommandCode::ChangeNextRunConfig {
321 error!("Unable to extract configuration file changes from {}", self);
322 return None;
323 }
324 let mut liftof_config = Vec::<String>::new();
325 match String::from_utf8(self.payload.clone()) {
326 Err(err) => {
327 error!("Unable to extract the String payload! {err}");
328 }
329 Ok(concat_string) => {
330 let foo = concat_string.split("::").collect::<Vec<&str>>().into_iter();
331 for k in foo {
332 liftof_config.push(String::from(k));
333 }
334 }
335 }
336 Some(liftof_config)
337 }
338}
339
340impl Packable for TofCommandV2 {
341 const PACKET_TYPE : PacketType = PacketType::TofCommandV2;
342}
343
344impl Serialization for TofCommandV2 {
345
346 const HEAD : u16 = 0xAAAA;
347 const TAIL : u16 = 0x5555;
348
349 fn from_bytestream(stream : &Vec<u8>,
350 pos : &mut usize)
351 -> Result<Self, SerializationError>{
352 let mut command = TofCommandV2::new();
353 if parse_u16(stream, pos) != Self::HEAD {
354 error!("The given position {} does not point to a valid header signature of {}", pos, Self::HEAD);
355 return Err(SerializationError::HeadInvalid {});
356 }
357 command.command_code = TofCommandCode::from(parse_u8(stream, pos));
358 let payload_size = parse_u8(stream, pos);
359 let payload = stream[*pos..*pos + payload_size as usize].to_vec();
360 command.payload = payload;
361 *pos += payload_size as usize;
362 let tail = parse_u16(stream, pos);
363 if tail != Self::TAIL {
364 error!("After parsing the event, we found an invalid tail signature {}", tail);
365 return Err(SerializationError::TailInvalid);
366 }
367 Ok(command)
368 }
369
370 fn to_bytestream(&self) -> Vec<u8> {
371 let mut stream = Vec::<u8>::with_capacity(9);
372 stream.extend_from_slice(&Self::HEAD.to_le_bytes());
373 stream.push(self.command_code as u8);
374 stream.push(self.payload.len() as u8);
375 stream.extend_from_slice(self.payload.as_slice());
376 stream.extend_from_slice(&Self::TAIL.to_le_bytes());
377 stream
378 }
379}
380
381impl Default for TofCommandV2 {
382 fn default() -> Self {
383 Self::new()
384 }
385}
386
387#[cfg(feature = "random")]
388impl FromRandom for TofCommandV2 {
389 fn from_random() -> Self {
390 let mut rng = rand::thread_rng();
391 let command_code = TofCommandCode::from_random();
392 let payload_size = rng.gen::<u8>();
393 let mut payload = Vec::<u8>::with_capacity(payload_size as usize);
394 for _ in 0..payload_size {
395 payload.push(rng.gen::<u8>());
396 }
397 Self {
398 command_code : command_code,
399 payload : payload
400 }
401 }
402}
403
404impl fmt::Display for TofCommandV2 {
405 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
406 let mut repr = String::from("<TofCommandV2");
408 repr += &(format!("\n cmd code : {}", self.command_code));
409 match self.command_code {
410 TofCommandCode::ShutdownRB
411 | TofCommandCode::ShutdownRAT
412 | TofCommandCode::ShutdownRATPair => {
413 repr += &(format!("\n Sending shutdown command to RBs {:?}>", self.payload));
414 }
415 _ => {
416 repr += ">";
417 }
418 }
419 write!(f, "{}", repr)
420 }
421}
422
423#[derive(Debug, Copy, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
428#[repr(u32)]
429pub enum TofResponseCode {
430 Unknown = 0u32,
431 RespErrUnexecutable = 500u32,
433 RespErrAccessDenied = 403u32,
434 RespErrNotImplemented = 404u32,
435 RespErrLevelNoProblem = 4000u32,
440 RespErrLevelMedium = 4010u32,
441 RespErrLevelSevere = 4020u32,
442 RespErrLevelCritical = 4030u32,
445 RespErrLevelMissionCritical = 4040u32,
449 RespErrLevelRunFoolRun = 99999u32,
453 RespSuccFingersCrossed = 200u32,
457 RespErrNoRunActive = 501u32,
459 RespErrRunActive = 502u32,
461 RespErrCmdStuck = 503u32
463}
464
465impl fmt::Display for TofResponseCode {
466 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
467 let r = serde_json::to_string(self).unwrap_or(
468 String::from("Error: cannot unwrap this TofResponseCode"));
469 write!(f, "<TofResponseCode: {}>", r)
470 }
471}
472
473impl From<u32> for TofResponseCode {
474 fn from(value: u32) -> Self {
475 match value {
476 500u32 => TofResponseCode::RespErrUnexecutable,
477 403u32 => TofResponseCode::RespErrAccessDenied,
478 404u32 => TofResponseCode::RespErrNotImplemented,
479 4000u32 => TofResponseCode::RespErrLevelNoProblem,
480 4010u32 => TofResponseCode::RespErrLevelMedium,
481 4020u32 => TofResponseCode::RespErrLevelSevere,
482 4030u32 => TofResponseCode::RespErrLevelCritical,
483 4040u32 => TofResponseCode::RespErrLevelMissionCritical,
484 99999u32 => TofResponseCode::RespErrLevelRunFoolRun,
485 200u32 => TofResponseCode::RespSuccFingersCrossed,
486 501u32 => TofResponseCode::RespErrNoRunActive,
487 502u32 => TofResponseCode::RespErrRunActive,
488 503u32 => TofResponseCode::RespErrCmdStuck,
489 _ => TofResponseCode::Unknown
490 }
491 }
492}
493
494#[cfg(feature = "random")]
495impl FromRandom for TofResponseCode {
496
497 fn from_random() -> Self {
498 let choices = [
499 TofResponseCode::RespErrAccessDenied,
500 TofResponseCode::RespErrUnexecutable,
501 TofResponseCode::RespErrNotImplemented,
502 TofResponseCode::RespErrLevelNoProblem,
503 TofResponseCode::RespErrLevelMedium,
504 TofResponseCode::RespErrLevelSevere,
505 TofResponseCode::RespErrLevelCritical,
506 TofResponseCode::RespErrLevelMissionCritical,
507 TofResponseCode::RespErrLevelRunFoolRun,
508 TofResponseCode::RespSuccFingersCrossed,
509 TofResponseCode::RespErrNoRunActive,
510 TofResponseCode::RespErrRunActive,
511 TofResponseCode::RespErrCmdStuck
512 ];
513 let mut rng = rand::thread_rng();
514 let idx = rng.gen_range(0..choices.len());
515 choices[idx]
516 }
517}
518
519#[derive(Debug, Copy, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
525#[repr(u8)]
526pub enum TofOperationMode {
527 Unknown = 0u8,
528 Default = 1u8,
529 RBHighThroughput = 30u8,
537 RBCalcCRC32 = 40u8,
538 RBWaveform = 50u8,
539}
540
541impl fmt::Display for TofOperationMode {
542 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
543 let r = serde_json::to_string(self).unwrap_or(
544 String::from("Error: cannot unwrap this TofOperationMode"));
545 write!(f, "<TofOperationMode: {}>", r)
546 }
547}
548
549impl From<u8> for TofOperationMode {
550 fn from(value: u8) -> Self {
551 match value {
552 0u8 => TofOperationMode::Unknown,
553 1u8 => TofOperationMode::Default,
554 30u8 => TofOperationMode::RBHighThroughput,
557 40u8 => TofOperationMode::RBCalcCRC32,
558 50u8 => TofOperationMode::RBWaveform,
559 _ => TofOperationMode::Unknown
560 }
561 }
562}
563
564#[cfg(feature = "random")]
565impl FromRandom for TofOperationMode {
566
567 fn from_random() -> Self {
568 let choices = [
569 TofOperationMode::Unknown,
570 TofOperationMode::Default,
571 TofOperationMode::RBHighThroughput,
574 TofOperationMode::RBCalcCRC32,
575 TofOperationMode::RBWaveform,
576 TofOperationMode::Unknown
577 ];
578 let mut rng = rand::thread_rng();
579 let idx = rng.gen_range(0..choices.len());
580 choices[idx]
581 }
582}
583
584#[derive(Debug, PartialEq, Copy, Clone, serde::Deserialize, serde::Serialize)]pub enum TofCommand {
607 Unknown (u32),
608 Ping (u32),
609 Moni (u32),
610 Power (u32),
611 SetThresholds (u32),
612 SetMTConfig (u32),
613 SetPreampBias (u32),
614 DataRunStop (u32),
615 DataRunStart (u32),
616 StartValidationRun (u32),
617 GetFullWaveforms (u32),
618 NoiCalibration (u32),
619 VoltageCalibration (u32),
620 TimingCalibration (u32),
621 DefaultCalibration (u32),
622 UnspoolEventCache (u32),
623 TriggerModeForced (u32),
624 TriggerModeForcedMTB (u32),
625 SystemdReboot (u32),
626 Listen (u32),
627 Lock (u32),
628 Unlock (u32),
629 Kill (u32),
630}
631
632impl Packable for TofCommand {
633 const PACKET_TYPE : PacketType = PacketType::TofCommand;
634}
635
636impl fmt::Display for TofCommand {
637 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
638 let r = serde_json::to_string(self).unwrap_or(
639 String::from("Error: cannot unwrap this TofCommand"));
640 write!(f, "<TofCommand: {}>", r)
641 }
642}
643
644impl TofCommand {
645
646 pub fn get_value(&self) -> u32 {
648 let value : u32;
649 match self {
650 TofCommand::Unknown (data) => { value = *data;},
651 TofCommand::Ping (data) => { value = *data;},
652 TofCommand::Moni (data) => { value = *data;},
653 TofCommand::Power (data) => { value = *data;},
654 TofCommand::SetThresholds (data) => { value = *data;},
655 TofCommand::SetMTConfig (data) => { value = *data;},
656 TofCommand::SetPreampBias (data) => { value = *data;},
657 TofCommand::DataRunStop (data) => { value = *data;},
658 TofCommand::DataRunStart (data) => { value = *data;},
659 TofCommand::StartValidationRun (data) => { value = *data;},
660 TofCommand::GetFullWaveforms (data) => { value = *data;},
661 TofCommand::NoiCalibration (data) => { value = *data;},
662 TofCommand::VoltageCalibration (data) => { value = *data;},
663 TofCommand::TimingCalibration (data) => { value = *data;},
664 TofCommand::DefaultCalibration (data) => { value = *data;},
665 TofCommand::UnspoolEventCache (data) => { value = *data;},
666 TofCommand::TriggerModeForced (data) => { value = *data;},
667 TofCommand::TriggerModeForcedMTB (data) => { value = *data;},
668 TofCommand::SystemdReboot (data) => { value = *data;},
669 TofCommand::Listen (data) => { value = *data;}
670 TofCommand::Kill (data) => { value = *data;}
671 TofCommand::Lock (data) => { value = *data;}
672 TofCommand::Unlock (data) => { value = *data;}
673 }
674 value
675 }
676
677 pub fn from_command_code(cc : TofCommandCode, value : u32) -> TofCommand {
680 match cc {
681 TofCommandCode::Unknown => TofCommand::Unknown (value),
682 TofCommandCode::Ping => TofCommand::Ping (value),
683 TofCommandCode::Moni => TofCommand::Moni (value),
684 TofCommandCode::SetLTBThresholds => TofCommand::SetThresholds (value),
685 TofCommandCode::SetMTConfig => TofCommand::SetMTConfig (value),
686 TofCommandCode::SetPreampBias => TofCommand::SetPreampBias (value),
687 TofCommandCode::DataRunStop => TofCommand::DataRunStop (value),
688 TofCommandCode::DataRunStart => TofCommand::DataRunStart (value),
689 TofCommandCode::StartValidationRun => TofCommand::StartValidationRun (value),
690 TofCommandCode::GetFullWaveforms => TofCommand::GetFullWaveforms (value),
691 TofCommandCode::RBCalibration => TofCommand::DefaultCalibration (value),
692 TofCommandCode::UnspoolEventCache => TofCommand::UnspoolEventCache (value),
693 TofCommandCode::RestartLiftofRBClients => TofCommand::SystemdReboot (value),
694 TofCommandCode::Listen => TofCommand::Listen (value),
695 TofCommandCode::Kill => TofCommand::Kill (value),
696 TofCommandCode::Lock => TofCommand::Lock (value),
697 TofCommandCode::Unlock => TofCommand::Unlock (value),
698 _ => TofCommand::Unknown (value),
699 }
700 }
701
702 pub fn to_command_code(cmd : &TofCommand) -> Option<TofCommandCode> {
704 match cmd {
705 TofCommand::Unknown (_) => Some(TofCommandCode::Unknown),
706 TofCommand::Power (_) => Some(TofCommandCode::Unknown),
707 TofCommand::NoiCalibration (_) => Some(TofCommandCode::Unknown),
708 TofCommand::VoltageCalibration (_) => Some(TofCommandCode::Unknown),
709 TofCommand::TimingCalibration (_) => Some(TofCommandCode::Unknown),
710 TofCommand::TriggerModeForced (_) => Some(TofCommandCode::Unknown),
711 TofCommand::TriggerModeForcedMTB (_) => Some(TofCommandCode::Unknown),
712
713 TofCommand::Ping (_) => Some(TofCommandCode::Ping),
714 TofCommand::Moni (_) => Some(TofCommandCode::Moni),
715 TofCommand::SetThresholds (_) => Some(TofCommandCode::SetLTBThresholds),
716 TofCommand::SetMTConfig (_) => Some(TofCommandCode::SetMTConfig),
717 TofCommand::SetPreampBias (_) => Some(TofCommandCode::SetPreampBias),
718 TofCommand::DataRunStop (_) => Some(TofCommandCode::DataRunStop),
719 TofCommand::DataRunStart (_) => Some(TofCommandCode::DataRunStart),
720 TofCommand::StartValidationRun (_) => Some(TofCommandCode::StartValidationRun),
721 TofCommand::GetFullWaveforms (_) => Some(TofCommandCode::GetFullWaveforms),
722 TofCommand::DefaultCalibration (_) => Some(TofCommandCode::RBCalibration),
723 TofCommand::UnspoolEventCache (_) => Some(TofCommandCode::UnspoolEventCache),
724 TofCommand::SystemdReboot (_) => Some(TofCommandCode::RestartLiftofRBClients),
725 TofCommand::Listen (_) => Some(TofCommandCode::Listen),
726 TofCommand::Kill (_) => Some(TofCommandCode::Kill),
727 TofCommand::Lock (_) => Some(TofCommandCode::Lock),
728 TofCommand::Unlock (_) => Some(TofCommandCode::Unlock),
729 }
730 }
731
732 pub fn from_tof_packet(packet : &TofPacket)
733 -> Option<TofCommand> {
734 match packet.packet_type {
735 PacketType::TofCommand => (),
736 _ => {
737 debug!("Packet doesn't have PacketType::TofCommand");
738 return None;
739 }
740 } let cmd_pk = TofCommand::from_bytestream(&packet.payload, &mut 0);
742 match cmd_pk {
743 Err(err) => {
744 warn!("Could not decode CMD packet, err {:?}", err);
745 return None;
746 }
747 Ok(cmd) => {
748 Some(cmd)
749 }
750 } }
752} impl From<(u8, u32)> for TofCommand {
758
759 fn from(pair : (u8, u32)) -> TofCommand {
764 let (input, value) = pair;
765 trace!("Got in input {:?}", pair);
766 TofCommand::from_command_code(TofCommandCode::try_from(input).unwrap(), value)
767 }
768}
769
770#[cfg(feature = "random")]
771impl FromRandom for TofCommand {
772
773 fn from_random() -> Self {
774 let mut rng = rand::thread_rng();
775 let val = rng.gen::<u32>();
776 let choices = [
777 TofCommand::Unknown (val),
778 TofCommand::Ping (val),
779 TofCommand::Moni (val),
780 TofCommand::Power (val),
781 TofCommand::SetThresholds (val),
782 TofCommand::SetMTConfig (val),
783 TofCommand::SetPreampBias (val),
784 TofCommand::DataRunStop (val),
785 TofCommand::DataRunStart (val),
786 TofCommand::StartValidationRun (val),
787 TofCommand::GetFullWaveforms (val),
788 TofCommand::NoiCalibration (val),
789 TofCommand::VoltageCalibration (val),
790 TofCommand::TimingCalibration (val),
791 TofCommand::DefaultCalibration (val),
792 TofCommand::UnspoolEventCache (val),
793 TofCommand::TriggerModeForced (val),
794 TofCommand::TriggerModeForcedMTB (val),
795 TofCommand::SystemdReboot (val),
796 TofCommand::Listen (val),
797 TofCommand::Kill (val),
798 TofCommand::Lock (val),
799 TofCommand::Unlock (val),
800 ];
801 let idx = rng.gen_range(0..choices.len());
802 choices[idx]
803 }
804}
805
806impl Serialization for TofCommand {
807
808 const HEAD : u16 = 0xAAAA;
809 const TAIL : u16 = 0x5555;
810 const SIZE : usize = 9;
818
819 fn to_bytestream(&self) -> Vec<u8> {
848 let mut stream : Vec::<u8> = vec![0,0,0,0,0,0,0,0,0];
850 stream[0] = 0xAA;
851 stream[1] = 0xAA;
852 stream[2] = TofCommand::to_command_code(&self)
853 .expect("This can't fail, since this is implemented on MYSELF and I am a TofCommand!") as u8;
854 let value_bytes = self.get_value().to_le_bytes();
855
856 for n in 0..4 {
857 stream[3+n] = value_bytes[n];
858 }
859 stream[7] = 0x55;
860 stream[8] = 0x55;
861 stream
862 }
863
864
865 fn from_bytestream(stream : &Vec<u8>,
866 pos : &mut usize)
867 -> Result<Self, SerializationError>{
868 Self::verify_fixed(stream, pos)?;
869 let cc = parse_u8(stream, pos);
870 let value = parse_u32(stream, pos);
871 let pair = (cc, value);
872 let command = Self::from(pair);
873 *pos += 2; Ok(command)
875 }
876}
877
878#[derive(Debug, Copy, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
883pub enum TofResponse {
884 Success(u32),
885 GeneralFail(u32),
890 EventNotReady(u32),
899 SerializationIssue(u32),
903 ZMQProblem(u32),
904 TimeOut(u32),
905 NotImplemented(u32),
906 AccessDenied(u32),
907 Unknown
908}
909
910impl Packable for TofResponse {
911 const PACKET_TYPE : PacketType = PacketType::TofResponse;
912}
913
914impl fmt::Display for TofResponse {
915 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
916 let r = serde_json::to_string(self).unwrap_or(
917 String::from("Error: cannot unwrap this TofResponse"));
918 write!(f, "<TofResponse: {}>", r)
919 }
920}
921
922#[cfg(feature = "random")]
923impl FromRandom for TofResponse {
924
925 fn from_random() -> Self {
926 let mut rng = rand::thread_rng();
927 let val = rng.gen::<u32>();
928 let choices = [
929 TofResponse::Success(val),
930 TofResponse::GeneralFail(val),
931 TofResponse::EventNotReady(val),
932 TofResponse::SerializationIssue(val),
933 TofResponse::ZMQProblem(val),
934 TofResponse::TimeOut(val),
935 TofResponse::NotImplemented(val),
936 TofResponse::AccessDenied(val),
937 TofResponse::Unknown,
938 ];
939 let idx = rng.gen_range(0..choices.len());
940 choices[idx]
941 }
942}
943
944
945impl Serialization for TofResponse {
946 const HEAD : u16 = 0xAAAA;
947 const TAIL : u16 = 0x5555;
948 const SIZE : usize = 9; fn to_bytestream(&self) -> Vec<u8> {
951 let mut bytestream = Vec::<u8>::with_capacity(9);
952 bytestream.extend_from_slice(&Self::HEAD.to_le_bytes());
953 let cc = u8::from(*self);
954 bytestream.push(cc);
955 let mut value : u32 = 0;
956 match self {
957 TofResponse::Success(data) => value = *data,
958 TofResponse::GeneralFail(data) => value = *data,
959 TofResponse::EventNotReady(data) => value = *data,
960 TofResponse::SerializationIssue(data) => value = *data,
961 TofResponse::ZMQProblem(data) => value = *data,
962 TofResponse::TimeOut(data) => value = *data,
963 TofResponse::NotImplemented(data) => value = *data,
964 TofResponse::AccessDenied(data) => value = *data,
965 TofResponse::Unknown => ()
966 }
967 bytestream.extend_from_slice(&value.to_le_bytes());
968 bytestream.extend_from_slice(&TofResponse::TAIL.to_le_bytes());
969 bytestream
970 }
971
972 fn from_bytestream(stream : &Vec<u8>,
973 pos : &mut usize)
974 -> Result<TofResponse, SerializationError>{
975 Self::verify_fixed(stream, pos)?;
976 let cc = parse_u8(stream, pos);
977 let value = parse_u32(stream, pos);
978 let pair = (cc, value);
979 let response = TofResponse::from(pair);
980 *pos += 2; Ok(response)
982 }
983}
984
985impl From<TofResponse> for u8 {
986 fn from(input : TofResponse) -> u8 {
987 match input {
988 TofResponse::Success(_) => 1,
989 TofResponse::GeneralFail(_) => 2,
990 TofResponse::EventNotReady(_) => 3,
991 TofResponse::SerializationIssue(_) => 4,
992 TofResponse::ZMQProblem(_) => 5,
993 TofResponse::TimeOut(_) => 6,
994 TofResponse::NotImplemented(_) => 7,
995 TofResponse::AccessDenied(_) => 8,
996 TofResponse::Unknown => 0
997 }
998 }
999}
1000
1001impl From<(u8, u32)> for TofResponse {
1002 fn from(pair : (u8, u32)) -> TofResponse {
1003 let (input, value) = pair;
1004 match input {
1005 1 => TofResponse::Success(value),
1006 2 => TofResponse::GeneralFail(value),
1007 3 => TofResponse::EventNotReady(value),
1008 4 => TofResponse::SerializationIssue(value),
1009 5 => TofResponse::ZMQProblem(value),
1010 6 => TofResponse::TimeOut(value),
1011 7 => TofResponse::NotImplemented(value),
1012 8 => TofResponse::AccessDenied(value),
1013 _ => TofResponse::Unknown
1014 }
1015 }
1016}
1017
1018#[cfg(feature = "random")]
1019#[test]
1020fn test_tofoperationmode() {
1021 let mut type_codes = Vec::<u8>::new();
1022 type_codes.push(TofOperationMode::Unknown as u8);
1023 type_codes.push(TofOperationMode::Default as u8);
1024 type_codes.push(TofOperationMode::RBHighThroughput as u8);
1025 type_codes.push(TofOperationMode::RBWaveform as u8);
1026 type_codes.push(TofOperationMode::RBCalcCRC32 as u8);
1027 for tc in type_codes.iter() {
1030 assert_eq!(*tc,TofOperationMode::try_from(*tc).unwrap() as u8);
1031 }
1032}
1033
1034#[cfg(feature = "random")]
1035#[test]
1036fn pack_tofresponse() {
1037 let resp = TofResponse::from_random();
1038 let test : TofResponse = resp.pack().unpack().unwrap();
1039 assert_eq!(resp, test);
1040}
1041
1042#[cfg(feature = "random")]
1053#[test]
1054fn pack_tofcommandv2() {
1055 for _ in 0..100 {
1056 let cmd = TofCommandV2::from_random();
1057 let test : TofCommandV2 = cmd.pack().unpack().unwrap();
1058 assert_eq!(cmd, test);
1059 }
1060}
1061
1062#[test]
1063fn forge_and_extract_tofcommandv2() {
1064 let input = vec![String::from("foo"), String::from("bar"), String::from("baz")];
1065 let cmd = TofCommandV2::forge_changerunconfig(&input);
1066 let output = cmd.extract_changerunconfig().unwrap();
1067 assert_eq!(input, output);
1068}