simple_someip/protocol/sd/
options.rs1use std::net::Ipv4Addr;
2
3use crate::protocol::{
4 Error,
5 byte_order::{ReadBytesExt, WriteBytesExt},
6};
7
8#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
9pub enum TransportProtocol {
10 Udp,
11 Tcp,
12}
13
14impl TryFrom<u8> for TransportProtocol {
15 type Error = Error;
16 fn try_from(value: u8) -> Result<Self, Error> {
17 match value {
18 0x11 => Ok(TransportProtocol::Udp),
19 0x06 => Ok(TransportProtocol::Tcp),
20 _ => Err(Error::InvalidSDOptionTransportProtocol(value)),
21 }
22 }
23}
24
25impl From<TransportProtocol> for u8 {
26 fn from(transport_protocol: TransportProtocol) -> u8 {
27 match transport_protocol {
28 TransportProtocol::Udp => 0x11,
29 TransportProtocol::Tcp => 0x06,
30 }
31 }
32}
33
34enum OptionType {
35 Configuration,
36 LoadBalancing,
37 IpV4Endpoint,
38 IpV6Endpoint,
39 IpV4Multicast,
40 IpV6Multicast,
41 IpV4SD,
42 IpV6SD,
43}
44
45impl TryFrom<u8> for OptionType {
46 type Error = Error;
47 fn try_from(value: u8) -> Result<Self, Error> {
48 match value {
49 0x01 => Ok(OptionType::Configuration),
50 0x02 => Ok(OptionType::LoadBalancing),
51 0x04 => Ok(OptionType::IpV4Endpoint),
52 0x06 => Ok(OptionType::IpV6Endpoint),
53 0x14 => Ok(OptionType::IpV4Multicast),
54 0x16 => Ok(OptionType::IpV6Multicast),
55 0x24 => Ok(OptionType::IpV4SD),
56 0x26 => Ok(OptionType::IpV6SD),
57 _ => Err(Error::InvalidSDOptionType(value)),
58 }
59 }
60}
61
62impl From<OptionType> for u8 {
63 fn from(option_type: OptionType) -> u8 {
64 match option_type {
65 OptionType::Configuration => 0x01,
66 OptionType::LoadBalancing => 0x02,
67 OptionType::IpV4Endpoint => 0x04,
68 OptionType::IpV6Endpoint => 0x06,
69 OptionType::IpV4Multicast => 0x14,
70 OptionType::IpV6Multicast => 0x16,
71 OptionType::IpV4SD => 0x24,
72 OptionType::IpV6SD => 0x26,
73 }
74 }
75}
76
77#[derive(Clone, Debug, Eq, PartialEq)]
78pub enum Options {
79 Configuration,
80 LoadBalancing,
81 IpV4Endpoint {
82 ip: Ipv4Addr,
83 protocol: TransportProtocol,
84 port: u16,
85 },
86 IpV6Endpoint,
87 IpV4Multicast,
88 IpV6Multicast,
89 IpV4SD,
90 IpV6SD,
91}
92
93impl Options {
94 #[must_use]
95 pub fn size(&self) -> usize {
96 match self {
97 Options::Configuration => todo!("Options::Configuration not implemented"),
98 Options::LoadBalancing => todo!("Options::Configuration not implemented"),
99 Options::IpV4Endpoint { .. } => 12,
100 Options::IpV6Endpoint => todo!("Options::Configuration not implemented"),
101 Options::IpV4Multicast => todo!("Options::Configuration not implemented"),
102 Options::IpV6Multicast => todo!("Options::Configuration not implemented"),
103 Options::IpV4SD => todo!("Options::Configuration not implemented"),
104 Options::IpV6SD => todo!("Options::Configuration not implemented"),
105 }
106 }
107
108 pub fn write<T: embedded_io::Write>(&self, writer: &mut T) -> Result<usize, Error> {
109 writer.write_u16_be(u16::try_from(self.size() - 3).expect("option size fits u16"))?;
110 match self {
111 Options::Configuration => todo!("Options::Configuration not implemented"),
112 Options::LoadBalancing => todo!("Options::Configuration not implemented"),
113 Options::IpV4Endpoint { ip, protocol, port } => {
114 writer.write_u8(u8::from(OptionType::IpV4Endpoint))?;
115 writer.write_u8(0)?;
116 writer.write_u32_be(ip.to_bits())?;
117 writer.write_u8(0)?;
118 writer.write_u8(u8::from(*protocol))?;
119 writer.write_u16_be(*port)?;
120 Ok(12)
121 }
122 Options::IpV6Endpoint => todo!("Options::Configuration not implemented"),
123 Options::IpV4Multicast => todo!("Options::Configuration not implemented"),
124 Options::IpV6Multicast => todo!("Options::Configuration not implemented"),
125 Options::IpV4SD => todo!("Options::Configuration not implemented"),
126 Options::IpV6SD => todo!("Options::Configuration not implemented"),
127 }
128 }
129
130 pub fn read<T: embedded_io::Read>(message_bytes: &mut T) -> Result<Self, Error> {
131 let length = message_bytes.read_u16_be()?;
132 let option_type = OptionType::try_from(message_bytes.read_u8()?)?;
133 let discard_flag = message_bytes.read_u8()? & 0x80 != 0;
134
135 match option_type {
136 OptionType::Configuration => {
137 todo!("Configuration option not implemented");
138 }
139 OptionType::LoadBalancing => {
140 todo!("LoadBalancing option not implemented");
141 }
142 OptionType::IpV4Endpoint => {
143 assert!(length == 9, "Invalid length for IpV4Endpoint");
144 assert!(!discard_flag, "Discard flag not set");
145 let ip = Ipv4Addr::from_bits(message_bytes.read_u32_be()?);
146 let reserved = message_bytes.read_u8()?;
147 assert!(reserved == 0, "Reserved byte not zero");
148 let protocol = TransportProtocol::try_from(message_bytes.read_u8()?)?;
149 let port = message_bytes.read_u16_be()?;
150 Ok(Options::IpV4Endpoint { ip, protocol, port })
151 }
152 OptionType::IpV6Endpoint => {
153 todo!("IpV6Endpoint option not implemented");
154 }
155 OptionType::IpV4Multicast => {
156 todo!("Multicast Option not implemented");
157 }
158 OptionType::IpV6Multicast => {
159 todo!("Multicast Option not implemented");
160 }
161 OptionType::IpV4SD => {
162 todo!("IpV4SD Option not implemented");
163 }
164 OptionType::IpV6SD => {
165 todo!("IpV6SD Option not implemented");
166 }
167 }
168 }
169}