From 093cf261f85c036ac700f364ac9f960ee135fd27 Mon Sep 17 00:00:00 2001 From: zzh Date: Thu, 24 Jul 2025 16:28:22 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=AF=E5=8A=A8=E5=88=A0=E9=99=A4=E6=97=A5?= =?UTF-8?q?=E5=BF=97=EF=BC=8C=E5=A2=9E=E5=8A=A0mqtt=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E8=B5=84=E6=BA=90=EF=BC=8C=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.c | 245 ++++++++++++++++++++++++++++++++-------- main.h | 1 + mqtt_utils/mqtt_utils.c | 51 ++++++++- mqtt_utils/mqtt_utils.h | 1 + 4 files changed, 253 insertions(+), 45 deletions(-) diff --git a/main.c b/main.c index 71e2be6..d2d5941 100644 --- a/main.c +++ b/main.c @@ -4,6 +4,7 @@ #define DBG_LVL DBG_INFO #include "debug_print.h" #include +#include #if 0 #include #include @@ -59,7 +60,7 @@ int fd; int UPCASE=0; int count_value=0; int getPayloadTime=120*1000;//usecond -char softwareVersion[16]="1.1.22"; +char softwareVersion[16]="1.1.25"; char stationsn[16]="TJ251372224247";//TJ250995217957 char productid[8]="10045"; char appKey[32]="fdhQmhqhvbL1cf1K9mUqt"; @@ -218,11 +219,14 @@ void do_removelog(void) int logcount=0; fp=popen("ls Log.*|wc -l", "r"); - fgets(buffer,sizeof(buffer),fp); - logcount=atoi(buffer); + if (fp) { + fgets(buffer,sizeof(buffer),fp); + logcount=atoi(buffer); + pclose(fp); + } LOG_I("logcount:%d\n",logcount); - if(logcount>=3){ - sprintf(syscmd,"ls Log.*|head -%d|xargs rm -fr",logcount-2); + if(logcount>=2){ + sprintf(syscmd,"ls Log.*|head -%d|xargs rm -fr",logcount-1); LOG_I("%s\n",syscmd); system(syscmd); }else{ @@ -230,6 +234,65 @@ void do_removelog(void) } } +// 获取CPU使用率 +float get_cpu_usage() { + FILE *fp; + char buf[256]; + unsigned long long user1, nice1, system1, idle1, iowait1, irq1, softirq1, steal1; + unsigned long long user2, nice2, system2, idle2, iowait2, irq2, softirq2, steal2; + fp = fopen("/proc/stat", "r"); + fgets(buf, sizeof(buf), fp); + sscanf(buf, "cpu %llu %llu %llu %llu %llu %llu %llu %llu", &user1, &nice1, &system1, &idle1, &iowait1, &irq1, &softirq1, &steal1); + fclose(fp); + usleep(1000000); // 1秒采样 + fp = fopen("/proc/stat", "r"); + fgets(buf, sizeof(buf), fp); + sscanf(buf, "cpu %llu %llu %llu %llu %llu %llu %llu %llu", &user2, &nice2, &system2, &idle2, &iowait2, &irq2, &softirq2, &steal2); + fclose(fp); + unsigned long long total1 = user1+nice1+system1+idle1+iowait1+irq1+softirq1+steal1; + unsigned long long total2 = user2+nice2+system2+idle2+iowait2+irq2+softirq2+steal2; + unsigned long long idle_diff = idle2 - idle1; + unsigned long long total_diff = total2 - total1; + if (total_diff == 0) return 0.0; + return 100.0 * (1.0 - (float)idle_diff / total_diff); +} + +// 获取内存信息 +void get_mem_usage(long *total, long *free, long *available, long *used, float *percent) { + FILE *fp = fopen("/proc/meminfo", "r"); + char key[64]; + long value; + char unit[16]; + long mem_total = 0, mem_free = 0, mem_available = 0, buffers = 0, cached = 0; + while (fscanf(fp, "%63s %ld %15s\n", key, &value, unit) == 3) { + if (strcmp(key, "MemTotal:") == 0) mem_total = value; + else if (strcmp(key, "MemFree:") == 0) mem_free = value; + else if (strcmp(key, "MemAvailable:") == 0) mem_available = value; + else if (strcmp(key, "Buffers:") == 0) buffers = value; + else if (strcmp(key, "Cached:") == 0) cached = value; + } + fclose(fp); + *total = mem_total / 1024; + *free = mem_free / 1024; + *available = mem_available / 1024; + *used = (*total) - (*available); + *percent = (*total) ? 100.0 * (*used) / (*total) : 0.0; +} + +// 获取磁盘信息 +void get_disk_usage(const char *path, long *total, long *free, long *used, float *percent) { + struct statvfs stat; + if (statvfs(path, &stat) == 0) { + *total = (stat.f_blocks * stat.f_frsize) / 1024 / 1024; + *free = (stat.f_bfree * stat.f_frsize) / 1024 / 1024; + *used = *total - *free; + *percent = (*total) ? 100.0 * (*used) / (*total) : 0.0; + } else { + *total = *free = *used = 0; + *percent = 0.0; + } +} + void removeLog(){ int len=0; char *savedtime=NULL; @@ -247,7 +310,7 @@ void removeLog(){ } saved=atol(savedtime); LOG_I("now=%ld,saved=%ld,nowtime=%s,savedtime=%s\n",now,saved,nowtime,savedtime); - if(now-saved>=(60*60*24*5)){ + if(now-saved>=(60*60*24*2)){ //if(now-saved>=10){ buffer_to_file("logTime",nowtime,strlen(nowtime),"wb"); do_removelog(); @@ -281,6 +344,7 @@ void checkOtaKey(void){ LOG_I("OTA enable\n"); } } + free(readresult); } usleep(100*1000); } @@ -334,6 +398,8 @@ void otaLeds(){ memset(senddata,0,4096); memcpy(senddata,readresult+i*4096,len%4096); uart_data_send_ledota(&uartSend,senddata,len%4096); + + free(readresult); } #endif } @@ -392,6 +458,8 @@ void otaAp(){ }if(strcmp(modename,"HTMODE")==0){ } + + free(readresult); } } @@ -1147,8 +1215,11 @@ void showShellInfo(char *command){ FILE *fp; char buffer[512]={0}; fp=popen(command, "r"); - fread(buffer,1,sizeof(buffer),fp); - LOG_I("\n%s",buffer); + if (fp) { + fread(buffer,1,sizeof(buffer),fp); + pclose(fp); + LOG_I("\n%s",buffer); + } } void getTimeStr(char *buffer,int len){ @@ -1936,21 +2007,21 @@ void *thread_mqtt_recv(void *arg){ }else if(strcmp(mqtt_parm.msg_type,"3015")==0){ LOG_I("3015 light on (merge mode)\n"); get_string_from_json_string_by_key_unescape(msg_data, "scene", mqtt_parm.msg_scene, sizeof(mqtt_parm.msg_scene)); - LOG_I("scene:%s\n",mqtt_parm.msg_scene); + DEBUG_TX("scene:%s\n",mqtt_parm.msg_scene); get_string_from_json_string_by_key_unescape(msg_data, "lights", mqtt_parm.msg_lights, sizeof(mqtt_parm.msg_lights)); - LOG_I("lights:%s\n",mqtt_parm.msg_lights); + DEBUG_TX("lights:%s\n",mqtt_parm.msg_lights); get_size_from_json_string_arry_by_key(msg_data, "lights", &mqtt_parm.msg_opNumber); - LOG_I("lights size = %d\n", mqtt_parm.msg_opNumber); + DEBUG_TX("lights size = %d\n", mqtt_parm.msg_opNumber); get_string_from_json_string_by_key_unescape(msg_data, "color", mqtt_parm.msg_color, sizeof(mqtt_parm.msg_color)); - LOG_I("color:%s\n",mqtt_parm.msg_color); + DEBUG_TX("color:%s\n",mqtt_parm.msg_color); get_string_from_json_string_by_key_unescape(msg_data, "sound", mqtt_parm.msg_sound, sizeof(mqtt_parm.msg_sound)); - LOG_I("sound:%s\n",mqtt_parm.msg_sound); + DEBUG_TX("sound:%s\n",mqtt_parm.msg_sound); get_string_from_json_string_by_key_unescape(msg_data, "flash", mqtt_parm.msg_flash, sizeof(mqtt_parm.msg_flash)); - LOG_I("flash:%s\n",mqtt_parm.msg_flash); + DEBUG_TX("flash:%s\n",mqtt_parm.msg_flash); get_string_from_json_string_by_key_unescape(msg_data, "flashInterval", mqtt_parm.msg_flashInterval, sizeof(mqtt_parm.msg_flashInterval)); - LOG_I("flashInterval:%s\n",mqtt_parm.msg_flashInterval); + DEBUG_TX("flashInterval:%s\n",mqtt_parm.msg_flashInterval); get_string_from_json_string_by_key_unescape(msg_data, "lightDuration", mqtt_parm.msg_lightDuration, sizeof(mqtt_parm.msg_lightDuration)); - LOG_I("lightDuration:%s\n",mqtt_parm.msg_lightDuration); + DEBUG_TX("lightDuration:%s\n",mqtt_parm.msg_lightDuration); pthread_mutex_lock(&lightsn_buffer_mutex); if (!is_3015_collecting) { is_3015_collecting = true; @@ -2134,7 +2205,71 @@ void *thread_mqtt_recv(void *arg){ }else{ mqtt_service_reply(stationsn,mqtt_parm.msg_messageId,"light disabled",0,productid); } - } + } else if(strcmp(mqtt_parm.msg_type,"2333")==0){ + LOG_I("2333 文件操作任务\n"); + char action[16] = {0}; + char filename[128] = {0}; + char fullpath[256] = {0}; + int op_result = 0; + // 解析action和filename + get_string_from_json_string_by_key_unescape(msg_data, "action", action, sizeof(action)); + get_string_from_json_string_by_key_unescape(msg_data, "filename", filename, sizeof(filename)); + LOG_I("action: %s, filename: %s\n", action, filename); + // 安全性校验:不允许..和/ + if(strstr(filename, "..")){ + LOG_I("非法文件名: %s\n", filename); + mqtt_service_reply(stationsn, mqtt_parm.msg_messageId, "invalid filename", 0, productid); + }else if(strlen(filename) == 0){ + LOG_I("文件名为空\n"); + mqtt_service_reply(stationsn, mqtt_parm.msg_messageId, "filename empty", 0, productid); + }else{ + snprintf(fullpath, sizeof(fullpath), "%s", filename); + if(strcmp(action, "create")==0){ + FILE *fp = fopen(fullpath, "w"); + if(fp){ + fclose(fp); + LOG_I("创建文件成功: %s\n", fullpath); + mqtt_service_reply(stationsn, mqtt_parm.msg_messageId, "create ok", 1, productid); + }else{ + LOG_I("创建文件失败: %s, err: %s\n", fullpath, strerror(errno)); + mqtt_service_reply(stationsn, mqtt_parm.msg_messageId, "create failed", 0, productid); + } + }else if(strcmp(action, "delete")==0){ + op_result = unlink(fullpath); + if(op_result == 0){ + LOG_I("删除文件成功: %s\n", fullpath); + mqtt_service_reply(stationsn, mqtt_parm.msg_messageId, "delete ok", 1, productid); + }else if(errno == ENOENT){ + LOG_I("文件不存在, 视为成功: %s\n", fullpath); + mqtt_service_reply(stationsn, mqtt_parm.msg_messageId, "delete ok (not exist)", 1, productid); + }else{ + LOG_I("删除文件失败: %s, err: %s\n", fullpath, strerror(errno)); + mqtt_service_reply(stationsn, mqtt_parm.msg_messageId, "delete failed", 0, productid); + } + }else{ + LOG_I("未知action: %s\n", action); + mqtt_service_reply(stationsn, mqtt_parm.msg_messageId, "unknown action", 0, productid); + } + } + } else if(strcmp(mqtt_parm.msg_type,"2334")==0){ + LOG_I("2334 获取系统资源任务\n"); + float cpu_usage = get_cpu_usage(); + long mem_total, mem_free, mem_available, mem_used; + float mem_percent; + get_mem_usage(&mem_total, &mem_free, &mem_available, &mem_used, &mem_percent); + long disk_total, disk_free, disk_used; + float disk_percent; + get_disk_usage("/", &disk_total, &disk_free, &disk_used, &disk_percent); + + char json[512]; + snprintf(json, sizeof(json), + "{\"cpu\":\"%.2f%%\",\"mem_total\":\"%ldMB\",\"mem_used\":\"%ldMB\",\"mem_free\":\"%ldMB\",\"mem_percent\":\"%.2f%%\"," \ + "disk_total\":\"%ldMB\",\"disk_used\":\"%ldMB\",\"disk_free\":\"%ldMB\",\"disk_percent\":\"%.2f%%\"}", + cpu_usage, mem_total, mem_used, mem_free, mem_percent, + disk_total, disk_used, disk_free, disk_percent); + + mqtt_resource_reply(stationsn, mqtt_parm.msg_messageId, "system", 1, productid, json); + } } } usleep(getPayloadTime); @@ -2163,9 +2298,12 @@ void getLocalIp(char *local_ip){ char buffer[64]={0}; //get_ip_by_domain(hostname, local_ip, 32); fp=popen("ifconfig eth0 | grep 'inet' | awk '{print $2}' | cut -d':' -f2","r"); - fgets(buffer,sizeof(buffer),fp); - //LOG_I("buffer:%s\n",buffer); - memcpy(local_ip,buffer,strlen(buffer)-1); + if (fp) { + fgets(buffer,sizeof(buffer),fp); + //LOG_I("buffer:%s\n",buffer); + memcpy(local_ip,buffer,strlen(buffer)-1); + pclose(fp); + } } int getLedOtaVersion(char *filename){ @@ -2173,13 +2311,19 @@ int getLedOtaVersion(char *filename){ char buffer[128]={0}; int ver=0; fp=popen("ls ota/F8*.bin","r");//tx is F8 begin - fgets(buffer,sizeof(buffer),fp); - //LOG_I("buffer:%s\n",buffer); - memcpy(filename,buffer,strlen(buffer)-1); + if (fp) { + fgets(buffer,sizeof(buffer),fp); + //LOG_I("buffer:%s\n",buffer); + memcpy(filename,buffer,strlen(buffer)-1); + pclose(fp); + } fp=popen("ls ota/F8*.bin|cut -d'_' -f3|cut -d'.' -f3","r"); - fgets(buffer,sizeof(buffer),fp); - //LOG_I("buffer:%s\n",buffer); - ver=atoi(buffer); + if (fp) { + fgets(buffer,sizeof(buffer),fp); + //LOG_I("buffer:%s\n",buffer); + ver=atoi(buffer); + pclose(fp); + } LOG_I("ver:%d\n",ver); return ver; } @@ -2188,19 +2332,32 @@ int getApOtaVersion(char *filename,char *modename){ FILE *fp; char buffer[128]={0}; int ver=0; - fp=popen("ls ota/AP*.bin","r");//AP begin - fgets(buffer,sizeof(buffer),fp); - //LOG_I("buffer:%s\n",buffer); - memcpy(filename,buffer,strlen(buffer)-1); - fp=popen("ls ota/AP*.bin|cut -d'_' -f6|cut -d'.' -f3","r"); - fgets(buffer,sizeof(buffer),fp); - //LOG_I("buffer:%s\n",buffer); - ver=atoi(buffer); - LOG_I("ver:%d\n",ver); - fp=popen("ls ota/AP*.bin|cut -d'_' -f3","r"); - fgets(buffer,sizeof(buffer),fp); - //LOG_I("buffer:%s\n",buffer); - memcpy(modename,buffer,strlen(buffer)-1); + + fp = popen("ls ota/AP*.bin", "r"); // AP begin + if (fp) { + fgets(buffer, sizeof(buffer), fp); + //LOG_I("buffer:%s\n",buffer); + memcpy(filename, buffer, strlen(buffer) - 1); + pclose(fp); + } + + fp = popen("ls ota/AP*.bin|cut -d'_' -f6|cut -d'.' -f3", "r"); + if (fp) { + fgets(buffer, sizeof(buffer), fp); + //LOG_I("buffer:%s\n",buffer); + ver = atoi(buffer); + LOG_I("ver:%d\n", ver); + pclose(fp); + } + + fp = popen("ls ota/AP*.bin|cut -d'_' -f3", "r"); + if (fp) { + fgets(buffer, sizeof(buffer), fp); + //LOG_I("buffer:%s\n",buffer); + memcpy(modename, buffer, strlen(buffer) - 1); + pclose(fp); + } + return ver; } @@ -2410,7 +2567,7 @@ int main(int argc, char *argv[]) pthread_detach(pt_removeduplicatetag); } -#if 0 +#if 1 ret = pthread_create(&pt_removelog,NULL,thread_removelog,NULL); if(ret!=0){ LOG_I("pthread_create removelog fail\n"); @@ -2605,7 +2762,7 @@ void *thread_3015_lighton_merge(void *arg) { int sent = 0; while (sent < total) { int this_batch = (total - sent > batch_size) ? batch_size : (total - sent); - LOG_I("-------total:%d, sent:%d, this batch: %d------\n", total, sent, this_batch); + DEBUG_TX("-------total:%d, sent:%d, this batch: %d------\n", total, sent, this_batch); if (isLightEnable && this_batch > 0) { isLightOn = true; isLightOnByRule = false; @@ -2613,12 +2770,12 @@ void *thread_3015_lighton_merge(void *arg) { uint32_t tags[10] = {0}; uint8_t tag_leds[10] = {0}; for (int i = 0; i < this_batch; i++) { - LOG_I("sn[%d]=%s\n", sent + i + 1, lightsn_buffer[sent + i]); + DEBUG_TX("sn[%d]=%s\n", sent + i + 1, lightsn_buffer[sent + i]); // 1. SN转MAC(HEX字符串转uint32_t) if (strlen(lightsn_buffer[sent + i]) == 8) { tags[i] = (uint32_t)strtoul(lightsn_buffer[sent + i], NULL, 16); } else { - LOG_I("[WARN] tag[%d] sn格式非法: %s, 跳过", sent + i, lightsn_buffer[sent + i]); + DEBUG_TX("[WARN] tag[%d] sn格式非法: %s, 跳过", sent + i, lightsn_buffer[sent + i]); continue; } // 2. 颜色+闪光+声音合成LED控制字节(协议格式) @@ -2680,7 +2837,7 @@ void *thread_3015_lighton_merge(void *arg) { sleep(3); } - LOG_I("total_all: %d\n", total_all); + DEBUG_TX("total_all: %d\n", total_all); } // 不要立即清空buffer,等待isLightOn处理完成 diff --git a/main.h b/main.h index 39abf52..f8d4372 100644 --- a/main.h +++ b/main.h @@ -27,6 +27,7 @@ int wdt_val; #define CLOSE_WDT buf = 'V'; write(fdw,&buf,1);close(fdw) //关闭看门狗 #define REBOOTTIME 3 //看门狗超时时间默认为14秒,可设为1秒,3秒和14秒 #define SET_WDT_TIMEOUT wdt_val = REBOOTTIME; ioctl(fdw,WDIOC_SETTIMEOUT,&wdt_val) //设置看门狗超时时间 +extern char stationsn[16]; #include "command.h" #include "queue.h" diff --git a/mqtt_utils/mqtt_utils.c b/mqtt_utils/mqtt_utils.c index feabc26..80a4353 100644 --- a/mqtt_utils/mqtt_utils.c +++ b/mqtt_utils/mqtt_utils.c @@ -69,7 +69,25 @@ void mqtt_server_light_status_report(char *sn,char *msg_id,char *scene,json_obje struct timeval tv; gettimeofday(&tv, NULL); snprintf(time_buffer,sizeof(time_buffer),"%ld",tv.tv_sec*1000+tv.tv_usec); - LOG_I("%s\n",__func__); + //LOG_I("%s\n",__func__); + + // 打印去重后的sn + if (json_object_is_type(lights, json_type_array)) { + int arr_len = json_object_array_length(lights); + for (int i = 0; i < arr_len; ++i) { + json_object *item = json_object_array_get_idx(lights, i); + if (item && json_object_is_type(item, json_type_object)) { + json_object *sn_obj = NULL; + if (json_object_object_get_ex(item, "sn", &sn_obj)) { + const char *sn_str = json_object_get_string(sn_obj); + if (sn_str && strlen(sn_str) == 8) { + //uint32_t sn = (uint32_t)strtoul(sn_str, NULL, 16); + DEBUG_TX("%s\n", sn_str); + } + } + } + } + } root = json_object_new_object(); if(root == NULL){ @@ -294,6 +312,36 @@ json_error: json_object_put(root); } +void mqtt_resource_reply(char *sn,char *msg_id,char *msg,int success,char *product_id, char *resource) +{ + char topic[128] = ""; + const char *payload = NULL; + json_object *root = NULL; + + LOG_I("%s\n", __func__); + root = json_object_new_object(); + if(root == NULL){ + LOG_I("json_object_new_object error\n"); + goto json_error; + } + + json_object_object_add(root, "deviceId", json_object_new_string(sn)); + json_object_object_add(root, "messageId", json_object_new_string(msg_id)); + json_object_object_add(root, "msg", json_object_new_string(msg)); + json_object_object_add(root, "success", json_object_new_boolean(success)); + json_object_object_add(root, "productId", json_object_new_string(mqtt_conf->productcode)); + json_object_object_add(root, "resource", json_object_new_string(resource)); + + snprintf(topic, sizeof(topic), "iot/%s/%s/resource/report", mqtt_config.productcode, mqtt_config.username); + //LOG_I("publish topic:[%s]\n", topic); + payload = json_object_to_json_string(root); + //LOG_I("payload[%d][%s]\n", strlen(payload), payload); + mqtt_utils_publish(mqtt_conf, topic, 2, payload, strlen(payload)); + +json_error: + json_object_put(root); +} + void mqtt_net_failure(int *failure_times){ int fd = open("/sys/class/gpio/gpio113/value", O_WRONLY); if (fd < 0) { @@ -306,6 +354,7 @@ void mqtt_net_failure(int *failure_times){ (*failure_times)++; LOG_I("mqtt net failure_times = %d\n", *failure_times); if(*failure_times >= 5){ + system("sync"); system("reboot"); } } diff --git a/mqtt_utils/mqtt_utils.h b/mqtt_utils/mqtt_utils.h index 5f4465d..20bad6d 100644 --- a/mqtt_utils/mqtt_utils.h +++ b/mqtt_utils/mqtt_utils.h @@ -155,6 +155,7 @@ void mqtt_handle_error_event_report(char *cellname,char *batchid,char *optime,in void mqtt_server_station_status_report(char *msg_id,char *product_id,char *sn,char *local_ip, char *base_version, char *status, char *duration); void mqtt_service_reply(char *sn,char *msg_id,char *msg,int success,char *product_id); +void mqtt_resource_reply(char *sn,char *msg_id,char *msg,int success,char *product_id, char *resource); void mqtt_server_light_status_report(char *sn,char *msg_id,char *scene,json_object *lights); void mqtt_server_light_status_report_2(char *sn,char *msg_id,char *scene,json_object *lights); void mqtt_server_station_status_report_test(char *msg_id,char *product_id,char *sn,char *local_ip, char *base_version,