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相比,多了:
- 持續(xù)時長字段(Duration)
- 標(biāo)識符Flags有所不同,下面表格進(jìn)行說明
- 網(wǎng)關(guān)地址(GwAdd),可變長度,但依賴于底層網(wǎng)絡(luò),在ZigBee網(wǎng)絡(luò)中2個字節(jié)長度
- 一個字節(jié)網(wǎng)關(guān)Id(GwId)
- 協(xié)議Id(ProtocolId),一個字節(jié),唯一值 0x01,統(tǒng)一表示協(xié)議名稱和協(xié)議名稱
- 廣播路徑跳數(shù)(廣播路徑深度/廣播輻射范圍),Radius,一個字節(jié)表示,0x00表示廣播給當(dāng)前網(wǎng)絡(luò)中所有節(jié)點
- 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 | 保留,沒有使用到 |
具體消息格式說明
ADVERTISE
網(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)志位:
- Will:若為1,客戶端會在稍后請求遺囑主題和遺囑消息
- 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)出來了:
- 接收MQTT-SN客戶端消息封裝后轉(zhuǎn)發(fā)給上游網(wǎng)關(guān)
- 解封上游網(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