ddp_connection/protocol/
mod.rs

1// http://www.3waylabs.com/ddp/
2
3pub mod packet_type;
4pub use packet_type::*;
5
6pub mod pixel_config;
7pub use pixel_config::{PixelConfig, PixelFormat};
8
9pub mod id;
10pub use id::ID;
11use crate::protocol::timecode::TimeCode;
12
13pub mod message;
14pub mod timecode;
15
16#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
17pub struct Header {
18    pub packet_type: PacketType,
19    pub sequence_number: u8,
20    pub pixel_config: PixelConfig,
21    pub id: ID,
22    pub offset: u32,
23    pub length: u16,
24    pub time_code: TimeCode, //technically supported, although untested and relies on user to handle
25}
26
27
28
29impl Default for Header {
30    fn default() -> Self {
31        Self {
32            packet_type: Default::default(),
33            sequence_number: Default::default(),
34            pixel_config: Default::default(),
35            id: Default::default(),
36            offset: Default::default(),
37            length: Default::default(),
38            time_code: Default::default(),
39        }
40    }
41}
42
43impl Into<[u8; 10]> for Header {
44    fn into(self) -> [u8; 10] {
45        // Define a byte array with the size of the header
46        let mut buffer: [u8; 10] = [0u8; 10];
47
48        // Write the packet type field to the buffer
49
50
51        let packet_type_byte: u8 = self.packet_type.into();
52        buffer[0] = packet_type_byte;
53
54        // Write the sequence number field to the buffer
55        buffer[1] = self.sequence_number;
56
57        // Write the pixel config field to the buffer
58        buffer[2] = self.pixel_config.into();
59
60        // Write the id field to the buffer
61        buffer[3] = self.id.into();
62
63        // Write the offset field to the buffer
64        let offset_bytes = self.offset.to_be_bytes();
65        buffer[4..8].copy_from_slice(&offset_bytes);
66
67        // Write the length field to the buffer
68        let length_bytes = self.length.to_be_bytes();
69        buffer[8..10].copy_from_slice(&length_bytes);
70
71
72
73        // Return a slice of the buffer representing the entire header
74        buffer
75    }
76}
77impl Into<[u8; 14]> for Header {
78    fn into(self) -> [u8; 14] {
79        // Define a byte array with the size of the header
80        let mut buffer = [0u8; 14];
81
82        // Write the packet type field to the buffer
83
84
85        let packet_type_byte: u8 = self.packet_type.into();
86        buffer[0] = packet_type_byte;
87
88        // Write the sequence number field to the buffer
89        buffer[1] = self.sequence_number;
90
91        // Write the pixel config field to the buffer
92        buffer[2] = self.pixel_config.into();
93
94        // Write the id field to the buffer
95        buffer[3] = self.id.into();
96
97        // Write the offset field to the buffer
98        let offset_bytes: [u8; 4] = self.offset.to_be_bytes();
99        buffer[4..8].copy_from_slice(&offset_bytes);
100
101        // Write the length field to the buffer
102        let length_bytes: [u8; 2] = self.length.to_be_bytes();
103        buffer[8..10].copy_from_slice(&length_bytes);
104
105        let time_code: [u8; 4] = self.time_code.to_bytes();
106        buffer[10..14].copy_from_slice(&time_code);
107
108        // Return a slice of the buffer representing the entire header
109        buffer
110    }
111}
112
113impl<'a> From<&'a [u8]> for Header {
114    fn from(bytes: &'a [u8]) -> Self {
115
116        // Extract the packet type field from the buffer
117        let packet_type = PacketType::from(bytes[0]);
118
119        // Extract the sequence number field from the buffer
120        let sequence_number = bytes[1];
121
122        // Extract the pixel config field from the buffer
123        let pixel_config = PixelConfig::from(bytes[2]);
124
125        // Extract the id field from the buffer
126        let id = ID::from(bytes[3]);
127
128        // Extract the offset field from the buffer
129        let offset = u32::from_be_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]);
130
131        // Extract the length field from the buffer
132        let length = u16::from_be_bytes([bytes[8], bytes[9]]);
133
134        return if packet_type.timecode && bytes.len() >= 14 {
135
136            let time_code = TimeCode::from_4_bytes([bytes[10], bytes[11], bytes[12], bytes[13]]);
137
138            Header {
139                packet_type,
140                sequence_number,
141                pixel_config,
142                id,
143                offset,
144                length,
145                time_code
146            }
147        } else {
148            Header {
149                packet_type,
150                sequence_number,
151                pixel_config,
152                id,
153                offset,
154                length,
155                time_code: TimeCode(None)
156            }
157        }
158    }
159}
160
161#[cfg(test)]
162mod tests {
163    use super::*;
164
165    #[test]
166    fn test_parsing() {
167        // Normal
168        {
169            let data: [u8; 10] = [65, 6, 10, 1, 0, 0, 0, 0, 0, 3];
170            let header = Header::from(&data[..]);
171
172            assert_eq!(
173                header.packet_type,
174                PacketType {
175                    version: 1,
176                    timecode: false,
177                    storage: false,
178                    reply: false,
179                    query: false,
180                    push: true
181                }
182            );
183            assert_eq!(header.sequence_number, 6);
184            assert_eq!(header.length, 3);
185            assert_eq!(header.offset, 0);
186        }
187
188        // oddity
189        {
190            let data: [u8; 10] = [255, 12, 13, 1, 0, 0, 0x99, 0xd5, 0x01, 0x19];
191            let header = Header::from(&data[..]);
192
193            assert_eq!(
194                header.packet_type,
195                PacketType {
196                    version: 3,
197                    timecode: true,
198                    storage: true,
199                    reply: true,
200                    query: true,
201                    push: true
202                }
203            );
204
205            assert_eq!(header.sequence_number, 12);
206            assert_eq!(
207                header.pixel_config,
208                PixelConfig {
209                    data_type: pixel_config::DataType::RGB,
210                    data_size: PixelFormat::Pixel24Bits,
211                    customer_defined: false
212                }
213            );
214            assert_eq!(header.length, 281);
215            assert_eq!(header.offset, 39381);
216        }
217    }
218}