AP05/main.c
2025-07-07 11:26:48 +08:00

2712 lines
105 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "main.h"
#define PRINT_TIME_TAG
#define DBG_TAG "main"
#define DBG_LVL DBG_INFO
#include "debug_print.h"
#include <sys/prctl.h>
#if 0
#include <fcntl.h>
#include <sys/mman.h>
#include <linux/serial.h>
#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_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 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.20";
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;
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 search_tag_report();
void copyOnlyTag(void);
/*================================================================================*/
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;
}
// 安全的命令执行函数
static int safe_exec_cmd(const char *cmd) {
// 检查命令是否包含危险字符
if (strstr(cmd, ";") || strstr(cmd, "|") || strstr(cmd, "&") || strstr(cmd, "..")) {
LOG_E("Dangerous command detected: %s", cmd);
return -1;
}
int ret = system(cmd);
if (ret != 0) {
LOG_E("Command failed: %s, error: %s", cmd, 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");
fgets(buffer,sizeof(buffer),fp);
logcount=atoi(buffer);
LOG_I("logcount:%d\n",logcount);
if(logcount>=3){
sprintf(syscmd,"ls Log.*|head -%d|xargs rm -fr",logcount-2);
LOG_I("%s\n",syscmd);
system(syscmd);
}else{
LOG_I("logcount less than 3,not remove\n");
}
}
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*5)){
//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");
}
}
}
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;i<len/4096;i++){
uart_data_send_ledota(&uartSend,readresult+i*4096,4096);
usleep(72*1000);
}
uart_data_send_ledota(&uartSend,readresult+i*4096,len%4096);
}
#else
int len=0,ver=0;
char *readresult=NULL;
char filename[128]={};
uint8_t senddata[4096]={};
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降级
int i=0;
for(i=0;i<len/4096;i++){
memset(senddata,0,4096);
memcpy(senddata,readresult+i*4096,4096);
uart_data_send_ledota(&uartSend,senddata,4096);
}
memset(senddata,0,4096);
memcpy(senddata,readresult+i*4096,len%4096);
uart_data_send_ledota(&uartSend,senddata,len%4096);
}
#endif
}
void otaAp(){
int len=0,ver=0;
char *readresult=NULL;
char filename[128]={};
char modename[32]={};
uint8_t dataori[2048]={0};
uint16_t data_crc=0;
uint16_t p_num=0;
ver=getApOtaVersion(filename,modename);
LOG_I("ota %s mode:%s ver:%d\n",filename,modename,ver);
readresult=file_to_buffer(filename,&len);
if(len%2048!=0){
p_num=len/2048 + 1;
}else{
p_num=len/2048;
}
if(readresult!=NULL){
isSendComEnd=false;
LOG_I("data len:%d\n",len);
if(strcmp(modename,"GTMODE")==0){
uart_data_send_head_apota(&uartSend,len,p_num);
usleep(60*1000);
memset(dataori,0,2048);
memcpy(dataori,readresult,2048);
data_crc=CRC16_APOTA(dataori,2048);
LOG_I("crc :%04x\n",data_crc);
uart_data_send_apota(&uartSend,dataori,len,p_num,data_crc);
while(!isAPBack){
usleep(60*1000);
}
int i=0;
for(i=1;i<len/2048;i++){
isAPBack=false;
memset(dataori,0,2048);
memcpy(dataori,readresult+i*2048,2048);
data_crc=CRC16_APOTA(dataori,2048);
LOG_I("crc :%04x\n",data_crc);
uart_data_send_apota(&uartSend,dataori,2048,i,data_crc);
while(!isAPBack){
usleep(60*1000);
}
}
if(len%2048!=0){
memset(dataori,0,2048);
memcpy(dataori,readresult+i*2048,len%2048);
data_crc=CRC16_APOTA(dataori,2048);
LOG_I("crc :%04x\n",data_crc);
uart_data_send_apota(&uartSend,dataori,2048,i,data_crc);
}
}else if(strcmp(modename,"DTMODE")==0){
}if(strcmp(modename,"HTMODE")==0){
}
}
}
void enableWatchDog() {
int fd;
char path[64];
char value[2];
// Enable watchdog pin SGM820
fd = open("/sys/class/gpio/export", O_WRONLY);
if (fd < 0) {
LOG_I("Failed to open gpio export: %s\n", strerror(errno));
return;
}
write(fd, "1", 1);
close(fd);
// Enable feed watchdog pin
fd = open("/sys/class/gpio/export", O_WRONLY);
if (fd < 0) {
LOG_I("Failed to open gpio export: %s\n", strerror(errno));
return;
}
write(fd, "112", 3);
close(fd);
// Set gpio1 direction
fd = open("/sys/class/gpio/gpio1/direction", O_WRONLY);
if (fd < 0) {
LOG_I("Failed to open gpio1 direction: %s\n", strerror(errno));
return;
}
write(fd, "out", 3);
close(fd);
// Set gpio112 direction
fd = open("/sys/class/gpio/gpio112/direction", O_WRONLY);
if (fd < 0) {
LOG_I("Failed to open gpio112 direction: %s\n", strerror(errno));
return;
}
write(fd, "out", 3);
close(fd);
// Set gpio1 value
fd = open("/sys/class/gpio/gpio1/value", O_WRONLY);
if (fd < 0) {
LOG_I("Failed to open gpio1 value: %s\n", strerror(errno));
return;
}
write(fd, "1", 1);
close(fd);
LOG_I("enable watchdog\n");
// Set gpio112 value
fd = open("/sys/class/gpio/gpio112/value", O_WRONLY);
if (fd < 0) {
LOG_I("Failed to open gpio112 value: %s\n", strerror(errno));
return;
}
write(fd, "1", 1);
close(fd);
}
void feedWatchDog() {
int fd = open("/sys/class/gpio/gpio112/value", O_WRONLY);
if (fd < 0) {
LOG_I("can not open watchdog gpio112\n");
return;
}
while(1) {
write(fd, "0", 1);
usleep(100*1000);
write(fd, "1", 1);
sleep(1);
}
close(fd);
return;
}
void rebootSystem(void){
while(!isTimeToReboot){
if(!isTimeToReboot){
struct tm *result;
time_t timep;
time (&timep);
result = localtime(&timep);
if(result->tm_hour==0 && result->tm_min==0 && result->tm_sec==10){
isTimeToReboot=true;
LOG_I("prepare to reboot\n");
}
}
sleep(1);
}
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);
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("save 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");
fread(buffer,1,sizeof(buffer),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 getDevRawPassword(char *devsn){
LOG_I("devsn:%s\n",devsn);
json_object *root = NULL;
const char *payload = NULL;
char payload_copy[256]={0};
char send_request[256]={0};
char signbase64[256]={0};
char signtmp[256]={0};
char jsondata[256] = {0};
char tmpdata[256] = {0};
//char tmpdata1[64] = {0};
char buffer[512];
FILE *fp;
root = json_object_new_object();
if(root == NULL){
LOG_I("json_object_new_object error\n");
}else{
json_object_object_add(root, "deviceId",json_object_new_string(devsn));
json_object_object_add(root, "oldPassword",json_object_new_string("12345"));
payload = json_object_to_json_string(root);
json_object_put(root);
if (payload == NULL) {
LOG_I("json_object_to_json_string error\n");
return;
}
strncpy(payload_copy, payload, sizeof(payload_copy)-1);
removeSpaces(payload_copy);
strncpy(signtmp, payload, sizeof(signtmp) - 1);
signtmp[sizeof(signtmp) - 1] = '\0';
strncat(signtmp, appSecret, sizeof(signtmp) - strlen(signtmp) - 1);
//LOG_I("signtmp:%s\n",signtmp);
get_base64_md5_from_string(signbase64, sizeof(signbase64), signtmp, strlen(signtmp));
//LOG_I("signbase64:%s\n",signbase64);
snprintf(send_request, sizeof(send_request), "curl -X POST -H 'x-appKey:%s' -H 'x-datadigest:%s' -H 'Content-Type: application/json' -d '%s' %s",
appKey, signbase64, payload_copy, getDevRawPasswordUrl);
LOG_I("send_request:%s\n",send_request);
fp=popen(send_request,"r");
if (fp != NULL) {
fgets(buffer, sizeof(buffer), fp);
pclose(fp);
}
//get_string_from_json_string_by_key_unescape(buffer, "message", tmpdata1, sizeof(tmpdata1));
//LOG_I("message: %s\n",tmpdata1);
get_string_from_json_string_by_key_unescape(buffer, "result", tmpdata, sizeof(tmpdata));
LOG_I("result: %s\n",tmpdata);
snprintf(jsondata, sizeof(jsondata), "{%s}", tmpdata);
//LOG_I("jsondata:%s\n",jsondata);
get_string_from_json_string_by_key_unescape(jsondata, "password", mqttRawPassword, sizeof(mqttRawPassword));
LOG_I("save mqttRawPassword:%s\n",mqttRawPassword);
if(strcmp(mqttRawPassword,"")!=0){
buffer_to_file("mqttRawPassword",mqttRawPassword,strlen(mqttRawPassword),"wb");
}
}
}
/*================================================================================*/
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();
}
void *thread_readqr(void *arg){
prctl(PR_SET_NAME, "readqr");
readQrcode();
}
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转MACHEX字符串转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 0
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);
}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<tagCountNew/200;i++){
json_object *lights =json_object_new_array();
for(j=i*200;j<i*200+200;j++){
LOG_I("onlyTags:%08X,%04x\n",onlyTagsNew[j].name,onlyTagsNew[j].battery);
char tagName[9]={0};
char battery[5]={0};
sprintf(tagName,"%08X",onlyTagsNew[j].name);
sprintf(battery,"%d",onlyTagsNew[j].battery);
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);
}
report_num+=200;
LOG_I("report_num:%d\n",report_num);
mqtt_server_light_status_report(stationsn,mqtt_parm.msg_messageId,"1",lights);
}
json_object *lights =json_object_new_array();
for(m=i*200;m<i*200+(tagCountNew%200);m++){
LOG_I("onlyTags:%08X,%04x\n",onlyTagsNew[m].name,onlyTagsNew[m].battery);
char tagName[9]={0};
char battery[5]={0};
sprintf(tagName,"%08X",onlyTagsNew[m].name);
sprintf(battery,"%d",onlyTagsNew[m].battery);
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);
}
report_num+=m-i*200;
//report_num+=tagCountNew%200;
LOG_I("report_num:%d\n",report_num);
mqtt_server_light_status_report(stationsn,mqtt_parm.msg_messageId,"1",lights);
}else{
json_object *lights =json_object_new_array();
for(n=0;n<tagCountNew;n++){
LOG_I("onlyTags:%08X,%04x\n",onlyTagsNew[n].name,onlyTagsNew[n].battery);
char tagName[9]={0};
char battery[5]={0};
sprintf(tagName,"%08X",onlyTagsNew[n].name);
sprintf(battery,"%d",onlyTagsNew[n].battery);
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);
}
report_num=tagCountNew;
LOG_I("report_num:%d\n",report_num);
mqtt_server_light_status_report(stationsn,mqtt_parm.msg_messageId,"1",lights);
}
mqtt_service_reply(stationsn,mqtt_parm.msg_messageId,"ok",1,productid);
tagCountNew=0;
memset(onlyTagsNew,0,5000);
}
void copyOnlyTag(void){
int i=0;
tagCountNew=0;
for(i=0;i<tagCount;i++){
if(getCurrentTime()-onlyTags[i].time<=60*50){
onlyTagsNew[tagCountNew]=onlyTags[i];
tagCountNew++;
}
}
LOG_I("tagCountNew:%d\n",tagCountNew);
}
void addOnlyTag(uint32_t tagname,uint16_t battery){
int i=0;
if(tagCount==0){
jt_only_tag_t jt_only_tag = {
.name=tagname,
.battery=battery,
.time=getCurrentTime(),
};
onlyTags[tagCount]=jt_only_tag;
tagCount++;
}else{
for(i=0;i<tagCount;i++){
if(tagname==onlyTags[i].name){
onlyTags[i].time=getCurrentTime();
break;
}
}
if(i==tagCount){
jt_only_tag_t jt_only_tag = {
.name=tagname,
.battery=battery,
.time=getCurrentTime(),
};
onlyTags[tagCount]=jt_only_tag;
tagCount++;
}
}
}
void *thread_remove_duplicate_tag(void *arg){
prctl(PR_SET_NAME, "rm_dup_tag");
uint32_t tagname=0;
uint16_t battery=0;
while(1){
if(!isSearchReport){
if(GetDataFromQueue(&tagname,&battery)==0){
//LOG_I("%08x,%04x\n",tagname,battery);
addOnlyTag(tagname,battery);
}
}
}
}
// 检查文件是否存在的函数
static int file_exists(const char *path) {
struct stat st;
return (stat(path, &st) == 0);
}
// 检查压缩包是否解压完成
static int check_unzip_complete(const char *zip_file) {
char cmd[256];
char last_file[256] = {0};
FILE *fp;
// 获取压缩包中最后一个文件
snprintf(cmd, sizeof(cmd), "unzip -l %s | tail -n 1 | awk '{print $4}'", zip_file);
fp = popen(cmd, "r");
if (fp == NULL) {
LOG_E("Failed to execute command: %s", cmd);
return -1;
}
if (fgets(last_file, sizeof(last_file), fp) == NULL) {
LOG_E("Failed to get last file from zip");
pclose(fp);
return -1;
}
pclose(fp);
// 去除换行符
last_file[strcspn(last_file, "\n")] = 0;
// 检查文件是否存在
char full_path[512];
snprintf(full_path, sizeof(full_path), "tx_ota/%s", last_file);
int retry_count = 0;
const int max_retries = 30; // 最多等待30秒
while (!file_exists(full_path) && retry_count < max_retries) {
usleep(1000000); // 等待1秒
retry_count++;
}
if (retry_count >= 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("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("sync");
sleep(1);
system("reboot");
}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));
LOG_I("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);
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);
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);
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);
}
}
}
}
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<len;t_i++)
// printf("%x ",result[t_i]);
Base64_encode( signbase64, signbase64_len, result,strlen(result));
//printf("last:%s\n",signbase64);
}
void getLocalIp(char *local_ip){
char hostname[32]={0};
FILE *fp;
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);
}
int getLedOtaVersion(char *filename){
FILE *fp;
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);
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);
LOG_I("ver:%d\n",ver);
return ver;
}
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);
return ver;
}
void saveStartUpTime(){
system("rm ./startUpTime");
struct timeval tv;
char startUpTime[32] = {0};
gettimeofday(&tv, NULL);
snprintf(startUpTime,sizeof(startUpTime),"%ld",tv.tv_sec);
buffer_to_file("startUpTime",startUpTime,strlen(startUpTime),"wb");
}
void calculateStartUpTime(char *startTime){
char *result=NULL;
struct timeval tv;
int len=0;
result=file_to_buffer("startUpTime",&len);
if(result!=NULL){
LOG_I("startUpTime:%s\n",result);
gettimeofday(&tv, NULL);
LOG_I("nowUpTime:%ld\n",tv.tv_sec);
snprintf(startTime,11,"%ld",tv.tv_sec-atoi(result));
}
}
void updateStationInfo(char *msg_id){
char local_ip[32] = {0};
char startTime[11]={0};
getLocalIp(local_ip);
LOG_I("local_ip:%s\n",local_ip);
calculateStartUpTime(startTime);
LOG_I("Time:%s\n",startTime);
mqtt_server_station_status_report(msg_id,productid,stationsn,local_ip,softwareVersion,"1",startTime);
mqtt_server_station_status_report_test(msg_id,productid,stationsn,local_ip,softwareVersion,"1",startTime);
}
bool timeNew(){
struct timeval tv;
gettimeofday(&tv, NULL);
long gettime=tv.tv_sec*1000+tv.tv_usec;
LOG_I("gettime:%ld\n",gettime);
if(gettime<1744000000000){
return false;
}
return true;
}
//==========================================================================================
int main(int argc, char *argv[])
{
int ret = -1;
uint32_t can_id;
char recv_data[8]={0};
char command_buffer[256] = "";
uint32_t len=0;
int getTimeCount=0;
char *readresult=NULL;
char networktype[32]={0};
pthread_t timeout_thread; // 添加超时检测线程变量
char syscmd[256]={0};
LOG_I("version:%s\n",softwareVersion);
FILE *fp = fopen("/userdata/tx_version", "w");
if (fp) {
fprintf(fp, "%s\n", softwareVersion);
fclose(fp);
} else {
LOG_I("Failed to write /userdata/tx_version\n");
}
#if 1
system("insmod /system/lib/modules/wk2xxx_spi.ko");
snprintf(syscmd, sizeof(syscmd), "ls Log.*|xargs rm -fr");
system(syscmd);
// 设置时区为 Asia/Shanghai直接修改 /etc/localtime 软链接
unlink("/etc/localtime");
symlink("/usr/share/zoneinfo/Asia/Shanghai", "/etc/localtime");
// 导出 GPIO 63
{
int fd = open("/sys/class/gpio/export", O_WRONLY);
if (fd >= 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_removelog,NULL,thread_removelog,NULL);
if(ret!=0){
LOG_I("pthread_create removelog fail\n");
system("reboot");
}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 0
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
readresult=file_to_buffer("savedDevSn",&len);
while(readresult==NULL){
readresult=file_to_buffer("savedDevSn",&len);
sleep(5);
LOG_I("please scan sn use tx_test\n");
}
strncpy(stationsn,readresult,len);
readresult=NULL;
LOG_I("saved stationsn:%s\n",stationsn);
#if 1
readresult=file_to_buffer("mqttRawPassword",&len);
if(readresult!=NULL){
strncpy(mqttRawPassword,readresult,len);
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("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{
LOG_I("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(&current_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) {
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;
int batch_size = 10;
int sent = 0;
while (sent < total) {
int this_batch = (total - sent > batch_size) ? batch_size : (total - sent);
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++) {
LOG_I("sn[%d]=%s\n", sent + i + 1, lightsn_buffer[sent + i]);
// 1. SN转MACHEX字符串转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]);
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) {
pthread_mutex_unlock(&lightsn_buffer_mutex); // 释放锁等待
sleep(3);
pthread_mutex_lock(&lightsn_buffer_mutex); // 重新加锁
}
}
// 不要立即清空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) >= 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;
}
}
usleep(1000 * 1000); // 每秒检查一次
}
return NULL;
}