Compare commits
2 Commits
67e579ac27
...
fc95e3561a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fc95e3561a | ||
|
|
f910a4d701 |
119
main.c
119
main.c
@ -101,6 +101,16 @@ typedef struct {
|
|||||||
pending_light_task_t pendingLightTasks[MAX_PENDING_LIGHT_TASKS] = {0};
|
pending_light_task_t pendingLightTasks[MAX_PENDING_LIGHT_TASKS] = {0};
|
||||||
int pendingLightTaskCount = 0;
|
int pendingLightTaskCount = 0;
|
||||||
pthread_mutex_t lightTaskMutex = PTHREAD_MUTEX_INITIALIZER;
|
pthread_mutex_t lightTaskMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
// 按键防抖相关
|
||||||
|
#define MAX_KEY_DEBOUNCE 50
|
||||||
|
typedef struct {
|
||||||
|
uint32_t tagCode;
|
||||||
|
time_t lastKeyTime;
|
||||||
|
} key_debounce_t;
|
||||||
|
key_debounce_t keyDebounceList[MAX_KEY_DEBOUNCE] = {0};
|
||||||
|
int keyDebounceCount = 0;
|
||||||
|
pthread_mutex_t keyDebounceMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
pthread_t pt_heartbeat_check;
|
pthread_t pt_heartbeat_check;
|
||||||
pthread_t pt_light_off_check;
|
pthread_t pt_light_off_check;
|
||||||
int lightbars_size=0;
|
int lightbars_size=0;
|
||||||
@ -363,15 +373,15 @@ void report_light_off(uint32_t tagCode) {
|
|||||||
|
|
||||||
// 使用任务中的真实数据构建payload
|
// 使用任务中的真实数据构建payload
|
||||||
snprintf(payload, sizeof(payload),
|
snprintf(payload, sizeof(payload),
|
||||||
"{\"id\":\"%s\",\"version\":\"1.0\",\"arg\":{\"beep\":{\"value\":%d,\"time\":%lld},\"flash\":{\"value\":%d,\"time\":%lld},\"light\":{\"value\":{\"R\":%d,\"G\":%d,\"B\":%d},\"time\":%lld}},\"method\":\"thing.service.lightOperate.invoke\",\"time\":%lld}",
|
"{\"id\":\"%s\",\"version\":\"1.0\",\"arg\":{\"beep\":{\"value\":%d,\"time\":%lld},\"flash\":{\"value\":%d,\"time\":%lld},\"light\":{\"value\":{\"R\":%d,\"G\":%d,\"B\":%d},\"time\":%lld}},\"method\":\"thing.property.post\",\"time\":%lld}",
|
||||||
uuid_str,
|
uuid_str,
|
||||||
pendingLightTasks[i].beep,
|
0,
|
||||||
timestamp,
|
timestamp,
|
||||||
pendingLightTasks[i].flash,
|
0,
|
||||||
timestamp,
|
timestamp,
|
||||||
pendingLightTasks[i].light_r,
|
0,
|
||||||
pendingLightTasks[i].light_g,
|
0,
|
||||||
pendingLightTasks[i].light_b,
|
0,
|
||||||
timestamp,
|
timestamp,
|
||||||
timestamp);
|
timestamp);
|
||||||
|
|
||||||
@ -493,7 +503,8 @@ void *thread_heartbeat_check(void *arg) {
|
|||||||
pthread_mutex_lock(&heartbeatMutex);
|
pthread_mutex_lock(&heartbeatMutex);
|
||||||
|
|
||||||
for (int i = 0; i < lightbarHeartbeatCount; i++) {
|
for (int i = 0; i < lightbarHeartbeatCount; i++) {
|
||||||
if (lightbarHeartbeat[i].isOnline) {
|
// 只检查已经有过心跳记录的灯条(避免启动时误报)
|
||||||
|
if (lightbarHeartbeat[i].isOnline && lightbarHeartbeat[i].lastHeartbeat > 0) {
|
||||||
time_t elapsed = now - lightbarHeartbeat[i].lastHeartbeat;
|
time_t elapsed = now - lightbarHeartbeat[i].lastHeartbeat;
|
||||||
if (elapsed > HEARTBEAT_TIMEOUT_SEC) {
|
if (elapsed > HEARTBEAT_TIMEOUT_SEC) {
|
||||||
lightbarHeartbeat[i].isOnline = false;
|
lightbarHeartbeat[i].isOnline = false;
|
||||||
@ -1831,7 +1842,7 @@ void mqtt_init(){
|
|||||||
mqtt_config.tracelevel=MQTTASYNC_TRACE_PROTOCOL;
|
mqtt_config.tracelevel=MQTTASYNC_TRACE_PROTOCOL;
|
||||||
mqtt_config.retain=0;
|
mqtt_config.retain=0;
|
||||||
mqtt_config.port=mqtt_port;
|
mqtt_config.port=mqtt_port;
|
||||||
mqtt_config.keepalive=300;
|
mqtt_config.keepalive=180;
|
||||||
|
|
||||||
memset(mqtt_config.clientid,0,sizeof(mqtt_config.clientid));
|
memset(mqtt_config.clientid,0,sizeof(mqtt_config.clientid));
|
||||||
memcpy(mqtt_config.clientid, clientid, strlen(clientid)+1);
|
memcpy(mqtt_config.clientid, clientid, strlen(clientid)+1);
|
||||||
@ -2204,7 +2215,89 @@ void *thread_uart_recv_back(void *arg){
|
|||||||
//LOG_I("heart beat from lightbar %06X\n", tagCode);
|
//LOG_I("heart beat from lightbar %06X\n", tagCode);
|
||||||
update_lightbar_heartbeat(tagCode);
|
update_lightbar_heartbeat(tagCode);
|
||||||
}else if(tagFeature==0xFD){
|
}else if(tagFeature==0xFD){
|
||||||
LOG_I("key\n");
|
LOG_I("key pressed from tag %08X\n", tagCode);
|
||||||
|
|
||||||
|
// 按键防抖:2秒内只处理一次
|
||||||
|
time_t now = time(NULL);
|
||||||
|
pthread_mutex_lock(&keyDebounceMutex);
|
||||||
|
bool shouldProcess = true;
|
||||||
|
int debounceIndex = -1;
|
||||||
|
|
||||||
|
// 查找是否已有该tag的记录
|
||||||
|
for (int i = 0; i < keyDebounceCount; i++) {
|
||||||
|
if (keyDebounceList[i].tagCode == tagCode) {
|
||||||
|
debounceIndex = i;
|
||||||
|
if (now - keyDebounceList[i].lastKeyTime < 2) {
|
||||||
|
shouldProcess = false;
|
||||||
|
LOG_I("Key debounce: ignoring key press from tag %08X (within 2s)\n", tagCode);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新或添加记录
|
||||||
|
if (shouldProcess) {
|
||||||
|
if (debounceIndex >= 0) {
|
||||||
|
keyDebounceList[debounceIndex].lastKeyTime = now;
|
||||||
|
} else if (keyDebounceCount < MAX_KEY_DEBOUNCE) {
|
||||||
|
keyDebounceList[keyDebounceCount].tagCode = tagCode;
|
||||||
|
keyDebounceList[keyDebounceCount].lastKeyTime = now;
|
||||||
|
keyDebounceCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&keyDebounceMutex);
|
||||||
|
|
||||||
|
if (!shouldProcess) {
|
||||||
|
continue; // 跳过此次按键处理
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按键按下时立即上报灭灯
|
||||||
|
pthread_mutex_lock(&lightTaskMutex);
|
||||||
|
bool found = false;
|
||||||
|
for (int i = 0; i < pendingLightTaskCount; i++) {
|
||||||
|
if (pendingLightTasks[i].tagCode == tagCode &&
|
||||||
|
pendingLightTasks[i].reported &&
|
||||||
|
!pendingLightTasks[i].lightOffReported) {
|
||||||
|
LOG_I("Key pressed - triggering immediate light-off for tag %08X (with task)\n", tagCode);
|
||||||
|
report_light_off(tagCode);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 即使没有任务也要上报灭灯
|
||||||
|
if (!found) {
|
||||||
|
LOG_I("Key pressed - sending light-off for tag %08X (no task)\n", tagCode);
|
||||||
|
char topic[256] = {0};
|
||||||
|
char payload[1024] = {0};
|
||||||
|
char tagStr[16] = {0};
|
||||||
|
char uuid_str[37] = {0};
|
||||||
|
uuid_t uuid;
|
||||||
|
|
||||||
|
uuid_generate(uuid);
|
||||||
|
uuid_unparse(uuid, uuid_str);
|
||||||
|
|
||||||
|
snprintf(tagStr, sizeof(tagStr), "AD10%08X", tagCode);
|
||||||
|
snprintf(topic, sizeof(topic), "/sys/WcSubLightStrip/%s/thing/property/post", tagStr);
|
||||||
|
|
||||||
|
struct timeval tv;
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
long long timestamp = (long long)tv.tv_sec * 1000 + tv.tv_usec / 1000;
|
||||||
|
|
||||||
|
snprintf(payload, sizeof(payload),
|
||||||
|
"{\"id\":\"%s\",\"version\":\"1.0\",\"arg\":{\"beep\":{\"value\":0,\"time\":%lld},\"flash\":{\"value\":0,\"time\":%lld},\"light\":{\"value\":{\"R\":0,\"G\":0,\"B\":0},\"time\":%lld}},\"method\":\"thing.property.post\",\"time\":%lld}",
|
||||||
|
uuid_str,
|
||||||
|
timestamp,
|
||||||
|
timestamp,
|
||||||
|
timestamp,
|
||||||
|
timestamp);
|
||||||
|
|
||||||
|
LOG_I("Key light-off - topic: %s\n", topic);
|
||||||
|
LOG_I("Key light-off - payload: %s\n", payload);
|
||||||
|
|
||||||
|
mqtt_utils_publish(&mqtt_config, topic, 0, payload, strlen(payload));
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&lightTaskMutex);
|
||||||
}else if(tagFeature==0xFC){
|
}else if(tagFeature==0xFC){
|
||||||
LOG_I("broadcast parm\n");
|
LOG_I("broadcast parm\n");
|
||||||
}
|
}
|
||||||
@ -2521,6 +2614,10 @@ void *thread_mqtt_recv(void *arg){
|
|||||||
if(mqtt_parm.msg_duration <= 5) {
|
if(mqtt_parm.msg_duration <= 5) {
|
||||||
mqtt_parm.msg_duration = 5;
|
mqtt_parm.msg_duration = 5;
|
||||||
LOG_I("new msg_duration = %d\n", mqtt_parm.msg_duration);
|
LOG_I("new msg_duration = %d\n", mqtt_parm.msg_duration);
|
||||||
|
} else {
|
||||||
|
// 向上取整到5的倍数,避免硬件提前灭灯
|
||||||
|
mqtt_parm.msg_duration = ((mqtt_parm.msg_duration + 4) / 5) * 5;
|
||||||
|
LOG_I("Rounded up msg_duration = %d\n", mqtt_parm.msg_duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析颜色
|
// 解析颜色
|
||||||
@ -2554,6 +2651,10 @@ void *thread_mqtt_recv(void *arg){
|
|||||||
if(mqtt_parm.msg_duration <= 5) {
|
if(mqtt_parm.msg_duration <= 5) {
|
||||||
mqtt_parm.msg_duration = 5;
|
mqtt_parm.msg_duration = 5;
|
||||||
LOG_I("new msg_duration = %d\n", mqtt_parm.msg_duration);
|
LOG_I("new msg_duration = %d\n", mqtt_parm.msg_duration);
|
||||||
|
} else {
|
||||||
|
// 向上取整到5的倍数,避免硬件提前灭灯
|
||||||
|
mqtt_parm.msg_duration = ((mqtt_parm.msg_duration + 4) / 5) * 5;
|
||||||
|
LOG_I("Rounded up msg_duration = %d\n", mqtt_parm.msg_duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析颜色
|
// 解析颜色
|
||||||
|
|||||||
@ -2722,8 +2722,8 @@ static void setRetryLoopInterval(int keepalive)
|
|||||||
|
|
||||||
if (proposed < 1)
|
if (proposed < 1)
|
||||||
proposed = 1;
|
proposed = 1;
|
||||||
else if (proposed > 5)
|
else if (proposed > 60)
|
||||||
proposed = 5;
|
proposed = 60; // 提高上限到60秒,适应更长的keepalive
|
||||||
if (proposed < retryLoopInterval)
|
if (proposed < retryLoopInterval)
|
||||||
retryLoopInterval = proposed;
|
retryLoopInterval = proposed;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1323,8 +1323,8 @@ static void setRetryLoopInterval(int keepalive)
|
|||||||
|
|
||||||
if (proposed < 1)
|
if (proposed < 1)
|
||||||
proposed = 1;
|
proposed = 1;
|
||||||
else if (proposed > 5)
|
else if (proposed > 60)
|
||||||
proposed = 5;
|
proposed = 60; // 提高上限到60秒,适应更长的keepalive
|
||||||
if (proposed < retryLoopInterval)
|
if (proposed < retryLoopInterval)
|
||||||
retryLoopInterval = proposed;
|
retryLoopInterval = proposed;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -633,7 +633,7 @@ void MQTTProtocol_keepalive(time_t now)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//LOG_I("PINGREQ send success\n");
|
LOG_I("PINGREQ send success at %ld\n", (long)now);
|
||||||
client->net.lastSent = now;
|
client->net.lastSent = now;
|
||||||
client->ping_outstanding = 1;
|
client->ping_outstanding = 1;
|
||||||
}
|
}
|
||||||
@ -641,9 +641,25 @@ void MQTTProtocol_keepalive(time_t now)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log(TRACE_PROTOCOL, -1, "PINGRESP not received in keepalive interval for client %s on socket %d, disconnecting", client->clientID, client->net.socket);
|
// 增加容错:允许ping_outstanding为2时再等待一个周期
|
||||||
LOG_I("%s:PINGRESP not received\n",__func__);
|
if (client->ping_outstanding >= 2) {
|
||||||
MQTTProtocol_closeSession(client, 1);
|
Log(TRACE_PROTOCOL, -1, "PINGRESP not received after 2 keepalive intervals for client %s on socket %d, disconnecting", client->clientID, client->net.socket);
|
||||||
|
LOG_I("%s:PINGRESP not received after 2 attempts\n",__func__);
|
||||||
|
MQTTProtocol_closeSession(client, 1);
|
||||||
|
} else {
|
||||||
|
// 第二次发送PINGREQ
|
||||||
|
if (Socket_noPendingWrites(client->net.socket)) {
|
||||||
|
if (MQTTPacket_send_pingreq(&client->net, client->clientID) != TCPSOCKET_COMPLETE) {
|
||||||
|
Log(TRACE_PROTOCOL, -1, "Error sending second PINGREQ for client %s on socket %d, disconnecting", client->clientID, client->net.socket);
|
||||||
|
LOG_I("%s:Error sending second PINGREQ for client %s on socket %d, disconnecting\n",__func__,client->clientID, client->net.socket);
|
||||||
|
MQTTProtocol_closeSession(client, 1);
|
||||||
|
} else {
|
||||||
|
LOG_I("Second PINGREQ send success at %ld\n", (long)now);
|
||||||
|
client->net.lastSent = now;
|
||||||
|
client->ping_outstanding++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -178,7 +178,7 @@ int MQTTProtocol_handlePingresps(void* pack, int sock)
|
|||||||
client = (Clients*)(ListFindItem(bstate->clients, &sock, clientSocketCompare)->content);
|
client = (Clients*)(ListFindItem(bstate->clients, &sock, clientSocketCompare)->content);
|
||||||
Log(LOG_PROTOCOL, 21, NULL, sock, client->clientID);
|
Log(LOG_PROTOCOL, 21, NULL, sock, client->clientID);
|
||||||
client->ping_outstanding = 0;
|
client->ping_outstanding = 0;
|
||||||
//LOG_I("PINGRESP receive success\n");
|
LOG_I("PINGRESP received successfully, ping_outstanding cleared\n");
|
||||||
FUNC_EXIT_RC(rc);
|
FUNC_EXIT_RC(rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -419,6 +419,8 @@ void mqtt_utils_connected(void *context, char *cause){
|
|||||||
if (lightbarHeartbeat[i].isOnline) {
|
if (lightbarHeartbeat[i].isOnline) {
|
||||||
LOG_I("Report again lightbar %08X login\n", lightbarHeartbeat[i].tagCode);
|
LOG_I("Report again lightbar %08X login\n", lightbarHeartbeat[i].tagCode);
|
||||||
report_lightbar_login(lightbarHeartbeat[i].tagCode);
|
report_lightbar_login(lightbarHeartbeat[i].tagCode);
|
||||||
|
// 添加短暂延迟,避免MQTT缓冲区溢出
|
||||||
|
usleep(100 * 1000); // 100ms延迟
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&heartbeatMutex);
|
pthread_mutex_unlock(&heartbeatMutex);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user