leodos_protocols/transport/cfdp/pdu/file_directive/keepalive/
large.rs1use bon::bon;
2use zerocopy::FromBytes;
3use zerocopy::Immutable;
4use zerocopy::IntoBytes;
5use zerocopy::KnownLayout;
6use zerocopy::Unaligned;
7use zerocopy::network_endian::U64;
8
9use crate::transport::cfdp::CfdpError;
10use crate::transport::cfdp::pdu::EntityId;
11use crate::transport::cfdp::pdu::Pdu;
12use crate::transport::cfdp::pdu::TransactionSeqNum;
13use crate::transport::cfdp::pdu::file_directive::DirectiveCode;
14use crate::transport::cfdp::pdu::file_directive::FileDirectivePdu;
15use crate::transport::cfdp::pdu::header::Direction;
16use crate::transport::cfdp::pdu::header::PduHeaderFixedPart;
17use crate::transport::cfdp::pdu::header::PduType;
18use crate::transport::cfdp::pdu::header::TransmissionMode;
19
20#[repr(C)]
33#[derive(Debug, FromBytes, IntoBytes, Unaligned, KnownLayout, Immutable)]
34pub struct KeepAlivePduLarge {
35 progress: U64,
37}
38
39impl KeepAlivePduLarge {
40 pub fn progress(&self) -> u64 {
42 self.progress.get()
43 }
44 pub fn set_progress(&mut self, progress: u64) {
46 self.progress.set(progress);
47 }
48}
49
50#[bon]
51impl KeepAlivePduLarge {
52 #[builder]
54 pub fn new<'a>(
55 buffer: &'a mut [u8],
56 source_entity_id: EntityId,
57 dest_entity_id: EntityId,
58 transaction_seq_num: TransactionSeqNum,
59 transmission_mode: TransmissionMode,
60 crc_flag: bool,
61 progress: u64,
62 ) -> Result<&'a mut Pdu, CfdpError> {
63 let data_field_len = (DirectiveCode::size() + size_of::<Self>()) as u16;
64
65 let header = PduHeaderFixedPart::builder()
66 .version(1)
67 .pdu_type(PduType::FileDirective)
68 .direction(Direction::TowardSender)
69 .tx_mode(transmission_mode)
70 .crc_flag(crc_flag)
71 .large_file_flag(true)
72 .data_field_len(data_field_len)
73 .seg_ctrl(false)
74 .seg_meta_flag(false)
75 .build()?;
76
77 let pdu = Pdu::builder()
78 .buffer(buffer)
79 .header_fixed(header)
80 .source_entity_id(source_entity_id)
81 .destination_entity_id(dest_entity_id)
82 .transaction_seq_num(transaction_seq_num)
83 .build()?;
84
85 let data_field = pdu.data_field_mut().unwrap();
86 let directive_pdu = FileDirectivePdu::mut_from_bytes(data_field).unwrap();
87 directive_pdu.set_directive_code(DirectiveCode::KeepAlive);
88
89 let keepalive_pdu = KeepAlivePduLarge::mut_from_bytes(&mut directive_pdu.rest).unwrap();
90 keepalive_pdu.set_progress(progress);
91
92 Ok(pdu)
93 }
94}