MQTT(MQ Telemetry Transport)是一种基于发布和订阅(publish/subscribe)的简单的、轻量级的通信协议,它应用于资源受限的设备及低带宽、高延时、不可靠的网络。MQTT3.1.1版本已成为OASIS的标准。
MQTT的实现承载在传输层安全协议TLS之上,通信的协议层次见下图。
接入IoT平台对接模式
设备使用MQTT很容易和华为OceanConnect IoT平台对接,平台目前支持两种对接模式。
一机一密模式,即一个设备在平台申请一个密码,流程图如下所示:
一型一密模式,即一种产品在平台申请一个密码,产品的设备唯一标识nodeid由设备厂家分配,设备的密码由设备和平台动态协商,流程图如下所示:
特点
使用LiteOS端云互通MQTT组件很容易和IoT平台实现连接:
- 支持一机一密即静态连接,及一型一密即动态连接。
- 支持数据上报到IoT平台。
- 支持接收执行IoT平台命令。
设备接入IoT平台集成开发流程
环境准备
平台侧环境准备
在开发之前,需要提前获取如下信息:
- 开发者Portal的访问地址/账号/密码,需要向OceanConnect IoT平台申请
- 设备对接地址/端口号
端侧环境准备:
LiteOS源代码托管在GitHub,地址为https://github.com/LiteOS/LiteOS。
- 集成开发工具:
- MDK 5.18版本或者以上版本,从MDK官方网站下载。
- MDK依赖的pack包
IoT平台配置
IoT平台需要有配置的MQTT设备信息,才能和设备连接。具体请参见IoT平台的操作资料。
一机一密(静态连接)配置
在平台的设备注册中输入设备信息,提交后保存对应的deviceid和password。
一型一密(动态连接)配置
在产品管理中导入产品,提交后保存productid和password。
设备使用MQTT组件的适配
编译
MQTT组件依赖于cJSON、mbedtls及tcp/ip的实现。tcp/ip可使用lwip实现或者在AT模块实现。详细的编译可参考config_mqtt.mk及Makefile。
MQTT组件相关代码如下:
目录 | 描述 |
---|---|
components/connectivity/mqtt | paho.mqtt.enbedded-c开源组件及适配 |
components/connectivity/agent_tiny/atiny_mqtt | 对接IoT平台的实现 |
动态连接secret info信息的存储
动态连接需要保存IoT平台分配的deviceid及password等secret info。需要使用1056字节保存该信息。该信息需要使用可擦除的不易丢失器件存储。该信息为用户的敏感信息,建议用户使用安全的加密算法如使用CBC模式的AES128算法进行加密存储,保护该信息安全。
动态连接nodeid唯一性要求
动态连接的nodeid需要能唯一标识设备,如使用SN或者MAC地址等等。
设备时间的要求
若设备配置的密码校验类型为校验时间戳时,即MQTT_SIGN_TYPE_HMACSHA256_CHECK_TIME,设备时间需要和IoT平台时间同步,年月日小时应该保持一致,连接才能校验通过。
否则可带任意时间。
设备配置参数必须和IoT平台配置一致
设备的连接参数、ca证书需要和IoT平台配置一致,才能连接成功。
数据的上报及命令下发及应答的格式需要和IoT平台配置的profile一致,才能实现数据上报及命令下发、应答。
静态设备平台profile的查询
动态设备profile查询
举例:
数据上报的Json格式要求为:
代码语言:javascript复制{
"msgType": "deviceReq",
"hasMore": 0,
"data": [{
"serviceId": "serviceIdValue",
"data": {
"defineData": "defineValue"
},
"eventTime": "20161219T114920Z"
}]
}
命令下发的Json格式要求为:
代码语言:javascript复制{
"msgType":"cloudReq",
"serviceId":"serviceIdValue",
"paras":{
"paraName":"paraValue"
},
"cmd":"cmdValue",
"hasMore":0,
"mid":0
}
命令响应报文格式为:
代码语言:javascript复制{
"msgType":"deviceRsp",
"mid":0,
"errcode":0,
"hasMore":0,
"body":{
"bodyParaName":"bodyParaValue"
}
}
# API参考
atiny_mqtt_init
接口1 | int atiny_mqtt_init(const mqtt_param_s* atiny_params, mqtt_client_s** phandle) |
---|---|
功能 | 初始化MQTT模块,配置必备信息。 |
入参 | atiny_params:MQTT服务器信息、传输层安全信息、用户交互命令钩子。 |
出参 | Phandle:MQTT客户端句柄。 |
返回值 | ATINY_OK表示成功;否则错误码。 |
atiny_mqtt_bind
接口2 | int atiny_mqtt_bind(const mqtt_device_info_s* device_info, mqtt_client_s* phandle) |
---|---|
功能 | 绑定MQTT设备,并占用该任务一直运行。 |
入参 | device_info:设备配置参数,即静态、动态连接相关参数,连接校验方式,编码方式。 |
出参 | phandle:MQTT客户端句柄。 |
返回值 | 返回错误码或者不返回。 |
atiny_mqtt_data_send
接口3 | int atiny_mqtt_data_send(mqtt_client_s* phandle, const char *msg, uint32_t msg_len, mqtt_qos_e qos) |
---|---|
功能 | 发送MQTT数据,可用于数据上报或命令下发的应答,数据格式需要和IOT平台定义一致。 |
入参 | phandle:MQTT客户端句柄。Msg:数据的消息。msg_len:消息长度。Qos:发送的服务质量。 |
出参 | 无 |
返回值 | ATINY_OK表示成功;否则错误码。 |
atiny_mqtt_isconnected
接口4 | int atiny_mqtt_isconnected(mqtt_client_s* phandle) |
---|---|
功能 | MQTT客户端是否已经连接到服务器。 |
入参 | phandle:MQTT客户端句柄。 |
出参 | 无 |
返回值 | 0表示未连接;否则连接。 |