MQTT-SN協議亂翻之消息格式

前言

緊接着上篇初步介紹,本文爲第二篇,主要梳理MQTT-SN 1.2協議中定義的消息格式。

通用消息格式

消息頭 其它可變部分
2/4字節表示 N字節組成

消息頭部

長度 消息類型
1或3個字節 1個字節
  • 長度要麼是1個字節,要麼3個字節表示,並且自身也會包含在其內。一個字節可表示256長度,一般情況下,完全夠用了。 
  • 只需要判斷第一個字節是否爲 0x01,若是那麼長度爲3個字節表示,剩下的兩個字節會表示真正的消息長度,最大長度爲65535 
  • 否則長度就是一個字節表示,256個長度,大部分消息長度都是一個字節,除非特別提醒 

備註:

 MQTT-SN不支持消息的分片和重組。底層網絡所定義數據包長度若小於MQTT-SN消息的最大長度,自身進行的分片和重組,對MQTT-SN協議本身不受影響。

MQTT-SN消息類型

MQTT-SN定義的消息類型數量衆多,超過25個,感覺有些頭大。

消息類型值 消息類型名稱 說明
0x00 ADVERTISE 廣播消息
0x01 SEARCHGW 尋找網關
0x02 GWINFO 網關信息
0x03 reserved 沒有使用到
0x04 CONNECT 發起連接
0x05 CONNACK 連接確認
0x06 WILLTOPICREQ 遺囑主題請求
0x07 WILLTOPIC 遺囑主題確認
0x08 WILLMSGREQ 遺囑消息請求
0x09 WILLMSG 遺囑消息確認
0x0A REGISTER 註冊主題
0x0B REGACK 註冊確認
0x0C PUBLISH 發佈消息
0x0D PUBACK 發佈確認
0x0E PUBCOMP 發佈環節消息
0x0F PUBREC 發佈環節消息
0x10 PUBREL 發佈環節消息
0x11 reserved 保留字段
0x12 SUBSCRIBE 訂閱主題
0x13 SUBACK 訂閱確認
0x14 UNSUBSCRIBE 退訂
0x15 UNSUBACK 退訂確認
0x16 PINGREQ Ping請求
0x17 PINGRESP Ping響應
0x18 DISCONNECT 斷開
0x19 reserved 保留字段
0x1A WILLTOPICUPD 遺囑主題更新
0x1B WILLTOPICRESP 遺囑主題更新確認
0x1C WILLMSGUPD 遺囑消息更新
0x1D WILLMSGRESP 遺囑消息更新確認
0x1E-0xFD reserved 保留字段
0xFE 轉發封裝標誌 用於轉發

消息可變部分

可變字段很多,與MQTT相比,多了:

  1. 持續時長字段(Duration) 
  2. 標識符Flags有所不同,下面表格進行說明 
  3. 網關地址(GwAdd),可變長度,但依賴於底層網絡,在ZigBee網絡中2個字節長度 
  4. 一個字節網關Id(GwId) 
  5. 協議Id(ProtocolId),一個字節,唯一值 0x01,統一表示協議名稱和協議名稱 
  6. 廣播路徑跳數(廣播路徑深度/廣播輻射範圍),Radius,一個字節表示,0x00表示廣播給當前網絡中所有節點 
  7. CONNECT/REGISTER/SUBSCRIBE/PUBLISH等消息對應回執中都會包含返回碼Recode Code,見下表格 
返回值 返回值含義
0x00 接受請求(Accepted)
0x01 因擁塞拒絕(Rejected: congestion),一般需要接收方等待T_WAIT時間長
0x02 因非法主題標識符拒絕(Rejected: invalid topic ID)
0x03 因不支持拒絕(Rejected: not supported)
0x04 - 0xFF 保留,沒有使用到

具體消息格式說明

網關週期性會對當前網絡下所有客戶端、節點進行廣播,用於客戶端發現可用網關。

字節索引 表示內容 說明
0 Length 0x05
1 MsgType 0x00
2 GwId 網關需要吧自身標識符包含其中
3-4 Duration 網關的下次廣播間隔時長,單位秒

SEARCHGW

字節索引 表示內容 說明
0 Length 0x03
1 MsgType 0x01
2 Radius 廣播半徑深度,同時也是隻是給當前網絡傳輸層

客戶端主動尋找網關進行廣播的消息,廣播路徑範圍受限於當前網絡環境下的客戶端部署密度,比如只有1跳廣播在非常密集的網絡環境下客戶端都可以彼此互相訪問。

GWINFO

字節索引 表示內容 說明
0 Length 動態確定
1 MsgType 0x02
2 GwId 網關Id
3-n GwAdd* 一個網關地址,僅僅由客戶端發出消息時,此字段才存在

GWINFO作爲對SEARCHGW消息的響應:

  • 若由網關發出,則無GwAdd字段 
  • 若來自於客戶端,需要包含網關地址 

CONNECT

客戶端向網關發出建立連接的消息。

字節索引 表示內容 說明
0 Length 動態計算
1 MsgType 0x04
2 Flags 標誌位
3 ProtocolId 0x01,表示協議版本和協議名稱
4-5 Duration 存活持續時長
6-n ClientId 客戶端標識符,1-23個字節表示的字符串

在CONNECT消息標誌位具體表示如下:

DUP QoS Retain Will CleanSession TopicIdType
bit 7 6,5 4 3 2 1,0
X X X 0/1 0/1 X
  • 0/1 表示具體值待定 
  • X 表示沒有使用到 

在Flags中使用到的標誌位:

  1. Will:若爲1,客戶端會在稍後請求遺囑主題和遺囑消息 
  2. CleanSession:不但表示訂閱持久化,同時也被可擴展到遺囑主題和遺囑消息中 

CONNACK

網關對客戶端發出CONNECT消息的響應。

字節索引 表示內容 說明
0 Length 0x03
1 MsgType 0x05
2 ReturnCode 接受值0x00,拒絕爲0x01-0x03,具體見上文RecodeCode定義

WILLTOPICREQ

根據客戶端CONNECT標誌位中WILL字段爲true情況下,網關向客戶端發出遺囑主題請求,格式如下:

字節索引 表示內容 說明
0 Length 0x02
1 MsgType 0x06

只有頭部部分,很簡單。

WILLTOPIC

客戶端作爲網關WILLTOPICREQ請求響應消息。下面是一個正常版本的WILLTOPIC消息:

字節索引 表示內容 說明
0 Length 動態計算
1 MsgType 0x07
2 Flags 標誌位
3-n WillTopic 遺囑主題

此時的標誌位如下

DUP QoS Retain Will CleanSession TopicIdType
bit 7 6,5 4 3 2 1,0
X 0x00-0x02 0/1 X X X

而空的WILLTOPIC也是允許存在的,就兩個字節表示,用於客戶端請求刪除已存在於服務器端的對應遺囑主題和消息。

字節索引 表示內容 說明
0 Length 0x02
1 MsgType 0x07

WILLMSGREQ

根據客戶端CONNECT標誌位中WILL字段爲真情況下,網關向客戶端發出遺囑消息請求,格式如下:

字節索引 表示內容 說明
0 Length 0x02
1 MsgType 0x08

只有頭部部分,沒有別的。

WILLMSG

客戶端對網關WILLMSGREQ請求的響應,從而把遺囑消息傳遞給網關進行保存。

字節索引 表示內容 說明
0 Length 動態計算
1 MsgType 0x09
2-n WillMsg 客戶端遺囑

REGISTER

  • 客戶端-->網關,請求主題(topic name)對應的主題標識符(topic id) 
  • 網關-->客戶端,通知主題(topic name)已經被指派到某個主題標識符(topic id) 
字節索引 表示內容 說明
0 Length 動態計算
1 MsgType 0x0A
2-3 TopicId 客戶端發出,此值爲0x0000;服務器發出,需要包含對應於Topic Name的主題標識符
4-5 MsgId 自然數,用以標識對應的REGACK確認
6-n TopicName 主題名稱,不能太長,儘量不要使用通配符

REGACK

客戶端或網關針對REGISTER消息的響應。

字節索引 表示內容 說明
0 Length 0x07
1 MsgType 0x0B
2-3 TopicId 對應於Topic Name的主題標識符,被用於PUBLISH消息發佈
4-5 MsgId 自然數,用以標識對應的REGISTER消息
6 ReturnCode 0x00被接受,其它值被拒絕

PUBLISH

PUBLISH消息用於客戶端或網關發佈消息用:

字節索引 表示內容 說明
0 Length 動態計算
1 MsgType 0x0C
2 Flags 標誌位
3-4 TopicId 主題標識符
5-6 MsgId QoS 1-2時需要填充自然值;QoS 0時,值爲0x0000
7-n Data 用於發佈的具體消息內容

標識位具體如下:

DUP QoS Retain Will CleanSession TopicIdType
bit 7 6,5 4 3 2 1,0
0/1 0x00-0x02 0/1 X X 0b00/0b01/0b10

標識位裏面各個字段和MQTT協議一致,無須多解釋。

PUBACK

客戶端/網關僅僅對QoS 1/2的PUBLISH消息做出響應。

字節索引 表示內容 說明
0 Length 0x07
1 MsgType 0x0D
2-3 TopicId 對應PUBLISH消息中TopicId
4-5 MsgId 自然數,用以標識對應的REGISTER消息
6 ReturnCode 0x00被接受,其它值被拒絕,不同值表示不同拒絕理由

處理PUBLISH消息異常?在PUBACK消息中的ReturnCode字段中以相應值體現出來,這就要求接收者處理拒絕理由。

PUBREC, PUBREL, PUBCOMP

只有在PUBLISH消息中QoS 2時,PUBREC, PUBREL, PUBCOMP纔會一起登場,否則是沒有出場機會的。消息格式嘛,都很統一:

字節索引 表示內容 說明
0 Length 0x04
1 MsgType 0x0F/0x10/0x0E
2-3 MsgId 對應PUBLISH消息中的MsgId

SUBSCRIBE

SUBSCRIBE用於客戶端訂閱某個主題的消息。

字節索引 表示內容 說明
0 Length 動態計算
1 MsgType 0x12
2 Flags 標誌位
3-4 MsgId 用於確定對應的訂閱確認SUBACK消息
5-N TopicId/TopicName 具體需要根據Flags標誌位中TopicIdType進行填充

標識位具體如下:

DUP QoS Retain Will CleanSession TopicIdType
bit 7 6,5 4 3 2 1,0
0/1 0x00-0x02 X X X 0b00/0b01/0b10

此處,標誌位中TopicIdType決定了SUBSCRIBE消息中TopicId/TopicName字段具體填充值:預定義topic id,或短小兩個字符表示主題(topic name),或直接填寫主題。

SUBACK

網關->客戶端,訂閱處理情況的確認回執,接受訂閱或出於其它原因拒絕之。

字節索引 表示內容 說明
0 Length 0x08
1 MsgType 0x13
2 Flags 標誌位
3-4 TopicId 網關接受其註冊,此處對應具體指派的TopicId
5-6 MsgId SUBSCRIBE消息中對應MsgId值
7 ReturnCode 0x00被接受,其它值被拒絕

標識位具體如下:

DUP QoS Retain Will CleanSession TopicIdType
bit 7 6,5 4 3 2 1,0
X 0x00-0x02 X X X X

SUBACK消息標誌位中QoS爲網關根據實際情況授權後的QoS具體值,這也應該是客戶端需要知道並處理的。

UNSUBSCRIBE

UNSUBSCRIBE用於客戶端取消訂閱某個主題的消息。

字節索引 表示內容 說明
0 Length 動態計算
1 MsgType 0x14
2 Flags 標誌位
3-4 MsgId 用於確定對應的退訂確認UNSUBACK消息
5-N TopicId/TopicName 具體需要根據Flags標誌位中TopicIdType進行填充

標識位具體如下:

DUP QoS Retain Will CleanSession TopicIdType
bit 7 6,5 4 3 2 1,0
X X X X X 0b00/0b01/0b10

UNSUBSCRIBE消息標誌位中唯一可用屬性TopicIdType決定了UNSUBSCRIBE消息中TopicId/TopicName字段具體填充值。

UNSUBACK

網關->客戶端,取消訂閱處理情況的確認回執,很簡單,4個字節表示。

字節索引 表示內容 說明
0 Length 0x04
1 MsgType 0x15
2-3 MsgId UNSUBSCRIBE消息中對應MsgId值

PINGREQ

和MQTT協議中的PINGREQ一致,存活檢測。

字節索引 表示內容 說明
0 Length 動態計算
1 MsgType 0x16
2-N ClientId 可選項,表示客戶端休眠狀態轉換爲喚醒狀態用於檢查網關是否爲其緩存消息

PINGRESP

接受PINGREQ消息的一方,如網關響應PINGRESP消息表示自己現在運行OK。

另外一個意圖,若喚醒狀態客戶端發送PINGREQ消息之後,直接收到PINGRESP消息,表示網關當前暫時沒有爲其緩存的消息可供發送。

字節索引 表示內容 說明
0 Length 0x02
1 MsgType 0x17

很簡單,兩個字節表示足矣。

DISCONNECT

字節索引 表示內容 說明
0 Length 動態計算
1 MsgType 0x18
2-3 Duration 可選項,表示客戶端即將進入睡眠狀態的持續時間值
  • 客戶端->網關,客戶端主動關閉當前連接,網關響應確認消息。只有表示自己進入睡眠狀態的客戶端,纔會在DISCONNECT消息中附加Duration持續字段。 
  • 網關->客戶端,網關由於異常主動通知客戶端關閉兩者之間連接,客戶端接收到DISCONNECT時需要發送CONNECT消息到網關,重試重新建立連接。沒有Duration字段填充。 

網關接收到要進入休眠狀態的客戶端發送的包含有Duration字段DISCONNECT消息時,可以直接返回2個字節的(不能包含有Duration字段)DISCONNECT消息以示確認。

WILLTOPICUPD

客戶端發送請求網關更新其遺囑主題。

字節索引 表示內容 說明
0 Length 動態計算
1 MsgType 0x1A
2 Flags 標誌位
3-N WillTopic 用於更新的遺囑主題

標識位具體如下:

DUP QoS Retain Will CleanSession TopicIdType
bit 7 6,5 4 3 2 1,0
X 0x00-0x02 0/1 X X X

協議規定只有兩個字節空WILLTOPICUPD也是允許存在的,存在意義用於客戶端請求網關刪除已保存的遺囑主題和遺囑消息等。

字節索引 表示內容 說明
0 Length 0x02
1 MsgType 0x1A

WILLTOPICRESP

WILLTOPICRESP爲網關收到WILLTOPICUPD後作出的應答消息。

字節索引 表示內容 說明
0 Length 0x03
1 MsgType 0x1B
2 ReturnCode 0x00被接受,其它值被拒絕

WILLMSGUPD

字節索引 表示內容 說明
0 Length 動態計算
1 MsgType 0x1C
2-N WillMsg 用於更新的遺囑消息

客戶端->網關,確認更新的遺囑消息。

WILLMSGRESP

WILLMSGRESP爲網關收到WILLMSGUPD後作出的應答消息。

字節索引 表示內容 說明
0 Length 0x03
1 MsgType 0x1D
2 ReturnCode 0x00被接受,其它值被拒絕

轉發封裝

在MQTT-SN架構圖中,MQTT-SN Forwarder轉發器適用於客戶端無法直接訪問網關或當前傳感器網絡區域中不存在網關時,轉發器作用就體現出來了:

  1. 接收MQTT-SN客戶端消息封裝後轉發給上游網關 
  2. 解封上游網關所發送消息,直接發送給對應客戶端 

轉發器作用於消息的封裝轉發,解封發送,針對消息不做修改。

轉發器對MQTT-SN消息封裝格式:

字節索引 表示內容 說明
0 Length 十進制表示長度就是N
1 MsgType 0xFE
2 Ctrl 包含網關和轉發器之間的控制交換信息,主要是前兩位包含了半徑範圍
3-N Wireless Node Id 標識所發目的或需要接收封裝消息的無線節點
N+1-M MQTT-SN message 一個MQTT-SN消息消息

無線節點Id(Wireless Node Id):

  • 轉發器->網關,無線節點Id爲轉發器所在的無線節點Id,便於告知網關轉發器位置 
  • 網關->轉發器,無線節點Id爲網關的無線節點Id 

控制交換字段Ctrl,單個字節,位表示含義:

bit 7,2 1,0
X 0x00-0x03

小結

MQTT-SN 1.2規範中所定義消息格式介紹完畢,下一篇將對MQTT-SN主要流程功、能進行闡述。

發佈了34 篇原創文章 · 獲贊 29 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章