大家好,今天小白给大家介绍一下Gokit4(G)开发板连接到机智云平台的过程,在机智云的整个架构里面,Gagent实现了从模块到整个云端的数据交互的过程,其实gagent里面就是用MQTT协议实现的,首先简单介绍下MQTT协议。
1、MQTT协议简介
MQTT协议(Message Queuing Telemetry Transport),翻译过来就是遥信消息队列传输,是IBM公司于1999年提出的,MQTT是一个基于TCP的发布订阅协议,设计的初始目的是为了极有限的内存设备和网络带宽很低的网络不可靠的通信,非常适合物联网通信。
MQTT协议特点:
a. 使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合;
b. 对负载内容屏蔽的消息传输;
c. 使用 TCP/IP 提供网络连接;
d. 有三种消息发布服务质量;
“至多一次”,消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一 次读记录无所谓,因为不久后还会有第二次发送。
“至少一次”,确保消息到达,但消息重复可能会发生。
“只有一次”,确保消息到达一次。这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果。
e. 小型传输,开销很小(固定长度的头部是 2 字节),协议交换最小化,以降低网络流量;
f. 使用 Last Will 和 Testament 特性通知有关各方客户端异常中断的机制;
关于MQTT协议相关的详细介绍可以参看:https://www.jianshu.com/p/ecde412d2eeb
2、gagent.a文件介绍
使用指令ar x libgagent.a,可以看到gagent.a库文件里面打包了很多.o文件:
aesdata.o dp.o gagentThread.o gatnet.o httpgat.o iofipc.o iofsocket.o libgagent.a localprotocol.o otawan.o simulatorcomm.o aes.o env.o gatbase64.o gatutilcode.o iofdev.o iofnet.o iofstring.o localcomm.o mqttgat.o productinfo.o simulator.o authorization.o gagent_md5.o gatlist.o gdns.o ioffile.o iofpthread.o ioftime.o localio.o mqttlib.o qlog.o tcp.o cmdtable.o gagent.o gatm2m.o gserver.o iofgpio.o iofserial.o lanvirtual.o local.o nwk_manage.o semaph.o timer_subsystem.o
不难发现里面就有:mqttgat.o, mqttlib.o等文件,即为MQTT协议的实现。
3、-wl文件中部分与MQTT协议相关的部分
#Linker Script and memory map
......
LOAD D:\GizwitsProgram\PRJ-NB\SoC_MDM9206_Source\gagent\libgagent.a(gatm2m.o) []
LOAD D:\GizwitsProgram\PRJ-NB\SoC_MDM9206_Source\gagent\libgagent.a(mqttgat.o) []
LOAD D:\GizwitsProgram\PRJ-NB\SoC_MDM9206_Source\gagent\libgagent.a(mqttlib.o) []
......
可以看到gatm2m.o中有如下API:
.text 0x43015e98 0x2648 D:\GizwitsProgram\PRJ-NB\SoC_MDM9206_Source\gagent\libgagent.a(gatm2m.o) #SHT_PROGBITS,SHF_ALLOC|SHF_EXECINSTR,4
0x43015ea4 m2mInfoSet
0x4301614c $d.3
0x43016180 $a.4
0x430162d0 m2mSktConnCb
0x430162d0 $a.6
0x43016554 $d.7
0x43016590 $a.8
......
0x43016768 gatSetM2MDomain
0x430167e4 $d.15
0x430167fc $a.16
0x430167fc gatGetM2MPort
0x43016808 $d.17
0x4301680c $a.18
0x4301680c gatSetM2MPort
0x4301687c $d.19
0x43016894 $a.20
0x430169b0 onM2MLoginCb
0x43016b98 $d.23
0x43016bc0 $a.24
0x43016bc0 onM2MSubTopicCb
0x43016cdc $d.25
0x43016cfc $a.26
......
0x43017a9c gatM2MReInit
0x43017b2c $d.45
0x43017c18 gatm2mDnsCb
0x43017c18 $a.48
0x43017d1c $d.49
......
可以看到mqttgat.o中有如下API:
.text 0x43027384 0x17a8 D:\GizwitsProgram\PRJ-NB\SoC_MDM9206_Source\gagent\libgagent.a(mqttgat.o) #SHT_PROGBITS,SHF_ALLOC|SHF_EXECINSTR,4
......
0x430276ec mqttPingTimeSetAlive
0x430276ec $a.4
0x43027708 mqttExtractPacket
0x43027828 $d.5
0x43027858 $a.6
0x43028078 $d.7
0x430280e4 mqttDataHandle
0x430280e4 $a.8
0x4302818c $d.9
0x430281bc $a.10
0x430283b4 $d.11
0x430283e4 $a.12
0x430283e4 mqttSubTopicS
0x430284e8 $d.13
0x430284fc $a.14NWK_CLOUD_CONNECTED
0x430284fc mqttSendPubData
0x43028580 gatMqttInit
0x43028600 $d.15
0x4302861c gatMqttReInit
0x4302861c $a.16
0x43028740 $d.17
......
0x4302896c gatCloudGizDataSend
0x4302896c $a.24
0x43028b0c $d.25
......
mqttlib.o中有如下API:
.text 0x43028b2c 0x1330 D:\GizwitsProgram\PRJ-NB\SoC_MDM9206_Source\gagent\libgagent.a(mqttlib.o) #SHT_PROGBITS,SHF_ALLOC|SHF_EXECINSTR,4
0x43028b2c $a.0
0x43028b2c mqtt_num_rem_len_bytes_safe
0x43028c5c $d.1
0x43028c78 $a.2
0x43028eb0 mqtt_init
0x43028f8c mqtt_connect
0x4302956c $d.3
0x430295a0 $a.4
0x430295a0 mqtt_disconnect
0x430295e8 mqtt_ping
0x43029630 mqtt_publish_with_qos
0x43029a28 $d.5
0x43029a58 $a.6
0x43029a58 mqtt_subscribes
0x43029e2c $d.7
......
4、开机启动的log信息
.....
[TD 78BBA38][153452][M2M] gatSetM2MDomain :sandbox.gizwi //获取m2m服务器的域名
[TD 78BBA38][153452][M2M] gatSetM2MPort = 1883 //获取m2m服务器的端口
[TD 78BBA38][153452][M2M] gatMqttReInit ...... ok
[TD 78BBA38][153452][M2M] gatM2MReInit ...... ok
[TD 78BBA38][153452][M2M] No m2m ip ,need to get it .
.....
[TD 78BBC98][158376][Dns] _dnsIpFound sandbox.gizwits.com dns ip found: 203.195.142.207 //获取ip
[TD 78BBC98][158376][M2M] gatm2mDnsCb result=1 ,ipAddr:203.195.142.207.
[TD 78BBC98][158376][GServer] m2m IP need to updata,and ReStart m2m. //更新ip,重启m2m服务器
.....
[TD 78BBC98][158376][M2M] m2m m2mInfoSet ...
[TD 78BBC98][158376][M2M] m2m sandbox.gizwits.com:1883
[TD 78BBC98][158376][M2M] m2m ip:203.195.142.207
**--**
[TD 78BBC98][158376][M2M] m2m fd:-1
[Socket] send conn cb:0x43016b34,fd:16385 //tcp socket描述符
[TD 78BBC98][158376][Pthread] iofSendSig ret=0.
[TD 78BBC98][158376][M2M] m2m fd:16385
[TD 78BBC98][158376][M2M] m2m m2mInfoSet ...
[TD 78BBC98][158376][M2M] m2m sandbox.gizwits.com:1883
[TD 78BBC98][157748][Http] Gserver Ip:119.29.47.111, port:80
....
[Http] gatHttpReq new httpfd=16386 //httpfd,用于建立http短连接
[Http] httpConnCb 404 fd:16386!
....
[TD 78BBC98][157672][Http] httpConnCb 410 fd:16386 port:80!
[TD 78BBC98][157644][Util] [157644][M.m 0x4307fda8] gatTcpListenAdd[184] len=20
[TD 78BBC98][157644][Tcp] gatTcpListenAdd fd =16386 to tcpChListNr.rfds,fdMax=16385
[TD 78BBC98][157644][Tcp] add tcp chList fdset update.fd:16386
[TD 78BBC98][157812][GAgent] SIG_CMD_SKTCON
[TD 80475338][157812][Timer] timer:dnsTick arrive.
[TD 78BBC98][157812][Tcp] socket connect result:0,fd:16385,cb:0x43016b34 //tcp socket连接成功
[TD 80475338][157812][Pthread] iofSendSig ret=0.
[TD 78BBC98][157812][M2M] m2mSktConnCb:96
[TD 78BBC98][157812][Socket] m2mSktConnCb result=0 ip:203.195.142.207 port:1883 fd=16385
......
[TD 78BBC98][157780][Util] [157780][M.m 0x4307fe18] gatTcpListenAdd[184] len=20
[TD 78BBC98][157780][Tcp] gatTcpListenAdd fd =16385 to tcpChListNr.rfds,fdMax=-1
[TD 78BBC98][157780][Tcp] add tcp chList fdset update.fd:16385
[TD 78BBC98][157768][Util] [157768][M.m 0x4307fe54] mqtt_connect[314] len=2 //客户端向代理发起订阅请求
[TD 78BBC98][157684][Util] [157684][M.m 0x430800ac] mqtt_connect[334] len=74
[TD 78BBC98][157684][M2M] m2m packet, len:74,data:
......
[TD 78BBC98][157616][Http] http send:
POST /dev/ota/v4.1/update_and_check/wCTUfa7joSqjAJN4P3oZJg HTTP/1.1
Host: api.gizwits.com
Content-Length: 127
Content-Type: application/x-www-form-urlencoded
passcode=BDCXEMKAQB&type=1&hard_version=BG960201&soft_version=04020025&sdk_hard_version=LinuxUbuntu_X86&sdk_soft_version=1.0.23 //设备信息,其中passcode表示GAgent首次运行时生成的随机数,需要上传给服务器
【2019-02-15 10:56:03:376】TD 78BBA38][157984][Mqtt] init a mqtt node data .
[TD 78BBA38][157984][M2M] mqttDataHandle 364 datalen=4 .
[TD 78BBA38][157984][M2M] mqttDataHandle MQTT_MSG_CONNACK result=0 . //连接确认
[TD 78BBA38][157984][M2M] onM2MLoginCb result=0
[TD 78BBA38][157984][M2M] sub topic:ser2cli_res/wCTUfa7joSqjAJN4P3oZJg m2mMsgId=-1 //设备ID: wCTUfa7joSqjAJN4P3oZJg
[TD 78BBA38][157984][M2M] topic[0]:ser2cli_res/wCTUfa7joSqjAJN4P3oZJg //订阅3个主题, 接收服务器的消息响应
[TD 78BBA38][157984][M2M] topic[1]:app2dev/wCTUfa7joSqjAJN4P3oZJg/# //接收远程控制指令
[TD 78BBA38][157984][M2M] topic[2]:ser2cli_res/wCTUfa7joSqjAJN4P3oZJg //同topicp[0]
[TD 78BBA38][157860][Util] [157860][M.m 0x4307ff84] mqtt_subscribes[690] len=113 //客户端向代理发起订阅请求
[TD 78BBA38][157860][Socket] func:m2mSend,add =0x4307ff84 fd=16385 len:113,data:
[TD 78BBC98][158284][GAgent] gatGetSoftVer :04020025 .
[TD 78BBA38][158220][Mqtt] mqttExtractPacket total datalen=0 offset=0
[TD 78BBA38][158220][Mqtt] mqttExtractPacket total datalen=0 offset=0
[TD 78BBC98][158220][Util] [158220][M.m 0x4307fe74] gatReqLastVersion[471] len=54
[TD 78BBA38][157992][Mqtt] msgType:MQTT_MSG_SUBACK //订阅确认
[TD 78BBC98][157992][Util] [157992][M.m 0x4307feb4] gatHttpReq[540] len=220
[TD 78BBA38][157684][Mqtt] mqtt_num_rem_len_bytes_safe 26 buf[1]=05
[TD 78BBC98][157684][Util] [157684][M.m 0x4307ff98] gatHttpReq[554] len=298
[TD 78BBA38][157684][Mqtt] mqttExtractPacket 219 dataLen=7 dataReMainLen=5
[TD 78BBC98][157668]
【2019-02-15 10:56:06:882】[Http] Gserver Ip:119.29.47.111, port:80
[TD 78BBA38][157668][Util] [157668][M.m 0x430800cc] mqttExtractPacket[226] len=7
[TD 78BBA38][157668][Mqtt] mqttExtractPacket 250 have mqtt packet now //数据发现
[TD 78BBA38][157668][Mqtt] init a mqtt node data .
[TD 78BBA38][157668][M2M] mqttDataHandle 364 datalen=7 .
[TD 78BBA38][157668][M2M] mqttDataHandle MQTT_MSG_SUBACK msgId=1 . //数据处理
[TD 78BBA38][157668][M2M] onM2MSubTopicCb msgId=1 m2mMsgId=1
[TD 78BBA38][157668][Timer] del timer:m2mRecTimer ok
[TD 78BBA38][157668][Util] [157668][M.f 0x4307fdfc] gatTimerDel[186]
[TD 78BBA38][157696][M2M] gatM2MHeartBeatStart . . .
[TD 78BBA38][157668][Util] [157668][M.m 0x4307fdfc] gatTimerAdd[96] len=20
**--**
[TD 78BBA38][157668][Timer] gatTimerAdd 97 pNodeEntry:0x4307fdfc
[TD 78BBA38][157668][Timer] T
【2019-02-15 10:56:06:985】imer: m2mHeartBeatTimer init.
[TD 78BBA38][157668][Timer] add timer:m2mHeartBeatTimer ok.
[TD 78BBA38][157668][GAgent] gatStatusSet old status:0118,flag:1
[TD 78BBA38][157668][GAgent] gatStatusSet new status:0138
[TD 78BBA38][157668][NWK] NWK_CLOUD_CONNECTED //设备上线
[TD 78BBA38][157668][NWK] gatSetNwkEvent halNwkStatus=2038 ret=0.
[TD 78BBA38][157668][Pthread] iofSendSig ret=0.
[TD 78BBA38][157668][M2M] gagent m2m up.
......
5、总结
本篇博客主要是简单介绍了MQTT协议,以及机智云源码包中的-wl文件,该文件中链接了一些库文件,这些库文件被打包在libgagent.a文件中,其中包括了MQTT协议的实现,主要是为了实现设备,云端之间的通信。也根据模块开机log简单地追溯了设备上电到连接到云端的一个大致流程,有误欢迎指正。