1use crate::*;
8use crate::{
9 connection::*,
10 error::{cip_error, cip_error_status},
11 Status,
12};
13use bytes::Buf;
14use rseip_core::{
15 cip::CommonPacketIter,
16 codec::{Decode, Decoder},
17 Either, Error,
18};
19
20#[inline]
21pub fn decode_service_and_status<'de, D>(mut decoder: D) -> Result<(u8, Status), D::Error>
22where
23 D: Decoder<'de>,
24{
25 decoder.ensure_size(4)?;
26 let reply_service = decoder.decode_u8(); decoder.buf_mut().advance(1); let general_status = decoder.decode_u8(); let extended_status_size = decoder.decode_u8(); decoder.ensure_size((extended_status_size * 2) as usize)?;
31 let extended_status = match extended_status_size {
32 0 => None,
33 1 => Some(decoder.decode_u16()),
34 v => return Err(Error::invalid_value("one of 0,1", v)),
35 };
36 let status = Status {
37 general: general_status,
38 extended: extended_status,
39 };
40
41 Ok((reply_service, status))
42}
43
44impl<'de, R> Decode<'de> for MessageReply<R>
45where
46 R: Decode<'de>,
47{
48 #[inline]
49 fn decode<D>(mut decoder: D) -> Result<Self, D::Error>
50 where
51 D: Decoder<'de>,
52 {
53 let (reply_service, status) = decode_service_and_status(&mut decoder)?;
54 if status.is_err() {
55 return Err(cip_error_status(status));
56 }
57 let data = decoder.decode_any()?;
58 Ok(MessageReply::new(reply_service, status, data))
59 }
60}
61
62#[inline]
68pub fn decode_connected_send<'de, D, R>(
69 mut cpf: CommonPacketIter<'de, D>,
70) -> Result<(u16, R), D::Error>
71where
72 D: Decoder<'de>,
73 R: Decode<'de> + 'static,
74{
75 if cpf.len() != 2 {
76 return Err(cip_error("common packet - expect 2 items"));
77 }
78 ensure_connected_address(&mut cpf)?;
80 if let Some(res) = cpf.next_typed() {
82 let data_item: CommonPacketItem<(u16, _)> = res?;
83 data_item.ensure_type_code::<D::Error>(0xB1)?;
84 return Ok(data_item.data);
85 }
86 Err(cip_error("common packet - expect connected data item"))
87}
88
89#[inline]
95pub fn decode_unconnected_send<'de, D, R>(mut cpf: CommonPacketIter<'de, D>) -> Result<R, D::Error>
96where
97 D: Decoder<'de>,
98 R: Decode<'de> + 'static,
99{
100 if cpf.len() != 2 {
101 return Err(cip_error("common packet - expected 2 items"));
102 }
103 ensure_null_address(&mut cpf)?;
105
106 if let Some(res) = cpf.next_typed() {
108 let data_item: CommonPacketItem<_> = res?;
109 data_item.ensure_type_code::<D::Error>(0xB2)?;
110 return Ok(data_item.data);
111 }
112 Err(cip_error("common packet - expect connected data item"))
113}
114
115impl<'de> Decode<'de> for ForwardOpenReply {
116 #[inline]
117 fn decode<D>(mut decoder: D) -> Result<Self, D::Error>
118 where
119 D: Decoder<'de>,
120 {
121 let (reply_service, status) = decode_service_and_status(&mut decoder)?;
122 let data = if status.is_err() {
123 let v = decode_forward_fail(decoder, status)?;
124 Either::Right(v)
125 } else {
126 let v = decode_forward_open_success(decoder)?;
127 Either::Left(v)
128 };
129 Ok(Self(MessageReply::new(reply_service, status, data)))
130 }
131}
132
133impl<'de> Decode<'de> for ForwardCloseReply {
134 #[inline]
135 fn decode<D>(mut decoder: D) -> Result<Self, D::Error>
136 where
137 D: Decoder<'de>,
138 {
139 let (reply_service, status) = decode_service_and_status(&mut decoder)?;
140 let data = if status.is_err() {
141 let v = decode_forward_fail(decoder, status)?;
142 Either::Right(v)
143 } else {
144 let v = decode_forward_close_success(decoder)?;
145 Either::Left(v)
146 };
147 Ok(Self(MessageReply::new(reply_service, status, data)))
148 }
149}
150
151#[inline]
152fn decode_forward_open_success<'de, D>(mut decoder: D) -> Result<ForwardOpenSuccess, D::Error>
153where
154 D: Decoder<'de>,
155{
156 decoder.ensure_size(26)?;
157 let v = ForwardOpenSuccess {
158 o_t_connection_id: decoder.decode_u32(),
159 t_o_connection_id: decoder.decode_u32(),
160 connection_serial_number: decoder.decode_u16(),
161 originator_vendor_id: decoder.decode_u16(),
162 originator_serial_number: decoder.decode_u32(),
163 o_t_api: decoder.decode_u32(),
164 t_o_api: decoder.decode_u32(),
165 app_data: {
166 let app_data_size = 2 * decoder.decode_u8() as usize;
168 decoder.ensure_size(app_data_size)?;
169 decoder.buf_mut().advance(1); decoder.buf_mut().copy_to_bytes(app_data_size)
171 },
172 };
173 Ok(v)
174}
175
176#[inline]
177fn decode_forward_close_success<'de, D>(mut decoder: D) -> Result<ForwardCloseSuccess, D::Error>
178where
179 D: Decoder<'de>,
180{
181 decoder.ensure_size(10)?;
182 let v = ForwardCloseSuccess {
183 connection_serial_number: decoder.decode_u16(), originator_vendor_id: decoder.decode_u16(), originator_serial_number: decoder.decode_u32(), app_data: {
187 let app_data_size = 2 * decoder.decode_u8() as usize;
189 decoder.ensure_size(app_data_size)?;
190 decoder.buf_mut().advance(1); decoder.buf_mut().copy_to_bytes(app_data_size)
192 },
193 };
194 Ok(v)
195}
196
197#[inline]
198fn decode_forward_fail<'de, D>(
199 mut decoder: D,
200 status: Status,
201) -> Result<ForwardRequestFail, D::Error>
202where
203 D: Decoder<'de>,
204{
205 let is_routing_error = status.is_routing_error();
206 let max_size = if is_routing_error { 9 } else { 8 };
207 decoder.ensure_size(max_size)?;
208 let res = ForwardRequestFail {
209 connection_serial_number: decoder.decode_u16(),
210 originator_vendor_id: decoder.decode_u16(),
211 originator_serial_number: decoder.decode_u32(),
212 remaining_path_size: if is_routing_error {
213 Some(decoder.decode_u8())
214 } else {
215 None
216 },
217 };
218 Ok(res)
219}
220
221#[inline]
222pub fn ensure_null_address<'de, D>(cpf: &mut CommonPacketIter<'de, D>) -> Result<(), D::Error>
223where
224 D: Decoder<'de>,
225{
226 if let Some(res) = cpf.next_item() {
227 let item = res?;
228 if item.type_code == 0 {
229 return Ok(());
230 }
231 }
232 Err(cip_error("common packet - expect null address"))
233}
234
235#[inline]
236pub fn ensure_connected_address<'de, D>(cpf: &mut CommonPacketIter<'de, D>) -> Result<(), D::Error>
237where
238 D: Decoder<'de>,
239{
240 if let Some(res) = cpf.next_item() {
241 let item = res?;
242 if item.type_code == 0xA1 {
243 return Ok(());
244 }
245 }
246 Err(cip_error("common packet - expect null address"))
247}