1use super::codec::*;
17use super::*;
18
19#[derive(Debug)]
21pub struct BufferMessageEncoder<'buf> {
22 buffer: &'buf mut [u8],
23 len: usize,
24 option_start: usize,
25 payload_start: usize,
26 last_option: OptionNumber,
27}
28
29impl<'buf> BufferMessageEncoder<'buf> {
30 pub const MIN_MESSAGE_BUFFER_LEN: usize = 12;
32
33 pub fn new(buffer: &'buf mut [u8]) -> BufferMessageEncoder<'buf> {
35 if buffer.len() < BufferMessageEncoder::MIN_MESSAGE_BUFFER_LEN {
36 panic!("Buffer too small");
37 }
38
39 buffer[0] = 0b01000000;
41
42 BufferMessageEncoder {
43 buffer,
44 len: 4,
45 option_start: 4,
46 payload_start: 4,
47 last_option: Default::default(),
48 }
49 }
50
51 pub fn as_bytes(&self) -> &[u8] {
53 &self.buffer[..self.len]
54 }
55
56 pub fn msg_token(&self) -> MsgToken {
58 let token_len = (self.buffer[0] & COAP_MSG_TKL_MASK) as usize;
59 MsgToken::new(&self.buffer[4..4 + token_len])
60 }
61}
62
63impl<'buf> std::fmt::Display for BufferMessageEncoder<'buf> {
64 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65 CoapByteDisplayFormatter(self.as_bytes()).fmt(f)
66 }
67}
68
69impl<'buf> core::ops::Deref for BufferMessageEncoder<'buf> {
70 type Target = [u8];
71
72 fn deref(&self) -> &Self::Target {
73 self.as_bytes()
74 }
75}
76
77impl<'buf> MessageWrite for BufferMessageEncoder<'buf> {
78 fn set_msg_type(&mut self, tt: MsgType) {
79 self.buffer[0] = (self.buffer[0] & !COAP_MSG_T_MASK) | ((tt as u8) << COAP_MSG_T_OFFS);
80 }
81
82 fn set_msg_id(&mut self, msg_id: u16) {
83 self.buffer[2] = (msg_id >> 8) as u8;
84 self.buffer[3] = (msg_id >> 0) as u8;
85 }
86
87 fn set_msg_code(&mut self, code: MsgCode) {
88 self.buffer[1] = code as u8;
89 }
90
91 fn set_msg_token(&mut self, token: MsgToken) {
92 if self.option_start != 4 + token.len() {
93 self.len = 4 + token.len();
94 self.option_start = self.len;
95 self.payload_start = self.option_start;
96
97 self.buffer[0] = (self.buffer[0] & !COAP_MSG_TKL_MASK) | token.len() as u8;
98 }
99
100 self.buffer[4..4 + token.len()].copy_from_slice(token.as_bytes());
101 }
102
103 fn append_payload_bytes(&mut self, body: &[u8]) -> Result<(), Error> {
104 if self.len == self.payload_start {
105 if self.payload_start >= self.buffer.len() {
106 return Err(Error::OutOfSpace);
107 }
108 self.buffer[self.payload_start] = 0xFF;
110 self.len += 1;
111 }
112
113 let new_body_end = self.len + body.len();
114
115 if new_body_end > self.buffer.len() {
116 return Err(Error::OutOfSpace);
117 }
118
119 self.buffer[self.len..new_body_end].copy_from_slice(body);
120 self.len = new_body_end;
121
122 Ok(())
123 }
124
125 fn clear(&mut self) {
126 self.buffer[0] = 0b01000000;
127 self.len = 4;
128 self.option_start = 4;
129 self.payload_start = 4;
130 self.last_option = Default::default();
131 }
132}
133
134impl<'buf> OptionInsert for BufferMessageEncoder<'buf> {
135 fn insert_option_with_bytes(&mut self, key: OptionNumber, value: &[u8]) -> Result<(), Error> {
136 if self.last_option == key && !key.is_repeatable() {
137 panic!("Option {} is not repeatable", key);
138 }
140 let option_start = self.option_start;
141 let (mut len, last_option) = insert_option(
142 &mut self.buffer[option_start..],
143 self.len - option_start,
144 self.last_option,
145 key,
146 value,
147 )?;
148
149 len += option_start;
150 self.last_option = last_option;
151 self.len = len;
152 self.payload_start = len;
153
154 Ok(())
155 }
156}
157
158#[derive(Debug)]
160pub struct VecMessageEncoder {
161 buffer: Vec<u8>,
162 option_start: usize,
163 payload_start: usize,
164 last_option: OptionNumber,
165}
166
167impl VecMessageEncoder {
168 pub fn new() -> VecMessageEncoder {
170 Self::with_payload_capacity(16)
171 }
172
173 pub fn with_payload_capacity(capacity: usize) -> VecMessageEncoder {
175 let mut buffer = Vec::with_capacity(16 + capacity);
176
177 buffer.push(0b01000000);
179 buffer.resize(4, 0);
180
181 VecMessageEncoder {
182 buffer,
183 option_start: 4,
184 payload_start: 4,
185 last_option: Default::default(),
186 }
187 }
188
189 pub fn as_bytes(&self) -> &[u8] {
191 &self.buffer
192 }
193
194 pub fn msg_token(&self) -> MsgToken {
196 let token_len = (self.buffer[0] & COAP_MSG_TKL_MASK) as usize;
197 MsgToken::new(&self.buffer[4..4 + token_len])
198 }
199}
200
201impl std::convert::From<VecMessageEncoder> for Vec<u8> {
202 fn from(x: VecMessageEncoder) -> Self {
203 x.buffer
204 }
205}
206
207impl std::convert::From<VecMessageEncoder> for OwnedImmutableMessage {
208 fn from(x: VecMessageEncoder) -> Self {
209 OwnedImmutableMessage::new(x.buffer).expect("Encoding corrupt")
210 }
211}
212
213impl Default for VecMessageEncoder {
214 fn default() -> Self {
215 Self::new()
216 }
217}
218
219impl std::fmt::Display for VecMessageEncoder {
220 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
221 CoapByteDisplayFormatter(self.as_bytes()).fmt(f)
222 }
223}
224
225impl core::ops::Deref for VecMessageEncoder {
226 type Target = [u8];
227
228 fn deref(&self) -> &Self::Target {
229 self.as_bytes()
230 }
231}
232
233impl MessageWrite for VecMessageEncoder {
234 fn set_msg_type(&mut self, tt: MsgType) {
235 self.buffer[0] = (self.buffer[0] & !COAP_MSG_T_MASK) | ((tt as u8) << COAP_MSG_T_OFFS);
236 }
237
238 fn set_msg_id(&mut self, msg_id: u16) {
239 self.buffer[2] = (msg_id >> 8) as u8;
240 self.buffer[3] = (msg_id >> 0) as u8;
241 }
242
243 fn set_msg_code(&mut self, code: MsgCode) {
244 self.buffer[1] = code as u8;
245 }
246
247 fn set_msg_token(&mut self, token: MsgToken) {
248 if self.option_start != 4 + token.len() {
249 self.buffer.resize(4 + token.len(), 0);
250 self.option_start = self.buffer.len();
251 self.payload_start = self.option_start;
252
253 self.buffer[0] = (self.buffer[0] & !COAP_MSG_TKL_MASK) | token.len() as u8;
254 }
255 self.buffer[4..4 + token.len()].copy_from_slice(token.as_bytes());
256 }
257
258 fn append_payload_bytes(&mut self, body: &[u8]) -> Result<(), Error> {
259 if self.buffer.len() == self.payload_start {
260 self.buffer.push(0xFF);
262 }
263 self.buffer.extend_from_slice(body);
264 Ok(())
265 }
266
267 fn clear(&mut self) {
268 self.buffer[0] = 0b01000000;
269 self.buffer.resize(4, 0);
270 self.option_start = 4;
271 self.payload_start = 4;
272 self.last_option = Default::default();
273 }
274}
275
276impl OptionInsert for VecMessageEncoder {
277 fn insert_option_with_bytes(&mut self, key: OptionNumber, value: &[u8]) -> Result<(), Error> {
278 if self.last_option == key && !key.is_repeatable() {
279 return Err(Error::OptionNotRepeatable);
280 }
281
282 let option_start = self.option_start;
283
284 let workspace = value.len() + 5;
285
286 let len = self.buffer.len();
287 self.buffer.resize(self.buffer.len() + workspace, 0);
288
289 let (mut len, last_option) = insert_option(
290 &mut self.buffer[option_start..],
291 len - option_start,
292 self.last_option,
293 key,
294 value,
295 )?;
296
297 len += option_start;
298 self.buffer.truncate(len);
299 self.last_option = last_option;
300 self.payload_start = len;
301
302 Ok(())
303 }
304}
305
306#[cfg(test)]
307mod tests {
308 use super::*;
309 use crate::option::*;
310
311 #[test]
312 fn message_builder_rfc7252_fig_16() {
313 let buffer = &mut [0u8; 200];
314
315 let mut builder = BufferMessageEncoder::new(buffer);
316 builder.set_msg_type(MsgType::Con);
317 builder.set_msg_code(MsgCode::MethodGet);
318 builder.set_msg_id(0x7d34);
319 assert_eq!(Ok(()), builder.insert_option(URI_PATH, "temperature"));
320 let packet_calc: &[u8] = &builder;
321 let packet_real = &[
322 0b01000000, 1, 0x7d, 0x34, 0xbb, b't', b'e', b'm', b'p', b'e', b'r', b'a', b't', b'u',
323 b'r', b'e',
324 ];
325 println!("request: {:#x?}", packet_calc);
326 assert_eq!(packet_real, packet_calc);
327
328 let parser = StandardMessageParser::new(packet_real).unwrap();
329 assert_eq!(MsgType::Con, parser.msg_type());
330 assert_eq!(MsgCode::MethodGet, parser.msg_code());
331 assert_eq!(0x7d34, parser.msg_id());
332 assert_eq!(MsgToken::EMPTY, parser.msg_token());
333 assert_eq!(None, parser.content_format());
334 assert_eq!(None, parser.accept());
335 assert!(parser.payload().is_empty());
336 let mut iter = parser.options();
337 assert_eq!(
338 Some(Ok((OptionNumber::URI_PATH, &b"temperature"[..]))),
339 iter.next()
340 );
341 assert_eq!(None, iter.next());
342
343 let mut builder = BufferMessageEncoder::new(buffer);
344 builder.set_msg_type(MsgType::Ack);
345 builder.set_msg_code(MsgCode::SuccessContent);
346 builder.set_msg_id(0x7d34);
347 assert_eq!(Ok(()), builder.append_payload_string(r#"22.3 C"#));
348 let packet_calc: &[u8] = &builder;
349 let packet_real = &[
350 0b01100000, 69, 0x7d, 0x34, 0xff, b'2', b'2', b'.', b'3', b' ', b'C',
351 ];
352 println!("response: {:#x?}", packet_calc);
353 assert_eq!(packet_real, packet_calc);
354 }
355
356 #[test]
357 fn message_builder_rfc7252_fig_17() {
358 let buffer = &mut [0u8; 200];
359
360 let mut builder = BufferMessageEncoder::new(buffer);
361 builder.set_msg_type(MsgType::Con);
362 builder.set_msg_code(MsgCode::MethodGet);
363 builder.set_msg_id(0x7d34);
364 builder.set_msg_token(MsgToken::from(0x20));
365 assert_eq!(Ok(()), builder.insert_option(URI_PATH, "temperature"));
366 let packet_calc: &[u8] = &builder;
367 let packet_real = &[
368 0b01000001, 1, 0x7d, 0x34, 0x20, 0xbb, b't', b'e', b'm', b'p', b'e', b'r', b'a', b't',
369 b'u', b'r', b'e',
370 ];
371 println!("request: {:#x?}", packet_calc);
372 assert_eq!(packet_real, packet_calc);
373
374 let mut builder = BufferMessageEncoder::new(buffer);
375 builder.set_msg_type(MsgType::Ack);
376 builder.set_msg_code(MsgCode::SuccessContent);
377 builder.set_msg_id(0x7d34);
378 builder.set_msg_token(MsgToken::from(0x20));
379 assert_eq!(Ok(()), builder.append_payload_string(r#"22.3 C"#));
380 let packet_calc: &[u8] = &builder;
381 let packet_real = &[
382 0b01100001, 69, 0x7d, 0x34, 0x20, 0xff, b'2', b'2', b'.', b'3', b' ', b'C',
383 ];
384 println!("response: {:#x?}", packet_calc);
385 assert_eq!(packet_real, packet_calc);
386 }
387
388 #[test]
389 fn message_builder_append_body() {
390 let buffer = &mut [0u8; 200];
391
392 let mut builder = BufferMessageEncoder::new(buffer);
393 builder.set_msg_type(MsgType::Ack);
394 builder.set_msg_code(MsgCode::SuccessContent);
395 builder.set_msg_id(0x7d34);
396 builder.set_msg_token(MsgToken::from(0x20));
397 assert_eq!(Ok(()), builder.append_payload_string(r#"22."#));
398 assert_eq!(Ok(()), builder.append_payload_string(r#"3 C"#));
399 let packet_calc: &[u8] = &builder;
400 let packet_real = &[
401 0b01100001, 69, 0x7d, 0x34, 0x20, 0xff, b'2', b'2', b'.', b'3', b' ', b'C',
402 ];
403 println!("response: {:#x?}", packet_calc);
404 assert_eq!(packet_real, packet_calc);
405 }
406
407 #[test]
408 fn message_builder_misc() {
409 let buffer = &mut [0u8; 200];
410 let mut builder = BufferMessageEncoder::new(buffer);
411 builder.set_msg_type(MsgType::Con);
412 builder.set_msg_code(MsgCode::MethodPost);
413 builder.set_msg_id(0x7d34);
414 builder.set_msg_token(MsgToken::from(0x2021));
415 assert_eq!(
416 Ok(()),
417 builder.insert_option(CONTENT_FORMAT, ContentFormat::TEXT_PLAIN_UTF8)
418 );
419 assert_eq!(Ok(()), builder.insert_option(URI_PATH, "temp"));
420 assert_eq!(Ok(()), builder.append_payload_string(r#"22."#));
421 assert_eq!(Ok(()), builder.append_payload_string(r#"3 C"#));
422 let packet_calc: &[u8] = &builder;
423 let packet_real = &[
424 0b01000010, 2, 0x7d, 0x34, 0x20, 0x21, 0xb4, b't', b'e', b'm', b'p', 0x10, 0xff, b'2',
425 b'2', b'.', b'3', b' ', b'C',
426 ];
427 println!("response: {:#x?}", packet_calc);
428 assert_eq!(packet_real, packet_calc);
429
430 let parser = StandardMessageParser::new(packet_real).unwrap();
431
432 assert_eq!(MsgType::Con, parser.msg_type());
433 assert_eq!(MsgCode::MethodPost, parser.msg_code());
434 assert_eq!(0x7d34, parser.msg_id());
435 assert_eq!(MsgToken::from(0x2021), parser.msg_token());
436
437 assert_eq!(
438 Some(ContentFormat::TEXT_PLAIN_UTF8),
439 parser.content_format()
440 );
441 assert_eq!(None, parser.accept());
442 assert_eq!(b"22.3 C", parser.payload());
443
444 let mut iter = parser.options();
445 assert_eq!(
446 Some(Ok((OptionNumber::URI_PATH, &b"temp"[..]))),
447 iter.next()
448 );
449 assert_eq!(
450 Some(Ok((OptionNumber::CONTENT_FORMAT, &b""[..]))),
451 iter.next()
452 );
453 assert_eq!(None, iter.next());
454
455 let mut iter = parser.options();
456 assert_eq!(Some(Ok("temp")), iter.find_next_of(URI_PATH));
457 assert_eq!(None, iter.find_next_of(URI_PATH));
458 assert_eq!(
459 Some(Ok(ContentFormat::TEXT_PLAIN_UTF8)),
460 iter.find_next_of(CONTENT_FORMAT)
461 );
462 assert_eq!(None, iter.next());
463 }
464
465 #[test]
466 fn vec_message_builder_misc() {
467 let mut builder = VecMessageEncoder::new();
468 builder.set_msg_type(MsgType::Con);
469 builder.set_msg_code(MsgCode::MethodPost);
470 builder.set_msg_id(0x7d34);
471 builder.set_msg_token(MsgToken::from(0x2021));
472 assert_eq!(
473 Ok(()),
474 builder.insert_option(CONTENT_FORMAT, ContentFormat::TEXT_PLAIN_UTF8)
475 );
476 assert_eq!(Ok(()), builder.insert_option(URI_PATH, "temp"));
477 assert_eq!(Ok(()), builder.append_payload_string(r#"22."#));
478 assert_eq!(Ok(()), builder.append_payload_string(r#"3 C"#));
479 let packet_calc: &[u8] = &builder;
480 let packet_real = &[
481 0b01000010, 2, 0x7d, 0x34, 0x20, 0x21, 0xb4, b't', b'e', b'm', b'p', 0x10, 0xff, b'2',
482 b'2', b'.', b'3', b' ', b'C',
483 ];
484 println!("response: {:#x?}", packet_calc);
485 assert_eq!(packet_real, packet_calc);
486
487 let parser = StandardMessageParser::new(packet_real).unwrap();
488
489 assert_eq!(MsgType::Con, parser.msg_type());
490 assert_eq!(MsgCode::MethodPost, parser.msg_code());
491 assert_eq!(0x7d34, parser.msg_id());
492 assert_eq!(MsgToken::from(0x2021), parser.msg_token());
493
494 assert_eq!(
495 Some(ContentFormat::TEXT_PLAIN_UTF8),
496 parser.content_format()
497 );
498 assert_eq!(None, parser.accept());
499 assert_eq!(b"22.3 C", parser.payload());
500
501 let mut iter = parser.options();
502 assert_eq!(
503 Some(Ok((OptionNumber::URI_PATH, &b"temp"[..]))),
504 iter.next()
505 );
506 assert_eq!(
507 Some(Ok((OptionNumber::CONTENT_FORMAT, &b""[..]))),
508 iter.next()
509 );
510 assert_eq!(None, iter.next());
511
512 let mut iter = parser.options();
513 assert_eq!(Some(Ok("temp")), iter.find_next_of(URI_PATH));
514 assert_eq!(None, iter.find_next_of(URI_PATH));
515 assert_eq!(
516 Some(Ok(ContentFormat::TEXT_PLAIN_UTF8)),
517 iter.find_next_of(CONTENT_FORMAT)
518 );
519 assert_eq!(None, iter.next());
520 }
521
522 #[test]
523 fn message_builder_reset() {
524 let buffer = &mut [0u8; 200];
525 let mut builder = BufferMessageEncoder::new(buffer);
526 builder.set_msg_type(MsgType::Con);
527 builder.set_msg_code(MsgCode::Empty);
528 builder.set_msg_id(0x0000);
529 builder.set_msg_token(MsgToken::EMPTY);
530 let packet_calc: &[u8] = &builder;
531 let packet_real = &[0b01000000, 0, 0x00, 0x00];
532 println!("response: {:#x?}", packet_calc);
533 assert_eq!(packet_real, packet_calc);
534
535 let parser = StandardMessageParser::new(packet_real).unwrap();
536
537 assert_eq!(MsgType::Con, parser.msg_type());
538 assert_eq!(MsgCode::Empty, parser.msg_code());
539 assert_eq!(0x0, parser.msg_id());
540 assert_eq!(MsgToken::EMPTY, parser.msg_token());
541
542 assert_eq!(None, parser.content_format());
543 assert_eq!(None, parser.accept());
544 assert_eq!(b"", parser.payload());
545 }
546}