Skip to content

Commit

Permalink
code to send to aprs.fi
Browse files Browse the repository at this point in the history
  • Loading branch information
on4akh committed Aug 5, 2014
1 parent c0dd856 commit a779a2e
Show file tree
Hide file tree
Showing 3 changed files with 220 additions and 35 deletions.
193 changes: 193 additions & 0 deletions aprs.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
/*
* Linux DMR Master server
Copyright (C) 2014 Wim Hofman
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "master_server.h"
sqlite3 *openDatabase();
void closeDatabase();


int openAprsSock(){

int rv;
int sockfd;
struct addrinfo hints, *servinfo, *p;

memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
char ipstr[INET_ADDRSTRLEN];

syslog(LOG_NOTICE,"Opening APRS socket");
if ((rv = getaddrinfo("belgium.aprs2.net", "8080", &hints, &servinfo)) != 0) {
syslog(LOG_NOTICE,"getaddrinfo: %s\n", gai_strerror(rv));
return;
}

// loop through all the results and connect to the first we can
for(p = servinfo; p != NULL; p = p->ai_next) {
struct in_addr *addr;
struct sockaddr_in *ipv = (struct sockaddr_in *) p->ai_addr;
addr = &(ipv->sin_addr);
inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);
syslog(LOG_NOTICE,"address: %s",ipstr);
if ((sockfd = socket(p->ai_family, p->ai_socktype,p->ai_protocol)) == -1) {
syslog(LOG_NOTICE,"To able to create APRS sock");
continue;
}
if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfd);
syslog(LOG_NOTICE,"Error to connect to APRS");
continue;
}
break;
}
if (p == NULL) syslog(LOG_NOTICE,"Failed to open APRS socket");

freeaddrinfo(servinfo); // all done with this structure
}

void sendAprsBeacon(char callsign[10],char pass[6],char loc[20],char phg[7],char text[100]){
char toSend[300];
char ipstr[INET_ADDRSTRLEN];
int sockfd;

sprintf(toSend,"user %s pass %s vers DMRgate 1.0\n%s>APRS,%s,qAR,%s:!%s&%s%s",callsign,pass,callsign,callsign,callsign,loc,phg,text);
openAprsSock();
send(sockfd,toSend,strlen(toSend),0);
close(sockfd);

}

void sendAprs(struct gpsCoordinates gpsData, int radioId, struct repeater repeater){
char toSend[300];
char timeString[7];
char SQLQUERY[200];
int sockfd;
struct idInfo radioIdent = {0};
sqlite3 *dbase;
sqlite3_stmt *stmt;
unsigned char aprsCor[30];

dbase = openDatabase();
sprintf(SQLQUERY,"SELECT callsign,aprsSuffix,aprsBeacon,aprsSymbol,lastAprsTime FROM callsigns WHERE radioId = %i",radioId);
if (sqlite3_prepare_v2(dbase,SQLQUERY,-1,&stmt,0) == 0){
if (sqlite3_step(stmt) == SQLITE_ROW){
sprintf(radioIdent.callsign,"%s",sqlite3_column_text(stmt,0));
sprintf(radioIdent.aprsSuffix,"%s",sqlite3_column_text(stmt,1));
sprintf(radioIdent.aprsBeacon,"%s",sqlite3_column_text(stmt,2));
radioIdent.aprsSymbol = sqlite3_column_int(stmt,3);
radioIdent.aprsTimeStamp = sqlite3_column_int(stmt,4);
sqlite3_finalize(stmt);

}
else{
sqlite3_finalize(stmt);
syslog(LOG_NOTICE,"[%s]DMR ID %i not found in database, not sending to aprs.fi",repeater.callsign,radioId);
closeDatabase(dbase);
return;
}
}
else{
syslog(LOG_NOTICE,"[%s]Bad query %s",repeater.callsign,SQLQUERY);
closeDatabase(dbase);
return;
}

if (time(NULL) - radioIdent.aprsTimeStamp < 5){
syslog(LOG_NOTICE,"[%s]Preventing aprs.fi flooding for %s",repeater.callsign,radioIdent.callsign);
closeDatabase(dbase);
return;
}

sprintf(SQLQUERY,"UPDATE callsigns SET hasSendAprs = 1, lastAprsTime = %lu where radioId = %i",time(NULL),radioId);
sqlite3_exec(dbase,SQLQUERY,0,0,0);
closeDatabase(dbase);
sprintf(aprsCor,"%s/%s>%s/%s",gpsData.latitude,gpsData.longitude,gpsData.heading,gpsData.speed);
aprsCor[18] = radioIdent.aprsSymbol;
sprintf(toSend,"user %s pass %s vers DMRgate 1.0\n%s%s>APRS,%s,qAR,%s:!%s %s\n",repeater.callsign,repeater.aprsPass,radioIdent.callsign,radioIdent.aprsSuffix,repeater.callsign,repeater.callsign,aprsCor,radioIdent.aprsBeacon);

//sockfd = openAprsSock();
//send(sockfd,toSend,strlen(toSend),0);
//close(sockfd);
syslog(LOG_NOTICE,"[%s]Would send info to APRS network for %s [%s]",repeater.callsign,radioIdent.callsign,toSend);
}


int checkCoordinates(struct gpsCoordinates gpsData, struct repeater repeater){

regex_t regex;
int reti;



reti = regcomp(&regex, "^[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 0;
}
reti = regexec(&regex,gpsData.latitude,0,NULL,0);
if(reti == REG_NOMATCH){
syslog(LOG_NOTICE,"[%s]Corrupt latitude received",repeater.callsign);
regfree(&regex);
return 0;
}
regfree(&regex);

reti = regcomp(&regex, "^[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(&regex);
return 0;
}
reti = regexec(&regex,gpsData.longitude,0,NULL,0);
if(reti == REG_NOMATCH){
syslog(LOG_NOTICE,"[%s]Corrupt longitude received",repeater.callsign);
regfree(&regex);
return 0;
}

reti = regcomp(&regex, "^[0-9][0-9][0-9]$", 0);
if(reti){
syslog(LOG_NOTICE,"[%s]Hyt GPS decode,could not compile regex heading",repeater.callsign);
regfree(&regex);
return 0;
}
reti = regexec(&regex,gpsData.heading,0,NULL,0);
if(reti == REG_NOMATCH){
syslog(LOG_NOTICE,"[%s]Corrupt heading received",repeater.callsign);
regfree(&regex);
return 0;
}

reti = regcomp(&regex, "^[0-9.][0-9.][0-9.]$", 0);
if(reti){
syslog(LOG_NOTICE,"[%s]Hyt GPS decode,could not compile regex speed",repeater.callsign);
regfree(&regex);
return 0;
}
reti = regexec(&regex,gpsData.speed,0,NULL,0);
if(reti == REG_NOMATCH){
syslog(LOG_NOTICE,"[%s]Corrupt speed received",repeater.callsign);
regfree(&regex);
return 0;
}

regfree(&regex);
return 1;
}
8 changes: 5 additions & 3 deletions dmr.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ void delRepeater();
bool * convertToBits();
struct BPTC1969 decodeBPTC1969();
unsigned char * decodeThreeQuarterRate();
void decodeHyteraGps();
void decodeHyteraGpsTriggered();
void decodeHyteraGpsCompressed();
void decodeHyteraGpsButton();

struct allow checkTalkGroup(int dstId, int slot, int callType){
struct allow toSend = {0};
Expand Down Expand Up @@ -371,8 +373,8 @@ void *dmrListener(void *f){
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,gpsStringHyt,4) == 0) decodeHyteraGpsTriggered(srcId,repeaterList[repPos],decodedString[slot]);
if(memcmp(decodedString[slot] + 4,gpsStringButtonHyt,4) == 0) decodeHyteraGpsButton(srcId,repeaterList[repPos],decodedString[slot]);
if(memcmp(decodedString[slot] + 4,gpsCompressedStringHyt,4) == 0) decodeHyteraGpsCompressed(srcId,repeaterList[repPos],decodedString[slot]);
}
memset(decodedString[slot],0,300);
Expand Down
54 changes: 22 additions & 32 deletions hyteraDecode.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@

#include "master_server.h"
void sendAprs();
int checkCoordinates();

void decodeHyteraGps(int radioId,struct repeater repeater, unsigned char data[300]){
void decodeHyteraGpsTriggered(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);
Expand All @@ -34,38 +33,29 @@ void decodeHyteraGps(int radioId,struct repeater repeater, unsigned char data[30
memcpy(gpsData.speed,data+57,3);
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);
syslog(LOG_NOTICE,"[%s]Decoded GPS data triggered(Hytera): LAT(%s) LONG(%s) SPEED(%s) HEADING(%s)",repeater.callsign,gpsData.latitude,gpsData.longitude,gpsData.speed,gpsData.heading);

reti = regcomp(&regex, "^[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(&regex,gpsData.latitude,0,NULL,0);
if(reti == REG_NOMATCH){
syslog(LOG_NOTICE,"[%s]Corrupt latitude received",repeater.callsign);
regfree(&regex);
return;
}
regfree(&regex);

reti = regcomp(&regex, "^[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(&regex);
return;
}
reti = regexec(&regex,gpsData.longitude,0,NULL,0);
if(reti == REG_NOMATCH){
syslog(LOG_NOTICE,"[%s]Corrupt longitude received",repeater.callsign);
regfree(&regex);
return;
}
regfree(&regex);

sendAprs(gpsData,radioId,repeater);
if (checkCoordinates(gpsData,repeater) == 1) sendAprs(gpsData,radioId,repeater);
}

void decodeHyteraGpsButton(int radioId,struct repeater repeater, unsigned char data[300]){

struct gpsCoordinates gpsData = {0};

memcpy(gpsData.latitude,data+33,3);
memcpy(gpsData.latitude+3,data+38,4);
memcpy(gpsData.latitude+7,data+32,1);
memcpy(gpsData.longitude,data+45,8);
memcpy(gpsData.longitude+8,data+44,1);
memcpy(gpsData.speed,data+57,3);
memcpy(gpsData.heading,data+60,3);

syslog(LOG_NOTICE,"[%s]Decoded GPS data button(Hytera): LAT(%s) LONG(%s) SPEED(%s) HEADING(%s)",repeater.callsign,gpsData.latitude,gpsData.longitude,gpsData.speed,gpsData.heading);

if (checkCoordinates(gpsData,repeater) == 1) sendAprs(gpsData,radioId,repeater);
}


void decodeHyteraGpsCompressed(int radioId,struct repeater repeater, unsigned char data[300]){

syslog(LOG_NOTICE,"[%s]Compressed GPS data(Hytera) not decoding",repeater.callsign);
Expand Down

0 comments on commit a779a2e

Please sign in to comment.