Skip to main content

mqtt_frame/
packet.rs

1use bytes::Bytes;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub enum ProtocolLevel {
5    V311 = 4,
6    V5 = 5,
7}
8
9#[derive(Debug, Clone, PartialEq, Eq)]
10pub enum Property {
11    PayloadFormatIndicator(u8),
12    MessageExpiryInterval(u32),
13    TopicAlias(u16),
14    ResponseTopic(String),
15    CorrelationData(Vec<u8>),
16    UserProperty(String, String),
17    SubscriptionIdentifier(u32),
18    ContentType(String),
19}
20
21#[derive(Debug, Clone, PartialEq, Eq)]
22pub enum MqttPacket {
23    Connect(Connect),
24    ConnAck(ConnAck),
25    Publish(Publish),
26    PubAck(PubAck),
27    PubRec(PubRec),
28    PubRel(PubRel),
29    PubComp(PubComp),
30    Subscribe(Subscribe),
31    SubAck(SubAck),
32    Unsubscribe(Unsubscribe),
33    UnsubAck(UnsubAck),
34    PingReq,
35    PingResp,
36    Disconnect,
37}
38
39impl MqttPacket {
40    pub fn packet_type(&self) -> u8 {
41        match self {
42            MqttPacket::Connect(_) => 1,
43            MqttPacket::ConnAck(_) => 2,
44            MqttPacket::Publish(_) => 3,
45            MqttPacket::PubAck(_) => 4,
46            MqttPacket::PubRec(_) => 5,
47            MqttPacket::PubRel(_) => 6,
48            MqttPacket::PubComp(_) => 7,
49            MqttPacket::Subscribe(_) => 8,
50            MqttPacket::SubAck(_) => 9,
51            MqttPacket::Unsubscribe(_) => 10,
52            MqttPacket::UnsubAck(_) => 11,
53            MqttPacket::PingReq => 12,
54            MqttPacket::PingResp => 13,
55            MqttPacket::Disconnect => 14,
56        }
57    }
58}
59
60#[derive(Debug, Clone, PartialEq, Eq)]
61pub struct Connect {
62    pub protocol_level: ProtocolLevel,
63    pub client_id: String,
64    pub clean_session: bool,
65    pub keep_alive: u16,
66    // Note: We ignore Will, Username, and Password for now in this MVP edge ingest
67}
68
69#[derive(Debug, Clone, PartialEq, Eq)]
70pub struct ConnAck {
71    pub session_present: bool,
72    pub return_code: u8,
73}
74
75#[derive(Debug, Clone, PartialEq, Eq)]
76pub struct Publish {
77    pub dup: bool,
78    pub qos: u8,
79    pub retain: bool,
80    pub topic: String,
81    pub packet_id: Option<u16>, // Only present if QoS > 0
82    pub properties: Vec<Property>,
83    pub payload: Bytes,
84}
85
86#[derive(Debug, Clone, PartialEq, Eq)]
87pub struct PubAck {
88    pub packet_id: u16,
89    /// MQTT v5 reason code. Ignored for v3.1.1.
90    /// - `None` or `Some(0x00)` = Success
91    /// - `Some(0x80)` = Unspecified error
92    /// - `Some(0x83)` = Implementation specific error
93    /// - `Some(0x97)` = Quota exceeded
94    /// - `Some(0x99)` = Payload format invalid
95    pub reason_code: Option<u8>,
96}
97
98#[derive(Debug, Clone, PartialEq, Eq)]
99pub struct PubRec {
100    pub packet_id: u16,
101}
102
103#[derive(Debug, Clone, PartialEq, Eq)]
104pub struct PubRel {
105    pub packet_id: u16,
106}
107
108#[derive(Debug, Clone, PartialEq, Eq)]
109pub struct PubComp {
110    pub packet_id: u16,
111}
112
113#[derive(Debug, Clone, PartialEq, Eq)]
114pub struct Subscribe {
115    pub packet_id: u16,
116    pub filters: Vec<(String, u8)>, // (topic filter, max qos)
117}
118
119#[derive(Debug, Clone, PartialEq, Eq)]
120pub struct SubAck {
121    pub packet_id: u16,
122    pub return_codes: Vec<u8>,
123}
124
125#[derive(Debug, Clone, PartialEq, Eq)]
126pub struct Unsubscribe {
127    pub packet_id: u16,
128    pub filters: Vec<String>,
129}
130
131#[derive(Debug, Clone, PartialEq, Eq)]
132pub struct UnsubAck {
133    pub packet_id: u16,
134}