/* * UnitProtocol.c * * Created on: 2019年11月28日 * Author: yt */ #include #include #include bool set_systime(int year, int mon, int day, int hour, int min, int sec) { int i; time_t t; struct tm _tm; struct timeval tv; _tm.tm_year = year-1900; _tm.tm_mon = mon-1; _tm.tm_mday = day; _tm.tm_hour = hour; _tm.tm_min = min; _tm.tm_sec = sec; t = mktime(&_tm); tv.tv_sec = t; tv.tv_usec = 0; if(settimeofday(&tv,(struct timezone *)0)<0){ return false; } system("hwclock -w"); chk_time(); for(i=0;i<16;i++){ if(unitShm->ThreadEnabled[i]==0x01) unitShm->ThreadUpdatetime[i] = unitShm->dataTime.Time_C; } return true; } bool chk_frame(unsigned char *data, int len) { int i,crc = 0; unsigned short dataLen; if((len>=14)&&((data[0]&0xff)==0x7e)&&((data[1]&0xff)==0x10) &&((data[len-1]&0xff)==0xe7)){ for(i=1;i<(len-2);i++) crc += (data[i]&0xff); // printf("chkframe: crc %02x-%02x\n",(crc&0xff),data[len-2]&0xff); if((data[len-2]&0xff)==(crc&0xff)){ dataLen = ((data[2]&0x00ff)<<8)|(data[3]&0x00ff); if(len==(dataLen+14)) return true; } } return false; } void mkCommCmd(unsigned char *cmd, unsigned char *data, unsigned char cmdCode, int dataLen) { int cur=0,crc=0; int i; cmd[cur++] = 0x7e; cmd[cur++] = 0x10; cmd[cur++] = ((dataLen>>8)&0xff); cmd[cur++] = dataLen&0xff; cmd[cur++] = cmdCode; cmd[cur++] = (((unitShm->dataTime.Year/1000)&0x0f)<<4) |(((unitShm->dataTime.Year%1000)/100)&0x0f); cmd[cur++] = ((((unitShm->dataTime.Year%100)/10)&0x0f)<<4) |((unitShm->dataTime.Year%10)&0x0f); cmd[cur++] = (((unitShm->dataTime.Month/10)&0x0f)<<4) |((unitShm->dataTime.Month%10)&0x0f); cmd[cur++] = (((unitShm->dataTime.Day/10)&0x0f)<<4) |((unitShm->dataTime.Day%10)&0x0f); cmd[cur++] = (((unitShm->dataTime.Hour/10)&0x0f)<<4) |((unitShm->dataTime.Hour%10)&0x0f); cmd[cur++] = (((unitShm->dataTime.Minute/10)&0x0f)<<4) |((unitShm->dataTime.Minute%10)&0x0f); cmd[cur++] = (((unitShm->dataTime.Second/10)&0x0f)<<4) |((unitShm->dataTime.Second%10)&0x0f); for(i=0;iUnitId)); int datalen = devidLen+4; data[cur++] = 0x01; data[cur++] = (devidLen>>8)&0xff; data[cur++] = devidLen&0xff; for(i=0;iUnitId[i]; data[cur] = 0x00; mkCommCmd(cmd,data,CMD,datalen); return datalen+14; } int mkDeviceIDSetRtn(unsigned char *inData, int inLen, unsigned char *cmd) { int i=0; unsigned char data[256]; unsigned char CMD = 0x83; int datalen = 1; unsigned short devidLen = ((inData[13]&0x00ff)<<8)|(inData[14]&0x00ff); if((inLen>=(devidLen+18))&&(devidLen<=32)){ for(i=0;iUnitId[i] = inData[15+i]; if(devidLen<32) unitShm->UnitId[devidLen] = 0x00; unitShm->UnSavedFalg[OFFSET_UNITID] = 0x01; data[0] = 0x01; mkCommCmd(cmd,data,CMD,datalen); return datalen+14; } return 0; } int mkTimeSetRtn(unsigned char *inData, int inLen, unsigned char *cmd) { int i=0, cur=0; unsigned char data[256]; unsigned char CMD = 0x83; int datalen = 0; bool idchk = true; unsigned short devidLen = ((inData[13]&0x00ff)<<8)|(inData[14]&0x00ff); if((inLen==(devidLen+25))&&(devidLen>0)&&(devidLen<=32)){ for(i=0;iUnitId[i]!=inData[15+i]){ idchk = false; break; } } if(idchk){ int year = ((inData[16+devidLen]>>4)&0x0f)*1000 +(inData[16+devidLen]&0x0f)*100 +((inData[17+devidLen]>>4)&0x0f)*10 +(inData[17+devidLen]&0x0f); int mon = ((inData[18+devidLen]>>4)&0x0f)*10 +(inData[18+devidLen]&0x0f); int day = ((inData[19+devidLen]>>4)&0x0f)*10 +(inData[19+devidLen]&0x0f); int hour = ((inData[20+devidLen]>>4)&0x0f)*10 +(inData[20+devidLen]&0x0f); int min = ((inData[21+devidLen]>>4)&0x0f)*10 +(inData[21+devidLen]&0x0f); int sec = ((inData[22+devidLen]>>4)&0x0f)*10 +(inData[22+devidLen]&0x0f); if(set_systime(year,mon,day,hour,min,sec)){ datalen = devidLen+4; data[cur++] = 0x0b; data[cur++] = inData[13]; data[cur++] = inData[14]; for(i=0;i0)&&(devidLen<=32)){ for(i=0;iUnitId[i]!=inData[15+i]){ idchk = false; break; } } if(idchk){ if((inData[17+devidLen]==0x01)||(inData[17+devidLen]==0x00)){ datalen = devidLen+4; data[cur++] = 0x0b; data[cur++] = inData[13]; data[cur++] = inData[14]; for(i=0;iUnSavedFalg[65535] = 0x01; else unitShm->UnSavedFalg[65534] = 0x01; return datalen+14; } } } return 0; } int mkServerQryRtn(unsigned char *inData, int inLen, unsigned char *cmd) { int i=0, cur=0; unsigned char data[256]; unsigned char CMD = 0x83; int datalen = 0; bool idchk = true; unsigned short devidLen = ((inData[13]&0x00ff)<<8)|(inData[14]&0x00ff); if((inLen==(devidLen+18))&&(devidLen>0)&&(devidLen<=32)){ for(i=0;iUnitId[i]!=inData[15+i]){ idchk = false; break; } } if(idchk){ datalen = devidLen+10; data[cur++] = 0x15; data[cur++] = (devidLen>>8)&0xff; data[cur++] = devidLen&0xff; for(i=0;iUnitId[i]; data[cur++] = 0x00; data[cur++] = (unitShm->ServerIP>>24)&0xff; data[cur++] = (unitShm->ServerIP>>16)&0xff; data[cur++] = (unitShm->ServerIP>>8)&0xff; data[cur++] = (unitShm->ServerIP&0xff); data[cur++] = (unitShm->ServerPort>>8)&0xff; data[cur++] = (unitShm->ServerPort&0xff); mkCommCmd(cmd,data,CMD,datalen); return datalen+14; } } return 0; } int mkServerSetRtn(unsigned char *inData, int inLen, unsigned char *cmd) { int i=0, cur=0; unsigned char data[256]; unsigned char CMD = 0x83; int datalen = 0; bool idchk = true; unsigned short devidLen = ((inData[13]&0x00ff)<<8)|(inData[14]&0x00ff); if((inLen==(devidLen+24))&&(devidLen>0)&&(devidLen<=32)){ for(i=0;iUnitId[i]!=inData[15+i]){ idchk = false; break; } } if(idchk){ unitShm->ServerIP = ((inData[17+devidLen]&0x000000ff)<<24) |((inData[18+devidLen]&0x000000ff)<<16) |((inData[19+devidLen]&0x000000ff)<<8) |(inData[20+devidLen]&0x000000ff); unitShm->ServerPort = ((inData[21+devidLen]&0x000000ff)<<8) |(inData[22+devidLen]&0x000000ff); unitShm->UnSavedFalg[OFFSET_SERVERSET] = 0x01; datalen = devidLen+4; data[cur++] = 0x16; data[cur++] = (devidLen>>8)&0xff; data[cur++] = devidLen&0xff; for(i=0;iUnitId[i]; data[cur++] = 0x00; mkCommCmd(cmd,data,CMD,datalen); return datalen+14; } } return 0; } int mk_ReportCmd(int idx, unsigned char *cmd) { union FC fc; int i=0, cur=0; unsigned char data[256]; unsigned char CMD = 0x03; struct tm *tm_time; int year,mon,day,hour,min,sec; int datalen = 0; int devidLen = 0; float x = 1.0; unsigned short pno = 0; if(idx>2047) return 0; pno = unitShm2->report[idx].Pno; // if(unitShm2->spoint[pno].SensorType=='L') // x = 0.001; printf("report: %s %d\n",unitShm2->spoint[pno].ServiceNo,unitShm2->report[idx].Port); devidLen = (int)(strlen(unitShm2->spoint[pno].ServiceNo))+1; if(devidLen==0) return 0; datalen = devidLen+20; data[cur++] = 0x41; data[cur++] = (idx>>8)&0xff; data[cur++] = idx&0xff; data[cur++] = (devidLen>>8)&0xff; data[cur++] = devidLen&0xff; for(i=0;i<(devidLen-1);i++) data[cur++] = unitShm2->spoint[pno].ServiceNo[i]; data[cur++] = 0x30+unitShm2->report[idx].Port; data[cur++] = 0x00; data[cur++] = 0x00; data[cur++] = unitShm2->report[idx].Type; data[cur++] = unitShm2->report[idx].Status; fc.f = unitShm2->report[idx].RealtimeValue * x; data[cur++] = fc.c[3]; data[cur++] = fc.c[2]; data[cur++] = fc.c[1]; data[cur++] = fc.c[0]; tm_time = gmtime(&(unitShm2->report[idx].UpdateTime)); year = 1900+tm_time->tm_year; mon = 1+tm_time->tm_mon; day = tm_time->tm_mday; hour = tm_time->tm_hour; min = tm_time->tm_min; sec = tm_time->tm_sec; data[cur++] = (((year/1000)&0x0f)<<4)|(((year%1000)/100)&0x0f); data[cur++] = ((((year%100)/10)&0x0f)<<4)|((year%10)&0x0f); data[cur++] = (((mon/10)&0x0f)<<4)|((mon%10)&0x0f); data[cur++] = (((day/10)&0x0f)<<4)|((day%10)&0x0f); data[cur++] = (((hour/10)&0x0f)<<4)|((hour%10)&0x0f); data[cur++] = (((min/10)&0x0f)<<4)|((min%10)&0x0f); data[cur++] = (((sec/10)&0x0f)<<4)|((sec%10)&0x0f); mkCommCmd(cmd,data,CMD,datalen); return datalen+14; } int mk_RealdataCmd(int idx, unsigned char *cmd) { union FC fc; int i=0, cur=0; int year,mon,day,hour,min,sec; unsigned char data[256]; unsigned char CMD = 0x03; int datalen = 0; int devidLen = 0; struct tm *tm_time; float x = 1.0; // if(((idx>=0)&&(idx<(int)unitShm->UnSavedFalg[OFFSET_MAXNUM+0])) // ||((idx>=256)&&(idx<(256+(int)unitShm->UnSavedFalg[OFFSET_MAXNUM+1]))) // ||((idx>=512)&&(idx<(512+(int)unitShm->UnSavedFalg[OFFSET_MAXNUM+2]))) // ||((idx>=768)&&(idx<(768+(int)unitShm->UnSavedFalg[OFFSET_MAXNUM+3])))) { // if(unitShm2->spoint[idx].SensorType=='L') // x = 0.001; devidLen = (int)(strlen(unitShm2->spoint[idx].ServiceNo))+1; if(devidLen==0) return 0; datalen = devidLen+18; data[cur++] = 0x43; data[cur++] = (devidLen>>8)&0xff; data[cur++] = devidLen&0xff; for(i=0;i<(devidLen-1);i++) data[cur++] = unitShm2->spoint[idx].ServiceNo[i]; data[cur++] = 0x31; data[cur++] = 0x00; data[cur++] = 0x00; data[cur++] = 0x00; data[cur++] = 0x00; fc.f = unitShm2->spoint[idx].CurrentLeak * x; data[cur++] = fc.c[3]; data[cur++] = fc.c[2]; data[cur++] = fc.c[1]; data[cur++] = fc.c[0]; tm_time = gmtime(&(unitShm2->spoint[idx].UpdateTime)); year = 1900+tm_time->tm_year; mon = 1+tm_time->tm_mon; day = tm_time->tm_mday; hour = tm_time->tm_hour; min = tm_time->tm_min; sec = tm_time->tm_sec; data[cur++] = (((year/1000)&0x0f)<<4)|(((year%1000)/100)&0x0f); data[cur++] = ((((year%100)/10)&0x0f)<<4)|((year%10)&0x0f); data[cur++] = (((mon/10)&0x0f)<<4)|((mon%10)&0x0f); data[cur++] = (((day/10)&0x0f)<<4)|((day%10)&0x0f); data[cur++] = (((hour/10)&0x0f)<<4)|((hour%10)&0x0f); data[cur++] = (((min/10)&0x0f)<<4)|((min%10)&0x0f); data[cur++] = (((sec/10)&0x0f)<<4)|((sec%10)&0x0f); mkCommCmd(cmd,data,CMD,datalen); return datalen+14; } return 0; } int mk_RecordCmd(int d,int n,int m, unsigned char *cmd) { union FC fc; int i=0, cur=0; unsigned char data[256]; unsigned char CMD = 0x03; struct tm *tm_time; int year,mon,day,hour,min,sec; int datalen = 0; int devidLen = 0; // int d = (idx>>15)&0x01; // int n = (idx>>10)&0x1f; // int m = idx&0x03ff; float x = 1.0; // if(idx>65535) // return 0; // if(unitShm2->spoint[m].SensorType=='L') // x = 0.001; devidLen = (int)(strlen(unitShm2->spoint[m].ServiceNo))+1; if(devidLen==0) return 0; datalen = devidLen+46; data[cur++] = 0x42; data[cur++] = (m>>8)&0xff; data[cur++] = m&0xff; data[cur++] = (devidLen>>8)&0xff; data[cur++] = devidLen&0xff; for(i=0;i<(devidLen-1);i++) data[cur++] = unitShm2->spoint[m].ServiceNo[i]; data[cur++] = 0x31; data[cur++] = 0x00; data[cur++] = 0x00; data[cur++] = unitShm2->record[d][n][m].Type; data[cur++] = unitShm2->record[d][n][m].IoValue; fc.f = unitShm2->record[d][n][m].RealtimeValue * x; data[cur++] = fc.c[3]; data[cur++] = fc.c[2]; data[cur++] = fc.c[1]; data[cur++] = fc.c[0]; fc.f = unitShm2->record[d][n][m].AveValue * x; data[cur++] = fc.c[3]; data[cur++] = fc.c[2]; data[cur++] = fc.c[1]; data[cur++] = fc.c[0]; tm_time = gmtime(&(unitShm2->record[d][n][m].UpdateTime)); year = 1900+tm_time->tm_year; mon = 1+tm_time->tm_mon; day = tm_time->tm_mday; hour = tm_time->tm_hour; min = tm_time->tm_min; sec = tm_time->tm_sec; // if(hour!=n) // return 0; data[cur++] = (((year/1000)&0x0f)<<4)|(((year%1000)/100)&0x0f); data[cur++] = ((((year%100)/10)&0x0f)<<4)|((year%10)&0x0f); data[cur++] = (((mon/10)&0x0f)<<4)|((mon%10)&0x0f); data[cur++] = (((day/10)&0x0f)<<4)|((day%10)&0x0f); data[cur++] = (((hour/10)&0x0f)<<4)|((hour%10)&0x0f); data[cur++] = (((min/10)&0x0f)<<4)|((min%10)&0x0f); data[cur++] = (((sec/10)&0x0f)<<4)|((sec%10)&0x0f); fc.f = unitShm2->record[d][n][m].MaxValue * x; data[cur++] = fc.c[3]; data[cur++] = fc.c[2]; data[cur++] = fc.c[1]; data[cur++] = fc.c[0]; tm_time = gmtime(&(unitShm2->record[d][n][m].MaxTime)); year = 1900+tm_time->tm_year; mon = 1+tm_time->tm_mon; day = tm_time->tm_mday; hour = tm_time->tm_hour; min = tm_time->tm_min; sec = tm_time->tm_sec; if(hour!=n) return 0; data[cur++] = (((year/1000)&0x0f)<<4)|(((year%1000)/100)&0x0f); data[cur++] = ((((year%100)/10)&0x0f)<<4)|((year%10)&0x0f); data[cur++] = (((mon/10)&0x0f)<<4)|((mon%10)&0x0f); data[cur++] = (((day/10)&0x0f)<<4)|((day%10)&0x0f); data[cur++] = (((hour/10)&0x0f)<<4)|((hour%10)&0x0f); data[cur++] = (((min/10)&0x0f)<<4)|((min%10)&0x0f); data[cur++] = (((sec/10)&0x0f)<<4)|((sec%10)&0x0f); fc.f = unitShm2->record[d][n][m].MinValue * x; data[cur++] = fc.c[3]; data[cur++] = fc.c[2]; data[cur++] = fc.c[1]; data[cur++] = fc.c[0]; tm_time = gmtime(&(unitShm2->record[d][n][m].MinTime)); year = 1900+tm_time->tm_year; mon = 1+tm_time->tm_mon; day = tm_time->tm_mday; hour = tm_time->tm_hour; min = tm_time->tm_min; sec = tm_time->tm_sec; if(hour!=n) return 0; data[cur++] = (((year/1000)&0x0f)<<4)|(((year%1000)/100)&0x0f); data[cur++] = ((((year%100)/10)&0x0f)<<4)|((year%10)&0x0f); data[cur++] = (((mon/10)&0x0f)<<4)|((mon%10)&0x0f); data[cur++] = (((day/10)&0x0f)<<4)|((day%10)&0x0f); data[cur++] = (((hour/10)&0x0f)<<4)|((hour%10)&0x0f); data[cur++] = (((min/10)&0x0f)<<4)|((min%10)&0x0f); data[cur++] = (((sec/10)&0x0f)<<4)|((sec%10)&0x0f); mkCommCmd(cmd,data,CMD,datalen); return datalen+14; } int chk_protocol(unsigned char *inData, int inLen, unsigned char *outData) { if(chk_frame(inData,inLen)){ if(inData[4]==0x81) return 0; else if((inLen>=14)&&(inData[4]==0x83)){ switch(inData[12]){ case 0x01: return mkDeviceIDQryRtn(outData); break; case 0x02: return mkDeviceIDSetRtn(inData,inLen,outData); break; case 0x0b: return mkTimeSetRtn(inData,inLen,outData); break; case 0x0c: return mkDevResetRtn(inData,inLen,outData); break; case 0x15: return mkServerQryRtn(inData,inLen,outData); break; case 0x16: return mkServerSetRtn(inData,inLen,outData); break; case 0x40: return 0; break; case 0x41: { int idx = ((inData[13]&0x00ff)<<8)|(inData[14]&0x00ff); unitShm2->report[idx].Send = 0x01; unitShm2->report[idx].UnSaved = 0x01; return 0; } break; case 0x42: { int idx = ((inData[13]&0x00ff)<<8)|(inData[14]&0x00ff); int d = (idx>>15)&0x01; int h = (idx>>10)&0x1f; int i = idx&0x03ff; unitShm2->record[d][h][i].Send = 0x01; unitShm2->record[d][h][i].UnSaved = 0x01; return 0; } break; default:break; } } } return 0; } int mkDeviceRegistCmd(unsigned char *cmd){ int i=0, cur=0; unsigned char data[256]; unsigned char CMD = 0x03; int datalen = 0; int IEMILen = strlen(unitShm->IMEI); int IMSILen = strlen(unitShm->IMSI); int DevLen = strlen(unitShm->UnitId); datalen = IEMILen+IMSILen+DevLen+11; data[cur++] = 0x40; data[cur++] = (IEMILen>>8)&0xff; data[cur++] = (IEMILen&0xff); for(i=0;iIMEI[i]&0xff; data[cur++] = 0x00; data[cur++] = (IMSILen>>8)&0xff; data[cur++] = (IMSILen&0xff); for(i=0;iIMSI[i]&0xff; data[cur++] = 0x00; data[cur++] = (DevLen>>8)&0xff; data[cur++] = (DevLen&0xff); for(i=0;iUnitId[i]&0xff; data[cur++] = 0x00; data[cur++] = unitShm->UnSavedFalg[OFFSET_CSQ]; mkCommCmd(cmd,data,CMD,datalen); return datalen+14; }