聶永的博客

          記錄工作/學習的點點滴滴。

          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主要流程功、能進行闡述。

          posted on 2015-01-08 21:52 nieyong 閱讀(6754) 評論(1)  編輯  收藏 所屬分類: MQTT

          評論

          # re: MQTT-SN協議亂翻之消息格式[未登錄] 2016-05-16 21:14 Echo

          大俠,關于MQTT-SN的網關發現有一處地方不大明白,還請指點。 ADVERTISE這個消息只發送的是GW的ID, client收到該消息之后,怎么知道GW的地址呢(比如GW的IP+Port)。 另外GWINFO這個消息里面,只有當client發出時,才包含地址,GW發出時不包含地址。 這樣豈不是client都沒辦法知道GW的地址啊? 謝謝  回復  更多評論   

          公告

          所有文章皆為原創,若轉載請標明出處,謝謝~

          新浪微博,歡迎關注:

          導航

          <2015年1月>
          28293031123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          統計

          常用鏈接

          留言簿(58)

          隨筆分類(130)

          隨筆檔案(151)

          個人收藏

          最新隨筆

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 庄浪县| 兴国县| 寿光市| 神木县| 仪征市| 土默特左旗| 铜川市| 柘城县| 浦江县| 阆中市| 康乐县| 南昌县| 仁化县| 科尔| 博爱县| 陵川县| 布尔津县| 新建县| 济南市| 城固县| 高碑店市| 平山县| 兰溪市| 雅安市| 伊宁市| 民权县| 乌拉特中旗| 秭归县| 丰县| 四子王旗| 庆阳市| 莲花县| 敦煌市| 平顶山市| 固始县| 武威市| 炎陵县| 乌什县| 梅河口市| 靖远县| 穆棱市|