聶永的博客

          記錄工作/學(xué)習(xí)的點點滴滴。

          MQTT-SN協(xié)議亂翻之消息格式

          前言

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

          通用消息格式

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

          消息頭部

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

          備注:

           MQTT-SN不支持消息的分片和重組。底層網(wǎng)絡(luò)所定義數(shù)據(jù)包長度若小于MQTT-SN消息的最大長度,自身進(jìn)行的分片和重組,對MQTT-SN協(xié)議本身不受影響。
          

          MQTT-SN消息類型

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

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

          消息可變部分

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

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

          具體消息格式說明

          網(wǎng)關(guān)周期性會對當(dāng)前網(wǎng)絡(luò)下所有客戶端、節(jié)點進(jìn)行廣播,用于客戶端發(fā)現(xiàn)可用網(wǎng)關(guān)。

          字節(jié)索引 表示內(nèi)容 說明
          0 Length 0x05
          1 MsgType 0x00
          2 GwId 網(wǎng)關(guān)需要吧自身標(biāo)識符包含其中
          3-4 Duration 網(wǎng)關(guān)的下次廣播間隔時長,單位秒

          SEARCHGW

          字節(jié)索引 表示內(nèi)容 說明
          0 Length 0x03
          1 MsgType 0x01
          2 Radius 廣播半徑深度,同時也是只是給當(dāng)前網(wǎng)絡(luò)傳輸層

          客戶端主動尋找網(wǎng)關(guān)進(jìn)行廣播的消息,廣播路徑范圍受限于當(dāng)前網(wǎng)絡(luò)環(huán)境下的客戶端部署密度,比如只有1跳廣播在非常密集的網(wǎng)絡(luò)環(huán)境下客戶端都可以彼此互相訪問。

          GWINFO

          字節(jié)索引 表示內(nèi)容 說明
          0 Length 動態(tài)確定
          1 MsgType 0x02
          2 GwId 網(wǎng)關(guān)Id
          3-n GwAdd* 一個網(wǎng)關(guān)地址,僅僅由客戶端發(fā)出消息時,此字段才存在

          GWINFO作為對SEARCHGW消息的響應(yīng):

          • 若由網(wǎng)關(guān)發(fā)出,則無GwAdd字段
          • 若來自于客戶端,需要包含網(wǎng)關(guān)地址

          CONNECT

          客戶端向網(wǎng)關(guān)發(fā)出建立連接的消息。

          字節(jié)索引 表示內(nèi)容 說明
          0 Length 動態(tài)計算
          1 MsgType 0x04
          2 Flags 標(biāo)志位
          3 ProtocolId 0x01,表示協(xié)議版本和協(xié)議名稱
          4-5 Duration 存活持續(xù)時長
          6-n ClientId 客戶端標(biāo)識符,1-23個字節(jié)表示的字符串

          在CONNECT消息標(biāo)志位具體表示如下:

          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中使用到的標(biāo)志位:

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

          CONNACK

          網(wǎng)關(guān)對客戶端發(fā)出CONNECT消息的響應(yīng)。

          字節(jié)索引 表示內(nèi)容 說明
          0 Length 0x03
          1 MsgType 0x05
          2 ReturnCode 接受值0x00,拒絕為0x01-0x03,具體見上文RecodeCode定義

          WILLTOPICREQ

          根據(jù)客戶端CONNECT標(biāo)志位中WILL字段為true情況下,網(wǎng)關(guān)向客戶端發(fā)出遺囑主題請求,格式如下:

          字節(jié)索引 表示內(nèi)容 說明
          0 Length 0x02
          1 MsgType 0x06

          只有頭部部分,很簡單。

          WILLTOPIC

          客戶端作為網(wǎng)關(guān)WILLTOPICREQ請求響應(yīng)消息。下面是一個正常版本的WILLTOPIC消息:

          字節(jié)索引 表示內(nèi)容 說明
          0 Length 動態(tài)計算
          1 MsgType 0x07
          2 Flags 標(biāo)志位
          3-n WillTopic 遺囑主題

          此時的標(biāo)志位如下

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

          而空的WILLTOPIC也是允許存在的,就兩個字節(jié)表示,用于客戶端請求刪除已存在于服務(wù)器端的對應(yīng)遺囑主題和消息。

          字節(jié)索引 表示內(nèi)容 說明
          0 Length 0x02
          1 MsgType 0x07

          WILLMSGREQ

          根據(jù)客戶端CONNECT標(biāo)志位中WILL字段為真情況下,網(wǎng)關(guān)向客戶端發(fā)出遺囑消息請求,格式如下:

          字節(jié)索引 表示內(nèi)容 說明
          0 Length 0x02
          1 MsgType 0x08

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

          WILLMSG

          客戶端對網(wǎng)關(guān)WILLMSGREQ請求的響應(yīng),從而把遺囑消息傳遞給網(wǎng)關(guān)進(jìn)行保存。

          字節(jié)索引 表示內(nèi)容 說明
          0 Length 動態(tài)計算
          1 MsgType 0x09
          2-n WillMsg 客戶端遺囑

          REGISTER

          • 客戶端-->網(wǎng)關(guān),請求主題(topic name)對應(yīng)的主題標(biāo)識符(topic id)
          • 網(wǎng)關(guān)-->客戶端,通知主題(topic name)已經(jīng)被指派到某個主題標(biāo)識符(topic id)
          字節(jié)索引 表示內(nèi)容 說明
          0 Length 動態(tài)計算
          1 MsgType 0x0A
          2-3 TopicId 客戶端發(fā)出,此值為0x0000;服務(wù)器發(fā)出,需要包含對應(yīng)于Topic Name的主題標(biāo)識符
          4-5 MsgId 自然數(shù),用以標(biāo)識對應(yīng)的REGACK確認(rèn)
          6-n TopicName 主題名稱,不能太長,盡量不要使用通配符

          REGACK

          客戶端或網(wǎng)關(guān)針對REGISTER消息的響應(yīng)。

          字節(jié)索引 表示內(nèi)容 說明
          0 Length 0x07
          1 MsgType 0x0B
          2-3 TopicId 對應(yīng)于Topic Name的主題標(biāo)識符,被用于PUBLISH消息發(fā)布
          4-5 MsgId 自然數(shù),用以標(biāo)識對應(yīng)的REGISTER消息
          6 ReturnCode 0x00被接受,其它值被拒絕

          PUBLISH

          PUBLISH消息用于客戶端或網(wǎng)關(guān)發(fā)布消息用:

          字節(jié)索引 表示內(nèi)容 說明
          0 Length 動態(tài)計算
          1 MsgType 0x0C
          2 Flags 標(biāo)志位
          3-4 TopicId 主題標(biāo)識符
          5-6 MsgId QoS 1-2時需要填充自然值;QoS 0時,值為0x0000
          7-n Data 用于發(fā)布的具體消息內(nèi)容

          標(biāo)識位具體如下:

          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

          標(biāo)識位里面各個字段和MQTT協(xié)議一致,無須多解釋。

          PUBACK

          客戶端/網(wǎng)關(guān)僅僅對QoS 1/2的PUBLISH消息做出響應(yīng)。

          字節(jié)索引 表示內(nèi)容 說明
          0 Length 0x07
          1 MsgType 0x0D
          2-3 TopicId 對應(yīng)PUBLISH消息中TopicId
          4-5 MsgId 自然數(shù),用以標(biāo)識對應(yīng)的REGISTER消息
          6 ReturnCode 0x00被接受,其它值被拒絕,不同值表示不同拒絕理由

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

          PUBREC, PUBREL, PUBCOMP

          只有在PUBLISH消息中QoS 2時,PUBREC, PUBREL, PUBCOMP才會一起登場,否則是沒有出場機(jī)會的。消息格式嘛,都很統(tǒng)一:

          字節(jié)索引 表示內(nèi)容 說明
          0 Length 0x04
          1 MsgType 0x0F/0x10/0x0E
          2-3 MsgId 對應(yīng)PUBLISH消息中的MsgId

          SUBSCRIBE

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

          字節(jié)索引 表示內(nèi)容 說明
          0 Length 動態(tài)計算
          1 MsgType 0x12
          2 Flags 標(biāo)志位
          3-4 MsgId 用于確定對應(yīng)的訂閱確認(rèn)SUBACK消息
          5-N TopicId/TopicName 具體需要根據(jù)Flags標(biāo)志位中TopicIdType進(jìn)行填充

          標(biāo)識位具體如下:

          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

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

          SUBACK

          網(wǎng)關(guān)->客戶端,訂閱處理情況的確認(rèn)回執(zhí),接受訂閱或出于其它原因拒絕之。

          字節(jié)索引 表示內(nèi)容 說明
          0 Length 0x08
          1 MsgType 0x13
          2 Flags 標(biāo)志位
          3-4 TopicId 網(wǎng)關(guān)接受其注冊,此處對應(yīng)具體指派的TopicId
          5-6 MsgId SUBSCRIBE消息中對應(yīng)MsgId值
          7 ReturnCode 0x00被接受,其它值被拒絕

          標(biāo)識位具體如下:

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

          SUBACK消息標(biāo)志位中QoS為網(wǎng)關(guān)根據(jù)實際情況授權(quán)后的QoS具體值,這也應(yīng)該是客戶端需要知道并處理的。

          UNSUBSCRIBE

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

          字節(jié)索引 表示內(nèi)容 說明
          0 Length 動態(tài)計算
          1 MsgType 0x14
          2 Flags 標(biāo)志位
          3-4 MsgId 用于確定對應(yīng)的退訂確認(rèn)UNSUBACK消息
          5-N TopicId/TopicName 具體需要根據(jù)Flags標(biāo)志位中TopicIdType進(jìn)行填充

          標(biāo)識位具體如下:

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

          UNSUBSCRIBE消息標(biāo)志位中唯一可用屬性TopicIdType決定了UNSUBSCRIBE消息中TopicId/TopicName字段具體填充值。

          UNSUBACK

          網(wǎng)關(guān)->客戶端,取消訂閱處理情況的確認(rèn)回執(zhí),很簡單,4個字節(jié)表示。

          字節(jié)索引 表示內(nèi)容 說明
          0 Length 0x04
          1 MsgType 0x15
          2-3 MsgId UNSUBSCRIBE消息中對應(yīng)MsgId值

          PINGREQ

          和MQTT協(xié)議中的PINGREQ一致,存活檢測。

          字節(jié)索引 表示內(nèi)容 說明
          0 Length 動態(tài)計算
          1 MsgType 0x16
          2-N ClientId 可選項,表示客戶端休眠狀態(tài)轉(zhuǎn)換為喚醒狀態(tài)用于檢查網(wǎng)關(guān)是否為其緩存消息

          PINGRESP

          接受PINGREQ消息的一方,如網(wǎng)關(guān)響應(yīng)PINGRESP消息表示自己現(xiàn)在運行OK。

          另外一個意圖,若喚醒狀態(tài)客戶端發(fā)送PINGREQ消息之后,直接收到PINGRESP消息,表示網(wǎng)關(guān)當(dāng)前暫時沒有為其緩存的消息可供發(fā)送。

          字節(jié)索引 表示內(nèi)容 說明
          0 Length 0x02
          1 MsgType 0x17

          很簡單,兩個字節(jié)表示足矣。

          DISCONNECT

          字節(jié)索引 表示內(nèi)容 說明
          0 Length 動態(tài)計算
          1 MsgType 0x18
          2-3 Duration 可選項,表示客戶端即將進(jìn)入睡眠狀態(tài)的持續(xù)時間值
          • 客戶端->網(wǎng)關(guān),客戶端主動關(guān)閉當(dāng)前連接,網(wǎng)關(guān)響應(yīng)確認(rèn)消息。只有表示自己進(jìn)入睡眠狀態(tài)的客戶端,才會在DISCONNECT消息中附加Duration持續(xù)字段。
          • 網(wǎng)關(guān)->客戶端,網(wǎng)關(guān)由于異常主動通知客戶端關(guān)閉兩者之間連接,客戶端接收到DISCONNECT時需要發(fā)送CONNECT消息到網(wǎng)關(guān),重試重新建立連接。沒有Duration字段填充。

          網(wǎng)關(guān)接收到要進(jìn)入休眠狀態(tài)的客戶端發(fā)送的包含有Duration字段DISCONNECT消息時,可以直接返回2個字節(jié)的(不能包含有Duration字段)DISCONNECT消息以示確認(rèn)。

          WILLTOPICUPD

          客戶端發(fā)送請求網(wǎng)關(guān)更新其遺囑主題。

          字節(jié)索引 表示內(nèi)容 說明
          0 Length 動態(tài)計算
          1 MsgType 0x1A
          2 Flags 標(biāo)志位
          3-N WillTopic 用于更新的遺囑主題

          標(biāo)識位具體如下:

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

          協(xié)議規(guī)定只有兩個字節(jié)空WILLTOPICUPD也是允許存在的,存在意義用于客戶端請求網(wǎng)關(guān)刪除已保存的遺囑主題和遺囑消息等。

          字節(jié)索引 表示內(nèi)容 說明
          0 Length 0x02
          1 MsgType 0x1A

          WILLTOPICRESP

          WILLTOPICRESP為網(wǎng)關(guān)收到WILLTOPICUPD后作出的應(yīng)答消息。

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

          WILLMSGUPD

          字節(jié)索引 表示內(nèi)容 說明
          0 Length 動態(tài)計算
          1 MsgType 0x1C
          2-N WillMsg 用于更新的遺囑消息

          客戶端->網(wǎng)關(guān),確認(rèn)更新的遺囑消息。

          WILLMSGRESP

          WILLMSGRESP為網(wǎng)關(guān)收到WILLMSGUPD后作出的應(yīng)答消息。

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

          轉(zhuǎn)發(fā)封裝

          在MQTT-SN架構(gòu)圖中,MQTT-SN Forwarder轉(zhuǎn)發(fā)器適用于客戶端無法直接訪問網(wǎng)關(guān)或當(dāng)前傳感器網(wǎng)絡(luò)區(qū)域中不存在網(wǎng)關(guān)時,轉(zhuǎn)發(fā)器作用就體現(xiàn)出來了:

          1. 接收MQTT-SN客戶端消息封裝后轉(zhuǎn)發(fā)給上游網(wǎng)關(guān)
          2. 解封上游網(wǎng)關(guān)所發(fā)送消息,直接發(fā)送給對應(yīng)客戶端

          轉(zhuǎn)發(fā)器作用于消息的封裝轉(zhuǎn)發(fā),解封發(fā)送,針對消息不做修改。

          轉(zhuǎn)發(fā)器對MQTT-SN消息封裝格式:

          字節(jié)索引 表示內(nèi)容 說明
          0 Length 十進(jìn)制表示長度就是N
          1 MsgType 0xFE
          2 Ctrl 包含網(wǎng)關(guān)和轉(zhuǎn)發(fā)器之間的控制交換信息,主要是前兩位包含了半徑范圍
          3-N Wireless Node Id 標(biāo)識所發(fā)目的或需要接收封裝消息的無線節(jié)點
          N+1-M MQTT-SN message 一個MQTT-SN消息消息

          無線節(jié)點Id(Wireless Node Id):

          • 轉(zhuǎn)發(fā)器->網(wǎng)關(guān),無線節(jié)點Id為轉(zhuǎn)發(fā)器所在的無線節(jié)點Id,便于告知網(wǎng)關(guān)轉(zhuǎn)發(fā)器位置
          • 網(wǎng)關(guān)->轉(zhuǎn)發(fā)器,無線節(jié)點Id為網(wǎng)關(guān)的無線節(jié)點Id

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

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

          小結(jié)

          MQTT-SN 1.2規(guī)范中所定義消息格式介紹完畢,下一篇將對MQTT-SN主要流程功、能進(jìn)行闡述。

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

          評論

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

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

          公告

          所有文章皆為原創(chuàng),若轉(zhuǎn)載請標(biāo)明出處,謝謝~

          新浪微博,歡迎關(guān)注:

          導(dǎo)航

          <2016年5月>
          24252627282930
          1234567
          891011121314
          15161718192021
          22232425262728
          2930311234

          統(tǒng)計

          常用鏈接

          留言簿(58)

          隨筆分類(130)

          隨筆檔案(151)

          個人收藏

          最新隨筆

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 马尔康县| 资中县| 塔河县| 商河县| 铅山县| 旺苍县| 濮阳县| 象州县| 玉门市| 颍上县| 当阳市| 宜昌市| 涡阳县| 新宁县| 邹城市| 望奎县| 海盐县| 农安县| 平谷区| 精河县| 绥宁县| 沭阳县| 清苑县| 绵竹市| 泰州市| 新和县| 辉县市| 阿拉尔市| 新泰市| 富蕴县| 岢岚县| 琼海市| 怀远县| 陆丰市| 内丘县| 安平县| 瑞昌市| 冷水江市| 澳门| 长垣县| 开鲁县|