1use bitflags::bitflags;
6use core::fmt::Debug;
7use packet_encoding::{decodable_enum, Decodable, Encodable};
8use std::cmp::PartialEq;
9
10use crate::error::{Error, PacketError};
11use crate::header::{HeaderIdentifier, HeaderSet};
12
13const OBEX_PROTOCOL_VERSION_NUMBER: u8 = 0x10;
17
18pub const MAX_PACKET_SIZE: usize = std::u16::MAX as usize;
22
23pub const MIN_MAX_PACKET_SIZE: usize = 255;
26
27bitflags! {
28 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
31 pub struct SetPathFlags: u8 {
32 const BACKUP = 0b0000_0001;
34 const DONT_CREATE = 0b0000_0010;
36 }
37}
38
39#[derive(Debug, Clone, Copy, PartialEq)]
40#[repr(u8)]
41pub enum OpCode {
42 Connect = 0x80,
43 Disconnect = 0x81,
44 Put = 0x02,
45 PutFinal = 0x82,
46 Get = 0x03,
47 GetFinal = 0x83,
48 Reserved = 0x04,
49 ReservedFinal = 0x84,
50 SetPath = 0x85,
51 Action = 0x06,
52 ActionFinal = 0x86,
53 Session = 0x87,
54 User(u8),
57 Abort = 0xff,
58}
59
60impl OpCode {
61 fn final_bit_set(v: u8) -> bool {
62 (v & 0x80) != 0
63 }
64
65 fn is_user(code: u8) -> bool {
66 code >= 0x10 && code <= 0x1f
68 }
69
70 fn is_reserved(code: u8) -> bool {
71 code >= 0x08 && code <= 0x0f
73 }
74
75 pub fn is_final(&self) -> bool {
77 let opcode_raw: u8 = self.into();
78 Self::final_bit_set(opcode_raw)
79 }
80
81 fn request_data_length(&self) -> usize {
86 match &self {
87 Self::Connect => 4, Self::SetPath => 2, _ => 0, }
91 }
92
93 pub fn response_data_length(&self) -> usize {
98 match &self {
99 Self::Connect => 4, _ => 0, }
102 }
103}
104
105impl Into<u8> for &OpCode {
106 fn into(self) -> u8 {
107 match &self {
108 OpCode::Connect => 0x80,
109 OpCode::Disconnect => 0x81,
110 OpCode::Put => 0x02,
111 OpCode::PutFinal => 0x82,
112 OpCode::Get => 0x03,
113 OpCode::GetFinal => 0x83,
114 OpCode::Reserved => 0x04,
115 OpCode::ReservedFinal => 0x84,
116 OpCode::SetPath => 0x85,
117 OpCode::Action => 0x06,
118 OpCode::ActionFinal => 0x86,
119 OpCode::Session => 0x87,
120 OpCode::User(v) => *v,
121 OpCode::Abort => 0xff,
122 }
123 }
124}
125
126impl TryFrom<u8> for OpCode {
127 type Error = PacketError;
128
129 fn try_from(src: u8) -> Result<OpCode, Self::Error> {
130 if src == 0xff {
132 return Ok(OpCode::Abort);
133 }
134
135 const FINAL_BIT_AND_OPCODE_BITMASK: u8 = 0x9f;
138 const OPCODE_BITMASK: u8 = 0x1f;
139 let src = src & FINAL_BIT_AND_OPCODE_BITMASK;
140 let is_final = OpCode::final_bit_set(src);
141 match src & OPCODE_BITMASK {
143 0x00 if is_final => Ok(OpCode::Connect),
144 0x01 if is_final => Ok(OpCode::Disconnect),
145 0x02 if is_final => Ok(OpCode::PutFinal),
146 0x02 => Ok(OpCode::Put),
147 0x03 if is_final => Ok(OpCode::GetFinal),
148 0x03 => Ok(OpCode::Get),
149 0x04 if is_final => Ok(OpCode::ReservedFinal),
150 0x04 => Ok(OpCode::Reserved),
151 0x05 if is_final => Ok(OpCode::SetPath),
152 0x06 if is_final => Ok(OpCode::ActionFinal),
153 0x06 => Ok(OpCode::Action),
154 0x07 if is_final => Ok(OpCode::Session),
155 v if OpCode::is_user(v) => Ok(OpCode::User(src)), v if OpCode::is_reserved(v) => Err(PacketError::Reserved),
157 _ => Err(PacketError::OpCode(src)),
158 }
159 }
160}
161
162#[derive(Clone, Debug, PartialEq)]
165pub struct Packet<T>
166where
167 T: Clone + Debug + PartialEq,
168 for<'a> &'a T: Into<u8>,
169{
170 code: T,
172 data: Vec<u8>,
175 headers: HeaderSet,
177}
178
179impl<T> Packet<T>
180where
181 T: Clone + Debug + PartialEq,
182 for<'a> &'a T: Into<u8>,
183{
184 pub const MIN_PACKET_SIZE: usize = 3;
186
187 pub fn new(code: T, data: Vec<u8>, headers: HeaderSet) -> Self {
188 Self { code, data, headers }
189 }
190
191 pub fn code(&self) -> &T {
192 &self.code
193 }
194
195 pub fn data(&self) -> &Vec<u8> {
196 &self.data
197 }
198
199 pub fn headers(&self) -> &HeaderSet {
200 &self.headers
201 }
202
203 fn decode_body(buf: &[u8], code: T, optional_data_length: usize) -> Result<Self, PacketError> {
206 let (headers_idx, data) = if optional_data_length != 0 {
208 if buf.len() < optional_data_length {
209 return Err(PacketError::BufferTooSmall);
210 }
211 let mut data = vec![0u8; optional_data_length];
212 data.copy_from_slice(&buf[..optional_data_length]);
213 (optional_data_length, data)
214 } else {
215 (0, vec![])
216 };
217
218 let headers = HeaderSet::decode(&buf[headers_idx..])?;
220 Ok(Self::new(code, data, headers))
221 }
222}
223
224impl<T> Encodable for Packet<T>
225where
226 T: Clone + Debug + PartialEq,
227 for<'a> &'a T: Into<u8>,
228{
229 type Error = PacketError;
230
231 fn encoded_len(&self) -> usize {
232 Self::MIN_PACKET_SIZE + self.data.len() + self.headers.encoded_len()
233 }
234
235 fn encode(&self, buf: &mut [u8]) -> Result<(), Self::Error> {
236 if buf.len() < self.encoded_len() {
237 return Err(PacketError::BufferTooSmall);
238 }
239
240 buf[0] = (&self.code).into();
243 let packet_length_bytes = (self.encoded_len() as u16).to_be_bytes();
244 buf[1..Self::MIN_PACKET_SIZE].copy_from_slice(&packet_length_bytes[..]);
245
246 let headers_idx = if self.data.len() != 0 {
248 let end_idx = Self::MIN_PACKET_SIZE + self.data.len();
249 buf[Self::MIN_PACKET_SIZE..end_idx].copy_from_slice(&self.data[..]);
250 end_idx
251 } else {
252 Self::MIN_PACKET_SIZE
253 };
254
255 self.headers.encode(&mut buf[headers_idx..])
257 }
258}
259
260impl<T> From<Packet<T>> for HeaderSet
261where
262 T: Clone + Debug + PartialEq,
263 for<'a> &'a T: Into<u8>,
264{
265 fn from(value: Packet<T>) -> Self {
266 value.headers
267 }
268}
269
270pub type RequestPacket = Packet<OpCode>;
273
274impl RequestPacket {
275 pub fn new_connect(max_packet_size: u16, headers: HeaderSet) -> Self {
277 let mut data = vec![
279 OBEX_PROTOCOL_VERSION_NUMBER,
280 0, ];
282 data.extend_from_slice(&max_packet_size.to_be_bytes());
283 Self::new(OpCode::Connect, data, headers)
284 }
285
286 pub fn new_disconnect(headers: HeaderSet) -> Self {
287 Self::new(OpCode::Disconnect, vec![], headers)
288 }
289
290 pub fn new_get(headers: HeaderSet) -> Self {
291 Self::new(OpCode::Get, vec![], headers)
292 }
293
294 pub fn new_get_final(headers: HeaderSet) -> Self {
295 Self::new(OpCode::GetFinal, vec![], headers)
296 }
297
298 pub fn new_put(headers: HeaderSet) -> Self {
299 Self::new(OpCode::Put, vec![], headers)
300 }
301
302 pub fn new_put_final(headers: HeaderSet) -> Self {
303 Self::new(OpCode::PutFinal, vec![], headers)
304 }
305
306 pub fn new_set_path(flags: SetPathFlags, headers: HeaderSet) -> Result<Self, Error> {
307 if !headers.contains_header(&HeaderIdentifier::Name)
311 && !flags.contains(SetPathFlags::BACKUP)
312 {
313 return Err(Error::operation(OpCode::SetPath, "name is required"));
314 }
315 let data = vec![flags.bits(), 0];
318 Ok(Self::new(OpCode::SetPath, data, headers))
319 }
320
321 pub fn new_abort(headers: HeaderSet) -> Self {
322 Self::new(OpCode::Abort, vec![], headers)
323 }
324}
325
326impl Decodable for RequestPacket {
327 type Error = PacketError;
328
329 fn decode(buf: &[u8]) -> Result<Self, Self::Error> {
330 if buf.len() < Self::MIN_PACKET_SIZE {
331 return Err(PacketError::BufferTooSmall);
332 }
333
334 let code = OpCode::try_from(buf[0])?;
335 let packet_length =
336 u16::from_be_bytes(buf[1..Self::MIN_PACKET_SIZE].try_into().expect("checked length"));
337
338 if buf.len() < packet_length.into() {
339 return Err(PacketError::BufferTooSmall);
340 }
341 Self::decode_body(&buf[Self::MIN_PACKET_SIZE..], code, code.request_data_length())
343 }
344}
345
346decodable_enum! {
347 pub enum ResponseCode<u8, PacketError, Reserved> {
352 Continue = 0x90,
353 Ok = 0xa0,
354 Created = 0xa1,
355 Accepted = 0xa2,
356 NonAuthoritativeInformation = 0xa3,
357 NoContent = 0xa4,
358 ResetContent = 0xa5,
359 PartialContent = 0xa6,
360 MultipleChoices = 0xb0,
361 MovedPermanently = 0xb1,
362 MovedTemporarily = 0xb2,
363 SeeOther = 0xb3,
364 NotModified = 0xb4,
365 UseProxy = 0xb5,
366 BadRequest = 0xc0,
367 Unauthorized = 0xc1,
368 PaymentRequired = 0xc2,
369 Forbidden = 0xc3,
370 NotFound = 0xc4,
371 MethodNotAllowed = 0xc5,
372 NotAcceptable = 0xc6,
373 ProxyAuthenticationRequired = 0xc7,
374 RequestTimeOut = 0xc8,
375 Conflict = 0xc9,
376 Gone = 0xca,
377 LengthRequired = 0xcb,
378 PreconditionFailed = 0xcc,
379 RequestedEntityTooLarge = 0xcd,
380 RequestedUrlTooLarge = 0xce,
381 UnsupportedMediaType = 0xcf,
382 InternalServerError = 0xd0,
383 NotImplemented = 0xd1,
384 BadGateway = 0xd2,
385 ServiceUnavailable = 0xd3,
386 GatewayTimeout = 0xd4,
387 HttpVersionNotSupported = 0xd5,
388 DatabaseFull = 0xe0,
389 DatabaseLocked = 0xe1,
390 }
391}
392
393pub type ResponsePacket = Packet<ResponseCode>;
396
397impl ResponsePacket {
398 pub fn new_no_data(code: ResponseCode, headers: HeaderSet) -> Self {
399 Self::new(code, vec![], headers)
400 }
401
402 pub fn new_connect(code: ResponseCode, max_packet_size: u16, headers: HeaderSet) -> Self {
403 const OBEX_CONNECT_RESPONSE_FLAGS: u8 = 0;
408 let mut data = vec![OBEX_PROTOCOL_VERSION_NUMBER, OBEX_CONNECT_RESPONSE_FLAGS];
409 data.extend_from_slice(&max_packet_size.to_be_bytes());
410 Self::new(code, data, headers)
411 }
412
413 pub fn new_disconnect(headers: HeaderSet) -> Self {
414 Self::new(ResponseCode::Ok, vec![], headers)
415 }
416
417 pub fn new_setpath(code: ResponseCode, headers: HeaderSet) -> Self {
418 Self::new(code, vec![], headers)
419 }
420
421 pub fn new_get(code: ResponseCode, headers: HeaderSet) -> Self {
422 Self::new(code, vec![], headers)
423 }
424
425 pub fn expect_code(self, request: OpCode, expected: ResponseCode) -> Result<Self, Error> {
426 if *self.code() == expected {
427 return Ok(self);
428 }
429 Err(Error::peer_rejected(request, *self.code()))
430 }
431
432 pub fn decode(buf: &[u8], request: OpCode) -> Result<Self, PacketError> {
437 if buf.len() < Self::MIN_PACKET_SIZE {
438 return Err(PacketError::BufferTooSmall);
439 }
440
441 let code = ResponseCode::try_from(buf[0]).map_err(|_| PacketError::ResponseCode(buf[0]))?;
442 let packet_length =
443 u16::from_be_bytes(buf[1..Self::MIN_PACKET_SIZE].try_into().expect("checked length"));
444
445 if buf.len() < packet_length.into() {
446 return Err(PacketError::BufferTooSmall);
447 }
448 Self::decode_body(&buf[Self::MIN_PACKET_SIZE..], code, request.response_data_length())
450 }
451}
452
453#[cfg(test)]
454mod tests {
455 use super::*;
456
457 use assert_matches::assert_matches;
458
459 use crate::header::{ConnectionIdentifier, Header};
460
461 #[fuchsia::test]
462 fn convert_opcode_success() {
463 let raw = 0x02;
465 let converted = OpCode::try_from(raw).expect("valid opcode");
466 assert_eq!(converted, OpCode::Put);
467 assert!(!converted.is_final());
468 assert_eq!(converted.request_data_length(), 0);
469 assert_eq!(converted.response_data_length(), 0);
470 let converted_raw: u8 = (&converted).into();
471 assert_eq!(converted_raw, raw);
472
473 let raw = 0x84;
475 let converted = OpCode::try_from(raw).expect("valid opcode");
476 assert_eq!(converted, OpCode::ReservedFinal);
477 assert!(converted.is_final());
478 let converted_raw: u8 = (&converted).into();
479 assert_eq!(converted_raw, raw);
480
481 let raw = 0xff;
483 let converted = OpCode::try_from(raw).expect("valid opcode");
484 assert_eq!(converted, OpCode::Abort);
485 assert!(converted.is_final());
486 let converted_raw: u8 = (&converted).into();
487 assert_eq!(converted_raw, raw);
488
489 let raw = 0xe5; let converted = OpCode::try_from(raw).expect("valid opcode");
493 assert_eq!(converted, OpCode::SetPath);
494 assert!(converted.is_final());
495 let converted_raw: u8 = (&converted).into();
496 assert_eq!(converted_raw, 0x85); }
498
499 #[fuchsia::test]
500 fn convert_user_opcode_success() {
501 let user = 0x1a;
503 let converted = OpCode::try_from(user).expect("valid opcode");
504 assert_eq!(converted, OpCode::User(0x1a));
505 assert!(!converted.is_final());
506 let converted_raw: u8 = (&converted).into();
507 assert_eq!(converted_raw, user);
508
509 let user = 0x9d;
511 let converted = OpCode::try_from(user).expect("valid opcode");
512 assert_eq!(converted, OpCode::User(0x9d));
513 assert!(converted.is_final());
514 let converted_raw: u8 = (&converted).into();
515 assert_eq!(converted_raw, user);
517
518 let user = 0xf3;
520 let converted = OpCode::try_from(user).expect("valid opcode");
521 assert_eq!(converted, OpCode::User(0x93)); assert!(converted.is_final());
523 let converted_raw: u8 = (&converted).into();
524 assert_eq!(converted_raw, 0x93);
525 }
526
527 #[fuchsia::test]
528 fn convert_invalid_opcode_is_error() {
529 let invalid = 0x01;
531 assert_matches!(OpCode::try_from(invalid), Err(PacketError::OpCode(_)));
532 let reserved = 0x08;
534 assert_matches!(OpCode::try_from(reserved), Err(PacketError::Reserved));
535 let reserved = 0x8f;
537 assert_matches!(OpCode::try_from(reserved), Err(PacketError::Reserved));
538 }
539
540 #[fuchsia::test]
541 fn construct_setpath() {
542 let headers = HeaderSet::from_header(Header::name("foo"));
544 let _request = RequestPacket::new_set_path(SetPathFlags::all(), headers.clone())
545 .expect("valid set path args");
546
547 let _request = RequestPacket::new_set_path(SetPathFlags::empty(), headers)
549 .expect("valid set path args");
550
551 let _request = RequestPacket::new_set_path(SetPathFlags::BACKUP, HeaderSet::new())
553 .expect("valid set path args");
554
555 assert_matches!(
557 RequestPacket::new_set_path(SetPathFlags::DONT_CREATE, HeaderSet::new()),
558 Err(Error::OperationError { .. })
559 );
560 }
561
562 #[fuchsia::test]
563 fn encode_request_packet_success() {
564 let headers = HeaderSet::from_headers(vec![Header::Permissions(2)]).unwrap();
565 let request = RequestPacket::new(OpCode::Abort, vec![], headers);
566 assert_eq!(request.encoded_len(), 8);
568 let mut buf = vec![0; request.encoded_len()];
569 request.encode(&mut buf[..]).expect("can encode request");
570 let expected = [0xff, 0x00, 0x08, 0xd6, 0x00, 0x00, 0x00, 0x02];
571 assert_eq!(buf, expected);
572 }
573
574 #[fuchsia::test]
575 fn encode_request_packet_no_headers_success() {
576 let request = RequestPacket::new(OpCode::Abort, vec![], HeaderSet::new());
578 assert_eq!(request.encoded_len(), 3);
579 let mut buf = vec![0; request.encoded_len()];
580 request.encode(&mut buf[..]).expect("can encode request");
581 let expected = [0xff, 0x00, 0x03];
582 assert_eq!(buf, expected);
583 }
584
585 #[fuchsia::test]
586 fn decode_request_packet_success() {
587 let request_buf = [
588 0x81, 0x00, 0x0e, 0x01, 0x00, 0xb, 0x00, 0x66, 0x00, 0x75, 0x00, 0x6e, 0x00, 0x00, ];
592 let decoded = RequestPacket::decode(&request_buf[..]).expect("valid request");
593 let expected_headers = HeaderSet::from_headers(vec![Header::name("fun")]).unwrap();
594 let expected = RequestPacket::new(OpCode::Disconnect, vec![], expected_headers);
595 assert_eq!(decoded, expected);
596 }
597
598 #[fuchsia::test]
600 fn encode_connect_request_packet_success() {
601 let headers =
602 HeaderSet::from_headers(vec![Header::Count(4), Header::Length(0xf483)]).unwrap();
603 let request = RequestPacket::new_connect(0x2000, headers);
604 assert_eq!(request.encoded_len(), 17);
605 let mut buf = vec![0; request.encoded_len()];
606 request.encode(&mut buf[..]).expect("can encode request");
607 let expected = [
608 0x80, 0x00, 0x11, 0x10, 0x00, 0x20, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x04, 0xc3, 0x00, 0x00, 0xf4, 0x83, ];
614 assert_eq!(buf, expected);
615 }
616
617 #[fuchsia::test]
618 fn decode_connect_request_packet_success() {
619 let request_buf = [
622 0x80, 0x00, 0x0c, 0x10, 0x00, 0xff, 0xff, 0xc0, 0x00, 0x00, 0xff, 0xff, ];
627 let decoded = RequestPacket::decode(&request_buf[..]).expect("valid request");
628 let expected_headers = HeaderSet::from_headers(vec![Header::Count(0xffff)]).unwrap();
629 let expected =
630 RequestPacket::new(OpCode::Connect, vec![0x10, 0x00, 0xff, 0xff], expected_headers);
631 assert_eq!(decoded, expected);
632 }
633
634 #[fuchsia::test]
635 fn decode_invalid_connect_request_error() {
636 let missing_data = [
637 0x80, 0x00, 0x03, ];
640 let decoded = RequestPacket::decode(&missing_data[..]);
641 assert_matches!(decoded, Err(PacketError::BufferTooSmall));
642
643 let invalid_data = [
644 0x80, 0x00, 0x07, 0x10, 0x00, ];
648 let decoded = RequestPacket::decode(&invalid_data[..]);
649 assert_matches!(decoded, Err(PacketError::BufferTooSmall));
650
651 let invalid_data_too_long = [
654 0x80, 0x00, 0x08, 0x10, 0x00, 0x00, 0xff, 0x01, ];
658 let decoded = RequestPacket::decode(&invalid_data_too_long[..]);
659 assert_matches!(decoded, Err(PacketError::BufferTooSmall));
660 }
661
662 #[fuchsia::test]
663 fn encode_setpath_request_success() {
664 let headers = HeaderSet::from_headers(vec![Header::name("bar")]).unwrap();
665 let request = RequestPacket::new_set_path(SetPathFlags::all(), headers).unwrap();
666 assert_eq!(request.encoded_len(), 16);
667 let mut buf = vec![0; request.encoded_len()];
668 request.encode(&mut buf[..]).expect("can encode request");
669 let expected = [
670 0x85, 0x00, 0x10, 0x03, 0x00, 0x01, 0x00, 0x0b, 0x00, 0x62, 0x00, 0x61, 0x00, 0x72, 0x00,
674 0x00, ];
676 assert_eq!(buf, expected);
677 }
678
679 #[fuchsia::test]
680 fn decode_setpath_request_success() {
681 let request_buf = [
682 0x85, 0x00, 0x0e, 0x02, 0x00, 0x01, 0x00, 0x09, 0x00, 0x61, 0x00, 0x72, 0x00, 0x00, ];
687 let decoded = RequestPacket::decode(&request_buf[..]).expect("valid request");
688 let expected_headers = HeaderSet::from_headers(vec![Header::name("ar")]).unwrap();
689 let expected = RequestPacket::new(OpCode::SetPath, vec![0x02, 0x00], expected_headers);
690 assert_eq!(decoded, expected);
691 }
692
693 #[fuchsia::test]
694 fn decode_invalid_setpath_request_error() {
695 let missing_data = [
696 0x85, 0x00,
698 0x03, ];
700 let decoded = RequestPacket::decode(&missing_data[..]);
701 assert_matches!(decoded, Err(PacketError::BufferTooSmall));
702
703 let invalid_data = [
704 0x85, 0x00, 0x04, 0x02, ];
708 let decoded = RequestPacket::decode(&invalid_data[..]);
709 assert_matches!(decoded, Err(PacketError::BufferTooSmall));
710
711 let invalid_data_too_long = [
714 0x85, 0x00, 0x08, 0x10, 0x00, 0x00, 0xff, 0x01, ];
718 let decoded = RequestPacket::decode(&invalid_data_too_long[..]);
719 assert_matches!(decoded, Err(_));
720 }
721
722 #[fuchsia::test]
723 fn encode_response_packet_success() {
724 let headers = HeaderSet::from_headers(vec![Header::DestName("foo".into())]).unwrap();
725 let response = ResponsePacket::new(ResponseCode::Gone, vec![], headers);
726 assert_eq!(response.encoded_len(), 14);
727 let mut buf = vec![0; response.encoded_len()];
728 response.encode(&mut buf[..]).expect("can encode valid response packet");
729 let expected_buf = [
730 0xca, 0x00, 0x0e, 0x15, 0x00, 0x0b, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x6f, 0x00,
732 0x00, ];
734 assert_eq!(buf, expected_buf);
735 }
736
737 #[fuchsia::test]
738 fn decode_response_packet_success() {
739 let response_buf = [
740 0xa0, 0x00, 0x09, 0x46, 0x00, 0x06, 0x00, 0x02, 0x04, ];
743 let decoded = ResponsePacket::decode(&response_buf[..], OpCode::GetFinal)
744 .expect("can decode valid response");
745 let expected_headers =
746 HeaderSet::from_headers(vec![Header::Target(vec![0x00, 0x02, 0x04])]).unwrap();
747 let expected = ResponsePacket::new(ResponseCode::Ok, vec![], expected_headers);
748 assert_eq!(decoded, expected);
749 }
750
751 #[fuchsia::test]
752 fn decode_invalid_response_packet_error() {
753 let response_buf = [0x90];
755 let decoded = ResponsePacket::decode(&response_buf[..], OpCode::SetPath);
756 assert_matches!(decoded, Err(PacketError::BufferTooSmall));
757
758 let response_buf = [
760 0x0f, 0x00, 0x03, ];
762 let decoded = ResponsePacket::decode(&response_buf[..], OpCode::PutFinal);
763 assert_matches!(decoded, Err(PacketError::ResponseCode(_)));
764
765 let response_buf = [
767 0x10, 0x00, 0x03, ];
769 let decoded = ResponsePacket::decode(&response_buf[..], OpCode::Disconnect);
770 assert_matches!(decoded, Err(PacketError::ResponseCode(_)));
771
772 let response_buf = [0x90, 0x00, 0x04];
774 let decoded = ResponsePacket::decode(&response_buf[..], OpCode::ActionFinal);
775 assert_matches!(decoded, Err(PacketError::BufferTooSmall));
776
777 let response_buf = [
779 0xa0, 0x00, 0x05, 0x10, 0x00, ];
782 let decoded = ResponsePacket::decode(&response_buf[..], OpCode::Connect);
783 assert_matches!(decoded, Err(PacketError::BufferTooSmall));
784 }
785
786 #[fuchsia::test]
787 fn encode_connect_response_packet_success() {
788 let connect_response = ResponsePacket::new(
790 ResponseCode::Accepted,
791 vec![0x10, 0x00, 0x00, 0xff],
792 HeaderSet::new(),
793 );
794 assert_eq!(connect_response.encoded_len(), 7);
795 let mut buf = vec![0; connect_response.encoded_len()];
796 connect_response.encode(&mut buf[..]).expect("can encode response");
797 let expected_buf = [
798 0xa2, 0x00, 0x07, 0x10, 0x00, 0x00, 0xff, ];
801 assert_eq!(buf, expected_buf);
802 }
803
804 #[fuchsia::test]
805 fn encode_setpath_response_packet_success() {
806 let setpath_response = ResponsePacket::new(ResponseCode::Ok, vec![], HeaderSet::new());
807 assert_eq!(setpath_response.encoded_len(), 3);
808 let mut buf = vec![0; setpath_response.encoded_len()];
809 setpath_response.encode(&mut buf[..]).expect("can encode response");
810 let expected_buf = [
811 0xa0, 0x00, 0x03, ];
813 assert_eq!(buf, expected_buf);
814 }
815
816 #[fuchsia::test]
817 fn expect_response_code() {
818 let response = ResponsePacket::new_no_data(ResponseCode::Ok, HeaderSet::new());
819 assert_matches!(response.clone().expect_code(OpCode::Get, ResponseCode::Ok), Ok(_));
820 assert_matches!(
821 response.expect_code(OpCode::Get, ResponseCode::Continue),
822 Err(Error::PeerRejected { .. })
823 );
824
825 let response = ResponsePacket::new_no_data(ResponseCode::Continue, HeaderSet::new());
826 assert_matches!(response.clone().expect_code(OpCode::Get, ResponseCode::Continue), Ok(_));
827 assert_matches!(
828 response.expect_code(OpCode::Get, ResponseCode::Ok),
829 Err(Error::PeerRejected { .. })
830 );
831
832 let response = ResponsePacket::new_no_data(ResponseCode::Conflict, HeaderSet::new());
833 assert_matches!(response.clone().expect_code(OpCode::Get, ResponseCode::Conflict), Ok(_));
834 assert_matches!(
835 response.expect_code(OpCode::Get, ResponseCode::Ok),
836 Err(Error::PeerRejected { .. })
837 );
838 }
839
840 #[fuchsia::test]
841 fn decode_connect_response_packet_success() {
842 let connect_response = [
843 0xa0, 0x00, 0x0c, 0x10, 0x00, 0x12, 0x34, 0xcb, 0x00, 0x00, 0x00, 0x01, ];
847 let decoded = ResponsePacket::decode(&connect_response[..], OpCode::Connect)
848 .expect("can decode valid response");
849 let expected_headers =
850 HeaderSet::from_headers(vec![Header::ConnectionId(ConnectionIdentifier(1))]).unwrap();
851 let expected =
852 ResponsePacket::new(ResponseCode::Ok, vec![0x10, 0x00, 0x12, 0x34], expected_headers);
853 assert_eq!(decoded, expected);
854 }
855
856 #[fuchsia::test]
857 fn decode_setpath_response_packet_success() {
858 let setpath_response = [
859 0xc3, 0x00, 0x08, 0xcf, 0x00, 0x00, 0x00, 0x02, ];
862 let decoded = ResponsePacket::decode(&setpath_response[..], OpCode::SetPath)
863 .expect("can decode valid response");
864 let expected_headers = HeaderSet::from_headers(vec![Header::CreatorId(2)]).unwrap();
865 let expected = ResponsePacket::new(ResponseCode::Forbidden, vec![], expected_headers);
866 assert_eq!(decoded, expected);
867 }
868
869 #[fuchsia::test]
870 fn decode_setpath_response_packet_additional_data_error() {
871 let setpath_response = [
872 0xc3, 0x00, 0x0b, 0xaa, 0xbb, 0xcc, 0xcf, 0x00, 0x00, 0x00, 0x03, ];
876 let decoded = ResponsePacket::decode(&setpath_response[..], OpCode::SetPath);
877 assert_matches!(decoded, Err(_));
878 }
879}