rumqttc/mqttbytes/v4/
connack.rs1use super::*;
2use bytes::{Buf, BufMut, Bytes, BytesMut};
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6#[repr(u8)]
7pub enum ConnectReturnCode {
8 Success = 0,
9 RefusedProtocolVersion,
10 BadClientId,
11 ServiceUnavailable,
12 BadUserNamePassword,
13 NotAuthorized,
14}
15
16#[derive(Debug, Clone, PartialEq, Eq)]
18pub struct ConnAck {
19 pub session_present: bool,
20 pub code: ConnectReturnCode,
21}
22
23impl ConnAck {
24 pub fn new(code: ConnectReturnCode, session_present: bool) -> ConnAck {
25 ConnAck {
26 session_present,
27 code,
28 }
29 }
30
31 fn len(&self) -> usize {
32 1 + 1
35 }
36
37 pub fn read(fixed_header: FixedHeader, mut bytes: Bytes) -> Result<Self, Error> {
38 let variable_header_index = fixed_header.fixed_header_len;
39 bytes.advance(variable_header_index);
40
41 let flags = read_u8(&mut bytes)?;
42 let return_code = read_u8(&mut bytes)?;
43
44 let session_present = (flags & 0x01) == 1;
45 let code = connect_return(return_code)?;
46 let connack = ConnAck {
47 session_present,
48 code,
49 };
50
51 Ok(connack)
52 }
53
54 pub fn write(&self, buffer: &mut BytesMut) -> Result<usize, Error> {
55 let len = self.len();
56 buffer.put_u8(0x20);
57
58 let count = write_remaining_length(buffer, len)?;
59 buffer.put_u8(self.session_present as u8);
60 buffer.put_u8(self.code as u8);
61
62 Ok(1 + count + len)
63 }
64}
65
66fn connect_return(num: u8) -> Result<ConnectReturnCode, Error> {
68 match num {
69 0 => Ok(ConnectReturnCode::Success),
70 1 => Ok(ConnectReturnCode::RefusedProtocolVersion),
71 2 => Ok(ConnectReturnCode::BadClientId),
72 3 => Ok(ConnectReturnCode::ServiceUnavailable),
73 4 => Ok(ConnectReturnCode::BadUserNamePassword),
74 5 => Ok(ConnectReturnCode::NotAuthorized),
75 num => Err(Error::InvalidConnectReturnCode(num)),
76 }
77}
78
79#[cfg(test)]
80mod test {
81 use super::*;
82 use bytes::BytesMut;
83 use pretty_assertions::assert_eq;
84
85 #[test]
86 fn connack_parsing_works() {
87 let mut stream = bytes::BytesMut::new();
88 let packetstream = &[
89 0b0010_0000,
90 0x02, 0x01,
92 0x00, 0xDE,
94 0xAD,
95 0xBE,
96 0xEF, ];
98
99 stream.extend_from_slice(&packetstream[..]);
100 let fixed_header = parse_fixed_header(stream.iter()).unwrap();
101 let connack_bytes = stream.split_to(fixed_header.frame_length()).freeze();
102 let connack = ConnAck::read(fixed_header, connack_bytes).unwrap();
103
104 assert_eq!(
105 connack,
106 ConnAck {
107 session_present: true,
108 code: ConnectReturnCode::Success,
109 }
110 );
111 }
112
113 #[test]
114 fn connack_encoding_works() {
115 let connack = ConnAck {
116 session_present: true,
117 code: ConnectReturnCode::Success,
118 };
119
120 let mut buf = BytesMut::new();
121 connack.write(&mut buf).unwrap();
122 assert_eq!(buf, vec![0b0010_0000, 0x02, 0x01, 0x00]);
123 }
124}