1use crate::pus::{source_buffer_large_enough, EcssTmSenderCore, EcssTmtcError};
78use core::fmt::{Debug, Display, Formatter};
79use core::hash::{Hash, Hasher};
80use core::marker::PhantomData;
81use core::mem::size_of;
82#[cfg(feature = "alloc")]
83use delegate::delegate;
84#[cfg(feature = "serde")]
85use serde::{Deserialize, Serialize};
86use spacepackets::ecss::tc::IsPusTelecommand;
87use spacepackets::ecss::tm::{PusTmCreator, PusTmSecondaryHeader};
88use spacepackets::ecss::{EcssEnumeration, PusError, WritablePusPacket};
89use spacepackets::{CcsdsPacket, PacketId, PacketSequenceCtrl};
90use spacepackets::{SpHeader, MAX_APID};
91
92pub use crate::seq_count::SeqCountProviderSimple;
93pub use spacepackets::ecss::verification::*;
94
95#[cfg(feature = "alloc")]
96pub use alloc_mod::{
97 VerificationReporter, VerificationReporterCfg, VerificationReporterWithSender,
98};
99#[cfg(feature = "std")]
100pub use std_mod::*;
101
102#[derive(Debug, Eq, Copy, Clone)]
108#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
109pub struct RequestId {
110 version_number: u8,
111 packet_id: PacketId,
112 psc: PacketSequenceCtrl,
113}
114
115impl Display for RequestId {
116 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
117 write!(f, "{:#08x}", self.raw())
118 }
119}
120
121impl Hash for RequestId {
122 fn hash<H: Hasher>(&self, state: &mut H) {
123 self.raw().hash(state);
124 }
125}
126
127impl PartialEq for RequestId {
129 fn eq(&self, other: &Self) -> bool {
130 self.version_number == other.version_number
131 && self.packet_id == other.packet_id
132 && self.psc == other.psc
133 }
134}
135
136impl RequestId {
137 pub const SIZE_AS_BYTES: usize = size_of::<u32>();
138
139 pub fn raw(&self) -> u32 {
140 ((self.version_number as u32) << 29)
141 | ((self.packet_id.raw() as u32) << 16)
142 | self.psc.raw() as u32
143 }
144
145 pub fn to_bytes(&self, buf: &mut [u8]) {
146 let raw = self.raw();
147 buf.copy_from_slice(raw.to_be_bytes().as_slice());
148 }
149
150 pub fn from_bytes(buf: &[u8]) -> Option<Self> {
151 if buf.len() < 4 {
152 return None;
153 }
154 let raw = u32::from_be_bytes(buf[0..Self::SIZE_AS_BYTES].try_into().unwrap());
155 Some(Self {
156 version_number: ((raw >> 29) & 0b111) as u8,
157 packet_id: PacketId::from(((raw >> 16) & 0xffff) as u16),
158 psc: PacketSequenceCtrl::from((raw & 0xffff) as u16),
159 })
160 }
161}
162impl RequestId {
163 pub fn new(tc: &(impl CcsdsPacket + IsPusTelecommand)) -> Self {
165 RequestId {
166 version_number: tc.ccsds_version(),
167 packet_id: tc.packet_id(),
168 psc: tc.psc(),
169 }
170 }
171}
172
173#[derive(Debug, Clone)]
176pub struct VerificationOrSendErrorWithToken<T>(pub EcssTmtcError, pub VerificationToken<T>);
177
178#[derive(Debug, Clone)]
179pub struct VerificationErrorWithToken<T>(pub EcssTmtcError, pub VerificationToken<T>);
180
181impl<T> From<VerificationErrorWithToken<T>> for VerificationOrSendErrorWithToken<T> {
182 fn from(value: VerificationErrorWithToken<T>) -> Self {
183 VerificationOrSendErrorWithToken(value.0, value.1)
184 }
185}
186#[derive(Debug, Clone, Copy, Eq, PartialEq)]
189pub struct VerificationToken<STATE> {
190 state: PhantomData<STATE>,
191 req_id: RequestId,
192}
193
194pub trait WasAtLeastAccepted {}
195
196#[derive(Copy, Clone, Debug, Eq, PartialEq)]
197pub struct TcStateNone;
198#[derive(Copy, Clone, Debug, Eq, PartialEq)]
199pub struct TcStateAccepted;
200#[derive(Copy, Clone, Debug, Eq, PartialEq)]
201pub struct TcStateStarted;
202#[derive(Copy, Clone, Debug, Eq, PartialEq)]
203pub struct TcStateCompleted;
204
205impl WasAtLeastAccepted for TcStateAccepted {}
206impl WasAtLeastAccepted for TcStateStarted {}
207impl WasAtLeastAccepted for TcStateCompleted {}
208
209#[derive(Debug, Copy, Clone, Eq, PartialEq)]
212pub enum TcStateToken {
213 None(VerificationToken<TcStateNone>),
214 Accepted(VerificationToken<TcStateAccepted>),
215 Started(VerificationToken<TcStateStarted>),
216 Completed(VerificationToken<TcStateCompleted>),
217}
218
219impl From<VerificationToken<TcStateNone>> for TcStateToken {
220 fn from(t: VerificationToken<TcStateNone>) -> Self {
221 TcStateToken::None(t)
222 }
223}
224
225impl TryFrom<TcStateToken> for VerificationToken<TcStateAccepted> {
226 type Error = ();
227
228 fn try_from(value: TcStateToken) -> Result<Self, Self::Error> {
229 if let TcStateToken::Accepted(token) = value {
230 Ok(token)
231 } else {
232 Err(())
233 }
234 }
235}
236
237impl TryFrom<TcStateToken> for VerificationToken<TcStateStarted> {
238 type Error = ();
239
240 fn try_from(value: TcStateToken) -> Result<Self, Self::Error> {
241 if let TcStateToken::Started(token) = value {
242 Ok(token)
243 } else {
244 Err(())
245 }
246 }
247}
248
249impl From<VerificationToken<TcStateAccepted>> for TcStateToken {
250 fn from(t: VerificationToken<TcStateAccepted>) -> Self {
251 TcStateToken::Accepted(t)
252 }
253}
254
255impl From<VerificationToken<TcStateStarted>> for TcStateToken {
256 fn from(t: VerificationToken<TcStateStarted>) -> Self {
257 TcStateToken::Started(t)
258 }
259}
260
261impl From<VerificationToken<TcStateCompleted>> for TcStateToken {
262 fn from(t: VerificationToken<TcStateCompleted>) -> Self {
263 TcStateToken::Completed(t)
264 }
265}
266
267impl<STATE> VerificationToken<STATE> {
268 fn new(req_id: RequestId) -> VerificationToken<TcStateNone> {
269 VerificationToken {
270 state: PhantomData,
271 req_id,
272 }
273 }
274
275 pub fn req_id(&self) -> RequestId {
276 self.req_id
277 }
278}
279
280pub struct FailParams<'stamp, 'fargs> {
282 time_stamp: Option<&'stamp [u8]>,
283 failure_code: &'fargs dyn EcssEnumeration,
284 failure_data: Option<&'fargs [u8]>,
285}
286
287impl<'stamp, 'fargs> FailParams<'stamp, 'fargs> {
288 pub fn new(
289 time_stamp: Option<&'stamp [u8]>,
290 failure_code: &'fargs impl EcssEnumeration,
291 failure_data: Option<&'fargs [u8]>,
292 ) -> Self {
293 Self {
294 time_stamp,
295 failure_code,
296 failure_data,
297 }
298 }
299}
300
301pub struct FailParamsWithStep<'stamp, 'fargs> {
303 bp: FailParams<'stamp, 'fargs>,
304 step: &'fargs dyn EcssEnumeration,
305}
306
307impl<'stamp, 'fargs> FailParamsWithStep<'stamp, 'fargs> {
308 pub fn new(
309 time_stamp: Option<&'stamp [u8]>,
310 step: &'fargs impl EcssEnumeration,
311 failure_code: &'fargs impl EcssEnumeration,
312 failure_data: Option<&'fargs [u8]>,
313 ) -> Self {
314 Self {
315 bp: FailParams::new(time_stamp, failure_code, failure_data),
316 step,
317 }
318 }
319}
320
321#[derive(Clone)]
322pub struct VerificationReporterCore {
323 pub dest_id: u16,
324 apid: u16,
325}
326
327pub enum VerifSuccess {}
328pub enum VerifFailure {}
329
330pub struct VerificationSendable<'src_data, State, SuccessOrFailure> {
334 token: Option<VerificationToken<State>>,
335 pus_tm: Option<PusTmCreator<'src_data>>,
336 phantom: PhantomData<SuccessOrFailure>,
337}
338
339impl<'src_data, State, SuccessOrFailure> VerificationSendable<'src_data, State, SuccessOrFailure> {
340 pub(crate) fn new(pus_tm: PusTmCreator<'src_data>, token: VerificationToken<State>) -> Self {
341 Self {
342 token: Some(token),
343 pus_tm: Some(pus_tm),
344 phantom: PhantomData,
345 }
346 }
347 pub(crate) fn new_no_token(pus_tm: PusTmCreator<'src_data>) -> Self {
348 Self {
349 token: None,
350 pus_tm: Some(pus_tm),
351 phantom: PhantomData,
352 }
353 }
354
355 pub fn len_packed(&self) -> usize {
356 self.pus_tm.as_ref().unwrap().len_written()
357 }
358
359 pub fn pus_tm(&self) -> &PusTmCreator<'src_data> {
360 self.pus_tm.as_ref().unwrap()
361 }
362
363 pub fn pus_tm_mut(&mut self) -> &mut PusTmCreator<'src_data> {
364 self.pus_tm.as_mut().unwrap()
365 }
366}
367
368impl<'src_data, State> VerificationSendable<'src_data, State, VerifFailure> {
369 pub fn send_success_verif_failure(self) {}
370}
371
372impl<'src_data, State> VerificationSendable<'src_data, State, VerifFailure> {
373 pub fn send_failure(self) -> (PusTmCreator<'src_data>, VerificationToken<State>) {
374 (self.pus_tm.unwrap(), self.token.unwrap())
375 }
376}
377
378impl<'src_data> VerificationSendable<'src_data, TcStateNone, VerifSuccess> {
379 pub fn send_success_acceptance_success(self) -> VerificationToken<TcStateAccepted> {
380 VerificationToken {
381 state: PhantomData,
382 req_id: self.token.unwrap().req_id(),
383 }
384 }
385}
386
387impl<'src_data> VerificationSendable<'src_data, TcStateAccepted, VerifSuccess> {
388 pub fn send_success_start_success(self) -> VerificationToken<TcStateStarted> {
389 VerificationToken {
390 state: PhantomData,
391 req_id: self.token.unwrap().req_id(),
392 }
393 }
394}
395
396impl<'src_data, TcState: WasAtLeastAccepted + Copy>
397 VerificationSendable<'src_data, TcState, VerifSuccess>
398{
399 pub fn send_success_step_or_completion_success(self) {}
400}
401
402impl VerificationReporterCore {
410 pub fn new(apid: u16) -> Option<Self> {
411 if apid > MAX_APID {
412 return None;
413 }
414 Some(Self { apid, dest_id: 0 })
415 }
416
417 pub fn set_apid(&mut self, apid: u16) -> bool {
418 if apid > MAX_APID {
419 return false;
420 }
421 self.apid = apid;
422 true
423 }
424
425 pub fn apid(&self) -> u16 {
426 self.apid
427 }
428
429 pub fn dest_id(&self) -> u16 {
430 self.dest_id
431 }
432
433 pub fn set_dest_id(&mut self, dest_id: u16) {
434 self.dest_id = dest_id;
435 }
436
437 pub fn add_tc(
440 &mut self,
441 pus_tc: &(impl CcsdsPacket + IsPusTelecommand),
442 ) -> VerificationToken<TcStateNone> {
443 self.add_tc_with_req_id(RequestId::new(pus_tc))
444 }
445
446 pub fn add_tc_with_req_id(&mut self, req_id: RequestId) -> VerificationToken<TcStateNone> {
449 VerificationToken::<TcStateNone>::new(req_id)
450 }
451
452 fn sendable_success_no_step<'src_data, State: Copy>(
453 &self,
454 src_data_buf: &'src_data mut [u8],
455 subservice: u8,
456 token: VerificationToken<State>,
457 seq_count: u16,
458 msg_count: u16,
459 time_stamp: Option<&'src_data [u8]>,
460 ) -> Result<
461 VerificationSendable<'src_data, State, VerifSuccess>,
462 VerificationErrorWithToken<State>,
463 > {
464 Ok(VerificationSendable::new(
465 self.create_pus_verif_success_tm(
466 src_data_buf,
467 subservice,
468 seq_count,
469 msg_count,
470 &token.req_id,
471 time_stamp,
472 None::<&dyn EcssEnumeration>,
473 )
474 .map_err(|e| VerificationErrorWithToken(e, token))?,
475 token,
476 ))
477 }
478
479 #[allow(clippy::too_many_arguments)]
481 fn sendable_failure_no_step<'src_data, State: Copy>(
482 &self,
483 src_data_buf: &'src_data mut [u8],
484 subservice: u8,
485 token: VerificationToken<State>,
486 seq_count: u16,
487 msg_count: u16,
488 step: Option<&(impl EcssEnumeration + ?Sized)>,
489 params: &FailParams<'src_data, '_>,
490 ) -> Result<
491 VerificationSendable<'src_data, State, VerifFailure>,
492 VerificationErrorWithToken<State>,
493 > {
494 Ok(VerificationSendable::new(
495 self.create_pus_verif_fail_tm(
496 src_data_buf,
497 subservice,
498 seq_count,
499 msg_count,
500 &token.req_id,
501 step,
502 params,
503 )
504 .map_err(|e| VerificationErrorWithToken(e, token))?,
505 token,
506 ))
507 }
508
509 pub fn acceptance_success<'src_data>(
511 &self,
512 src_data_buf: &'src_data mut [u8],
513 token: VerificationToken<TcStateNone>,
514 seq_count: u16,
515 msg_count: u16,
516 time_stamp: Option<&'src_data [u8]>,
517 ) -> Result<
518 VerificationSendable<'src_data, TcStateNone, VerifSuccess>,
519 VerificationErrorWithToken<TcStateNone>,
520 > {
521 self.sendable_success_no_step(
522 src_data_buf,
523 Subservice::TmAcceptanceSuccess.into(),
524 token,
525 seq_count,
526 msg_count,
527 time_stamp,
528 )
529 }
530
531 pub fn send_acceptance_success(
532 &self,
533 mut sendable: VerificationSendable<'_, TcStateNone, VerifSuccess>,
534 sender: &(impl EcssTmSenderCore + ?Sized),
535 ) -> Result<VerificationToken<TcStateAccepted>, VerificationOrSendErrorWithToken<TcStateNone>>
536 {
537 sender
538 .send_tm(sendable.pus_tm.take().unwrap().into())
539 .map_err(|e| VerificationOrSendErrorWithToken(e, sendable.token.unwrap()))?;
540 Ok(sendable.send_success_acceptance_success())
541 }
542
543 pub fn send_acceptance_failure(
544 &self,
545 mut sendable: VerificationSendable<'_, TcStateNone, VerifFailure>,
546 sender: &(impl EcssTmSenderCore + ?Sized),
547 ) -> Result<(), VerificationOrSendErrorWithToken<TcStateNone>> {
548 sender
549 .send_tm(sendable.pus_tm.take().unwrap().into())
550 .map_err(|e| VerificationOrSendErrorWithToken(e, sendable.token.unwrap()))?;
551 sendable.send_success_verif_failure();
552 Ok(())
553 }
554
555 pub fn acceptance_failure<'src_data>(
557 &self,
558 src_data_buf: &'src_data mut [u8],
559 token: VerificationToken<TcStateNone>,
560 seq_count: u16,
561 msg_count: u16,
562 params: FailParams<'src_data, '_>,
563 ) -> Result<
564 VerificationSendable<'src_data, TcStateNone, VerifFailure>,
565 VerificationErrorWithToken<TcStateNone>,
566 > {
567 self.sendable_failure_no_step(
568 src_data_buf,
569 Subservice::TmAcceptanceFailure.into(),
570 token,
571 seq_count,
572 msg_count,
573 None::<&dyn EcssEnumeration>,
574 ¶ms,
575 )
576 }
577
578 pub fn start_success<'src_data>(
582 &self,
583 src_data_buf: &'src_data mut [u8],
584 token: VerificationToken<TcStateAccepted>,
585 seq_count: u16,
586 msg_count: u16,
587 time_stamp: Option<&'src_data [u8]>,
588 ) -> Result<
589 VerificationSendable<'src_data, TcStateAccepted, VerifSuccess>,
590 VerificationErrorWithToken<TcStateAccepted>,
591 > {
592 self.sendable_success_no_step(
593 src_data_buf,
594 Subservice::TmStartSuccess.into(),
595 token,
596 seq_count,
597 msg_count,
598 time_stamp,
599 )
600 }
601
602 pub fn send_start_success(
603 &self,
604 mut sendable: VerificationSendable<'_, TcStateAccepted, VerifSuccess>,
605 sender: &(impl EcssTmSenderCore + ?Sized),
606 ) -> Result<VerificationToken<TcStateStarted>, VerificationOrSendErrorWithToken<TcStateAccepted>>
607 {
608 sender
609 .send_tm(sendable.pus_tm.take().unwrap().into())
610 .map_err(|e| VerificationOrSendErrorWithToken(e, sendable.token.unwrap()))?;
611 Ok(sendable.send_success_start_success())
612 }
613
614 pub fn start_failure<'src_data>(
619 &self,
620 src_data_buf: &'src_data mut [u8],
621 token: VerificationToken<TcStateAccepted>,
622 seq_count: u16,
623 msg_count: u16,
624 params: FailParams<'src_data, '_>,
625 ) -> Result<
626 VerificationSendable<'src_data, TcStateAccepted, VerifFailure>,
627 VerificationErrorWithToken<TcStateAccepted>,
628 > {
629 self.sendable_failure_no_step(
630 src_data_buf,
631 Subservice::TmStartFailure.into(),
632 token,
633 seq_count,
634 msg_count,
635 None::<&dyn EcssEnumeration>,
636 ¶ms,
637 )
638 }
639
640 pub fn send_start_failure(
641 &self,
642 mut sendable: VerificationSendable<'_, TcStateAccepted, VerifFailure>,
643 sender: &(impl EcssTmSenderCore + ?Sized),
644 ) -> Result<(), VerificationOrSendErrorWithToken<TcStateAccepted>> {
645 sender
646 .send_tm(sendable.pus_tm.take().unwrap().into())
647 .map_err(|e| VerificationOrSendErrorWithToken(e, sendable.token.unwrap()))?;
648 sendable.send_success_verif_failure();
649 Ok(())
650 }
651
652 pub fn step_success<'src_data>(
656 &self,
657 src_data_buf: &'src_data mut [u8],
658 token: &VerificationToken<TcStateStarted>,
659 seq_count: u16,
660 msg_count: u16,
661 time_stamp: Option<&'src_data [u8]>,
662 step: impl EcssEnumeration,
663 ) -> Result<VerificationSendable<'src_data, TcStateStarted, VerifSuccess>, EcssTmtcError> {
664 Ok(VerificationSendable::new_no_token(
665 self.create_pus_verif_success_tm(
666 src_data_buf,
667 Subservice::TmStepSuccess.into(),
668 seq_count,
669 msg_count,
670 &token.req_id,
671 time_stamp,
672 Some(&step),
673 )?,
674 ))
675 }
676
677 pub fn step_failure<'src_data>(
682 &self,
683 src_data_buf: &'src_data mut [u8],
684 token: VerificationToken<TcStateStarted>,
685 seq_count: u16,
686 msg_count: u16,
687 params: FailParamsWithStep<'src_data, '_>,
688 ) -> Result<
689 VerificationSendable<'src_data, TcStateStarted, VerifFailure>,
690 VerificationErrorWithToken<TcStateStarted>,
691 > {
692 Ok(VerificationSendable::new(
693 self.create_pus_verif_fail_tm(
694 src_data_buf,
695 Subservice::TmStepFailure.into(),
696 seq_count,
697 msg_count,
698 &token.req_id,
699 Some(params.step),
700 ¶ms.bp,
701 )
702 .map_err(|e| VerificationErrorWithToken(e, token))?,
703 token,
704 ))
705 }
706
707 pub fn completion_success<'src_data, TcState: WasAtLeastAccepted + Copy>(
712 &self,
713 src_data_buf: &'src_data mut [u8],
714 token: VerificationToken<TcState>,
715 seq_counter: u16,
716 msg_counter: u16,
717 time_stamp: Option<&'src_data [u8]>,
718 ) -> Result<
719 VerificationSendable<'src_data, TcState, VerifSuccess>,
720 VerificationErrorWithToken<TcState>,
721 > {
722 self.sendable_success_no_step(
723 src_data_buf,
724 Subservice::TmCompletionSuccess.into(),
725 token,
726 seq_counter,
727 msg_counter,
728 time_stamp,
729 )
730 }
731
732 pub fn completion_failure<'src_data, TcState: WasAtLeastAccepted + Copy>(
737 &self,
738 src_data_buf: &'src_data mut [u8],
739 token: VerificationToken<TcState>,
740 seq_count: u16,
741 msg_count: u16,
742 params: FailParams<'src_data, '_>,
743 ) -> Result<
744 VerificationSendable<'src_data, TcState, VerifFailure>,
745 VerificationErrorWithToken<TcState>,
746 > {
747 self.sendable_failure_no_step(
748 src_data_buf,
749 Subservice::TmCompletionFailure.into(),
750 token,
751 seq_count,
752 msg_count,
753 None::<&dyn EcssEnumeration>,
754 ¶ms,
755 )
756 }
757
758 pub fn send_step_or_completion_success<TcState: WasAtLeastAccepted + Copy>(
759 &self,
760 mut sendable: VerificationSendable<'_, TcState, VerifSuccess>,
761 sender: &(impl EcssTmSenderCore + ?Sized),
762 ) -> Result<(), VerificationOrSendErrorWithToken<TcState>> {
763 sender
764 .send_tm(sendable.pus_tm.take().unwrap().into())
765 .map_err(|e| VerificationOrSendErrorWithToken(e, sendable.token.unwrap()))?;
766 sendable.send_success_step_or_completion_success();
767 Ok(())
768 }
769
770 pub fn send_step_or_completion_failure<TcState: WasAtLeastAccepted + Copy>(
771 &self,
772 mut sendable: VerificationSendable<'_, TcState, VerifFailure>,
773 sender: &(impl EcssTmSenderCore + ?Sized),
774 ) -> Result<(), VerificationOrSendErrorWithToken<TcState>> {
775 sender
776 .send_tm(sendable.pus_tm.take().unwrap().into())
777 .map_err(|e| VerificationOrSendErrorWithToken(e, sendable.token.unwrap()))?;
778 sendable.send_success_verif_failure();
779 Ok(())
780 }
781
782 #[allow(clippy::too_many_arguments)]
784 fn create_pus_verif_success_tm<'src_data>(
785 &self,
786 src_data_buf: &'src_data mut [u8],
787 subservice: u8,
788 seq_count: u16,
789 msg_counter: u16,
790 req_id: &RequestId,
791 time_stamp: Option<&'src_data [u8]>,
792 step: Option<&(impl EcssEnumeration + ?Sized)>,
793 ) -> Result<PusTmCreator<'src_data>, EcssTmtcError> {
794 let mut source_data_len = size_of::<u32>();
795 if let Some(step) = step {
796 source_data_len += step.size();
797 }
798 source_buffer_large_enough(src_data_buf.len(), source_data_len)?;
799 let mut idx = 0;
800 req_id.to_bytes(&mut src_data_buf[0..RequestId::SIZE_AS_BYTES]);
801 idx += RequestId::SIZE_AS_BYTES;
802 if let Some(step) = step {
803 step.write_to_be_bytes(&mut src_data_buf[idx..idx + step.size()])
805 .unwrap();
806 }
807 let mut sp_header = SpHeader::tm_unseg(self.apid(), seq_count, 0).unwrap();
808 Ok(self.create_pus_verif_tm_base(
809 src_data_buf,
810 subservice,
811 msg_counter,
812 &mut sp_header,
813 time_stamp,
814 source_data_len,
815 ))
816 }
817
818 #[allow(clippy::too_many_arguments)]
820 fn create_pus_verif_fail_tm<'src_data>(
821 &self,
822 src_data_buf: &'src_data mut [u8],
823 subservice: u8,
824 seq_count: u16,
825 msg_counter: u16,
826 req_id: &RequestId,
827 step: Option<&(impl EcssEnumeration + ?Sized)>,
828 params: &FailParams<'src_data, '_>,
829 ) -> Result<PusTmCreator<'src_data>, EcssTmtcError> {
830 let mut idx = 0;
831 let mut source_data_len = RequestId::SIZE_AS_BYTES + params.failure_code.size();
832 if let Some(step) = step {
833 source_data_len += step.size();
834 }
835 if let Some(failure_data) = params.failure_data {
836 source_data_len += failure_data.len();
837 }
838 source_buffer_large_enough(src_data_buf.len(), source_data_len)?;
839 req_id.to_bytes(&mut src_data_buf[0..RequestId::SIZE_AS_BYTES]);
840 idx += RequestId::SIZE_AS_BYTES;
841 if let Some(step) = step {
842 step.write_to_be_bytes(&mut src_data_buf[idx..idx + step.size()])
844 .unwrap();
845 idx += step.size();
846 }
847 params
848 .failure_code
849 .write_to_be_bytes(&mut src_data_buf[idx..idx + params.failure_code.size()])
850 .map_err(PusError::ByteConversion)?;
851 idx += params.failure_code.size();
852 if let Some(failure_data) = params.failure_data {
853 src_data_buf[idx..idx + failure_data.len()].copy_from_slice(failure_data);
854 }
855 let mut sp_header = SpHeader::tm_unseg(self.apid(), seq_count, 0).unwrap();
856 Ok(self.create_pus_verif_tm_base(
857 src_data_buf,
858 subservice,
859 msg_counter,
860 &mut sp_header,
861 params.time_stamp,
862 source_data_len,
863 ))
864 }
865
866 fn create_pus_verif_tm_base<'src_data>(
867 &self,
868 src_data_buf: &'src_data mut [u8],
869 subservice: u8,
870 msg_counter: u16,
871 sp_header: &mut SpHeader,
872 time_stamp: Option<&'src_data [u8]>,
873 source_data_len: usize,
874 ) -> PusTmCreator<'src_data> {
875 let tm_sec_header =
876 PusTmSecondaryHeader::new(1, subservice, msg_counter, self.dest_id, time_stamp);
877 PusTmCreator::new(
878 sp_header,
879 tm_sec_header,
880 &src_data_buf[0..source_data_len],
881 true,
882 )
883 }
884}
885
886#[cfg(feature = "alloc")]
887mod alloc_mod {
888 use super::*;
889 use crate::pus::alloc_mod::EcssTmSender;
890 use crate::seq_count::SequenceCountProvider;
891 use alloc::boxed::Box;
892 use alloc::vec;
893 use alloc::vec::Vec;
894 use core::cell::RefCell;
895 use spacepackets::ecss::tc::IsPusTelecommand;
896
897 #[derive(Clone)]
898 pub struct VerificationReporterCfg {
899 apid: u16,
900 pub step_field_width: usize,
901 pub fail_code_field_width: usize,
902 pub max_fail_data_len: usize,
903 }
904
905 impl VerificationReporterCfg {
906 pub fn new(
907 apid: u16,
908 step_field_width: usize,
909 fail_code_field_width: usize,
910 max_fail_data_len: usize,
911 ) -> Option<Self> {
912 if apid > MAX_APID {
913 return None;
914 }
915 Some(Self {
916 apid,
917 step_field_width,
918 fail_code_field_width,
919 max_fail_data_len,
920 })
921 }
922 }
923
924 #[derive(Clone)]
929 pub struct VerificationReporter {
930 source_data_buf: RefCell<Vec<u8>>,
931 pub seq_count_provider: Option<Box<dyn SequenceCountProvider<u16> + Send>>,
932 pub msg_count_provider: Option<Box<dyn SequenceCountProvider<u16> + Send>>,
933 pub reporter: VerificationReporterCore,
934 }
935
936 impl VerificationReporter {
937 pub fn new(cfg: &VerificationReporterCfg) -> Self {
938 let reporter = VerificationReporterCore::new(cfg.apid).unwrap();
939 Self {
940 source_data_buf: RefCell::new(vec![
941 0;
942 RequestId::SIZE_AS_BYTES
943 + cfg.step_field_width
944 + cfg.fail_code_field_width
945 + cfg.max_fail_data_len
946 ]),
947 seq_count_provider: None,
948 msg_count_provider: None,
949 reporter,
950 }
951 }
952
953 delegate!(
954 to self.reporter {
955 pub fn set_apid(&mut self, apid: u16) -> bool;
956 pub fn apid(&self) -> u16;
957 pub fn add_tc(&mut self, pus_tc: &(impl CcsdsPacket + IsPusTelecommand)) -> VerificationToken<TcStateNone>;
958 pub fn add_tc_with_req_id(&mut self, req_id: RequestId) -> VerificationToken<TcStateNone>;
959 pub fn dest_id(&self) -> u16;
960 pub fn set_dest_id(&mut self, dest_id: u16);
961 }
962 );
963
964 pub fn allowed_source_data_len(&self) -> usize {
965 self.source_data_buf.borrow().capacity()
966 }
967
968 pub fn acceptance_success(
970 &self,
971 token: VerificationToken<TcStateNone>,
972 sender: &(impl EcssTmSenderCore + ?Sized),
973 time_stamp: Option<&[u8]>,
974 ) -> Result<VerificationToken<TcStateAccepted>, VerificationOrSendErrorWithToken<TcStateNone>>
975 {
976 let seq_count = self
977 .seq_count_provider
978 .as_ref()
979 .map_or(0, |v| v.get_and_increment());
980 let msg_count = self
981 .seq_count_provider
982 .as_ref()
983 .map_or(0, |v| v.get_and_increment());
984 let mut source_data_buf = self.source_data_buf.borrow_mut();
985 let sendable = self.reporter.acceptance_success(
986 source_data_buf.as_mut_slice(),
987 token,
988 seq_count,
989 msg_count,
990 time_stamp,
991 )?;
992 self.reporter.send_acceptance_success(sendable, sender)
993 }
994
995 pub fn acceptance_failure(
997 &self,
998 token: VerificationToken<TcStateNone>,
999 sender: &(impl EcssTmSenderCore + ?Sized),
1000 params: FailParams,
1001 ) -> Result<(), VerificationOrSendErrorWithToken<TcStateNone>> {
1002 let seq_count = self
1003 .seq_count_provider
1004 .as_ref()
1005 .map_or(0, |v| v.get_and_increment());
1006 let msg_count = self
1007 .seq_count_provider
1008 .as_ref()
1009 .map_or(0, |v| v.get_and_increment());
1010 let mut buf = self.source_data_buf.borrow_mut();
1011 let sendable = self.reporter.acceptance_failure(
1012 buf.as_mut_slice(),
1013 token,
1014 seq_count,
1015 msg_count,
1016 params,
1017 )?;
1018 self.reporter.send_acceptance_failure(sendable, sender)
1019 }
1020
1021 pub fn start_success(
1025 &self,
1026 token: VerificationToken<TcStateAccepted>,
1027 sender: &(impl EcssTmSenderCore + ?Sized),
1028 time_stamp: Option<&[u8]>,
1029 ) -> Result<
1030 VerificationToken<TcStateStarted>,
1031 VerificationOrSendErrorWithToken<TcStateAccepted>,
1032 > {
1033 let seq_count = self
1034 .seq_count_provider
1035 .as_ref()
1036 .map_or(0, |v| v.get_and_increment());
1037 let msg_count = self
1038 .seq_count_provider
1039 .as_ref()
1040 .map_or(0, |v| v.get_and_increment());
1041 let mut buf = self.source_data_buf.borrow_mut();
1042 let sendable = self.reporter.start_success(
1043 buf.as_mut_slice(),
1044 token,
1045 seq_count,
1046 msg_count,
1047 time_stamp,
1048 )?;
1049 self.reporter.send_start_success(sendable, sender)
1050 }
1051
1052 pub fn start_failure(
1057 &self,
1058 token: VerificationToken<TcStateAccepted>,
1059 sender: &(impl EcssTmSenderCore + ?Sized),
1060 params: FailParams,
1061 ) -> Result<(), VerificationOrSendErrorWithToken<TcStateAccepted>> {
1062 let seq_count = self
1063 .seq_count_provider
1064 .as_ref()
1065 .map_or(0, |v| v.get_and_increment());
1066 let msg_count = self
1067 .seq_count_provider
1068 .as_ref()
1069 .map_or(0, |v| v.get_and_increment());
1070 let mut buf = self.source_data_buf.borrow_mut();
1071 let sendable = self.reporter.start_failure(
1072 buf.as_mut_slice(),
1073 token,
1074 seq_count,
1075 msg_count,
1076 params,
1077 )?;
1078 self.reporter.send_start_failure(sendable, sender)
1079 }
1080
1081 pub fn step_success(
1085 &self,
1086 token: &VerificationToken<TcStateStarted>,
1087 sender: &(impl EcssTmSenderCore + ?Sized),
1088 time_stamp: Option<&[u8]>,
1089 step: impl EcssEnumeration,
1090 ) -> Result<(), EcssTmtcError> {
1091 let seq_count = self
1092 .seq_count_provider
1093 .as_ref()
1094 .map_or(0, |v| v.get_and_increment());
1095 let msg_count = self
1096 .seq_count_provider
1097 .as_ref()
1098 .map_or(0, |v| v.get_and_increment());
1099 let mut buf = self.source_data_buf.borrow_mut();
1100 let sendable = self.reporter.step_success(
1101 buf.as_mut_slice(),
1102 token,
1103 seq_count,
1104 msg_count,
1105 time_stamp,
1106 step,
1107 )?;
1108 self.reporter
1109 .send_step_or_completion_success(sendable, sender)
1110 .map_err(|e| e.0)
1111 }
1112
1113 pub fn step_failure(
1118 &self,
1119 token: VerificationToken<TcStateStarted>,
1120 sender: &(impl EcssTmSenderCore + ?Sized),
1121 params: FailParamsWithStep,
1122 ) -> Result<(), VerificationOrSendErrorWithToken<TcStateStarted>> {
1123 let seq_count = self
1124 .seq_count_provider
1125 .as_ref()
1126 .map_or(0, |v| v.get_and_increment());
1127 let msg_count = self
1128 .seq_count_provider
1129 .as_ref()
1130 .map_or(0, |v| v.get_and_increment());
1131 let mut buf = self.source_data_buf.borrow_mut();
1132 let sendable = self.reporter.step_failure(
1133 buf.as_mut_slice(),
1134 token,
1135 seq_count,
1136 msg_count,
1137 params,
1138 )?;
1139 self.reporter
1140 .send_step_or_completion_failure(sendable, sender)
1141 }
1142
1143 pub fn completion_success<TcState: WasAtLeastAccepted + Copy>(
1148 &self,
1149 token: VerificationToken<TcState>,
1150 sender: &(impl EcssTmSenderCore + ?Sized),
1151 time_stamp: Option<&[u8]>,
1152 ) -> Result<(), VerificationOrSendErrorWithToken<TcState>> {
1153 let seq_count = self
1154 .seq_count_provider
1155 .as_ref()
1156 .map_or(0, |v| v.get_and_increment());
1157 let msg_count = self
1158 .seq_count_provider
1159 .as_ref()
1160 .map_or(0, |v| v.get_and_increment());
1161 let mut buf = self.source_data_buf.borrow_mut();
1162 let sendable = self.reporter.completion_success(
1163 buf.as_mut_slice(),
1164 token,
1165 seq_count,
1166 msg_count,
1167 time_stamp,
1168 )?;
1169 self.reporter
1170 .send_step_or_completion_success(sendable, sender)
1171 }
1172
1173 pub fn completion_failure<TcState: WasAtLeastAccepted + Copy>(
1178 &self,
1179 token: VerificationToken<TcState>,
1180 sender: &(impl EcssTmSenderCore + ?Sized),
1181 params: FailParams,
1182 ) -> Result<(), VerificationOrSendErrorWithToken<TcState>> {
1183 let seq_count = self
1184 .seq_count_provider
1185 .as_ref()
1186 .map_or(0, |v| v.get_and_increment());
1187 let msg_count = self
1188 .seq_count_provider
1189 .as_ref()
1190 .map_or(0, |v| v.get_and_increment());
1191 let mut buf = self.source_data_buf.borrow_mut();
1192 let sendable = self.reporter.completion_failure(
1193 buf.as_mut_slice(),
1194 token,
1195 seq_count,
1196 msg_count,
1197 params,
1198 )?;
1199 self.reporter
1200 .send_step_or_completion_failure(sendable, sender)
1201 }
1202 }
1203
1204 #[derive(Clone)]
1207 pub struct VerificationReporterWithSender {
1208 pub reporter: VerificationReporter,
1209 pub sender: Box<dyn EcssTmSender>,
1210 }
1211
1212 impl VerificationReporterWithSender {
1213 pub fn new(cfg: &VerificationReporterCfg, sender: Box<dyn EcssTmSender>) -> Self {
1214 let reporter = VerificationReporter::new(cfg);
1215 Self::new_from_reporter(reporter, sender)
1216 }
1217
1218 pub fn new_from_reporter(
1219 reporter: VerificationReporter,
1220 sender: Box<dyn EcssTmSender>,
1221 ) -> Self {
1222 Self { reporter, sender }
1223 }
1224
1225 delegate! {
1226 to self.reporter {
1227 pub fn set_apid(&mut self, apid: u16) -> bool;
1228 pub fn apid(&self) -> u16;
1229 pub fn add_tc(&mut self, pus_tc: &(impl CcsdsPacket + IsPusTelecommand)) -> VerificationToken<TcStateNone>;
1230 pub fn add_tc_with_req_id(&mut self, req_id: RequestId) -> VerificationToken<TcStateNone>;
1231 pub fn dest_id(&self) -> u16;
1232 pub fn set_dest_id(&mut self, dest_id: u16);
1233 }
1234 }
1235
1236 pub fn acceptance_success(
1237 &self,
1238 token: VerificationToken<TcStateNone>,
1239 time_stamp: Option<&[u8]>,
1240 ) -> Result<VerificationToken<TcStateAccepted>, VerificationOrSendErrorWithToken<TcStateNone>>
1241 {
1242 self.reporter
1243 .acceptance_success(token, self.sender.as_ref(), time_stamp)
1244 }
1245
1246 pub fn acceptance_failure(
1247 &self,
1248 token: VerificationToken<TcStateNone>,
1249 params: FailParams,
1250 ) -> Result<(), VerificationOrSendErrorWithToken<TcStateNone>> {
1251 self.reporter
1252 .acceptance_failure(token, self.sender.as_ref(), params)
1253 }
1254
1255 pub fn start_success(
1256 &self,
1257 token: VerificationToken<TcStateAccepted>,
1258 time_stamp: Option<&[u8]>,
1259 ) -> Result<
1260 VerificationToken<TcStateStarted>,
1261 VerificationOrSendErrorWithToken<TcStateAccepted>,
1262 > {
1263 self.reporter
1264 .start_success(token, self.sender.as_ref(), time_stamp)
1265 }
1266
1267 pub fn start_failure(
1268 &self,
1269 token: VerificationToken<TcStateAccepted>,
1270 params: FailParams,
1271 ) -> Result<(), VerificationOrSendErrorWithToken<TcStateAccepted>> {
1272 self.reporter
1273 .start_failure(token, self.sender.as_ref(), params)
1274 }
1275
1276 pub fn step_success(
1277 &self,
1278 token: &VerificationToken<TcStateStarted>,
1279 time_stamp: Option<&[u8]>,
1280 step: impl EcssEnumeration,
1281 ) -> Result<(), EcssTmtcError> {
1282 self.reporter
1283 .step_success(token, self.sender.as_ref(), time_stamp, step)
1284 }
1285
1286 pub fn step_failure(
1287 &self,
1288 token: VerificationToken<TcStateStarted>,
1289 params: FailParamsWithStep,
1290 ) -> Result<(), VerificationOrSendErrorWithToken<TcStateStarted>> {
1291 self.reporter
1292 .step_failure(token, self.sender.as_ref(), params)
1293 }
1294
1295 pub fn completion_success<TcState: WasAtLeastAccepted + Copy>(
1296 &self,
1297 token: VerificationToken<TcState>,
1298 time_stamp: Option<&[u8]>,
1299 ) -> Result<(), VerificationOrSendErrorWithToken<TcState>> {
1300 self.reporter
1301 .completion_success(token, self.sender.as_ref(), time_stamp)
1302 }
1303
1304 pub fn completion_failure<TcState: WasAtLeastAccepted + Copy>(
1305 &self,
1306 token: VerificationToken<TcState>,
1307 params: FailParams,
1308 ) -> Result<(), VerificationOrSendErrorWithToken<TcState>> {
1309 self.reporter
1310 .completion_failure(token, self.sender.as_ref(), params)
1311 }
1312 }
1313}
1314
1315#[cfg(feature = "std")]
1316mod std_mod {
1317 use crate::pus::verification::VerificationReporterWithSender;
1318 use std::sync::{Arc, Mutex};
1319
1320 pub type StdVerifReporterWithSender = VerificationReporterWithSender;
1321 pub type SharedStdVerifReporterWithSender = Arc<Mutex<StdVerifReporterWithSender>>;
1322}
1323
1324#[cfg(test)]
1325mod tests {
1326 use crate::pool::{PoolProviderWithGuards, StaticMemoryPool, StaticPoolConfig};
1327 use crate::pus::tests::CommonTmInfo;
1328 use crate::pus::verification::{
1329 EcssTmSenderCore, EcssTmtcError, FailParams, FailParamsWithStep, RequestId, TcStateNone,
1330 VerificationReporter, VerificationReporterCfg, VerificationReporterWithSender,
1331 VerificationToken,
1332 };
1333 use crate::pus::{EcssChannel, MpscTmInSharedPoolSender, PusTmWrapper};
1334 use crate::tmtc::tm_helper::SharedTmPool;
1335 use crate::ChannelId;
1336 use alloc::boxed::Box;
1337 use alloc::format;
1338 use spacepackets::ecss::tc::{PusTcCreator, PusTcSecondaryHeader};
1339 use spacepackets::ecss::tm::PusTmReader;
1340 use spacepackets::ecss::{EcssEnumU16, EcssEnumU32, EcssEnumU8, PusError, PusPacket};
1341 use spacepackets::util::UnsignedEnum;
1342 use spacepackets::{ByteConversionError, CcsdsPacket, SpHeader};
1343 use std::cell::RefCell;
1344 use std::collections::VecDeque;
1345 use std::sync::mpsc;
1346 use std::time::Duration;
1347 use std::vec;
1348 use std::vec::Vec;
1349
1350 fn is_send<T: Send>(_: &T) {}
1351 #[allow(dead_code)]
1352 fn is_sync<T: Sync>(_: &T) {}
1353
1354 const TEST_APID: u16 = 0x02;
1355 const EMPTY_STAMP: [u8; 7] = [0; 7];
1356
1357 #[derive(Debug, Eq, PartialEq, Clone)]
1358 struct TmInfo {
1359 pub common: CommonTmInfo,
1360 pub req_id: RequestId,
1361 pub additional_data: Option<Vec<u8>>,
1362 }
1363
1364 #[derive(Default, Clone)]
1365 struct TestSender {
1366 pub service_queue: RefCell<VecDeque<TmInfo>>,
1367 }
1368
1369 impl EcssChannel for TestSender {
1370 fn id(&self) -> ChannelId {
1371 0
1372 }
1373 fn name(&self) -> &'static str {
1374 "test_sender"
1375 }
1376 }
1377
1378 impl EcssTmSenderCore for TestSender {
1379 fn send_tm(&self, tm: PusTmWrapper) -> Result<(), EcssTmtcError> {
1380 match tm {
1381 PusTmWrapper::InStore(_) => {
1382 panic!("TestSender: Can not deal with addresses");
1383 }
1384 PusTmWrapper::Direct(tm) => {
1385 assert_eq!(PusPacket::service(&tm), 1);
1386 assert!(!tm.source_data().is_empty());
1387 let mut time_stamp = [0; 7];
1388 time_stamp.clone_from_slice(&tm.timestamp()[0..7]);
1389 let src_data = tm.source_data();
1390 assert!(src_data.len() >= 4);
1391 let req_id =
1392 RequestId::from_bytes(&src_data[0..RequestId::SIZE_AS_BYTES]).unwrap();
1393 let mut vec = None;
1394 if src_data.len() > 4 {
1395 let mut new_vec = Vec::new();
1396 new_vec.extend_from_slice(&src_data[RequestId::SIZE_AS_BYTES..]);
1397 vec = Some(new_vec);
1398 }
1399 self.service_queue.borrow_mut().push_back(TmInfo {
1400 common: CommonTmInfo::new_from_tm(&tm),
1401 req_id,
1402 additional_data: vec,
1403 });
1404 Ok(())
1405 }
1406 }
1407 }
1408 }
1409
1410 struct TestBase<'a> {
1411 vr: VerificationReporter,
1412 #[allow(dead_code)]
1413 tc: PusTcCreator<'a>,
1414 }
1415
1416 impl<'a> TestBase<'a> {
1417 fn rep(&mut self) -> &mut VerificationReporter {
1418 &mut self.vr
1419 }
1420 }
1421 struct TestBaseWithHelper<'a> {
1422 helper: VerificationReporterWithSender,
1423 #[allow(dead_code)]
1424 tc: PusTcCreator<'a>,
1425 }
1426
1427 impl<'a> TestBaseWithHelper<'a> {
1428 fn rep(&mut self) -> &mut VerificationReporter {
1429 &mut self.helper.reporter
1430 }
1431 }
1432
1433 fn base_reporter() -> VerificationReporter {
1434 let cfg = VerificationReporterCfg::new(TEST_APID, 1, 2, 8).unwrap();
1435 VerificationReporter::new(&cfg)
1436 }
1437
1438 fn base_tc_init(app_data: Option<&[u8]>) -> (PusTcCreator, RequestId) {
1439 let mut sph = SpHeader::tc_unseg(TEST_APID, 0x34, 0).unwrap();
1440 let tc_header = PusTcSecondaryHeader::new_simple(17, 1);
1441 let app_data = app_data.unwrap_or(&[]);
1442 let pus_tc = PusTcCreator::new(&mut sph, tc_header, app_data, true);
1443 let req_id = RequestId::new(&pus_tc);
1444 (pus_tc, req_id)
1445 }
1446
1447 fn base_init(api_sel: bool) -> (TestBase<'static>, VerificationToken<TcStateNone>) {
1448 let mut reporter = base_reporter();
1449 let (tc, req_id) = base_tc_init(None);
1450 let init_tok = if api_sel {
1451 reporter.add_tc_with_req_id(req_id)
1452 } else {
1453 reporter.add_tc(&tc)
1454 };
1455 (TestBase { vr: reporter, tc }, init_tok)
1456 }
1457
1458 fn base_with_helper_init() -> (TestBaseWithHelper<'static>, VerificationToken<TcStateNone>) {
1459 let mut reporter = base_reporter();
1460 let (tc, _) = base_tc_init(None);
1461 let init_tok = reporter.add_tc(&tc);
1462 let sender = TestSender::default();
1463 let helper = VerificationReporterWithSender::new_from_reporter(reporter, Box::new(sender));
1464 (TestBaseWithHelper { helper, tc }, init_tok)
1465 }
1466
1467 fn acceptance_check(sender: &mut TestSender, req_id: &RequestId) {
1468 let cmp_info = TmInfo {
1469 common: CommonTmInfo {
1470 subservice: 1,
1471 apid: TEST_APID,
1472 msg_counter: 0,
1473 dest_id: 0,
1474 time_stamp: EMPTY_STAMP,
1475 },
1476 additional_data: None,
1477 req_id: *req_id,
1478 };
1479 let mut service_queue = sender.service_queue.borrow_mut();
1480 assert_eq!(service_queue.len(), 1);
1481 let info = service_queue.pop_front().unwrap();
1482 assert_eq!(info, cmp_info);
1483 }
1484
1485 #[test]
1486 fn test_mpsc_verif_send_sync() {
1487 let pool = StaticMemoryPool::new(StaticPoolConfig::new(vec![(8, 8)], false));
1488 let shared_tm_store = SharedTmPool::new(pool);
1489 let (tx, _) = mpsc::channel();
1490 let mpsc_verif_sender =
1491 MpscTmInSharedPoolSender::new(0, "verif_sender", shared_tm_store, tx);
1492 is_send(&mpsc_verif_sender);
1493 }
1494
1495 #[test]
1496 fn test_state() {
1497 let (mut b, _) = base_init(false);
1498 assert_eq!(b.vr.apid(), TEST_APID);
1499 b.vr.set_apid(TEST_APID + 1);
1500 assert_eq!(b.vr.apid(), TEST_APID + 1);
1501 }
1502
1503 #[test]
1504 fn test_basic_acceptance_success() {
1505 let (b, tok) = base_init(false);
1506 let mut sender = TestSender::default();
1507 b.vr.acceptance_success(tok, &sender, Some(&EMPTY_STAMP))
1508 .expect("Sending acceptance success failed");
1509 acceptance_check(&mut sender, &tok.req_id);
1510 }
1511
1512 #[test]
1513 fn test_basic_acceptance_success_with_helper() {
1514 let (mut b, tok) = base_with_helper_init();
1515 b.helper
1516 .acceptance_success(tok, Some(&EMPTY_STAMP))
1517 .expect("Sending acceptance success failed");
1518 let sender: &mut TestSender = b.helper.sender.downcast_mut().unwrap();
1519 acceptance_check(sender, &tok.req_id);
1520 }
1521
1522 fn acceptance_fail_check(sender: &mut TestSender, req_id: RequestId, stamp_buf: [u8; 7]) {
1523 let cmp_info = TmInfo {
1524 common: CommonTmInfo {
1525 subservice: 2,
1526 apid: TEST_APID,
1527 msg_counter: 0,
1528 dest_id: 5,
1529 time_stamp: stamp_buf,
1530 },
1531 additional_data: Some([0, 2].to_vec()),
1532 req_id,
1533 };
1534 let mut service_queue = sender.service_queue.borrow_mut();
1535 assert_eq!(service_queue.len(), 1);
1536 let info = service_queue.pop_front().unwrap();
1537 assert_eq!(info, cmp_info);
1538 }
1539
1540 #[test]
1541 fn test_basic_acceptance_failure() {
1542 let (mut b, tok) = base_init(true);
1543 b.rep().reporter.dest_id = 5;
1544 let stamp_buf = [1, 2, 3, 4, 5, 6, 7];
1545 let mut sender = TestSender::default();
1546 let fail_code = EcssEnumU16::new(2);
1547 let fail_params = FailParams::new(Some(stamp_buf.as_slice()), &fail_code, None);
1548 b.vr.acceptance_failure(tok, &sender, fail_params)
1549 .expect("Sending acceptance success failed");
1550 acceptance_fail_check(&mut sender, tok.req_id, stamp_buf);
1551 }
1552
1553 #[test]
1554 fn test_basic_acceptance_failure_with_helper() {
1555 let (mut b, tok) = base_with_helper_init();
1556 b.rep().reporter.dest_id = 5;
1557 let stamp_buf = [1, 2, 3, 4, 5, 6, 7];
1558 let fail_code = EcssEnumU16::new(2);
1559 let fail_params = FailParams::new(Some(stamp_buf.as_slice()), &fail_code, None);
1560 b.helper
1561 .acceptance_failure(tok, fail_params)
1562 .expect("Sending acceptance success failed");
1563 let sender: &mut TestSender = b.helper.sender.downcast_mut().unwrap();
1564 acceptance_fail_check(sender, tok.req_id, stamp_buf);
1565 }
1566
1567 #[test]
1568 fn test_acceptance_fail_data_too_large() {
1569 let (mut b, tok) = base_with_helper_init();
1570 b.rep().reporter.dest_id = 5;
1571 let stamp_buf = [1, 2, 3, 4, 5, 6, 7];
1572 let fail_code = EcssEnumU16::new(2);
1573 let fail_data: [u8; 16] = [0; 16];
1574 assert_eq!(b.rep().allowed_source_data_len(), 15);
1576 let fail_params = FailParams::new(
1577 Some(stamp_buf.as_slice()),
1578 &fail_code,
1579 Some(fail_data.as_slice()),
1580 );
1581 let res = b.helper.acceptance_failure(tok, fail_params);
1582 assert!(res.is_err());
1583 let err_with_token = res.unwrap_err();
1584 assert_eq!(err_with_token.1, tok);
1585 match err_with_token.0 {
1586 EcssTmtcError::Pus(PusError::ByteConversion(e)) => match e {
1587 ByteConversionError::ToSliceTooSmall { found, expected } => {
1588 assert_eq!(
1589 expected,
1590 fail_data.len() + RequestId::SIZE_AS_BYTES + fail_code.size()
1591 );
1592 assert_eq!(found, b.rep().allowed_source_data_len());
1593 }
1594 _ => {
1595 panic!("{}", format!("Unexpected error {:?}", e))
1596 }
1597 },
1598 _ => {
1599 panic!("{}", format!("Unexpected error {:?}", err_with_token.0))
1600 }
1601 }
1602 }
1603
1604 #[test]
1605 fn test_basic_acceptance_failure_with_fail_data() {
1606 let (b, tok) = base_init(false);
1607 let sender = TestSender::default();
1608 let fail_code = EcssEnumU8::new(10);
1609 let fail_data = EcssEnumU32::new(12);
1610 let mut fail_data_raw = [0; 4];
1611 fail_data.write_to_be_bytes(&mut fail_data_raw).unwrap();
1612 let fail_params = FailParams::new(
1613 Some(&EMPTY_STAMP),
1614 &fail_code,
1615 Some(fail_data_raw.as_slice()),
1616 );
1617 b.vr.acceptance_failure(tok, &sender, fail_params)
1618 .expect("Sending acceptance success failed");
1619 let cmp_info = TmInfo {
1620 common: CommonTmInfo {
1621 subservice: 2,
1622 apid: TEST_APID,
1623 msg_counter: 0,
1624 dest_id: 0,
1625 time_stamp: EMPTY_STAMP,
1626 },
1627 additional_data: Some([10, 0, 0, 0, 12].to_vec()),
1628 req_id: tok.req_id,
1629 };
1630 let mut service_queue = sender.service_queue.borrow_mut();
1631 assert_eq!(service_queue.len(), 1);
1632 let info = service_queue.pop_front().unwrap();
1633 assert_eq!(info, cmp_info);
1634 }
1635
1636 fn start_fail_check(sender: &mut TestSender, req_id: RequestId, fail_data_raw: [u8; 4]) {
1637 let mut srv_queue = sender.service_queue.borrow_mut();
1638 assert_eq!(srv_queue.len(), 2);
1639 let mut cmp_info = TmInfo {
1640 common: CommonTmInfo {
1641 subservice: 1,
1642 apid: TEST_APID,
1643 msg_counter: 0,
1644 dest_id: 0,
1645 time_stamp: EMPTY_STAMP,
1646 },
1647 additional_data: None,
1648 req_id,
1649 };
1650 let mut info = srv_queue.pop_front().unwrap();
1651 assert_eq!(info, cmp_info);
1652
1653 cmp_info = TmInfo {
1654 common: CommonTmInfo {
1655 subservice: 4,
1656 apid: TEST_APID,
1657 msg_counter: 0,
1658 dest_id: 0,
1659 time_stamp: EMPTY_STAMP,
1660 },
1661 additional_data: Some([&[22], fail_data_raw.as_slice()].concat().to_vec()),
1662 req_id,
1663 };
1664 info = srv_queue.pop_front().unwrap();
1665 assert_eq!(info, cmp_info);
1666 }
1667
1668 #[test]
1669 fn test_start_failure() {
1670 let (b, tok) = base_init(false);
1671 let mut sender = TestSender::default();
1672 let fail_code = EcssEnumU8::new(22);
1673 let fail_data: i32 = -12;
1674 let mut fail_data_raw = [0; 4];
1675 fail_data_raw.copy_from_slice(fail_data.to_be_bytes().as_slice());
1676 let fail_params = FailParams::new(
1677 Some(&EMPTY_STAMP),
1678 &fail_code,
1679 Some(fail_data_raw.as_slice()),
1680 );
1681
1682 let accepted_token =
1683 b.vr.acceptance_success(tok, &sender, Some(&EMPTY_STAMP))
1684 .expect("Sending acceptance success failed");
1685 b.vr.start_failure(accepted_token, &mut sender, fail_params)
1686 .expect("Start failure failure");
1687 start_fail_check(&mut sender, tok.req_id, fail_data_raw);
1688 }
1689
1690 #[test]
1691 fn test_start_failure_with_helper() {
1692 let (mut b, tok) = base_with_helper_init();
1693 let fail_code = EcssEnumU8::new(22);
1694 let fail_data: i32 = -12;
1695 let mut fail_data_raw = [0; 4];
1696 fail_data_raw.copy_from_slice(fail_data.to_be_bytes().as_slice());
1697 let fail_params = FailParams::new(
1698 Some(&EMPTY_STAMP),
1699 &fail_code,
1700 Some(fail_data_raw.as_slice()),
1701 );
1702
1703 let accepted_token = b
1704 .helper
1705 .acceptance_success(tok, Some(&EMPTY_STAMP))
1706 .expect("Sending acceptance success failed");
1707 let empty = b
1708 .helper
1709 .start_failure(accepted_token, fail_params)
1710 .expect("Start failure failure");
1711 assert_eq!(empty, ());
1712 let sender: &mut TestSender = b.helper.sender.downcast_mut().unwrap();
1713 start_fail_check(sender, tok.req_id, fail_data_raw);
1714 }
1715
1716 fn step_success_check(sender: &mut TestSender, req_id: RequestId) {
1717 let mut cmp_info = TmInfo {
1718 common: CommonTmInfo {
1719 subservice: 1,
1720 apid: TEST_APID,
1721 msg_counter: 0,
1722 dest_id: 0,
1723 time_stamp: EMPTY_STAMP,
1724 },
1725 additional_data: None,
1726 req_id,
1727 };
1728 let mut srv_queue = sender.service_queue.borrow_mut();
1729 let mut info = srv_queue.pop_front().unwrap();
1730 assert_eq!(info, cmp_info);
1731 cmp_info = TmInfo {
1732 common: CommonTmInfo {
1733 subservice: 3,
1734 apid: TEST_APID,
1735 msg_counter: 0,
1736 dest_id: 0,
1737 time_stamp: [0, 1, 0, 1, 0, 1, 0],
1738 },
1739 additional_data: None,
1740 req_id,
1741 };
1742 info = srv_queue.pop_front().unwrap();
1743 assert_eq!(info, cmp_info);
1744 cmp_info = TmInfo {
1745 common: CommonTmInfo {
1746 subservice: 5,
1747 apid: TEST_APID,
1748 msg_counter: 0,
1749 dest_id: 0,
1750 time_stamp: EMPTY_STAMP,
1751 },
1752 additional_data: Some([0].to_vec()),
1753 req_id,
1754 };
1755 info = srv_queue.pop_front().unwrap();
1756 assert_eq!(info, cmp_info);
1757 cmp_info = TmInfo {
1758 common: CommonTmInfo {
1759 subservice: 5,
1760 apid: TEST_APID,
1761 msg_counter: 0,
1762 dest_id: 0,
1763 time_stamp: EMPTY_STAMP,
1764 },
1765 additional_data: Some([1].to_vec()),
1766 req_id,
1767 };
1768 info = srv_queue.pop_front().unwrap();
1769 assert_eq!(info, cmp_info);
1770 }
1771
1772 #[test]
1773 fn test_steps_success() {
1774 let (mut b, tok) = base_init(false);
1775 let mut sender = TestSender::default();
1776 let accepted_token = b
1777 .rep()
1778 .acceptance_success(tok, &sender, Some(&EMPTY_STAMP))
1779 .expect("Sending acceptance success failed");
1780 let started_token = b
1781 .rep()
1782 .start_success(accepted_token, &sender, Some(&[0, 1, 0, 1, 0, 1, 0]))
1783 .expect("Sending start success failed");
1784 b.rep()
1785 .step_success(
1786 &started_token,
1787 &sender,
1788 Some(&EMPTY_STAMP),
1789 EcssEnumU8::new(0),
1790 )
1791 .expect("Sending step 0 success failed");
1792 b.vr.step_success(
1793 &started_token,
1794 &sender,
1795 Some(&EMPTY_STAMP),
1796 EcssEnumU8::new(1),
1797 )
1798 .expect("Sending step 1 success failed");
1799 assert_eq!(sender.service_queue.borrow().len(), 4);
1800 step_success_check(&mut sender, tok.req_id);
1801 }
1802
1803 #[test]
1804 fn test_steps_success_with_helper() {
1805 let (mut b, tok) = base_with_helper_init();
1806 let accepted_token = b
1807 .helper
1808 .acceptance_success(tok, Some(&EMPTY_STAMP))
1809 .expect("Sending acceptance success failed");
1810 let started_token = b
1811 .helper
1812 .start_success(accepted_token, Some(&[0, 1, 0, 1, 0, 1, 0]))
1813 .expect("Sending start success failed");
1814 b.helper
1815 .step_success(&started_token, Some(&EMPTY_STAMP), EcssEnumU8::new(0))
1816 .expect("Sending step 0 success failed");
1817 b.helper
1818 .step_success(&started_token, Some(&EMPTY_STAMP), EcssEnumU8::new(1))
1819 .expect("Sending step 1 success failed");
1820 let sender: &mut TestSender = b.helper.sender.downcast_mut().unwrap();
1821 assert_eq!(sender.service_queue.borrow().len(), 4);
1822 step_success_check(sender, tok.req_id);
1823 }
1824
1825 fn check_step_failure(sender: &mut TestSender, req_id: RequestId, fail_data_raw: [u8; 4]) {
1826 assert_eq!(sender.service_queue.borrow().len(), 4);
1827 let mut cmp_info = TmInfo {
1828 common: CommonTmInfo {
1829 subservice: 1,
1830 apid: TEST_APID,
1831 msg_counter: 0,
1832 dest_id: 0,
1833 time_stamp: EMPTY_STAMP,
1834 },
1835 additional_data: None,
1836 req_id,
1837 };
1838 let mut info = sender.service_queue.borrow_mut().pop_front().unwrap();
1839 assert_eq!(info, cmp_info);
1840
1841 cmp_info = TmInfo {
1842 common: CommonTmInfo {
1843 subservice: 3,
1844 apid: TEST_APID,
1845 msg_counter: 0,
1846 dest_id: 0,
1847 time_stamp: [0, 1, 0, 1, 0, 1, 0],
1848 },
1849 additional_data: None,
1850 req_id,
1851 };
1852 info = sender.service_queue.borrow_mut().pop_front().unwrap();
1853 assert_eq!(info, cmp_info);
1854
1855 cmp_info = TmInfo {
1856 common: CommonTmInfo {
1857 subservice: 5,
1858 apid: TEST_APID,
1859 msg_counter: 0,
1860 dest_id: 0,
1861 time_stamp: EMPTY_STAMP,
1862 },
1863 additional_data: Some([0].to_vec()),
1864 req_id,
1865 };
1866 info = sender.service_queue.get_mut().pop_front().unwrap();
1867 assert_eq!(info, cmp_info);
1868
1869 cmp_info = TmInfo {
1870 common: CommonTmInfo {
1871 subservice: 6,
1872 apid: TEST_APID,
1873 msg_counter: 0,
1874 dest_id: 0,
1875 time_stamp: EMPTY_STAMP,
1876 },
1877 additional_data: Some(
1878 [
1879 [1].as_slice(),
1880 &[0, 0, 0x10, 0x20],
1881 fail_data_raw.as_slice(),
1882 ]
1883 .concat()
1884 .to_vec(),
1885 ),
1886 req_id,
1887 };
1888 info = sender.service_queue.get_mut().pop_front().unwrap();
1889 assert_eq!(info, cmp_info);
1890 }
1891
1892 #[test]
1893 fn test_step_failure() {
1894 let (b, tok) = base_init(false);
1895 let mut sender = TestSender::default();
1896 let req_id = tok.req_id;
1897 let fail_code = EcssEnumU32::new(0x1020);
1898 let fail_data: f32 = -22.3232;
1899 let mut fail_data_raw = [0; 4];
1900 fail_data_raw.copy_from_slice(fail_data.to_be_bytes().as_slice());
1901 let fail_step = EcssEnumU8::new(1);
1902 let fail_params = FailParamsWithStep::new(
1903 Some(&EMPTY_STAMP),
1904 &fail_step,
1905 &fail_code,
1906 Some(fail_data_raw.as_slice()),
1907 );
1908
1909 let accepted_token =
1910 b.vr.acceptance_success(tok, &mut sender, Some(&EMPTY_STAMP))
1911 .expect("Sending acceptance success failed");
1912 let started_token =
1913 b.vr.start_success(accepted_token, &mut sender, Some(&[0, 1, 0, 1, 0, 1, 0]))
1914 .expect("Sending start success failed");
1915 let mut empty =
1916 b.vr.step_success(
1917 &started_token,
1918 &mut sender,
1919 Some(&EMPTY_STAMP),
1920 EcssEnumU8::new(0),
1921 )
1922 .expect("Sending completion success failed");
1923 assert_eq!(empty, ());
1924 empty =
1925 b.vr.step_failure(started_token, &mut sender, fail_params)
1926 .expect("Step failure failed");
1927 assert_eq!(empty, ());
1928 check_step_failure(&mut sender, req_id, fail_data_raw);
1929 }
1930
1931 #[test]
1932 fn test_steps_failure_with_helper() {
1933 let (mut b, tok) = base_with_helper_init();
1934 let req_id = tok.req_id;
1935 let fail_code = EcssEnumU32::new(0x1020);
1936 let fail_data: f32 = -22.3232;
1937 let mut fail_data_raw = [0; 4];
1938 fail_data_raw.copy_from_slice(fail_data.to_be_bytes().as_slice());
1939 let fail_step = EcssEnumU8::new(1);
1940 let fail_params = FailParamsWithStep::new(
1941 Some(&EMPTY_STAMP),
1942 &fail_step,
1943 &fail_code,
1944 Some(fail_data_raw.as_slice()),
1945 );
1946
1947 let accepted_token = b
1948 .helper
1949 .acceptance_success(tok, Some(&EMPTY_STAMP))
1950 .expect("Sending acceptance success failed");
1951 let started_token = b
1952 .helper
1953 .start_success(accepted_token, Some(&[0, 1, 0, 1, 0, 1, 0]))
1954 .expect("Sending start success failed");
1955 let mut empty = b
1956 .helper
1957 .step_success(&started_token, Some(&EMPTY_STAMP), EcssEnumU8::new(0))
1958 .expect("Sending completion success failed");
1959 assert_eq!(empty, ());
1960 empty = b
1961 .helper
1962 .step_failure(started_token, fail_params)
1963 .expect("Step failure failed");
1964 assert_eq!(empty, ());
1965 let sender: &mut TestSender = b.helper.sender.downcast_mut().unwrap();
1966 check_step_failure(sender, req_id, fail_data_raw);
1967 }
1968
1969 fn completion_fail_check(sender: &mut TestSender, req_id: RequestId) {
1970 assert_eq!(sender.service_queue.borrow().len(), 3);
1971
1972 let mut cmp_info = TmInfo {
1973 common: CommonTmInfo {
1974 subservice: 1,
1975 apid: TEST_APID,
1976 msg_counter: 0,
1977 dest_id: 0,
1978 time_stamp: EMPTY_STAMP,
1979 },
1980 additional_data: None,
1981 req_id,
1982 };
1983 let mut info = sender.service_queue.get_mut().pop_front().unwrap();
1984 assert_eq!(info, cmp_info);
1985
1986 cmp_info = TmInfo {
1987 common: CommonTmInfo {
1988 subservice: 3,
1989 apid: TEST_APID,
1990 msg_counter: 0,
1991 dest_id: 0,
1992 time_stamp: [0, 1, 0, 1, 0, 1, 0],
1993 },
1994 additional_data: None,
1995 req_id,
1996 };
1997 info = sender.service_queue.get_mut().pop_front().unwrap();
1998 assert_eq!(info, cmp_info);
1999
2000 cmp_info = TmInfo {
2001 common: CommonTmInfo {
2002 subservice: 8,
2003 apid: TEST_APID,
2004 msg_counter: 0,
2005 dest_id: 0,
2006 time_stamp: EMPTY_STAMP,
2007 },
2008 additional_data: Some([0, 0, 0x10, 0x20].to_vec()),
2009 req_id,
2010 };
2011 info = sender.service_queue.get_mut().pop_front().unwrap();
2012 assert_eq!(info, cmp_info);
2013 }
2014
2015 #[test]
2016 fn test_completion_failure() {
2017 let (b, tok) = base_init(false);
2018 let mut sender = TestSender::default();
2019 let req_id = tok.req_id;
2020 let fail_code = EcssEnumU32::new(0x1020);
2021 let fail_params = FailParams::new(Some(&EMPTY_STAMP), &fail_code, None);
2022
2023 let accepted_token =
2024 b.vr.acceptance_success(tok, &mut sender, Some(&EMPTY_STAMP))
2025 .expect("Sending acceptance success failed");
2026 let started_token =
2027 b.vr.start_success(accepted_token, &mut sender, Some(&[0, 1, 0, 1, 0, 1, 0]))
2028 .expect("Sending start success failed");
2029 let empty =
2030 b.vr.completion_failure(started_token, &mut sender, fail_params)
2031 .expect("Completion failure");
2032 assert_eq!(empty, ());
2033 completion_fail_check(&mut sender, req_id);
2034 }
2035
2036 #[test]
2037 fn test_completion_failure_with_helper() {
2038 let (mut b, tok) = base_with_helper_init();
2039 let req_id = tok.req_id;
2040 let fail_code = EcssEnumU32::new(0x1020);
2041 let fail_params = FailParams::new(Some(&EMPTY_STAMP), &fail_code, None);
2042
2043 let accepted_token = b
2044 .helper
2045 .acceptance_success(tok, Some(&EMPTY_STAMP))
2046 .expect("Sending acceptance success failed");
2047 let started_token = b
2048 .helper
2049 .start_success(accepted_token, Some(&[0, 1, 0, 1, 0, 1, 0]))
2050 .expect("Sending start success failed");
2051 let empty = b
2052 .helper
2053 .completion_failure(started_token, fail_params)
2054 .expect("Completion failure");
2055 assert_eq!(empty, ());
2056 let sender: &mut TestSender = b.helper.sender.downcast_mut().unwrap();
2057 completion_fail_check(sender, req_id);
2058 }
2059
2060 fn completion_success_check(sender: &mut TestSender, req_id: RequestId) {
2061 assert_eq!(sender.service_queue.borrow().len(), 3);
2062 let cmp_info = TmInfo {
2063 common: CommonTmInfo {
2064 subservice: 1,
2065 apid: TEST_APID,
2066 msg_counter: 0,
2067 dest_id: 0,
2068 time_stamp: EMPTY_STAMP,
2069 },
2070 additional_data: None,
2071 req_id,
2072 };
2073 let mut info = sender.service_queue.borrow_mut().pop_front().unwrap();
2074 assert_eq!(info, cmp_info);
2075
2076 let cmp_info = TmInfo {
2077 common: CommonTmInfo {
2078 subservice: 3,
2079 apid: TEST_APID,
2080 msg_counter: 0,
2081 dest_id: 0,
2082 time_stamp: [0, 1, 0, 1, 0, 1, 0],
2083 },
2084 additional_data: None,
2085 req_id,
2086 };
2087 info = sender.service_queue.borrow_mut().pop_front().unwrap();
2088 assert_eq!(info, cmp_info);
2089 let cmp_info = TmInfo {
2090 common: CommonTmInfo {
2091 subservice: 7,
2092 apid: TEST_APID,
2093 msg_counter: 0,
2094 dest_id: 0,
2095 time_stamp: EMPTY_STAMP,
2096 },
2097 additional_data: None,
2098 req_id,
2099 };
2100 info = sender.service_queue.borrow_mut().pop_front().unwrap();
2101 assert_eq!(info, cmp_info);
2102 }
2103
2104 #[test]
2105 fn test_complete_success_sequence() {
2106 let (b, tok) = base_init(false);
2107 let mut sender = TestSender::default();
2108 let accepted_token =
2109 b.vr.acceptance_success(tok, &mut sender, Some(&EMPTY_STAMP))
2110 .expect("Sending acceptance success failed");
2111 let started_token =
2112 b.vr.start_success(accepted_token, &mut sender, Some(&[0, 1, 0, 1, 0, 1, 0]))
2113 .expect("Sending start success failed");
2114 b.vr.completion_success(started_token, &mut sender, Some(&EMPTY_STAMP))
2115 .expect("Sending completion success failed");
2116 completion_success_check(&mut sender, tok.req_id);
2117 }
2118
2119 #[test]
2120 fn test_complete_success_sequence_with_helper() {
2121 let (mut b, tok) = base_with_helper_init();
2122 let accepted_token = b
2123 .helper
2124 .acceptance_success(tok, Some(&EMPTY_STAMP))
2125 .expect("Sending acceptance success failed");
2126 let started_token = b
2127 .helper
2128 .start_success(accepted_token, Some(&[0, 1, 0, 1, 0, 1, 0]))
2129 .expect("Sending start success failed");
2130 b.helper
2131 .completion_success(started_token, Some(&EMPTY_STAMP))
2132 .expect("Sending completion success failed");
2133 let sender: &mut TestSender = b.helper.sender.downcast_mut().unwrap();
2134 completion_success_check(sender, tok.req_id);
2135 }
2136
2137 #[test]
2138 fn test_seq_count_increment() {
2139 let pool_cfg =
2140 StaticPoolConfig::new(vec![(10, 32), (10, 64), (10, 128), (10, 1024)], false);
2141 let tm_pool = StaticMemoryPool::new(pool_cfg.clone());
2142 let shared_tm_store = SharedTmPool::new(tm_pool);
2143 let shared_tm_pool = shared_tm_store.clone_backing_pool();
2144 let (verif_tx, verif_rx) = mpsc::channel();
2145 let sender =
2146 MpscTmInSharedPoolSender::new(0, "Verification Sender", shared_tm_store, verif_tx);
2147 let cfg = VerificationReporterCfg::new(TEST_APID, 1, 2, 8).unwrap();
2148 let mut reporter = VerificationReporterWithSender::new(&cfg, Box::new(sender));
2149
2150 let mut sph = SpHeader::tc_unseg(TEST_APID, 0, 0).unwrap();
2151 let tc_header = PusTcSecondaryHeader::new_simple(17, 1);
2152 let pus_tc_0 = PusTcCreator::new_no_app_data(&mut sph, tc_header, true);
2153 let init_token = reporter.add_tc(&pus_tc_0);
2154
2155 let accepted_token = reporter
2157 .acceptance_success(init_token, Some(&EMPTY_STAMP))
2158 .unwrap();
2159 let started_token = reporter
2160 .start_success(accepted_token, Some(&EMPTY_STAMP))
2161 .unwrap();
2162 reporter
2163 .completion_success(started_token, Some(&EMPTY_STAMP))
2164 .unwrap();
2165
2166 let mut tm_buf: [u8; 1024] = [0; 1024];
2168 let mut packet_idx = 0;
2169 while packet_idx < 3 {
2170 let addr = verif_rx.recv_timeout(Duration::from_millis(10)).unwrap();
2171 let tm_len;
2172 {
2173 let mut rg = shared_tm_pool.write().expect("Error locking shared pool");
2174 let store_guard = rg.read_with_guard(addr);
2175 tm_len = store_guard
2176 .read(&mut tm_buf)
2177 .expect("Error reading TM slice");
2178 }
2179 let (pus_tm, _) =
2180 PusTmReader::new(&tm_buf[0..tm_len], 7).expect("Error reading verification TM");
2181 if packet_idx == 0 {
2182 assert_eq!(pus_tm.subservice(), 1);
2183 assert_eq!(pus_tm.sp_header.seq_count(), 0);
2184 } else if packet_idx == 1 {
2185 assert_eq!(pus_tm.subservice(), 3);
2186 assert_eq!(pus_tm.sp_header.seq_count(), 0);
2187 } else if packet_idx == 2 {
2188 assert_eq!(pus_tm.subservice(), 7);
2189 assert_eq!(pus_tm.sp_header.seq_count(), 0);
2190 }
2191 packet_idx += 1;
2192 }
2193 }
2194}