osdp/command/
file_transfer.rs1use crate::error::Error;
6use alloc::vec::Vec;
7
8#[derive(Debug, Clone, PartialEq, Eq)]
10pub struct FileTransfer {
11 pub file_type: u8,
13 pub total_size: u32,
15 pub offset: u32,
17 pub fragment: Vec<u8>,
19}
20
21impl FileTransfer {
22 pub fn encode(&self) -> Result<Vec<u8>, Error> {
24 if self.fragment.len() > u16::MAX as usize {
25 return Err(Error::MalformedPayload {
26 code: 0x7C,
27 reason: "FILETRANSFER fragment > 65535 bytes",
28 });
29 }
30 let mut out = Vec::with_capacity(11 + self.fragment.len());
31 out.push(self.file_type);
32 out.extend_from_slice(&self.total_size.to_le_bytes());
33 out.extend_from_slice(&self.offset.to_le_bytes());
34 out.extend_from_slice(&(self.fragment.len() as u16).to_le_bytes());
35 out.extend_from_slice(&self.fragment);
36 Ok(out)
37 }
38
39 pub fn decode(data: &[u8]) -> Result<Self, Error> {
41 if data.len() < 11 {
42 return Err(Error::MalformedPayload {
43 code: 0x7C,
44 reason: "FILETRANSFER requires at least 11 bytes",
45 });
46 }
47 let total_size = u32::from_le_bytes([data[1], data[2], data[3], data[4]]);
48 let offset = u32::from_le_bytes([data[5], data[6], data[7], data[8]]);
49 let frag_len = u16::from_le_bytes([data[9], data[10]]) as usize;
50 if data.len() != 11 + frag_len {
51 return Err(Error::MalformedPayload {
52 code: 0x7C,
53 reason: "FILETRANSFER fragment length disagrees with payload",
54 });
55 }
56 Ok(Self {
57 file_type: data[0],
58 total_size,
59 offset,
60 fragment: data[11..11 + frag_len].to_vec(),
61 })
62 }
63}