1use bitflags::bitflags;
6use core::fmt::Debug;
7use packet_encoding::{Decodable, Encodable, decodable_enum};
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
27pub const MAX_OBJECT_SIZE: usize = 64 * 1024 * 1024;
31
32bitflags! {
33 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
36 pub struct SetPathFlags: u8 {
37 const BACKUP = 0b0000_0001;
39 const DONT_CREATE = 0b0000_0010;
41 }
42}
43
44#[derive(Debug, Clone, Copy, PartialEq)]
45#[repr(u8)]
46pub enum OpCode {
47 Connect = 0x80,
48 Disconnect = 0x81,
49 Put = 0x02,
50 PutFinal = 0x82,
51 Get = 0x03,
52 GetFinal = 0x83,
53 Reserved = 0x04,
54 ReservedFinal = 0x84,
55 SetPath = 0x85,
56 Action = 0x06,
57 ActionFinal = 0x86,
58 Session = 0x87,
59 User(u8),
62 Abort = 0xff,
63}
64
65impl OpCode {
66 fn final_bit_set(v: u8) -> bool {
67 (v & 0x80) != 0
68 }
69
70 fn is_user(code: u8) -> bool {
71 code >= 0x10 && code <= 0x1f
73 }
74
75 fn is_reserved(code: u8) -> bool {
76 code >= 0x08 && code <= 0x0f
78 }
79
80 pub fn is_final(&self) -> bool {
82 let opcode_raw: u8 = self.into();
83 Self::final_bit_set(opcode_raw)
84 }
85
86 fn request_data_length(&self) -> usize {
91 match &self {
92 Self::Connect => 4, Self::SetPath => 2, _ => 0, }
96 }
97
98 pub fn response_data_length(&self) -> usize {
103 match &self {
104 Self::Connect => 4, _ => 0, }
107 }
108}
109
110impl Into<u8> for &OpCode {
111 fn into(self) -> u8 {
112 match &self {
113 OpCode::Connect => 0x80,
114 OpCode::Disconnect => 0x81,
115 OpCode::Put => 0x02,
116 OpCode::PutFinal => 0x82,
117 OpCode::Get => 0x03,
118 OpCode::GetFinal => 0x83,
119 OpCode::Reserved => 0x04,
120 OpCode::ReservedFinal => 0x84,
121 OpCode::SetPath => 0x85,
122 OpCode::Action => 0x06,
123 OpCode::ActionFinal => 0x86,
124 OpCode::Session => 0x87,
125 OpCode::User(v) => *v,
126 OpCode::Abort => 0xff,
127 }
128 }
129}
130
131impl TryFrom<u8> for OpCode {
132 type Error = PacketError;
133
134 fn try_from(src: u8) -> Result<OpCode, Self::Error> {
135 if src == 0xff {
137 return Ok(OpCode::Abort);
138 }
139
140 const FINAL_BIT_AND_OPCODE_BITMASK: u8 = 0x9f;
143 const OPCODE_BITMASK: u8 = 0x1f;
144 let src = src & FINAL_BIT_AND_OPCODE_BITMASK;
145 let is_final = OpCode::final_bit_set(src);
146 match src & OPCODE_BITMASK {
148 0x00 if is_final => Ok(OpCode::Connect),
149 0x01 if is_final => Ok(OpCode::Disconnect),
150 0x02 if is_final => Ok(OpCode::PutFinal),
151 0x02 => Ok(OpCode::Put),
152 0x03 if is_final => Ok(OpCode::GetFinal),
153 0x03 => Ok(OpCode::Get),
154 0x04 if is_final => Ok(OpCode::ReservedFinal),
155 0x04 => Ok(OpCode::Reserved),
156 0x05 if is_final => Ok(OpCode::SetPath),
157 0x06 if is_final => Ok(OpCode::ActionFinal),
158 0x06 => Ok(OpCode::Action),
159 0x07 if is_final => Ok(OpCode::Session),
160 v if OpCode::is_user(v) => Ok(OpCode::User(src)), v if OpCode::is_reserved(v) => Err(PacketError::Reserved),
162 _ => Err(PacketError::OpCode(src)),
163 }
164 }
165}
166
167#[derive(Clone, Debug, PartialEq)]
170pub struct Packet<T>
171where
172 T: Clone + Debug + PartialEq,
173 for<'a> &'a T: Into<u8>,
174{
175 code: T,
177 data: Vec<u8>,
180 headers: HeaderSet,
182}
183
184impl<T> Packet<T>
185where
186 T: Clone + Debug + PartialEq,
187 for<'a> &'a T: Into<u8>,
188{
189 pub const MIN_PACKET_SIZE: usize = 3;
191
192 pub fn new(code: T, data: Vec<u8>, headers: HeaderSet) -> Self {
193 Self { code, data, headers }
194 }
195
196 pub fn code(&self) -> &T {
197 &self.code
198 }
199
200 pub fn data(&self) -> &Vec<u8> {
201 &self.data
202 }
203
204 pub fn headers(&self) -> &HeaderSet {
205 &self.headers
206 }
207
208 fn decode_body(buf: &[u8], code: T, optional_data_length: usize) -> Result<Self, PacketError> {
211 let (headers_idx, data) = if optional_data_length != 0 {
213 if buf.len() < optional_data_length {
214 return Err(PacketError::BufferTooSmall);
215 }
216 let mut data = vec![0u8; optional_data_length];
217 data.copy_from_slice(&buf[..optional_data_length]);
218 (optional_data_length, data)
219 } else {
220 (0, vec![])
221 };
222
223 let headers = HeaderSet::decode(&buf[headers_idx..])?;
225 Ok(Self::new(code, data, headers))
226 }
227}
228
229impl<T> Encodable for Packet<T>
230where
231 T: Clone + Debug + PartialEq,
232 for<'a> &'a T: Into<u8>,
233{
234 type Error = PacketError;
235
236 fn encoded_len(&self) -> usize {
237 Self::MIN_PACKET_SIZE + self.data.len() + self.headers.encoded_len()
238 }
239
240 fn encode(&self, buf: &mut [u8]) -> Result<(), Self::Error> {
241 if buf.len() < self.encoded_len() {
242 return Err(PacketError::BufferTooSmall);
243 }
244
245 buf[0] = (&self.code).into();
248 let packet_length_bytes = (self.encoded_len() as u16).to_be_bytes();
249 buf[1..Self::MIN_PACKET_SIZE].copy_from_slice(&packet_length_bytes[..]);
250
251 let headers_idx = if self.data.len() != 0 {
253 let end_idx = Self::MIN_PACKET_SIZE + self.data.len();
254 buf[Self::MIN_PACKET_SIZE..end_idx].copy_from_slice(&self.data[..]);
255 end_idx
256 } else {
257 Self::MIN_PACKET_SIZE
258 };
259
260 self.headers.encode(&mut buf[headers_idx..])
262 }
263}
264
265impl<T> From<Packet<T>> for HeaderSet
266where
267 T: Clone + Debug + PartialEq,
268 for<'a> &'a T: Into<u8>,
269{
270 fn from(value: Packet<T>) -> Self {
271 value.headers
272 }
273}
274
275pub type RequestPacket = Packet<OpCode>;
278
279impl RequestPacket {
280 pub fn new_connect(max_packet_size: u16, headers: HeaderSet) -> Self {
282 let mut data = vec![
284 OBEX_PROTOCOL_VERSION_NUMBER,
285 0, ];
287 data.extend_from_slice(&max_packet_size.to_be_bytes());
288 Self::new(OpCode::Connect, data, headers)
289 }
290
291 pub fn new_disconnect(headers: HeaderSet) -> Self {
292 Self::new(OpCode::Disconnect, vec![], headers)
293 }
294
295 pub fn new_get(headers: HeaderSet) -> Self {
296 Self::new(OpCode::Get, vec![], headers)
297 }
298
299 pub fn new_get_final(headers: HeaderSet) -> Self {
300 Self::new(OpCode::GetFinal, vec![], headers)
301 }
302
303 pub fn new_put(headers: HeaderSet) -> Self {
304 Self::new(OpCode::Put, vec![], headers)
305 }
306
307 pub fn new_put_final(headers: HeaderSet) -> Self {
308 Self::new(OpCode::PutFinal, vec![], headers)
309 }
310
311 pub fn new_set_path(flags: SetPathFlags, headers: HeaderSet) -> Result<Self, Error> {
312 if !headers.contains_header(&HeaderIdentifier::Name)
316 && !flags.contains(SetPathFlags::BACKUP)
317 {
318 return Err(Error::operation(OpCode::SetPath, "name is required"));
319 }
320 let data = vec![flags.bits(), 0];
323 Ok(Self::new(OpCode::SetPath, data, headers))
324 }
325
326 pub fn new_abort(headers: HeaderSet) -> Self {
327 Self::new(OpCode::Abort, vec![], headers)
328 }
329}
330
331impl Decodable for RequestPacket {
332 type Error = PacketError;
333
334 fn decode(buf: &[u8]) -> Result<Self, Self::Error> {
335 if buf.len() < Self::MIN_PACKET_SIZE {
336 return Err(PacketError::BufferTooSmall);
337 }
338
339 let code = OpCode::try_from(buf[0])?;
340 let packet_length =
341 u16::from_be_bytes(buf[1..Self::MIN_PACKET_SIZE].try_into().expect("checked length"));
342
343 if buf.len() < packet_length.into() {
344 return Err(PacketError::BufferTooSmall);
345 }
346 Self::decode_body(&buf[Self::MIN_PACKET_SIZE..], code, code.request_data_length())
348 }
349}
350
351decodable_enum! {
352 pub enum ResponseCode<u8, PacketError, Reserved> {
357 Continue = 0x90,
358 Ok = 0xa0,
359 Created = 0xa1,
360 Accepted = 0xa2,
361 NonAuthoritativeInformation = 0xa3,
362 NoContent = 0xa4,
363 ResetContent = 0xa5,
364 PartialContent = 0xa6,
365 MultipleChoices = 0xb0,
366 MovedPermanently = 0xb1,
367 MovedTemporarily = 0xb2,
368 SeeOther = 0xb3,
369 NotModified = 0xb4,
370 UseProxy = 0xb5,
371 BadRequest = 0xc0,
372 Unauthorized = 0xc1,
373 PaymentRequired = 0xc2,
374 Forbidden = 0xc3,
375 NotFound = 0xc4,
376 MethodNotAllowed = 0xc5,
377 NotAcceptable = 0xc6,
378 ProxyAuthenticationRequired = 0xc7,
379 RequestTimeOut = 0xc8,
380 Conflict = 0xc9,
381 Gone = 0xca,
382 LengthRequired = 0xcb,
383 PreconditionFailed = 0xcc,
384 RequestedEntityTooLarge = 0xcd,
385 RequestedUrlTooLarge = 0xce,
386 UnsupportedMediaType = 0xcf,
387 InternalServerError = 0xd0,
388 NotImplemented = 0xd1,
389 BadGateway = 0xd2,
390 ServiceUnavailable = 0xd3,
391 GatewayTimeout = 0xd4,
392 HttpVersionNotSupported = 0xd5,
393 DatabaseFull = 0xe0,
394 DatabaseLocked = 0xe1,
395 }
396}
397
398pub type ResponsePacket = Packet<ResponseCode>;
401
402impl ResponsePacket {
403 pub fn new_empty(code: ResponseCode) -> Self {
405 Self::new_no_data(code, HeaderSet::new())
406 }
407
408 pub fn new_no_data(code: ResponseCode, headers: HeaderSet) -> Self {
409 Self::new(code, vec![], headers)
410 }
411
412 pub fn new_connect(code: ResponseCode, max_packet_size: u16, headers: HeaderSet) -> Self {
413 const OBEX_CONNECT_RESPONSE_FLAGS: u8 = 0;
418 let mut data = vec![OBEX_PROTOCOL_VERSION_NUMBER, OBEX_CONNECT_RESPONSE_FLAGS];
419 data.extend_from_slice(&max_packet_size.to_be_bytes());
420 Self::new(code, data, headers)
421 }
422
423 pub fn new_disconnect(headers: HeaderSet) -> Self {
424 Self::new(ResponseCode::Ok, vec![], headers)
425 }
426
427 pub fn new_setpath(code: ResponseCode, headers: HeaderSet) -> Self {
428 Self::new(code, vec![], headers)
429 }
430
431 pub fn new_get(code: ResponseCode, headers: HeaderSet) -> Self {
432 Self::new(code, vec![], headers)
433 }
434
435 pub fn expect_code(self, request: OpCode, expected: ResponseCode) -> Result<Self, Error> {
436 if *self.code() == expected {
437 return Ok(self);
438 }
439 Err(Error::peer_rejected(request, *self.code()))
440 }
441
442 pub fn decode(buf: &[u8], request: OpCode) -> Result<Self, PacketError> {
447 if buf.len() < Self::MIN_PACKET_SIZE {
448 return Err(PacketError::BufferTooSmall);
449 }
450
451 let code = ResponseCode::try_from(buf[0]).map_err(|_| PacketError::ResponseCode(buf[0]))?;
452 let packet_length =
453 u16::from_be_bytes(buf[1..Self::MIN_PACKET_SIZE].try_into().expect("checked length"));
454
455 if buf.len() < packet_length.into() {
456 return Err(PacketError::BufferTooSmall);
457 }
458 Self::decode_body(&buf[Self::MIN_PACKET_SIZE..], code, request.response_data_length())
460 }
461}
462
463#[cfg(test)]
464mod tests {
465 use super::*;
466
467 use assert_matches::assert_matches;
468
469 use crate::header::{ConnectionIdentifier, Header};
470
471 #[fuchsia::test]
472 fn convert_opcode_success() {
473 let raw = 0x02;
475 let converted = OpCode::try_from(raw).expect("valid opcode");
476 assert_eq!(converted, OpCode::Put);
477 assert!(!converted.is_final());
478 assert_eq!(converted.request_data_length(), 0);
479 assert_eq!(converted.response_data_length(), 0);
480 let converted_raw: u8 = (&converted).into();
481 assert_eq!(converted_raw, raw);
482
483 let raw = 0x84;
485 let converted = OpCode::try_from(raw).expect("valid opcode");
486 assert_eq!(converted, OpCode::ReservedFinal);
487 assert!(converted.is_final());
488 let converted_raw: u8 = (&converted).into();
489 assert_eq!(converted_raw, raw);
490
491 let raw = 0xff;
493 let converted = OpCode::try_from(raw).expect("valid opcode");
494 assert_eq!(converted, OpCode::Abort);
495 assert!(converted.is_final());
496 let converted_raw: u8 = (&converted).into();
497 assert_eq!(converted_raw, raw);
498
499 let raw = 0xe5; let converted = OpCode::try_from(raw).expect("valid opcode");
503 assert_eq!(converted, OpCode::SetPath);
504 assert!(converted.is_final());
505 let converted_raw: u8 = (&converted).into();
506 assert_eq!(converted_raw, 0x85); }
508
509 #[fuchsia::test]
510 fn convert_user_opcode_success() {
511 let user = 0x1a;
513 let converted = OpCode::try_from(user).expect("valid opcode");
514 assert_eq!(converted, OpCode::User(0x1a));
515 assert!(!converted.is_final());
516 let converted_raw: u8 = (&converted).into();
517 assert_eq!(converted_raw, user);
518
519 let user = 0x9d;
521 let converted = OpCode::try_from(user).expect("valid opcode");
522 assert_eq!(converted, OpCode::User(0x9d));
523 assert!(converted.is_final());
524 let converted_raw: u8 = (&converted).into();
525 assert_eq!(converted_raw, user);
527
528 let user = 0xf3;
530 let converted = OpCode::try_from(user).expect("valid opcode");
531 assert_eq!(converted, OpCode::User(0x93)); assert!(converted.is_final());
533 let converted_raw: u8 = (&converted).into();
534 assert_eq!(converted_raw, 0x93);
535 }
536
537 #[fuchsia::test]
538 fn convert_invalid_opcode_is_error() {
539 let invalid = 0x01;
541 assert_matches!(OpCode::try_from(invalid), Err(PacketError::OpCode(_)));
542 let reserved = 0x08;
544 assert_matches!(OpCode::try_from(reserved), Err(PacketError::Reserved));
545 let reserved = 0x8f;
547 assert_matches!(OpCode::try_from(reserved), Err(PacketError::Reserved));
548 }
549
550 #[fuchsia::test]
551 fn construct_setpath() {
552 let headers = HeaderSet::from_header(Header::name("foo"));
554 let _request = RequestPacket::new_set_path(SetPathFlags::all(), headers.clone())
555 .expect("valid set path args");
556
557 let _request = RequestPacket::new_set_path(SetPathFlags::empty(), headers)
559 .expect("valid set path args");
560
561 let _request = RequestPacket::new_set_path(SetPathFlags::BACKUP, HeaderSet::new())
563 .expect("valid set path args");
564
565 assert_matches!(
567 RequestPacket::new_set_path(SetPathFlags::DONT_CREATE, HeaderSet::new()),
568 Err(Error::OperationError { .. })
569 );
570 }
571
572 #[fuchsia::test]
573 fn encode_request_packet_success() {
574 let headers = HeaderSet::from_headers(vec![Header::Permissions(2)]).unwrap();
575 let request = RequestPacket::new(OpCode::Abort, vec![], headers);
576 assert_eq!(request.encoded_len(), 8);
578 let mut buf = vec![0; request.encoded_len()];
579 request.encode(&mut buf[..]).expect("can encode request");
580 let expected = [0xff, 0x00, 0x08, 0xd6, 0x00, 0x00, 0x00, 0x02];
581 assert_eq!(buf, expected);
582 }
583
584 #[fuchsia::test]
585 fn encode_request_packet_no_headers_success() {
586 let request = RequestPacket::new(OpCode::Abort, vec![], HeaderSet::new());
588 assert_eq!(request.encoded_len(), 3);
589 let mut buf = vec![0; request.encoded_len()];
590 request.encode(&mut buf[..]).expect("can encode request");
591 let expected = [0xff, 0x00, 0x03];
592 assert_eq!(buf, expected);
593 }
594
595 #[fuchsia::test]
596 fn decode_request_packet_success() {
597 let request_buf = [
598 0x81, 0x00, 0x0e, 0x01, 0x00, 0xb, 0x00, 0x66, 0x00, 0x75, 0x00, 0x6e, 0x00, 0x00, ];
602 let decoded = RequestPacket::decode(&request_buf[..]).expect("valid request");
603 let expected_headers = HeaderSet::from_headers(vec![Header::name("fun")]).unwrap();
604 let expected = RequestPacket::new(OpCode::Disconnect, vec![], expected_headers);
605 assert_eq!(decoded, expected);
606 }
607
608 #[fuchsia::test]
610 fn encode_connect_request_packet_success() {
611 let headers =
612 HeaderSet::from_headers(vec![Header::Count(4), Header::Length(0xf483)]).unwrap();
613 let request = RequestPacket::new_connect(0x2000, headers);
614 assert_eq!(request.encoded_len(), 17);
615 let mut buf = vec![0; request.encoded_len()];
616 request.encode(&mut buf[..]).expect("can encode request");
617 let expected = [
618 0x80, 0x00, 0x11, 0x10, 0x00, 0x20, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x04, 0xc3, 0x00, 0x00, 0xf4, 0x83, ];
624 assert_eq!(buf, expected);
625 }
626
627 #[fuchsia::test]
628 fn decode_connect_request_packet_success() {
629 let request_buf = [
632 0x80, 0x00, 0x0c, 0x10, 0x00, 0xff, 0xff, 0xc0, 0x00, 0x00, 0xff, 0xff, ];
637 let decoded = RequestPacket::decode(&request_buf[..]).expect("valid request");
638 let expected_headers = HeaderSet::from_headers(vec![Header::Count(0xffff)]).unwrap();
639 let expected =
640 RequestPacket::new(OpCode::Connect, vec![0x10, 0x00, 0xff, 0xff], expected_headers);
641 assert_eq!(decoded, expected);
642 }
643
644 #[fuchsia::test]
645 fn decode_invalid_connect_request_error() {
646 let missing_data = [
647 0x80, 0x00, 0x03, ];
650 let decoded = RequestPacket::decode(&missing_data[..]);
651 assert_matches!(decoded, Err(PacketError::BufferTooSmall));
652
653 let invalid_data = [
654 0x80, 0x00, 0x07, 0x10, 0x00, ];
658 let decoded = RequestPacket::decode(&invalid_data[..]);
659 assert_matches!(decoded, Err(PacketError::BufferTooSmall));
660
661 let invalid_data_too_long = [
664 0x80, 0x00, 0x08, 0x10, 0x00, 0x00, 0xff, 0x01, ];
668 let decoded = RequestPacket::decode(&invalid_data_too_long[..]);
669 assert_matches!(decoded, Err(PacketError::BufferTooSmall));
670 }
671
672 #[fuchsia::test]
673 fn encode_setpath_request_success() {
674 let headers = HeaderSet::from_headers(vec![Header::name("bar")]).unwrap();
675 let request = RequestPacket::new_set_path(SetPathFlags::all(), headers).unwrap();
676 assert_eq!(request.encoded_len(), 16);
677 let mut buf = vec![0; request.encoded_len()];
678 request.encode(&mut buf[..]).expect("can encode request");
679 let expected = [
680 0x85, 0x00, 0x10, 0x03, 0x00, 0x01, 0x00, 0x0b, 0x00, 0x62, 0x00, 0x61, 0x00, 0x72, 0x00,
684 0x00, ];
686 assert_eq!(buf, expected);
687 }
688
689 #[fuchsia::test]
690 fn decode_setpath_request_success() {
691 let request_buf = [
692 0x85, 0x00, 0x0e, 0x02, 0x00, 0x01, 0x00, 0x09, 0x00, 0x61, 0x00, 0x72, 0x00, 0x00, ];
697 let decoded = RequestPacket::decode(&request_buf[..]).expect("valid request");
698 let expected_headers = HeaderSet::from_headers(vec![Header::name("ar")]).unwrap();
699 let expected = RequestPacket::new(OpCode::SetPath, vec![0x02, 0x00], expected_headers);
700 assert_eq!(decoded, expected);
701 }
702
703 #[fuchsia::test]
704 fn decode_invalid_setpath_request_error() {
705 let missing_data = [
706 0x85, 0x00,
708 0x03, ];
710 let decoded = RequestPacket::decode(&missing_data[..]);
711 assert_matches!(decoded, Err(PacketError::BufferTooSmall));
712
713 let invalid_data = [
714 0x85, 0x00, 0x04, 0x02, ];
718 let decoded = RequestPacket::decode(&invalid_data[..]);
719 assert_matches!(decoded, Err(PacketError::BufferTooSmall));
720
721 let invalid_data_too_long = [
724 0x85, 0x00, 0x08, 0x10, 0x00, 0x00, 0xff, 0x01, ];
728 let decoded = RequestPacket::decode(&invalid_data_too_long[..]);
729 assert_matches!(decoded, Err(_));
730 }
731
732 #[fuchsia::test]
733 fn encode_response_packet_success() {
734 let headers = HeaderSet::from_headers(vec![Header::DestName("foo".into())]).unwrap();
735 let response = ResponsePacket::new(ResponseCode::Gone, vec![], headers);
736 assert_eq!(response.encoded_len(), 14);
737 let mut buf = vec![0; response.encoded_len()];
738 response.encode(&mut buf[..]).expect("can encode valid response packet");
739 let expected_buf = [
740 0xca, 0x00, 0x0e, 0x15, 0x00, 0x0b, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x6f, 0x00,
742 0x00, ];
744 assert_eq!(buf, expected_buf);
745 }
746
747 #[fuchsia::test]
748 fn decode_response_packet_success() {
749 let response_buf = [
750 0xa0, 0x00, 0x09, 0x46, 0x00, 0x06, 0x00, 0x02, 0x04, ];
753 let decoded = ResponsePacket::decode(&response_buf[..], OpCode::GetFinal)
754 .expect("can decode valid response");
755 let expected_headers =
756 HeaderSet::from_headers(vec![Header::Target(vec![0x00, 0x02, 0x04])]).unwrap();
757 let expected = ResponsePacket::new(ResponseCode::Ok, vec![], expected_headers);
758 assert_eq!(decoded, expected);
759 }
760
761 #[fuchsia::test]
762 fn decode_invalid_response_packet_error() {
763 let response_buf = [0x90];
765 let decoded = ResponsePacket::decode(&response_buf[..], OpCode::SetPath);
766 assert_matches!(decoded, Err(PacketError::BufferTooSmall));
767
768 let response_buf = [
770 0x0f, 0x00, 0x03, ];
772 let decoded = ResponsePacket::decode(&response_buf[..], OpCode::PutFinal);
773 assert_matches!(decoded, Err(PacketError::ResponseCode(_)));
774
775 let response_buf = [
777 0x10, 0x00, 0x03, ];
779 let decoded = ResponsePacket::decode(&response_buf[..], OpCode::Disconnect);
780 assert_matches!(decoded, Err(PacketError::ResponseCode(_)));
781
782 let response_buf = [0x90, 0x00, 0x04];
784 let decoded = ResponsePacket::decode(&response_buf[..], OpCode::ActionFinal);
785 assert_matches!(decoded, Err(PacketError::BufferTooSmall));
786
787 let response_buf = [
789 0xa0, 0x00, 0x05, 0x10, 0x00, ];
792 let decoded = ResponsePacket::decode(&response_buf[..], OpCode::Connect);
793 assert_matches!(decoded, Err(PacketError::BufferTooSmall));
794 }
795
796 #[fuchsia::test]
797 fn encode_connect_response_packet_success() {
798 let connect_response = ResponsePacket::new(
800 ResponseCode::Accepted,
801 vec![0x10, 0x00, 0x00, 0xff],
802 HeaderSet::new(),
803 );
804 assert_eq!(connect_response.encoded_len(), 7);
805 let mut buf = vec![0; connect_response.encoded_len()];
806 connect_response.encode(&mut buf[..]).expect("can encode response");
807 let expected_buf = [
808 0xa2, 0x00, 0x07, 0x10, 0x00, 0x00, 0xff, ];
811 assert_eq!(buf, expected_buf);
812 }
813
814 #[fuchsia::test]
815 fn encode_setpath_response_packet_success() {
816 let setpath_response = ResponsePacket::new(ResponseCode::Ok, vec![], HeaderSet::new());
817 assert_eq!(setpath_response.encoded_len(), 3);
818 let mut buf = vec![0; setpath_response.encoded_len()];
819 setpath_response.encode(&mut buf[..]).expect("can encode response");
820 let expected_buf = [
821 0xa0, 0x00, 0x03, ];
823 assert_eq!(buf, expected_buf);
824 }
825
826 #[fuchsia::test]
827 fn expect_response_code() {
828 let response = ResponsePacket::new_no_data(ResponseCode::Ok, HeaderSet::new());
829 assert_matches!(response.clone().expect_code(OpCode::Get, ResponseCode::Ok), Ok(_));
830 assert_matches!(
831 response.expect_code(OpCode::Get, ResponseCode::Continue),
832 Err(Error::PeerRejected { .. })
833 );
834
835 let response = ResponsePacket::new_no_data(ResponseCode::Continue, HeaderSet::new());
836 assert_matches!(response.clone().expect_code(OpCode::Get, ResponseCode::Continue), Ok(_));
837 assert_matches!(
838 response.expect_code(OpCode::Get, ResponseCode::Ok),
839 Err(Error::PeerRejected { .. })
840 );
841
842 let response = ResponsePacket::new_no_data(ResponseCode::Conflict, HeaderSet::new());
843 assert_matches!(response.clone().expect_code(OpCode::Get, ResponseCode::Conflict), Ok(_));
844 assert_matches!(
845 response.expect_code(OpCode::Get, ResponseCode::Ok),
846 Err(Error::PeerRejected { .. })
847 );
848 }
849
850 #[fuchsia::test]
851 fn decode_connect_response_packet_success() {
852 let connect_response = [
853 0xa0, 0x00, 0x0c, 0x10, 0x00, 0x12, 0x34, 0xcb, 0x00, 0x00, 0x00, 0x01, ];
857 let decoded = ResponsePacket::decode(&connect_response[..], OpCode::Connect)
858 .expect("can decode valid response");
859 let expected_headers =
860 HeaderSet::from_headers(vec![Header::ConnectionId(ConnectionIdentifier(1))]).unwrap();
861 let expected =
862 ResponsePacket::new(ResponseCode::Ok, vec![0x10, 0x00, 0x12, 0x34], expected_headers);
863 assert_eq!(decoded, expected);
864 }
865
866 #[fuchsia::test]
867 fn decode_setpath_response_packet_success() {
868 let setpath_response = [
869 0xc3, 0x00, 0x08, 0xcf, 0x00, 0x00, 0x00, 0x02, ];
872 let decoded = ResponsePacket::decode(&setpath_response[..], OpCode::SetPath)
873 .expect("can decode valid response");
874 let expected_headers = HeaderSet::from_headers(vec![Header::CreatorId(2)]).unwrap();
875 let expected = ResponsePacket::new(ResponseCode::Forbidden, vec![], expected_headers);
876 assert_eq!(decoded, expected);
877 }
878
879 #[fuchsia::test]
880 fn decode_setpath_response_packet_additional_data_error() {
881 let setpath_response = [
882 0xc3, 0x00, 0x0b, 0xaa, 0xbb, 0xcc, 0xcf, 0x00, 0x00, 0x00, 0x03, ];
886 let decoded = ResponsePacket::decode(&setpath_response[..], OpCode::SetPath);
887 assert_matches!(decoded, Err(_));
888 }
889}