# MQTT ***Copyright © Quectel Wireless Solutions Co., Ltd. 2026. All rights reserved.*** --- # 功能概述 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是基于TCP/IP、采用发布/订阅(publish/subscribe)架构的轻量级物联网通信协议,由IBM在1999年发布。该协议的核心优势在于能够以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。 凭借低开销、低带宽占用的特性,MQTT在物联网、小型设备、移动应用、机器对机器(M2M)等方面得到广泛应用,如卫星链路通信传感器、偶尔拨号的医疗设备、智能家居及各类小型化设备。 ## 核心特性 - **发布/订阅模式:** 发送者(发布者)与接收者(订阅者)解耦,双方无需知道对方的IP地址或直接建立连接。 - **轻量级:** 报文体积小,头部仅需2字节,大幅节省带宽和计算资源。 - **服务质量(QoS):** 提供三种等级(0-最多一次、1-至少一次、2-仅一次),确保消息在不稳定网络中的可靠传输。 - **遗嘱机制(Will):** 当客户端异常断开连接时,服务器自动通知其他订阅者,适用于设备故障监控。 - **主题(Topic):** 类似于目录结构,实现消息分类和路由。 - **基于 TCP 协议**:通常基于TCP协议保证数据传输的可靠性,默认使用端口1883。 # MQTT协议原理与实现 ## 角色与通信模型 MQTT采用客户端-服务器架构,通信过程涉及三种身份:发布者(Publisher)、消息代理(Broker/服务器)、订阅者(Subscriber)。发布者和订阅者均为客户端,且发布者可以同时是订阅者。 MQTT传输的消息分为主题(Topic)和负载(Payload)两部分: - 主题(Topic):消息的类型,订阅者订阅后,即可收到该主题的消息。 - 负载(Payload):消息的内容,即订阅者实际接收和使用的数据。 ## MQTT客户端 使用MQTT协议的应用程序或设备,始终与服务器建立网络连接。客户端具备以下能力: - 发布其他客户端可能订阅的消息; - 订阅其它客户端发布的消息; - 退订或删除应用程序的消息; - 断开与服务器连接。 ## MQTT服务器(消息代理Broker) 位于消息发布者和订阅者之间的应用程序或设备,主要功能包括: - 接受来自客户端的网络连接; - 接收客户端发布的应用信息; - 处理客户端的订阅和退订请求; - 向匹配的订阅客户端转发消息。 ## 订阅、主题与会话 - **订阅(Subscription)**:包含主题筛选器(Topic Filter)和最大服务质量(QoS),与一条会话(Session)关联。单个会话可绑定多条订阅,每条订阅都有不同的主题筛选器。 - **会话(Session)**:客户端与服务器建立连接后的状态交互实体,可跨越多个连续的网络连接存在。 - **主题名(Topic Name)**:连接应用程序消息的标签,与服务器订阅相匹配。服务器会将消息发送给订阅所匹配标签的每个客户端。 - **主题筛选器(Topic Filter)**:订阅表达式中使用的通配符筛选器,用于匹配多个主题。 - **负载(Payload)**:消息订阅者具体接收的内容。 ## 协议方法 MQTT定义了对资源进行操作的方法,主要包括: - Connect:等待与服务器建立连接。 - Disconnect:完成当前工作后,与服务器断开TCP/IP会话。 - Subscribe:等待完成主题订阅。 - UnSubscribe:取消客户端对一个或多个主题的订阅。 - Publish:发送消息请求,发送完成后返回应用程序线程。 # MQTT数据包结构 一个标准的MQTT数据包由以下三部分构成: - 固定头(Fixed header):存在于所有MQTT数据包中,用于表示数据包类型及分组类标识。 - 可变头(Variable header):存在于部分数据包中,其是否存在及具体内容由数据包类型决定。 - 消息体(Payload):存在于部分数据包中,表示客户端收到的具体数据内容。 ## 控制报文交互流程 ```{image} images/image_XWkqb6cqWoKwHaxRDKocCzEwnlM.webp :width: 458px :height: 579px :align: center ``` # MQTT API ## 头文件 *qcm_mqtt.h* *qcm_mqtt_config.h* ## 函数概览 ### 基础通用API | **函数** | **说明** | | --- | --- | | *qcm_mqtt_client_default_config()* | 加载默认配置 | | *qcm_mqtt_client_create()* | 申请一个新的MQTT客户端句柄 | | *qcm_mqtt_client_init()* | 初始化指定客户端 | | *qcm_mqtt_client_open()* | 向指定MQTT服务器发起异步TCP连接 | | *qcm_mqtt_client_connect()* | 向服务器发送CONNECT请求,在客户端与服务器之间建立MQTT会话连接 | | *qcm_mqtt_client_subscribe()* | 订阅主题 | | *qcm_mqtt_client_unsubscribe()* | 取消主题订阅 | | *qcm_mqtt_client_publish()* | 发布指定主题的消息 | | *qcm_mqtt_client_disconnect()* | 发送DISCONNECT报文并断开MQTT协议链接 | | *qcm_mqtt_client_close()* | 关闭TCP连接 | | *qcm_mqtt_client_wait_read_cnt()* | 查询当前客户端缓存中未读取的PUBLISH消息数量 | | *qcm_mqtt_read_subscribe_message()* | 根据指定 *store_id* 定读取一条缓存的已订阅消息 | | *qcm_mqtt_client_read_cacha_data()* | 顺序读取缓存队列中下一条消息 | | *qcm_mqtt_client_get_state_info()* | 获取客户端当前运行状态和信息 | | *qcm_mqtt_get_last_close_event()* | 查询指定客户端上一次连接断开的原因 | | *qcm_mqtt_last_close_event_init()* | 清零重置客户端断连原因记录 | ### MQTT 5.0专有/扩展 API | **函数名** | **描述** | | --- | --- | | *qcm_mqtt_topic_alias_check()* | 检查主题别名是否合法 | | *qcm_mqtt_client_get_server_info()* | 获取CONNACK报文中服务器返回的属性信息 | | *qcm_mqtt_release_connack_props()* | 释放 *qcm_mqtt_client_get_server_info()* 获取的CONNACK属性内存 | | *qcm_mqtt_release_newmsg_props()* | 释放收到PUBLISH消息中携带的MQTT 5.0属性内存 | ### 辅助内存管理函数 | **函数名** | **描述** | | --- | --- | | *qcm_mqtt_free_data()* | 释放 *qcm_mqtt_data_t* 结构体中动态分配的 *data_ptr* 内存 | | *qcm_mqtt_malloc_data()* | 分配内存并拷贝数据至 *qcm_mqtt_data_t* | | *qcm_mqtt_user_property_free_data()* | 批量释放MQTT 5.0用户属性数组中所有动态分配的 *key/value* 内存 | ## 函数详解 ### qcm_mqtt_client_default_config - **功能描述** 加载默认配置。给 *qcm_mqtt_config_t* 配置结构体填充默认推荐参数,用户在此基础上修改即可使用。 - **函数原型** ```c qcm_mqtt_eercode_e qcm_mqtt_client_default_config(qcm_mqtt_config_t *config_ptr); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *config_ptr* | 输出 | *qcm_mqtt_config_t \** | MQTT客户端全局配置;详见 [*qcm_mqtt_config_t*](#qcmmqttconfig_t) | - **返回值说明** *QCM_MQTT_RES_OK*:函数执行成功 其他值:函数执行失败;详见 [*qcm_mqtt_eercode_e*](#qcmmqtteercode_e) ### qcm_mqtt_client_create - **功能描述** 申请一个新的MQTT客户端句柄。 - **函数原型** ```c qosa_uint8_t qcm_mqtt_client_create(void); ``` - **参数说明** 无 - **返回值说明** 大于0的客户端句柄:函数执行成功 *0*:函数执行失败 ### qcm_mqtt_client_init - **功能描述** 初始化指定客户端,绑定配置、事件回调函数和用户私有参数。 - **函数原型** ```c qcm_mqtt_eercode_e qcm_mqtt_client_init(qosa_uint8_t client_id, qcm_mqtt_config_t *config_ptr, qcm_mqtt_client_event_cb evt_cb, void *user_param); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *client_id* | 输入 | qosa_uint8_t | *qcm_mqtt_client_create()* 返回的客户端句柄 | | *config_ptr* | 输入 | *qcm_mqtt_config_t* * | MQTT客户端全局配置;详见 [*qcm_mqtt_config_t*](#qcmmqttconfig_t) | | *evt_cb* | 输入 | *qcm_mqtt_client_event_cb* | 事件回调函数;详见 [*qcm_mqtt_client_event_cb*](#qcmmqttclienteventcb) | | *user_param* | 输入 | void * | 用户自定义参数 | - **返回值说明** *QCM_MQTT_RES_OK*:函数执行成功 其他值:函数执行失败;详见 [*qcm_mqtt_eercode_e*](#qcmmqtteercode_e) #### qcm_mqtt_client_event_cb - **函数原型** ```c typedef void (*qcm_mqtt_client_event_cb)(qcm_mqtt_client_event_e event_id, void *evt_param, void *user_param); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *event_id* | 输入 | *qcm_mqtt_client_event_e* | 当前触发的事件类型;详见qcm_mqtt_client_event_e | | *evt_param* | 输入 | void * | 通用响应状态通知;详见 [*qcm_mqtt_common_resp_t*](#qcmmqttcommonrespt) | | user_param | 输入 | void * | 用户自定义参数 | - **返回值说明** 无 ### qcm_mqtt_client_open - **功能描述** 向指定MQTT服务器发起异步TCP连接(支持域名或IP地址),连接结果通过事件回调通知。 - **函数原型** ```c qcm_mqtt_eercode_e qcm_mqtt_client_open(qosa_uint8_t client_id, char *addr, qosa_uint16_t port); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *client_id* | 输入 | qosa_uint8_t | 客户端ID | | *addr* | 输入 | char * | 服务器地址(域名或IP地址) | | *port* | 输入 | qosa_uint16_t | 服务器端口号(通常为1883或8883) | - **返回值说明** *QCM_MQTT_RES_OK*:函数执行成功 其他值:函数执行失败;详见 [*qcm_mqtt_eercode_e*](#qcmmqtteercode_e) ### qcm_mqtt_client_connect - **功能描述** 向服务器发送CONNECT请求,在客户端与服务器之间建立MQTT会话连接。 - **函数原型** ```cpp qcm_mqtt_eercode_e qcm_mqtt_client_connect(qosa_uint8_t client_id, const char *client_name, int client_name_len, const char *username, int username_len, const char *password, int password_len); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *client_id* | 输入 | qosa_uint8_t | 客户端ID | | *client_name* | 输入 | const char * | 客户端ID字符串 | | *client_name_len* | 输入 | int | 客户端ID字符串长度 | | *username* | 输入 | const char * | 用户名;可为 *NULL* | | *username_len* | 输入 | int | 用户名长度;0代表无用户名 | | *password* | 输入 | const char * | 登录密码;可为 *NULL* | | *password_len* | 输入 | int | 密码长度;0代表无密码 | - **返回值说明** *QCM_MQTT_RES_OK*:函数执行成功 其他值:函数执行失败;详见 [*qcm_mqtt_eercode_e*](#qcmmqtteercode_e) ### qcm_mqtt_client_subscribe - **功能描述** 订阅主题,订阅结果通过SUBACK事件异步回调。 - **函数原型** ```c qcm_mqtt_eercode_e qcm_mqtt_client_subscribe(qosa_uint8_t client_id, qcm_mqtt_sub_config_t *sub_info); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *client_id* | 输入 | qosa_uint8_t | 客户端ID | | *sub_info* | 输入 | *qcm_mqtt_sub_config_t* * | 订阅配置;详见 [*qcm_mqtt_sub_config_t*](#qcmmqttsubconfigt) | - **返回值说明** *QCM_MQTT_RES_OK*:函数执行成功 其他值:函数执行失败;详见 [*qcm_mqtt_eercode_e*](#qcmmqtteercode_e) ### qcm_mqtt_client_unsubscribe - **功能描述** 取消主题订阅,结果通过UNSUBACK事件异步回调。 - **函数原型** ```c qcm_mqtt_eercode_e qcm_mqtt_client_unsubscribe(qosa_uint8_t client_id, qcm_mqtt_sub_config_t *sub_info); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *client_id* | 输入 | qosa_uint8_t | 客户端ID | | *sub_info* | 输入 | *qcm_mqtt_sub_config_t* * | 订阅配置;详见 [*qcm_mqtt_sub_config_t*](#qcmmqttsubconfigt) | - **返回值说明** *QCM_MQTT_RES_OK*:函数执行成功 其他值:函数执行失败;详见 [*qcm_mqtt_eercode_e*](#qcmmqtteercode_e) ### qcm_mqtt_client_publish - **功能描述** 发布指定主题的消息。 - **函数原型** ```c qcm_mqtt_eercode_e qcm_mqtt_client_publish(qosa_uint8_t client_id, qcm_mqtt_pub_config_t *pub_info); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *client_id* | 输入 | qosa_uint8_t | 客户端ID | | *pub_info* | 输入 | *qcm_mqtt_pub_config_t* * | 发布配置;详见 [*qcm_mqtt_pub_config_t*](#qcmmqttpubconfigt) | - **返回值说明** *QCM_MQTT_RES_OK*:函数执行成功 其他值:函数执行失败;详见 [*qcm_mqtt_eercode_e*](#qcmmqtteercode_e) ### qcm_mqtt_client_disconnect - **功能描述** 发送DISCONNECT报文并断开MQTT协议链接,支持MQTT5.0断开属性。 - **函数原型** ```c qcm_mqtt_eercode_e qcm_mqtt_client_disconnect(qosa_uint8_t client_id, qcm_mqtt_disc_config_t *disconn_info); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *client_id* | 输入 | qosa_uint8_t | 客户端ID | | *disconn_info* | 输入 | *qcm_mqtt_disc_config_t* * | 断开配置;详见 [*qcm_mqtt_disc_config_t*](#qcmmqttdiscconfigt) | - **返回值说明** *QCM_MQTT_RES_OK*:函数执行成功 其他值:函数执行失败;详见 [*qcm_mqtt_eercode_e*](#qcmmqtteercode_e) ### qcm_mqtt_client_close - **功能描述** 关闭TCP连接,通常在协议层断开或异常后调用。 - **函数原型** ```c qcm_mqtt_eercode_e qcm_mqtt_client_close(qosa_uint8_t client_id); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *client_id* | 输入 | qosa_uint8_t | 客户端ID | - **返回值说明** *QCM_MQTT_RES_OK*:函数执行成功 其他值:函数执行失败;详见 [*qcm_mqtt_eercode_e*](#qcmmqtteercode_e) ### qcm_mqtt_client_wait_read_cnt - **功能描述** 查询当前客户端缓存中未读取的PUBLISH消息数量。 - **函数原型** ```c qosa_uint32_t qcm_mqtt_client_wait_read_cnt(qosa_uint8_t client_id); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *client_id* | 输入 | qosa_uint8_t | 客户端ID | - **返回值说明** 缓存待读消息条数(uint32_t)。 ### qcm_mqtt_client_read_subcribe_message - **功能描述** 根据指定 *store_id* 定读取一条缓存的已订阅消息。 - **函数原型** ```c qcm_mqtt_eercode_e qcm_mqtt_client_read_subcribe_message(qosa_uint8_t client_id, qosa_uint8_t store_id, qcm_mqtt_recv_pub_t *recv_pub); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *client_id* | 输入 | qosa_uint8_t | 客户端ID | | *store_id* | 输入 | qosa_uint8_t | 消息存储唯一标识 | | *recv_pub* | 输出 | *qcm_mqtt_recv_pub_t* * | 已订阅消息内容;详见 [*qcm_mqtt_recv_pub_t*](#qcmmqttrecvpubt) | - **返回值说明** *QCM_MQTT_RES_OK*:函数执行成功 其他值:函数执行失败;详见 [*qcm_mqtt_eercode_e*](#qcmmqtteercode_e) ### qcm_mqtt_client_read_cacha_data - **功能描述** 顺序读取缓存队列中下一条消息,内部读取游标自动递增。 - **函数原型** ```c qcm_mqtt_eercode_e qcm_mqtt_client_read_cacha_data(qosa_uint8_t client_id, qcm_mqtt_recv_pub_t *recv_pub); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *client_id* | 输入 | qosa_uint8_t | 客户端ID | | *recv_pub* | 输出 | *qcm_mqtt_recv_pub_t* * | 消息内容;详见 [*qcm_mqtt_recv_pub_t*](#qcmmqttrecvpubt) | - **返回值说明** *QCM_MQTT_RES_OK*:函数执行成功 其他值:函数执行失败;详见 [*qcm_mqtt_eercode_e*](#qcmmqtteercode_e) ### qcm_mqtt_client_get_state_info - **功能描述** 获取客户端当前运行状态和信息。 - **函数原型** ```c qcm_mqtt_eercode_e qcm_mqtt_client_get_state_info(qosa_uint8_t client_id, qcm_mqtt_client_info_t *client_info); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *client_id* | 输入 | qosa_uint8_t | 客户端ID | | *client_info* | 输出 | *qcm_mqtt_client_info_t* * | 运行状态和信息;详见 [*qcm_mqtt_client_info_t*](#qcmmqttclientinfot) | - **返回值说明** *QCM_MQTT_RES_OK*:函数执行成功 其他值:函数执行失败;详见 [*qcm_mqtt_eercode_e*](#qcmmqtteercode_e) ### qcm_mqtt_get_last_close_event - **功能描述** 查询指定客户端上一次连接断开的原因。 - **函数原型** ```c int qcm_mqtt_get_last_close_event(int client_id); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *client_id* | 输入 | int | 客户端ID | - **返回值说明** [*qcm_mqtt_client_close_reason_e*](#qcmmqttclientclosereason_e) 枚举成员:断开原因 ### qcm_mqtt_last_close_event_init - **功能描述** 清零重置客户端断连原因记录。 - **函数原型** ```c void qcm_mqtt_last_close_event_init(int client_id); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *client_id* | 输入 | int | 客户端ID | - **返回值说明** 无 ### qcm_mqtt_topic_alias_check(MQTT5.0) - **功能描述** 校验主题别名是否合法。 - **函数原型** ```c qcm_mqtt_eercode_e qcm_mqtt_topic_alias_check(qosa_uint8_t client_id, qosa_uint16_t topic_alias); ``` - **参数说明** | **参数名** | **输入 / 输出** | **类型** | **说明** | | --- | --- | --- | --- | | *client_id* | 输入 | qosa_uint8_t | 客户端ID | | *topic_alias* | 输入 | qosa_uint16_t | 待校验主题别名;合法范围 1~65535 | - **返回值说明** *QCM_MQTT_RES_OK*:合法 其他值:不合法;详见 [*qcm_mqtt_eercode_e*](#qcmmqtteercode_e) ### qcm_mqtt_client_get_server_info(MQTT5.0) - **功能描述** 获取CONNACK报文中服务器返回的属性信息。 - **函数原型** ```c qcm_mqtt_eercode_e qcm_mqtt_client_get_server_info(qosa_uint8_t client_id, qcm_mqtt_connack_properties_t *conn_props); ``` - **参数说明** | **参数名** | **输入 / 输出** | **类型** | **说明** | | --- | --- | --- | --- | | *client_id* | 输入 | qosa_uint8_t | 客户端ID | | *conn_props* | 输出 | *qcm_mqtt_connack_properties_t* * | CONNACK报文中服务器返回的属性信息;详见 [*qcm_mqtt_connack_properties_t*](#qcmmqttconnackpropertiest);使用完需释放内存 | - **返回值说明** *QCM_MQTT_RES_OK*:函数执行成功 其他值:函数执行失败;详见 [*qcm_mqtt_eercode_e*](#qcmmqtteercode_e) ### qcm_mqtt_release_connack_props(MQTT5.0) - **功能描述** 释放 *qcm_mqtt_client_get_server_info()* 获取的CONNACK属性内存。 - **函数原型** ```c qcm_mqtt_eercode_e qcm_mqtt_release_connack_props(qcm_mqtt_connack_properties_t *conn_props); ``` - **参数说明** | **参数名** | **输入 / 输出** | **类型** | **说明** | | --- | --- | --- | --- | | *conn_props* | 输入 | *qcm_mqtt_connack_properties_t* * | 服务器属性信息;详见 [*qcm_mqtt_connack_properties_t*](#qcmmqttconnackpropertiest) | - **返回值说明** *QCM_MQTT_RES_OK*:函数执行成功 其他值:函数执行失败;详见 [*qcm_mqtt_eercode_e*](#qcmmqtteercode_e) ### qcm_mqtt_release_newmsg_props(MQTT5.0) - **功能描述** 释放收到PUBLISH报文中携带的MQTT 5.0属性内存。 - **函数原型** ```c qcm_mqtt_eercode_e qcm_mqtt_release_newmsg_props(qcm_mqtt_pub_properties_t *pub_props); ``` - **参数说明** | **参数名** | **输入 / 输出** | **类型** | **说明** | | --- | --- | --- | --- | | *pub_props* | 输入 | *qcm_mqtt_pub_properties_t* * | PUBLISH报文中携带的发布属性;详见 [*qcm_mqtt_pub_properties_t*](#qcmmqttpubpropertiest) | - **返回值说明** *QCM_MQTT_RES_OK*:函数执行成功 其他值:函数执行失败;详见 [*qcm_mqtt_eercode_e*](#qcmmqtteercode_e) ### qcm_mqtt_free_data - **功能描述** 释放 *qcm_mqtt_data_t* 结构体中动态分配的 *data_ptr* 内存。 - **函数原型** ```c void qcm_mqtt_free_data(qcm_mqtt_data_t *data_ptr); ``` - **参数说明** | **参数名** | **输入 / 输出** | **类型** | **说明** | | --- | --- | --- | --- | | *data_ptr* | 输入 | *qcm_mqtt_data_t \** | 指向 [*qcm_mqtt_data_t*](#qcmmqttdata_t) 的结构体指针 | - **返回值说明** 无 ### qcm_mqtt_malloc_data - **功能描述** 分配内存并拷贝数据至 *qcm_mqtt_data_t*,用于填充主题、负载、用户属性等变长字段。 - **函数原型** ```c qcm_mqtt_eercode_e qcm_mqtt_malloc_data(qcm_mqtt_data_t *data_ptr, qosa_uint32_t data_len, char *data); ``` - **参数说明** | **参数名** | **输入 / 输出** | **类型** | **说明** | | --- | --- | --- | --- | | *data_ptr* | 输出 | *qcm_mqtt_data_t* * | 指向 [*qcm_mqtt_data_t*](#qcmmqttdata_t) 的结构体指针 | | *data_len* | 输入 | qosa_uint32_t | 需要分配并拷贝的数据长度;单位:字节 | | *data* | 输入 | char * | 源数据缓冲区指针 | - **返回值说明** *QCM_MQTT_RES_OK*:函数执行成功 其他值:函数执行失败;详见 [*qcm_mqtt_eercode_e*](#qcmmqtteercode_e) ### qcm_mqtt_user_property_free_data - **功能描述** 批量释放MQTT 5.0用户属性数组中所有动态分配的 *key/value* 内存(仅在宏 *CONFIG_QCM_MQTT5_FUNC* 开启时生效)。 - **函数原型** ```c qcm_mqtt_eercode_e qcm_mqtt_user_property_free_data(qosa_uint8_t user_property_cnt, qcm_mqtt_user_property_t *user_prop); ``` - **参数说明** | **参数名** | **输入 / 输出** | **类型** | **说明** | | --- | --- | --- | --- | | *user_property_cnt* | 输入 | qosa_uint8_t | 用户属性数组元素个数 | | *user_prop* | 输入 | *qcm_mqtt_user_property_t* * | 用户自定义属性的键值对;详见 [*qcm_mqtt_user_property_t*](#qcmmqttuserpropertyt) | - **返回值说明** *QCM_MQTT_RES_OK*:函数执行成功 其他值:函数执行失败;详见 [*qcm_mqtt_eercode_e*](#qcmmqtteercode_e) ## 结构体定义 ### qcm_mqtt_config_t MQTT客户端全局配置结构体定义如下: ```c typedef struct { qcm_mqtt_support_version_e version; qosa_uint8_t pdp_cid; qosa_uint8_t sim_id; qosa_uint32_t kalive_time; qosa_uint32_t delivery_time; qosa_uint8_t delivery_cnt; qosa_uint8_t will_flag; qcm_mqtt_quality_of_service_e will_qos; qcm_mqtt_data_t will_topic; qcm_mqtt_data_t will_message; qosa_uint32_t connect_time; qosa_uint32_t close_ping_interval; qosa_uint32_t rec_buf_size; qosa_uint8_t max_recv_store_cnt; qosa_bool_t clean_session; qosa_bool_t will_retain; qosa_bool_t ssl_enable; qosa_uint8_t ssl_ctx_id; qcm_ssl_config_t *ssl_config; #endif #ifdef CONFIG_QCM_MQTT5_FUNC qcm_mqtt_conn_properties_t conn_properties; qcm_mqtt_will_properties_t will_properties; #endif } qcm_mqtt_config_t; ``` | **参数** | **类型** | **说明** | | --- | --- | --- | | *version* | *qcm_mqtt_support_version_e* | MQTT协议版本;详见 [*qcm_mqtt_support_version_e*](#qcmmqttsupportversione) | | *pdp_cid* | qosa_uint8_t | PDP Context ID | | *sim_id* | qosa_uint8_t | SIM ID | | *kalive_time* | qosa_uint32_t | MQTT保活心跳间隔;默认值:120;单位:秒 | | *delivery_time* | qosa_uint32_t | 消息重传间隔;仅当QoS=1/2时生效;默认值:120;单位:秒 | | *delivery_cnt* | qosa_uint8_t | 最大重传次数;仅当QoS=1/2时生效;默认值:0 | | *will_flag* | qosa_uint8_t | 遗嘱消息使能标志
*1*:使能
*0*:不使能 | | *will_qos* | *qcm_mqtt_quality_of_service_e* | 遗嘱消息QoS等级;详见 [*qcm_mqtt_quality_of_service_e*](#qcmmqttqualityofservice_e) | | *will_topic* | qcm_mqtt_data_t | 遗嘱消息主题;详见 [*qcm_mqtt_data_t*](#qcmmqttdata_t) | | *will_message* | qcm_mqtt_data_t | 遗嘱消息载荷内容;详见 [*qcm_mqtt_data_t*](#qcmmqttdata_t) | | *connect_time* | qosa_uint32_t | PDP激活最大超时时间;单位:秒 | | *close_ping_interval* | qosa_uint32_t | Ping超时后延迟关闭最大时长;单位:秒 | | *rec_buf_size* | qosa_uint32_t | Socket接收缓冲区大小;单位:字节 | | *max_recv_store_cnt* | qosa_uint8_t | 服务端下发PUB消息最大缓存条数 | | *clean_session* | qosa_bool_t | 清除会话标识
*0*:复用历史会话
*1*:每次新建会话 | | *will_retain* | qosa_bool_t | 遗嘱消息保留标志
*0*:不保留
*1*:服务器持久保留 | | *ssl_enable* | qosa_bool_t | SSL/TLS 加密使能(依赖 *CONFIG_QCM_VTLS_FUNC*)
*1*:使能
*0*:不使能 | | *ssl_ctx_id* | qosa_uint8_t | 用户配置SSL上下文ID(依赖 *CONFIG_QCM_VTLS_FUNC*) | | *ssl_config* | qcm_ssl_config_t * | SSL详细配置指针(依赖 *CONFIG_QCM_VTLS_FUNC*) | | *conn_properties* | *qcm_mqtt_conn_properties_t* | MQTT5.0 CONNECT扩展属性(依赖 *CONFIG_QCM_MQTT5_FUNC*);详见 [*qcm_mqtt_conn_properties_t*](#qcmmqttconnpropertiest) | | *will_properties* | *qcm_mqtt_will_properties_t* | MQTT5.0遗嘱消息扩展属性(依赖 *CONFIG_QCM_MQTT5_FUNC*);详见 [*qcm_mqtt_will_properties_t*](#qcmmqttwillpropertiest) | ### qcm_mqtt_sub_config_t 订阅配置结构体定义如下: ```c typedef struct { int msg_id; qcm_mqtt_sub_topic_t *topics; qosa_uint8_t topic_cnt; #ifdef CONFIG_QCM_MQTT5_FUNC qcm_mqtt_sub_properties_t properties; #endif } qcm_mqtt_sub_config_t; ``` | **参数** | **类型** | **说明** | | --- | --- | --- | | *msg_id* | int | 消息ID | | *topics* | *qcm_mqtt_sub_topic_t* * | 订阅主题信息集合;详见 [*qcm_mqtt_sub_topic_t*](#qcmmqttsubtopict) | | *topic_cnt* | qosa_uint8_t | 订阅主题的数量 | | *properties* | *qcm_mqtt_sub_properties_t* | MQTT5.0 SUBSCRIBE报文属性(依赖 *CONFIG_QCM_MQTT5_FUNC*);详见 [*qcm_mqtt_sub_properties_t*](#qcmmqttsubpropertiest) | ### qcm_mqtt_pub_config_t 发布配置结构体定义如下: ```c typedef struct { int msg_id; qcm_mqtt_quality_of_service_e qos; qosa_bool_t retain; qcm_mqtt_data_t topic; qcm_mqtt_data_t payload; #ifdef CONFIG_QCM_MQTT5_FUNC qcm_mqtt_pub_properties_t properties; #endif } qcm_mqtt_pub_config_t; ``` | **参数** | **类型** | **说明** | | --- | --- | --- | | *msg_id* | int | 消息ID,QoS=0时为0 | | *qos* | *qcm_mqtt_quality_of_service_e* | 发布消息的QoS等级;详见 [*qcm_mqtt_quality_of_service_e*](#qcmmqttqualityofservice_e) | | *retain* | qosa_bool_t | 发布消息的保留标志
*1*:保留
*0*:不保留 | | *topic* | *qcm_mqtt_data_t* | 发布消息的主题;详见 [*qcm_mqtt_data_t*](#qcmmqttdata_t) | | *payload* | *qcm_mqtt_data_t* | 发布消息的内容;详见 [*qcm_mqtt_data_t*](#qcmmqttdata_t) | | *properties* | *qcm_mqtt_pub_properties_t* | MQTT5.0发布属性(依赖CONFIG_QCM_MQTT5_FUNC);详见 [*qcm_mqtt_pub_properties_t*](#qcmmqttpubpropertiest) | ### qcm_mqtt_disc_config_t 断开配置结构体定义如下: ```c typedef struct { #ifdef CONFIG_QCM_MQTT5_FUNC qcm_mqtt_disc_properties_t properties; #endif } qcm_mqtt_disc_config_t; ``` | **参数** | **类型** | **说明** | | --- | --- | --- | | *properties* | *qcm_mqtt_disc_properties_t* | MQTT 5.0断开连接属性配置 (依赖CONFIG_QCM_MQTT5_FUNC);详见 [*qcm_mqtt_disc_properties_t*](#qcmmqttdiscpropertiest) | ### qcm_mqtt_recv_pub_t 已订阅消息内容结构体定义如下: ```c typedef struct { qosa_uint16_t msg_id; qcm_mqtt_data_t topic; qcm_mqtt_data_t payload; #ifdef CONFIG_QCM_MQTT5_FUNC qcm_mqtt_pub_properties_t *properties; #endif } qcm_mqtt_recv_pub_t; ``` | **参数** | **类型** | **说明** | | --- | --- | --- | | *msg_id* | qosa_uint16_t | 消息ID | | *topic* | *qcm_mqtt_data_t* | 消息所属主题;详见 [*qcm_mqtt_data_t*](#qcmmqttdata_t) | | *payload* | *qcm_mqtt_data_t* | 消息的内容;详见 [*qcm_mqtt_data_t*](#qcmmqttdata_t) | | *properties* | *qcm_mqtt_pub_properties_t \** | MQTT5.0消息附加属性指针(依赖CONFIG_QCM_MQTT5_FUNC);详见 [*qcm_mqtt_pub_properties_t*](#qcmmqttpubpropertiest) | ### qcm_mqtt_client_info_t 运行状态和信息结构体定义如下: ```c typedef struct { int client_id; qosa_uint16_t svr_port; char srv_host[CONFIG_QOSA_HOST_URL_MAX_LEN]; qcm_mqtt_state_e client_state; } qcm_mqtt_client_info_t; ``` | **参数** | **类型** | **说明** | | --- | --- | --- | | *client_id* | int | 客户端ID | | *svr_port* | qosa_uint16_t | 服务器远端端口 | | *srv_host* | char | 服务器地址 | | *client_state* | *qcm_mqtt_state_e* | 内部连接状态;详见 [*qcm_mqtt_state_e*](#qcmmqttstate_e) | ### **qcm_mqtt_connack_properties_t** CONNACK报文中服务器返回的属性信息结构体定义如下: ```cpp typedef struct { qosa_uint32_t session_expiry_interval; qosa_uint16_t receive_maximum; qosa_uint8_t maximum_qos; qosa_uint8_t retain_available; qosa_uint32_t maximum_packet_size; qosa_uint16_t topic_alias_maximum; qosa_uint8_t wildcard_subscription_available; qosa_uint8_t subscription_identifier_available; qosa_uint8_t shared_subscription_available; qosa_uint16_t server_keep_alive; qcm_mqtt_data_t response_information; qcm_mqtt_user_property_t user_property[QCM_MQTT_MAX_USER_PROPERTY_SUPPORT]; qosa_uint8_t user_property_cnt; } qcm_mqtt_connack_properties_t; ``` | **参数** | **类型** | **说明** | | --- | --- | --- | | *session_expiry_interval* | qosa_uint32_t | 会话过期间隔;单位:秒 | | *receive_maximum* | qosa_uint16_t | 允许同时处理的最大未确认QoS 1/2消息数 | | *maximum_qos* | qosa_uint8_t | 支持的最高QoS等级 | | *retain_available* | qosa_uint8_t | 是否支持保留消息标志
*1*:支持
*0*:不支持 | | *maximum_packet_size* | qosa_uint32_t | 允许接收的最大报文长度;单位:字节 | | *topic_alias_maximum* | qosa_uint16_t | 允许使用的最大主题别名数量 | | *wildcard_subscription_available* | qosa_uint8_t | 是否支持通配符订阅
*1*:支持
*0*:不支持 | | *subscription_identifier_available* | qosa_uint8_t | 是否支持订阅标识符
*1*:支持
*0*:不支持 | | *shared_subscription_available* | qosa_uint8_t | 是否支持共享订阅
*1*:支持
*0*:不支持 | | *server_keep_alive* | qosa_uint16_t | 指定的Keep Alive时间间隔;单位:秒 | | *response_information* | *qcm_mqtt_data_t* | 响应信息字符串,用于请求/响应模式;详见 [*qcm_mqtt_data_t*](#qcmmqttdata_t) | | *user_property* | *qcm_mqtt_user_property_t* | 用户自定义属性键值对数组,最大长度由 *QCM_MQTT_MAX_USER_PROPERTY_SUPPORT* 定义;详见 [*qcm_mqtt_user_property_t*](#qcmmqttuserpropertyt) | | *user_property_cnt* | qosa_uint8_t | 当前设置的用户属性数量 | ### qcm_mqtt_pub_properties_t PUBLISH报文中携带的发布属性结构体定义如下: ```cpp typedef struct { qosa_uint32_t message_expiry_interval; qosa_uint32_t subscription_identifier; qosa_uint16_t topic_alias; qosa_uint8_t payload_format_indicator; qcm_mqtt_data_t response_topic; qcm_mqtt_data_t content_type; qcm_mqtt_data_t correlation_data; qcm_mqtt_user_property_t user_property [QCM_MQTT_MAX_USER_PROPERTY_SUPPORT]; qosa_uint8_t user_property_cnt; } qcm_mqtt_pub_properties_t; ``` | **参数** | **类型** | **说明** | | --- | --- | --- | | *message_expiry_interval* | qosa_uint32_t | 消息过期间隔,超时后服务器将丢弃该消息;单位:秒 | | *subscription_identifier* | qosa_uint32_t | 订阅标识符,用于关联订阅与发布消息 | | *topic_alias* | qosa_uint16_t | 主题别名,用于减少重复主题字符串的传输开销 | | *payload_format_indicator* | qosa_uint8_t | 载荷格式标识
*0*:未指定格式
*1*:UTF-8 编码文本 | | *response_topic* | *qcm_mqtt_data_t* | 响应主题,供接收方回复使用;详见 [*qcm_mqtt_data_t*](#qcmmqttdata_t) | | *content_type* | *qcm_mqtt_data_t* | 内容类型,描述载荷的数据类型或格式;详见 [*qcm_mqtt_data_t*](#qcmmqttdata_t) | | *correlation_data* | *qcm_mqtt_data_t* | 关联数据,用于匹配请求与响应消息;详见 [*qcm_mqtt_data_t*](#qcmmqttdata_t) | | *user_property* | *qcm_mqtt_user_property_t* | 用户自定义属性键值对数组,最大长度由 *QCM_MQTT_MAX_USER_PROPERTY_SUPPORT* 定义;详见 [*qcm_mqtt_user_property_t*](#qcmmqttuserpropertyt) | | *user_property_cnt* | qosa_uint8_t | 当前设置的用户属性数量 | ### qcm_mqtt_data_t 用于存储变长数据内容的结构体定义如下: ```c typedef struct { char *data_ptr; qosa_uint32_t data_len; } qcm_mqtt_data_t; ``` | **参数** | **类型** | **说明** | | --- | --- | --- | | *data_ptr* | char * | 数据内容 | | *data_len* | qosa_uint32_t | 数据内容长度 | ### qcm_mqtt_user_property_t 用户自定义属性的键值对结构体定义如下: ```cpp typedef struct { qcm_mqtt_data_t key; qcm_mqtt_data_t value; } qcm_mqtt_user_property_t; ``` | **参数** | **类型** | **说明** | | --- | --- | --- | | *key* | qcm_mqtt_data_t | 用户属性的键(Key);详见 [*qcm_mqtt_data_t*](#qcmmqttdata_t) | | *value* | qcm_mqtt_data_t | 用户属性的值(Value);详见 [*qcm_mqtt_data_t*](#qcmmqttdata_t) | ### qcm_mqtt_sub_topic_t 订阅主题信息集合结构体定义如下: ```c typedef struct { qcm_mqtt_data_t topic; qosa_uint8_t qos; #ifdef CONFIG_QCM_MQTT5_FUNC qcm_mqtt_subscribe_options_t opts; #endif } qcm_mqtt_sub_topic_t; ``` | **参数** | **类型** | **说明** | | --- | --- | --- | | *topic* | *qcm_mqtt_data_t* | 客户端订阅的主题。 | | *qos* | qosa_uint8_t | 客户端发布消息的QoS 等级 | | *opts* | *qcm_mqtt_subscribe_options_t* | MQTT5.0订阅选项(依赖CONFIG_QCM_MQTT5_FUNC);详见 [*qcm_mqtt_subscribe_options_t*](#qcmmqttsubscribeoptionst) | ### qcm_mqtt_sub_properties_t MQTT 5.0 SUBSCRIBE报文属性结构体定义如下: ```cpp typedef struct { qosa_uint32_t subscription_identifier; qcm_mqtt_user_property_t user_property[QCM_MQTT_MAX_USER_PROPERTY_SUPPORT]; qosa_uint8_t user_property_cnt; } qcm_mqtt_sub_properties_t; ``` | **参数** | **类型** | **说明** | | --- | --- | --- | | *subscription_identifier* | qosa_uint32_t | 订阅标识符,用于标识本次订阅请求 | | *user_property* | *qcm_mqtt_user_property_t* | 用户自定义属性键值对数组,最大长度由 *QCM_MQTT_MAX_USER_PROPERTY_SUPPORT* 定义;详见 [*qcm_mqtt_user_property_t*](#qcmmqttuserpropertyt) | | *user_property_cnt* | qosa_uint8_t | 当前设置的用户属性数量 | ### qcm_mqtt_disc_properties_t MQTT 5.0断开连接属性配置结构体定义如下: ```cpp typedef struct { qosa_uint32_t session_expiry_interval; qcm_mqtt_user_property_t user_property[QCM_MQTT_MAX_USER_PROPERTY_SUPPORT]; qosa_uint8_t user_property_cnt; } qcm_mqtt_disc_properties_t; ``` | **参数** | **类型** | **说明** | | --- | --- | --- | | *session_expiry_interval* | qosa_uint32_t | 会话过期间隔,用于控制服务器维持会话的时长;单位:秒 | | *user_property* | *qcm_mqtt_user_property_t* | 用户自定义属性键值对数组,允许附加额外信息 | | *user_property_cnt* | qosa_uint8_t | 当前设置的用户属性数量 | ### qcm_mqtt_subscribe_options_t MQTT5.0订阅选项结构体定义如下: ```cpp typedef struct { unsigned char noLocal; unsigned char retainAsPublished; unsigned char retainHandling; } qcm_mqtt_subscribe_options_t; ``` | **参数** | **类型** | **说明** | | --- | --- | --- | | *noLocal* | unsigned char | 本地消息过滤
*1*:不接收本客户端自己发布的消息
*0*:兼容旧版,正常接收匹配订阅的所有消息 | | *retainAsPublished* | unsigned char | 保留标志透传
1:保持原始发布消息的保留标志
0:仅在响应订阅请求时设置保留标志 | | *retainHandling* | unsigned char | 保留消息处理策略
*0*: 订阅时发送保留消息(传统MQTT行为)
*1*: 仅当订阅为新订阅时发送保留消息
*2*: 不发送保留消息 | ### qcm_mqtt_conn_properties_t MQTT 5.0 CONNECT扩展属性结构体定义如下: ```cpp typedef struct { qosa_uint32_t session_expiry_interval; qosa_uint16_t receive_maximum; qosa_uint16_t topic_alias_maximum; qosa_uint32_t maximum_packet_size; qosa_uint8_t request_response_information; qosa_uint8_t request_problem_information; qcm_mqtt_user_property_t user_property[QCM_MQTT_MAX_USER_PROPERTY_SUPPORT]; qosa_uint8_t user_property_cnt; } qcm_mqtt_conn_properties_t; ``` | **参数** | **类型** | **说明** | | --- | --- | --- | | *session_expiry_interval* | qosa_uint32_t | 会话过期间隔;单位:秒 | | *receive_maximum* | qosa_uint16_t | 允许同时处理的最大未确认QoS 1/2消息数 | | *topic_alias_maximum* | qosa_uint16_t | 允许使用的最大主题别名数量 | | *maximum_packet_size* | qosa_uint32_t | 允许接收的最大报文长度;单位:字节 | | *request_response_information* | qosa_uint8_t | 请求响应信息标志,指示服务器是否在CONNACK 中返回响应信息
*1*:返回
*0*:不返回 | | *request_problem_information* | qosa_uint8_t | 请求问题信息标志,指示服务器是否在错误时返回问题详情
*1*:返回
*0*:不返回 | | *user_property* | *qcm_mqtt_user_property_t* | 用户自定义属性键值对数组,最大长度由 *QCM_MQTT_MAX_USER_PROPERTY_SUPPORT* 定义;详见 [*qcm_mqtt_user_property_t*](#qcmmqttuserpropertyt) | | *user_property_cnt* | qosa_uint8_t | 当前设置的用户属性数量 | ### qcm_mqtt_will_properties_t MQTT5.0遗嘱消息扩展属性结构体定义如下: ```cpp typedef struct { qosa_uint32_t will_delay_interval; qosa_uint32_t message_expiry_interval; qcm_mqtt_data_t content_type; qcm_mqtt_data_t response_topic; qcm_mqtt_data_t correlation_data; qosa_uint8_t payload_format_indicator; qcm_mqtt_user_property_t user_property[QCM_MQTT_MAX_USER_PROPERTY_SUPPORT]; qosa_uint8_t user_property_cnt; } qcm_mqtt_will_properties_t; ``` | **参数** | **类型** | **说明** | | --- | --- | --- | | *will_delay_interval* | qosa_uint32_t | 遗嘱延迟间隔,连接断开后延迟指定时间才发布遗嘱消息;单位:秒 | | *message_expiry_interval* | qosa_uint32_t | 遗嘱消息过期间隔;单位:秒 | | *content_type* | *qcm_mqtt_data_t* | 遗嘱消息的内容类型描述;详见 [*qcm_mqtt_data_t*](#qcmmqttdata_t) | | *response_topic* | *qcm_mqtt_data_t* | 遗嘱消息的响应主题;详见 [*qcm_mqtt_data_t*](#qcmmqttdata_t) | | *correlation_data* | *qcm_mqtt_data_t* | 遗嘱消息的关联数据;详见 [*qcm_mqtt_data_t*](#qcmmqttdata_t) | | *payload_format_indicator* | qosa_uint8_t | 遗嘱消息载荷格式标识
*0*:未指定
*1*:UTF-8 编码文本 | | *user_property* | *qcm_mqtt_user_property_t* | 用户自定义属性键值对数组,最大长度由 *QCM_MQTT_MAX_USER_PROPERTY_SUPPORT* 定义;详见 [*qcm_mqtt_user_property_t*](#qcmmqttuserpropertyt) | | *user_property_cnt* | qosa_uint8_t | 当前设置的用户属性数量 | ### qcm_mqtt_common_resp_t MQTT通用响应状态通知结构体定义如下: ```c typedef struct { qcm_mqtt_support_version_e version; qosa_uint8_t client_id; qcm_mqtt_eercode_e result; qosa_uint8_t pocotrol_code; qosa_uint16_t msg_id; void *data; } qcm_mqtt_common_resp_t; ``` | **参数** | **类型** | **说明** | | --- | --- | --- | | *version* | *qcm_mqtt_support_version_e* | MQTT协议版本;详见 [*qcm_mqtt_support_version_e*](#qcmmqttsupportversione) | | *client_id* | qosa_uint8_t | 客户端ID | | *result* | *qcm_mqtt_eercode_e* | 执行结果码;详见 [*qcm_mqtt_eercode_e*](#qcmmqtteercode_e) | | *pocotrol_code* | qosa_uint8_t | MQTT协议原生返回码 | | *msg_id* | qosa_uint16_t | 对应交互报文的消息ID | | *data* | void * | 通用数据指针,根据具体事件类型指向不同的响应数据结构 | ### qcm_mqtt_suback_resp_t 订阅主题响应(SUBACK)状态通知结构体定义如下: ```c typedef struct { qosa_uint8_t *qoss; int qos_cnt; #ifdef CONFIG_QCM_MQTT5_FUNC qcm_mqtt_suback_properties_t *options; #endif } qcm_mqtt_suback_resp_t; ``` | **参数** | **类型** | **说明** | | --- | --- | --- | | *qoss* | qosa_uint8_t * | 服务器授权的QoS等级列表指针 | | *qos_cnt* | int | 本次应答返回的主题数量 | | *options* | *qcm_mqtt_suback_properties_t* * | MQTT5.0 SUBACK扩展属性指针,依赖 *CONFIG_QCM_MQTT5_FUNC* 宏 | ### qcm_mqtt_send_resp_t 消息发送状态通知结构体定义如下: ```c typedef struct { qosa_uint16_t msg_id; qosa_uint8_t retry_count; qcm_mqtt_send_result_type_e send_result; } qcm_mqtt_send_resp_t; ``` | **参数** | **类型** | **说明** | | --- | --- | --- | | *msg_id* | qosa_uint16_t | 消息ID | | *retry_count* | qosa_uint8_t | 发生重传时的累计重传次数 | | *send_result* | *qcm_mqtt_send_result_type_e* | 本次发送最终结果状态;详见 [*qcm_mqtt_send_result_type_e*](#qcmmqttsendresulttype_e) | ### qcm_mqtt_new_msg_notify_t 新消息到达通知结构体定义如下: ```c typedef struct { qosa_uint8_t client_id; qosa_uint8_t store_id; } qcm_mqtt_new_msg_notify_t; ``` | **参数** | **类型** | **说明** | | --- | --- | --- | | *client_id* | qosa_uint8_t | 触发事件的客户端ID | | *store_id* | qosa_uint8_t | 消息内部缓存存储索引ID | ### qcm_mqtt_close_cause_t 连接关闭原因通知结构体定义如下: ```c typedef struct { qcm_mqtt_client_close_reason_e close_cause; } qcm_mqtt_close_cause_t; ``` | **参数** | **类型** | **说明** | | --- | --- | --- | | *close_cause* | *qcm_mqtt_client_close_reason_e* | MQTT客户端连接关闭的具体原因;详见 [*qcm_mqtt_client_close_reason_e*](#qcmmqttclientclosereason_e) | ## 枚举定义 ### qcm_mqtt_eercode_e MQTT结果码枚举定义如下: ```c typedef enum { QCM_MQTT_RES_OK = QOSA_OK, QCM_MQTT_RES_ERROR_GENERAL = 1 | QCM_ERRCODE_MQTT_BASE, QCM_MQTT_RES_ERROR_NO_MEMORY, QCM_MQTT_RES_ERROR_PARAM_INVALID, QCM_MQTT_RES_ERROR_PARAM_IS_NULL, QCM_MQTT_RES_ERROR_STATUS, QCM_MQTT_RES_ERROR_CLIENT_EXIST, QCM_MQTT_RES_ERROR_ID_USE, QCM_MQTT_RES_ERROR_DNS, QCM_MQTT_RES_ERROR_IP_VERSION, QCM_MQTT_RES_ERROR_CREATE_TIMER, QCM_MQTT_RES_ERROR_START_TIMER, QCM_MQTT_RES_ERROR_STOP_TIMER, QCM_MQTT_RES_ERROR_MSG_ID_DUPLICATE, QCM_MQTT_RES_ERROR_STORE_FAIL, QCM_MQTT_RES_NOT_READ_DATA, QCM_MQTT_RES_ERROR_SUBCRIBE, QCM_MQTT_RES_ERROR_DATACALL, QCM_MQTT_RES_ERROR_SOCKET_CREATE, QCM_MQTT_RES_ERROR_TCP_CONNECT, QCM_MQTT_RES_ERROR_CONNECT_TIMEOUT, QCM_MQTT_RES_ERROR_TIMEOUT, QCM_MQTT_RES_ERROR_TASK, QCM_MQTT_RES_ERROR_PACKET, QCM_MQTT_RES_ERROR_SSL_HS_FAIL, QCM_MQTT_RES_ERROR_CONN_REFUSED, QCM_MQTT_RES_ERROR_NETWORK, QCM_MQTT_RES_ERROR_STORE_FULL, QCM_MQTT_RES_ERROR_PROTOCOL_FAIL, QCM_MQTT_RES_ERROR_DATA_WOULDBLOCK, #ifdef CONFIG_QCM_MQTT5_FUNC QCM_MQTT_RES_ERROR_INVALID_PROPERTY_ID, #endif } qcm_mqtt_eercode_e; ``` | **成员** | **说明** | | --- | --- | | *QCM_MQTT_RES_OK* | 函数执行成功 | | *QCM_MQTT_RES_ERROR_GENERAL* | 通用未知MQTT错误 | | *QCM_MQTT_RES_ERROR_NO_MEMORY* | 内存分配失败 | | *QCM_MQTT_RES_ERROR_PARAM_INVALID* | 参数无效 | | *QCM_MQTT_RES_ERROR_PARAM_IS_NULL* | 参数为空 | | *QCM_MQTT_RES_ERROR_STATUS* | 客户端状态不允许执行该操作 | | *QCM_MQTT_RES_ERROR_CLIENT_EXIST* | 客户端不存在 | | *QCM_MQTT_RES_ERROR_ID_USE* | 客户端ID已占用 | | *QCM_MQTT_RES_ERROR_DNS* | DNS域名解析失败 | | *QCM_MQTT_RES_ERROR_IP_VERSION* | PDP获取IP版本与服务端地址版本不匹配 | | *QCM_MQTT_RES_ERROR_CREATE_TIMER* | 定时器创建失败 | | *QCM_MQTT_RES_ERROR_START_TIMER* | 定时器启动失败 | | *QCM_MQTT_RES_ERROR_STOP_TIMER* | 定时器停止失败 | | *QCM_MQTT_RES_ERROR_MSG_ID_DUPLICATE* | 消息ID未释放重复使用 | | *QCM_MQTT_RES_ERROR_STORE_FAIL* | 获取消息缓存ID失败 | | *QCM_MQTT_RES_NOT_READ_DATA* | 读取缓存消息失败 | | *QCM_MQTT_RES_ERROR_SUBCRIBE* | 主题订阅失败 | | *QCM_MQTT_RES_ERROR_DATACALL* | 数据呼叫激活请求失败 | | *QCM_MQTT_RES_ERROR_SOCKET_CREATE* | Socket创建失败 | | *QCM_MQTT_RES_ERROR_TCP_CONNECT* | TCP连接建立失败 | | *QCM_MQTT_RES_ERROR_CONNECT_TIMEOUT* | CONNECT报文服务端超时无应答 | | *QCM_MQTT_RES_ERROR_TIMEOUT* | 整体请求超时 | | *QCM_MQTT_RES_ERROR_TASK* | MQTT后台任务未创建 | | *QCM_MQTT_RES_ERROR_PACKET* | 协议报文组包异常 | | *QCM_MQTT_RES_ERROR_SSL_HS_FAIL* | SSL/TLS 握手失败 | | *QCM_MQTT_RES_ERROR_CONN_REFUSED* | MQTT服务端拒绝协议连接 | | *QCM_MQTT_RES_ERROR_NETWORK* | 网络异常导致断连 | | *QCM_MQTT_RES_ERROR_STORE_FULL* | 接收消息缓存队列已满 | | *QCM_MQTT_RES_ERROR_PROTOCOL_FAIL* | 收到非法协议报文 | | *QCM_MQTT_RES_ERROR_DATA_WOULDBLOCK* | 协议数据不足,无法完成解析 | | *QCM_MQTT_RES_ERROR_INVALID_PROPERTY_ID* | MQTT5.0非法属性ID(仅开启 CONFIG_QCM_MQTT5_FUNC 生效) | ### qcm_mqtt_client_close_reason_e 客户端断开原因枚举定义如下: ```c typedef enum { QCM_MQTT_CLOSE_BY_ACIVE_CLOSE = 0, QCM_MQTT_CLOSE_BY_PEER_RESET = 1, QCM_MQTT_CLOSE_BY_PING_TIMEOUT = 2, QCM_MQTT_CLOSE_BY_CONN_TIMEOUT = 3, QCM_MQTT_CLOSE_BY_CONNACK_FAIL = 4, QCM_MQTT_CLOSE_BY_DISCONN_PEER_FIN = 5, QCM_MQTT_CLOSE_BY_PROTOCOL_FAIL = 8, QCM_MQTT_CLOSE_BY_DISCONNECT = 9, QCM_MQTT_CLOSE_BY_SSL_HS_FAILED = 10, QCM_MQTT_CLOSE_BY_SEND_FAILED = 11, QCM_MQTT_CLOSE_BY_PDP_DEACTED = 12, QCM_MQTT_CLOSE_BY_OTHER_FAIL = 13, } qcm_mqtt_client_close_reason_e; ``` | **成员** | **说明** | | --- | --- | | *QCM_MQTT_CLOSE_BY_ACIVE_CLOSE* | 主动关闭 | | *QCM_MQTT_CLOSE_BY_PEER_RESET* | 对端重置断开 | | *QCM_MQTT_CLOSE_BY_PING_TIMEOUT* | Ping超时断开 | | *QCM_MQTT_CLOSE_BY_CONN_TIMEOUT* | 连接超时 | | *QCM_MQTT_CLOSE_BY_CONNACK_FAIL* | CONNACK应答异常导致关闭 | | *QCM_MQTT_CLOSE_BY_DISCONN_PEER_FIN* | 服务端下发DISCONNECT主动断开 | | *QCM_MQTT_CLOSE_BY_PROTOCOL_FAIL* | 协议解析错误导致关闭 | | *QCM_MQTT_CLOSE_BY_DISCONNECT* | 本地发送DISCONNECT优雅断开 | | *QCM_MQTT_CLOSE_BY_SSL_HS_FAILED* | SSL握手失败断开 | | *QCM_MQTT_CLOSE_BY_SEND_FAILED* | 消息发送失败触发断开 | | *QCM_MQTT_CLOSE_BY_PDP_DEACTED* | PDP承载去激活导致断网 | | *QCM_MQTT_CLOSE_BY_OTHER_FAIL* | 其他内部错误 | ### qcm_mqtt_support_version_e MQTT协议版本枚举定义如下: ```c typedef enum { QCM_MQTT_VERSION_V3 = 3, QCM_MQTT_VERSION_V3_1_1 = 4, #ifdef CONFIG_QCM_MQTT5_FUNC QCM_MQTT_VERSION_V5 = 5, #endif QCM_MQTT_VERSION_MAX, } qcm_mqtt_support_version_e; ``` | **成员** | **说明** | | --- | --- | | *QCM_MQTT_VERSION_V3* | MQTT 3.0 | | *QCM_MQTT_VERSION_V3_1_1* | MQTT 3.1.1 | | *QCM_MQTT_VERSION_V5* | MQTT 5.0(仅开启CONFIG_QCM_MQTT5_FUNC生效) | | *QCM_MQTT_VERSION_MAX* | 版本上限占位,保留 | ### qcm_mqtt_quality_of_service_e MQTT QoS枚举定义如下: ```c typedef enum { QCM_MQTT_AT_MOST_ONCE_DELIVERY = 0, QCM_MQTT_AT_LEAST_ONCE_DELIVERY = 1, QCM_MQTT_EXACTLY_ONCE_DELIVERY = 2, } qcm_mqtt_quality_of_service_e; ``` | **成员** | **说明** | | --- | --- | | *QCM_MQTT_AT_MOST_ONCE_DELIVERY* | QoS=0,最多一次投递 | | *QCM_MQTT_AT_LEAST_ONCE_DELIVERY* | QoS=1,至少一次投递 | | *QCM_MQTT_EXACTLY_ONCE_DELIVERY* | QoS=2,仅一次精确投递 | ### qcm_mqtt_state_e 内部连接状态枚举定义如下: ```c typedef enum { QCM_MQTT_STATE_INIT = 0, QCM_MQTT_STATE_DATACALL_ING = 1, QCM_MQTT_STATE_DNS_QUERY = 2, QCM_MQTT_STATE_TCP_CONNECTING = 3, QCM_MQTT_STATE_SSL_HANDSHAKE = 4, QCM_MQTT_STATE_TCP_CONNECTED = 5, QCM_MQTT_STATE_MQTT_CONNECTING = 6, QCM_MQTT_STATE_MQTT_CONNECTED = 7, QCM_MQTT_STATE_MQTT_DISCONNECTING = 8, QCM_MQTT_STATE_TCP_CLOSING = 9, QCM_MQTT_STATE_TCP_CLOSED = 10, } qcm_mqtt_state_e; ``` | **成员** | **说明** | | --- | --- | | *QCM_MQTT_STATE_INIT* | 初始空闲状态,可发起连接 | | *QCM_MQTT_STATE_DATACALL_ING* | 正在进行数据呼叫激活。 | | *QCM_MQTT_STATE_DNS_QUERY* | 正在进行域名DNS解析 | | *QCM_MQTT_STATE_TCP_CONNECTING* | TCP握手连接中 | | *QCM_MQTT_STATE_SSL_HANDSHAKE* | SSL/TLS 握手协商中 | | *QCM_MQTT_STATE_TCP_CONNECTED* | TCP连接完成 | | *QCM_MQTT_STATE_MQTT_CONNECTING* | 协议连接阶段 | | *QCM_MQTT_STATE_MQTT_CONNECTED* | 协议连接完成 | | *QCM_MQTT_STATE_MQTT_DISCONNECTING* | 协议正在关闭 | | *QCM_MQTT_STATE_TCP_CLOSING* | TCP正在关闭 | | *QCM_MQTT_STATE_TCP_CLOSED* | TCP已关闭 | ### qcm_mqtt_send_result_type_e MQTT消息发送结果状态枚举定义如下: ```c typedef enum { QCM_MQTT_SEND_OK = 0, QCM_MQTT_SEND_RETRY, QCM_MQTT_SEND_ERROR, } qcm_mqtt_send_result_type_e; ``` | **成员** | **说明** | | --- | --- | | *QCM_MQTT_SEND_OK* | 数据包发送成功;对于QoS 1/2,表示已收到ACK/PUBCOMP;对于QoS 0,表示报文已成功发出(无需ACK) | | *QCM_MQTT_SEND_RETRY* | 超时未收到MQTT协议应答、或PUBCOMP流程未完成,触发消息重传 | | *QCM_MQTT_SEND_ERROR* | 达到最大重传次数仍未收到应答,发送最终失败 | ### qcm_mqtt_client_event_e 触发的事件类型枚举定义如下: ```c typedef enum { QCM_MQTT_CLIENT_OPEN_EVENT = 1, QCM_MQTT_CLIENT_CLOSE_EVENT = 2, QCM_MQTT_CLIENT_CONNECT_EVENT = 3, QCM_MQTT_CLIENT_SUBSCRIBE_EVENT = 4, QCM_MQTT_CLIENT_SUBACK_EVENT = 5, QCM_MQTT_CLIENT_UNSUBSCRIBE_EVENT = 6, QCM_MQTT_CLIENT_UNSUBACK_EVENT = 7, QCM_MQTT_CLIENT_PUBLISH_EVENT = 8, QCM_MQTT_CLIENT_PING_EVENT = 9, QCM_MQTT_CLIENT_DISCONNECT_EVENT = 10, QCM_MQTT_CLIENT_NEW_MESSAGE_EVENT = 11, QCM_MQTT_CLIENT_STATE_EVENT = 12, #ifdef CONFIG_QCM_MQTT5_FUNC QCM_MQTT_CLIENT_AUTH_EVENT = 13, #endif QCM_MQTT_CLIENT_MAX_EVENT, } qcm_mqtt_client_event_e; ``` | **成员** | **说明** | | --- | --- | | *QCM_MQTT_CLIENT_OPEN_EVENT* | TCP连接创建成功事件 | | *QCM_MQTT_CLIENT_CLOSE_EVENT* | TCP连接关闭事件 | | *QCM_MQTT_CLIENT_CONNECT_EVENT* | MQTT协议连接建立成功事件(收到CONNACK) | | *QCM_MQTT_CLIENT_SUBSCRIBE_EVENT* | 主题订阅请求已发送事件;在开启 MQTT5.0 的情况下,此事件对应 [*qcm_mqtt_send_resp_t*](#qcmmqttsendrespt) | | *QCM_MQTT_CLIENT_SUBACK_EVENT* | 收到主题订阅响应(SUBACK)事件;在开启 MQTT5.0 的情况下,此事件对应 [*qcm_mqtt_suback_resp_t*](#qcmmqttsubackrespt) | | *QCM_MQTT_CLIENT_UNSUBSCRIBE_EVENT* | 主题取消订阅请求已发送事件;在开启 MQTT5.0 的情况下,此事件对应 [*qcm_mqtt_send_resp_t*](#qcmmqttsendrespt) | | *QCM_MQTT_CLIENT_UNSUBACK_EVENT* | 收到取消订阅响应(UNSUBACK)事件 | | *QCM_MQTT_CLIENT_PUBLISH_EVENT* | 消息发布请求已发送事件;在开启 MQTT5.0 的情况下,此事件对应 [*qcm_mqtt_send_resp_t*](#qcmmqttsendrespt) | | *QCM_MQTT_CLIENT_PING_EVENT* | PINGREQ心跳请求已发送事件 | | *QCM_MQTT_CLIENT_DISCONNECT_EVENT* | MQTT 协议连接断开事件(主动或被动) | | *QCM_MQTT_CLIENT_NEW_MESSAGE_EVENT* | 收到服务器下发的新消息(PUBLISH)事件;在开启 MQTT5.0 的情况下,此事件对应 [*qcm_mqtt_new_msg_notify_t*](#qcmmqttnewmsgnotify_t) | | *QCM_MQTT_CLIENT_STATE_EVENT* | 客户端内部状态机变更事件;在开启 MQTT5.0 的情况下,此事件对应 [*qcm_mqtt_close_cause_t*](#qcmmqttclosecauset) | | *QCM_MQTT_CLIENT_AUTH_EVENT* | MQTT 5.0 认证事件(仅在定义 *CONFIG_QCM_MQTT5_FUNC* 时可用) | | *QCM_MQTT_CLIENT_MAX_EVENT* | 事件枚举边界占位,用于数组长度定义,不代表实际事件。 | # 应用逻辑流程图 ```{figure} images/board_QQiNw12flhMT5CbIjtdcMeXdnzc.jpg :align: center :alt: image ``` # 示例代码 - MQTT: https://github.com/UniRTOS/UniRTOS-Doc-Examples/blob/main/network/network_protocol/mqtt/mqtt_demo.c - MQTT 5: https://github.com/UniRTOS/UniRTOS-Doc-Examples/blob/main/network/network_protocol/mqtt/mqtt5_demo.c