Skip to main content

rust_ethernet_ip_protocol/
encap.rs

1use bytes::{Buf, BufMut, BytesMut};
2
3use crate::{Decode, Encode, ProtocolError, Result};
4
5pub const REGISTER_SESSION: u16 = 0x0065;
6pub const UNREGISTER_SESSION: u16 = 0x0066;
7pub const SEND_RR_DATA: u16 = 0x006F;
8#[allow(dead_code)]
9pub const SEND_UNIT_DATA: u16 = 0x0070;
10
11#[derive(Debug, Clone, PartialEq, Eq)]
12pub struct EncapsulationHeader {
13    pub command: u16,
14    pub length: u16,
15    pub session_handle: u32,
16    pub status: u32,
17    pub sender_context: [u8; 8],
18    pub options: u32,
19}
20
21impl EncapsulationHeader {
22    pub fn new(command: u16, length: u16, session_handle: u32) -> Self {
23        Self {
24            command,
25            length,
26            session_handle,
27            status: 0,
28            sender_context: [0; 8],
29            options: 0,
30        }
31    }
32
33    pub fn send_rr_data(length: u16, session_handle: u32) -> Self {
34        Self {
35            sender_context: [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08],
36            ..Self::new(SEND_RR_DATA, length, session_handle)
37        }
38    }
39
40    pub fn send_rr_data_with_context(
41        length: u16,
42        session_handle: u32,
43        sender_context: [u8; 8],
44    ) -> Self {
45        Self {
46            sender_context,
47            ..Self::new(SEND_RR_DATA, length, session_handle)
48        }
49    }
50}
51
52impl Encode for EncapsulationHeader {
53    fn encode(&self, buf: &mut BytesMut) {
54        buf.put_u16_le(self.command);
55        buf.put_u16_le(self.length);
56        buf.put_u32_le(self.session_handle);
57        buf.put_u32_le(self.status);
58        buf.put_slice(&self.sender_context);
59        buf.put_u32_le(self.options);
60    }
61}
62
63impl Decode for EncapsulationHeader {
64    fn decode(buf: &mut impl Buf) -> Result<Self> {
65        if buf.remaining() < 24 {
66            return Err(ProtocolError::new(
67                "Encapsulation header too short".to_string(),
68            ));
69        }
70
71        let command = buf.get_u16_le();
72        let length = buf.get_u16_le();
73        let session_handle = buf.get_u32_le();
74        let status = buf.get_u32_le();
75        let mut sender_context = [0u8; 8];
76        buf.copy_to_slice(&mut sender_context);
77        let options = buf.get_u32_le();
78
79        Ok(Self {
80            command,
81            length,
82            session_handle,
83            status,
84            sender_context,
85            options,
86        })
87    }
88}