added portmap[] for mobile op

pull/1/head
Tom Early 8 years ago
parent 19c97203a5
commit 016a5acdb6

@ -1,3 +1,22 @@
/*
* Copyright (C) 2010 by Scott Lawson KI4LKF
* Copyright (C) 2017-2018 by Thomas Early N7TAE
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#pragma once #pragma once
#include <string> #include <string>
@ -10,7 +29,7 @@ std::vector<std::string> stringTokenizer(const std::string &str);
int getAllIPV4Addresses(const char *name, unsigned short port, unsigned int *num, struct sockaddr_in *addr, unsigned int max_addr); int getAllIPV4Addresses(const char *name, unsigned short port, unsigned int *num, struct sockaddr_in *addr, unsigned int max_addr);
void safeStringCopy (char * dest, const char * src, unsigned int buf_size); void safeStringCopy(char * dest, const char * src, unsigned int buf_size);
char *getCurrentTime(void); char *getCurrentTime(void);

@ -1,8 +1,8 @@
# g2_ircddb Configuration # g2_ircddb Configuration
ircddb = { ircddb = {
login = "CHANGEME!!!!"; # login callsign for the ircDDB network login = "CHANGEME!!!!"; # login callsign for the ircDDB network
# host = "rr.openquad.net" # other include group1-irc.ircddb.net # host = "rr.openquad.net" # other include group1-irc.ircddb.net
# port = 9007 # not a good idea to change! # port = 9007 # not a good idea to change!
# password = "1111111111111" # not needed for Openquad # password = "1111111111111" # not needed for Openquad
} }
@ -36,7 +36,7 @@ module = {
# a DVRPTR connected to a 70cm radio is shown in this example # a DVRPTR connected to a 70cm radio is shown in this example
# type must be defined. This is how the dvrptr program finds the config params. # type must be defined. This is how the dvrptr program finds the config params.
# type = "dvrptr" type = "dvrptr"
# If you operate in "restriction mode", set callsign equal to your personal callsign # If you operate in "restriction mode", set callsign equal to your personal callsign
# Otherwise do not set callsign and we will use ircddb.username # Otherwise do not set callsign and we will use ircddb.username
@ -98,9 +98,8 @@ module = {
# If you don't know what it is, run the program and look in the log file! # If you don't know what it is, run the program and look in the log file!
# serial_number = "00.00.00.00" # serial_number = "00.00.00.00"
# the dvrptr program runs here, leave the commented out unless you know what you are doing! # internal_ip = "0.0.0.0" # the dvrptr address, usually leave this alone
# internal_ip = "0.0.0.0" # port = 19999 # module defaults: A=20000, B=19999, C=19998
# port = 19999 # default for mod b
# Some settings for your DVRPTR modem (see DVRPTR V1 manual for more info). # Some settings for your DVRPTR modem (see DVRPTR V1 manual for more info).
# rf_rx_level = 80 # rf_rx_level = 80
@ -157,7 +156,7 @@ module = {
# a 2m DVAP is shown as an example # a 2m DVAP is shown as an example
# type must be defined. This is how the dvap_rptr program finds the config params. # type must be defined. This is how the dvap_rptr program finds the config params.
# type = "dvap" type = "dvap"
# If you operate in "restriction mode", set RPTR equal to your personal callsign # If you operate in "restriction mode", set RPTR equal to your personal callsign
# Otherwise do not set callsign and it will use ircddb.username # Otherwise do not set callsign and it will use ircddb.username
@ -208,8 +207,8 @@ module = {
# desc1 = "" # desc1 = ""
# desc2 = "" # desc2 = ""
# the url of your repeater, 80 chars max, defaults to "github.com/n7tae/g2_ircddb # the url of your repeater, 80 chars max
# url = "" # 80 char max, defaults to "github.com/n7tae/g2_ircddb # url = "github.com/n7tae/g2_ircddb"
# where other g2 programs find this repeater software # where other g2 programs find this repeater software
# ip = "127.0.0.1" # where is the device running? must be a "dotted number" # ip = "127.0.0.1" # where is the device running? must be a "dotted number"
@ -225,7 +224,7 @@ module = {
log = { log = {
# debuging and extra logging switches # debuging and extra logging switches
# qso = true # QSO info goes into the log # qso = false # QSO info goes into the log
# irc = false # IRC debug info # irc = false # IRC debug info
# dtmf = false # DTMF debug info # dtmf = false # DTMF debug info
} }
@ -251,7 +250,7 @@ g2_link = {
# xrf_port = 30001 # port for XRF linking, don't change # xrf_port = 30001 # port for XRF linking, don't change
# dcs_port = 30051 # port for DCS linking, don't change # dcs_port = 30051 # port for DCS linking, don't change
# announce = true # do link, unlink, etc. announcements # announce = true # do link, unlink, etc. announcements
# acknowledge = true # sent text acknowledgement on key-up # acknowledge = true # send text acknowledgement on key-up
# max_dongles = 5 # maximum number of linked hotspots # max_dongles = 5 # maximum number of linked hotspots
} }

@ -1,7 +1,6 @@
/* /*
* Copyright (C) 2010 by Scott Lawson KI4LKF * Copyright (C) 2010 by Scott Lawson KI4LKF
* * Copyright (C) 2017-2018 by Thomas Early N7TAE
* Copyright 2017-2018 by Thomas Early N7TAE
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -18,7 +17,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* by KI4LKF, N7TAE */ /* by KI4LKF, N7TAE */
/* /*
g2_ircddb is a dstar G2 gateway, using irc routing g2_ircddb is a dstar G2 gateway, using irc routing
@ -323,7 +321,7 @@ bool CG2_ircddb::read_config(char *cfgFile)
get_value(cfg, "g2_link.port", g2_link.port, 16000, 65535, 18997); get_value(cfg, "g2_link.port", g2_link.port, 16000, 65535, 18997);
get_value(cfg, "log.qso", bool_qso_details, true); get_value(cfg, "log.qso", bool_qso_details, false);
get_value(cfg, "log.irc", bool_irc_debug, false); get_value(cfg, "log.irc", bool_irc_debug, false);
@ -504,9 +502,6 @@ void CG2_ircddb::GetIRCDataThread()
/* return codes: 0=OK(found it), 1=TRY AGAIN, 2=FAILED(bad data) */ /* return codes: 0=OK(found it), 1=TRY AGAIN, 2=FAILED(bad data) */
int CG2_ircddb::get_yrcall_rptr_from_cache(char *call, char *arearp_cs, char *zonerp_cs, char *mod, char *ip, char RoU) int CG2_ircddb::get_yrcall_rptr_from_cache(char *call, char *arearp_cs, char *zonerp_cs, char *mod, char *ip, char RoU)
{ {
std::map<std::string, std::string>::iterator user_pos = user2rptr_map.end();
std::map<std::string, std::string>::iterator rptr_pos = rptr2gwy_map.end();
std::map<std::string, std::string>::iterator gwy_pos = gwy2ip_map.end();
char temp[CALL_SIZE + 1]; char temp[CALL_SIZE + 1];
memset(arearp_cs, ' ', CALL_SIZE); memset(arearp_cs, ' ', CALL_SIZE);
@ -517,7 +512,7 @@ int CG2_ircddb::get_yrcall_rptr_from_cache(char *call, char *arearp_cs, char *zo
/* find the user in the CACHE */ /* find the user in the CACHE */
if (RoU == 'U') { if (RoU == 'U') {
user_pos = user2rptr_map.find(call); auto user_pos = user2rptr_map.find(call);
if (user_pos != user2rptr_map.end()) { if (user_pos != user2rptr_map.end()) {
memcpy(arearp_cs, user_pos->second.c_str(), 7); memcpy(arearp_cs, user_pos->second.c_str(), 7);
*mod = user_pos->second.c_str()[7]; *mod = user_pos->second.c_str()[7];
@ -540,14 +535,14 @@ int CG2_ircddb::get_yrcall_rptr_from_cache(char *call, char *arearp_cs, char *zo
temp[7] = *mod; temp[7] = *mod;
temp[CALL_SIZE] = '\0'; temp[CALL_SIZE] = '\0';
rptr_pos = rptr2gwy_map.find(temp); auto rptr_pos = rptr2gwy_map.find(temp);
if (rptr_pos != rptr2gwy_map.end()) { if (rptr_pos != rptr2gwy_map.end()) {
memcpy(zonerp_cs, rptr_pos->second.c_str(), CALL_SIZE); memcpy(zonerp_cs, rptr_pos->second.c_str(), CALL_SIZE);
zonerp_cs[CALL_SIZE] = '\0'; zonerp_cs[CALL_SIZE] = '\0';
gwy_pos = gwy2ip_map.find(zonerp_cs); auto gwy_pos = gwy2ip_map.find(zonerp_cs);
if (gwy_pos != gwy2ip_map.end()) { if (gwy_pos != gwy2ip_map.end()) {
strncpy(ip, gwy_pos->second.c_str(),IP_SIZE); strncpy(ip, gwy_pos->second.c_str(), IP_SIZE);
ip[IP_SIZE] = '\0'; ip[IP_SIZE] = '\0';
return 0; return 0;
} else { } else {
@ -604,7 +599,7 @@ bool CG2_ircddb::get_yrcall_rptr(char *call, char *arearp_cs, char *zonerp_cs, c
} }
/* run the main loop for g2_ircddb */ /* run the main loop for g2_ircddb */
void CG2_ircddb::runit() void CG2_ircddb::process()
{ {
SDSVT g2buf; SDSVT g2buf;
fd_set fdset; fd_set fdset;
@ -632,9 +627,6 @@ void CG2_ircddb::runit()
unsigned char tmp_txt[3]; unsigned char tmp_txt[3];
/* END: TEXT crap */ /* END: TEXT crap */
//int ber_data[3];
//int ber_errs;
int max_nfds = 0; int max_nfds = 0;
dstar_dv_init(); dstar_dv_init();
@ -800,14 +792,23 @@ void CG2_ircddb::runit()
socklen_t fromlen = sizeof(struct sockaddr_in); socklen_t fromlen = sizeof(struct sockaddr_in);
int g2buflen = recvfrom(g2_sock, g2buf.title, 56, 0, (struct sockaddr *)&fromDst4, &fromlen); int g2buflen = recvfrom(g2_sock, g2buf.title, 56, 0, (struct sockaddr *)&fromDst4, &fromlen);
// save incoming port for mobile systems
if (portmap.end() == portmap.find(fromDst4.sin_addr.s_addr))
traceit("New g2 contact at %s on port %u\n", inet_ntoa(fromDst4.sin_addr), ntohs(fromDst4.sin_port));
else {
if (fromDst4.sin_port != portmap[fromDst4.sin_addr.s_addr])
traceit("New g2 port from %s is now %u\n", inet_ntoa(fromDst4.sin_addr), ntohs(fromDst4.sin_port));
}
portmap[fromDst4.sin_addr.s_addr] = ntohs(fromDst4.sin_port);
if ( ((g2buflen == 56) || (g2buflen == 27)) && if ( ((g2buflen == 56) || (g2buflen == 27)) &&
(0==memcmp(g2buf.title, "DSVT", 4)) && (0==memcmp(g2buf.title, "DSVT", 4)) &&
((g2buf.config == 0x10) || (g2buf.config == 0x20)) && /* header or voiceframe */ ((g2buf.config == 0x10) || (g2buf.config == 0x20)) && /* header or voiceframe */
(g2buf.id == 0x20)) { /* voice type */ (g2buf.id == 0x20)) { /* voice type */
if (g2buflen == 56) { if (g2buflen == 56) {
// Find out the local repeater module IP/port // Find out the local repeater module IP/port to send the data to
// to send the data to
int i = g2buf.hdr.rpt1[7] - 'A'; int i = g2buf.hdr.rpt1[7] - 'A';
/* valid repeater module? */ /* valid repeater module? */
@ -822,13 +823,13 @@ void CG2_ircddb::runit()
(g2buf.hdr.flag[0] == 0x28) || (g2buf.hdr.flag[0] == 0x28) ||
(g2buf.hdr.flag[0] == 0x40))) { (g2buf.hdr.flag[0] == 0x40))) {
if (bool_qso_details) if (bool_qso_details)
traceit("START from g2: streamID=%04x, flags=%02x:%02x:%02x, my=%.8s, sfx=%.4s, ur=%.8s, rpt1=%.8s, rpt2=%.8s, %d bytes fromIP=%s\n", traceit("START from g2: streamID=%04x, flags=%02x:%02x:%02x, my=%.8s, sfx=%.4s, ur=%.8s, rpt1=%.8s, rpt2=%.8s, %d bytes fromIP=%s and port %u\n",
g2buf.streamid, g2buf.streamid,
g2buf.hdr.flag[0], g2buf.hdr.flag[1], g2buf.hdr.flag[2], g2buf.hdr.flag[0], g2buf.hdr.flag[1], g2buf.hdr.flag[2],
g2buf.hdr.mycall, g2buf.hdr.mycall,
g2buf.hdr.sfx, g2buf.hdr.urcall, g2buf.hdr.sfx, g2buf.hdr.urcall,
g2buf.hdr.rpt1, g2buf.hdr.rpt2, g2buf.hdr.rpt1, g2buf.hdr.rpt2,
g2buflen, inet_ntoa(fromDst4.sin_addr)); g2buflen, inet_ntoa(fromDst4.sin_addr), ntohs(fromDst4.sin_port));
memcpy(rptrbuf.pkt_id, "DSTR", 4); memcpy(rptrbuf.pkt_id, "DSTR", 4);
rptrbuf.counter = toRptr[i].G2_COUNTER; rptrbuf.counter = toRptr[i].G2_COUNTER;
@ -860,8 +861,7 @@ void CG2_ircddb::runit()
} else { } else {
if (g2buf.counter & 0x40) { if (g2buf.counter & 0x40) {
if (bool_qso_details) if (bool_qso_details)
traceit("END from g2: streamID=%04x, %d bytes from IP=%s\n", traceit("END from g2: streamID=%04x, %d bytes from IP=%s\n", g2buf.streamid, g2buflen,inet_ntoa(fromDst4.sin_addr));
g2buf.streamid, g2buflen,inet_ntoa(fromDst4.sin_addr));
} }
/* find out which repeater module to send the data to */ /* find out which repeater module to send the data to */
@ -1116,12 +1116,15 @@ void CG2_ircddb::runit()
bool result = get_yrcall_rptr(temp_radio_user, arearp_cs, zonerp_cs, &temp_mod, ip, 'R'); bool result = get_yrcall_rptr(temp_radio_user, arearp_cs, zonerp_cs, &temp_mod, ip, 'R');
if (result) { /* it is a repeater */ if (result) { /* it is a repeater */
uint32_t address;
/* set the destination */ /* set the destination */
to_remote_g2[i].streamid = rptrbuf.vpkt.streamid; to_remote_g2[i].streamid = rptrbuf.vpkt.streamid;
memset(&to_remote_g2[i].toDst4, 0, sizeof(struct sockaddr_in)); memset(&to_remote_g2[i].toDst4, 0, sizeof(struct sockaddr_in));
to_remote_g2[i].toDst4.sin_family = AF_INET; to_remote_g2[i].toDst4.sin_family = AF_INET;
to_remote_g2[i].toDst4.sin_port = htons(g2_external.port); to_remote_g2[i].toDst4.sin_addr.s_addr = address = inet_addr(ip);
to_remote_g2[i].toDst4.sin_addr.s_addr = inet_addr(ip); // if the address is in the portmap, we'll use its port instead of the default port
auto theAddress = portmap.find(address);
to_remote_g2[i].toDst4.sin_port = htons((theAddress==portmap.end()) ? g2_external.port : theAddress->second);
memcpy(g2buf.title, "DSVT", 4); memcpy(g2buf.title, "DSVT", 4);
g2buf.config = 0x10; g2buf.config = 0x10;
@ -1145,19 +1148,17 @@ void CG2_ircddb::runit()
/* set PFCS */ /* set PFCS */
calcPFCS(g2buf.title, 56); calcPFCS(g2buf.title, 56);
/* // The remote repeater has been set, lets fill in the dest_rptr
The remote repeater has been set, lets fill in the dest_rptr // so that later we can send that to the LIVE web site
so that later we can send that to the LIVE web site
*/
memcpy(band_txt[i].dest_rptr, g2buf.hdr.rpt1, 8); memcpy(band_txt[i].dest_rptr, g2buf.hdr.rpt1, 8);
band_txt[i].dest_rptr[CALL_SIZE] = '\0'; band_txt[i].dest_rptr[CALL_SIZE] = '\0';
/* send to remote gateway */ // send to remote gateway
for (int j=0; j<5; j++) for (int j=0; j<5; j++)
sendto(g2_sock, g2buf.title, 56, 0, (struct sockaddr *)&(to_remote_g2[i].toDst4), sizeof(struct sockaddr_in)); sendto(g2_sock, g2buf.title, 56, 0, (struct sockaddr *)&(to_remote_g2[i].toDst4), sizeof(struct sockaddr_in));
traceit("Routing to IP=%s, streamID=%04x, my=%.8s, sfx=%.4s, ur=%.8s, rpt1=%.8s, rpt2=%.8s, %d bytes\n", traceit("Routing to IP=%s port=%u, streamID=%04x, my=%.8s, sfx=%.4s, ur=%.8s, rpt1=%.8s, rpt2=%.8s, %d bytes\n",
inet_ntoa(to_remote_g2[i].toDst4.sin_addr), inet_ntoa(to_remote_g2[i].toDst4.sin_addr), ntohs(to_remote_g2[i].toDst4.sin_port),
g2buf.streamid, g2buf.hdr.mycall, g2buf.streamid, g2buf.hdr.mycall,
g2buf.hdr.sfx, g2buf.hdr.urcall, g2buf.hdr.sfx, g2buf.hdr.urcall,
g2buf.hdr.rpt1, &g2buf.hdr.rpt2, g2buf.hdr.rpt1, &g2buf.hdr.rpt2,
@ -1195,12 +1196,15 @@ void CG2_ircddb::runit()
if (i>=0 && i<3) { if (i>=0 && i<3) {
/* one radio user on a repeater module at a time */ /* one radio user on a repeater module at a time */
if (to_remote_g2[i].toDst4.sin_addr.s_addr == 0) { if (to_remote_g2[i].toDst4.sin_addr.s_addr == 0) {
uint32_t address;
/* set the destination */ /* set the destination */
to_remote_g2[i].streamid = rptrbuf.vpkt.streamid; to_remote_g2[i].streamid = rptrbuf.vpkt.streamid;
memset(&to_remote_g2[i].toDst4, 0, sizeof(struct sockaddr_in)); memset(&to_remote_g2[i].toDst4, 0, sizeof(struct sockaddr_in));
to_remote_g2[i].toDst4.sin_family = AF_INET; to_remote_g2[i].toDst4.sin_family = AF_INET;
to_remote_g2[i].toDst4.sin_port = htons(g2_external.port); to_remote_g2[i].toDst4.sin_addr.s_addr = address = inet_addr(ip);
to_remote_g2[i].toDst4.sin_addr.s_addr = inet_addr(ip); // if the address is in the portmap, we'll use its port instead of the default
auto theAddress = portmap.find(address);
to_remote_g2[i].toDst4.sin_port = htons((theAddress==portmap.end())? g2_external.port : theAddress->second);
memcpy(g2buf.title, "DSVT", 4); memcpy(g2buf.title, "DSVT", 4);
g2buf.config = 0x10; g2buf.config = 0x10;
@ -1230,8 +1234,8 @@ void CG2_ircddb::runit()
for (int j=0; j<5; j++) for (int j=0; j<5; j++)
sendto(g2_sock, g2buf.title, 56, 0, (struct sockaddr *)&(to_remote_g2[i].toDst4), sizeof(struct sockaddr_in)); sendto(g2_sock, g2buf.title, 56, 0, (struct sockaddr *)&(to_remote_g2[i].toDst4), sizeof(struct sockaddr_in));
traceit("Routing to IP=%s, streamID=%04x, my=%.8s, sfx=%.4s, ur=%.8s, rpt1=%.8s, rpt2=%.8s, %d bytes\n", traceit("Routing to IP=%s, port=%u, streamID=%04x, my=%.8s, sfx=%.4s, ur=%.8s, rpt1=%.8s, rpt2=%.8s, %d bytes\n",
inet_ntoa(to_remote_g2[i].toDst4.sin_addr), inet_ntoa(to_remote_g2[i].toDst4.sin_addr), ntohs(to_remote_g2[i].toDst4.sin_port),
g2buf.streamid, g2buf.hdr.mycall, g2buf.streamid, g2buf.hdr.mycall,
g2buf.hdr.sfx, g2buf.hdr.urcall, g2buf.hdr.sfx, g2buf.hdr.urcall,
g2buf.hdr.rpt1, g2buf.hdr.rpt2, g2buf.hdr.rpt1, g2buf.hdr.rpt2,
@ -1913,7 +1917,7 @@ void CG2_ircddb::runit()
/* aprs processing */ /* aprs processing */
if (bool_send_aprs) if (bool_send_aprs)
// streamID seq audio+text size // streamID seq audio+text size
aprs->ProcessText(rptrbuf.vpkt.streamid, rptrbuf.vpkt.ctrl, rptrbuf.vpkt.vasd.voice, (recvlen == 29)?12:15); aprs->ProcessText(rptrbuf.vpkt.streamid, rptrbuf.vpkt.ctrl, rptrbuf.vpkt.vasd.voice, (recvlen == 29)?12:15);
for (int i=0; i<3; i++) { for (int i=0; i<3; i++) {
@ -1921,13 +1925,17 @@ void CG2_ircddb::runit()
if (to_remote_g2[i].streamid == rptrbuf.vpkt.streamid) { if (to_remote_g2[i].streamid == rptrbuf.vpkt.streamid) {
memcpy(g2buf.title, "DSVT", 4); memcpy(g2buf.title, "DSVT", 4);
g2buf.config = 0x20; g2buf.config = 0x20;
g2buf.flaga[0] = g2buf.flaga[1] = g2buf.flaga[2] = 0x00; g2buf.flaga[0] = g2buf.flaga[1] = g2buf.flaga[2] = 0;
memcpy(&g2buf.id, &rptrbuf.vpkt.icm_id, 7); memcpy(&g2buf.id, &rptrbuf.vpkt.icm_id, 7);
if (recvlen == 29) if (recvlen == 29)
memcpy(g2buf.vasd.voice, rptrbuf.vpkt.vasd.voice, 12); memcpy(g2buf.vasd.voice, rptrbuf.vpkt.vasd.voice, 12);
else else
memcpy(g2buf.vasd.voice, rptrbuf.vpkt.vasd1.voice, 12); memcpy(g2buf.vasd.voice, rptrbuf.vpkt.vasd1.voice, 12);
uint32_t address = to_remote_g2[i].toDst4.sin_addr.s_addr;
auto theAddress = portmap.find(address);
if (theAddress != portmap.end())
to_remote_g2[i].toDst4.sin_port = htons(theAddress->second);
sendto(g2_sock, g2buf.title, 27, 0, (struct sockaddr *)&(to_remote_g2[i].toDst4), sizeof(struct sockaddr_in)); sendto(g2_sock, g2buf.title, 27, 0, (struct sockaddr *)&(to_remote_g2[i].toDst4), sizeof(struct sockaddr_in));
time(&(to_remote_g2[i].last_time)); time(&(to_remote_g2[i].last_time));
@ -2836,6 +2844,6 @@ int main(int argc, char **argv)
CG2_ircddb g2; CG2_ircddb g2;
if (g2.init(argv[1])) if (g2.init(argv[1]))
return 1; return 1;
g2.runit(); g2.process();
traceit("Leaving processing loop...\n"); traceit("Leaving processing loop...\n");
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2018 by Thomas Early N7TAE * Copyright (C) 2018 by Thomas Early N7TAE
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -92,6 +92,8 @@ private:
int play_wait, play_delay, echotest_rec_timeout, voicemail_rec_timeout, from_remote_g2_timeout, from_local_rptr_timeout, dtmf_digit; int play_wait, play_delay, echotest_rec_timeout, voicemail_rec_timeout, from_remote_g2_timeout, from_local_rptr_timeout, dtmf_digit;
std::map <uint32_t, uint16_t> portmap;
// data needed for aprs login and aprs beacon // data needed for aprs login and aprs beacon
// RPTR defined in aprs.h // RPTR defined in aprs.h
SRPTR rptr; SRPTR rptr;
@ -167,6 +169,6 @@ private:
bool validate_csum(SBANDTXT &bt, bool is_gps); bool validate_csum(SBANDTXT &bt, bool is_gps);
public: public:
void runit(); void process();
int init(char *cfgfile); int init(char *cfgfile);
}; };

@ -62,12 +62,6 @@ using namespace libconfig;
#define QUERY_SIZE 56 #define QUERY_SIZE 56
#define MAXHOSTNAMELEN 64 #define MAXHOSTNAMELEN 64
#define TIMEOUT 50 #define TIMEOUT 50
#define LINK_CODE 'L'
#define UNLINK_CODE 'U'
#define INFO_CODE 'I'
#define EXEC_CODE 'X'
#define DONGLE_CODE 'D'
#define FILE_REFRESH_GWYS_CODE 'F'
/* configuration data */ /* configuration data */
static std::string login_call; static std::string login_call;
@ -1094,13 +1088,10 @@ static void g2link(char from_mod, char *call, char to_mod)
strcpy(to_remote_g2[i].to_call, call); strcpy(to_remote_g2[i].to_call, call);
to_remote_g2[i].to_mod = to_mod; to_remote_g2[i].to_mod = to_mod;
if ((memcmp(call, "REF", 3) == 0) || if ((memcmp(call, "REF", 3) == 0) || (memcmp(call, "DCS", 3) == 0)) {
(memcmp(call, "DCS", 3) == 0)) {
for (counter = 0; counter < 3; counter++) { for (counter = 0; counter < 3; counter++) {
if (counter != i) { if (counter != i) {
if ( (to_remote_g2[counter].to_call[0] != '\0') && if ('\0'!=to_remote_g2[counter].to_call[0] && !strcmp(to_remote_g2[counter].to_call,to_remote_g2[i].to_call) && to_remote_g2[counter].to_mod==to_remote_g2[i].to_mod)
(strcmp(to_remote_g2[counter].to_call,to_remote_g2[i].to_call) == 0) &&
(to_remote_g2[counter].to_mod == to_remote_g2[i].to_mod) )
break; break;
} }
} }
@ -1108,11 +1099,7 @@ static void g2link(char from_mod, char *call, char to_mod)
to_remote_g2[i].to_mod = ' '; to_remote_g2[i].to_mod = ' ';
if (counter < 3) { if (counter < 3) {
traceit("Another mod(%c) is already linked to %s %c\n", traceit("Another mod(%c) is already linked to %s %c\n", to_remote_g2[counter].from_mod, to_remote_g2[counter].to_call, to_remote_g2[counter].to_mod);
to_remote_g2[counter].from_mod,
to_remote_g2[counter].to_call,
to_remote_g2[counter].to_mod);
return; return;
} }
} }
@ -1140,8 +1127,7 @@ static void g2link(char from_mod, char *call, char to_mod)
if (host[0] != '\0') { if (host[0] != '\0') {
ok = resolve_rmt(host, SOCK_DGRAM, &(to_remote_g2[i].toDst4)); ok = resolve_rmt(host, SOCK_DGRAM, &(to_remote_g2[i].toDst4));
if (!ok) { if (!ok) {
traceit("Call %s is host %s but could not resolve to IP\n", traceit("Call %s is host %s but could not resolve to IP\n", call, host);
call, host);
memset(&to_remote_g2[i], 0, sizeof(to_remote_g2[i])); memset(&to_remote_g2[i], 0, sizeof(to_remote_g2[i]));
return; return;
} }
@ -1163,9 +1149,7 @@ static void g2link(char from_mod, char *call, char to_mod)
link_request[9] = to_mod; link_request[9] = to_mod;
link_request[10] = '\0'; link_request[10] = '\0';
traceit("sending link request from mod %c to link with: [%s] mod %c [%s]\n", traceit("sending link request from mod %c to link with: [%s] mod %c [%s]\n", to_remote_g2[i].from_mod, to_remote_g2[i].to_call, to_remote_g2[i].to_mod, payload);
to_remote_g2[i].from_mod,
to_remote_g2[i].to_call, to_remote_g2[i].to_mod, payload);
for (j=0; j<5; j++) for (j=0; j<5; j++)
sendto(xrf_g2_sock, link_request, CALL_SIZE + 3, 0, (struct sockaddr *)&(to_remote_g2[i].toDst4), sizeof(to_remote_g2[i].toDst4)); sendto(xrf_g2_sock, link_request, CALL_SIZE + 3, 0, (struct sockaddr *)&(to_remote_g2[i].toDst4), sizeof(to_remote_g2[i].toDst4));
@ -1177,12 +1161,8 @@ static void g2link(char from_mod, char *call, char to_mod)
memcpy(link_request + 11, to_remote_g2[i].to_call, 8); memcpy(link_request + 11, to_remote_g2[i].to_call, 8);
strcpy(link_request + 19, G2_html); strcpy(link_request + 19, G2_html);
traceit("sending link request from mod %c to link with: [%s] mod %c [%s]\n", traceit("sending link request from mod %c to link with: [%s] mod %c [%s]\n", to_remote_g2[i].from_mod, to_remote_g2[i].to_call, to_remote_g2[i].to_mod, payload);
to_remote_g2[i].from_mod, sendto(dcs_g2_sock, link_request, 519, 0, (struct sockaddr *)&(to_remote_g2[i].toDst4), sizeof(to_remote_g2[i].toDst4));
to_remote_g2[i].to_call, to_remote_g2[i].to_mod, payload);
// Login form 5 to 1
for (j=0; j<1; j++)
sendto(dcs_g2_sock, link_request, 519, 0, (struct sockaddr *)&(to_remote_g2[i].toDst4), sizeof(to_remote_g2[i].toDst4));
} else if (port_i == rmt_ref_port) { } else if (port_i == rmt_ref_port) {
for (counter = 0; counter < 3; counter++) { for (counter = 0; counter < 3; counter++) {
if (counter != i) { if (counter != i) {
@ -1192,9 +1172,7 @@ static void g2link(char from_mod, char *call, char to_mod)
} }
} }
if (counter > 2) { if (counter > 2) {
traceit("sending link command from mod %c to: [%s] mod %c [%s]\n", traceit("sending link command from mod %c to: [%s] mod %c [%s]\n", to_remote_g2[i].from_mod, to_remote_g2[i].to_call, to_remote_g2[i].to_mod, payload);
to_remote_g2[i].from_mod,
to_remote_g2[i].to_call, to_remote_g2[i].to_mod, payload);
queryCommand[0] = 5; queryCommand[0] = 5;
queryCommand[1] = 0; queryCommand[1] = 0;
@ -1202,13 +1180,11 @@ static void g2link(char from_mod, char *call, char to_mod)
queryCommand[3] = 0; queryCommand[3] = 0;
queryCommand[4] = 1; queryCommand[4] = 1;
for (j = 0; j < 1; j++) sendto(ref_g2_sock, queryCommand, 5, 0, (struct sockaddr *)&(to_remote_g2[i].toDst4), sizeof(to_remote_g2[i].toDst4));
sendto(ref_g2_sock, queryCommand, 5, 0, (struct sockaddr *)&(to_remote_g2[i].toDst4), sizeof(to_remote_g2[i].toDst4));
} else { } else {
if (to_remote_g2[counter].is_connected) { if (to_remote_g2[counter].is_connected) {
to_remote_g2[i].is_connected = true; to_remote_g2[i].is_connected = true;
traceit("Local module %c is also connected to %s %c\n", traceit("Local module %c is also connected to %s %c\n", from_mod, call, to_mod);
from_mod, call, to_mod);
print_status_file(); print_status_file();
tracing[i].last_time = time(NULL); tracing[i].last_time = time(NULL);
@ -1218,10 +1194,7 @@ static void g2link(char from_mod, char *call, char to_mod)
space_p = strchr(linked_remote_system, ' '); space_p = strchr(linked_remote_system, ' ');
if (space_p) if (space_p)
*space_p = '\0'; *space_p = '\0';
sprintf(notify_msg, "%c_linked.dat_LINKED_%s_%c", sprintf(notify_msg, "%c_linked.dat_LINKED_%s_%c", to_remote_g2[i].from_mod, linked_remote_system, to_remote_g2[i].to_mod);
to_remote_g2[i].from_mod,
linked_remote_system,
to_remote_g2[i].to_mod);
audio_notify(notify_msg); audio_notify(notify_msg);
} else } else
traceit("status from %s %c pending\n", to_remote_g2[i].to_call, to_remote_g2[i].to_mod); traceit("status from %s %c pending\n", to_remote_g2[i].to_call, to_remote_g2[i].to_mod);
@ -3342,13 +3315,13 @@ static void runit()
if ((memcmp(readBuffer + 36, "CQCQCQ", 6) != 0) && (i >= 0)) { if ((memcmp(readBuffer + 36, "CQCQCQ", 6) != 0) && (i >= 0)) {
if ((memcmp(readBuffer + 36, owner.c_str(), CALL_SIZE-1) != 0) && if ((memcmp(readBuffer + 36, owner.c_str(), CALL_SIZE-1) != 0) &&
(readBuffer[43] == LINK_CODE) && (readBuffer[43] == 'L') &&
(memcmp(readBuffer + 20, owner.c_str(), CALL_SIZE-1) == 0) && (memcmp(readBuffer + 20, owner.c_str(), CALL_SIZE-1) == 0) &&
(readBuffer[27] == 'G') && (readBuffer[27] == 'G') &&
((readBuffer[17] == 0x00) || ((readBuffer[17] == 0x00) ||
(readBuffer[17] == 0x08) || (readBuffer[17] == 0x08) ||
(readBuffer[17] == 0x20) || (readBuffer[17] == 0x20) ||
(readBuffer[17] == 0x28))) { (readBuffer[17] == 0x28))) {
if (only_link_unlink && if (only_link_unlink &&
(link_unlink_user.find(call) == link_unlink_user.end())) { (link_unlink_user.find(call) == link_unlink_user.end())) {
traceit("link request denied, unauthorized rf user [%s]\n", call); traceit("link request denied, unauthorized rf user [%s]\n", call);
@ -3374,10 +3347,8 @@ static void runit()
audio_notify(notify_msg); audio_notify(notify_msg);
} }
} }
} else if ((readBuffer[43] == UNLINK_CODE) && } else if ((readBuffer[43] == 'U') && (readBuffer[36] == ' ')) {
(readBuffer[36] == ' ')) { if (only_link_unlink && (link_unlink_user.find(call) == link_unlink_user.end())) {
if (only_link_unlink &&
(link_unlink_user.find(call) == link_unlink_user.end())) {
traceit("unlink request denied, unauthorized rf user [%s]\n", call); traceit("unlink request denied, unauthorized rf user [%s]\n", call);
} else { } else {
if (to_remote_g2[i].to_call[0] != '\0') { if (to_remote_g2[i].to_call[0] != '\0') {
@ -3444,8 +3415,7 @@ static void runit()
audio_notify(notify_msg); audio_notify(notify_msg);
} }
} }
} else if ((readBuffer[43] == INFO_CODE) && } else if ((readBuffer[43] == 'I') && (readBuffer[36] == ' ')) {
(readBuffer[36] == ' ')) {
if (to_remote_g2[i].is_connected) { if (to_remote_g2[i].is_connected) {
strcpy(linked_remote_system, to_remote_g2[i].to_call); strcpy(linked_remote_system, to_remote_g2[i].to_call);
space_p = strchr(linked_remote_system, ' '); space_p = strchr(linked_remote_system, ' ');
@ -3460,9 +3430,7 @@ static void runit()
sprintf(notify_msg, "%c_id.dat_%s_NOT_LINKED", readBuffer[35], owner.c_str()); sprintf(notify_msg, "%c_id.dat_%s_NOT_LINKED", readBuffer[35], owner.c_str());
audio_notify(notify_msg); audio_notify(notify_msg);
} }
} else if ((readBuffer[43] == EXEC_CODE) && } else if ((readBuffer[43] == 'X') && (readBuffer[36] == ' ') && (admin.find(call) != admin.end())) { // only ADMIN can execute scripts
(readBuffer[36] == ' ') &&
(admin.find(call) != admin.end())) { // only ADMIN can execute scripts
if (readBuffer[42] != ' ') { if (readBuffer[42] != ' ') {
memset(system_cmd, '\0', sizeof(system_cmd)); memset(system_cmd, '\0', sizeof(system_cmd));
snprintf(system_cmd, FILENAME_MAX, "%s/exec_%c.sh %s %c &", snprintf(system_cmd, FILENAME_MAX, "%s/exec_%c.sh %s %c &",
@ -3471,9 +3439,7 @@ static void runit()
traceit("Executing %s\n", system_cmd); traceit("Executing %s\n", system_cmd);
system(system_cmd); system(system_cmd);
} }
} else if ((readBuffer[42] == DONGLE_CODE) && } else if ((readBuffer[42] == 'D') && (readBuffer[36] == ' ') && (admin.find(call) != admin.end())) { // only ADMIN can block dongle users
(readBuffer[36] == ' ') &&
(admin.find(call) != admin.end())) { // only ADMIN can block dongle users
if (readBuffer[43] == '1') { if (readBuffer[43] == '1') {
max_dongles = saved_max_dongles; max_dongles = saved_max_dongles;
traceit("Dongle connections are now allowed\n"); traceit("Dongle connections are now allowed\n");
@ -3482,9 +3448,7 @@ static void runit()
max_dongles = 0; max_dongles = 0;
traceit("Dongle connections are now disallowed\n"); traceit("Dongle connections are now disallowed\n");
} }
} else if ((readBuffer[43] == FILE_REFRESH_GWYS_CODE) && } else if ((readBuffer[43] == 'F') && (readBuffer[36] == ' ') && (admin.find(call) != admin.end())) { // only ADMIN can reload gwys.txt
(readBuffer[36] == ' ') &&
(admin.find(call) != admin.end())) { // only ADMIN can reload gwys.txt
gwy_list.clear(); gwy_list.clear();
load_gwys(gwys); load_gwys(gwys);
} }
@ -4086,9 +4050,7 @@ int main(int argc, char **argv)
return 1; return 1;
} }
int rc = regcomp(&preg, int rc = regcomp(&preg, "^(([1-9][A-Z])|([A-Z][0-9])|([A-Z][A-Z][0-9]))[0-9A-Z]*[A-Z][ ]*[ A-RT-Z]$", REG_EXTENDED | REG_NOSUB);
"^(([1-9][A-Z])|([A-Z][0-9])|([A-Z][A-Z][0-9]))[0-9A-Z]*[A-Z][ ]*[ A-RT-Z]$",
REG_EXTENDED | REG_NOSUB);
if (rc != 0) { if (rc != 0) {
traceit("The IRC regular expression is NOT valid\n"); traceit("The IRC regular expression is NOT valid\n");
return 1; return 1;

Loading…
Cancel
Save

Powered by TurnKey Linux.