[keep alive]wifi保活

保活机制(Keepalive) 用于维持设备与路由器(AP)的连接,防止因 闲置超时(Idle Timeout)、省电模式(Power Save) 或 信号波动 导致意外断开。

应用层保活

在这里插入图片描述

网络层保活

在这里插入图片描述

链路层保活

在这里插入图片描述

static IOT_State IOT_state = STATE_MQTT_CONNECT; // 当前状态初始化为STATE_INIT // 定义全局变量用于记录计数 volatile uint32_t keep_alive_counter = 0; // 定义是否需要发送消息的标志 volatile uint8_t need_keep_alive = 1; /* * 阿里云物联网平台连接管理函数 * 功能:实现WiFi连接、MQTT协议通信及消息处理 */ void Aliyun_Iot(char *redata) { char return_buff[RETURN_BUFF_SIZE]; char qos, dup, retain; // 解析 ReceivelPublish 参数 int id; // 每次进入状态机时递增计数器 if (need_keep_alive) { keep_alive_counter++; } switch (IOT_state) { case STATE_INIT: // 初始化状态 if (wifi_state == 0) // 如果WiFi未连接 { WIFI_Clean(); if (WIFI_Connect() == 0) // 尝试连接WiFi { WIFI_Clean(); Aliyun_Init(); // 处理三元组信息,得到连接参数 wifi_state = 1; IOT_state = STATE_MQTT_CONNECT; // 转到发送连接报文状态 } } // 重置计数器,因为在初始化阶段不发送消息 keep_alive_counter = 0; break; case STATE_MQTT_CONNECT: // 发送MQTT连接报文 MQTT_Connect(clientid, // clientid username, // username password, // password WILL_TOPIC, // will_topic WILL_MESSAGE, // will_message USER_NAME_FLAG, // user_name_flag PASS_WORD_FLAG, // pass_word_flag WILL_RETAIN, // will_retain WILL_QOS, // will_qos WILL_FLAG, // will_flag CLEAN_SESSION, // clean_session KEEP_ALIVE); // keep_alive IOT_state = STATE_WAIT_CONNACK; // 转到等待连接确认状态 // 重置计数器 keep_alive_counter = 0; break; case STATE_WAIT_CONNACK: // 等待连接确认 if (MQTT_ConnAck(redata) == 1) // 如果接收到连接确认 { IOT_state = STATE_SUBSCRIBE; // 转到订阅主题状态 } // 重置计数器 keep_alive_counter = 0; break; case STATE_SUBSCRIBE: // 订阅主题 MQTT_Subscribe(SET_TOPIC, SUBSCRIBE_ID, 0, 1); IOT_state = STATE_RECEIVE_MSG; // 转到消息接收状态 // 重置计数器 keep_alive_counter = 0; break; case STATE_RECEIVE_MSG: // 消息接收与处理 switch (redata[0] >> 4) // 首字节高4位表示报文类型 { case 3: // 接收PUBLISH消息 if (MQTT_ReceivelPublish(&dup, &qos, &retain, &id, redata, return_buff, RETURN_BUFF_SIZE) == 0) { printf("\r\n* 解析 0x%02x 报文: dup = %d, qos = %d, retain = %d, id = %02X *\r\n", redata[0], dup, qos, retain, id); Iot_Control(return_buff); // 调用 Iot_Control 控制硬件 if (qos == 1) { MQTT_SendPubAck(id); // QoS1需要回复PubAck } else if (qos == 2) { MQTT_SendPubRec(id); // QoS2需要回复PubRec } // 当接收到消息时,重置计数器并跳过下一次 keep_alive_counter = 0; need_keep_alive = 0; } break; case 4: // 接收PUBACK消息 id = MQTT_ReceivePubAck(redata); if (id != 0) { remove_from_retry_list(id); // 移除重传链表中的QoS1报文 } break; case 5: // 接收PUBREC消息 id = MQTT_ReceivePubRec(redata); if (id != 0) { remove_from_retry_list(id); // 移除重传链表中的QoS2报文 MQTT_SendPubRel(id); // 回复PUBREL } break; case 6: // 接收PUBREL消息 id = MQTT_ReceivePubRel(redata); if (id != 0) { MQTT_SendPubComp(id); // 回复PUBCOMP } break; case 7: // 接收PUBCOMP消息 id = MQTT_ReceivePubComp(redata); if (id != 0) { remove_from_retry_list(id); // 移除重传链表中的PUBREL报文 } break; case 9: // 接收SUBACK消息 if (MQTT_SubAck(redata) == 1) { IOT_state = STATE_KEEP_ALIVE; // 转到状态 } break; case 11: // 接收UNSUBACK消息 if (MQTT_UnSubAck(redata, SUBSCRIBE_ID) == 1) { printf("UNSUBACK received successfully.\n"); IOT_state = STATE_KEEP_ALIVE; // 转到状态 } else { printf("UNSUBACK failed. Retrying unsubscribe...\n"); MQTT_Subscribe(SET_TOPIC, SUBSCRIBE_ID, 0, 0); // 重新尝试取消订阅 } break; case 13: // 接收PINGRESP消息 if (MQTT_PingResp(redata) == 1) { // 当接收到PINGRESP时,重置计数器 keep_alive_counter = 0; need_keep_alive = 1; // 允许下一次 } break; default: break; } break; case STATE_KEEP_ALIVE: // 状态 // 在空闲时发送命令 if (keep_alive_counter >= PING_INTERVAL_TICKS && need_keep_alive) { MQTT_PingREQ(); // 发送PingReq消息 keep_alive_counter = 0; // 重置计数器 // 检查连续发送PingReq的次数 keep_alive_counter++; if (keep_alive_counter >= MAX_PING_FAILS * PING_INTERVAL_TICKS) { printf("Keep-alive failed! No response after %d attempts.\n", MAX_PING_FAILS); // 尝试重新连接MQTT服务器 MQTT_Connect(clientid, username, password, WILL_TOPIC, WILL_MESSAGE, USER_NAME_FLAG, PASS_WORD_FLAG, WILL_RETAIN, WILL_QOS, WILL_FLAG, CLEAN_SESSION, KEEP_ALIVE); if (MQTT_ConnAck(redata) == 1) // 重新连接到服务器 { printf("Server reconnected successfully.\n"); keep_alive_counter = 0; // 重置计数器 } else { // 如果无法连接到服务器,则尝试重新连接WiFi printf("Failed to reconnect to server. Attempting WiFi reconnection...\n"); WIFI_Clean(); // 清理WiFi连接 if (WIFI_Connect() == 0) // 重新连接WiFi { Aliyun_Init(); // 初始化阿里云连接参数 IOT_state = STATE_MQTT_CONNECT; // 返回MQTT连接状态 keep_alive_counter = 0; // 重置计数器 } else { // 如果WiFi连接失败,则返回初始化状态 printf("WiFi reconnection failed. Resetting state machine to initialization state.\n"); IOT_state = STATE_INIT; // 返回初始化状态 keep_alive_counter = 0; // 重置计数器 } } } } break; case STATE_DISCONNECT: // 断开连接 MQTT_DisConnect(); IOT_state = STATE_INIT; // 返回初始化状态 // 重置计数器 keep_alive_counter = 0; break; default: break; } }
最新发布
06-12
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值