@ -30,7 +30,7 @@ use nom7::sequence::tuple;
use nom7 ::{ Err , IResult , Needed } ;
use nom7 ::{ Err , IResult , Needed } ;
use num_traits ::FromPrimitive ;
use num_traits ::FromPrimitive ;
#[ derive( Debug)]
#[ derive( Copy, Clone, Debug)]
pub struct FixedHeader {
pub struct FixedHeader {
pub message_type : MQTTTypeCode ,
pub message_type : MQTTTypeCode ,
pub dup_flag : bool ,
pub dup_flag : bool ,
@ -222,94 +222,108 @@ pub fn parse_connect(i: &[u8]) -> IResult<&[u8], MQTTConnectData> {
) )
) )
}
}
pub fn parse_connack ( i : & [ u8 ] , protocol_version : u8 ) -> IResult < & [ u8 ] , MQTTConnackData > {
#[ inline ]
let ( i , topic_name_compression_response ) = be_u8 ( i ) ? ;
pub fn parse_connack ( protocol_version : u8 ) -> impl Fn ( & [ u8 ] ) -> IResult < & [ u8 ] , MQTTConnackData >
let ( i , return_code ) = be_u8 ( i ) ? ;
where
let ( i , properties ) = parse_properties ( i , protocol_version = = 5 ) ? ;
{
Ok ( (
move | i : & [ u8 ] | {
i ,
let ( i , topic_name_compression_response ) = be_u8 ( i ) ? ;
MQTTConnackData {
let ( i , return_code ) = be_u8 ( i ) ? ;
session_present : ( topic_name_compression_response & 1 ) ! = 0 ,
let ( i , properties ) = parse_properties ( i , protocol_version = = 5 ) ? ;
return_code ,
Ok ( (
properties ,
i ,
} ,
MQTTConnackData {
) )
session_present : ( topic_name_compression_response & 1 ) ! = 0 ,
return_code ,
properties ,
} ,
) )
}
}
}
pub fn parse_publish (
#[ inline ]
i : & [ u8 ] , protocol_version : u8 , has_id : bool ,
fn parse_publish (
) -> IResult < & [ u8 ] , MQTTPublishData > {
protocol_version : u8 , has_id : bool ,
let ( i , topic ) = parse_mqtt_string ( i ) ? ;
) -> impl Fn ( & [ u8 ] ) -> IResult < & [ u8 ] , MQTTPublishData >
let ( i , message_id ) = cond ( has_id , be_u16 ) ( i ) ? ;
where
let ( message , properties ) = parse_properties ( i , protocol_version = = 5 ) ? ;
{
Ok ( (
move | i : & [ u8 ] | {
i ,
let ( i , topic ) = parse_mqtt_string ( i ) ? ;
MQTTPublishData {
let ( i , message_id ) = cond ( has_id , be_u16 ) ( i ) ? ;
topic ,
let ( message , properties ) = parse_properties ( i , protocol_version = = 5 ) ? ;
message_id ,
Ok ( (
message : message . to_vec ( ) ,
i ,
properties ,
MQTTPublishData {
} ,
topic ,
) )
message_id ,
message : message . to_vec ( ) ,
properties ,
} ,
) )
}
}
}
#[ inline ]
#[ inline ]
fn parse_msgidonly ( input : & [ u8 ] , protocol_version : u8 ) -> IResult < & [ u8 ] , MQTTMessageIdOnly > {
pub fn parse_msgidonly ( protocol_version : u8 ) -> impl Fn ( & [ u8 ] ) -> IResult < & [ u8 ] , MQTTMessageIdOnly >
if protocol_version < 5 {
where
// before v5 we don't even have to care about reason codes
{
// and properties, lucky us
move | input : & [ u8 ] | {
return parse_msgidonly_v3 ( input ) ;
if protocol_version < 5 {
}
// before v5 we don't even have to care about reason codes
let remaining_len = input . len ( ) ;
// and properties, lucky us
match be_u16 ( input ) {
return parse_msgidonly_v3 ( input ) ;
Ok ( ( rem , message_id ) ) = > {
}
if remaining_len = = 2 {
let remaining_len = input . len ( ) ;
// from the spec: " The Reason Code and Property Length can be
match be_u16 ( input ) {
// omitted if the Reason Code is 0x00 (Success) and there are
Ok ( ( rem , message_id ) ) = > {
// no Properties. In this case the message has a Remaining
if remaining_len = = 2 {
// Length of 2."
// from the spec: " The Reason Code and Property Length can be
return Ok ( (
// omitted if the Reason Code is 0x00 (Success) and there are
rem ,
// no Properties. In this case the message has a Remaining
MQTTMessageIdOnly {
// Length of 2."
message_id ,
return Ok ( (
reason_code : Some ( 0 ) ,
rem ,
properties : None ,
MQTTMessageIdOnly {
} ,
message_id ,
) ) ;
reason_code : Some ( 0 ) ,
}
properties : None ,
match be_u8 ( rem ) {
} ,
Ok ( ( rem , reason_code ) ) = > {
) ) ;
// We are checking for 3 because in that case we have a
}
// header plus reason code, but no properties.
match be_u8 ( rem ) {
if remaining_len = = 3 {
Ok ( ( rem , reason_code ) ) = > {
// no properties
// We are checking for 3 because in that case we have a
return Ok ( (
// header plus reason code, but no properties.
rem ,
if remaining_len = = 3 {
MQTTMessageIdOnly {
// no properties
message_id ,
reason_code : Some ( reason_code ) ,
properties : None ,
} ,
) ) ;
}
match parse_properties ( rem , true ) {
Ok ( ( rem , properties ) ) = > {
return Ok ( (
return Ok ( (
rem ,
rem ,
MQTTMessageIdOnly {
MQTTMessageIdOnly {
message_id ,
message_id ,
reason_code : Some ( reason_code ) ,
reason_code : Some ( reason_code ) ,
properties ,
properties : None ,
} ,
} ,
) ) ;
) ) ;
}
}
Err ( e ) = > return Err ( e ) ,
match parse_properties ( rem , true ) {
Ok ( ( rem , properties ) ) = > {
return Ok ( (
rem ,
MQTTMessageIdOnly {
message_id ,
reason_code : Some ( reason_code ) ,
properties ,
} ,
) ) ;
}
Err ( e ) = > return Err ( e ) ,
}
}
}
Err ( e ) = > return Err ( e ) ,
}
}
Err ( e ) = > return Err ( e ) ,
}
}
Err ( e ) = > return Err ( e ) ,
}
}
Err ( e ) = > return Err ( e ) ,
}
}
}
}
@ -333,114 +347,140 @@ pub fn parse_subscribe_topic(i: &[u8]) -> IResult<&[u8], MQTTSubscribeTopicData>
Ok ( ( i , MQTTSubscribeTopicData { topic_name , qos } ) )
Ok ( ( i , MQTTSubscribeTopicData { topic_name , qos } ) )
}
}
pub fn parse_subscribe ( i : & [ u8 ] , protocol_version : u8 ) -> IResult < & [ u8 ] , MQTTSubscribeData > {
#[ inline ]
let ( i , message_id ) = be_u16 ( i ) ? ;
pub fn parse_subscribe ( protocol_version : u8 ) -> impl Fn ( & [ u8 ] ) -> IResult < & [ u8 ] , MQTTSubscribeData >
let ( i , properties ) = parse_properties ( i , protocol_version = = 5 ) ? ;
where
let ( i , topics ) = many1 ( complete ( parse_subscribe_topic ) ) ( i ) ? ;
{
Ok ( (
move | i : & [ u8 ] | {
i ,
let ( i , message_id ) = be_u16 ( i ) ? ;
MQTTSubscribeData {
let ( i , properties ) = parse_properties ( i , protocol_version = = 5 ) ? ;
message_id ,
let ( i , topics ) = many1 ( complete ( parse_subscribe_topic ) ) ( i ) ? ;
topics ,
Ok ( (
properties ,
i ,
} ,
MQTTSubscribeData {
) )
message_id ,
topics ,
properties ,
} ,
) )
}
}
}
pub fn parse_suback ( i : & [ u8 ] , protocol_version : u8 ) -> IResult < & [ u8 ] , MQTTSubackData > {
#[ inline ]
let ( i , message_id ) = be_u16 ( i ) ? ;
pub fn parse_suback ( protocol_version : u8 ) -> impl Fn ( & [ u8 ] ) -> IResult < & [ u8 ] , MQTTSubackData >
let ( qoss , properties ) = parse_properties ( i , protocol_version = = 5 ) ? ;
where
Ok ( (
{
i ,
move | i : & [ u8 ] | {
MQTTSubackData {
let ( i , message_id ) = be_u16 ( i ) ? ;
message_id ,
let ( qoss , properties ) = parse_properties ( i , protocol_version = = 5 ) ? ;
qoss : qoss . to_vec ( ) ,
Ok ( (
properties ,
i ,
} ,
MQTTSubackData {
) )
message_id ,
qoss : qoss . to_vec ( ) ,
properties ,
} ,
) )
}
}
}
pub fn parse_unsubscribe ( i : & [ u8 ] , protocol_version : u8 ) -> IResult < & [ u8 ] , MQTTUnsubscribeData > {
#[ inline ]
let ( i , message_id ) = be_u16 ( i ) ? ;
pub fn parse_unsubscribe (
let ( i , properties ) = parse_properties ( i , protocol_version = = 5 ) ? ;
protocol_version : u8 ,
let ( i , topics ) = many0 ( complete ( parse_mqtt_string ) ) ( i ) ? ;
) -> impl Fn ( & [ u8 ] ) -> IResult < & [ u8 ] , MQTTUnsubscribeData >
Ok ( (
where
i ,
{
MQTTUnsubscribeData {
move | i : & [ u8 ] | {
message_id ,
let ( i , message_id ) = be_u16 ( i ) ? ;
topics ,
let ( i , properties ) = parse_properties ( i , protocol_version = = 5 ) ? ;
properties ,
let ( i , topics ) = many0 ( complete ( parse_mqtt_string ) ) ( i ) ? ;
} ,
Ok ( (
) )
i ,
MQTTUnsubscribeData {
message_id ,
topics ,
properties ,
} ,
) )
}
}
}
pub fn parse_unsuback ( i : & [ u8 ] , protocol_version : u8 ) -> IResult < & [ u8 ] , MQTTUnsubackData > {
#[ inline ]
let ( i , message_id ) = be_u16 ( i ) ? ;
pub fn parse_unsuback ( protocol_version : u8 ) -> impl Fn ( & [ u8 ] ) -> IResult < & [ u8 ] , MQTTUnsubackData >
let ( i , properties ) = parse_properties ( i , protocol_version = = 5 ) ? ;
where
let ( i , reason_codes ) = many0 ( complete ( be_u8 ) ) ( i ) ? ;
{
Ok ( (
move | i : & [ u8 ] | {
i ,
let ( i , message_id ) = be_u16 ( i ) ? ;
MQTTUnsubackData {
let ( i , properties ) = parse_properties ( i , protocol_version = = 5 ) ? ;
message_id ,
let ( i , reason_codes ) = many0 ( complete ( be_u8 ) ) ( i ) ? ;
properties ,
Ok ( (
reason_codes : Some ( reason_codes ) ,
i ,
} ,
MQTTUnsubackData {
) )
message_id ,
properties ,
reason_codes : Some ( reason_codes ) ,
} ,
) )
}
}
}
#[ inline ]
#[ inline ]
fn parse_disconnect (
fn parse_disconnect (
input : & [ u8 ] , remaining_len : usize , protocol_version : u8 ,
remaining_len : usize , protocol_version : u8 ,
) -> IResult < & [ u8 ] , MQTTDisconnectData > {
) -> impl Fn ( & [ u8 ] ) -> IResult < & [ u8 ] , MQTTDisconnectData >
if protocol_version < 5 {
where
return Ok ( (
{
input ,
move | input : & [ u8 ] | {
MQTTDisconnectData {
if protocol_version < 5 {
reason_code : None ,
return Ok ( (
properties : None ,
input ,
} ,
MQTTDisconnectData {
) ) ;
reason_code : None ,
}
properties : None ,
if remaining_len = = 0 {
} ,
// The Reason Code and Property Length can be omitted if the Reason
) ) ;
// Code is 0x00 (Normal disconnection) and there are no Properties.
}
// In this case the DISCONNECT has a Remaining Length of 0.
if remaining_len = = 0 {
return Ok ( (
// The Reason Code and Property Length can be omitted if the Reason
input ,
// Code is 0x00 (Normal disconnection) and there are no Properties.
MQTTDisconnectData {
// In this case the DISCONNECT has a Remaining Length of 0.
reason_code : Some ( 0 ) ,
return Ok ( (
properties : None ,
input ,
} ,
MQTTDisconnectData {
) ) ;
reason_code : Some ( 0 ) ,
}
properties : None ,
match be_u8 ( input ) {
} ,
Ok ( ( rem , reason_code ) ) = > {
) ) ;
// We are checking for 1 because in that case we have a
}
// header plus reason code, but no properties.
match be_u8 ( input ) {
if remaining_len = = 1 {
Ok ( ( rem , reason_code ) ) = > {
// no properties
// We are checking for 1 because in that case we have a
return Ok ( (
// header plus reason code, but no properties.
rem ,
if remaining_len = = 1 {
MQTTDisconnectData {
// no properties
reason_code : Some ( 0 ) ,
properties : None ,
} ,
) ) ;
}
match parse_properties ( rem , true ) {
Ok ( ( rem , properties ) ) = > {
return Ok ( (
return Ok ( (
rem ,
rem ,
MQTTDisconnectData {
MQTTDisconnectData {
reason_code : Some ( reason_code ) ,
reason_code : Some ( 0 ) ,
properties ,
properties : None ,
} ,
} ,
) ) ;
) ) ;
}
}
Err ( e ) = > return Err ( e ) ,
match parse_properties ( rem , true ) {
Ok ( ( rem , properties ) ) = > {
return Ok ( (
rem ,
MQTTDisconnectData {
reason_code : Some ( reason_code ) ,
properties ,
} ,
) ) ;
}
Err ( e ) = > return Err ( e ) ,
}
}
}
Err ( e ) = > return Err ( e ) ,
}
}
Err ( e ) = > return Err ( e ) ,
}
}
}
}
@ -457,6 +497,151 @@ pub fn parse_auth(i: &[u8]) -> IResult<&[u8], MQTTAuthData> {
) )
) )
}
}
#[ inline ]
fn parse_remaining_message < ' a > (
full : & ' a [ u8 ] , len : usize , skiplen : usize , header : FixedHeader , message_type : MQTTTypeCode ,
protocol_version : u8 ,
) -> impl Fn ( & ' a [ u8 ] ) -> IResult < & ' a [ u8 ] , MQTTMessage >
where
{
move | input : & ' a [ u8 ] | {
match message_type {
MQTTTypeCode ::CONNECT = > match parse_connect ( input ) {
Ok ( ( _rem , conn ) ) = > {
let msg = MQTTMessage {
header ,
op : MQTTOperation ::CONNECT ( conn ) ,
} ;
Ok ( ( & full [ skiplen + len .. ] , msg ) )
}
Err ( e ) = > Err ( e ) ,
} ,
MQTTTypeCode ::CONNACK = > match parse_connack ( protocol_version ) ( input ) {
Ok ( ( _rem , connack ) ) = > {
let msg = MQTTMessage {
header ,
op : MQTTOperation ::CONNACK ( connack ) ,
} ;
Ok ( ( & full [ skiplen + len .. ] , msg ) )
}
Err ( e ) = > Err ( e ) ,
} ,
MQTTTypeCode ::PUBLISH = > {
match parse_publish ( protocol_version , header . qos_level > 0 ) ( input ) {
Ok ( ( _rem , publish ) ) = > {
let msg = MQTTMessage {
header ,
op : MQTTOperation ::PUBLISH ( publish ) ,
} ;
Ok ( ( & full [ skiplen + len .. ] , msg ) )
}
Err ( e ) = > Err ( e ) ,
}
}
MQTTTypeCode ::PUBACK
| MQTTTypeCode ::PUBREC
| MQTTTypeCode ::PUBREL
| MQTTTypeCode ::PUBCOMP = > match parse_msgidonly ( protocol_version ) ( input ) {
Ok ( ( _rem , msgidonly ) ) = > {
let msg = MQTTMessage {
header ,
op : match message_type {
MQTTTypeCode ::PUBACK = > MQTTOperation ::PUBACK ( msgidonly ) ,
MQTTTypeCode ::PUBREC = > MQTTOperation ::PUBREC ( msgidonly ) ,
MQTTTypeCode ::PUBREL = > MQTTOperation ::PUBREL ( msgidonly ) ,
MQTTTypeCode ::PUBCOMP = > MQTTOperation ::PUBCOMP ( msgidonly ) ,
_ = > MQTTOperation ::UNASSIGNED ,
} ,
} ;
Ok ( ( & full [ skiplen + len .. ] , msg ) )
}
Err ( e ) = > Err ( e ) ,
} ,
MQTTTypeCode ::SUBSCRIBE = > match parse_subscribe ( protocol_version ) ( input ) {
Ok ( ( _rem , subs ) ) = > {
let msg = MQTTMessage {
header ,
op : MQTTOperation ::SUBSCRIBE ( subs ) ,
} ;
Ok ( ( & full [ skiplen + len .. ] , msg ) )
}
Err ( e ) = > Err ( e ) ,
} ,
MQTTTypeCode ::SUBACK = > match parse_suback ( protocol_version ) ( input ) {
Ok ( ( _rem , suback ) ) = > {
let msg = MQTTMessage {
header ,
op : MQTTOperation ::SUBACK ( suback ) ,
} ;
Ok ( ( & full [ skiplen + len .. ] , msg ) )
}
Err ( e ) = > Err ( e ) ,
} ,
MQTTTypeCode ::UNSUBSCRIBE = > match parse_unsubscribe ( protocol_version ) ( input ) {
Ok ( ( _rem , unsub ) ) = > {
let msg = MQTTMessage {
header ,
op : MQTTOperation ::UNSUBSCRIBE ( unsub ) ,
} ;
Ok ( ( & full [ skiplen + len .. ] , msg ) )
}
Err ( e ) = > Err ( e ) ,
} ,
MQTTTypeCode ::UNSUBACK = > match parse_unsuback ( protocol_version ) ( input ) {
Ok ( ( _rem , unsuback ) ) = > {
let msg = MQTTMessage {
header ,
op : MQTTOperation ::UNSUBACK ( unsuback ) ,
} ;
Ok ( ( & full [ skiplen + len .. ] , msg ) )
}
Err ( e ) = > Err ( e ) ,
} ,
MQTTTypeCode ::PINGREQ | MQTTTypeCode ::PINGRESP = > {
let msg = MQTTMessage {
header ,
op : match message_type {
MQTTTypeCode ::PINGREQ = > MQTTOperation ::PINGREQ ,
MQTTTypeCode ::PINGRESP = > MQTTOperation ::PINGRESP ,
_ = > MQTTOperation ::UNASSIGNED ,
} ,
} ;
Ok ( ( & full [ skiplen + len .. ] , msg ) )
}
MQTTTypeCode ::DISCONNECT = > match parse_disconnect ( len , protocol_version ) ( input ) {
Ok ( ( _rem , disco ) ) = > {
let msg = MQTTMessage {
header ,
op : MQTTOperation ::DISCONNECT ( disco ) ,
} ;
Ok ( ( & full [ skiplen + len .. ] , msg ) )
}
Err ( e ) = > Err ( e ) ,
} ,
MQTTTypeCode ::AUTH = > match parse_auth ( input ) {
Ok ( ( _rem , auth ) ) = > {
let msg = MQTTMessage {
header ,
op : MQTTOperation ::AUTH ( auth ) ,
} ;
Ok ( ( & full [ skiplen + len .. ] , msg ) )
}
Err ( e ) = > Err ( e ) ,
} ,
// Unassigned message type code. Unlikely to happen with
// regular traffic, might be an indication for broken or
// crafted MQTT traffic.
_ = > {
let msg = MQTTMessage {
header ,
op : MQTTOperation ::UNASSIGNED ,
} ;
return Ok ( ( & full [ skiplen + len .. ] , msg ) ) ;
}
}
}
}
pub fn parse_message (
pub fn parse_message (
input : & [ u8 ] , protocol_version : u8 , max_msg_size : usize ,
input : & [ u8 ] , protocol_version : u8 , max_msg_size : usize ,
) -> IResult < & [ u8 ] , MQTTMessage > {
) -> IResult < & [ u8 ] , MQTTMessage > {
@ -500,143 +685,22 @@ pub fn parse_message(
// Parse the contents of the buffer into a single message.
// Parse the contents of the buffer into a single message.
// We reslice the remainder into the portion that we are interested
// We reslice the remainder into the portion that we are interested
// in, according to the length we just parsed. This helps with the
// in, according to the length we just parsed. This helps with the
// complete ! parsers, where we would otherwise need to keep track
// complete () parsers, where we would otherwise need to keep track
// of the already parsed length.
// of the already parsed length.
let rem = & fullrem [ .. len ] ;
let rem = & fullrem [ .. len ] ;
match message_type {
MQTTTypeCode ::CONNECT = > match parse_connect ( rem ) {
// Parse remaining message in buffer. We use complete() to ensure
Ok ( ( _rem , conn ) ) = > {
// we do not request additional content in case of incomplete
let msg = MQTTMessage {
// parsing, but raise an error instead as we should have all the
header ,
// data asked for in the header.
op : MQTTOperation ::CONNECT ( conn ) ,
return complete ( parse_remaining_message (
} ;
input ,
Ok ( ( & input [ skiplen + len .. ] , msg ) )
len ,
}
skiplen ,
Err ( e ) = > Err ( e ) ,
header ,
} ,
message_type ,
MQTTTypeCode ::CONNACK = > match parse_connack ( rem , protocol_version ) {
protocol_version ,
Ok ( ( _rem , connack ) ) = > {
) ) ( rem ) ;
let msg = MQTTMessage {
header ,
op : MQTTOperation ::CONNACK ( connack ) ,
} ;
Ok ( ( & input [ skiplen + len .. ] , msg ) )
}
Err ( e ) = > Err ( e ) ,
} ,
MQTTTypeCode ::PUBLISH = > {
match parse_publish ( rem , protocol_version , header . qos_level > 0 ) {
Ok ( ( _rem , publish ) ) = > {
let msg = MQTTMessage {
header ,
op : MQTTOperation ::PUBLISH ( publish ) ,
} ;
Ok ( ( & input [ skiplen + len .. ] , msg ) )
}
Err ( e ) = > Err ( e ) ,
}
}
MQTTTypeCode ::PUBACK
| MQTTTypeCode ::PUBREC
| MQTTTypeCode ::PUBREL
| MQTTTypeCode ::PUBCOMP = > match parse_msgidonly ( rem , protocol_version ) {
Ok ( ( _rem , msgidonly ) ) = > {
let msg = MQTTMessage {
header ,
op : match message_type {
MQTTTypeCode ::PUBACK = > MQTTOperation ::PUBACK ( msgidonly ) ,
MQTTTypeCode ::PUBREC = > MQTTOperation ::PUBREC ( msgidonly ) ,
MQTTTypeCode ::PUBREL = > MQTTOperation ::PUBREL ( msgidonly ) ,
MQTTTypeCode ::PUBCOMP = > MQTTOperation ::PUBCOMP ( msgidonly ) ,
_ = > MQTTOperation ::UNASSIGNED ,
} ,
} ;
Ok ( ( & input [ skiplen + len .. ] , msg ) )
}
Err ( e ) = > Err ( e ) ,
} ,
MQTTTypeCode ::SUBSCRIBE = > match parse_subscribe ( rem , protocol_version ) {
Ok ( ( _rem , subs ) ) = > {
let msg = MQTTMessage {
header ,
op : MQTTOperation ::SUBSCRIBE ( subs ) ,
} ;
Ok ( ( & input [ skiplen + len .. ] , msg ) )
}
Err ( e ) = > Err ( e ) ,
} ,
MQTTTypeCode ::SUBACK = > match parse_suback ( rem , protocol_version ) {
Ok ( ( _rem , suback ) ) = > {
let msg = MQTTMessage {
header ,
op : MQTTOperation ::SUBACK ( suback ) ,
} ;
Ok ( ( & input [ skiplen + len .. ] , msg ) )
}
Err ( e ) = > Err ( e ) ,
} ,
MQTTTypeCode ::UNSUBSCRIBE = > match parse_unsubscribe ( rem , protocol_version ) {
Ok ( ( _rem , unsub ) ) = > {
let msg = MQTTMessage {
header ,
op : MQTTOperation ::UNSUBSCRIBE ( unsub ) ,
} ;
Ok ( ( & input [ skiplen + len .. ] , msg ) )
}
Err ( e ) = > Err ( e ) ,
} ,
MQTTTypeCode ::UNSUBACK = > match parse_unsuback ( rem , protocol_version ) {
Ok ( ( _rem , unsuback ) ) = > {
let msg = MQTTMessage {
header ,
op : MQTTOperation ::UNSUBACK ( unsuback ) ,
} ;
Ok ( ( & input [ skiplen + len .. ] , msg ) )
}
Err ( e ) = > Err ( e ) ,
} ,
MQTTTypeCode ::PINGREQ | MQTTTypeCode ::PINGRESP = > {
let msg = MQTTMessage {
header ,
op : match message_type {
MQTTTypeCode ::PINGREQ = > MQTTOperation ::PINGREQ ,
MQTTTypeCode ::PINGRESP = > MQTTOperation ::PINGRESP ,
_ = > MQTTOperation ::UNASSIGNED ,
} ,
} ;
return Ok ( ( & input [ skiplen + len .. ] , msg ) ) ;
}
MQTTTypeCode ::DISCONNECT = > match parse_disconnect ( rem , len , protocol_version ) {
Ok ( ( _rem , disco ) ) = > {
let msg = MQTTMessage {
header ,
op : MQTTOperation ::DISCONNECT ( disco ) ,
} ;
Ok ( ( & input [ skiplen + len .. ] , msg ) )
}
Err ( e ) = > Err ( e ) ,
} ,
MQTTTypeCode ::AUTH = > match parse_auth ( rem ) {
Ok ( ( _rem , auth ) ) = > {
let msg = MQTTMessage {
header ,
op : MQTTOperation ::AUTH ( auth ) ,
} ;
Ok ( ( & input [ skiplen + len .. ] , msg ) )
}
Err ( e ) = > Err ( e ) ,
} ,
// Unassigned message type code. Unlikely to happen with
// regular traffic, might be an indication for broken or
// crafted MQTT traffic.
_ = > {
let msg = MQTTMessage {
header ,
op : MQTTOperation ::UNASSIGNED ,
} ;
return Ok ( ( & rem [ len .. ] , msg ) ) ;
}
}
}
}
Err ( err ) = > {
Err ( err ) = > {
return Err ( err ) ;
return Err ( err ) ;