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:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user