async_coap/message/
std_parser.rs1use super::*;
17use std::borrow::Borrow;
18
19#[derive(Debug)]
21pub struct StandardMessageParser<'buf> {
22 buffer: &'buf [u8],
23 msg_code: MsgCode,
24 msg_type: MsgType,
25 msg_id: u16,
26 token: MsgToken,
27 content_format: Option<ContentFormat>,
28 accept: Option<ContentFormat>,
29 block2: Option<BlockInfo>,
30 block1: Option<BlockInfo>,
31 option_start: usize,
32 payload_start: usize,
33}
34
35impl<'buf> std::fmt::Display for StandardMessageParser<'buf> {
36 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37 MessageDisplay(self).fmt(f)
38 }
39}
40
41impl<'buf> StandardMessageParser<'buf> {
42 pub const MIN_MESSAGE_BUFFER_LEN: usize = 4;
44
45 pub fn new(buffer: &'buf [u8]) -> Result<StandardMessageParser<'buf>, Error> {
47 if buffer.len() < StandardMessageParser::MIN_MESSAGE_BUFFER_LEN {
48 return Err(Error::ParseFailure);
49 }
50
51 let msg_code = MsgCode::try_from(buffer[1]).ok_or(Error::UnknownMessageCode)?;
52
53 let msg_type = MsgType::from((buffer[0] & COAP_MSG_T_MASK) >> COAP_MSG_T_OFFS);
54 let msg_id = buffer[3] as u16 | ((buffer[2] as u16) << 8);
55 let token_len = (buffer[0] & COAP_MSG_TKL_MASK) as usize;
56 if token_len > 8 {
57 return Err(Error::ParseFailure);
58 }
59 let token = MsgToken::new(&buffer[4..4 + token_len]);
60
61 let mut content_format = None;
62 let mut accept = None;
63 let mut block2 = None;
64 let mut block1 = None;
65
66 let mut iter = OptionIterator::new(&buffer[4 + token_len..]);
67
68 for result in &mut iter {
69 match result {
70 Ok((OptionNumber::CONTENT_FORMAT, value)) => {
71 content_format = Some(ContentFormat(
72 try_decode_u16(value).ok_or(Error::ParseFailure)?,
73 ));
74 }
75 Ok((OptionNumber::ACCEPT, value)) => match try_decode_u16(value) {
76 Some(x) => accept = Some(ContentFormat(x)),
77 None => return Err(Error::ParseFailure),
78 },
79 Ok((OptionNumber::BLOCK2, value)) => match try_decode_u32(value) {
80 Some(x) => block2 = Some(BlockInfo(x).valid().ok_or(Error::ParseFailure)?),
81 None => return Err(Error::ParseFailure),
82 },
83 Ok((OptionNumber::BLOCK1, value)) => match try_decode_u32(value) {
84 Some(x) => block1 = Some(BlockInfo(x).valid().ok_or(Error::ParseFailure)?),
85 None => return Err(Error::ParseFailure),
86 },
87 Ok((_key, _value)) => {
88 }
90 Err(e) => {
91 return Err(e);
92 }
93 }
94 }
95
96 let payload_start = iter.as_slice().as_ptr() as usize - buffer.as_ptr() as usize;
97
98 let ret = StandardMessageParser {
99 buffer,
100 msg_code,
101 msg_type,
102 msg_id,
103 token,
104 content_format,
105 accept,
106 block2,
107 block1,
108 option_start: 4 + token_len,
109 payload_start,
110 };
111
112 Ok(ret)
113 }
114
115 pub fn as_bytes(&self) -> &'buf [u8] {
117 self.buffer
118 }
119}
120
121impl<'buf> MessageRead for StandardMessageParser<'buf> {
122 fn msg_code(&self) -> MsgCode {
123 self.msg_code
124 }
125
126 fn msg_type(&self) -> MsgType {
127 self.msg_type
128 }
129
130 fn msg_id(&self) -> u16 {
131 self.msg_id
132 }
133
134 fn msg_token(&self) -> MsgToken {
135 self.token
136 }
137
138 fn payload(&self) -> &[u8] {
139 &self.buffer[self.payload_start..]
140 }
141
142 fn content_format(&self) -> Option<ContentFormat> {
143 self.content_format
144 }
145
146 fn accept(&self) -> Option<ContentFormat> {
147 self.accept
148 }
149
150 fn block2(&self) -> Option<BlockInfo> {
151 self.block2
152 }
153
154 fn block1(&self) -> Option<BlockInfo> {
155 self.block1
156 }
157
158 fn options(&self) -> OptionIterator<'_> {
159 OptionIterator::new(&self.buffer[4 + self.token.len()..])
160 }
161}
162
163#[derive(Debug, Clone, Eq, PartialEq)]
165pub struct OwnedImmutableMessage {
166 buffer: Vec<u8>,
167 msg_code: MsgCode,
168 msg_type: MsgType,
169 msg_id: u16,
170 token: MsgToken,
171 content_format: Option<ContentFormat>,
172 accept: Option<ContentFormat>,
173 block2: Option<BlockInfo>,
174 block1: Option<BlockInfo>,
175 option_start: usize,
176 payload_start: usize,
177}
178
179impl std::fmt::Display for OwnedImmutableMessage {
180 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
181 MessageDisplay(self).fmt(f)
182 }
183}
184
185impl<'a> Borrow<dyn MessageRead + 'a> for OwnedImmutableMessage {
186 fn borrow(&self) -> &(dyn MessageRead + 'a) {
187 self
188 }
189}
190
191impl OwnedImmutableMessage {
192 pub const MIN_MESSAGE_BUFFER_LEN: usize = 4;
194
195 pub fn new(buffer: Vec<u8>) -> Result<OwnedImmutableMessage, Error> {
197 let msg_code = MsgCode::try_from(buffer[1]).ok_or(Error::UnknownMessageCode)?;
198
199 let msg_type = MsgType::from((buffer[0] & COAP_MSG_T_MASK) >> COAP_MSG_T_OFFS);
200 let msg_id = buffer[3] as u16 | ((buffer[2] as u16) << 8);
201 let token_len = (buffer[0] & COAP_MSG_TKL_MASK) as usize;
202 if token_len > 8 {
203 return Err(Error::ParseFailure);
204 }
205 let token = MsgToken::new(&buffer[4..4 + token_len]);
206
207 let mut content_format = None;
208 let mut accept = None;
209 let mut block2 = None;
210 let mut block1 = None;
211
212 let mut iter = OptionIterator::new(&buffer[4 + token_len..]);
213
214 for result in &mut iter {
215 match result {
216 Ok((OptionNumber::CONTENT_FORMAT, value)) => {
217 content_format = Some(ContentFormat(
218 try_decode_u16(value).ok_or(Error::ParseFailure)?,
219 ));
220 }
221 Ok((OptionNumber::ACCEPT, value)) => match try_decode_u16(value) {
222 Some(x) => accept = Some(ContentFormat(x)),
223 None => return Err(Error::ParseFailure),
224 },
225 Ok((OptionNumber::BLOCK2, value)) => match try_decode_u32(value) {
226 Some(x) => block2 = Some(BlockInfo(x).valid().ok_or(Error::ParseFailure)?),
227 None => return Err(Error::ParseFailure),
228 },
229 Ok((OptionNumber::BLOCK1, value)) => match try_decode_u32(value) {
230 Some(x) => block1 = Some(BlockInfo(x).valid().ok_or(Error::ParseFailure)?),
231 None => return Err(Error::ParseFailure),
232 },
233 Ok((_key, _value)) => {
234 }
236 Err(e) => {
237 return Err(e);
238 }
239 }
240 }
241
242 let payload_start = iter.as_slice().as_ptr() as usize - buffer.as_ptr() as usize;
243
244 let ret = OwnedImmutableMessage {
245 buffer,
246 msg_code,
247 msg_type,
248 msg_id,
249 token,
250 content_format,
251 accept,
252 block2,
253 block1,
254 option_start: 4 + token_len,
255 payload_start,
256 };
257
258 Ok(ret)
259 }
260
261 pub fn as_bytes(&self) -> &[u8] {
263 &self.buffer
264 }
265}
266
267impl MessageRead for OwnedImmutableMessage {
268 fn msg_code(&self) -> MsgCode {
269 self.msg_code
270 }
271
272 fn msg_type(&self) -> MsgType {
273 self.msg_type
274 }
275
276 fn msg_id(&self) -> u16 {
277 self.msg_id
278 }
279
280 fn msg_token(&self) -> MsgToken {
281 self.token
282 }
283
284 fn payload(&self) -> &[u8] {
285 &self.buffer[self.payload_start..]
286 }
287
288 fn content_format(&self) -> Option<ContentFormat> {
289 self.content_format
290 }
291
292 fn accept(&self) -> Option<ContentFormat> {
293 self.accept
294 }
295
296 fn block2(&self) -> Option<BlockInfo> {
297 self.block2
298 }
299
300 fn block1(&self) -> Option<BlockInfo> {
301 self.block1
302 }
303
304 fn options(&self) -> OptionIterator<'_> {
305 OptionIterator::new(&self.buffer[4 + self.token.len()..])
306 }
307}