应用层网络协议
AC79NN AIoT SDK 提供的应用层网络协议能力总览,涵盖 HTTP/HTTPS 客户端库、MQTT 物联网消息协议(OneSDK、腾讯云 IoT Explorer、阿里云 Link SDK 三套栈)、WebSocket(NoPoll / Mongoose)以及 Mongoose 多协议引擎,是设备与云端应用通信的核心层。
Purpose and Scope
本页介绍 SDK 中位于 include_lib/net(NETWORK_LIB)及应用层 SDK(apps/common/LLM/onesdk、apps/common/LLM/tc_iot_twetalk)内的应用层协议实现与使用方式:
- HTTP/HTTPS 客户端库(
http_cli.h)的上下文、回调、错误码模型; - MQTT 协议的三套实现:OneSDK
iot_mqtt(基于 libwebsockets)、腾讯云qcloud_iot_explorer_sdk、阿里云include_lib/net/aliyun; - WebSocket 协议支持(NoPoll 库与 Mongoose 引擎);
- Mongoose 多协议事件引擎(HTTP / WebSocket / MQTT 统一回调模型)。
以下内容属于兄弟页面,不在本页展开:TCP/UDP 传输层与 socket 接口、TLS/SSL 安全层、DNS 解析、Wi-Fi 网络配置。本页聚焦协议本身的报文模型、API 契约与事件语义。
概述
在 AIoT 场景中,设备需要以标准化协议与云端平台通信:用 HTTP/HTTPS 拉取或上报资源,用 MQTT 做低开销、高实时的发布/订阅消息,用 WebSocket 承载全双工实时通道。AC79NN SDK 对此提供了多套可选的协议栈,按产品形态选择:
| 协议栈 | 位置 | 适用场景 |
|---|---|---|
| HTTP/HTTPS 客户端 | include_lib/net/http/http_cli.h | REST API、OTA 下载、固件/资源拉取 |
| OneSDK MQTT(lws) | apps/common/LLM/onesdk/include/iot_mqtt.h | LLM/AI 应用,MQTT over WebSocket,支持 MQTTS |
| 腾讯云 IoT Explorer MQTT | apps/common/LLM/tc_iot_twetalk/qcloud_iot_explorer_sdk/ | 腾讯云物联网平台的设备接入、数据模板、OTA |
| 阿里云 Link SDK | include_lib/net/aliyun/ | 阿里云物联网平台的设备模型、影子、OTA |
| NoPoll WebSocket | include_lib/net/nopoll/ | 独立 WebSocket 客户端 |
| Mongoose 引擎 | include_lib/net/mongoose/mongoose.h | 多协议统一事件驱动的嵌入式网络应用 |
设计上,各协议栈都遵循事件回调 + 用户私有数据的模型:库负责报文收发与状态机,业务逻辑通过回调函数被驱动,回调携带用户 priv/user_data 指针,避免全局状态。
架构
flowchart TD
subgraph sg_App["应用层 (Applications)"]
APP["业务 App / LLM 应用"]
end
subgraph sg_Proto["应用层协议栈 (NETWORK_LIB + App SDK)"]
HTTP["HTTP/HTTPS 客户端<br/>http_cli.h"]
MQTT1["OneSDK iot_mqtt<br/>libwebsockets (MQTT over WS)"]
MQTT2["腾讯云 IoT Explorer<br/>mqtt_client_*.c"]
MQTT3["阿里云 Link SDK<br/>iotx_cm_mqtt / dm_*"]
WS["WebSocket<br/>nopoll / mongoose"]
MGS["Mongoose 多协议引擎<br/>MG_EV_HTTP_MSG / WS / MQTT"]
end
subgraph sg_Transport["传输层"]
SOCK["Socket 抽象<br/>net_http_socket_ops / lws"]
TLS["TLS 加密 (MQTTS / HTTPS)"]
end
APP --> HTTP
APP --> MQTT1
APP --> MQTT2
APP --> MQTT3
APP --> WS
APP --> MGS
HTTP --> SOCK
MQTT1 --> WS
MQTT2 --> SOCK
MQTT3 --> SOCK
WS --> SOCK
MGS --> SOCK
SOCK --> TLS
TLS --> TCP["TCP/IP"]
架构要点:传输层可替换。HTTP 客户端通过 net_http_socket_ops 函数指针表抽象 socket 创建/收发/关闭(见 http_cli.h),这使得同一套 HTTP 解析逻辑既能跑在明文 TCP 上,也能挂在 TLS 之上;OneSDK MQTT 则直接基于 libwebsockets 的 lws_context 运行,天然获得 TLS 与 WebSocket 能力。
核心协议详解
HTTP/HTTPS 客户端(http_cli.h)
http_cli.h 是 SDK 内置 HTTP/HTTPS 客户端库的公共头文件,采用单上下文 + 回调的拉模式设计:调用方填充 httpcli_ctx 结构(URL、范围请求、POST 数据、超时、回调),库负责连接、发送、解析响应并分块回调数据。
错误码模型(httpin_error,http_cli.h)覆盖了客户端可能遇到的每类失败:内存不足、URL 解析头失败、服务器响应异常、socket 连接失败、用户回调中止、参数错误、重定向过深(最多 4 层)、chunked 传输解析失败、接收超时等。
处理状态(httpin_status,http_cli.h)通过 HTTPIN_HEADER → HTTPIN_PROGRESS → HTTPIN_FINISHED 描述一次下载的推进,回调在每个状态被调用;HTTPIN_ABORT/HTTPIN_ERROR/HTTPIN_NON_BLOCK 分别表示用户中止、出错与"非阻塞处理中"。
上下文结构(http_cli.h)分为三段:用户必须初始化的输入(url、user_http_header、lowRange/highRange、cb、priv、post_data、data_len、timeout_millsec、connection),用户可读取的输出(content_length、content_type、transfer_encoding),以及库内部状态(exit_flag、chunked 解析缓存、mode 等)。HTTP_USE_DATA_BOX/HTTP_POST_MORE_DATA 宏控制内部 512 字节接收盒与分段 POST 能力。
MQTT 协议栈
OneSDK iot_mqtt(LLM 场景)
iot_mqtt.h 定义了面向 LLM/AI 应用的高层 MQTT 客户端,底层由 libwebsockets(lws_*)驱动,即 MQTT over WebSocket(iot_mqtt.h)。其设计特点:
- 配置即结构体:
iot_mqtt_config_t集中了主机、用户名/密码(AWS string 类型)、keep_alive、ping 间隔、自动重连开关、MQTTS 使能; - 事件驱动:
iot_mqtt_event_type_t定义了 CONNECTED/DISCONNECTED/PUBLISHED/SUBSCRIBED/UNSUBSCRIBED/MESSAGE_RECEIVED/ERROR 七类事件,通过event_callback统一上抛; - 主题订阅映射:
iot_mqtt_topic_map_t把 topic 与消息回调绑定,iot_mqtt_pending_sub_list_t/iot_mqtt_pending_pub_list_t分别缓存待订阅/待发布列表,配合waiting_for_suback/waiting_for_puback标志实现同步确认; - 线程安全:
iot_mqtt_ctx_t内置sub_topic_mutex/pub_topic_mutex两把 pthread 互斥锁,分别保护订阅表与发布表; - QoS 受限:仅支持 QoS0/QoS1(QoS2 注释"暂不支持"),符合嵌入式资源约束。
腾讯云 IoT Explorer SDK(tc_iot_twetalk)
qcloud_iot_explorer_sdk 提供完整的 MQTT 客户端分层:mqtt_client_connect.c(建连与 CONNACK)、mqtt_client_publish.c/mqtt_client_subscribe.c(PUBLISH/SUBSCRIBE 报文)、mqtt_client_yield.c(事件循环)、mqtt_packet_serialize.c/mqtt_packet_deserialize.c(MQTT 报文编解码)、mqtt_client_common.c(公共逻辑)。在此之上还有 data_template_mqtt.c(物模型数据模板)、ota_mqtt.c(OTA 升级)、system_mqtt.c(系统消息)、sevice_mqtt.c(服务调用),构成腾讯云平台的完整接入链路。其协议头见 mqtt_packet.h、qcloud_iot_mqtt_client.h。
阿里云 Link SDK(include_lib/net/aliyun)
阿里云侧以 iotx_cm_mqtt.h 为连接管理入口,dm_* 系列(dm_client.h、dm_shadow.h、dm_tsl_alink.h、dm_fota.h、dm_cota.h、dm_message.h、dm_msg_process.h、dm_manager.h)实现设备模型(Device Model)、设备影子(Shadow)、TSL Alink 协议、固件/配置 OTA 与消息缓存;dev_sign_* 负责设备三元组签名鉴权,dm_server_adapter.h/dm_client_adapter.h 抽象上下行通道。
WebSocket 与 Mongoose 多协议引擎
- NoPoll(
include_lib/net/nopoll/)是独立的 WebSocket 库,nopoll_conn.h管理连接,nopoll_decl.h中nopoll_msg抽象单条 WebSocket 消息(nopoll_decl.h); - Mongoose(
include_lib/net/mongoose/mongoose.h)是事件驱动的多协议引擎,用统一事件枚举区分协议:MG_EV_HTTP_MSG(HTTP 请求/响应)、MG_EV_WS_OPEN(WebSocket 握手完成)、MG_EV_WS_MSG/MG_EV_WS_CTL(WebSocket 数据/控制帧)、MG_EV_MQTT_CMD(MQTT 底层命令),事件参数分别指向mg_http_message/mg_ws_message/mg_mqtt_message(mongoose.h)。WebSocket 帧类型通过WEBSOCKET_OP_*常量(CONTINUE/TEXT 等)区分(mongoose.h)。
核心流程
HTTP 请求/下载流程
sequenceDiagram
participant App as 业务代码
participant HTTP as HTTP 客户端 (httpcli_ctx)
participant CB as 用户回调 httpcli_cb
participant Sock as Socket (net_http_socket_ops)
App->>HTTP: 填充 url/cb/priv/timeout 等字段
HTTP->>Sock: sock_create / 连接 + 发送请求头
Sock-->>HTTP: 响应头 + 数据块
loop 数据分块到达
HTTP->>CB: HTTPIN_HEADER (响应头就绪)
HTTP->>CB: HTTPIN_PROGRESS (数据块, buf/size)
CB-->>HTTP: 返回 0 继续 / 非 0 中止
end
HTTP->>CB: HTTPIN_FINISHED (content_length 完整接收)
HTTP->>Sock: sock_close (或 keep-alive 复用)
流程说明:httpcli_ctx 的 ops 指针指向 net_http_socket_ops 函数表(http_cli.h),库通过它完成建连、发送、接收与关闭;收到的数据按 HTTPIN_HEADER → HTTPIN_PROGRESS… → HTTPIN_FINISHED 顺序交给用户回调;若用户回调返回非零则视为中止(对应 HERROR_CALLBACK)。http_body_obj 在内存不足时自动 realloc 并递增 buf_count,支持超大响应体的分片累积(http_cli.h)。
OneSDK MQTT 发布/订阅流程
sequenceDiagram
participant App as 业务代码
participant MQTT as iot_mqtt (lws)
participant Broker as MQTT Broker
App->>MQTT: iot_mqtt_init(ctx, config)
App->>MQTT: iot_mqtt_subscribe(ctx, topic_map)
MQTT->>MQTT: 加入 pending_sub_list + 加锁 sub_topic_mutex
App->>MQTT: iot_mqtt_connect(ctx)
MQTT-->>App: MQTT_EVENT_CONNECTED (event_callback)
MQTT->>Broker: SUBSCRIBE 报文
Broker-->>MQTT: SUBACK
MQTT-->>App: MQTT_EVENT_SUBSCRIBED
App->>MQTT: iot_mqtt_publish(ctx, topic, payload, len, qos)
MQTT->>Broker: PUBLISH (QoS0/1)
Broker-->>MQTT: PUBACK (QoS1)
MQTT-->>App: MQTT_EVENT_PUBLISHED
loop 事件循环
App->>MQTT: iot_mqtt_run_event_loop(ctx, timeout_ms)
Broker-->>MQTT: 下行消息
MQTT->>App: MQTT_EVENT_MESSAGE_RECEIVED (message_callback)
end
设计意图:订阅在连接之前即可登记,pending_sub_list 缓存待订阅项,连接建立后统一补发 SUBSCRIBE,避免"订阅早于连接"的竞态;waiting_for_suback/waiting_for_puback 是 volatile 标志,配合互斥锁在单线程事件循环内安全地完成 ACK 同步(iot_mqtt.h)。
使用示例
示例 1:HTTP 客户端上下文初始化(头文件契约)
以下代码展示了 httpcli_ctx 的使用契约——用户需初始化的字段与库输出的字段,摘自库公共头文件:
typedef struct httpcli_ctx {
void *sock_hdl;
const struct net_http_socket_ops *ops;
//user need init
const char *url; /*!< url */
char *redirection_url; /*!< redirection_url */
const char *user_http_header; /*!< user parse http header in person, must finish in '\0' */
unsigned int lowRange; /*!< Start byte range of the content to get */
unsigned int highRange; /*!< Finish byte range of the content to get */
httpcli_cb cb; /*!< user callback function */
void *priv; /*!< The pointer to the private data of the callback function */
const char *post_data; /*!< The pointer to the post data */
int data_len; /*!< The size of the post data */
int timeout_millsec; /*!< The timeout value of the connect, send, receive */
char *connection; /*!< "close" or "keep-alive" */
//user get
int content_length; /*!< The length of the content get from the server */
char content_type[64]; /*!< The type of the content get from the server */
char transfer_encoding[64]; /*!< The transfer encoding method of the content */
...
} httpcli_ctx;
Source: http_cli.h
调用方只需设置 //user need init 部分(URL、回调、私有指针、超时、可选 POST 数据与 Range),发起请求后即可从 //user get 部分读取服务器返回的 content_length、content_type 与 transfer_encoding。ops 由库或移植层提供,用于把 socket 实现(明文 TCP 或 TLS)注入客户端。
示例 2:OneSDK MQTT 配置与回调(头文件契约)
#define IOT_DEFAULT_PING_INTERVAL_S 60 // 60s
typedef struct {
const char *mqtt_host;
iot_basic_config_t *basic_config;
struct aws_string *username;
struct aws_string *password;
uint16_t keep_alive;
bool auto_reconnect;
int32_t ping_interval;
bool enable_mqtts;
} iot_mqtt_config_t;
typedef void (*message_callback)(const char *topic, const uint8_t *payload, size_t len, void *user_data);
typedef void (*event_callback)(iot_mqtt_event_type_t event_type, void *user_data);
typedef struct {
const char *topic;
message_callback message_callback;
event_callback event_callback;
void *user_data;
iot_mqtt_qos_t qos;
} iot_mqtt_topic_map_t;
Source: iot_mqtt.h
使用方式:构造 iot_mqtt_config_t(指定 host、鉴权、keep_alive、是否自动重连、是否启用 MQTTS),将每个关注的主题封装为 iot_mqtt_topic_map_t(绑定 message_callback 与 event_callback,两者共享 user_data),然后按 iot_mqtt_init → iot_mqtt_subscribe → iot_mqtt_connect → iot_mqtt_run_event_loop 的顺序驱动。QoS 通过 iot_mqtt_qos_t(IOT_MQTT_QOS0/IOT_MQTT_QOS1)指定。
配置选项
OneSDK MQTT(iot_mqtt_config_t)
| 选项 | 类型 | 默认 | 说明 |
|---|---|---|---|
mqtt_host | const char * | 无(必填) | MQTT Broker 主机地址 |
basic_config | iot_basic_config_t * | NULL | 基础配置(鉴权/证书等,由 OneSDK 定义) |
username / password | struct aws_string * | NULL | 连接鉴权用户名/密码 |
keep_alive | uint16_t | 0(由用户设置) | 保活时间(秒),对应 MQTT CONNECT 报文 Keep Alive 字段 |
auto_reconnect | bool | false | 断线后是否自动重连 |
ping_interval | int32_t | IOT_DEFAULT_PING_INTERVAL_S(60) | PINGREQ 发送间隔(秒),见 iot_mqtt.h |
enable_mqtts | bool | false | 是否启用 MQTTS(TLS 加密) |
HTTP 客户端(httpcli_ctx 输入字段)
| 选项 | 类型 | 默认 | 说明 |
|---|---|---|---|
url | const char * | 无(必填) | 请求 URL |
user_http_header | const char * | NULL | 自定义 HTTP 头,必须以 '\0' 结尾 |
lowRange / highRange | unsigned int | 0 | 请求内容字节范围(Range 请求) |
cb | httpcli_cb | NULL(使用默认回调) | 数据处理回调;为 NULL 时走默认 chunked 解析,失败返回 HERROR_BODY_ANALYSIS |
priv | void * | NULL | 回调私有数据 |
post_data / data_len | const char * / int | NULL / 0 | POST 请求体与长度 |
timeout_millsec | int | 0(由用户设置) | 连接/发送/接收超时(毫秒),超时返回 HERROR_RECV_TIMEOUT |
connection | char * | NULL | "close" 或 "keep-alive" |
配置契约见 http_cli.h。
API 参考
OneSDK MQTT 客户端
所有函数均以 iot_mqtt_ctx_t *ctx 为首参,返回 int(0 表示成功,非 0 表示失败),声明于 iot_mqtt.h。
int iot_mqtt_init(iot_mqtt_ctx_t *ctx, iot_mqtt_config_t *config) 初始化 MQTT 上下文:创建 libwebsockets lws_context、初始化互斥锁与待办列表。
ctx:由调用方分配并置零的上下文;config:见配置表。- 返回:0 成功,非 0 失败(如 lws_context 创建失败)。
void iot_mqtt_deinit(iot_mqtt_ctx_t *ctx) 释放上下文:关闭连接、销毁 lws_context 与互斥锁。
int iot_mqtt_connect(iot_mqtt_ctx_t *ctx) 发起连接(含 MQTTS 时走 TLS 握手),成功后回调 MQTT_EVENT_CONNECTED。
int iot_mqtt_disconnect(iot_mqtt_ctx_t *ctx) 主动断开连接,触发 MQTT_EVENT_DISCONNECTED。
int iot_mqtt_reconnect(iot_mqtt_ctx_t *ctx) 手动重连;若配置了 auto_reconnect,断线后库会自动调用。
int iot_mqtt_publish(iot_mqtt_ctx_t *ctx, const char *topic, const uint8_t *payload, size_t len, int qos) 发布消息。qos 取 IOT_MQTT_QOS0/IOT_MQTT_QOS1(QoS2 暂不支持);QoS1 时等待 PUBACK 后回调 MQTT_EVENT_PUBLISHED。内部以 pub_topic_mutex 保护待发布列表。
int iot_mqtt_subscribe(iot_mqtt_ctx_t *ctx, iot_mqtt_topic_map_t *topic_map) 登记订阅主题(可连接前调用,存入 pending_sub_list);连接成功后补发 SUBSCRIBE 并等待 SUBACK(MQTT_EVENT_SUBSCRIBED)。
int iot_mqtt_run_event_loop(iot_mqtt_ctx_t *ctx, int timeout_ms) 运行 lws 事件循环,驱动收发与回调分发;应用需周期性调用(如配合 ping_interval 维持保活)。
HTTP 客户端错误码(httpin_error)
| 值 | 枚举 | 触发场景 |
|---|---|---|
| 1 | HERROR_REDIRECT | 保留未用 |
| 0 | HERROR_OK | 成功 |
| -1 | HERROR_MEM | 内存分配失败 |
| -2 | HERROR_HEADER | 从 URL 设置请求头失败 |
| -3 | HERROR_RESPOND | 服务器响应异常 |
| -4 | HERROR_SOCK | socket 连接失败 |
| -5 | HERROR_CALLBACK | 用户回调返回非零(中止) |
| -6 | HERROR_UNKNOWN | socket 处理未知错误 |
| -7 | HERROR_PARAM | 输入参数错误 |
| -8 | HERROR_REDIRECT_DEEP | 重定向超过最大深度(4 层) |
| -9 | HERROR_BODY_ANALYSIS | 默认回调解析 chunked 响应失败 |
| -10 | HERROR_SOCKHDL | socket 句柄异常 |
| -11 | HERROR_RECV_TIMEOUT | socket 接收超时 |
完整枚举见 http_cli.h。
HTTP 回调函数
typedef int (*httpcli_cb)(void *httpcli_ctx, void *buf, unsigned int size, void *priv, httpin_status status)
httpcli_ctx:HTTP 上下文;buf/size:本次数据块指针与长度;priv:用户私有数据;status:httpin_status之一。- 返回 0 继续处理,返回非 0 中止并导致
HERROR_CALLBACK(http_cli.h)。
失败模式、边界情况与并发
HTTP 客户端
- 重定向限制:最多支持 4 层重定向,超出返回
HERROR_REDIRECT_DEEP,防止重定向环导致的资源耗尽; - 超时控制:
timeout_millsec统一作用于连接/发送/接收,超时映射为HERROR_RECV_TIMEOUT;业务侧应据此做重试或降级; - chunked 解析:用户未提供
cb时走默认回调,Transfer-Encoding: chunked 接收失败返回HERROR_BODY_ANALYSIS——自定义回调模式下该逻辑由用户接管; - 内存策略:
http_body_obj的buf_count累加 + 自动 realloc 机制支持未知长度响应体,但buf_count为unsigned char,极端超大响应存在计数回绕边界,适合流式消费而非全量缓存; - 模式选择:
MODE_HTTP/MODE_HTTPS决定是否走 TLS;HTTPIN_NON_BLOCK状态支持非阻塞处理路径。
MQTT(OneSDK)
- QoS 约束:仅 QoS0/1,无 QoS2;发布端 QoS1 依赖 PUBACK,Broker 不回复时将停留在
waiting_for_puback状态,需要超时/重连机制兜底; - 竞态防护:订阅先于连接登记,
pending_sub_list在sub_topic_mutex保护下访问;waiting_for_suback/waiting_for_puback为volatile,用于事件循环内的同步标志; - 断线恢复:
auto_reconnect与iot_mqtt_reconnect配合MQTT_EVENT_DISCONNECTED事件,业务可在此事件中清理会话状态;MQTTS 模式下 TLS 握手失败会触发MQTT_EVENT_ERROR; - 单线程模型:所有回调均在
iot_mqtt_run_event_loop所在线程执行,回调内不应长时间阻塞,否则影响 PINGREQ 保活与 ACK 处理。
腾讯云 / 阿里云栈
- 腾讯云 SDK 的报文编解码与连接状态机分离(
mqtt_packet_serialize/deserialize),便于在受限内存中按需裁剪;mqtt_client_yield需周期性调用以维持心跳; - 阿里云
dm_message_cache提供上行消息缓存,网络抖动时避免数据丢失;dm_fota/dm_cota将 OTA 与固件/配置下发协议绑定到设备模型框架。
性能与运维考量
- 保活开销:OneSDK 默认
ping_interval60 秒,与keep_alive配合可检测半开连接;实际部署中应按运营商 NAT 超时调整; - 缓冲区设计:HTTP 接收盒为 512 字节(
http_data_box.buf[512]),逐块回调,适合边收边写 Flash/边渲染的流式场景;http_body_obj则面向需要整体响应体的场景,两者按需选择; - 协议栈选型:纯 REST 场景用
http_cli;LLM/长连接实时场景用 OneSDK MQTT(over WebSocket);接入特定云平台时优先使用该平台 SDK(腾讯/阿里),以复用其物模型、影子与 OTA 能力; - TLS 开销:
enable_mqtts/MODE_HTTPS引入握手与加密计算,对 MCU 主频与内存敏感,建议仅在传输敏感数据或平台强制时启用。
扩展点
- 传输层替换:
net_http_socket_ops(sock_create/send/recv/close)允许把 HTTP 客户端挂到任意 socket 实现上(明文 TCP、TLS、甚至虚拟通道),是移植与安全增强的官方扩展点(http_cli.h); - 用户回调:
httpcli_cb与iot_mqtt_topic_map_t均以priv/user_data传递业务上下文,可在不改库代码的前提下扩展业务状态机; - 多协议统一:基于 Mongoose
MG_EV_*事件模型可在单一lws/mg事件循环中混合 HTTP、WebSocket 与 MQTT 服务,适合网关类产品; - 云平台适配:腾讯云
data_template_mqtt.c、阿里云dm_tsl_alink.h均为平台物模型协议的实现层,新增平台能力时按同样模式扩展即可。