MQTT协议接入OneNET (一)

MQTT协议是一个面向物联网应用的即时通信协议,使用TCP/IP提供网络连接,能够对负载内容实现消息屏蔽传输,开销小,可以有效降低网络流量。MQTT协议适用于设备和平台需要保持长连接的使用场景,MQTT特点在于可以实现设备间的消息单播以及组播,可以不依赖于其他服务(下发命令服务,推送服务等)实现让设备以应用服务器的方式对真实设备进行管理和控制。

正因为MQTT协议拥有这些特点,现在成文了各个物联网云平台支持的最广泛的协议,百度、阿里、亚马逊、OneNet等国内外物联网云服务提供商均支持该协议,所以在做物联网开发的过程中,有必要学习和了解一下该协议。接下来我们就以OneNET的MQTT接入协议为例,学习一下该协议个通讯。

 

硬件连接环境:麒麟座迷你开发板用STlink连接到PC的USB口

软件开发环境:Keil MDK5.25编辑麒麟座mini开发板官方例程”6.ESP8266-MQTT_TYPE3-LED

网络环境:PC机以太网卡连接路由器接入互联网,Windows10无线网卡建立热点,麒麟座开发板的ESP8266经过热点接入互联网。

抓包工具:Wireshart抓取以太网卡的数据包,设置过滤条件为”ip.addr == 183.230.40.39”,只显示与OneNET MQTT服务器通讯的数据包。

模拟器:simulate-device.exe,在PC上可以模拟嵌入式设备通讯。

参考文档:OneNET官方MQTT文档:”MQTT.docx”,MQTT中文文档MQTT.PDF

交互过程:连接权鉴,数据上报,命令下发,断开连接。

 

一、连接权鉴

    首先在修改官方例程中的参数信息,把WiFi名称和密码改成使用PC无线网卡模拟的热点网络,OneNET服务器的IP地址和端口号确保为”183.230.40.39”和”6002”,onenet.c中的PROID、DEVID、AUTH_INFO修改为项目中的真实值。

 

0001.png

 

0002.png

 

 

   编译并下载程序到麒麟座迷你开发板,在PC上使用Wireshark开始抓取以太网卡的数据包,设置过滤条件为”ip.addr == 183.230.40.39”,只显示与OneNET MQTT服务器通讯的数据包。给麒麟座开发板上电,等待几秒钟后,就可以看到开发板与OneNET服务器通讯的数据包了。

 

0003.png

 

 

 

      数据包中前三帧为开发板与OneNET服务器建立TCP连接的三次握手信息,这个是开发板给ESP8266发送建立TCP连接指令后,ESP8266与服务器之间自动建立的。

      数据包的第四帧至第五帧为麒麟座开发板项OneNET发送的鉴权信息和服务区应答。第六帧和第七帧是OneNET服务器返回的鉴权结果信息和ESP8266的应答。

      在以上过程中,我们作为设备端开发人员,只需要了解第四帧的鉴权信息发送和第六帧的服务器鉴权结果返回就可以了。

      接下来重点分析第四帧数据,次帧数据总计有114字节,去除以太网头14字节,IP头20字节,TCP头20字节,剩余的TCP有效载荷共计60字节。

 

0004.png

 

 

   根据MQTT报文协议中规定,每一个MQTT包总共包含三部分:

0005.png

 

 

 

1、Fixed Header部分定义如下:

0006.png

 

      根据抓包的数据,TCP负载的第一个字节是0x10,对应表格可以得知,MQTT Packet Type值为1,名称为CONNECT,其功能是客户端请求与服务器建立连接。其第二个字节的0x3a为表格中的Remaining Length字段,为数据包的长度。

 

 

      根据MQTT协议规定,剩余长度(Remaining Length)表示当前报文剩余部分的字节数,包括可变报头和负载的数据。剩余长度不包括用于编码剩余长度字段本身的字节数。0x3a为十进制的58,这个数正好是TCP负载的60字节减去固定报头的两个字节长度。至于如何判断剩余长度占用的字节数,MQTT协议是这么规定的:

 

 

 

 

      剩余长度字段使用一个变长度编码方案,对小于128的值它使用单字节编码。更大的值按下面的方式处理。低7位有效位用于编码数据,最高有效位用于指示是否有更多的字节。因此每个字节可以编码128个数值和一个延续位(continuation bit)。剩余长度字段最大4个字节。

 

 

 

 

      根据以上定义,0x3a的二进制最高位为0,可以判定数据长度为1字节。

 

 

 

 

      固定报头的部分分析完成后,根据下表进行判断:

 

0007.png

 

 

 

2、CONNECT类型的消息是有可变报头和负载的。对于可变报头部分,按照以下格式编码:

 

0008.png        对照抓包数据:

0009.png

 

 

 

      其中byte1-byte6是固定值,表格与数据完全对应。Byte7表示MQTT协议版本,这个必须固定为4,即3.1.1版,OneNET只支持这一版本协议,不支持更早版本的协议。

 

      在Byte8中,user flag与password flag平台不允许匿名登陆,因此这两个标志位在连接时必须设置为1,否则认为协议错误,平台将会断开连接。所以该字节数据为0xC0。

 

      Byte9-10为保持连接(Keep Alive),是一个以秒为单位的时间间隔,表示为一个16位的字,它是指在客户端传输完成一个控制报文的时刻到发送下一个报文的时刻,两者之间允许空闲的最大时间间隔。如果保持连接的值非零,并且服务端在一点五倍的保持连接时间内没有收到客户端的控制报文,它必须断开客户端的网络连接,认为网络连接已断开。OneNET规定最短120秒,最长65535秒,这里设置的事0x0100,也就是256秒。

 

3、负载部分

      负载部分的数据是按照以下格式编码

0010.png      对照数据:

0011.png

 

 

 

      0x0008为域一的字符串长度,这里是8字节,内容为ASCII码的“31421353”,正好是源码中DEVID,也就是设备ID(DeviceID);0x0006为域二的字符串长度,这里是6字节,内容为ASCII码的“141215”,正好是源码中PROID,也就是产品ID(ProduceID);0x001C为域三的字符串长度,这里是28字节,内容为ASCII码的”dpsO9ruH0aTZublG9g5SvBtFSEQ=”,正好是源码中AUTH_INFO,也就是产品ID(AuthInfo);

 

      至此,上传的鉴权信息就分析完毕了,服务器接收到鉴权信息后首先会有一个应答包,同时进行鉴权,鉴权完毕后会下发结果给客户端:

0012.png

 

 

      鉴权结果同样采用TCP传输,总共60个字节,除去以太网头、IP头、TCP头共计54字节,还剩余60字节,其中有效TCP负载为4字节,其后面的两个字节为TCP数据包需要四字节对齐所补充的无效数据。

      服务器返回的鉴权结果同样遵循MQTT包规则,首先是固定报头,根据上文表格0x20表示服务器确认连接,0x02表示后面跟随两字节有效数据,这里就是可变报头了。

 

      可变报头规则如下:

0013.png

 

 

 

      根据返回的数据为0x0000,表示鉴权成功了。

 

二、数据上报

      数据上报过程其实就是TCP通讯过程,每一次上报数据需要三帧,分别是数据上报,服务器确认,客户端确认,其中只需要了解数据上报帧就可以了。

 

0014.png

 

 

   在数据上报帧中,总计有121字节,除去以太网头、IP头、TCP头共计54字节,TCP有效字节数为67字节。

1、固定报头

   根据MQTT协议规定的上传报文中的固定报头格式如下:

0015.png

 

 

   对照抓取的数据,TCP负载第一个字节0x32中的“3”表示上传数据报文,其中的“2”表示QoS值为1。

 

   根据MQTT协议中服务质量定义表格如下:

0016.png

 

 

  对照表格,表示QoS值为1,即至少分发一次。

    TCP负载的第二字节的0x41表示后面数据长度为65字节。

 

2、可变报头

    其报文格式如下:

0017.png

 

 

    对照抓取数据:

0018.png

 

 

      0x0003为域一的两字节字符串长度,这里为3个字节,内容为主题名,这里为ASCII码的”$dp”,OneNET规定,”$dp”为系统上传数据点的指令。

接下来的0x000a为报文标识符(PacketIdentifier),因为之前QoS值选用的1,所以这两个字节在这里是必须的,固定为10,也就是0x000a。

 

3、负载

      Payload包含真正的数据点内容,支持的格式如下:

0019.png

 

 

 

   对照抓取的数据:

0020.png

 

   负载的第一个字节为0x03,即Type=3,根据类型3的说明:

 

0021.png

 

 

   类型3说明后面个数据是JSON格式2的字符串,后面两个字节0x0037表示字符串的长度为55。

   最后的55个字节就是上传的数据了,内容为55个ASCII码:

       {"Red_Led":1,"Green_Led":1,"Yellow_Led":1,"Blue_Led":1}

   这里表示上传了代表Led灯状态的四个数据流以及对应的值,OneNET服务器就会解析数据流并保存数据了。

 

三、命令下发

      通过抓取数据包,命令下发过程需要四帧完成。

0022.png

 

 

   根据MQTT协议,四帧分别是服务器命令下发,客户端应答,客户端命令回复,服务器端应答。所以我们只需要了解服务器命令下发帧和客户端命令回复帧即可。

   根据抓取到的数据,服务器命令下发帧总计108字节,其中TCP负载为54字节。

0023.png

 

 

   固定报头中的0x30表示发布消息,0x34表示后续内容有52字节。

      可变报头部分数据格式如下:

0024.png

 

 

   根据抓取数据,0002a表示字符串长度为42字节,字符串内容为ASCII码的”$creq/e8b6c9b6-225b-57dc-abaa-246ba58761d8”。其中”$creq”为系统下发指令标记,”/”为分隔符,后续的”e8b6c9b6-225b-57dc-abaa-246ba58761d8”为该条指令的uuid,uuid是通用唯一识别码,用于识别该指令的唯一性。

 

   最后的八个字节为MQTT数据报的负载部分,为真正的指令内容,这里是”redled:0”,客户端接收到该指令后控制led灯的亮灭。

 

四、断开连接

      MQTT协议的断开连接没有特殊的规定,只是遵循了TCP的断开连接过程,主要就是双方各自发送FIN标记的TCP包,并给对方确认,总共四帧数据完成。

 

0099.png

 

 

五、总结

   至此OneNET官方例程中的主要MQTT协议就分析完成了,其实除了分析过的外,还有其他交易存在,比如订阅、取消订阅、创建Topic、推送Topic、离线Topic等等,但是在例程中没有用到,而且在也不是最常用的,所以这里没有分析。通过分析发现,MQTT协议非常的精炼,很适合作为物联网的控制协议,而且通过分析,基本了解了MQTT协议的主要内容,这对于下一步在各个不同平台(Arduino,STM32,树莓派,windows)通过MQTT协议接入OneNET云做了充分的准备。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要实现STM32与ESP8266连接OneNet云平台,可以按照以下步骤进行: 1. 首先,硬件上需要准备好STM32和ESP8266模块。将STM32与ESP8266通过串口进行连接,确保两者之间能够进行通信。 2. 在OneNet云平台上创建一个新的设备,获取该设备的产品ID和设备ID。这将用于与OneNet云平台进行通信。 3. 在STM32上编写程序,实现STM32与ESP8266之间的串口通信。使用STM32的串口库函数,通过串口与ESP8266进行数据的发送和接收。 4. 在STM32的程序中,构建符合OneNet云平台要求的数据包,并通过ESP8266发送到OneNet云平台。可以使用HTTP或MQTT协议进行数据传输。具体的协议细节可以参考OneNet云平台提供的通信接口文档。 5. 在ESP8266上编写程序,实现与OneNet云平台的通信。根据OneNet云平台提供的API文档,使用ESP8266连接到OneNet云平台,并将从STM32接收到的数据上传到OneNet云平台。 6. 在OneNet云平台上配置相应的数据流和数据点,以便接收和展示从STM32和ESP8266发送过来的数据。 7. 在STM32程序中,可以考虑加入循环发送数据的功能,以实现实时监测和控制。 8. 调试完成后,上传STM32和ESP8266的程序到对应的硬件上,使其能够连接OneNet云平台。 通过以上步骤,就可以实现STM32与ESP8266连接OneNet云平台的程序。 ### 回答2: 要实现STM32与ESP8266连接到OneNet云平台,需要以下步骤: 1. 确保STM32开发板和ESP8266模块都正常工作,并且都有串口通信功能。 2. 在OneNet平台上创建设备和数据流,并获取到设备ID和API Key。 3. 在STM32开发环境中,配置串口通信和WiFi模块。 4. 在STM32中,使用串口与ESP8266模块进行通信。可以使用AT指令控制ESP8266,将其设置为STA(Station)模式并连接到WiFi网络。 5. 在STM32中,使用串口与ESP8266模块进行HTTP通信。可以使用AT指令发送HTTP请求,并将设备数据上传到OneNet云平台。 6. 在STM32中,解析ESP8266返回的HTTP响应,并根据需要进行相应的处理。 7. 在STM32中,根据需要,可以设置定时器来定期上传数据到OneNet云平台。 8. 在STM32中,可以通过解析OneNet云平台的HTTP响应,获取云平台发送的命令,并根据命令来执行相应的操作。 最后,通过以上步骤,就可以实现STM32与ESP8266连接到OneNet云平台并实现数据的上传和命令的执行。 ### 回答3: 要将STM32和ESP8266连接到OneNet云平台,需要进行以下步骤: 1. 准备硬件: - STM32单片机开发板 - ESP8266 WiFi模块 - 连接线等 2. 在OneNet云平台上创建设备和数据流: - 登录OneNet云平台账号 - 创建一个设备,并为设备添加相应的数据流,用于接收和发送数据 3. 配置ESP8266模块: - 将ESP8266与STM32开发板连接,确保串口通信正常 - 在ESP8266上烧录相关固件,如AT指令固件,可以使用串口助手通过AT指令测试ESP8266的连接和通信功能 4. 编写STM32程序: - 使用适当的开发环境,如Keil或STM32CubeIDE等,创建STM32项目 - 引入相应的库文件,如串口库、网络库等 - 初始化串口和网络连接 - 通过串口与ESP8266进行通信,发送AT指令以连接WiFi,获取IP地址 - 使用HTTP或MQTT协议,将数据发送到OneNet云平台的设备数据流中 5. 测试连接和通信: - 将STM32开发板上电,并观察串口输出,确保模块正常连接WiFi - 向STM32发送指令来触发数据的传输 - 在OneNet云平台上监控数据流,验证数据是否成功接收和处理 总结一下,连接STM32和ESP8266到OneNet云平台的关键是通过ESP8266模块建立WiFi连接,然后通过STM32与ESP8266进行串口通信,将数据发送到OneNet云平台的设备数据流中。这样就可以实现STM32与OneNet云平台的数据传输和通信。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值