fix(vd960DBN): MQTT CONNECT 改为 poll 内延迟发送,避免中断内 WCHNET_SocketSend 崩溃

1. 参考 net_srv.c mqtt_connect 模式重写 iot_mqtt_send_connect:
   - clientID 用 g_dev_number_str(全局),不用 g_iot_dev_serial
   - username/password 直接赋值,不用 strlen 检查
   - memset 手动初始化,不用 brace-initializer 赋值

2. SINT_STAT_CONNECT 中断内不再调 iot_mqtt_send_connect,
   改为标记 TCP_CONNECTED,由 iot_mqtt_poll 下一轮发送 —
   参考 tcp_json_handle_sock_int 不立即发送数据的模式
This commit is contained in:
wangfq
2026-07-06 15:16:24 +08:00
parent 884a622cab
commit 88526158d0
@@ -77,33 +77,26 @@ static int iot_mqtt_send(const uint8_t *buf, uint16_t len) {
return (ret == WCHNET_ERR_SUCCESS) ? 0 : -1;
}
/* 发送 MQTT CONNECT */
/* 发送 MQTT CONNECT — 参考 net_srv.c mqtt_connect 实现 */
static int iot_mqtt_send_connect(void) {
static MQTTPacket_connectData opts; // static: 避免 85字节栈开销
static uint8_t buf[256]; // static: 避免 256字节栈开销
static MQTTPacket_connectData opts; // static: 避免栈开销
static uint8_t buf[256];
int len;
// struct assignment 不支持 brace initializer,用临时变量中转
{ MQTTPacket_connectData _init = MQTTPacket_connectData_initializer; opts = _init; }
opts.MQTTVersion = 4; // MQTT 3.1.1
// 手动初始化(参考 net_srv.c 模式,不依赖 brace-initializer 赋值)
memset(&opts, 0, sizeof(opts));
opts.struct_id[0] = 'M'; opts.struct_id[1] = 'Q';
opts.struct_id[2] = 'T'; opts.struct_id[3] = 'C';
opts.MQTTVersion = 4;
opts.keepAliveInterval = IOT_MQTT_KEEPALIVE_SEC;
opts.cleansession = 1;
// clientID
if (strlen((char *)iot_net_info.client_id) > 0) {
opts.clientID.cstring = (char *)iot_net_info.client_id;
} else {
opts.clientID.cstring = g_iot_dev_serial;
}
// clientID — 参考 net_srv.c 直接使用 g_dev_number_str
opts.clientID.cstring = g_dev_number_str;
// username / password
if (strlen((char *)iot_net_info.username) > 0) {
opts.username.cstring = (char *)iot_net_info.username;
}
if (strlen((char *)iot_net_info.password) > 0) {
opts.password.cstring = (char *)iot_net_info.password;
}
// username / password — 参考 net_srv.c 直接赋值
opts.username.cstring = (char *)iot_net_info.username;
opts.password.cstring = (char *)iot_net_info.password;
len = MQTTSerialize_connect(buf, sizeof(buf), &opts);
if (len <= 0) {
@@ -531,15 +524,13 @@ static void iot_connect_broker(void) {
void iot_mqtt_handle_sock_int(uint8_t socketid, uint8_t intstat) {
if (socketid != g_iot_socket) return;
/* CONNECT 成功 */
/* CONNECT 成功 — 仅标记状态,由 poll 延迟发送 CONNECT */
if (intstat & SINT_STAT_CONNECT) {
PRINT("IOT: TCP connected (sock=%d)\n", socketid);
WCHNET_ModifyRecvBuf(socketid, (uint32_t)_iot_wchnet_buf, RECE_BUF_LEN);
g_iot_state = IOT_STATE_TCP_CONNECTED;
_iot_recv_len = 0;
// 发送 MQTT CONNECT
iot_mqtt_send_connect();
g_iot_state = IOT_STATE_MQTT_CONNECTING;
// 不在此发送 CONNECT,等下一轮 poll 处理
}
/* 收到数据 */
@@ -603,6 +594,12 @@ void iot_mqtt_poll(void) {
}
}
/* TCP 已连接 — 发送 MQTT CONNECT(延迟到 poll 而非中断内) */
if (g_iot_state == IOT_STATE_TCP_CONNECTED) {
iot_mqtt_send_connect();
g_iot_state = IOT_STATE_MQTT_CONNECTING;
}
/* MQTT Keepalive — PINGREQ */
if (g_iot_state == IOT_STATE_READY) {
uint32_t now = mstick();