#include "main.h" #include "json-c/json.h" #include "uart_utils/uart_utils.h" #include "uart_can/uart_can.h" #include "mqtt_utils/mqtt_utils.h" #include "queue/queue.h" #define PRINT_TIME_TAG #define DBG_TAG "main" #define DBG_LVL DBG_INFO #include "debug_print/debug_print.h" // 全局变量声明 jt_led_or_group_package_t tags; jt_led_or_group_package_t led_ctrl; // 函数声明 void light_status_report(void); void update_app(void); // MQTT协议相关常量定义 #define MQTT_ALGORITHM "AUK1_MQTT_HMAC_SHA1" #define MQTT_SECURE_MODE "TCP" #define MQTT_AUTH_TYPE_REGISTER "REGISTER" #define MQTT_AUTH_TYPE_AUTH "AUTH" 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_reporttag; pthread_t pt_mqtt; pthread_t pt_removelog; pthread_t pt_watchdog; pthread_t pt_removeduplicatetag; pthread_t pt_keycheck; pthread_t pt_mqtt_status; pthread_t pt_station_heartbeat; 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 newappDownloaded=false; bool isLightOn=false; bool isLightOnById=false; bool isLightOnByGroup=false; bool isBindTag=false; bool isSendComEnd=true; bool isStopBroadcast=false; bool isStopBroadcastBegin=false; bool isOtaEnable=false; jt_only_tag_t onlyTags[200]={0}; int tagCount=0; int lightbars_size=0; int lightbars_count=0; uint8_t changecolor=0; uint8_t changesound=0; uint8_t groupno=0; int fd; int UPCASE=0; int count_value=0; int getPayloadTime=100*1000;//usecond char softwareVersion[16]="2.1.22"; //char stationsn[16]="d126ei4lj4cc00";//TJ250995217957 //char productid[8]="10045"; //char appSecret[64]="s3izIliw0CF48Pcsi16rjOmoFRf5WEt8"; char stationsn[32]="90A9F73002CD"; char productid[16]="WcLightStrip"; char appKey[32]="fdhQmhqhvbL1cf1K9mUqt"; char appSecret[64]="RxU8NZjfZaxsKg2B3Dr6sx"; char hostDomain[64]="auk-iot.test1.zservey.com"; 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 *updateUrl="https://idata-creat.oss-cn-shenzhen.aliyuncs.com/jd_ota.zip"; char *getDevRawPasswordUrl="https://gaea.zt-express.com/device/modifyRegisterInfo"; //char *hostDomain="emqx.thingtalk.jdl.com"; char lightsn1[7]={0}; char lightsn2[7]={0}; char lightsn3[7]={0}; char lightsn4[7]={0}; char lightsn5[7]={0}; char lightsn6[7]={0}; char lightsn7[7]={0}; char lightsn8[7]={0}; char lightsn9[7]={0}; char lightsn10[7]={0}; char lightsn11[7]={0}; char lightsn12[7]={0}; char lightsn13[7]={0}; char lightsn14[7]={0}; char lightsn15[7]={0}; char lightsn16[7]={0}; char lightsn17[7]={0}; char lightsn18[7]={0}; char lightsn19[7]={0}; char lightsn20[7]={0}; char lightsn21[7]={0}; char lightsn22[7]={0}; char lightsn23[7]={0}; char lightsn24[7]={0}; char lightsn25[7]={0}; char lightsn26[7]={0}; char lightsn27[7]={0}; char lightsn28[7]={0}; char lightsn29[7]={0}; char lightsn30[7]={0}; int lightsnNum=0; int mqtt_port=1883; void hmacsha1_hex(char *key, char* data, char *signhex, int signhex_len); void *thread_mqtt_status_check(void *arg); void *thread_station_heartbeat(void *arg); /*================================================================================*/ 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"); } 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 enableWatchDog(){ system("echo 1 > /sys/class/gpio/export");//watchdog enable pin SGM820 system("echo 112 > /sys/class/gpio/export");//feed watchdog pin red system("echo out > /sys/class/gpio/gpio1/direction"); system("echo out > /sys/class/gpio/gpio112/direction"); system("echo 1 > /sys/class/gpio/gpio1/value"); LOG_I("enable watchdog\n"); system("echo 1 > /sys/class/gpio/gpio112/value"); } void feedWatchDog(){ while(1){ //LOG_I("feed watchdog\n"); system("echo 0 > /sys/class/gpio/gpio112/value"); usleep(100*1000); system("echo 1 > /sys/class/gpio/gpio112/value"); sleep(1); } } void report_tag(void){ while(1){ sleep(60*10); LOG_I("report_tag\n"); light_status_report(); } } 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"); system("reboot"); }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"); } } void removeFile(char *filename){ char cmd[32]={0}; sprintf(cmd,"rm %s",filename); //LOG_I("%s\n",cmd); system(cmd); } #endif void hmacsha1_hex(char *key, char* data, char *signhex, int signhex_len) { unsigned char result[256] = {0}; size_t len = sizeof(result); hmac_sha1((const uint8_t*)key, strlen(key), (const uint8_t*)data, strlen(data), result, &len); // 转换为十六进制格式 for (int i = 0; i < len && i * 2 + 1 < signhex_len; i++) { snprintf(signhex + i * 2, 3, "%02x", result[i]); } } 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 10.10.12.12",strlen("# address 10.10.12.12"),"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 10.10.12.1",strlen("# gateway 10.10.12.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 1 if(strstr(str,"d")!=NULL && strlen(str)>=27){ LOG_I("ok\n"); char *result=NULL; char *p; result=strtok_r(str,":",&p); while(result!=NULL){ if(strstr(result,"d")!=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); } result=strtok_r(NULL,",",&p); } } #else if(strstr(str,"d1")!=NULL){ buffer_to_file("savedDevSn",str,strlen(str),"wb"); } #endif } 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 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); removeSpaces(payload); strcpy(signtmp,payload); strcat(signtmp,appSecret); //LOG_I("signtmp:%s\n",signtmp); get_base64_md5_from_string(signbase64, sizeof(signbase64), signtmp, strlen(signtmp)); //LOG_I("signbase64:%s\n",signbase64); sprintf(send_request,"curl -X POST -H 'x-appKey:%s' -H 'x-datadigest:%s' -H 'Content-Type: application/json' -d '%s' %s", appKey,signbase64,payload,getDevRawPasswordUrl); LOG_I("send_request:%s\n",send_request); fp=popen(send_request,"r"); fgets(buffer,sizeof(buffer),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 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"); update_app(); } } } usleep(100*1000); } } } void update_app(void){ system("rm -fr ota"); system("mkdir ota"); char otaCmd[256]={0}; sprintf(otaCmd,"curl -o /root/ota/jd_ota.zip %s",updateUrl); system(otaCmd); sleep(15); system("unzip ota/jd_ota.zip"); system("mv jd_ota/* ota"); system("rm -fr jd_ota"); system("mv ota/start.sh /root"); sleep(1); system("reboot"); } /*================================================================================*/ void mqtt_init(){ int ret=0; char username[64] = {0}; char password[64] = {0}; char clientid[256] = {0}; char stringToSign[512] = {0}; // 待签名串 char hostip[16]={0}; struct timeval tv; // 获取当前时间戳(毫秒) gettimeofday(&tv, NULL); long timestamp = tv.tv_sec * 1000 + tv.tv_usec / 1000; // 使用实时时间戳,确保与服务器时间同步 LOG_I("%ld\n", timestamp); // 使用白名单中的设备ID char unique_device_id[32]; // 使用白名单中的设备ID strcpy(unique_device_id, stationsn); LOG_I("使用白名单设备ID: %s\n", unique_device_id); // 使用REGISTER模式进行设备注册 // 因为设备在白名单中但还没注册,需要先注册 const char* authType = MQTT_AUTH_TYPE_AUTH; char* secretKey = appSecret; // 使用ProductSecret进行注册 LOG_I("%s\n", unique_device_id); // 根据新协议格式构建ClientId: ProductKey&/DeviceClientId/SecureMode/Algorithm/Timestamp/AuthType snprintf(clientid, sizeof(clientid), "%s&/%s/%s/%s/%ld/%s", productid, unique_device_id, MQTT_SECURE_MODE, MQTT_ALGORITHM, timestamp, authType); // 根据新协议格式构建Username: /ProductKey/DeviceKey snprintf(username, sizeof(username), "/%s/%s", productid, unique_device_id); // 构建待签名串: deviceKey + deviceKey + productKey + algorithm + timestamp // 格式与Python代码保持一致: deviceKey + deviceKey + productKey + 'AUK1_MQTT_HMAC_SHA1' + timestamp char timestamp_str[32]; snprintf(timestamp_str, sizeof(timestamp_str), "%ld", timestamp); snprintf(stringToSign, sizeof(stringToSign), "%s%s%s%s%s", unique_device_id, unique_device_id, productid, MQTT_ALGORITHM, timestamp_str); // 使用HMAC-SHA1算法生成密码签名(十六进制格式) // 根据设备注册状态选择签名密钥: // - REGISTER模式:使用ProductSecret (appSecret) // - AUTH模式:使用DeviceSecret (mqttRawPassword) hmacsha1_hex(secretKey, stringToSign, password, sizeof(password)); LOG_I("=== 白名单设备注册信息 ===\n"); LOG_I("设备Key: %s\n", unique_device_id); LOG_I("设备密钥: %s\n", secretKey); LOG_I("认证模式: %s\n", authType); LOG_I("ClientId: %s\n", clientid); LOG_I("Username: %s\n", username); LOG_I("StringToSign: %s\n", stringToSign); LOG_I("Password: %s\n", password); LOG_I("时间戳: %ld\n", timestamp); LOG_I("========================\n"); mqtt_config.tracelevel=MQTTASYNC_TRACE_PROTOCOL; mqtt_config.retain=0; mqtt_config.port=mqtt_port; mqtt_config.keepalive=60; memset(mqtt_config.clientid,0,sizeof(mqtt_config.clientid)); memcpy(mqtt_config.clientid, clientid, strlen(clientid)+1); memset(mqtt_config.productcode, 0, sizeof(mqtt_config.productcode)); memcpy(mqtt_config.productcode, productid, strlen(productid)+1); memset(mqtt_config.username, 0, sizeof(mqtt_config.username)); memcpy(mqtt_config.username, username, strlen(username)+1); memset(mqtt_config.password, 0, sizeof(mqtt_config.password)); memcpy(mqtt_config.password, password, strlen(password)+1); get_ip_by_domain(hostDomain,hostip,16); LOG_I("MQTT服务器域名: %s, 解析IP: %s\n", hostDomain, hostip); // 如果DNS解析失败,使用硬编码的IP地址 if (strlen(hostip) == 0 || strcmp(hostip, "0.0.0.0") == 0) { LOG_I("DNS解析失败,使用硬编码IP地址\n"); strcpy(hostip, "103.37.154.120"); // 使用日志中看到的IP } memset(mqtt_config.host, 0, sizeof(mqtt_config.host)); memcpy(mqtt_config.host, hostip, strlen(hostip)+1); mqtt_config.MQTTVersion = 4; /* will options */ mqtt_config.will_topic = NULL; mqtt_config.will_payload = NULL; mqtt_config.will_qos = 1; 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_keycheck(void *arg){ checkOtaKey(); } void *thread_reporttag(void *arg){ report_tag(); } void *thread_mqtt(void *arg){ mqtt_init(); } void *thread_removelog(void *arg){ removeLog(); } void *thread_feed_watchdog(void *arg){ feedWatchDog(); } void *thread_readqr(void *arg){ readQrcode(); } void *thread_uart_recv_ack(void *arg){ 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){ jt_led_or_group_package_t led_ctrl={ .s.color=changecolor, .s.sound=changesound, .s.single=0, .s.flash=3, };//0xC1 11000001 flash高位 jt_led_or_group_package_t group={ .group=groupno, };//0xC1 11000001 flash高位 //jt_led_or_group_package_t stop={ // .group=0x72, //};//0xC1 11000001 flash高位 jt_group_package_t groups[1]={{groupno,led_ctrl}}; //jt_group_package_t groups_stop[2]={{0x58,stop},{0xE3,0x00}}; #if 0 uint32_t tag1=strtol(lightsn1,NULL,16); uint32_t tag2=strtol(lightsn2,NULL,16); uint32_t tag3=strtol(lightsn3,NULL,16); uint32_t tag4=strtol(lightsn4,NULL,16); uint32_t tag5=strtol(lightsn5,NULL,16); uint32_t tag6=strtol(lightsn6,NULL,16); uint32_t tag7=strtol(lightsn7,NULL,16); uint32_t tag8=strtol(lightsn8,NULL,16); uint32_t tag9=strtol(lightsn9,NULL,16); uint32_t tag10=strtol(lightsn10,NULL,16); uint32_t tag11=strtol(lightsn11,NULL,16); uint32_t tag12=strtol(lightsn12,NULL,16); uint32_t tag13=strtol(lightsn13,NULL,16); uint32_t tag14=strtol(lightsn14,NULL,16); uint32_t tag15=strtol(lightsn15,NULL,16); uint32_t tag16=strtol(lightsn16,NULL,16); uint32_t tag17=strtol(lightsn17,NULL,16); uint32_t tag18=strtol(lightsn18,NULL,16); uint32_t tag19=strtol(lightsn19,NULL,16); uint32_t tag20=strtol(lightsn20,NULL,16); uint32_t tag21=strtol(lightsn21,NULL,16); uint32_t tag22=strtol(lightsn22,NULL,16); uint32_t tag23=strtol(lightsn23,NULL,16); uint32_t tag24=strtol(lightsn24,NULL,16); uint32_t tag25=strtol(lightsn25,NULL,16); uint32_t tag26=strtol(lightsn26,NULL,16); uint32_t tag27=strtol(lightsn27,NULL,16); uint32_t tag28=strtol(lightsn28,NULL,16); uint32_t tag29=strtol(lightsn29,NULL,16); uint32_t tag30=strtol(lightsn30,NULL,16); #else //low power #if 0 uint32_t tag1=strtol("000511",NULL,16); uint32_t tag2=strtol("00051C",NULL,16); uint32_t tag3=strtol("000E99",NULL,16); uint32_t tag4=strtol("004137",NULL,16); uint32_t tag5=strtol("004348",NULL,16); uint32_t tag6=strtol("004391",NULL,16); uint32_t tag7=strtol("004DB8",NULL,16); uint32_t tag8=strtol("005966",NULL,16); uint32_t tag9=strtol("014BEE",NULL,16); uint32_t tag10=strtol("014BF0",NULL,16); #else uint32_t tag1=strtol(lightsn1,NULL,16); uint32_t tag2=strtol(lightsn2,NULL,16); uint32_t tag3=strtol(lightsn3,NULL,16); uint32_t tag4=strtol(lightsn4,NULL,16); uint32_t tag5=strtol(lightsn5,NULL,16); uint32_t tag6=strtol(lightsn6,NULL,16); uint32_t tag7=strtol(lightsn7,NULL,16); uint32_t tag8=strtol(lightsn8,NULL,16); uint32_t tag9=strtol(lightsn9,NULL,16); uint32_t tag10=strtol(lightsn10,NULL,16); #endif uint32_t tag11=strtol(lightsn11,NULL,16); uint32_t tag12=strtol(lightsn12,NULL,16); uint32_t tag13=strtol(lightsn13,NULL,16); uint32_t tag14=strtol(lightsn14,NULL,16); uint32_t tag15=strtol(lightsn15,NULL,16); uint32_t tag16=strtol(lightsn16,NULL,16); uint32_t tag17=strtol(lightsn17,NULL,16); uint32_t tag18=strtol(lightsn18,NULL,16); uint32_t tag19=strtol(lightsn19,NULL,16); uint32_t tag20=strtol(lightsn20,NULL,16); uint32_t tag21=strtol(lightsn21,NULL,16); uint32_t tag22=strtol(lightsn22,NULL,16); uint32_t tag23=strtol(lightsn23,NULL,16); uint32_t tag24=strtol(lightsn24,NULL,16); uint32_t tag25=strtol(lightsn25,NULL,16); uint32_t tag26=strtol(lightsn26,NULL,16); uint32_t tag27=strtol(lightsn27,NULL,16); uint32_t tag28=strtol(lightsn28,NULL,16); uint32_t tag29=strtol(lightsn29,NULL,16); uint32_t tag30=strtol(lightsn30,NULL,16); #endif #if 0 if(isStopBroadcast){ uart_data_send_lighton_by_group(&uartSend,groups_stop,2); isStopBroadcast=false; } #endif if(isLightOn){ jt_tag_package_t tags[30]={{(tag1>>16)&0xFF,(tag1>>8)&0xFF,(tag1)&0xFF,led_ctrl}, {(tag2>>16)&0xFF,(tag2>>8)&0xFF,(tag2)&0xFF,led_ctrl}, {(tag3>>16)&0xFF,(tag3>>8)&0xFF,(tag3)&0xFF,led_ctrl}, {(tag4>>16)&0xFF,(tag4>>8)&0xFF,(tag4)&0xFF,led_ctrl}, {(tag5>>16)&0xFF,(tag5>>8)&0xFF,(tag5)&0xFF,led_ctrl}, {(tag6>>16)&0xFF,(tag6>>8)&0xFF,(tag6)&0xFF,led_ctrl}, {(tag7>>16)&0xFF,(tag7>>8)&0xFF,(tag7)&0xFF,led_ctrl}, {(tag8>>16)&0xFF,(tag8>>8)&0xFF,(tag8)&0xFF,led_ctrl}, {(tag9>>16)&0xFF,(tag9>>8)&0xFF,(tag9)&0xFF,led_ctrl}, {(tag10>>16)&0xFF,(tag10>>8)&0xFF,(tag10)&0xFF,led_ctrl}, {(tag11>>16)&0xFF,(tag11>>8)&0xFF,(tag11)&0xFF,led_ctrl}, {(tag12>>16)&0xFF,(tag12>>8)&0xFF,(tag12)&0xFF,led_ctrl}, {(tag13>>16)&0xFF,(tag13>>8)&0xFF,(tag13)&0xFF,led_ctrl}, {(tag14>>16)&0xFF,(tag14>>8)&0xFF,(tag14)&0xFF,led_ctrl}, {(tag15>>16)&0xFF,(tag15>>8)&0xFF,(tag15)&0xFF,led_ctrl}, {(tag16>>16)&0xFF,(tag16>>8)&0xFF,(tag16)&0xFF,led_ctrl}, {(tag17>>16)&0xFF,(tag17>>8)&0xFF,(tag17)&0xFF,led_ctrl}, {(tag18>>16)&0xFF,(tag18>>8)&0xFF,(tag18)&0xFF,led_ctrl}, {(tag19>>16)&0xFF,(tag19>>8)&0xFF,(tag19)&0xFF,led_ctrl}, {(tag20>>16)&0xFF,(tag20>>8)&0xFF,(tag20)&0xFF,led_ctrl}, {(tag21>>16)&0xFF,(tag21>>8)&0xFF,(tag21)&0xFF,led_ctrl}, {(tag22>>16)&0xFF,(tag22>>8)&0xFF,(tag22)&0xFF,led_ctrl}, {(tag23>>16)&0xFF,(tag23>>8)&0xFF,(tag23)&0xFF,led_ctrl}, {(tag24>>16)&0xFF,(tag24>>8)&0xFF,(tag24)&0xFF,led_ctrl}, {(tag25>>16)&0xFF,(tag25>>8)&0xFF,(tag25)&0xFF,led_ctrl}, {(tag26>>16)&0xFF,(tag26>>8)&0xFF,(tag26)&0xFF,led_ctrl}, {(tag27>>16)&0xFF,(tag27>>8)&0xFF,(tag27)&0xFF,led_ctrl}, {(tag28>>16)&0xFF,(tag28>>8)&0xFF,(tag28)&0xFF,led_ctrl}, {(tag29>>16)&0xFF,(tag29>>8)&0xFF,(tag29)&0xFF,led_ctrl}, {(tag30>>16)&0xFF,(tag30>>8)&0xFF,(tag30)&0xFF,led_ctrl}}; uart_data_send_lighton_or_group(&uartSend,tags,lightbars_size); isLightOn=false; #if 0 isStopBroadcastBegin=false; while(1){ usleep(150*1000); if(isStopBroadcastBegin){ break; } } uart_data_send_head(&uartSend,'R',5,30/5,1);//stop broadcast by groupno isStopBroadcast=true; #endif } if(isBindTag){ jt_tag_package_t tags[30]={{(tag1>>16)&0xFF,(tag1>>8)&0xFF,(tag1)&0xFF,group}, {(tag2>>16)&0xFF,(tag2>>8)&0xFF,(tag2)&0xFF,group}, {(tag3>>16)&0xFF,(tag3>>8)&0xFF,(tag3)&0xFF,group}, {(tag4>>16)&0xFF,(tag4>>8)&0xFF,(tag4)&0xFF,group}, {(tag5>>16)&0xFF,(tag5>>8)&0xFF,(tag5)&0xFF,group}, {(tag6>>16)&0xFF,(tag6>>8)&0xFF,(tag6)&0xFF,group}, {(tag7>>16)&0xFF,(tag7>>8)&0xFF,(tag7)&0xFF,group}, {(tag8>>16)&0xFF,(tag8>>8)&0xFF,(tag8)&0xFF,group}, {(tag9>>16)&0xFF,(tag9>>8)&0xFF,(tag9)&0xFF,group}, {(tag10>>16)&0xFF,(tag10>>8)&0xFF,(tag10)&0xFF,group}, {(tag11>>16)&0xFF,(tag11>>8)&0xFF,(tag11)&0xFF,group}, {(tag12>>16)&0xFF,(tag12>>8)&0xFF,(tag12)&0xFF,group}, {(tag13>>16)&0xFF,(tag13>>8)&0xFF,(tag13)&0xFF,group}, {(tag14>>16)&0xFF,(tag14>>8)&0xFF,(tag14)&0xFF,group}, {(tag15>>16)&0xFF,(tag15>>8)&0xFF,(tag15)&0xFF,group}, {(tag16>>16)&0xFF,(tag16>>8)&0xFF,(tag16)&0xFF,group}, {(tag17>>16)&0xFF,(tag17>>8)&0xFF,(tag17)&0xFF,group}, {(tag18>>16)&0xFF,(tag18>>8)&0xFF,(tag18)&0xFF,group}, {(tag19>>16)&0xFF,(tag19>>8)&0xFF,(tag19)&0xFF,group}, {(tag20>>16)&0xFF,(tag20>>8)&0xFF,(tag20)&0xFF,group}, {(tag21>>16)&0xFF,(tag21>>8)&0xFF,(tag21)&0xFF,group}, {(tag22>>16)&0xFF,(tag22>>8)&0xFF,(tag22)&0xFF,group}, {(tag23>>16)&0xFF,(tag23>>8)&0xFF,(tag23)&0xFF,group}, {(tag24>>16)&0xFF,(tag24>>8)&0xFF,(tag24)&0xFF,group}, {(tag25>>16)&0xFF,(tag25>>8)&0xFF,(tag25)&0xFF,group}, {(tag26>>16)&0xFF,(tag26>>8)&0xFF,(tag26)&0xFF,group}, {(tag27>>16)&0xFF,(tag27>>8)&0xFF,(tag27)&0xFF,group}, {(tag28>>16)&0xFF,(tag28>>8)&0xFF,(tag28)&0xFF,group}, {(tag29>>16)&0xFF,(tag29>>8)&0xFF,(tag29)&0xFF,group}, {(tag30>>16)&0xFF,(tag30>>8)&0xFF,(tag30)&0xFF,group}}; uart_data_send_lighton_or_group(&uartSend,tags,lightbars_size); isBindTag=false; } if(isLightOnById){ uart_data_send_lighton_by_id(&uartSend,0x00,0xFF,0x00000000,0xFFFFFFFF,led_ctrl,0x0000); isLightOnById=false; } if(isLightOnByGroup){ uart_data_send_lighton_by_group(&uartSend,groups,1); isLightOnByGroup=false; } }else if(parm_ack==0x4646){ isSendComEnd=true; }else if(parm_ack==0x5252){ uart_data_receive_version(&uartSend); isSendComEnd=true; } }else{ isSendComEnd=true; } usleep(100*1000); } } void *thread_uart_recv_data(void *arg){ uint16_t parmAck; uint16_t tagCodeHead; uint32_t tagCode; uint8_t tagSignal; uint8_t totalLen; uint8_t tagFeature; uint8_t count; uint8_t batteryV; uint16_t version; uint8_t ledCtrl; uint16_t signCode; uint16_t reserve; uint32_t lableParm; while(1){ uart_data_receive_data_back(&uartRecvData,&parmAck,&tagCodeHead,&tagCode,&tagSignal,&totalLen,&tagFeature, &count,&batteryV,&version,&ledCtrl,&signCode,&reserve,&lableParm); LOG_I("recv_data:%04x,%04x,tag:%08x,%02x,%02x,%02x,%02x,battery:%02x,%04x,%02x,%04x,reserve:%04x,%08x\n", parmAck,tagCodeHead,tagCode,tagSignal,totalLen,tagFeature,count,batteryV,version,ledCtrl,signCode,reserve,lableParm); isStopBroadcastBegin=true; //sleep(2); } } void *thread_uart_recv_back(void *arg){ uint16_t parmAck; uint16_t tagCodeHead; uint32_t tagCode; uint8_t tagSignal; uint8_t totalLen; uint8_t tagFeature; uint8_t count; uint8_t batteryV; uint16_t version; uint8_t ledCtrl; uint16_t signCode; uint16_t reserve; uint32_t lableParm; while(1){ uart_data_receive_data_back(&uartRecvBack,&parmAck,&tagCodeHead,&tagCode,&tagSignal,&totalLen,&tagFeature, &count,&batteryV,&version,&ledCtrl,&signCode,&reserve,&lableParm); LOG_I("recv_back:%04x,%04x,tag:%08x,%02x,%02x,%02x,%02x,battery:%02x,%04x,%02x,%04x,reserve:%04x,%08x\n", parmAck,tagCodeHead,tagCode,tagSignal,totalLen,tagFeature,count,batteryV,version,ledCtrl,signCode,reserve,lableParm); PutDataIntoQueue(tagCode,batteryV,reserve); if(tagFeature==0xFF){ LOG_I("heart beat\n"); }else if(tagFeature==0xFD){ LOG_I("key\n"); }else if(tagFeature==0xFC){ LOG_I("broadcast parm\n"); } } } void functions_reply(char *task_id,char *msg_id){ json_object *functions = NULL; functions=json_object_new_array(); json_object *function = json_object_new_object(); json_object *out = json_object_new_object(); json_object_object_add(function, "key", json_object_new_string("relay-lightbar.control")); json_object_object_add(out, "dev-name", json_object_new_string("")); json_object_object_add(out, "task-id", json_object_new_string(task_id)); json_object_object_add(out, "code", json_object_new_int(200)); json_object_object_add(out, "desc", json_object_new_string("success")); json_object_object_add(out, "ext1", json_object_new_string("")); json_object_object_add(out, "ext2", json_object_new_string("")); json_object_object_add(function, "parameters", out); json_object_array_add(functions,function); mqtt_server_reply(stationsn,msg_id,functions); } void station_status_report(){ char myid[32]={0}; char time_buffer[16] = ""; char app_time_buffer[16] = ""; struct timeval tv; myrand(myid,19); gettimeofday(&tv, NULL); snprintf(time_buffer,sizeof(time_buffer),"%ld",tv.tv_sec*1000+tv.tv_usec); snprintf(app_time_buffer,sizeof(app_time_buffer),"%ld",tv.tv_sec*1000+tv.tv_usec); json_object *root = json_object_new_object(); json_object *arg = json_object_new_object(); json_object *app = json_object_new_object(); json_object *value = json_object_new_object(); // 构建value对象 json_object_object_add(value, "version", json_object_new_string(softwareVersion)); // 构建APP对象 json_object_object_add(app, "value", value); json_object_object_add(app, "time", json_object_new_string(app_time_buffer)); // 构建arg对象 json_object_object_add(arg, "APP", app); // 构建根对象 json_object_object_add(root, "id", json_object_new_string(myid)); json_object_object_add(root, "version", json_object_new_string("1.0")); json_object_object_add(root, "method", json_object_new_string("thing.firmware.ota.inform")); json_object_object_add(root, "arg", arg); json_object_object_add(root, "time", json_object_new_string(time_buffer)); mqtt_server_events_report(stationsn,myid,root,productid); } void light_status_report(){ LOG_I("%s:tagCount:%d\n",__func__,tagCount); if(tagCount <= 0) { return; } // 创建TaskResult根对象 json_object *task_result = json_object_new_object(); json_object *results_array = json_object_new_array(); char myid[32]={0}; char time_buffer[16] = ""; struct timeval tv; myrand(myid,19); gettimeofday(&tv, NULL); snprintf(time_buffer,sizeof(time_buffer),"%ld",tv.tv_sec*1000+tv.tv_usec/1000); // 添加TaskResult字段 json_object_object_add(task_result, "ID", json_object_new_string(stationsn)); // 使用基站ID json_object_object_add(task_result, "TotalCount", json_object_new_int(tagCount)); json_object_object_add(task_result, "SendCount", json_object_new_int(tagCount)); // 构建Results数组,每个元素是TaskItemResult for(int i=0;i>8)&0xFF); // 根据分组判断readType if(strcmp(group,"00")==0 || strcmp(group,"FF")==0){ readType = 1; // 0xFD 接触返回 }else{ readType = 2; // 0xFE 通信返回 } // 创建TaskItemResult对象 json_object *task_item = json_object_new_object(); json_object_object_add(task_item, "TagID", json_object_new_string(tagName)); json_object_object_add(task_item, "Version", json_object_new_string("1.0")); json_object_object_add(task_item, "ReadType", json_object_new_int(readType)); json_object_object_add(task_item, "RfPowerSend", json_object_new_int(-25)); // AP方发送RF功率,dBm json_object_object_add(task_item, "RfPowerRecv", json_object_new_int(-30)); // 灯条RF功率,dBm // 电池电量处理 int battery_percent = 0; if(onlyTags[i].battery>=30){ battery_percent = 100; }else if(onlyTags[i].battery>=29){ battery_percent = 90; }else if(onlyTags[i].battery>=28){ battery_percent = 70; }else if(onlyTags[i].battery>=27){ battery_percent = 60; }else if(onlyTags[i].battery>=26){ battery_percent = 50; }else if(onlyTags[i].battery>=25){ battery_percent = 40; }else if(onlyTags[i].battery>=24){ battery_percent = 30; }else{ battery_percent = 0; } json_object_object_add(task_item, "Battery", json_object_new_int(battery_percent)); // Colors RGB数组 json_object *colors = json_object_new_object(); json_object_object_add(colors, "R", json_object_new_boolean(false)); // 红色状态 json_object_object_add(colors, "G", json_object_new_boolean(false)); // 绿色状态 json_object_object_add(colors, "B", json_object_new_boolean(false)); // 蓝色状态 json_object_object_add(task_item, "Colors", colors); // Group分组号 int group_num = (int)strtol(group, NULL, 16); json_object_object_add(task_item, "Group", json_object_new_int(group_num)); json_object_array_add(results_array, task_item); } json_object_object_add(task_result, "Results", results_array); // 发送到MQTT主题 /estation/{ID}/result char topic[128] = {0}; snprintf(topic, sizeof(topic), "/estation/%s/result", stationsn); const char *json_string = json_object_to_json_string(task_result); LOG_I("Light status report JSON: %s\n", json_string); // TODO: 发送到MQTT服务器 // mqtt_publish(topic, json_string); json_object_put(task_result); // 清空标签数据 tagCount=0; memset(onlyTags,0,sizeof(onlyTags)); } void *thread_station_heartbeat(void *arg){ while(1){ sleep(20); // 20秒间隔 char local_mac[32] = {0}; char local_ip[32] = {0}; getLocalMac(local_mac); getLocalIp(local_ip); json_object *root = json_object_new_object(); json_object *estation_info = json_object_new_object(); // 添加基站心跳信息 json_object_object_add(estation_info, "ID", json_object_new_string(stationsn)); json_object_object_add(estation_info, "MAC", json_object_new_string(local_mac)); json_object_object_add(estation_info, "Alias", json_object_new_string("")); json_object_object_add(estation_info, "ClientType", json_object_new_int(2)); json_object_object_add(estation_info, "ServerAddress", json_object_new_string("")); json_object_object_add(estation_info, "Parameters", json_object_new_string("")); json_object_object_add(estation_info, "LocalIP", json_object_new_string(local_ip)); json_object_object_add(estation_info, "SubnetMask", json_object_new_string("")); json_object_object_add(estation_info, "Gateway", json_object_new_string("")); json_object_object_add(estation_info, "Heartbeat", json_object_new_int(20)); json_object_object_add(estation_info, "DummyVersion", json_object_new_string("")); json_object_object_add(estation_info, "AppVersion", json_object_new_string(softwareVersion)); json_object_object_add(estation_info, "TotalCount", json_object_new_int(0)); json_object_object_add(estation_info, "SendCount", json_object_new_int(0)); json_object_object_add(root, "eStationInfor", estation_info); const char *json_string = json_object_to_json_string(root); LOG_I("station_heartbeat:%s\n", json_string); // 发送心跳到 /estation/{ID}/heartbeat topic char topic[128] = {0}; snprintf(topic, sizeof(topic), "/estation/%s/heartbeat", stationsn); // 这里需要使用MQTT发送函数,暂时用LOG输出 LOG_I("Sending heartbeat to topic: %s\n", topic); json_object_put(root); } return NULL; } void addOnlyTag(uint32_t tagname,uint16_t battery,uint16_t reserve){ int i=0; if(tagCount==0){ jt_only_tag_t jt_only_tag = { .name=tagname, .battery=battery, .reserve=reserve, }; onlyTags[tagCount]=jt_only_tag; tagCount++; }else{ for(i=0;i 8) { // 将后8位移动到字符串开头 memmove(mqtt_parm.msg_sn, mqtt_parm.msg_sn + (tag_len - 8), 8); mqtt_parm.msg_sn[8] = '\0'; LOG_I("TagID after truncation = %s\n", mqtt_parm.msg_sn); } else if(tag_len == 0) { LOG_I("Warning: TagID is empty!\n"); } LOG_I("TagID (last 8 chars) = %s\n", mqtt_parm.msg_sn); // 解析Colors数组 get_size_from_json_string_arry_by_key(msg_items, "Colors", &colors_size); LOG_I("Colors size = %d\n", colors_size); // 默认颜色设置 changecolor = 1; // 默认蓝色 // 遍历Colors数组,找到第一个为true的颜色 for(int j = 0; j < colors_size; j++){ get_string_from_json_string_arry_by_key(msg_items,"Colors",msg_color_value,512,j); snprintf(msg_colors, sizeof(msg_colors), "{%s}", msg_color_value); LOG_I("msg_colors[%d] = %s\n", j, msg_colors); int r_enable = 0, g_enable = 0, b_enable = 0; get_int_from_json_string_by_key(msg_colors,"R",&r_enable); get_int_from_json_string_by_key(msg_colors,"G",&g_enable); get_int_from_json_string_by_key(msg_colors,"B",&b_enable); // 根据RGB组合设置颜色 if(r_enable && !g_enable && !b_enable){ changecolor = 4; // 红色 break; }else if(!r_enable && g_enable && !b_enable){ changecolor = 2; // 绿色 break; }else if(!r_enable && !g_enable && b_enable){ changecolor = 1; // 蓝色 break; }else if(r_enable && g_enable && !b_enable){ changecolor = 6; // 黄色 break; }else if(r_enable && !g_enable && b_enable){ changecolor = 5; // 紫色 break; }else if(!r_enable && g_enable && b_enable){ changecolor = 3; // 青色 break; }else if(r_enable && g_enable && b_enable){ changecolor = 7; // 白色 break; } } LOG_I("changecolor=%d\n",changecolor); // 将TagID存储到lightsn数组中(保持兼容性) if(i < 30) { char *lightsn_array[] = {lightsn1, lightsn2, lightsn3, lightsn4, lightsn5, lightsn6, lightsn7, lightsn8, lightsn9, lightsn10, lightsn11, lightsn12, lightsn13, lightsn14, lightsn15, lightsn16, lightsn17, lightsn18, lightsn19, lightsn20, lightsn21, lightsn22, lightsn23, lightsn24, lightsn25, lightsn26, lightsn27, lightsn28, lightsn29, lightsn30}; memset(lightsn_array[i], 0, 7); memcpy(lightsn_array[i], mqtt_parm.msg_sn, strlen(mqtt_parm.msg_sn)); LOG_I("lightsn[%d] = %s\n", i, lightsn_array[i]); } } // 设置lightbars_size为items_size lightbars_size = items_size; LOG_I("lightbars_size = %d\n", lightbars_size); // 根据任务类型进行处理 // 任务1:发布灯条指令 (topic: /estation/设备ID/task) // 任务2:发布基站OTA任务 (topic: /estation/设备ID/ota) // 判断任务类型:如果有Items数组且包含TagID,则为灯条任务 if(items_size > 0) { LOG_I("Processing lightbar task (task_id: lightbar)\n"); // 灯条点亮任务 lightbars_count += lightbars_size; if(lightbars_count >= 30) { // 处理超过30个灯条的情况 } else { // 正常处理 } isSendComEnd = false; isLightOnByGroup = false; isLightOnById = false; isLightOn = true; isBindTag = false; // P点灯 B绑定 &群控(不支持) *根据id点亮 uart_data_send_head(&uartSend, 'P', 5, mqtt_parm.msg_duration/5, lightbars_size); } else { LOG_I("Processing OTA task (task_id: ota)\n"); // 解析新的OTA任务JSON格式 LOG_I("OTA payload debug: %s\n", payload); LOG_I("OTA payload after cleaning: %s\n", payload); // 首先检查是否存在data数组 int data_array_size = 0; int size_check_result = get_size_from_json_string_arry_by_key(payload, "data", &data_array_size); LOG_I("Data array size check result: %d, size: %d\n", size_check_result, data_array_size); int has_data_array = (size_check_result == 0 && data_array_size > 0); if (has_data_array) { LOG_I("Found data array with %d items\n", data_array_size); // 从data数组中获取第一个对象的完整JSON字符串 char data_item[2048] = {0}; int extract_result = get_string_from_json_string_arry_by_key_unescape(payload, "data", data_item, sizeof(data_item), 0); LOG_I("Extract data array item result: %d\n", extract_result); if (extract_result == 0) { LOG_I("Found data array item: %s\n", data_item); // 构造完整的JSON对象字符串(添加花括号) char complete_json[2048] = {0}; snprintf(complete_json, sizeof(complete_json), "{%s}", data_item); LOG_I("Complete JSON object: %s\n", complete_json); // 解析data项中的各个字段 get_string_from_json_string_by_key_unescape(complete_json, "url", mqtt_parm.msg_zipPath, sizeof(mqtt_parm.msg_zipPath)); get_string_from_json_string_by_key_unescape(complete_json, "sign", mqtt_parm.msg_md5, sizeof(mqtt_parm.msg_md5)); get_string_from_json_string_by_key_unescape(complete_json, "firmware", mqtt_parm.msg_type, sizeof(mqtt_parm.msg_type)); get_string_from_json_string_by_key_unescape(complete_json, "tv", mqtt_parm.msg_version, sizeof(mqtt_parm.msg_version)); } else { LOG_I("Failed to extract data array item\n"); } } else { LOG_I("No data array found, trying legacy format\n"); // 如果没有data数组,尝试旧格式兼容 get_string_from_json_string_by_key_unescape(payload, "Firmware", mqtt_parm.msg_zipPath, sizeof(mqtt_parm.msg_zipPath)); get_string_from_json_string_by_key_unescape(payload, "MD5", mqtt_parm.msg_md5, sizeof(mqtt_parm.msg_md5)); get_string_from_json_string_by_key_unescape(payload, "Type", mqtt_parm.msg_type, sizeof(mqtt_parm.msg_type)); get_string_from_json_string_by_key_unescape(payload, "Version", mqtt_parm.msg_version, sizeof(mqtt_parm.msg_version)); } LOG_I("OTA firmware path: %s\n", mqtt_parm.msg_zipPath); LOG_I("OTA firmware MD5: %s\n", mqtt_parm.msg_md5); LOG_I("OTA firmware Type: %s\n", mqtt_parm.msg_type); LOG_I("OTA firmware Version: %s\n", mqtt_parm.msg_version); // 如果解析到了firmware路径,执行下载命令 if (strlen(mqtt_parm.msg_zipPath) > 0) { char otaCmd[1024]; sprintf(otaCmd, "curl -o /root/mt_ota.zip %s", mqtt_parm.msg_zipPath); LOG_I("Executing OTA download command: %s\n", otaCmd); // 执行下载命令 int result = system(otaCmd); if (result == 0) { LOG_I("OTA firmware download successful\n"); sleep(15); // 下载成功后执行解压和安装操作 system("unzip /root/mt_ota.zip"); system("rm -fr /root/ota"); system("mv /root/mt_ota /root/ota"); system("cp /root/ota/mt_server /tmp/mt_server_new"); LOG_I("cp /root/ota/mt_server /tmp/mt_server_new\n"); system("chmod +x /tmp/mt_server_new"); system("mv /tmp/mt_server_new /root/mt_server"); LOG_I("mv /tmp/mt_server_new /root/mt_server\n"); system("systemctl restart mt_server"); // OTA成功后重置状态 isSendComEnd = false; isLightOnByGroup = false; isLightOnById = false; isLightOn = false; isBindTag = false; } else { LOG_I("OTA firmware download failed with code: %d\n", result); // OTA失败时保持isSendComEnd为true,允许后续消息处理 isSendComEnd = true; isLightOnByGroup = false; isLightOnById = false; isLightOn = false; isBindTag = false; } } else { LOG_I("No firmware path found in OTA task\n"); // OTA解析失败时保持isSendComEnd为true,允许后续消息处理 isSendComEnd = true; isLightOnByGroup = false; isLightOnById = false; isLightOn = false; isBindTag = false; } } // 发送回复消息(如果需要) // functions_reply(mqtt_parm.msg_taskId, mqtt_parm.msg_messageId); } } 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 /sys/class/gpio/export");//pin 113 yellow system("echo out > /sys/class/gpio/gpio113/direction"); system("echo 63 > /sys/class/gpio/export");//pin 63 key system("echo in > /sys/class/gpio/gpio63/direction"); #if 0 enableWatchDog(); ret = pthread_create(&pt_watchdog,NULL,thread_feed_watchdog,NULL); if(ret!=0){ LOG_I("pthread_create watchdog fail\n"); system("reboot"); }else{ LOG_I("pthread_create watchdog success\n"); pthread_detach(pt_watchdog); } #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"); system("reboot"); }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"); system("reboot"); }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"); system("reboot"); }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"); system("reboot"); }else{ pthread_detach(pt_mqtt_recv); LOG_I("pthread_create mqtt_recv success\n"); } 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); } 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); } #if 0 ret = pthread_create(&pt_readqr,NULL,thread_readqr,NULL); if(ret!=0){ LOG_I("pthread_create readqr fail\n"); system("reboot"); }else{ LOG_I("pthread_create readqr success\n"); pthread_detach(pt_readqr); } #endif ret = pthread_create(&pt_reporttag,NULL,thread_reporttag,NULL); if(ret!=0){ LOG_I("pthread_create reporttag fail\n"); system("reboot"); }else{ LOG_I("pthread_create reporttag success\n"); pthread_detach(pt_reporttag); } ret = pthread_create(&pt_keycheck,NULL,thread_keycheck,NULL); if(ret!=0){ LOG_I("pthread_create keycheck fail\n"); system("reboot"); }else{ LOG_I("pthread_create keycheck success\n"); pthread_detach(pt_keycheck); } ret = pthread_create(&pt_station_heartbeat,NULL,thread_station_heartbeat,NULL); if(ret!=0){ LOG_I("pthread_create station_heartbeat fail\n"); system("reboot"); }else{ LOG_I("pthread_create station_heartbeat success\n"); pthread_detach(pt_station_heartbeat); } #if 0 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); } } readresult=file_to_buffer("LightEnable",&len); if(readresult!=NULL){ if(strcmp(readresult,"enable")==0){ isLightEnable=true; }else{ isLightEnable=false; } readresult=NULL; } #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); while(readresult==NULL){ readresult=file_to_buffer("savedDevSn",&len); sleep(5); LOG_I("please scan sn\n"); } strncpy(stationsn,readresult,len); trim_whitespace(stationsn); // 清理空白字符 readresult=NULL; LOG_I("saved stationsn:%s\n",stationsn); // 读取productid配置 readresult=file_to_buffer("productid",&len); if(readresult!=NULL){ memset(productid, 0, sizeof(productid)); strncpy(productid,readresult,len); trim_whitespace(productid); // 清理空白字符 readresult=NULL; LOG_I("saved productid:%s\n",productid); } else { LOG_I("use default productid:%s\n",productid); } // 读取appSecret配置 readresult=file_to_buffer("appSecret",&len); if(readresult!=NULL){ memset(appSecret, 0, sizeof(appSecret)); strncpy(appSecret,readresult,len); trim_whitespace(appSecret); // 清理空白字符 readresult=NULL; LOG_I("saved appSecret:%s\n",appSecret); } else { LOG_I("use default appSecret:%s\n",appSecret); } // 读取hostDomain配置 readresult=file_to_buffer("hostDomain",&len); if(readresult!=NULL){ memset(hostDomain, 0, sizeof(hostDomain)); strncpy(hostDomain,readresult,len); trim_whitespace(hostDomain); // 清理空白字符 readresult=NULL; LOG_I("saved hostDomain:%s\n",hostDomain); } else { LOG_I("use default hostDomain:%s\n",hostDomain); } #if 0 isSendComEnd=false; isLightOnByGroup=false; isLightOnById=false; isLightOn=true; isBindTag=false; lightbars_size=5; changecolor=4; changesound=1; groupno=1; //uart_data_send_head(&uartSend,'B',5,0,lightbars_size);//bind groupno uart_data_send_head(&uartSend,'P',5,10/5,lightbars_size);//lighton by tag //uart_data_send_head(&uartSend,'*',5,5/5,0);//lighton by id //uart_data_send_head(&uartSend,'&',5,5/5,1);//lighton by groupno //uart_data_send_head(&uartSend,'R',5,30/5,1);//stop broadcast by groupno //isStopBroadcast=true; #endif #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"); system("reboot"); }else{ pthread_detach(pt_mqtt); LOG_I("pthread_create mqtt success\n"); } #if 0 // 添加MQTT连接状态检查线程 ret = pthread_create(&pt_mqtt_status,NULL,thread_mqtt_status_check,NULL); if(ret!=0){ LOG_I("pthread_create mqtt_status_check fail\n"); }else{ pthread_detach(pt_mqtt_status); LOG_I("pthread_create mqtt_status_check success\n"); } #endif break; }else{ LOG_I("net not ready\n"); sleep(3); } } #endif while(1) { fgets(command_buffer, sizeof(command_buffer), stdin); if(execute_command(command_buffer, (command_t *)&__start_command, (&__stop_command - &__start_command)/2) < 0) { LOG_I("unsupport command!\r\n"); } } return 0; }