#include "main.h" #define PRINT_TIME_TAG #define DBG_TAG "main" #define DBG_LVL DBG_INFO #include "debug_print.h" #include #include #include "curl_arm64/include/curl.h" #include "redis_sn/redis_sn_client.h" #if 0 #include #include #include #define DMA_START_TX _IOW('U', 0x10, struct dma_config) struct dma_config { void *buf; size_t len; }; #endif pthread_t pt_uart_send; pthread_t pt_uart_recv_ack; pthread_t pt_uart_recv_data; pthread_t pt_uart_recv_back; pthread_t pt_vm_heartbeat; pthread_t pt_mqtt_recv; pthread_t pt_readqr; // 禁用二维码扫描线程 pthread_t pt_ota; pthread_t pt_doota; pthread_t pt_mqtt; pthread_t pt_removelog; pthread_t pt_reboot; pthread_t pt_watchdog; pthread_t pt_tagsearch; pthread_t pt_removeduplicatetag; uart_utils_t uartSend = {0}; uart_utils_t uartRecvData = {0}; uart_utils_t uartRecvBack = {0}; mqtt_parm_t mqtt_parm={0}; mqtt_utils_t mqtt_config; struct input_event buff; bool isTimeToReboot=false; bool isLightOn=false; bool isLightOnByRule=false; bool isLabelUp=false; bool isSearchLabel=false; bool isSearchReport=false; bool isSearchLabelOn=false; bool isSearchLabelOntest=false; bool isLightEnable=true; bool isSendComEnd=true; bool isOtaEnable=false; bool isLEDOtaSuccess=false; bool isAPOtaSuccess=false; bool isAPBack=false; jt_only_tag_t onlyTags[5000]={0}; jt_only_tag_t onlyTagsNew[5000]={0}; int tagCount=0; int tagCountNew=0; int tagIndex=0; int otaCount=0; int fd; int UPCASE=0; int count_value=0; int getPayloadTime=120*1000;//usecond char softwareVersion[16]="1.1.41"; char stationsn[16]="TJ251372224247";//TJ250995217957 char productid[8]="10045"; char appKey[32]="fdhQmhqhvbL1cf1K9mUqt"; char appSecret[64]="s3izIliw0CF48Pcsi16rjOmoFRf5WEt8"; char mqttRawPassword[64]=""; char input_value[1024]={0};//94b4e39caf1d45ee9a071d701cc037b4 char input_value_copy[1024]={0}; char *getDevRegisterStatusUrl="https://gaea-zt-express.com/device/modifyRegisterInfo"; //char *logUploadUrl="http://pda.pupumall.net:1180/open/api/device/log/upload"; char *getDevRawPasswordUrl="https://gaea.zt-express.com/device/modifyRegisterInfo"; char *hostDomain="tx-mqtt.zt-express.com"; char lightsn1[32]={0}; char lightsn2[32]={0}; char lightsn3[32]={0}; char lightsn4[32]={0}; char lightsn5[32]={0}; char lightsn6[32]={0}; char lightsn7[32]={0}; char lightsn8[32]={0}; char lightsn9[32]={0}; char lightsn10[32]={0}; char lightsn11[32]={0}; char lightsn12[32]={0}; char lightsn13[32]={0}; char lightsn14[32]={0}; char lightsn15[32]={0}; char lightsn16[32]={0}; char lightsn17[32]={0}; char lightsn18[32]={0}; char lightsn19[32]={0}; char lightsn20[32]={0}; char lightsn21[32]={0}; char lightsn22[32]={0}; char lightsn23[32]={0}; char lightsn24[32]={0}; char lightsn25[32]={0}; char lightsn26[32]={0}; char lightsn27[32]={0}; char lightsn28[32]={0}; char lightsn29[32]={0}; char lightsn30[32]={0}; int searchTimeOut=0; int searchTimeOld=0; int searchTimeNew=0; int lightsnNum=0; int mqtt_port=1883; uint32_t Tag1=0; uint32_t Tag2=0; uint32_t Tag3=0; uint32_t Tag4=0; uint32_t Tag5=0; static time_t last_2323_time = 0; // 记录上次收到0x2323的时间 static bool waiting_for_4646 = false; // 是否在等待0x4646 // ====== 3015合并点亮相关全局变量 ====== #define MAX_LIGHTSN_BUFFER 4096 static char lightsn_buffer[MAX_LIGHTSN_BUFFER][32] = {0}; static char color_buffer[MAX_LIGHTSN_BUFFER][8] = {0}; // 颜色缓冲区,与sn一一对应 static char sound_buffer[MAX_LIGHTSN_BUFFER][8] = {0}; // 声音缓冲区 static char flash_buffer[MAX_LIGHTSN_BUFFER][8] = {0}; // 闪光缓冲区 static int lightsn_buffer_count = 0; static time_t first_3015_time = 0; static bool is_3015_collecting = false; static pthread_mutex_t lightsn_buffer_mutex = PTHREAD_MUTEX_INITIALIZER; // 3022合包缓存定义(放在文件顶部或main函数外部) #define LABEL_BATCH_SIZE 20 static uint32_t tags_buf[LABEL_BATCH_SIZE] = {0}; static uint8_t lable1_buf[LABEL_BATCH_SIZE] = {0}; static uint16_t lable2_buf[LABEL_BATCH_SIZE] = {0}; static uint32_t lable3_buf[LABEL_BATCH_SIZE] = {0}; static int label_buf_count = 0; static time_t label_buf_first_time = 0; // 函数声明 void *thread_timeout_check(void *arg); void *thread_3015_lighton_merge(void *arg); void *thread_label_batch_send(void *arg); int getLedOtaVersion(char *filename); int getApOtaVersion(char *filename,char *modename); void hmacsha1(char *key,char* data,char *signbase64,int signbase64_len); void light_off_tag_report(uint32_t name,uint16_t batteryv); void light_battery_report(uint32_t tagCode, uint16_t batteryV); void search_tag_report(); void copyOnlyTag(void); // 安全的命令执行函数 static int safe_exec_cmd(const char *cmd) { LOG_I("Executing command: %s\n", cmd); int ret = system(cmd); if (ret != 0) { LOG_E("Command failed: %s, return code: %d, error: %s", cmd, ret, strerror(errno)); // 如果是init.d脚本失败,记录更多信息 if (strstr(cmd, "/etc/init.d/tx_server") != NULL) { FILE *log_file = fopen("/var/log/tx_server_restart.log", "a"); if (log_file != NULL) { time_t now = time(NULL); struct tm *tm_info = localtime(&now); char time_str[26]; strftime(time_str, 26, "%Y-%m-%d %H:%M:%S", tm_info); fprintf(log_file, "[%s] DEBUG: Command that failed: %s\n", time_str, cmd); fprintf(log_file, "[%s] DEBUG: Return code: %d\n", time_str, ret); fprintf(log_file, "[%s] DEBUG: errno: %d (%s)\n", time_str, errno, strerror(errno)); // 检查脚本是否存在且可执行 if (access("/etc/init.d/tx_server", F_OK) == 0) { fprintf(log_file, "[%s] DEBUG: Script exists\n", time_str); if (access("/etc/init.d/tx_server", X_OK) == 0) { fprintf(log_file, "[%s] DEBUG: Script is executable\n", time_str); } else { fprintf(log_file, "[%s] DEBUG: Script is NOT executable\n", time_str); } } else { fprintf(log_file, "[%s] DEBUG: Script does NOT exist\n", time_str); } fclose(log_file); } } return -1; } LOG_I("Command succeeded: %s\n", cmd); return 0; } // 兼容的服务重启函数,支持systemctl和init.d两种方式 int restart_tx_server_service(void) { // 首先尝试使用systemctl方式 if (access("/bin/systemctl", F_OK) == 0) { LOG_I("Using systemctl to restart tx_server service\n"); int ret = safe_exec_cmd("systemctl restart tx_server"); if (ret == 0) { LOG_I("Successfully restarted tx_server using systemctl\n"); return 0; } else { LOG_W("systemctl restart failed, trying init.d method\n"); } } // 如果systemctl不可用或失败,尝试使用init.d方式 if (access("/etc/init.d/tx_server", F_OK) == 0) { LOG_I("Using init.d script to restart tx_server service\n"); // 详细诊断信息 FILE *log_file = fopen("/var/log/tx_server_restart.log", "a"); if (log_file != NULL) { time_t now = time(NULL); struct tm *tm_info = localtime(&now); char time_str[26]; strftime(time_str, 26, "%Y-%m-%d %H:%M:%S", tm_info); // 记录执行前的系统状态 fprintf(log_file, "[%s] INFO: Starting tx_server restart process\n", time_str); fprintf(log_file, "[%s] INFO: Current UID: %d, GID: %d\n", time_str, getuid(), getgid()); // 检查脚本权限 struct stat st; if (stat("/etc/init.d/tx_server", &st) == 0) { fprintf(log_file, "[%s] INFO: Script permissions: %o\n", time_str, st.st_mode & 0777); fprintf(log_file, "[%s] INFO: Script owner: %d, group: %d\n", time_str, st.st_uid, st.st_gid); } // 检查当前进程状态 fprintf(log_file, "[%s] INFO: Current working directory: ", time_str); char cwd[256]; if (getcwd(cwd, sizeof(cwd)) != NULL) { fprintf(log_file, "%s\n", cwd); } else { fprintf(log_file, "unknown\n"); } // 检查环境变量 fprintf(log_file, "[%s] INFO: PATH=%s\n", time_str, getenv("PATH") ? getenv("PATH") : "not set"); fclose(log_file); } system("echo 0 > /sys/class/gpio/gpio1/value"); int ret = safe_exec_cmd("/etc/init.d/tx_server restart"); log_file = fopen("/var/log/tx_server_restart.log", "a"); if (log_file != NULL) { time_t now = time(NULL); struct tm *tm_info = localtime(&now); char time_str[26]; strftime(time_str, 26, "%Y-%m-%d %H:%M:%S", tm_info); if (ret == 0) { fprintf(log_file, "[%s] SUCCESS: tx_server restarted successfully using init.d\n", time_str); LOG_I("Successfully restarted tx_server using init.d\n"); } else { fprintf(log_file, "[%s] FAILED: tx_server restart failed using init.d (return code: %d)\n", time_str, ret); fprintf(log_file, "[%s] ERROR: errno=%d, error=%s\n", time_str, errno, strerror(errno)); LOG_E("init.d restart also failed\n"); // 尝试获取更多错误信息 FILE *cmd_output = popen("/etc/init.d/tx_server restart 2>&1", "r"); if (cmd_output != NULL) { char buffer[1024]; fprintf(log_file, "[%s] DEBUG: Command output:\n", time_str); while (fgets(buffer, sizeof(buffer), cmd_output) != NULL) { fprintf(log_file, "[%s] DEBUG: %s", time_str, buffer); } pclose(cmd_output); } } fclose(log_file); } if (ret == 0) { return 0; } } else { LOG_E("Neither systemctl nor init.d script found for tx_server\n"); } LOG_E("All service restart methods failed\n"); return -1; } /*================================================================================*/ void doCommand_help(int argc, char *argv[]) { printf("************************************************************\r\n"\ "all commands are case insensitive\r\n"\ "help print this message\r\n"\ "SND [01-60] set sound S01-S60\r\n"\ "************************************************************\r\n"); } static int safe_rename(const char *src, const char *dst) { if (rename(src, dst) != 0) { LOG_E("Failed to rename %s to %s: %s", src, dst, strerror(errno)); return -1; } return 0; } static int safe_remove_dir(const char *path) { if (rmdir(path) != 0) { LOG_E("Failed to remove directory %s: %s", path, strerror(errno)); return -1; } return 0; } static int safe_remove_file(const char *path) { if (unlink(path) != 0) { LOG_E("Failed to remove file %s: %s", path, strerror(errno)); return -1; } return 0; } static int safe_mkdir(const char *path) { if (mkdir(path, 0755) != 0 && errno != EEXIST) { LOG_E("Failed to create directory %s: %s", path, strerror(errno)); return -1; } return 0; } void doCommand(int argc, char *argv[]) { //sendData(argv[1],argv[0]); } __command_initialize("RON", doCommand); __command_initialize("help",doCommand_help); /*================================================================================*/ void do_removelog(void) { LOG_I("%s\n",__func__); FILE *fp; char buffer[5]; char syscmd[32]; int logcount=0; fp=popen("ls Log.*|wc -l", "r"); if (fp) { fgets(buffer,sizeof(buffer),fp); logcount=atoi(buffer); pclose(fp); } LOG_I("logcount:%d\n",logcount); if(logcount>=2){ sprintf(syscmd,"ls Log.*|head -%d|xargs rm -fr",logcount-1); LOG_I("%s\n",syscmd); system(syscmd); }else{ LOG_I("logcount less than 3,not remove\n"); } } // 获取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; char nowtime[16]={0}; long now=0; long saved=0; while(1){ now=getCurrentTime(); sprintf(nowtime,"%ld",now); savedtime=file_to_buffer("logTime",&len); if(savedtime==NULL){ buffer_to_file("logTime",nowtime,strlen(nowtime),"wb"); savedtime=file_to_buffer("logTime",&len); } saved=atol(savedtime); LOG_I("now=%ld,saved=%ld,nowtime=%s,savedtime=%s\n",now,saved,nowtime,savedtime); if(now-saved>=(60*60*24*2)){ //if(now-saved>=10){ buffer_to_file("logTime",nowtime,strlen(nowtime),"wb"); do_removelog(); } sleep(60*60*1); } } void checkOtaKey(void){ int len=0; int keycount=0; char *readresult=NULL; while(1){ if(isOtaEnable){ system("echo 0 > /sys/class/gpio/gpio113/value"); sleep(1); system("echo 1 > /sys/class/gpio/gpio113/value"); sleep(1); }else{ readresult=file_to_buffer("/sys/class/gpio/gpio63/value",&len); //LOG_I("resetKey:%s\n",readresult); if(readresult!=NULL){ if(strcmp(readresult,"0\n")==0){ keycount++; if(keycount==3){ keycount=0; isOtaEnable=true; isLEDOtaSuccess=false; isAPOtaSuccess=false; isSendComEnd=true; LOG_I("OTA enable\n"); } } free(readresult); } usleep(100*1000); } } } void otaLeds(){ #if 0 int len=0,ver=0; char *readresult=NULL; char filename[128]={}; uint16_t data_crc=0; ver=getLedOtaVersion(filename); LOG_I("ota %s ver:%d\n",filename,ver); readresult=file_to_buffer(filename,&len); if(readresult!=NULL){ isSendComEnd=false; LOG_I("data len:%d\n",len); data_crc=CRC16_XMODEM(readresult,len); LOG_I("crc :%04x\n",data_crc); uart_data_send_head_ledota(&uartSend,len,data_crc,ver);//0xFF降级 usleep(72*1000); int i=0; for(i=0;itm_hour==0 && result->tm_min==0 && result->tm_sec==10){ isTimeToReboot=true; LOG_I("prepare to reboot\n"); } } sleep(1); } system("sync"); sleep(10); system("sync"); system("reboot"); } int readQrcode() { fd = open("/dev/input/event2", O_RDONLY); if (fd < 0) { LOG_I("can not open scanner input event2!\n"); goto error; } while (1) { while (read(fd, &buff, sizeof(struct input_event)) == 0) { ; } if (buff.type == EV_KEY){ if(buff.value==0){ #if 0 LOG_I("type:%d code:%d value:%d\n", buff.type, buff.code, buff.value); #else switch(buff.code){ case 2: if(UPCASE==1){ input_value[count_value]='!'; }else{ input_value[count_value]='1'; } UPCASE=0; count_value++; break; case 3: if(UPCASE==1){ input_value[count_value]='@'; }else{ input_value[count_value]='2'; } UPCASE=0; count_value++; break; case 4: if(UPCASE==1){ input_value[count_value]='#'; }else{ input_value[count_value]='3'; } UPCASE=0; count_value++; break; case 5: if(UPCASE==1){ input_value[count_value]='$'; }else{ input_value[count_value]='4'; } UPCASE=0; count_value++; break; case 6: if(UPCASE==1){ input_value[count_value]='%'; }else{ input_value[count_value]='5'; } UPCASE=0; count_value++; break; case 7: if(UPCASE==1){ input_value[count_value]='^'; }else{ input_value[count_value]='6'; } UPCASE=0; count_value++; break; case 8: if(UPCASE==1){ input_value[count_value]='&'; }else{ input_value[count_value]='7'; } UPCASE=0; count_value++; break; case 9: if(UPCASE==1){ input_value[count_value]='*'; }else{ input_value[count_value]='8'; } UPCASE=0; count_value++; break; case 10: if(UPCASE==1){ input_value[count_value]='('; }else{ input_value[count_value]='9'; } UPCASE=0; count_value++; break; case 11: if(UPCASE==1){ input_value[count_value]=')'; }else{ input_value[count_value]='0'; } UPCASE=0; count_value++; break; case 12: if(UPCASE==1){ input_value[count_value]='_'; }else{ input_value[count_value]='-'; } UPCASE=0; count_value++; break; case 13: if(UPCASE==1){ input_value[count_value]='+'; }else{ input_value[count_value]='='; } UPCASE=0; count_value++; break; case 16: if(UPCASE==1){ input_value[count_value]='Q'; }else{ input_value[count_value]='q'; } UPCASE=0; count_value++; break; case 17: if(UPCASE==1){ input_value[count_value]='W'; }else{ input_value[count_value]='w'; } UPCASE=0; count_value++; break; case 18: if(UPCASE==1){ input_value[count_value]='E'; }else{ input_value[count_value]='e'; } UPCASE=0; count_value++; break; case 19: if(UPCASE==1){ input_value[count_value]='R'; }else{ input_value[count_value]='r'; } UPCASE=0; count_value++; break; case 20: if(UPCASE==1){ input_value[count_value]='T'; }else{ input_value[count_value]='T'; } UPCASE=0; count_value++; break; case 21: if(UPCASE==1){ input_value[count_value]='Y'; }else{ input_value[count_value]='y'; } UPCASE=0; count_value++; break; case 22: if(UPCASE==1){ input_value[count_value]='U'; }else{ input_value[count_value]='u'; } UPCASE=0; count_value++; break; case 23: if(UPCASE==1){ input_value[count_value]='I'; }else{ input_value[count_value]='i'; } UPCASE=0; count_value++; break; case 24: if(UPCASE==1){ input_value[count_value]='O'; }else{ input_value[count_value]='o'; } UPCASE=0; count_value++; break; case 25: if(UPCASE==1){ input_value[count_value]='P'; }else{ input_value[count_value]='p'; } UPCASE=0; count_value++; break; case 26: if(UPCASE==1){ input_value[count_value]='{'; }else{ input_value[count_value]='['; } UPCASE=0; count_value++; break; case 27: if(UPCASE==1){ input_value[count_value]='}'; }else{ input_value[count_value]=']'; } UPCASE=0; count_value++; break; case 28: input_value[count_value]='\0'; //LOG_I("%s\n",input_value); memset(input_value_copy,0,1024); memcpy(input_value_copy,input_value,1024); memset(input_value,0,1024); count_value=0; int ret=-1; pthread_t pt_handleqrcode; ret = pthread_create(&pt_handleqrcode,NULL,actHandleQrcode,input_value_copy); if(ret!=0){ LOG_I("pthread_create handleqrcode fail\n"); }else{ pthread_detach(pt_handleqrcode); } break; case 30: if(UPCASE==1){ input_value[count_value]='A'; }else{ input_value[count_value]='a'; } UPCASE=0; count_value++; break; case 31: if(UPCASE==1){ input_value[count_value]='S'; }else{ input_value[count_value]='s'; } UPCASE=0; count_value++; break; case 32: if(UPCASE==1){ input_value[count_value]='D'; }else{ input_value[count_value]='d'; } UPCASE=0; count_value++; break; case 33: if(UPCASE==1){ input_value[count_value]='F'; }else{ input_value[count_value]='f'; } UPCASE=0; count_value++; break; case 34: if(UPCASE==1){ input_value[count_value]='G'; }else{ input_value[count_value]='g'; } UPCASE=0; count_value++; break; case 35: if(UPCASE==1){ input_value[count_value]='H'; }else{ input_value[count_value]='h'; } UPCASE=0; count_value++; break; case 36: if(UPCASE==1){ input_value[count_value]='J'; }else{ input_value[count_value]='j'; } UPCASE=0; count_value++; break; case 37: if(UPCASE==1){ input_value[count_value]='K'; }else{ input_value[count_value]='k'; } UPCASE=0; count_value++; break; case 38: if(UPCASE==1){ input_value[count_value]='L'; }else{ input_value[count_value]='l'; } UPCASE=0; count_value++; break; case 39: if(UPCASE==1){ input_value[count_value]=':'; }else{ input_value[count_value]=';'; } UPCASE=0; count_value++; break; case 40: if(UPCASE==1){ input_value[count_value]='"'; }else{ input_value[count_value]='\''; } UPCASE=0; count_value++; break; case 42: UPCASE=1; break; case 43: if(UPCASE==1){ input_value[count_value]='|'; }else{ input_value[count_value]='\\'; } UPCASE=0; count_value++; break; case 44: if(UPCASE==1){ input_value[count_value]='Z'; }else{ input_value[count_value]='z'; } UPCASE=0; count_value++; break; case 45: if(UPCASE==1){ input_value[count_value]='X'; }else{ input_value[count_value]='x'; } UPCASE=0; count_value++; break; case 46: if(UPCASE==1){ input_value[count_value]='C'; }else{ input_value[count_value]='c'; } UPCASE=0; count_value++; break; case 47: if(UPCASE==1){ input_value[count_value]='V'; }else{ input_value[count_value]='v'; } UPCASE=0; count_value++; break; case 48: if(UPCASE==1){ input_value[count_value]='B'; }else{ input_value[count_value]='b'; } UPCASE=0; count_value++; break; case 49: if(UPCASE==1){ input_value[count_value]='N'; }else{ input_value[count_value]='n'; } UPCASE=0; count_value++; break; case 50: if(UPCASE==1){ input_value[count_value]='M'; }else{ input_value[count_value]='m'; } UPCASE=0; count_value++; break; case 51: if(UPCASE==1){ input_value[count_value]='<'; }else{ input_value[count_value]=','; } UPCASE=0; count_value++; break; case 52: if(UPCASE==1){ input_value[count_value]='>'; }else{ input_value[count_value]='.'; } UPCASE=0; count_value++; break; case 53: if(UPCASE==1){ input_value[count_value]='?'; }else{ input_value[count_value]='/'; } UPCASE=0; count_value++; break; } #endif } } } close(fd); return 0; error: return 1; } #if 0 void writeWpa(char *filename,char *ssid,char *psw){ LOG_I("%s\n",__func__); buffer_to_file(filename,"# WPA-PSK/TKIP\n",strlen("# WPA-PSK/TKIP\n"),"wb"); buffer_to_file(filename,"ap_scan=1\n",strlen("ap_scan=1\n"),"a"); buffer_to_file(filename,"ctrl_interface=/var/run/wpa_supplicant\n",strlen("ctrl_interface=/var/run/wpa_supplicant\n"),"a"); buffer_to_file(filename,"network={\n",strlen("network={\n"),"a"); buffer_to_file(filename,"ssid=\"",strlen("ssid=\""),"a"); buffer_to_file(filename,ssid,strlen(ssid),"a"); buffer_to_file(filename,"\"",strlen("\""),"a"); buffer_to_file(filename,"\n",strlen("\n"),"a"); buffer_to_file(filename,"key_mgmt=WPA-PSK\n",strlen("key_mgmt=WPA-PSK\n"),"a"); buffer_to_file(filename,"proto=WPA RSN\n",strlen("proto=WPA RSN\n"),"a"); buffer_to_file(filename,"pairwise=CCMP TKIP\n",strlen("pairwise=CCMP TKIP\n"),"a"); buffer_to_file(filename,"group=CCMP TKIP\n",strlen("group=CCMP TKIP\n"),"a"); buffer_to_file(filename,"psk=\"",strlen("psk=\""),"a"); buffer_to_file(filename,psw,strlen(psw),"a"); buffer_to_file(filename,"\"",strlen("\""),"a"); buffer_to_file(filename,"\n",strlen("\n"),"a"); buffer_to_file(filename,"}\n",strlen("}\n"),"a"); buffer_to_file(filename,"\n",strlen("\n"),"a"); } void writeWlan(char *filename,char *netway,char *gate,char *ip){ LOG_I("%s\n",__func__); buffer_to_file(filename,"METHOD=",strlen("METHOD="),"wb"); buffer_to_file(filename,netway,strlen(netway),"a"); buffer_to_file(filename,"\n",strlen("\n"),"a"); if(strcmp(netway,"STATIC")==0){ buffer_to_file(filename,"IPADDR=",strlen("IPADDR="),"a"); buffer_to_file(filename,ip,strlen(ip),"a"); buffer_to_file(filename,"\n",strlen("\n"),"a"); buffer_to_file(filename,"NETMASK=255.255.255.0\n",strlen("NETMASK=255.255.255.0\n"),"a"); buffer_to_file(filename,"GATEWAY=",strlen("GATEWAY="),"a"); buffer_to_file(filename,gate,strlen(gate),"a"); buffer_to_file(filename,"\n",strlen("\n"),"a"); } } #endif void writeNetworkInterface(char *filename,char *dest){ buffer_to_file(filename,"# interfaces(5) file used by ifup(8) and ifdown(8)", strlen("# interfaces(5) file used by ifup(8) and ifdown(8)"),"wb"); buffer_to_file(filename,"\n",strlen("\n"),"a"); buffer_to_file(filename,"# Include files from /etc/network/interfaces.d:",strlen("# Include files from /etc/network/interfaces.d:"),"a"); buffer_to_file(filename,"\n",strlen("\n"),"a"); buffer_to_file(filename,"source-directory /etc/network/interfaces.d",strlen("source-directory /etc/network/interfaces.d"),"a"); buffer_to_file(filename,"\n",strlen("\n"),"a"); buffer_to_file(filename,"auto lo",strlen("auto lo"),"a"); buffer_to_file(filename,"\n",strlen("\n"),"a"); buffer_to_file(filename,"iface lo inet loopback",strlen("iface lo inet loopback"),"a"); buffer_to_file(filename,"\n",strlen("\n"),"a"); buffer_to_file(filename,"auto eth0",strlen("auto eth0"),"a"); buffer_to_file(filename,"\n",strlen("\n"),"a"); buffer_to_file(filename,"iface eth0 inet dhcp",strlen("iface eth0 inet dhcp"),"a"); buffer_to_file(filename,"\n",strlen("\n"),"a"); buffer_to_file(filename,"# address 192.168.1.100",strlen("# address 192.168.1.100"),"a"); buffer_to_file(filename,"\n",strlen("\n"),"a"); buffer_to_file(filename,"# netmask 255.255.255.0",strlen("# netmask 255.255.255.0"),"a"); buffer_to_file(filename,"\n",strlen("\n"),"a"); buffer_to_file(filename,"# gateway 192.168.1.1",strlen("# gateway 192.168.1.1"),"a"); buffer_to_file(filename,"\n",strlen("\n"),"a"); buffer_to_file(filename,"hwaddress ether ",strlen("hwaddress ether "),"a"); buffer_to_file(filename,dest,strlen(dest),"a"); system("sync"); } char* insert_colon(const char* src, int interval) { if (!src || interval <= 0) return NULL; size_t len = strlen(src); if (len == 0) { // 空字符串返回空 char* res = malloc(1); if (res) res[0] = '\0'; return res; } // 计算新字符串长度 size_t sections = (len + interval - 1) / interval; // 总段数 size_t new_len = len + (sections - 1); // 新长度 = 原长 + 冒号数 char* new_str = malloc(new_len + 1); // 分配内存:ml-citation{ref="2" data="citationList"} if (!new_str) return NULL; size_t src_idx = 0, dst_idx = 0; while (src_idx < len) { // 计算本次复制的字符数 size_t copy_size = (len - src_idx < (size_t)interval) ? (len - src_idx) : (size_t)interval; memcpy(new_str + dst_idx, src + src_idx, copy_size); // 块复制:ml-citation{ref="3" data="citationList"} src_idx += copy_size; dst_idx += copy_size; // 非末尾段时插入冒号 if (src_idx < len) new_str[dst_idx++] = ':'; } new_str[dst_idx] = '\0'; // 终止符:ml-citation{ref="7" data="citationList"} return new_str; } void *actHandleQrcode(void *parm){ char *str=(char *)parm; LOG_I("scan:%s\n",str); // 检查是否为T或D开头的生产批次号码 if((str[0] == 'T' || str[0] == 'D') && strlen(str) > 1) { LOG_I("检测到生产批次号码: %s\n", str); char sn_buffer[64] = {0}; char mac_buffer[32] = {0}; // 从Redis中根据批次号码查找对应的SN和MAC int result = get_sn_mac_by_batch_number(str, sn_buffer, sizeof(sn_buffer), mac_buffer, sizeof(mac_buffer)); if(result == 0) { // 成功获取到SN和MAC,保存到文件 LOG_I("根据批次号码获取到SN: %s, MAC: %s\n", sn_buffer, mac_buffer); // 保存SN到文件 buffer_to_file("savedDevSn", sn_buffer, strlen(sn_buffer), "wb"); LOG_I("已保存SN到文件: %s\n", sn_buffer); // 保存原始MAC到文件 buffer_to_file("savedDevMac", mac_buffer, strlen(mac_buffer), "wb"); LOG_I("已保存MAC到文件: %s\n", mac_buffer); // 格式化MAC地址并更新网络接口配置 char* formatted_mac = insert_colon(mac_buffer, 2); if(formatted_mac != NULL) { LOG_I("格式化后的MAC: %s\n", formatted_mac); writeNetworkInterface("/etc/network/interfaces", formatted_mac); writeNetworkInterface("/etc/network/interfaces.default", formatted_mac); free(formatted_mac); } // 更新全局变量stationsn if(strlen(sn_buffer) < sizeof(stationsn)) { strcpy(stationsn, sn_buffer); LOG_I("已更新全局stationsn: %s\n", stationsn); } // 发送审计记录到Redis if(send_audit_to_redis(str, mac_buffer, sn_buffer) == 0) { LOG_I("审计记录已发送到Redis: batch=%s, mac=%s, sn=%s\n", str, mac_buffer, sn_buffer); } else { LOG_I("发送审计记录到Redis失败\n"); } } else { LOG_I("根据批次号码 %s 未找到对应的SN和MAC\n", str); } pthread_exit(NULL); return NULL; } if(strstr(str,"{")!=NULL){ #if 0 char deviceSecret[64]={0}; char deviceCode[64]={0}; char netWorkType[64]={0}; char netWorkSsid[64]={0}; char netWorkPassword[64]={0}; get_string_from_json_string_by_key_unescape(str, "deviceSecret",deviceSecret,64); LOG_I("deviceSecret:%s\n",deviceSecret); get_string_from_json_string_by_key_unescape(str, "deviceCode",deviceCode,64); LOG_I("deviceCode:%s\n",deviceCode); if(strcmp(deviceSecret,"")!=0 && strcmp(deviceCode,"")!=0){ buffer_to_file("deviceSecret",deviceSecret,strlen(deviceSecret),"wb"); buffer_to_file("savedDevSn",deviceCode,strlen(deviceCode),"wb"); } get_string_from_json_string_by_key_unescape(str, "netWorkType",netWorkType,64); LOG_I("netWorkType:%s\n",netWorkType); if(strcmp(netWorkType,"net_wifi")==0){ buffer_to_file("nettype","net_wifi",strlen("net_wifi"),"wb"); get_string_from_json_string_by_key_unescape(str, "netWorkSsid",netWorkSsid,64); LOG_I("netWorkSsid:%s\n",netWorkSsid); get_string_from_json_string_by_key_unescape(str, "netWorkPassword",netWorkPassword,64); LOG_I("netWorkPassword:%s\n",netWorkPassword); if(strcmp(netWorkSsid,"")!=0 && strcmp(netWorkPassword,"")!=0){ writeWpa("/etc/wpa_supplicant.conf",netWorkSsid,netWorkPassword); sleep(1); system("reboot"); }else{ } }else if(strcmp(netWorkType,"net_wired")==0){ buffer_to_file("nettype","net_wired",strlen("net_wired"),"wb"); LOG_I("use wired\n"); sleep(1); system("reboot"); }else if(strcmp(netWorkType,"net_mobile")==0){ buffer_to_file("nettype","net_mobile",strlen("net_mobile"),"wb"); LOG_I("use mobile\n"); sleep(1); system("reboot"); } #endif }else{ if(strstr(str,"TJ")!=NULL && strlen(str)==27){ LOG_I("ok\n"); char *result=NULL; char *p; result=strtok_r(str,":",&p); while(result!=NULL){ if(strstr(result,"TJ")!=NULL){ LOG_I("save sn:%s\n",result); buffer_to_file("savedDevSn",result,strlen(result),"wb"); }else{ LOG_I("save mac:%s\n",result); buffer_to_file("savedDevMac",result,strlen(result),"wb"); char* destmac = insert_colon(result, 2); LOG_I("formatted mac:%s\n",destmac); writeNetworkInterface("/etc/network/interfaces",destmac); writeNetworkInterface("/etc/network/interfaces.default",destmac); } result=strtok_r(NULL,",",&p); } } } pthread_exit(NULL); } char *file_to_buffer(const char *pathname, unsigned int *size){ FILE *fp = NULL; char *temp = NULL; fp = fopen(pathname, "rb"); if(fp==NULL){ //LOG_I("open %s error\n", pathname); }else{ fseek(fp,0,2); *size = ftell(fp); rewind(fp); temp = (char *)malloc(*size); fread(temp, 1, *size, fp); fclose(fp); } return temp; } /*================================================================================*/ void showShellInfo(char *command){ FILE *fp; char buffer[512]={0}; fp=popen(command, "r"); if (fp) { fread(buffer,1,sizeof(buffer),fp); pclose(fp); LOG_I("\n%s",buffer); } } void getTimeStr(char *buffer,int len){ time_t timep; struct tm *p; time (&timep); p=localtime(&timep); strftime (buffer,len,"%Y-%m-%d %H:%M:%S",p); } long getCurrentTime(){ struct timeval begin; gettimeofday(&begin,NULL); long long beginTime = (long long)begin.tv_sec * 1000 + (long long)begin.tv_usec / 1000; long last=beginTime/1000; return last; } void myrand(char *randnum,int len){ int i; srand((unsigned)time(0)); for(i=0;i<=len-1;i++) randnum[i]=rand()%10 +'0'; randnum[len]='\0'; } void removeSpaces(char *str) { int i = 0, j = 0; while (str[i] != '\0') { if (str[i] != ' ') { str[j++] = str[i]; } i++; } str[j] = '\0'; } void test_lighton_search(void){ LOG_I("%s\n",__func__); isSendComEnd=false; isLightOn=true; isLightOnByRule=false; isLabelUp=false; isSearchLabel=false; if(tagCount<=5){ lightsnNum=tagCount; }else{ lightsnNum=5; } LOG_I("tagCount:%d\n",tagCount); LOG_I("lightsnNum:%d\n",lightsnNum); for(int i=0;i=searchTimeOut){ isSearchLabelOntest=false; //search_tag_report(); test_lighton_search(); } } // 从savedDevMac文件读取MAC地址 unsigned int mac_file_size = 0; char *saved_mac = file_to_buffer("savedDevMac", &mac_file_size); char redis_mac[32] = {0}; char formatted_mac[32] = {0}; if (saved_mac != NULL && mac_file_size > 0) { strncpy(redis_mac, saved_mac, sizeof(redis_mac) - 1); redis_mac[sizeof(redis_mac) - 1] = '\0'; free(saved_mac); LOG_I("Got MAC from saved file: %s\n", redis_mac); // 格式化MAC地址 if(format_mac_address(redis_mac, formatted_mac, sizeof(formatted_mac)) == 0) { LOG_I("Formatted MAC: %s\n", formatted_mac); // 更新/etc/network/interfaces文件中的MAC地址 LOG_I("Updating MAC address in /etc/network/interfaces\n"); // 读取当前的interfaces文件内容 unsigned int file_size = 0; char *interfaces_content = file_to_buffer("/etc/network/interfaces", &file_size); if(interfaces_content != NULL) { // 查找并替换hwaddress ether行 char *hwaddress_line = strstr(interfaces_content, "hwaddress ether"); if(hwaddress_line != NULL) { // 找到行的结束位置 char *line_end = strchr(hwaddress_line, '\n'); if(line_end != NULL) { // 构建新的interfaces文件内容 size_t before_len = hwaddress_line - interfaces_content; size_t after_len = strlen(line_end); char new_interfaces[4096] = {0}; strncpy(new_interfaces, interfaces_content, before_len); snprintf(new_interfaces + before_len, sizeof(new_interfaces) - before_len, "hwaddress ether %s%s", formatted_mac, line_end); // 写入更新后的内容 int write_result = buffer_to_file("/etc/network/interfaces", new_interfaces, strlen(new_interfaces), "wb"); if(write_result == 0) { LOG_I("MAC address updated in /etc/network/interfaces successfully\n"); sync(); } else { LOG_I("Failed to update MAC address in /etc/network/interfaces\n"); } } else { LOG_I("Could not find end of hwaddress line\n"); } } else { LOG_I("hwaddress ether line not found in interfaces file\n"); } free(interfaces_content); } else { LOG_I("Failed to read /etc/network/interfaces file\n"); } } else { LOG_I("Failed to format MAC address\n"); } } else { LOG_I("Failed to read MAC from saved file\n"); } } else { LOG_I("Failed to save mqttRawPassword\n"); } } } } /*================================================================================*/ void mqtt_init(){ int ret=0; char username[32] = {0}; char password[32] = {0}; char clientid[256] = {0}; //char clientid[256] = "TJ250995217957|signmethod=hmacsha1|timestamp=1741416329331"; char hostip[16]={0}; //char protocol[64]="mqtt"; //char RawPassword[64]="94b4e39caf1d45ee9a071d701cc037b4"; struct timeval tv; //MQTTASYNC_TRACE_MAXIMUM //MQTTASYNC_TRACE_MEDIUM //MQTTASYNC_TRACE_MINIMUM //MQTTASYNC_TRACE_PROTOCOL //MQTTASYNC_TRACE_ERROR //MQTTASYNC_TRACE_SEVERE //MQTTASYNC_TRACE_FATAL //mqtt_config.tracelevel=get_trace_level_by_name("MQTTASYNC_TRACE_PROTOCOL"); gettimeofday(&tv, NULL); snprintf(clientid,sizeof(clientid),"%s|signmethod=hmacsha1|timestamp=%ld",stationsn,tv.tv_sec*1000+tv.tv_usec); LOG_I("clientid:%s,mqttRawPassword:%s\n",clientid,mqttRawPassword); hmacsha1(mqttRawPassword,clientid,password,sizeof(password)); mqtt_config.tracelevel=MQTTASYNC_TRACE_PROTOCOL; mqtt_config.retain=0; mqtt_config.port=mqtt_port; mqtt_config.keepalive=30; //memset(mqtt_config.protocol,0,sizeof(mqtt_config.protocol)); //memcpy(mqtt_config.protocol,protocol,sizeof(protocol)); memset(mqtt_config.clientid,0,sizeof(mqtt_config.clientid)); memcpy(mqtt_config.clientid,clientid,sizeof(clientid)); snprintf(username, sizeof(username), "%s", stationsn); LOG_I("username:%s,password:%s\n",username,password); memset(mqtt_config.productcode, 0, sizeof(mqtt_config.productcode)); memcpy(mqtt_config.productcode, productid, strlen(productid)); memset(mqtt_config.username, 0, sizeof(mqtt_config.username)); memcpy(mqtt_config.username, username, strlen(username)); memset(mqtt_config.password, 0, sizeof(mqtt_config.password)); memcpy(mqtt_config.password, password, strlen(password)); get_ip_by_domain(hostDomain,hostip,16); memset(mqtt_config.host, 0, sizeof(mqtt_config.host)); memcpy(mqtt_config.host, hostip, strlen(hostip)); mqtt_config.MQTTVersion = 4; /* will options */ mqtt_config.will_topic = NULL; mqtt_config.will_payload = NULL; mqtt_config.will_qos = 2; mqtt_config.will_retain = 0; /* TLS options */ mqtt_config.insecure = 0; mqtt_config.capath = NULL; mqtt_config.cert = NULL; mqtt_config.cafile = NULL; mqtt_config.key = NULL; mqtt_config.keypass = NULL; mqtt_config.ciphers = NULL; ret = sem_init(&mqtt_config.sem_connect, 0, 0); if (ret != 0) { LOG_I("sem_connect init error\n"); goto error; } ret = mqtt_utils_init(&mqtt_config); if (ret < 0) { LOG_I("mqtt_utils_init error\n"); ret = -1; goto error; } sem_wait(&mqtt_config.sem_connect); ret = 0; error: return; } /*================================================================================*/ void *thread_ota(void *arg){ prctl(PR_SET_NAME, "ota"); checkOtaKey(); } void *thread_mqtt(void *arg){ prctl(PR_SET_NAME, "mqtt"); mqtt_init(); } void *thread_removelog(void *arg){ prctl(PR_SET_NAME, "removelog"); removeLog(); } void *thread_reboot(void *arg){ prctl(PR_SET_NAME, "reboot"); rebootSystem(); } void *thread_feed_watchdog(void *arg){ prctl(PR_SET_NAME, "watchdog"); feedWatchDog(); } #if 1 void *thread_readqr(void *arg){ prctl(PR_SET_NAME, "readqr"); readQrcode(); } #endif void *thread_vm_heartbeat(void *arg) { char *client_id = (char *)arg; const char *url = "http://180.163.74.83:8428/api/v1/import/prometheus"; char post_data[256]; CURL *curl = curl_easy_init(); if (!curl) { DEBUG_TX("curl init failed\n"); pthread_exit(NULL); } system("ntpdate -u cn.pool.ntp.org"); while (1) { time_t now = time(NULL); // Prometheus exposition format snprintf(post_data, sizeof(post_data), "client_online{client_id=\"%s\"} %ld\n", client_id, now); curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data); CURLcode res = curl_easy_perform(curl); if (res != CURLE_OK) { DEBUG_TX("send to VictoriaMetrics failed: %s\n", curl_easy_strerror(res)); } else { DEBUG_TX("heartbeat sent: %s", post_data); } sleep(3); // 3秒心跳 } curl_easy_cleanup(curl); pthread_exit(NULL); } void *thread_tag_search_send(void *arg){ prctl(PR_SET_NAME, "tag_search"); while(1){ if(isSearchLabelOn){ sleep(10); searchTimeNew=getCurrentTime(); if((searchTimeNew-searchTimeOld)>=(searchTimeOut-20)){ isSearchReport=true; search_tag_report(); isSearchReport=false; isSearchLabelOn=false; } } else { usleep(100000); // 休眠100ms } } } void *thread_do_ota(void *arg){ prctl(PR_SET_NAME, "do_ota"); while(1){ if(isOtaEnable && isSendComEnd && !isLEDOtaSuccess){ sleep(1); otaLeds(); } else { usleep(100000); // 休眠100ms } } } //char *tag_1="00A04CCE"; //char *tag_2="00A04C0E"; //char *tag_3="00A04C0F"; //char *tag_4="00A04C11"; //char *tag_5="00A04CD0"; void *thread_uart_recv_ack(void *arg){ prctl(PR_SET_NAME, "uart_ack"); uint16_t parm_ack; int ret=0; while(1){ ret=uart_data_receive_ack(&uartSend,&parm_ack); if(ret>0){ LOG_I("ack:%x\n",parm_ack); if(parm_ack==0x2323){ // 记录收到0x2323的时间,并设置等待0x4646标志 time(&last_2323_time); waiting_for_4646 = true; #if 0 if(isLightOn){ uint32_t tags[30] = {0}; uint8_t tag_leds[30] = {0}; int valid_count = 0; for (int i = 0; i < lightsn_buffer_count; ++i) { // 1. SN转MAC(HEX字符串转uint32_t) if (strlen(lightsn_buffer[i]) == 8) { tags[valid_count] = (uint32_t)strtoul(lightsn_buffer[i], NULL, 16); } else { LOG_I("[WARN] tag[%d] sn格式非法: %s, 跳过", i, lightsn_buffer[i]); continue; } // 2. 颜色+闪光+声音合成LED控制字节(协议格式) int flash = (strlen(flash_buffer[i]) > 0) ? atoi(flash_buffer[i]) : atoi(mqtt_parm.msg_flash); // "1"=闪光, "0"=常亮 int sound = (strlen(sound_buffer[i]) > 0) ? atoi(sound_buffer[i]) : atoi(mqtt_parm.msg_sound); // "1"=有声, "0"=无声 int changecolor = 0; if(strcmp(color_buffer[i],"1")==0){ changecolor=4; }else if(strcmp(color_buffer[i],"2")==0){ changecolor=6; }else if(strcmp(color_buffer[i],"3")==0){ changecolor=1; }else if(strcmp(color_buffer[i],"4")==0){ changecolor=2; }else if(strcmp(color_buffer[i],"5")==0){ changecolor=3; }else if(strcmp(color_buffer[i],"6")==0){ changecolor=7; }else if(strcmp(color_buffer[i],"7")==0){ changecolor=5; }else if(strcmp(color_buffer[i],"8")==0){ changecolor=0; } uint8_t led_val = 0; if (flash) led_val |= 0x40; // Bit6 if (sound) led_val |= 0x10; // Bit4 led_val |= (changecolor & 0x0F); // 低4位为颜色 tag_leds[valid_count] = led_val; LOG_I("tag[%d]: sn=%s, color=%s, led=0x%02X ", valid_count, lightsn_buffer[i], color_buffer[i], tag_leds[valid_count]); valid_count++; } if (valid_count > 0) { uint8_t changecolor=0; if(strcmp(mqtt_parm.msg_color,"1")==0){ changecolor=4; }else if(strcmp(mqtt_parm.msg_color,"2")==0){ changecolor=6; }else if(strcmp(mqtt_parm.msg_color,"3")==0){ changecolor=1; }else if(strcmp(mqtt_parm.msg_color,"4")==0){ changecolor=2; }else if(strcmp(mqtt_parm.msg_color,"5")==0){ changecolor=3; }else if(strcmp(mqtt_parm.msg_color,"6")==0){ changecolor=7; }else if(strcmp(mqtt_parm.msg_color,"7")==0){ changecolor=5; }else if(strcmp(mqtt_parm.msg_color,"8")==0){ changecolor=0; } jt_ledctrl_package_t led_ctrl={ .s.color=changecolor, .s.sound=atoi(mqtt_parm.msg_sound), .s.flash=atoi(mqtt_parm.msg_flash), }; uart_data_send_lightband(&uartSend, led_ctrl.ch, atoi(mqtt_parm.msg_flash), atoi(mqtt_parm.msg_lightDuration), tags, tag_leds, valid_count); } isLightOn=false; // 处理完成后清空buffer pthread_mutex_lock(&lightsn_buffer_mutex); lightsn_buffer_count = 0; memset(lightsn_buffer, 0, sizeof(lightsn_buffer)); memset(color_buffer, 0, sizeof(color_buffer)); memset(sound_buffer, 0, sizeof(sound_buffer)); memset(flash_buffer, 0, sizeof(flash_buffer)); pthread_mutex_unlock(&lightsn_buffer_mutex); } #endif #if 1 if(isSearchLabel){ uart_data_send_search(&uartSend,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF); isSearchLabel=false; } #endif if(isLightOnByRule){ #if 0 uint16_t label2=strtol("FF01",NULL,16)&0xFFFF; uint32_t label3=strtol("663855c0",NULL,16); uint16_t flash_i=strtol("1",NULL,16)&0xFFFF; uint16_t light_d=strtol("5",NULL,16)&0xFFFF; jt_ledctrl_package_t led_ctrl={ .s.color=1, .s.sound=1, .s.flash=1, }; uart_data_send_light_rule(&uartSend,atoi("03"),label2,label3, atoi("0"), atoi("0"),atoi("0"), led_ctrl.ch, flash_i,light_d); #else uint16_t label2=strtol(mqtt_parm.msg_label2,NULL,16)&0xFFFF; uint32_t label3=strtol(mqtt_parm.msg_label3,NULL,16); uint16_t flash_i=strtol(mqtt_parm.msg_flashInterval,NULL,16)&0xFFFF; uint16_t light_d=strtol(mqtt_parm.msg_lightDuration,NULL,16)&0xFFFF; uint8_t changecolor=0; //8灭 1红 2黄 3蓝 4绿 5青 6白 7紫 tuxi //0灭 1蓝 2绿 3青 4红 5紫 6黄 7白 yitaile if(strcmp(mqtt_parm.msg_color,"1")==0){ changecolor=4; }else if(strcmp(mqtt_parm.msg_color,"2")==0){ changecolor=6; }else if(strcmp(mqtt_parm.msg_color,"3")==0){ changecolor=1; }else if(strcmp(mqtt_parm.msg_color,"4")==0){ changecolor=2; }else if(strcmp(mqtt_parm.msg_color,"5")==0){ changecolor=3; }else if(strcmp(mqtt_parm.msg_color,"6")==0){ changecolor=7; }else if(strcmp(mqtt_parm.msg_color,"7")==0){ changecolor=5; }else if(strcmp(mqtt_parm.msg_color,"8")==0){ changecolor=0; } jt_ledctrl_package_t led_ctrl={ .s.color=changecolor, .s.sound=atoi(mqtt_parm.msg_sound), .s.flash=atoi(mqtt_parm.msg_flash), }; uart_data_send_light_rule(&uartSend,atoi(mqtt_parm.msg_label1),label2,label3, atoi(mqtt_parm.msg_label1Rule), atoi(mqtt_parm.msg_label2Rule),atoi(mqtt_parm.msg_label3Rule), led_ctrl.ch, flash_i,light_d); #endif isLightOnByRule=false; } if(isLabelUp){ #if 0 time_t now = time(NULL); if(label_buf_count > 0 && (label_buf_count >= LABEL_BATCH_SIZE || (now - label_buf_first_time) >= 180)) { uart_data_send_head_lableup(&uartSend, 5, label_buf_count); usleep(10000); uart_data_send_lable(&uartSend, tags_buf, lable1_buf, lable2_buf, lable3_buf, label_buf_count); label_buf_count = 0; label_buf_first_time = 0; isLabelUp = false; } #endif } }else if(parm_ack==0x4646){ last_2323_time = 0; // 重置时间 waiting_for_4646 = false; // 重置等待状态 isSendComEnd=true; }else if(parm_ack==0x4f4f){ last_2323_time = 0; // 重置时间 waiting_for_4646 = false; // 重置等待状态 isSendComEnd=true; if(isOtaEnable){ otaCount++; if(otaCount>=2){ otaCount=0; isLEDOtaSuccess=true; isOtaEnable=false; system("echo 1 > /sys/class/gpio/gpio113/value"); } } }else if(parm_ack==0x5252){ last_2323_time = 0; // 重置时间 waiting_for_4646 = false; // 重置等待状态 uart_data_receive_version(&uartSend); isSendComEnd=true; isAPOtaSuccess=true; }else if(parm_ack==0x6464){ last_2323_time = 0; // 重置时间 waiting_for_4646 = false; // 重置等待状态 isSendComEnd=true; }else if(parm_ack==0x4848){ last_2323_time = 0; // 重置时间 waiting_for_4646 = false; // 重置等待状态 isAPBack=true; } } usleep(100*1000); } } void *thread_uart_recv_data(void *arg){ prctl(PR_SET_NAME, "uart_data"); uint16_t parmAck; uint32_t tagCode; uint8_t tagSignal; uint8_t totalLen; uint8_t tagFeature; uint8_t count; uint16_t batteryV; uint16_t version; uint8_t ledCtrl; uint8_t lable1; uint16_t lable2; uint32_t lable3; while(1){ uart_data_receive_data_back(&uartRecvData,&parmAck,&tagCode,&tagSignal,&totalLen,&tagFeature, &count,&batteryV,&version,&ledCtrl,&lable1,&lable2,&lable3); //LOG_I("recv_data:%04x,%08x,%02x,%02x,%02x,%02x,%04x,%04x,%02x,%02x,%04x,%08x\n",parmAck,tagCode,tagSignal,totalLen, // tagFeature,count,batteryV,version,ledCtrl,lable1,lable2,lable3); //sleep(2); } } void *thread_uart_recv_back(void *arg){ prctl(PR_SET_NAME, "uart_back"); uint16_t parmAck; uint32_t tagCode; uint8_t tagSignal; uint8_t totalLen; uint8_t tagFeature; uint8_t count; uint16_t batteryV; uint16_t version; uint8_t ledCtrl; uint8_t lable1; uint16_t lable2; uint32_t lable3; while(1){ uart_data_receive_data_back(&uartRecvBack,&parmAck,&tagCode,&tagSignal,&totalLen,&tagFeature, &count,&batteryV,&version,&ledCtrl,&lable1,&lable2,&lable3); //LOG_I("recv_back:%04x,%08x,%02x,%02x,%02x,%02x,%04x,%04x,%02x,%02x,%04x,%08x\n",parmAck,tagCode,tagSignal,totalLen, //tagFeature,count,batteryV,version,ledCtrl,lable1,lable2,lable3); //if(tagCode>0x90000000){ // PutDataIntoQueue(tagCode,batteryV); //} PutDataIntoQueue(tagCode,batteryV); if(tagFeature==0x83){ //LOG_I("search tag:%08x,battery:%04x\n",tagCode,batteryV); }else if(tagFeature==0x82){ //LOG_I("light down tag:%08x,battery:%04x\n",tagCode,batteryV); light_off_tag_report(tagCode,batteryV); //light_battery_report(tagCode,batteryV); }else if(tagFeature==0x81){ LOG_I("key down tag:%08x,battery:%04x,version:%4x\n",tagCode,batteryV,version); }else if(tagFeature==0xff){ //LOG_I("heart tag:%08x,battery:%04x,version:%4x\n",tagCode,batteryV,version); } } } void light_off_tag_report(uint32_t name,uint16_t batteryv){ json_object *lights = NULL; lights=json_object_new_array(); char tagName[9]={0}; char battery[5]={0}; sprintf(tagName,"%08X",name); sprintf(battery,"%d",batteryv); json_object *light = json_object_new_object(); json_object_object_add(light, "sn", json_object_new_string(tagName)); json_object_object_add(light, "battery", json_object_new_string(battery)); json_object_array_add(lights,light); json_object *lights_2 = json_object_new_array(); json_object *light_2 = json_object_new_object(); json_object_object_add(light_2, "sn", json_object_new_string(tagName)); json_object_object_add(light_2, "battery", json_object_new_string(battery)); json_object_array_add(lights_2, light_2); char myid[32]={0}; myrand(myid,19); mqtt_server_light_status_report(stationsn,myid,"2",lights); //mqtt_server_light_status_report_2(stationsn,myid,"2",lights_2); } void search_tag_report(){ int report_num=0; int i=0,j=0,m=0,n=0; copyOnlyTag(); LOG_I("%s tagCount:%d\n",__func__,tagCount); LOG_I("%s tagCountNew:%d\n",__func__,tagCountNew); if(tagCountNew>200){ for(i=0;i= max_retries) { LOG_E("Timeout waiting for unzip to complete"); return -1; } return 0; } void *thread_mqtt_recv(void *arg){ prctl(PR_SET_NAME, "mqtt_recv"); char payload[1024]={0}; char msg_body_value[1024] ={0}; char msg_body[1024] = {0}; char msg_data_value[1024] = {0}; char msg_data[1024] = {0}; char msg_labelconfig_value[1024] = {0}; char msg_labelconfig[1024] = {0}; char msg_lightsn_value[128] = {0}; char msg_lightsn[128] = {0}; while(1){ if(isSendComEnd){ if(GetDataFromMQueue(payload)==0){ //getPayloadTime=120*1000; LOG_I("payload:%s\n",payload); get_string_from_json_string_by_key_unescape(payload,"messageId",mqtt_parm.msg_messageId,sizeof(mqtt_parm.msg_messageId)); //LOG_I("messageId:%s\n",mqtt_parm.msg_messageId); if(isSearchLabelOn){ mqtt_service_reply(stationsn,mqtt_parm.msg_messageId,"search busy",0,productid); }else{ get_string_from_json_string_by_key_unescape(payload,"deviceId",mqtt_parm.msg_deviceId,sizeof(mqtt_parm.msg_deviceId)); LOG_I("deviceId:%s\n",mqtt_parm.msg_deviceId); get_int_from_json_string_by_key(payload,"timestamp",&mqtt_parm.msg_timestamp); LOG_I("timestamp:%d\n",mqtt_parm.msg_timestamp); get_string_from_json_string_by_key_unescape(payload, "msg", msg_body_value, sizeof(msg_body_value)); snprintf(msg_body, sizeof(msg_body), "%s", msg_body_value); LOG_I("msg_body:%s\n",msg_body); get_string_from_json_string_by_key_unescape(msg_body, "msgType", mqtt_parm.msg_type, sizeof(mqtt_parm.msg_type)); LOG_I("msgType:%s\n",mqtt_parm.msg_type); get_string_from_json_string_by_key_unescape(msg_body, "data", msg_data_value, sizeof(msg_data_value)); snprintf(msg_data, sizeof(msg_data), "{%s}", msg_data_value); LOG_I("msg_data:%s\n",msg_data); if(strcmp(mqtt_parm.msg_type,"1001")==0){ LOG_I("1001 dev disable\n"); isLightEnable=false; buffer_to_file("LightEnable","disable",strlen("disable"),"wb"); mqtt_service_reply(stationsn,mqtt_parm.msg_messageId,"ok",1,productid); }else if(strcmp(mqtt_parm.msg_type,"1002")==0){ LOG_I("1002 dev enable\n"); isLightEnable=true; buffer_to_file("LightEnable","enable",strlen("enable"),"wb"); mqtt_service_reply(stationsn,mqtt_parm.msg_messageId,"ok",1,productid); }else if(strcmp(mqtt_parm.msg_type,"1005")==0){ LOG_I("1005 dev reboot\n"); mqtt_service_reply(stationsn,mqtt_parm.msg_messageId,"ok",1,productid); system("sync"); sleep(10); system("sync"); system("reboot"); }else if(strcmp(mqtt_parm.msg_type,"1014")==0){ LOG_I("1014 update fw\n"); isSendComEnd=false; get_int_from_json_string_by_key(msg_data, "needWifi", &mqtt_parm.msg_needWifi); LOG_I("needWifi:%d\n",mqtt_parm.msg_needWifi); get_string_from_json_string_by_key_unescape(msg_data, "zipPath", mqtt_parm.msg_zipPath, sizeof(mqtt_parm.msg_zipPath)); LOG_I("zipPath:%s\n",mqtt_parm.msg_zipPath); get_int_from_json_string_by_key(msg_data, "installType", &mqtt_parm.msg_installType); LOG_I("installType:%d\n",mqtt_parm.msg_installType); get_int_from_json_string_by_key(msg_data, "immediately", &mqtt_parm.msg_immediately); LOG_I("immediately:%d\n",mqtt_parm.msg_immediately); get_int_from_json_string_by_key(msg_data, "installTime", &mqtt_parm.msg_installTime); LOG_I("installTime:%d\n",mqtt_parm.msg_installTime); get_string_from_json_string_by_key_unescape(msg_data, "version", mqtt_parm.msg_version, sizeof(mqtt_parm.msg_version)); LOG_I("version:%s\n",mqtt_parm.msg_version); mqtt_service_reply(stationsn,mqtt_parm.msg_messageId,"ok",1,productid); char otaCmd[256]={0}; sprintf(otaCmd,"curl -o /userdata/tx_ota.zip %s",mqtt_parm.msg_zipPath); //sprintf(otaCmd,"curl -o /root/tx_server https://fscdn.zto.com/cloudm/iot-device-package/7d609af2165b4d14ae318f17659b2fbf.bin"); system(otaCmd); sleep(15); system("unzip /userdata/tx_ota.zip"); //system("mv ../tx_ota/* /userdata/ota"); //system("rm -fr /userdata/ota/tx_ota"); system("rm -fr /userdata/ota"); system("mv /userdata/tx_ota /userdata/ota"); system("mv /userdata/ota/ustart.sh /userdata"); system("cp /userdata/ota/tx_server /tmp/tx_server_new"); LOG_I("cp /userdata/ota/tx_server /tmp/tx_server_new\n"); system("chmod +x /tmp/tx_server_new"); system("mv /tmp/tx_server_new /userdata/tx_server"); system("sync"); sleep(2); restart_tx_server_service(); }else if(strcmp(mqtt_parm.msg_type,"5003")==0){ LOG_I("5003 need report station info\n"); updateStationInfo(mqtt_parm.msg_messageId); }else if(strcmp(mqtt_parm.msg_type,"5005")==0){ LOG_I("5005 cloud search light\n"); //isSendComEnd=false; isLightOn=false; isLightOnByRule=false; isLabelUp=false; //isSearchLabel=true; 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); get_string_from_json_string_by_key_unescape(msg_data, "timeout", mqtt_parm.msg_timeout, sizeof(mqtt_parm.msg_timeout)); LOG_I("timeout:%s\n",mqtt_parm.msg_timeout); searchTimeOut=atoi(mqtt_parm.msg_timeout); LOG_I("searchTimeOut:%d\n",searchTimeOut); searchTimeOld=getCurrentTime(); LOG_I("searchTimeOld:%d\n",searchTimeOld); isSearchLabelOn=true; }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)); 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)); DEBUG_TX("lights:%s\n",mqtt_parm.msg_lights); get_size_from_json_string_arry_by_key(msg_data, "lights", &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)); 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)); 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)); 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)); 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)); DEBUG_TX("lightDuration:%s\n",mqtt_parm.msg_lightDuration); pthread_mutex_lock(&lightsn_buffer_mutex); if (!is_3015_collecting) { is_3015_collecting = true; first_3015_time = time(NULL); lightsn_buffer_count = 0; memset(lightsn_buffer, 0, sizeof(lightsn_buffer)); memset(color_buffer, 0, sizeof(color_buffer)); memset(sound_buffer, 0, sizeof(sound_buffer)); memset(flash_buffer, 0, sizeof(flash_buffer)); } int i; char msg_lightsn_value[128] = {0}; char msg_lightsn[128] = {0}; for (i = 0; i < mqtt_parm.msg_opNumber && lightsn_buffer_count < MAX_LIGHTSN_BUFFER; i++) { get_string_from_json_string_arry_by_key(msg_data, "lights", msg_lightsn_value, 128, i); snprintf(msg_lightsn, sizeof(msg_lightsn), "{%s}", msg_lightsn_value); get_string_from_json_string_by_key_unescape(msg_lightsn, "sn", lightsn_buffer[lightsn_buffer_count], 32); get_string_from_json_string_by_key_unescape(msg_lightsn, "color", color_buffer[lightsn_buffer_count], 8); get_string_from_json_string_by_key_unescape(msg_lightsn, "sound", sound_buffer[lightsn_buffer_count], 8); get_string_from_json_string_by_key_unescape(msg_lightsn, "flash", flash_buffer[lightsn_buffer_count], 8); if (strlen(color_buffer[lightsn_buffer_count]) == 0) strcpy(color_buffer[lightsn_buffer_count], mqtt_parm.msg_color); if (strlen(sound_buffer[lightsn_buffer_count]) == 0) strcpy(sound_buffer[lightsn_buffer_count], mqtt_parm.msg_sound); if (strlen(flash_buffer[lightsn_buffer_count]) == 0) strcpy(flash_buffer[lightsn_buffer_count], mqtt_parm.msg_flash); LOG_I("buffered sn: %s, color: %s, sound: %s, flash: %s\n", lightsn_buffer[lightsn_buffer_count], color_buffer[lightsn_buffer_count], sound_buffer[lightsn_buffer_count], flash_buffer[lightsn_buffer_count]); lightsn_buffer_count++; } pthread_mutex_unlock(&lightsn_buffer_mutex); mqtt_service_reply(stationsn, mqtt_parm.msg_messageId, "ok", 1, productid); }else if(strcmp(mqtt_parm.msg_type,"3022")==0){ LOG_I("3022 updata lable\n"); char sn_str[32] = {0}; char label1_str[8] = {0}; char label2_str[8] = {0}; char label3_str[16] = {0}; get_string_from_json_string_by_key_unescape(msg_data, "sn", sn_str, sizeof(sn_str)); get_string_from_json_string_by_key_unescape(msg_data, "label1", label1_str, sizeof(label1_str)); get_string_from_json_string_by_key_unescape(msg_data, "label2", label2_str, sizeof(label2_str)); get_string_from_json_string_by_key_unescape(msg_data, "label3", label3_str, sizeof(label3_str)); LOG_I("sn:%s\n", sn_str); LOG_I("label1:%s\n", label1_str); LOG_I("label2:%s\n", label2_str); LOG_I("label3:%s\n", label3_str); if(strcmp(sn_str,"")!=0){ if(label_buf_count == 0) { label_buf_first_time = time(NULL); } tags_buf[label_buf_count] = strtoul(sn_str, NULL, 16); lable1_buf[label_buf_count] = (uint8_t)atoi(label1_str); lable2_buf[label_buf_count] = (uint16_t)strtoul(label2_str, NULL, 16); lable3_buf[label_buf_count] = strtoul(label3_str, NULL, 16); label_buf_count++; mqtt_service_reply(stationsn, mqtt_parm.msg_messageId, "ok", 1, productid); isSendComEnd = true; isLightOn = false; isLightOnByRule = false; isLabelUp = true; }else{ mqtt_service_reply(stationsn, mqtt_parm.msg_messageId, "sn is empty", 0, productid); } }else if(strcmp(mqtt_parm.msg_type,"3023")==0){ LOG_I("3023 light on by rule\n"); get_string_from_json_string_by_key_unescape(msg_data, "labelConfig", msg_labelconfig_value, sizeof(msg_labelconfig_value)); snprintf(msg_labelconfig, sizeof(msg_labelconfig), "{%s}", msg_labelconfig_value); LOG_I("msg_labelconfig:%s\n",msg_labelconfig); get_string_from_json_string_by_key_unescape(msg_labelconfig, "label1", mqtt_parm.msg_label1, sizeof(mqtt_parm.msg_label1)); LOG_I("label1:%s\n",mqtt_parm.msg_label1); get_string_from_json_string_by_key_unescape(msg_labelconfig, "label2", mqtt_parm.msg_label2, sizeof(mqtt_parm.msg_label2)); LOG_I("label2:%s\n",mqtt_parm.msg_label2); get_string_from_json_string_by_key_unescape(msg_labelconfig, "label3", mqtt_parm.msg_label3, sizeof(mqtt_parm.msg_label3)); LOG_I("label3:%s\n",mqtt_parm.msg_label3); get_string_from_json_string_by_key_unescape(msg_labelconfig, "label1Rule", mqtt_parm.msg_label1Rule, sizeof(mqtt_parm.msg_label1Rule)); LOG_I("label1Rule:%s\n",mqtt_parm.msg_label1Rule); get_string_from_json_string_by_key_unescape(msg_labelconfig, "label2Rule", mqtt_parm.msg_label2Rule, sizeof(mqtt_parm.msg_label2Rule)); LOG_I("label2Rule:%s\n",mqtt_parm.msg_label2Rule); get_string_from_json_string_by_key_unescape(msg_labelconfig, "label3Rule", mqtt_parm.msg_label3Rule, sizeof(mqtt_parm.msg_label3Rule)); LOG_I("label3Rule:%s\n",mqtt_parm.msg_label3Rule); 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); 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); 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); 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); 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); if(strcmp(msg_labelconfig_value,"")!=0){ mqtt_service_reply(stationsn,mqtt_parm.msg_messageId,"ok",1,productid); isSendComEnd=false; isLightOn=false; isLightOnByRule=true; isLabelUp=false; //isSearchLabel=false; uart_data_send_head_lightonrule(&uartSend,5); }else{ mqtt_service_reply(stationsn,mqtt_parm.msg_messageId,"labelconfig is empty",0,productid); } }else if(strcmp(mqtt_parm.msg_type,"3027")==0){ LOG_I("3027 All light on/off 广播点亮\n"); get_string_from_json_string_by_key_unescape(msg_data, "color", mqtt_parm.msg_color, sizeof(mqtt_parm.msg_color)); //strcpy(mqtt_parm.msg_color, "1"); // 默认关闭颜色 LOG_I("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)); //strcpy(mqtt_parm.msg_sound, "0"); // 默认关闭声音 LOG_I("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)); //strcpy(mqtt_parm.msg_flash, "0"); // 默认关闭闪烁 LOG_I("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); 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); if(isLightEnable){ mqtt_service_reply(stationsn,mqtt_parm.msg_messageId,"ok",1,productid); // 设置规则并广播点亮,重置变量,防止被3015污染 isSendComEnd=false; isLightOn=false; isLightOnByRule=true; // 使用规则控制 isLabelUp=false; memset(lightsn1, 0, sizeof(lightsn1)); memset(lightsn2, 0, sizeof(lightsn2)); memset(lightsn3, 0, sizeof(lightsn3)); memset(lightsn4, 0, sizeof(lightsn4)); memset(lightsn5, 0, sizeof(lightsn5)); memset(lightsn6, 0, sizeof(lightsn6)); memset(lightsn7, 0, sizeof(lightsn7)); memset(lightsn8, 0, sizeof(lightsn8)); memset(lightsn9, 0, sizeof(lightsn9)); memset(lightsn10, 0, sizeof(lightsn10)); memset(lightsn11, 0, sizeof(lightsn11)); memset(lightsn12, 0, sizeof(lightsn12)); memset(lightsn13, 0, sizeof(lightsn13)); memset(lightsn14, 0, sizeof(lightsn14)); memset(lightsn15, 0, sizeof(lightsn15)); memset(lightsn16, 0, sizeof(lightsn16)); memset(lightsn17, 0, sizeof(lightsn17)); memset(lightsn18, 0, sizeof(lightsn18)); memset(lightsn19, 0, sizeof(lightsn19)); memset(lightsn20, 0, sizeof(lightsn20)); memset(lightsn21, 0, sizeof(lightsn21)); memset(lightsn22, 0, sizeof(lightsn22)); memset(lightsn23, 0, sizeof(lightsn23)); memset(lightsn24, 0, sizeof(lightsn24)); memset(lightsn25, 0, sizeof(lightsn25)); memset(lightsn26, 0, sizeof(lightsn26)); memset(lightsn27, 0, sizeof(lightsn27)); memset(lightsn28, 0, sizeof(lightsn28)); memset(lightsn29, 0, sizeof(lightsn29)); memset(lightsn30, 0, sizeof(lightsn30)); // 设置label1和label2不参与匹配 strcpy(mqtt_parm.msg_label1Rule, "04"); // ∅ 不参与匹配 strcpy(mqtt_parm.msg_label2Rule, "04"); // ∅ 不参与匹配 // 设置label3不等于386cd300的规则 strcpy(mqtt_parm.msg_label3Rule, "03"); // ≠ 不等于 strcpy(mqtt_parm.msg_label3, "386cd300"); // 广播点亮命令 LOG_I("Broadcasting light on command\n"); uart_data_send_head_lightonrule(&uartSend, 5); // 再次广播,提升可靠性 //usleep(100000); // 等待100ms //LOG_I("Sending second broadcast\n"); //uart_data_send_head_lightonrule(&uartSend, 5); }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); } else if(strcmp(mqtt_parm.msg_type,"2335")==0){ LOG_I("2335 执行命令任务\n"); char cmd[128] = {0}; char result[1024] = {0}; get_string_from_json_string_by_key_unescape(msg_data, "cmd", cmd, sizeof(cmd)); LOG_I("cmd: %s\n", cmd); if(strstr(cmd, "rm") || strstr(cmd, "reboot") || strstr(cmd, "shutdown")) { LOG_I("非法或危险命令: %s\n", cmd); mqtt_resource_reply(stationsn, mqtt_parm.msg_messageId, "system", 0, productid, "invalid or dangerous command"); } else if(strlen(cmd) == 0){ LOG_I("命令为空\n"); mqtt_resource_reply(stationsn, mqtt_parm.msg_messageId, "system", 0, productid, "command empty"); } else { FILE *fp = popen(cmd, "r"); if(fp){ fread(result, 1, sizeof(result)-1, fp); pclose(fp); LOG_I("命令输出: %s\n", result); mqtt_resource_reply(stationsn, mqtt_parm.msg_messageId, "system", 1, productid, result); } else { LOG_I("命令执行失败: %s\n", cmd); mqtt_resource_reply(stationsn, mqtt_parm.msg_messageId, "system", 0, productid, "command exec failed"); } } } } } usleep(getPayloadTime); }else{ usleep(getPayloadTime); } } } /*================================================================================*/ void hmacsha1(char *key,char* data,char *signbase64,int signbase64_len){ char result[256]={0}; size_t len=sizeof(result); //LOG_I("key_len:%d,data_len:%d\n",strlen(key),strlen(data)); hmac_sha1(key,strlen(key),data,strlen(data),result,&len); //LOG_I("result_len:%d\n",len); //int t_i; //for(t_i=0;t_i= 0) { write(fd, "63", 2); close(fd); } } // 设置 GPIO 63 方向为 in { int fd = open("/sys/class/gpio/gpio63/direction", O_WRONLY); if (fd >= 0) { write(fd, "in", 2); close(fd); } } // 导出 GPIO 113 { int fd = open("/sys/class/gpio/export", O_WRONLY); if (fd >= 0) { write(fd, "113", 3); close(fd); } } // 设置 GPIO 113 方向为 out { int fd = open("/sys/class/gpio/gpio113/direction", O_WRONLY); if (fd >= 0) { write(fd, "out", 3); close(fd); } } #endif #if 0 system("insmod /system/lib/modules/wk2xxx_spi.ko"); system("busybox udhcpc -i eth0"); system("timedatectl set-timezone Asia/Shanghai"); system("echo 63 > /sys/class/gpio/export");//reset key system("echo in > /sys/class/gpio/gpio63/direction"); system("echo 113 > /sys/class/gpio/export");//pin 113 yellow system("echo out > /sys/class/gpio/gpio113/direction"); #endif uart_open(&uartSend,"/dev/ttyS0");//GT U12 ttyS0,U14 ttyS4,U21 ttysWK0 U13 ttysWK1 U15 ttysWK2 U22 ttysWK3 U20 ttyS1 uart_init(&uartSend,115200,8,1,'N',0); uart_open(&uartRecvData,"/dev/ttyS4");//DT uart_init(&uartRecvData,115200,8,1,'N',0); uart_open(&uartRecvBack,"/dev/ttysWK0");//HT uart_init(&uartRecvBack,115200,8,1,'N',0); #if 0 struct dma_config cfg = { .buf = malloc(256), .len = 256 }; // 填充测试数据 memset(cfg.buf, 0x55, 256); // 启动DMA传输 ioctl(uartSend.uart_fd, DMA_START_TX, &cfg); #endif //doCommand_help(0, NULL); #if 1 enableWatchDog(); ret = pthread_create(&pt_watchdog,NULL,thread_feed_watchdog,NULL); if(ret!=0){ LOG_I("pthread_create watchdog fail\n"); }else{ LOG_I("pthread_create watchdog success\n"); pthread_detach(pt_watchdog); } #endif #if 0 ret = pthread_create(&pt_reboot,NULL,thread_reboot,NULL); if(ret!=0){ LOG_I("pthread_create reboot fail\n"); }else{ LOG_I("pthread_create reboot success\n"); pthread_detach(pt_reboot); } #endif ret = pthread_create(&pt_uart_recv_ack,NULL,thread_uart_recv_ack,NULL); if(ret!=0){ LOG_I("pthread_create uart_recv_ack fail\n"); }else{ pthread_detach(pt_uart_recv_ack); LOG_I("pthread_create uart_recv_ack success\n"); } ret = pthread_create(&pt_uart_recv_data,NULL,thread_uart_recv_data,NULL); if(ret!=0){ LOG_I("pthread_create uart_recv_data fail\n"); }else{ pthread_detach(pt_uart_recv_data); LOG_I("pthread_create uart_recv_data success\n"); } ret = pthread_create(&pt_uart_recv_back,NULL,thread_uart_recv_back,NULL); if(ret!=0){ LOG_I("pthread_create uart_recv_back fail\n"); }else{ pthread_detach(pt_uart_recv_back); LOG_I("pthread_create uart_recv_back success\n"); } ret = pthread_create(&pt_mqtt_recv,NULL,thread_mqtt_recv,NULL); if(ret!=0){ LOG_I("pthread_create mqtt_recv fail\n"); }else{ pthread_detach(pt_mqtt_recv); LOG_I("pthread_create mqtt_recv success\n"); } ret = pthread_create(&pt_tagsearch,NULL,thread_tag_search_send,NULL); if(ret!=0){ LOG_I("pthread_create tag search send fail\n"); }else{ LOG_I("pthread_create tag search success\n"); pthread_detach(pt_tagsearch); } ret = pthread_create(&pt_removeduplicatetag,NULL,thread_remove_duplicate_tag,NULL); if(ret!=0){ LOG_I("pthread_create remove duplicate tag send fail\n"); }else{ LOG_I("pthread_create remove duplicate tag success\n"); pthread_detach(pt_removeduplicatetag); } #if 0 ret = pthread_create(&pt_vm_heartbeat, NULL, thread_vm_heartbeat, stationsn); if(ret!=0){ LOG_I("pthread_create vm heartbeat fail\n"); }else{ LOG_I("pthread_create vm heartbeat success\n"); pthread_detach(pt_vm_heartbeat); } #endif #if 1 ret = pthread_create(&pt_removelog,NULL,thread_removelog,NULL); if(ret!=0){ LOG_I("pthread_create removelog fail\n"); }else{ LOG_I("pthread_create removelog success\n"); pthread_detach(pt_removelog); } #endif // 创建超时检测线程 ret = pthread_create(&timeout_thread, NULL, thread_timeout_check, NULL); if(ret!=0){ LOG_I("pthread_create timeout_check fail\n"); }else{ LOG_I("pthread_create timeout_check success\n"); pthread_detach(timeout_thread); } // 新增:3015合并点亮线程 pthread_t pt_3015_merge; ret = pthread_create(&pt_3015_merge, NULL, thread_3015_lighton_merge, NULL); if (ret != 0) { LOG_I("pthread_create 3015_merge fail\n"); } else { pthread_detach(pt_3015_merge); LOG_I("pthread_create 3015_merge success\n"); } // 新增:3022合包批量下发线程 pthread_t pt_label_batch_send; ret = pthread_create(&pt_label_batch_send, NULL, thread_label_batch_send, NULL); if (ret != 0) { LOG_I("pthread_create label_batch_send fail\n"); } else { pthread_detach(pt_label_batch_send); LOG_I("pthread_create label_batch_send success\n"); } ret = pthread_create(&pt_ota,NULL,thread_ota,NULL); if(ret!=0){ LOG_I("pthread_create ota fail\n"); }else{ LOG_I("pthread_create ota success\n"); pthread_detach(pt_ota); } ret = pthread_create(&pt_doota,NULL,thread_do_ota,NULL); if(ret!=0){ LOG_I("pthread_create doota fail\n"); }else{ LOG_I("pthread_create doota success\n"); pthread_detach(pt_doota); } #if 1 ret = pthread_create(&pt_readqr,NULL,thread_readqr,NULL); if(ret!=0){ LOG_I("pthread_create readqr fail\n"); }else{ LOG_I("pthread_create readqr success\n"); pthread_detach(pt_readqr); } #endif // 字符串清理函数,去除末尾的空白字符 void trim_whitespace(char *str) { if (str == NULL) return; int len = strlen(str); while (len > 0 && (str[len-1] == '\n' || str[len-1] == '\r' || str[len-1] == ' ' || str[len-1] == '\t')) { str[--len] = '\0'; } } readresult=file_to_buffer("savedDevSn",&len); #if 0 if(readresult==NULL){ // savedDevSn文件不存在,尝试从Redis获取SN LOG_I("savedDevSn file not found, trying to get SN from Redis...\n"); // 初始化Redis SN客户端 if (init_redis_sn_client() == 0) { LOG_I("Redis SN client initialized successfully\n"); // 尝试从Redis获取设备SN和MAC地址 char redis_sn[32] = {0}; char redis_mac[32] = {0}; if (get_device_sn_and_mac_from_redis(redis_sn, sizeof(redis_sn), redis_mac, sizeof(redis_mac)) == 0) { // 成功获取到SN和MAC,保存SN到文件 LOG_I("Got device SN: %s, MAC: %s from Redis\n", redis_sn, redis_mac); buffer_to_file("savedDevSn", redis_sn, strlen(redis_sn), "wb"); // 保存MAC地址到文件供getDevRawPassword使用 buffer_to_file("savedDevMac", redis_mac, strlen(redis_mac), "wb"); LOG_I("Device MAC saved to file: %s\n", redis_mac); strncpy(stationsn, redis_sn, sizeof(stationsn) - 1); stationsn[sizeof(stationsn) - 1] = '\0'; readresult = redis_sn; // 设置readresult避免进入while循环 len = strlen(redis_sn); } else { LOG_I("Failed to get SN from Redis, waiting for manual scan...\n"); } // 清理Redis客户端资源 cleanup_redis_sn_client(); } else { LOG_I("Redis SN client initialization failed, waiting for manual scan...\n"); } } #endif // 如果Redis获取失败或savedDevSn文件存在,按原逻辑处理 while(readresult==NULL){ readresult=file_to_buffer("savedDevSn",&len); sleep(5); LOG_I("please scan sn\n"); //TODO输出日志到180.163.74.83网页 } strncpy(stationsn,readresult,len); trim_whitespace(stationsn); // 清理空白字符 readresult=NULL; LOG_I("saved stationsn:%s\n",stationsn); #if 1 readresult=file_to_buffer("/userdata/mqttRawPassword",&len); if(readresult!=NULL){ strncpy(mqttRawPassword,readresult,len); trim_whitespace(mqttRawPassword); // 清理空白字符 readresult=NULL; LOG_I("saved mqttRawPassword:%s\n",mqttRawPassword); }else{ if((ping("8.8.8.8") == 0)||(ping("8.8.4.4") == 0)){ getDevRawPassword(stationsn); }else{ LOG_I("getDevRawPassword net not ready\n"); sleep(3); } } #endif readresult=file_to_buffer("/userdata/LightEnable",&len); if(readresult!=NULL){ if(strcmp(readresult,"enable")==0){ isLightEnable=true; }else{ isLightEnable=false; } readresult=NULL; } #if 1 while(1){ if((ping("8.8.8.8") == 0)||(ping("8.8.4.4") == 0)){ LOG_I("net ok\n"); while(!timeNew()){ //LOG_I("sleep\n"); getTimeCount++; if(getTimeCount==100){ break; } sleep(1); } saveStartUpTime(); ret = pthread_create(&pt_mqtt,NULL,thread_mqtt,NULL); if(ret!=0){ LOG_I("pthread_create mqtt fail\n"); }else{ pthread_detach(pt_mqtt); LOG_I("pthread_create mqtt success\n"); } break; }else{ DEBUG_TX("net not ready\n"); sleep(3); } } #endif #if 1 while(1) { // 先检查标准输入是否可用 if (feof(stdin) || ferror(stdin)) { //LOG_I("stdin error or EOF, sleeping for 1 second\n"); sleep(1); continue; } memset(command_buffer, 0, sizeof(command_buffer)); if (fgets(command_buffer, sizeof(command_buffer), stdin) == NULL) { usleep(100000); continue; } command_buffer[strcspn(command_buffer, "\n")] = 0; if (strlen(command_buffer) == 0) { continue; } if(execute_command(command_buffer, (command_t *)&__start_command, (&__stop_command - &__start_command)/2) < 0) { LOG_I("unsupport command!\r\n"); } } #endif return 0; } // 超时检测线程 void *thread_timeout_check(void *arg) { prctl(PR_SET_NAME, "timeout_check"); while(1) { if(last_2323_time != 0 && waiting_for_4646) { // 只有在等待0x4646时才检查超时 time_t current_time; time(¤t_time); if(difftime(current_time, last_2323_time) >= 10.0) { // 超过10秒 LOG_I("thread_timeout_check: Timeout after receiving 0x2323, no 0x4646 received, setting isSendComEnd to 1\n"); isSendComEnd = 1; last_2323_time = 0; // 重置时间 waiting_for_4646 = false; // 重置等待状态 isLightEnable = 1; // 重置点亮使能标志 isLightOn = false; // 重置点亮状态 isLightOnByRule = false; // 重置规则点亮状态 isLabelUp = false; // 重置标签更新状态 } } usleep(100*1000); // 每100ms检查一次 } return NULL; } // 合并点亮线程 void *thread_3015_lighton_merge(void *arg) { int total_all = 0; while (1) { pthread_mutex_lock(&lightsn_buffer_mutex); if (is_3015_collecting) { time_t now = time(NULL); if ((now - first_3015_time >= 3) || (lightsn_buffer_count >= MAX_LIGHTSN_BUFFER)) { int total = lightsn_buffer_count; total_all += total; int batch_size = 10; int sent = 0; while (sent < total) { int this_batch = (total - sent > batch_size) ? batch_size : (total - sent); DEBUG_TX("-------total:%d, sent:%d, this batch: %d------\n", total, sent, this_batch); if (isLightEnable && this_batch > 0) { isLightOn = true; isLightOnByRule = false; isLabelUp = false; uint32_t tags[10] = {0}; uint8_t tag_leds[10] = {0}; for (int i = 0; i < this_batch; 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 { DEBUG_TX("[WARN] tag[%d] sn格式非法: %s, 跳过", sent + i, lightsn_buffer[sent + i]); continue; } // 2. 颜色+闪光+声音合成LED控制字节(协议格式) int flash = (strlen(flash_buffer[sent + i]) > 0) ? atoi(flash_buffer[sent + i]) : atoi(mqtt_parm.msg_flash); // "1"=闪光, "0"=常亮 int sound = (strlen(sound_buffer[sent + i]) > 0) ? atoi(sound_buffer[sent + i]) : atoi(mqtt_parm.msg_sound); // "1"=有声, "0"=无声 int changecolor = 0; if(strcmp(color_buffer[sent + i],"1")==0){ changecolor=4; }else if(strcmp(color_buffer[sent + i],"2")==0){ changecolor=6; }else if(strcmp(color_buffer[sent + i],"3")==0){ changecolor=1; }else if(strcmp(color_buffer[sent + i],"4")==0){ changecolor=2; }else if(strcmp(color_buffer[sent + i],"5")==0){ changecolor=3; }else if(strcmp(color_buffer[sent + i],"6")==0){ changecolor=7; }else if(strcmp(color_buffer[sent + i],"7")==0){ changecolor=5; }else if(strcmp(color_buffer[sent + i],"8")==0){ changecolor=0; } uint8_t led_val = 0; if (flash) led_val |= 0x40; // Bit6 if (sound) led_val |= 0x10; // Bit4 led_val |= (changecolor & 0x0F); // 低4位为颜色 tag_leds[i] = led_val; } uint8_t changecolor=0; if(strcmp(mqtt_parm.msg_color,"1")==0){ changecolor=4; }else if(strcmp(mqtt_parm.msg_color,"2")==0){ changecolor=6; }else if(strcmp(mqtt_parm.msg_color,"3")==0){ changecolor=1; }else if(strcmp(mqtt_parm.msg_color,"4")==0){ changecolor=2; }else if(strcmp(mqtt_parm.msg_color,"5")==0){ changecolor=3; }else if(strcmp(mqtt_parm.msg_color,"6")==0){ changecolor=7; }else if(strcmp(mqtt_parm.msg_color,"7")==0){ changecolor=5; }else if(strcmp(mqtt_parm.msg_color,"8")==0){ changecolor=0; } jt_ledctrl_package_t led_ctrl={ .s.color=changecolor, .s.sound=atoi(mqtt_parm.msg_sound), .s.flash=atoi(mqtt_parm.msg_flash), }; uart_data_send_head_lightband(&uartSend, 2, this_batch); usleep(50000); uart_data_send_lightband(&uartSend, led_ctrl.ch, atoi(mqtt_parm.msg_flash), atoi(mqtt_parm.msg_lightDuration), tags, tag_leds, this_batch); } sent += this_batch; if (sent < total) { sleep(3); } DEBUG_TX("total_all: %d\n", total_all); } // 不要立即清空buffer,等待isLightOn处理完成 is_3015_collecting = false; first_3015_time = 0; isLightOn = false; } } pthread_mutex_unlock(&lightsn_buffer_mutex); usleep(100*1000); } return NULL; } // 3022合包批量下发线程 void *thread_label_batch_send(void *arg) { while (1) { if (isLightOnByRule == false && isLightOn == false) { time_t now = time(NULL); if (label_buf_count > 0 && (label_buf_count >= 10 || (now - label_buf_first_time) >= 60)) { uart_data_send_head_lableup(&uartSend, 5, label_buf_count); usleep(10000); uart_data_send_lable(&uartSend, tags_buf, lable1_buf, lable2_buf, lable3_buf, label_buf_count); label_buf_count = 0; label_buf_first_time = 0; isLabelUp = false; } } usleep(1000 * 1000); // 每秒检查一次 } return NULL; } void light_battery_report(uint32_t tagCode, uint16_t batteryV) { const char *url = "http://180.163.74.83:8428/api/v1/import/prometheus"; char post_data[256]; CURL *curl = curl_easy_init(); if (!curl) { DEBUG_TX("curl init failed\n"); return; } time_t now = time(NULL); // Prometheus exposition format: light_battery{tag="xxxxxx"} value timestamp snprintf(post_data, sizeof(post_data), "light_battery{tag=\"%08X\"} %d\n", tagCode, batteryV); curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data); CURLcode res = curl_easy_perform(curl); if (res != CURLE_OK) { DEBUG_TX("send light_battery_report failed: %s\n", curl_easy_strerror(res)); } else { DEBUG_TX("light_battery_report sent: %s", post_data); } curl_easy_cleanup(curl); }