From c0dd856545b1fc81a4a40cef3f692b6a1944883c Mon Sep 17 00:00:00 2001 From: on4akh Date: Mon, 4 Aug 2014 18:39:05 +0200 Subject: [PATCH] code to send to aprs.fi --- dmr.c | 57 +++++++++++++++++++++++++++---------------------- hyteraDecode.c | 31 ++++++++++++++++++++++++++- main.c | 7 +++--- master_server.h | 3 ++- sqlite.c | 13 ++++++++++- 5 files changed, 79 insertions(+), 32 deletions(-) diff --git a/dmr.c b/dmr.c index 3ed4373..7f1b83f 100644 --- a/dmr.c +++ b/dmr.c @@ -234,8 +234,10 @@ void *dmrListener(void *f){ int dataBlocks[3] = {0}; unsigned char *decoded34[3]; unsigned char decodedString[3][300]; - unsigned char gpsString[4] = {0x08,0xD0,0x03,0x00}; - unsigned char gpsCompressedString[4] = {0x01,0xD0,0x03,0x00}; + + unsigned char gpsStringHyt[4] = {0x08,0xD0,0x03,0x00}; + unsigned char gpsStringButtonHyt[4] = {0x08,0xA0,0x02,0x00}; + unsigned char gpsCompressedStringHyt[4] = {0x01,0xD0,0x03,0x00}; syslog(LOG_NOTICE,"DMR thread for port %i started",baseDmrPort + repPos); sockfd=socket(AF_INET,SOCK_DGRAM,0); @@ -297,7 +299,7 @@ void *dmrListener(void *f){ sendto(sMaster.sockfd,webUserInfo,strlen(webUserInfo),0,(struct sockaddr *)&sMaster.address,sizeof(sMaster.address)); } if (dstId == echoId){ - syslog(LOG_NOTICE,"[%i-%s]Echo test started on slot %i src %i",baseDmrPort + repPos,repeaterList[repPos].callsign,slot,srcId); + syslog(LOG_NOTICE,"[%s]Echo test started on slot %i src %i",repeaterList[repPos].callsign,slot,srcId); echoTest(buffer,sockfd,repeaterList[repPos].address,srcId,repPos); repeaterList[repPos].sending[slot] = false; break; @@ -314,7 +316,7 @@ void *dmrListener(void *f){ memset(sMasterFrame+90,0,4); } dmrState[slot] = VOICE; - syslog(LOG_NOTICE,"[%i-%s]Voice call started on slot %i src %i dst %i type %i",baseDmrPort + repPos,repeaterList[repPos].callsign,slot,srcId,dstId,callType); + syslog(LOG_NOTICE,"[%s]Voice call started on slot %i src %i dst %i type %i",repeaterList[repPos].callsign,slot,srcId,dstId,callType); //break; } break; @@ -337,39 +339,42 @@ void *dmrListener(void *f){ dmrState[slot] = DATA; dataBlocks[slot] = 0; BPTC1969decode[slot] = decodeBPTC1969(bits); - syslog(LOG_NOTICE,"[%i-%s]Data header on slot %i src %i dst %i type %i appendBlocks %i",baseDmrPort + repPos,repeaterList[repPos].callsign,slot,srcId,dstId,callType,BPTC1969decode[slot].appendBlocks); + syslog(LOG_NOTICE,"[%s]Data header on slot %i src %i dst %i type %i appendBlocks %i",repeaterList[repPos].callsign,slot,srcId,dstId,callType,BPTC1969decode[slot].appendBlocks); break; } if (slotType == 0x5555 && dmrState[slot] == DATA){ // 1/2 rate data continuation - //syslog(LOG_NOTICE,"[%i-%s]1/2 rate data continuation on slot %i src %i dst %i type %i",baseDmrPort + repPos,repeaterList[repPos].callsign,slot,srcId,dstId,callType); + //syslog(LOG_NOTICE,"[%s]1/2 rate data continuation on slot %i src %i dst %i type %i",repeaterList[repPos].callsign,slot,srcId,dstId,callType); dataBlocks[slot]++; if(BPTC1969decode[slot].appendBlocks == dataBlocks[slot]){ dmrState[slot] = IDLE; dataBlocks[slot] = 0; repeaterList[repPos].sending[slot] = false; - //syslog(LOG_NOTICE,"[%i-%s]All data blocks received",baseDmrPort + repPos,repeaterList[repPos].callsign); + //syslog(LOG_NOTICE,"[%s]All data blocks received",repeaterList[repPos].callsign); } break; } if (slotType == 0x6666 && dmrState[slot] == DATA){ // 3/4 rate data continuation - syslog(LOG_NOTICE,"[%i-%s]3/4 rate data continuation on slot %i src %i dst %i type %i",baseDmrPort + repPos,repeaterList[repPos].callsign,slot,srcId,dstId,callType); + syslog(LOG_NOTICE,"[%s]3/4 rate data continuation on slot %i src %i dst %i type %i",repeaterList[repPos].callsign,slot,srcId,dstId,callType); decoded34[slot] = decodeThreeQuarterRate(bits); memcpy(decodedString[slot]+(18*dataBlocks[slot]),decoded34[slot],18); dataBlocks[slot]++; if(BPTC1969decode[slot].appendBlocks == dataBlocks[slot]){ dmrState[slot] = IDLE; - printf("String\n"); - for(ii=0;ii<(dataBlocks[slot]*18);ii++){ - printf("(%02X)%c",decodedString[slot][ii],decodedString[slot][ii]); - } - printf("\n"); + //printf("String\n"); + //for(ii=0;ii<(dataBlocks[slot]*18);ii++){ + //printf("(%02X)%c",decodedString[slot][ii],decodedString[slot][ii]); + //} + //printf("\n"); dataBlocks[slot] = 0; repeaterList[repPos].sending[slot] = false; - syslog(LOG_NOTICE,"[%i-%s]All data blocks received",baseDmrPort + repPos,repeaterList[repPos].callsign); - printf("--------------------------------------------------------------\n"); - if(memcmp(decodedString[slot] + 4,gpsString,4) == 0) decodeHyteraGps(srcId,repeaterList[repPos],decodedString[slot]); - if(memcmp(decodedString[slot] + 4,gpsCompressedString,4) == 0) decodeHyteraGpsCompressed(srcId,repeaterList[repPos],decodedString[slot]); + syslog(LOG_NOTICE,"[%s]All data blocks received",repeaterList[repPos].callsign); + //printf("--------------------------------------------------------------\n"); + if (dstId == rrsGpsId){ + if(memcmp(decodedString[slot] + 4,gpsStringHyt,4) == 0) decodeHyteraGps(srcId,repeaterList[repPos],decodedString[slot]); + if(memcmp(decodedString[slot] + 4,gpsStringButtonHyt,4) == 0) decodeHyteraGps(srcId,repeaterList[repPos],decodedString[slot]); + if(memcmp(decodedString[slot] + 4,gpsCompressedStringHyt,4) == 0) decodeHyteraGpsCompressed(srcId,repeaterList[repPos],decodedString[slot]); + } memset(decodedString[slot],0,300); } } @@ -379,8 +384,8 @@ void *dmrListener(void *f){ if (slotType == 0x2222){ //Terminator with LC dmrState[slot] = IDLE; repeaterList[repPos].sending[slot] = false; - syslog(LOG_NOTICE,"[%i-%s]Voice call ended on slot %i",baseDmrPort + repPos,repeaterList[repPos].callsign,slot); - if (block[slot] == true) syslog(LOG_NOTICE,"[%i-%s] But was blocked because of not allowed talk group",baseDmrPort + repPos,repeaterList[repPos].callsign); + syslog(LOG_NOTICE,"[%s]Voice call ended on slot %i",repeaterList[repPos].callsign,slot); + if (block[slot] == true) syslog(LOG_NOTICE,"[%s] But was blocked because of not allowed talk group",repeaterList[repPos].callsign); block[slot] = false; } break; @@ -399,7 +404,7 @@ void *dmrListener(void *f){ } } else{ - syslog(LOG_NOTICE,"[%i-%s]Incomming traffic on slot %i, but DMR not IDLE",baseDmrPort + repPos,repeaterList[repPos].callsign,slot); + syslog(LOG_NOTICE,"[%s]Incomming traffic on slot %i, but DMR not IDLE",repeaterList[repPos].callsign,slot); } } else{ @@ -416,26 +421,26 @@ void *dmrListener(void *f){ } time(&timeNow); if (repeaterList[repPos].sending[1] && dmrState[1] != IDLE){ - if (dmrState[1] == VOICE) syslog(LOG_NOTICE,"[%i-%s]Voice call ended after timeout on slot 1",baseDmrPort + repPos,repeaterList[repPos].callsign); + if (dmrState[1] == VOICE) syslog(LOG_NOTICE,"[%s]Voice call ended after timeout on slot 1",repeaterList[repPos].callsign); if (dmrState[1] == DATA){ - syslog(LOG_NOTICE,"[%i-%s]Data call ended after timeout on slot 1",baseDmrPort + repPos,repeaterList[repPos].callsign); + syslog(LOG_NOTICE,"[%s]Data call ended after timeout on slot 1",repeaterList[repPos].callsign); dataBlocks[1] = 0; } dmrState[1] = IDLE; repeaterList[repPos].sending[1] = false; block[1] = false; - syslog(LOG_NOTICE,"[%i-%s]Slot 1 IDLE",baseDmrPort + repPos,repeaterList[repPos].callsign); + syslog(LOG_NOTICE,"[%s]Slot 1 IDLE",repeaterList[repPos].callsign); } if (repeaterList[repPos].sending[2] && dmrState[2] != IDLE){ - if (dmrState[2] == VOICE) syslog(LOG_NOTICE,"[%i-%s]Voice call ended after timeout on slot 2",baseDmrPort + repPos,repeaterList[repPos].callsign); + if (dmrState[2] == VOICE) syslog(LOG_NOTICE,"[%s]Voice call ended after timeout on slot 2",repeaterList[repPos].callsign); if (dmrState[2] == DATA){ - syslog(LOG_NOTICE,"[%i-%s]Data call ended after timeout on slot 2",baseDmrPort + repPos,repeaterList[repPos].callsign); + syslog(LOG_NOTICE,"[%s]Data call ended after timeout on slot 2",repeaterList[repPos].callsign); dataBlocks[2] = 0; } dmrState[2] = IDLE; repeaterList[repPos].sending[2] = false; block[2] = false; - syslog(LOG_NOTICE,"[%i-%s]Slot 2 IDLE",baseDmrPort + repPos,repeaterList[repPos].callsign); + syslog(LOG_NOTICE,"[%s]Slot 2 IDLE",repeaterList[repPos].callsign); } if (difftime(timeNow,pingTime) > 60 && !repeaterList[repPos].sending[slot]){ syslog(LOG_NOTICE,"PING timeout on DMR port %i repeater %s, exiting thread",baseDmrPort + repPos,repeaterList[repPos].callsign); diff --git a/hyteraDecode.c b/hyteraDecode.c index 9a7da88..c7b7a5d 100644 --- a/hyteraDecode.c +++ b/hyteraDecode.c @@ -23,7 +23,8 @@ void sendAprs(); void decodeHyteraGps(int radioId,struct repeater repeater, unsigned char data[300]){ struct gpsCoordinates gpsData = {0}; - + regex_t regex; + int reti; memcpy(gpsData.latitude,data+33,3); memcpy(gpsData.latitude+3,data+38,4); @@ -34,6 +35,34 @@ void decodeHyteraGps(int radioId,struct repeater repeater, unsigned char data[30 memcpy(gpsData.heading,data+60,3); syslog(LOG_NOTICE,"[%s]Decoded GPS data(Hytera): LAT(%s) LONG(%s) SPEED(%s) HEADING(%s)",repeater.callsign,gpsData.latitude,gpsData.longitude,gpsData.speed,gpsData.heading); + + reti = regcomp(®ex, "^[0-9][0-9][0-9][0-9][.][0-9][0-9][NZ]$", 0); + if(reti){ + syslog(LOG_NOTICE,"[%s]Hyt GPS decode,could not compile regex latitude",repeater.callsign); + return; + } + reti = regexec(®ex,gpsData.latitude,0,NULL,0); + if(reti == REG_NOMATCH){ + syslog(LOG_NOTICE,"[%s]Corrupt latitude received",repeater.callsign); + regfree(®ex); + return; + } + regfree(®ex); + + reti = regcomp(®ex, "^[0-9][0-9][0-9][0-9][0-9][.][0-9][0-9][EW]$", 0); + if(reti){ + syslog(LOG_NOTICE,"[%s]Hyt GPS decode,could not compile regex longitude",repeater.callsign); + regfree(®ex); + return; + } + reti = regexec(®ex,gpsData.longitude,0,NULL,0); + if(reti == REG_NOMATCH){ + syslog(LOG_NOTICE,"[%s]Corrupt longitude received",repeater.callsign); + regfree(®ex); + return; + } + regfree(®ex); + sendAprs(gpsData,radioId,repeater); } diff --git a/main.c b/main.c index e70a2ed..de52d64 100644 --- a/main.c +++ b/main.c @@ -159,7 +159,7 @@ void delRepeater(struct sockaddr_in address){ memset(repeaterList[i].mode,0,4); memset(repeaterList[i].language,0,50); memset(repeaterList[i].geoLocation,0,20); - memset(repeaterList[i].aprsPass,0,5); + memset(repeaterList[i].aprsPass,0,6); memset(repeaterList[i].aprsBeacon,0,100); memset(repeaterList[i].aprsPHG,0,7); syslog(LOG_NOTICE,"Repeater deleted from list pos %i",i); @@ -374,7 +374,7 @@ int getMasterInfo(){ syslog(LOG_NOTICE,"sMaster info: ownName %s, ownCountryCode %s, ownRegion %s, sMasterIp %s, sMasterPort %s", master.ownName,master.ownCountryCode,master.ownRegion,master.sMasterIp,master.sMasterPort); - sprintf(SQLQUERY,"SELECT servicePort, rdacPort, dmrPort, baseDmrPort, maxRepeaters, echoId FROM master"); + sprintf(SQLQUERY,"SELECT servicePort, rdacPort, dmrPort, baseDmrPort, maxRepeaters, echoId,rrsGpsId FROM master"); if (sqlite3_prepare_v2(db,SQLQUERY,-1,&stmt,0) == 0){ if (sqlite3_step(stmt) == SQLITE_ROW){ servicePort = sqlite3_column_int(stmt,0); @@ -383,6 +383,7 @@ int getMasterInfo(){ baseDmrPort = sqlite3_column_int(stmt,3); maxRepeaters = sqlite3_column_int(stmt,4) + 1; echoId = sqlite3_column_int(stmt,5); + rrsGpsId = sqlite3_column_int(stmt,6); } else{ syslog(LOG_NOTICE,"failed to read masterInfo, no row"); @@ -396,7 +397,7 @@ int getMasterInfo(){ closeDatabase(db); return 0; } - syslog(LOG_NOTICE,"ServicePort %i rdacPort %i dmrPort %i baseDmrPort %i baseRdacPort %i maxRepeaters %i echoId %i rrsGpsId", + syslog(LOG_NOTICE,"ServicePort %i rdacPort %i dmrPort %i baseDmrPort %i baseRdacPort %i maxRepeaters %i echoId %i rrsGpsId %i", servicePort,rdacPort,dmrPort,baseDmrPort,baseRdacPort,maxRepeaters-1,echoId,rrsGpsId); if (maxRepeaters > 98){ syslog(LOG_NOTICE,"maxRepeaters exceeded 98, quiting application"); diff --git a/master_server.h b/master_server.h index 5e07cca..977a5e0 100644 --- a/master_server.h +++ b/master_server.h @@ -36,6 +36,7 @@ #include #include #include +#include struct repeater{ struct sockaddr_in address; @@ -56,7 +57,7 @@ struct repeater{ unsigned char mode[4]; unsigned char language[50]; unsigned char geoLocation[20]; - unsigned char aprsPass[5]; + unsigned char aprsPass[6]; unsigned char aprsBeacon[100]; unsigned char aprsPHG[7]; }; diff --git a/sqlite.c b/sqlite.c index 147e68f..da9376b 100644 --- a/sqlite.c +++ b/sqlite.c @@ -90,7 +90,7 @@ int initDatabase(sqlite3 *db){ bool neededToCreate = false; if (!isTableExisting(db,"master")){ - sprintf(SQLQUERY,"CREATE TABLE master (repTS1 VARCHAR(100) default '',repTS2 VARCHAR(100) default '',sMasterTS1 VARCHAR(100) default '',sMasterTS2 VARCHAR(100) default '', timeBase INTEGER default 60, servicePort int default 50000, rdacPort int default 50002,dmrPort int default 50001, baseDmrPort int default 50100, baseRdacPort int default 50200, maxRepeaters int default 20, echoId int default 9990)"); + sprintf(SQLQUERY,"CREATE TABLE master (repTS1 VARCHAR(100) default '',repTS2 VARCHAR(100) default '',sMasterTS1 VARCHAR(100) default '',sMasterTS2 VARCHAR(100) default '', timeBase INTEGER default 60, servicePort int default 50000, rdacPort int default 50002,dmrPort int default 50001, baseDmrPort int default 50100, baseRdacPort int default 50200, maxRepeaters int default 20, echoId int default 9990, rrsGpsId in default 500)"); if (sqlite3_exec(db,SQLQUERY,0,0,0) == 0){ neededToCreate = true; sprintf(SQLQUERY,"INSERT INTO master (repTS1) VALUES ('')"); @@ -162,6 +162,17 @@ int initDatabase(sqlite3 *db){ } } + if (!isFieldExisting(db,"master","rrsGpsId")){ + sprintf(SQLQUERY,"ALTER TABLE master ADD COLUMN rrsGpsId int default 500"); + if (sqlite3_exec(db,SQLQUERY,0,0,0) == 0){ + syslog(LOG_NOTICE,"field rrsGpsId in master created"); + } + else{ + syslog(LOG_NOTICE,"Database error: %s",sqlite3_errmsg(db)); + return 0; + } + } + if (!isFieldExisting(db,"repeaters","geoLocation")){ sprintf(SQLQUERY,"ALTER TABLE repeaters ADD COLUMN geoLocation varchar(20) default ''"); if (sqlite3_exec(db,SQLQUERY,0,0,0) == 0){