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; return (ret == WCHNET_ERR_SUCCESS) ? 0 : -1;
} }
/* 发送 MQTT CONNECT */ /* 发送 MQTT CONNECT — 参考 net_srv.c mqtt_connect 实现 */
static int iot_mqtt_send_connect(void) { static int iot_mqtt_send_connect(void) {
static MQTTPacket_connectData opts; // static: 避免 85字节栈开销 static MQTTPacket_connectData opts; // static: 避免栈开销
static uint8_t buf[256]; // static: 避免 256字节栈开销 static uint8_t buf[256];
int len; int len;
// struct assignment 不支持 brace initializer,用临时变量中转 // 手动初始化(参考 net_srv.c 模式,不依赖 brace-initializer 赋值)
{ MQTTPacket_connectData _init = MQTTPacket_connectData_initializer; opts = _init; } memset(&opts, 0, sizeof(opts));
opts.struct_id[0] = 'M'; opts.struct_id[1] = 'Q';
opts.MQTTVersion = 4; // MQTT 3.1.1 opts.struct_id[2] = 'T'; opts.struct_id[3] = 'C';
opts.MQTTVersion = 4;
opts.keepAliveInterval = IOT_MQTT_KEEPALIVE_SEC; opts.keepAliveInterval = IOT_MQTT_KEEPALIVE_SEC;
opts.cleansession = 1; opts.cleansession = 1;
// clientID // clientID — 参考 net_srv.c 直接使用 g_dev_number_str
if (strlen((char *)iot_net_info.client_id) > 0) { opts.clientID.cstring = g_dev_number_str;
opts.clientID.cstring = (char *)iot_net_info.client_id;
} else {
opts.clientID.cstring = g_iot_dev_serial;
}
// username / password // username / password — 参考 net_srv.c 直接赋值
if (strlen((char *)iot_net_info.username) > 0) { opts.username.cstring = (char *)iot_net_info.username;
opts.username.cstring = (char *)iot_net_info.username; opts.password.cstring = (char *)iot_net_info.password;
}
if (strlen((char *)iot_net_info.password) > 0) {
opts.password.cstring = (char *)iot_net_info.password;
}
len = MQTTSerialize_connect(buf, sizeof(buf), &opts); len = MQTTSerialize_connect(buf, sizeof(buf), &opts);
if (len <= 0) { 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) { void iot_mqtt_handle_sock_int(uint8_t socketid, uint8_t intstat) {
if (socketid != g_iot_socket) return; if (socketid != g_iot_socket) return;
/* CONNECT 成功 */ /* CONNECT 成功 — 仅标记状态,由 poll 延迟发送 CONNECT */
if (intstat & SINT_STAT_CONNECT) { if (intstat & SINT_STAT_CONNECT) {
PRINT("IOT: TCP connected (sock=%d)\n", socketid); PRINT("IOT: TCP connected (sock=%d)\n", socketid);
WCHNET_ModifyRecvBuf(socketid, (uint32_t)_iot_wchnet_buf, RECE_BUF_LEN); WCHNET_ModifyRecvBuf(socketid, (uint32_t)_iot_wchnet_buf, RECE_BUF_LEN);
g_iot_state = IOT_STATE_TCP_CONNECTED; g_iot_state = IOT_STATE_TCP_CONNECTED;
_iot_recv_len = 0; _iot_recv_len = 0;
// 发送 MQTT CONNECT // 不在此发送 CONNECT,等下一轮 poll 处理
iot_mqtt_send_connect();
g_iot_state = IOT_STATE_MQTT_CONNECTING;
} }
/* 收到数据 */ /* 收到数据 */
@@ -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 */ /* MQTT Keepalive — PINGREQ */
if (g_iot_state == IOT_STATE_READY) { if (g_iot_state == IOT_STATE_READY) {
uint32_t now = mstick(); uint32_t now = mstick();