|
|
|
@ -77,26 +77,19 @@ static bool bool_send_qrgs, bool_irc_debug, bool_dtmf_debug, bool_regen_header,b
|
|
|
|
|
|
|
|
|
|
|
|
static int play_wait, play_delay, echotest_rec_timeout, voicemail_rec_timeout, from_remote_g2_timeout, from_local_rptr_timeout, dtmf_digit;
|
|
|
|
static int play_wait, play_delay, echotest_rec_timeout, voicemail_rec_timeout, from_remote_g2_timeout, from_local_rptr_timeout, dtmf_digit;
|
|
|
|
|
|
|
|
|
|
|
|
/* 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
|
|
|
|
RPTR rptr;
|
|
|
|
RPTR rptr;
|
|
|
|
|
|
|
|
|
|
|
|
/* local repeater modules being recorded */
|
|
|
|
// local repeater modules being recorded
|
|
|
|
/* This is for echotest */
|
|
|
|
// This is for echotest and voicemail
|
|
|
|
static struct {
|
|
|
|
static struct {
|
|
|
|
time_t last_time;
|
|
|
|
time_t last_time;
|
|
|
|
unsigned char streamid[2];
|
|
|
|
unsigned char streamid[2];
|
|
|
|
int fd;
|
|
|
|
int fd;
|
|
|
|
char file[FILENAME_MAX + 1];
|
|
|
|
char file[FILENAME_MAX + 1];
|
|
|
|
} recd[3];
|
|
|
|
} recd[3], vm[3];
|
|
|
|
|
|
|
|
|
|
|
|
/* this is for vm */
|
|
|
|
|
|
|
|
static struct {
|
|
|
|
|
|
|
|
time_t last_time;
|
|
|
|
|
|
|
|
unsigned char streamid[2];
|
|
|
|
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
char file[FILENAME_MAX + 1];
|
|
|
|
|
|
|
|
} vm[3];
|
|
|
|
|
|
|
|
static unsigned char recbuf[100]; /* 56 or 27, max is 56 */
|
|
|
|
static unsigned char recbuf[100]; /* 56 or 27, max is 56 */
|
|
|
|
|
|
|
|
|
|
|
|
/* the streamids going to remote Gateways from each local module */
|
|
|
|
/* the streamids going to remote Gateways from each local module */
|
|
|
|
@ -186,8 +179,7 @@ static std::map<std::string, std::string> user2rptr_map, rptr2gwy_map, gwy2ip_ma
|
|
|
|
|
|
|
|
|
|
|
|
static pthread_mutex_t irc_data_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
static pthread_mutex_t irc_data_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
|
|
|
|
|
|
|
|
static int g2_open();
|
|
|
|
static int open_port(const PORTIP &pip);
|
|
|
|
static int srv_open();
|
|
|
|
|
|
|
|
static void calcPFCS(unsigned char *packet, int len);
|
|
|
|
static void calcPFCS(unsigned char *packet, int len);
|
|
|
|
static void *get_irc_data(void *arg);
|
|
|
|
static void *get_irc_data(void *arg);
|
|
|
|
static int get_yrcall_rptr_from_cache(char *call, char *arearp_cs, char *zonerp_cs, char *mod, char *ip, char RoU);
|
|
|
|
static int get_yrcall_rptr_from_cache(char *call, char *arearp_cs, char *zonerp_cs, char *mod, char *ip, char RoU);
|
|
|
|
@ -447,15 +439,15 @@ static int read_config(char *cfgFile)
|
|
|
|
if (! get_value(cfg, "aprs.filter", rptr.aprs_filter, 0, 512, ""))
|
|
|
|
if (! get_value(cfg, "aprs.filter", rptr.aprs_filter, 0, 512, ""))
|
|
|
|
return 1;
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
|
|
if (! get_value(cfg, "gateway.g2_external.ip", g2_external.ip, 7, IP_SIZE, "0.0.0.0"))
|
|
|
|
if (! get_value(cfg, "gateway.external.ip", g2_external.ip, 7, IP_SIZE, "0.0.0.0"))
|
|
|
|
return 1;
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
|
|
get_value(cfg, "gateway.g2_external.port", g2_external.port, 20001, 65535, 40000);
|
|
|
|
get_value(cfg, "gateway.external.port", g2_external.port, 20001, 65535, 40000);
|
|
|
|
|
|
|
|
|
|
|
|
if (! get_value(cfg, "gateway.g2_internal.ip", g2_internal.ip, 7, IP_SIZE, "0.0.0.0"))
|
|
|
|
if (! get_value(cfg, "gateway.internal.ip", g2_internal.ip, 7, IP_SIZE, "0.0.0.0"))
|
|
|
|
return 1;
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
|
|
get_value(cfg, "gateway.g2_internal.port", g2_internal.port, 16000, 65535, 19000);
|
|
|
|
get_value(cfg, "gateway.internal.port", g2_internal.port, 16000, 65535, 19000);
|
|
|
|
|
|
|
|
|
|
|
|
if (! get_value(cfg, "g2_link.outgoing_ip", g2_link.ip, 7, IP_SIZE, "127.0.0.1"))
|
|
|
|
if (! get_value(cfg, "g2_link.outgoing_ip", g2_link.ip, 7, IP_SIZE, "127.0.0.1"))
|
|
|
|
return 1;
|
|
|
|
return 1;
|
|
|
|
@ -501,58 +493,30 @@ static int read_config(char *cfgFile)
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Create the 40000 g2_external port */
|
|
|
|
// Create ports
|
|
|
|
static int g2_open()
|
|
|
|
static int open_port(const PORTIP &pip)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
struct sockaddr_in sin;
|
|
|
|
struct sockaddr_in sin;
|
|
|
|
|
|
|
|
|
|
|
|
g2_sock = socket(PF_INET,SOCK_DGRAM,0);
|
|
|
|
int sock = socket(PF_INET, SOCK_DGRAM, 0);
|
|
|
|
if (g2_sock == -1) {
|
|
|
|
if (0 > sock) {
|
|
|
|
traceit("Failed to create g2 socket,errno=%d\n",errno);
|
|
|
|
traceit("Failed to create socket on %s:%d, errno=%d\n", pip.ip.c_str(), pip.port, errno);
|
|
|
|
return 1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fcntl(g2_sock,F_SETFL,O_NONBLOCK);
|
|
|
|
fcntl(sock, F_SETFL, O_NONBLOCK);
|
|
|
|
|
|
|
|
|
|
|
|
memset(&sin,0,sizeof(struct sockaddr_in));
|
|
|
|
memset(&sin, 0, sizeof(struct sockaddr_in));
|
|
|
|
sin.sin_family = AF_INET;
|
|
|
|
sin.sin_family = AF_INET;
|
|
|
|
sin.sin_port = htons(g2_external.port);
|
|
|
|
sin.sin_port = htons(pip.port);
|
|
|
|
sin.sin_addr.s_addr = inet_addr(g2_external.ip.c_str());
|
|
|
|
sin.sin_addr.s_addr = inet_addr(pip.ip.c_str());
|
|
|
|
|
|
|
|
|
|
|
|
if (bind(g2_sock,(struct sockaddr *)&sin,sizeof(struct sockaddr_in)) != 0) {
|
|
|
|
if (bind(sock, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)) != 0) {
|
|
|
|
traceit("Failed to bind g2 socket on port %d, errno=%d\n",g2_external.port,errno);
|
|
|
|
traceit("filed to bind %s:%d, errno=%d\n", pip.ip.c_str(), pip.port, errno);
|
|
|
|
close(g2_sock);
|
|
|
|
close(sock);
|
|
|
|
g2_sock = -1;
|
|
|
|
return -1;
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
return sock;
|
|
|
|
|
|
|
|
|
|
|
|
/* Create the 19000 g2_internal port */
|
|
|
|
|
|
|
|
static int srv_open()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
struct sockaddr_in sin;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
srv_sock = socket(PF_INET,SOCK_DGRAM,0);
|
|
|
|
|
|
|
|
if (srv_sock == -1) {
|
|
|
|
|
|
|
|
traceit("Failed to create srv socket,errno=%d\n",errno);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
fcntl(srv_sock,F_SETFL,O_NONBLOCK);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
memset(&sin,0,sizeof(struct sockaddr_in));
|
|
|
|
|
|
|
|
sin.sin_family = AF_INET;
|
|
|
|
|
|
|
|
sin.sin_port = htons(g2_internal.port);
|
|
|
|
|
|
|
|
sin.sin_addr.s_addr = inet_addr(g2_internal.ip.c_str());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (bind(srv_sock,(struct sockaddr *)&sin,sizeof(struct sockaddr_in)) != 0) {
|
|
|
|
|
|
|
|
traceit("Failed to bind srv socket on port %d, errno=%d\n",
|
|
|
|
|
|
|
|
g2_internal.port, errno);
|
|
|
|
|
|
|
|
close(srv_sock);
|
|
|
|
|
|
|
|
srv_sock = -1;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* receive data from the irc server and save it */
|
|
|
|
/* receive data from the irc server and save it */
|
|
|
|
@ -683,8 +647,7 @@ static void *get_irc_data(void *arg)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 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) */
|
|
|
|
static int get_yrcall_rptr_from_cache(char *call, char *arearp_cs, char *zonerp_cs,
|
|
|
|
static int get_yrcall_rptr_from_cache(char *call, char *arearp_cs, char *zonerp_cs, char *mod, char *ip, char RoU)
|
|
|
|
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 user_pos = user2rptr_map.end();
|
|
|
|
std::map<std::string, std::string>::iterator rptr_pos = rptr2gwy_map.end();
|
|
|
|
std::map<std::string, std::string>::iterator rptr_pos = rptr2gwy_map.end();
|
|
|
|
@ -800,6 +763,16 @@ static void sigCatch(int signum)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int CreateThread(pthread_t *thread, void *(*start_sub)(void *), void *arg = (void *)0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
pthread_attr_t attr;
|
|
|
|
|
|
|
|
pthread_attr_init(&attr);
|
|
|
|
|
|
|
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
|
|
|
|
|
|
|
int rc = pthread_create(thread, &attr, start_sub, arg);
|
|
|
|
|
|
|
|
pthread_attr_destroy(&attr);
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* run the main loop for g2_ircddb */
|
|
|
|
/* run the main loop for g2_ircddb */
|
|
|
|
static void runit()
|
|
|
|
static void runit()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -822,15 +795,11 @@ static void runit()
|
|
|
|
char zonerp_cs[CALL_SIZE + 1];
|
|
|
|
char zonerp_cs[CALL_SIZE + 1];
|
|
|
|
char ip[IP_SIZE + 1];
|
|
|
|
char ip[IP_SIZE + 1];
|
|
|
|
|
|
|
|
|
|
|
|
int rc = 0;
|
|
|
|
|
|
|
|
char tempfile[FILENAME_MAX + 1];
|
|
|
|
char tempfile[FILENAME_MAX + 1];
|
|
|
|
pthread_t echo_thread;
|
|
|
|
|
|
|
|
pthread_attr_t attr;
|
|
|
|
|
|
|
|
long num_recs = 0L;
|
|
|
|
long num_recs = 0L;
|
|
|
|
short int rec_len = 56;
|
|
|
|
short int rec_len = 56;
|
|
|
|
|
|
|
|
|
|
|
|
pthread_t aprs_beacon_thread;
|
|
|
|
pthread_t aprs_beacon_thread, echo_thread, irc_data_thread;
|
|
|
|
pthread_t irc_data_thread;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* START: TEXT crap */
|
|
|
|
/* START: TEXT crap */
|
|
|
|
bool new_group[3] = { true, true, true };
|
|
|
|
bool new_group[3] = { true, true, true };
|
|
|
|
@ -852,30 +821,21 @@ static void runit()
|
|
|
|
max_nfds = g2_sock;
|
|
|
|
max_nfds = g2_sock;
|
|
|
|
if (srv_sock > max_nfds)
|
|
|
|
if (srv_sock > max_nfds)
|
|
|
|
max_nfds = srv_sock;
|
|
|
|
max_nfds = srv_sock;
|
|
|
|
traceit("g2=%d, srv=%d, MAX+1=%d\n",
|
|
|
|
traceit("g2=%d, srv=%d, MAX+1=%d\n", g2_sock, srv_sock, max_nfds + 1);
|
|
|
|
g2_sock, srv_sock, max_nfds + 1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* start the beacon thread */
|
|
|
|
/* start the beacon thread */
|
|
|
|
if (bool_send_aprs) {
|
|
|
|
if (bool_send_aprs) {
|
|
|
|
pthread_attr_init(&attr);
|
|
|
|
if (CreateThread(&aprs_beacon_thread, send_aprs_beacon))
|
|
|
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
|
|
|
|
|
|
|
rc = pthread_create(&aprs_beacon_thread,&attr,send_aprs_beacon,(void *)0);
|
|
|
|
|
|
|
|
if (rc != 0)
|
|
|
|
|
|
|
|
traceit("failed to start the aprs beacon thread\n");
|
|
|
|
traceit("failed to start the aprs beacon thread\n");
|
|
|
|
else
|
|
|
|
else
|
|
|
|
traceit("APRS beacon thread started\n");
|
|
|
|
traceit("APRS beacon thread started\n");
|
|
|
|
pthread_attr_destroy(&attr);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pthread_attr_init(&attr);
|
|
|
|
if (CreateThread(&irc_data_thread, get_irc_data)) {
|
|
|
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
|
|
|
|
|
|
|
rc = pthread_create(&irc_data_thread,&attr,get_irc_data,(void *)0);
|
|
|
|
|
|
|
|
if (rc != 0) {
|
|
|
|
|
|
|
|
traceit("failed to start the get_irc_data thread\n");
|
|
|
|
traceit("failed to start the get_irc_data thread\n");
|
|
|
|
keep_running = false;
|
|
|
|
keep_running = false;
|
|
|
|
} else
|
|
|
|
} else
|
|
|
|
traceit("get_irc_data thread started\n");
|
|
|
|
traceit("get_irc_data thread started\n");
|
|
|
|
pthread_attr_destroy(&attr);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ii->kickWatchdog(IRCDDB_VERSION);
|
|
|
|
ii->kickWatchdog(IRCDDB_VERSION);
|
|
|
|
|
|
|
|
|
|
|
|
@ -888,25 +848,19 @@ static void runit()
|
|
|
|
traceit("Inactivity on echotest recording mod %d, removing stream id=%d,%d\n",
|
|
|
|
traceit("Inactivity on echotest recording mod %d, removing stream id=%d,%d\n",
|
|
|
|
i,recd[i].streamid[0], recd[i].streamid[1]);
|
|
|
|
i,recd[i].streamid[0], recd[i].streamid[1]);
|
|
|
|
|
|
|
|
|
|
|
|
recd[i].streamid[0] = 0x00;
|
|
|
|
recd[i].streamid[0] = recd[i].streamid[1] = 0x00;
|
|
|
|
recd[i].streamid[1] = 0x00;
|
|
|
|
|
|
|
|
recd[i].last_time = 0;
|
|
|
|
recd[i].last_time = 0;
|
|
|
|
close(recd[i].fd);
|
|
|
|
close(recd[i].fd);
|
|
|
|
recd[i].fd = -1;
|
|
|
|
recd[i].fd = -1;
|
|
|
|
// traceit("Closed echotest audio file:[%s]\n", recd[i].file);
|
|
|
|
// traceit("Closed echotest audio file:[%s]\n", recd[i].file);
|
|
|
|
|
|
|
|
|
|
|
|
/* START: echotest thread setup */
|
|
|
|
/* START: echotest thread setup */
|
|
|
|
pthread_attr_init(&attr);
|
|
|
|
if (CreateThread(&echo_thread, echotest, (void *)recd[i].file)) {
|
|
|
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
|
|
|
|
|
|
|
rc = pthread_create(&echo_thread, &attr, echotest, (void *)recd[i].file);
|
|
|
|
|
|
|
|
if (rc != 0) {
|
|
|
|
|
|
|
|
traceit("failed to start echotest thread\n");
|
|
|
|
traceit("failed to start echotest thread\n");
|
|
|
|
/* when the echotest thread runs, it deletes the file,
|
|
|
|
// when the echotest thread runs, it deletes the file,
|
|
|
|
Because the echotest thread did NOT start, we delete the file here
|
|
|
|
// Because the echotest thread did NOT start, we delete the file here
|
|
|
|
*/
|
|
|
|
|
|
|
|
unlink(recd[i].file);
|
|
|
|
unlink(recd[i].file);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pthread_attr_destroy(&attr);
|
|
|
|
|
|
|
|
/* END: echotest thread setup */
|
|
|
|
/* END: echotest thread setup */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -916,10 +870,9 @@ static void runit()
|
|
|
|
time(&t_now);
|
|
|
|
time(&t_now);
|
|
|
|
if ((t_now - vm[i].last_time) > voicemail_rec_timeout) {
|
|
|
|
if ((t_now - vm[i].last_time) > voicemail_rec_timeout) {
|
|
|
|
traceit("Inactivity on voicemail recording mod %d, removing stream id=%d,%d\n",
|
|
|
|
traceit("Inactivity on voicemail recording mod %d, removing stream id=%d,%d\n",
|
|
|
|
i,vm[i].streamid[0], vm[i].streamid[1]);
|
|
|
|
i, vm[i].streamid[0], vm[i].streamid[1]);
|
|
|
|
|
|
|
|
|
|
|
|
vm[i].streamid[0] = 0x00;
|
|
|
|
vm[i].streamid[0] = vm[i].streamid[1] = 0x00;
|
|
|
|
vm[i].streamid[1] = 0x00;
|
|
|
|
|
|
|
|
vm[i].last_time = 0;
|
|
|
|
vm[i].last_time = 0;
|
|
|
|
close(vm[i].fd);
|
|
|
|
close(vm[i].fd);
|
|
|
|
vm[i].fd = -1;
|
|
|
|
vm[i].fd = -1;
|
|
|
|
@ -927,21 +880,17 @@ static void runit()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* any stream going to local repeater timed out? */
|
|
|
|
// any stream going to local repeater timed out?
|
|
|
|
if (toRptr[i].last_time != 0) {
|
|
|
|
if (toRptr[i].last_time != 0) {
|
|
|
|
time(&t_now);
|
|
|
|
time(&t_now);
|
|
|
|
/*
|
|
|
|
// The stream can be from a cross-band, or from a remote system,
|
|
|
|
The stream can be from a cross-band, or from a remote system,
|
|
|
|
// so we could use either FROM_LOCAL_RPTR_TIMEOUT or FROM_REMOTE_G2_TIMEOUT
|
|
|
|
so we could use either FROM_LOCAL_RPTR_TIMEOUT or FROM_REMOTE_G2_TIMEOUT
|
|
|
|
// but FROM_REMOTE_G2_TIMEOUT makes more sense, probably is a bigger number
|
|
|
|
but FROM_REMOTE_G2_TIMEOUT makes more sense, probably is a bigger number
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
if ((t_now - toRptr[i].last_time) > from_remote_g2_timeout) {
|
|
|
|
if ((t_now - toRptr[i].last_time) > from_remote_g2_timeout) {
|
|
|
|
traceit("Inactivity to local rptr mod index %d, removing stream id %d,%d\n",
|
|
|
|
traceit("Inactivity to local rptr mod index %d, removing stream id %d,%d\n", i, toRptr[i].streamid[0], toRptr[i].streamid[1]);
|
|
|
|
i, toRptr[i].streamid[0], toRptr[i].streamid[1]);
|
|
|
|
|
|
|
|
/*
|
|
|
|
// Send end_of_audio to local repeater.
|
|
|
|
Send end_of_audio to local repeater.
|
|
|
|
// Let the repeater re-initialize
|
|
|
|
Let the repeater re-initialize
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
end_of_audio[5] = (unsigned char)(toRptr[i].G2_COUNTER & 0xff);
|
|
|
|
end_of_audio[5] = (unsigned char)(toRptr[i].G2_COUNTER & 0xff);
|
|
|
|
end_of_audio[4] = (unsigned char)((toRptr[i].G2_COUNTER >> 8) & 0xff);
|
|
|
|
end_of_audio[4] = (unsigned char)((toRptr[i].G2_COUNTER >> 8) & 0xff);
|
|
|
|
if (i == 0)
|
|
|
|
if (i == 0)
|
|
|
|
@ -955,14 +904,11 @@ static void runit()
|
|
|
|
end_of_audio[16] = toRptr[i].sequence | 0x40;
|
|
|
|
end_of_audio[16] = toRptr[i].sequence | 0x40;
|
|
|
|
|
|
|
|
|
|
|
|
for (j = 0; j < 2; j++)
|
|
|
|
for (j = 0; j < 2; j++)
|
|
|
|
sendto(srv_sock, (char *)end_of_audio,29,0,
|
|
|
|
sendto(srv_sock, (char *)end_of_audio, 29, 0, (struct sockaddr *)&toRptr[i].band_addr, sizeof(struct sockaddr_in));
|
|
|
|
(struct sockaddr *)&toRptr[i].band_addr,
|
|
|
|
|
|
|
|
sizeof(struct sockaddr_in));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
toRptr[i].G2_COUNTER ++;
|
|
|
|
toRptr[i].G2_COUNTER ++;
|
|
|
|
|
|
|
|
|
|
|
|
toRptr[i].streamid[0] = '\0';
|
|
|
|
toRptr[i].streamid[0] = toRptr[i].streamid[1] = '\0';
|
|
|
|
toRptr[i].streamid[1] = '\0';
|
|
|
|
|
|
|
|
toRptr[i].adr = 0;
|
|
|
|
toRptr[i].adr = 0;
|
|
|
|
toRptr[i].last_time = 0;
|
|
|
|
toRptr[i].last_time = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -974,14 +920,10 @@ static void runit()
|
|
|
|
if ((t_now - band_txt[i].last_time) > from_local_rptr_timeout) {
|
|
|
|
if ((t_now - band_txt[i].last_time) > from_local_rptr_timeout) {
|
|
|
|
/* This local stream never went to a remote system, so trace the timeout */
|
|
|
|
/* This local stream never went to a remote system, so trace the timeout */
|
|
|
|
if (to_remote_g2[i].toDst4.sin_addr.s_addr == 0)
|
|
|
|
if (to_remote_g2[i].toDst4.sin_addr.s_addr == 0)
|
|
|
|
traceit("Inactivity from local rptr band %d, removing stream id %d,%d\n",
|
|
|
|
traceit("Inactivity from local rptr band %d, removing stream id %d,%d\n", i, band_txt[i].streamID[0], band_txt[i].streamID[1]);
|
|
|
|
i, band_txt[i].streamID[0], band_txt[i].streamID[1]);
|
|
|
|
|
|
|
|
|
|
|
|
band_txt[i].streamID[0] = band_txt[i].streamID[1] = 0x0;
|
|
|
|
band_txt[i].streamID[0] = 0x00;
|
|
|
|
band_txt[i].flags[0] = band_txt[i].flags[1] = band_txt[i].flags[2] = 0x0;
|
|
|
|
band_txt[i].streamID[1] = 0x00;
|
|
|
|
|
|
|
|
band_txt[i].flags[0] = 0x00;
|
|
|
|
|
|
|
|
band_txt[i].flags[1] = 0x00;
|
|
|
|
|
|
|
|
band_txt[i].flags[2] = 0x00;
|
|
|
|
|
|
|
|
band_txt[i].lh_mycall[0] = '\0';
|
|
|
|
band_txt[i].lh_mycall[0] = '\0';
|
|
|
|
band_txt[i].lh_sfx[0] = '\0';
|
|
|
|
band_txt[i].lh_sfx[0] = '\0';
|
|
|
|
band_txt[i].lh_yrcall[0] = '\0';
|
|
|
|
band_txt[i].lh_yrcall[0] = '\0';
|
|
|
|
@ -1018,40 +960,29 @@ static void runit()
|
|
|
|
|
|
|
|
|
|
|
|
/* wait 20 ms max */
|
|
|
|
/* wait 20 ms max */
|
|
|
|
FD_ZERO(&fdset);
|
|
|
|
FD_ZERO(&fdset);
|
|
|
|
FD_SET(g2_sock,&fdset);
|
|
|
|
FD_SET(g2_sock, &fdset);
|
|
|
|
FD_SET(srv_sock,&fdset);
|
|
|
|
FD_SET(srv_sock, &fdset);
|
|
|
|
tv.tv_sec = 0;
|
|
|
|
tv.tv_sec = 0;
|
|
|
|
tv.tv_usec = 20000; /* 20 ms */
|
|
|
|
tv.tv_usec = 20000; /* 20 ms */
|
|
|
|
(void)select(max_nfds + 1,&fdset,0,0,&tv);
|
|
|
|
(void)select(max_nfds + 1, &fdset, 0, 0, &tv);
|
|
|
|
|
|
|
|
|
|
|
|
/* process packets coming from remote G2 */
|
|
|
|
/* process packets coming from remote G2 */
|
|
|
|
if (FD_ISSET(g2_sock, &fdset)) {
|
|
|
|
if (FD_ISSET(g2_sock, &fdset)) {
|
|
|
|
fromlen = sizeof(struct sockaddr_in);
|
|
|
|
fromlen = sizeof(struct sockaddr_in);
|
|
|
|
recvlen2 = recvfrom(g2_sock,(char *)readBuffer2,2000,
|
|
|
|
recvlen2 = recvfrom(g2_sock, (char *)readBuffer2, 2000, 0, (struct sockaddr *)&fromDst4, &fromlen);
|
|
|
|
0,(struct sockaddr *)&fromDst4,&fromlen);
|
|
|
|
|
|
|
|
|
|
|
|
if ( ((recvlen2 == 56) || (recvlen2 == 27)) &&
|
|
|
|
if ( ((recvlen2 == 56) ||
|
|
|
|
(memcmp(readBuffer2, "DSVT", 4) == 0) &&
|
|
|
|
(recvlen2 == 27)) &&
|
|
|
|
((readBuffer2[4] == 0x10) || (readBuffer2[4] == 0x20)) && /* header or voiceframe */
|
|
|
|
(memcmp(readBuffer2, "DSVT", 4) == 0) &&
|
|
|
|
|
|
|
|
((readBuffer2[4] == 0x10) || /* header */
|
|
|
|
|
|
|
|
(readBuffer2[4] == 0x20)) && /* details */
|
|
|
|
|
|
|
|
(readBuffer2[8] == 0x20)) { /* voice type */
|
|
|
|
(readBuffer2[8] == 0x20)) { /* voice type */
|
|
|
|
if (recvlen2 == 56) {
|
|
|
|
if (recvlen2 == 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
|
|
|
|
i = readBuffer2[25] - 'A';
|
|
|
|
*/
|
|
|
|
|
|
|
|
i = -1;
|
|
|
|
|
|
|
|
if (readBuffer2[25] == 'A')
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
else if (readBuffer2[25] == 'B')
|
|
|
|
|
|
|
|
i = 1;
|
|
|
|
|
|
|
|
else if (readBuffer2[25] == 'C')
|
|
|
|
|
|
|
|
i = 2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* valid repeater module? */
|
|
|
|
/* valid repeater module? */
|
|
|
|
if (i >= 0) {
|
|
|
|
if (i>=0 && i<3) {
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
toRptr[i] is active if a remote system is talking to it or
|
|
|
|
toRptr[i] is active if a remote system is talking to it or
|
|
|
|
toRptr[i] is receiving data from a cross-band
|
|
|
|
toRptr[i] is receiving data from a cross-band
|
|
|
|
@ -1107,8 +1038,7 @@ static void runit()
|
|
|
|
if ((readBuffer2[14] & 0x40) != 0) {
|
|
|
|
if ((readBuffer2[14] & 0x40) != 0) {
|
|
|
|
if (bool_qso_details)
|
|
|
|
if (bool_qso_details)
|
|
|
|
traceit("END from g2: streamID=%d,%d, %d bytes from IP=%s\n",
|
|
|
|
traceit("END from g2: streamID=%d,%d, %d bytes from IP=%s\n",
|
|
|
|
readBuffer2[12],readBuffer2[13],
|
|
|
|
readBuffer2[12], readBuffer2[13], recvlen2,inet_ntoa(fromDst4.sin_addr));
|
|
|
|
recvlen2,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 */
|
|
|
|
@ -1124,9 +1054,9 @@ static void runit()
|
|
|
|
readBuffer[8] = 0x00;
|
|
|
|
readBuffer[8] = 0x00;
|
|
|
|
readBuffer[9] = 0x13;
|
|
|
|
readBuffer[9] = 0x13;
|
|
|
|
readBuffer[10] = 0x20;
|
|
|
|
readBuffer[10] = 0x20;
|
|
|
|
memcpy(readBuffer + 11, readBuffer2 + 9, 18);
|
|
|
|
memcpy(readBuffer+11, readBuffer2+9, 18);
|
|
|
|
|
|
|
|
|
|
|
|
sendto(srv_sock, (char *)readBuffer,29,0,
|
|
|
|
sendto(srv_sock, (char *)readBuffer, 29, 0,
|
|
|
|
(struct sockaddr *)&toRptr[i].band_addr,
|
|
|
|
(struct sockaddr *)&toRptr[i].band_addr,
|
|
|
|
sizeof(struct sockaddr_in));
|
|
|
|
sizeof(struct sockaddr_in));
|
|
|
|
|
|
|
|
|
|
|
|
@ -1134,7 +1064,7 @@ static void runit()
|
|
|
|
time(&toRptr[i].last_time);
|
|
|
|
time(&toRptr[i].last_time);
|
|
|
|
|
|
|
|
|
|
|
|
/* bump G2 counter */
|
|
|
|
/* bump G2 counter */
|
|
|
|
toRptr[i].G2_COUNTER ++;
|
|
|
|
toRptr[i].G2_COUNTER++;
|
|
|
|
|
|
|
|
|
|
|
|
toRptr[i].sequence = readBuffer[16];
|
|
|
|
toRptr[i].sequence = readBuffer[16];
|
|
|
|
|
|
|
|
|
|
|
|
@ -1255,15 +1185,9 @@ static void runit()
|
|
|
|
(readBuffer[17] == 0x20) || /* BREAK */
|
|
|
|
(readBuffer[17] == 0x20) || /* BREAK */
|
|
|
|
(readBuffer[17] == 0x28))) { /* EMR + BREAK */
|
|
|
|
(readBuffer[17] == 0x28))) { /* EMR + BREAK */
|
|
|
|
|
|
|
|
|
|
|
|
i = -1;
|
|
|
|
i = readBuffer[35] - 'A';
|
|
|
|
if (readBuffer[35] == 'A')
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
else if (readBuffer[35] == 'B')
|
|
|
|
|
|
|
|
i = 1;
|
|
|
|
|
|
|
|
else if (readBuffer[35] == 'C')
|
|
|
|
|
|
|
|
i = 2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (i >= 0) {
|
|
|
|
if (i>=0 && i<3) {
|
|
|
|
dtmf_last_frame[i] = 0;
|
|
|
|
dtmf_last_frame[i] = 0;
|
|
|
|
dtmf_counter[i] = 0;
|
|
|
|
dtmf_counter[i] = 0;
|
|
|
|
memset(dtmf_buf[i], 0, sizeof(dtmf_buf[i]));
|
|
|
|
memset(dtmf_buf[i], 0, sizeof(dtmf_buf[i]));
|
|
|
|
@ -1341,9 +1265,7 @@ static void runit()
|
|
|
|
|
|
|
|
|
|
|
|
/* send data g2_link */
|
|
|
|
/* send data g2_link */
|
|
|
|
if (mycall_valid == REG_NOERROR)
|
|
|
|
if (mycall_valid == REG_NOERROR)
|
|
|
|
sendto(srv_sock, (char *)readBuffer, recvlen,0,
|
|
|
|
sendto(srv_sock, (char *)readBuffer, recvlen, 0, (struct sockaddr *)&plug, sizeof(struct sockaddr_in));
|
|
|
|
(struct sockaddr *)&plug,
|
|
|
|
|
|
|
|
sizeof(struct sockaddr_in));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((mycall_valid == REG_NOERROR) &&
|
|
|
|
if ((mycall_valid == REG_NOERROR) &&
|
|
|
|
(memcmp(readBuffer + 36, "XRF", 3) != 0) && /* not a reflector */
|
|
|
|
(memcmp(readBuffer + 36, "XRF", 3) != 0) && /* not a reflector */
|
|
|
|
@ -1366,15 +1288,9 @@ static void runit()
|
|
|
|
(readBuffer[17] == 0x28)) /* EMR + BK */
|
|
|
|
(readBuffer[17] == 0x28)) /* EMR + BK */
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
if (memcmp(readBuffer + 37, OWNER.c_str(), 6) != 0) { /* the value after the slash in urcall, is NOT this repeater */
|
|
|
|
if (memcmp(readBuffer + 37, OWNER.c_str(), 6) != 0) { /* the value after the slash in urcall, is NOT this repeater */
|
|
|
|
i = -1;
|
|
|
|
i = readBuffer[35] - 'A';
|
|
|
|
if (readBuffer[35] == 'A')
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
if (i>=0 && i<3) {
|
|
|
|
else if (readBuffer[35] == 'B')
|
|
|
|
|
|
|
|
i = 1;
|
|
|
|
|
|
|
|
else if (readBuffer[35] == 'C')
|
|
|
|
|
|
|
|
i = 2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (i >= 0) {
|
|
|
|
|
|
|
|
/* 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) {
|
|
|
|
/* YRCALL=/repeater + mod */
|
|
|
|
/* YRCALL=/repeater + mod */
|
|
|
|
@ -1468,15 +1384,9 @@ static void runit()
|
|
|
|
if (result) {
|
|
|
|
if (result) {
|
|
|
|
/* destination is a remote system */
|
|
|
|
/* destination is a remote system */
|
|
|
|
if (memcmp(zonerp_cs, OWNER.c_str(), 7) != 0) {
|
|
|
|
if (memcmp(zonerp_cs, OWNER.c_str(), 7) != 0) {
|
|
|
|
i = -1;
|
|
|
|
i = readBuffer[35] - 'A';
|
|
|
|
if (readBuffer[35] == 'A')
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
if (i>=0 && i<3) {
|
|
|
|
else if (readBuffer[35] == 'B')
|
|
|
|
|
|
|
|
i = 1;
|
|
|
|
|
|
|
|
else if (readBuffer[35] == 'C')
|
|
|
|
|
|
|
|
i = 2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (i >= 0) {
|
|
|
|
|
|
|
|
/* 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) {
|
|
|
|
/* set the destination */
|
|
|
|
/* set the destination */
|
|
|
|
@ -1531,15 +1441,9 @@ static void runit()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
i = -1;
|
|
|
|
i = readBuffer[35] - 'A';
|
|
|
|
if (readBuffer[35] == 'A')
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
if (i>=0 && i<3) {
|
|
|
|
else if (readBuffer[35] == 'B')
|
|
|
|
|
|
|
|
i = 1;
|
|
|
|
|
|
|
|
else if (readBuffer[35] == 'C')
|
|
|
|
|
|
|
|
i = 2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (i >= 0) {
|
|
|
|
|
|
|
|
/* the user we are trying to contact is on our gateway */
|
|
|
|
/* the user we are trying to contact is on our gateway */
|
|
|
|
/* make sure they are on a different module */
|
|
|
|
/* make sure they are on a different module */
|
|
|
|
if (temp_mod != readBuffer[35]) {
|
|
|
|
if (temp_mod != readBuffer[35]) {
|
|
|
|
@ -1551,16 +1455,10 @@ static void runit()
|
|
|
|
band_txt[i].dest_rptr[7] = temp_mod;
|
|
|
|
band_txt[i].dest_rptr[7] = temp_mod;
|
|
|
|
band_txt[i].dest_rptr[CALL_SIZE] = '\0';
|
|
|
|
band_txt[i].dest_rptr[CALL_SIZE] = '\0';
|
|
|
|
|
|
|
|
|
|
|
|
i = -1;
|
|
|
|
i = temp_mod - 'A';
|
|
|
|
if (temp_mod == 'A')
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
else if (temp_mod == 'B')
|
|
|
|
|
|
|
|
i = 1;
|
|
|
|
|
|
|
|
else if (temp_mod == 'C')
|
|
|
|
|
|
|
|
i = 2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* valid destination repeater module? */
|
|
|
|
/* valid destination repeater module? */
|
|
|
|
if (i >= 0) {
|
|
|
|
if (i>=0 && i<3) {
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
toRptr[i] : receiving from a remote system or cross-band
|
|
|
|
toRptr[i] : receiving from a remote system or cross-band
|
|
|
|
band_txt[i] : local RF is talking.
|
|
|
|
band_txt[i] : local RF is talking.
|
|
|
|
@ -1599,15 +1497,9 @@ static void runit()
|
|
|
|
} else if ((readBuffer[43] == '0') &&
|
|
|
|
} else if ((readBuffer[43] == '0') &&
|
|
|
|
(readBuffer[42] == CLEAR_VM_CODE) &&
|
|
|
|
(readBuffer[42] == CLEAR_VM_CODE) &&
|
|
|
|
(readBuffer[36] == ' ')) {
|
|
|
|
(readBuffer[36] == ' ')) {
|
|
|
|
i = -1;
|
|
|
|
i = readBuffer[35] - 'A';
|
|
|
|
if (readBuffer[35] == 'A')
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
else if (readBuffer[35] == 'B')
|
|
|
|
|
|
|
|
i = 1;
|
|
|
|
|
|
|
|
else if (readBuffer[35] == 'C')
|
|
|
|
|
|
|
|
i = 2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (i >= 0) {
|
|
|
|
if (i>=0 && i<3) {
|
|
|
|
/* voicemail file is closed */
|
|
|
|
/* voicemail file is closed */
|
|
|
|
if ((vm[i].fd == -1) && (vm[i].file[0] != '\0')) {
|
|
|
|
if ((vm[i].fd == -1) && (vm[i].file[0] != '\0')) {
|
|
|
|
unlink(vm[i].file);
|
|
|
|
unlink(vm[i].file);
|
|
|
|
@ -1630,27 +1522,17 @@ static void runit()
|
|
|
|
if (i >= 0) {
|
|
|
|
if (i >= 0) {
|
|
|
|
/* voicemail file is closed */
|
|
|
|
/* voicemail file is closed */
|
|
|
|
if ((vm[i].fd == -1) && (vm[i].file[0] != '\0')) {
|
|
|
|
if ((vm[i].fd == -1) && (vm[i].file[0] != '\0')) {
|
|
|
|
pthread_attr_init(&attr);
|
|
|
|
if (CreateThread(&echo_thread, echotest, (void *)vm[i].file))
|
|
|
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
|
|
|
|
|
|
|
rc = pthread_create(&echo_thread, &attr, echotest, (void *)vm[i].file);
|
|
|
|
|
|
|
|
if (rc != 0)
|
|
|
|
|
|
|
|
traceit("failed to start playing back voicemail\n");
|
|
|
|
traceit("failed to start playing back voicemail\n");
|
|
|
|
pthread_attr_destroy(&attr);
|
|
|
|
|
|
|
|
} else
|
|
|
|
} else
|
|
|
|
traceit("No voicemail to recall or still recording\n");
|
|
|
|
traceit("No voicemail to recall or still recording\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if ((readBuffer[43] == '0') &&
|
|
|
|
} else if ((readBuffer[43] == '0') &&
|
|
|
|
(readBuffer[42] == STORE_VM_CODE) &&
|
|
|
|
(readBuffer[42] == STORE_VM_CODE) &&
|
|
|
|
(readBuffer[36] == ' ')) {
|
|
|
|
(readBuffer[36] == ' ')) {
|
|
|
|
i = -1;
|
|
|
|
i = readBuffer[35] - 'A';
|
|
|
|
if (readBuffer[35] == 'A')
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
else if (readBuffer[35] == 'B')
|
|
|
|
|
|
|
|
i = 1;
|
|
|
|
|
|
|
|
else if (readBuffer[35] == 'C')
|
|
|
|
|
|
|
|
i = 2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (i >= 0) {
|
|
|
|
if (i>=0 && i<3) {
|
|
|
|
if (vm[i].fd >= 0)
|
|
|
|
if (vm[i].fd >= 0)
|
|
|
|
traceit("Already recording for voicemail on mod %d\n", i);
|
|
|
|
traceit("Already recording for voicemail on mod %d\n", i);
|
|
|
|
else {
|
|
|
|
else {
|
|
|
|
@ -1704,15 +1586,9 @@ static void runit()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if ((readBuffer[43] == ECHO_CODE) &&
|
|
|
|
} else if ((readBuffer[43] == ECHO_CODE) &&
|
|
|
|
(readBuffer[36] == ' ')) {
|
|
|
|
(readBuffer[36] == ' ')) {
|
|
|
|
i = -1;
|
|
|
|
i = readBuffer[35] - 'A';
|
|
|
|
if (readBuffer[35] == 'A')
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
else if (readBuffer[35] == 'B')
|
|
|
|
|
|
|
|
i = 1;
|
|
|
|
|
|
|
|
else if (readBuffer[35] == 'C')
|
|
|
|
|
|
|
|
i = 2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (i >= 0) {
|
|
|
|
if (i>=0 && i<3) {
|
|
|
|
if (recd[i].fd >= 0)
|
|
|
|
if (recd[i].fd >= 0)
|
|
|
|
traceit("Already recording for echotest on mod %d\n", i);
|
|
|
|
traceit("Already recording for echotest on mod %d\n", i);
|
|
|
|
else {
|
|
|
|
else {
|
|
|
|
@ -1776,37 +1652,21 @@ static void runit()
|
|
|
|
(readBuffer[27] == 'B') ||
|
|
|
|
(readBuffer[27] == 'B') ||
|
|
|
|
(readBuffer[27] == 'C')) && /* !!! usually a G of rpt2, but we see A,B,C */
|
|
|
|
(readBuffer[27] == 'C')) && /* !!! usually a G of rpt2, but we see A,B,C */
|
|
|
|
(readBuffer[35] != readBuffer[27])) { /* cross-banding? make sure NOT the same */
|
|
|
|
(readBuffer[35] != readBuffer[27])) { /* cross-banding? make sure NOT the same */
|
|
|
|
i = -1;
|
|
|
|
i = readBuffer[35] - 'A';
|
|
|
|
if (readBuffer[35] == 'A')
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
if (i>=0 && i<3) {
|
|
|
|
else if (readBuffer[35] == 'B')
|
|
|
|
// The remote repeater has been set, lets fill in the dest_rptr
|
|
|
|
i = 1;
|
|
|
|
// so that later we can send that to the LIVE web site
|
|
|
|
else if (readBuffer[35] == 'C')
|
|
|
|
|
|
|
|
i = 2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (i >= 0) {
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
The remote repeater has been set, lets fill in the dest_rptr
|
|
|
|
|
|
|
|
so that later we can send that to the LIVE web site
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
memcpy(band_txt[i].dest_rptr, readBuffer + 20, CALL_SIZE);
|
|
|
|
memcpy(band_txt[i].dest_rptr, readBuffer + 20, CALL_SIZE);
|
|
|
|
band_txt[i].dest_rptr[CALL_SIZE] = '\0';
|
|
|
|
band_txt[i].dest_rptr[CALL_SIZE] = '\0';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
i = -1;
|
|
|
|
i = readBuffer[27] - 'A';
|
|
|
|
if (readBuffer[27] == 'A')
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
else if (readBuffer[27] == 'B')
|
|
|
|
|
|
|
|
i = 1;
|
|
|
|
|
|
|
|
else if (readBuffer[27] == 'C')
|
|
|
|
|
|
|
|
i = 2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* valid destination repeater module? */
|
|
|
|
/* valid destination repeater module? */
|
|
|
|
if (i >= 0) {
|
|
|
|
if (i>=0 && i<3) {
|
|
|
|
/*
|
|
|
|
// toRptr[i] : receiving from a remote system or cross-band
|
|
|
|
toRptr[i] : receiving from a remote system or cross-band
|
|
|
|
// band_txt[i] : local RF is talking.
|
|
|
|
band_txt[i] : local RF is talking.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
if ((toRptr[i].last_time == 0) && (band_txt[i].last_time == 0)) {
|
|
|
|
if ((toRptr[i].last_time == 0) && (band_txt[i].last_time == 0)) {
|
|
|
|
traceit("ZONEmode cross-banding from mod %c to %c\n", readBuffer[35], readBuffer[27]);
|
|
|
|
traceit("ZONEmode cross-banding from mod %c to %c\n", readBuffer[35], readBuffer[27]);
|
|
|
|
|
|
|
|
|
|
|
|
@ -1871,11 +1731,8 @@ static void runit()
|
|
|
|
band_txt[i].num_dv_silent_frames,
|
|
|
|
band_txt[i].num_dv_silent_frames,
|
|
|
|
band_txt[i].num_bit_errors);
|
|
|
|
band_txt[i].num_bit_errors);
|
|
|
|
|
|
|
|
|
|
|
|
band_txt[i].streamID[0] = 0x00;
|
|
|
|
band_txt[i].streamID[0] = band_txt[i].streamID[1] = 0x0;
|
|
|
|
band_txt[i].streamID[1] = 0x00;
|
|
|
|
band_txt[i].flags[0] = band_txt[i].flags[1] = band_txt[i].flags[2] = 0x0;
|
|
|
|
band_txt[i].flags[0] = 0x00;
|
|
|
|
|
|
|
|
band_txt[i].flags[1] = 0x00;
|
|
|
|
|
|
|
|
band_txt[i].flags[2] = 0x00;
|
|
|
|
|
|
|
|
band_txt[i].lh_mycall[0] = '\0';
|
|
|
|
band_txt[i].lh_mycall[0] = '\0';
|
|
|
|
band_txt[i].lh_sfx[0] = '\0';
|
|
|
|
band_txt[i].lh_sfx[0] = '\0';
|
|
|
|
band_txt[i].lh_yrcall[0] = '\0';
|
|
|
|
band_txt[i].lh_yrcall[0] = '\0';
|
|
|
|
@ -2258,37 +2115,27 @@ static void runit()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* send data to g2_link */
|
|
|
|
/* send data to g2_link */
|
|
|
|
sendto(srv_sock, (char *)readBuffer, recvlen,0,
|
|
|
|
sendto(srv_sock, (char *)readBuffer, recvlen, 0, (struct sockaddr *)&plug, sizeof(struct sockaddr_in));
|
|
|
|
(struct sockaddr *)&plug,
|
|
|
|
|
|
|
|
sizeof(struct sockaddr_in));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* aprs processing */
|
|
|
|
/* aprs processing */
|
|
|
|
if (bool_send_aprs)
|
|
|
|
if (bool_send_aprs)
|
|
|
|
aprs->ProcessText(readBuffer + 14, /* stream ID */
|
|
|
|
// streamID seq audio+text size
|
|
|
|
readBuffer[16], /* seq */
|
|
|
|
aprs->ProcessText(readBuffer+14, readBuffer[16], readBuffer+17, (recvlen == 29)?12:15);
|
|
|
|
readBuffer + 17, /* audio + text */
|
|
|
|
|
|
|
|
(recvlen == 29)?12:15); /* size */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
/* find out if data must go to the remote G2 */
|
|
|
|
/* find out if data must go to the remote G2 */
|
|
|
|
if (memcmp(to_remote_g2[i].streamid, readBuffer + 14, 2) == 0) {
|
|
|
|
if (memcmp(to_remote_g2[i].streamid, readBuffer + 14, 2) == 0) {
|
|
|
|
memcpy(readBuffer2, "DSVT", 4);
|
|
|
|
memcpy(readBuffer2, "DSVT", 4);
|
|
|
|
readBuffer2[4] = 0x20;
|
|
|
|
readBuffer2[4] = 0x20;
|
|
|
|
readBuffer2[5] = 0x00;
|
|
|
|
readBuffer2[5] = readBuffer2[6] = readBuffer2[7] = 0x00;
|
|
|
|
readBuffer2[6] = 0x00;
|
|
|
|
memcpy(readBuffer2 + 8, readBuffer + 10, 7);
|
|
|
|
readBuffer2[7] = 0x00;
|
|
|
|
|
|
|
|
readBuffer2[8] = readBuffer[10];
|
|
|
|
|
|
|
|
readBuffer2[9] = readBuffer[11];
|
|
|
|
|
|
|
|
readBuffer2[10] = readBuffer[12];
|
|
|
|
|
|
|
|
readBuffer2[11] = readBuffer[13];
|
|
|
|
|
|
|
|
memcpy(readBuffer2 + 12, readBuffer + 14, 3);
|
|
|
|
|
|
|
|
if (recvlen == 29)
|
|
|
|
if (recvlen == 29)
|
|
|
|
memcpy(readBuffer2 + 15, readBuffer + 17, 12);
|
|
|
|
memcpy(readBuffer2 + 15, readBuffer + 17, 12);
|
|
|
|
else
|
|
|
|
else
|
|
|
|
memcpy(readBuffer2 + 15, readBuffer + 20, 12);
|
|
|
|
memcpy(readBuffer2 + 15, readBuffer + 20, 12);
|
|
|
|
|
|
|
|
|
|
|
|
sendto(g2_sock, (char *)readBuffer2, 27,
|
|
|
|
sendto(g2_sock, (char *)readBuffer2, 27,
|
|
|
|
0,(struct sockaddr *)&(to_remote_g2[i].toDst4),
|
|
|
|
0, (struct sockaddr *)&(to_remote_g2[i].toDst4),
|
|
|
|
sizeof(struct sockaddr_in));
|
|
|
|
sizeof(struct sockaddr_in));
|
|
|
|
|
|
|
|
|
|
|
|
time(&(to_remote_g2[i].last_time));
|
|
|
|
time(&(to_remote_g2[i].last_time));
|
|
|
|
@ -2296,8 +2143,7 @@ static void runit()
|
|
|
|
/* Is this the end-of-stream */
|
|
|
|
/* Is this the end-of-stream */
|
|
|
|
if ((readBuffer[16] & 0x40) != 0) {
|
|
|
|
if ((readBuffer[16] & 0x40) != 0) {
|
|
|
|
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].streamid[0] = '\0';
|
|
|
|
to_remote_g2[i].streamid[0] = to_remote_g2[i].streamid[1] = '\0';
|
|
|
|
to_remote_g2[i].streamid[1] = '\0';
|
|
|
|
|
|
|
|
to_remote_g2[i].last_time = 0;
|
|
|
|
to_remote_g2[i].last_time = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
@ -2335,10 +2181,7 @@ static void runit()
|
|
|
|
// traceit("Closed echotest audio file:[%s]\n", recd[i].file);
|
|
|
|
// traceit("Closed echotest audio file:[%s]\n", recd[i].file);
|
|
|
|
|
|
|
|
|
|
|
|
/* we are in echotest mode, so play it back */
|
|
|
|
/* we are in echotest mode, so play it back */
|
|
|
|
pthread_attr_init(&attr);
|
|
|
|
if (CreateThread(&echo_thread, echotest, (void *)recd[i].file)) {
|
|
|
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
|
|
|
|
|
|
|
rc = pthread_create(&echo_thread, &attr, echotest, (void *)recd[i].file);
|
|
|
|
|
|
|
|
if (rc != 0) {
|
|
|
|
|
|
|
|
traceit("failed to start echotest thread\n");
|
|
|
|
traceit("failed to start echotest thread\n");
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
When the echotest thread runs, it deletes the file,
|
|
|
|
When the echotest thread runs, it deletes the file,
|
|
|
|
@ -2346,7 +2189,6 @@ static void runit()
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
unlink(recd[i].file);
|
|
|
|
unlink(recd[i].file);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pthread_attr_destroy(&attr);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
} else
|
|
|
|
} else
|
|
|
|
@ -2385,8 +2227,7 @@ static void runit()
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
} else
|
|
|
|
} else
|
|
|
|
/* or maybe this is cross-banding data */
|
|
|
|
/* or maybe this is cross-banding data */
|
|
|
|
if ((memcmp(toRptr[i].streamid, readBuffer + 14, 2) == 0) &&
|
|
|
|
if ((memcmp(toRptr[i].streamid, readBuffer + 14, 2) == 0) && (toRptr[i].adr == fromRptr.sin_addr.s_addr)) {
|
|
|
|
(toRptr[i].adr == fromRptr.sin_addr.s_addr)) {
|
|
|
|
|
|
|
|
sendto(srv_sock, (char *)readBuffer,29,0,
|
|
|
|
sendto(srv_sock, (char *)readBuffer,29,0,
|
|
|
|
(struct sockaddr *)&toRptr[i].band_addr,
|
|
|
|
(struct sockaddr *)&toRptr[i].band_addr,
|
|
|
|
sizeof(struct sockaddr_in));
|
|
|
|
sizeof(struct sockaddr_in));
|
|
|
|
@ -2852,16 +2693,10 @@ int main(int argc, char **argv)
|
|
|
|
rptr.mod[2].band = "2m";
|
|
|
|
rptr.mod[2].band = "2m";
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
band_txt[i].streamID[0] = 0x00;
|
|
|
|
band_txt[i].streamID[0] = band_txt[i].streamID[1] = 0x0;
|
|
|
|
band_txt[i].streamID[1] = 0x00;
|
|
|
|
band_txt[i].flags[0] = band_txt[i].flags[1] = band_txt[i].flags[2] = 0x0;
|
|
|
|
band_txt[i].flags[0] = 0x00;
|
|
|
|
band_txt[i].lh_mycall[0] = band_txt[i].lh_sfx[0] = band_txt[i].lh_yrcall[0] = '\0';
|
|
|
|
band_txt[i].flags[1] = 0x00;
|
|
|
|
band_txt[i].lh_rpt1[0] = band_txt[i].lh_rpt2[0] = '\0';
|
|
|
|
band_txt[i].flags[2] = 0x00;
|
|
|
|
|
|
|
|
band_txt[i].lh_mycall[0] = '\0';
|
|
|
|
|
|
|
|
band_txt[i].lh_sfx[0] = '\0';
|
|
|
|
|
|
|
|
band_txt[i].lh_yrcall[0] = '\0';
|
|
|
|
|
|
|
|
band_txt[i].lh_rpt1[0] = '\0';
|
|
|
|
|
|
|
|
band_txt[i].lh_rpt2[0] = '\0';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
band_txt[i].last_time = 0;
|
|
|
|
band_txt[i].last_time = 0;
|
|
|
|
|
|
|
|
|
|
|
|
@ -2945,62 +2780,46 @@ int main(int argc, char **argv)
|
|
|
|
|
|
|
|
|
|
|
|
do {
|
|
|
|
do {
|
|
|
|
/* udp port 40000 must open first */
|
|
|
|
/* udp port 40000 must open first */
|
|
|
|
rc = g2_open();
|
|
|
|
g2_sock = open_port(g2_external);
|
|
|
|
if (rc != 0) {
|
|
|
|
if (0 > g2_sock) {
|
|
|
|
traceit("g2_open() failed\n");
|
|
|
|
traceit("Can't open %s:%d\n", g2_external.ip.c_str(), g2_external.port);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Open udp INTERNAL port */
|
|
|
|
/* Open udp INTERNAL port */
|
|
|
|
rc = srv_open();
|
|
|
|
srv_sock = open_port(g2_internal);
|
|
|
|
if (rc != 0) {
|
|
|
|
if (0 > srv_sock) {
|
|
|
|
traceit("srv_open() failed\n");
|
|
|
|
traceit("Can't open %s:%d\n", g2_internal.ip.c_str(), g2_internal.port);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* recording for echotest on local repeater modules */
|
|
|
|
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
|
|
|
|
// recording for echotest on local repeater modules
|
|
|
|
recd[i].last_time = 0;
|
|
|
|
recd[i].last_time = 0;
|
|
|
|
recd[i].streamid[0] = 0x00;
|
|
|
|
recd[i].streamid[0] = recd[i].streamid[1] = 0x0;
|
|
|
|
recd[i].streamid[1] = 0x00;
|
|
|
|
|
|
|
|
recd[i].fd = -1;
|
|
|
|
recd[i].fd = -1;
|
|
|
|
memset(recd[i].file, 0, sizeof(recd[i].file));
|
|
|
|
memset(recd[i].file, 0, sizeof(recd[i].file));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* recording for voicemail on local repeater modules */
|
|
|
|
// recording for voicemail on local repeater modules
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
|
|
|
|
vm[i].last_time = 0;
|
|
|
|
vm[i].last_time = 0;
|
|
|
|
vm[i].streamid[0] = 0x00;
|
|
|
|
vm[i].streamid[0] = vm[i].streamid[1] = 0x0;
|
|
|
|
vm[i].streamid[1] = 0x00;
|
|
|
|
|
|
|
|
vm[i].fd = -1;
|
|
|
|
vm[i].fd = -1;
|
|
|
|
memset(vm[i].file, 0, sizeof(vm[i].file));
|
|
|
|
memset(vm[i].file, 0, sizeof(vm[i].file));
|
|
|
|
|
|
|
|
|
|
|
|
if (i == 0)
|
|
|
|
snprintf(vm[i].file, FILENAME_MAX, "%s/%c_%s", echotest_dir.c_str(), 'A'+i, "voicemail.dat");
|
|
|
|
snprintf(vm[i].file, FILENAME_MAX, "%s/%c_%s",
|
|
|
|
|
|
|
|
echotest_dir.c_str(),'A',"voicemail.dat");
|
|
|
|
|
|
|
|
else if (i == 1)
|
|
|
|
|
|
|
|
snprintf(vm[i].file, FILENAME_MAX, "%s/%c_%s",
|
|
|
|
|
|
|
|
echotest_dir.c_str(),'B',"voicemail.dat");
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
snprintf(vm[i].file, FILENAME_MAX, "%s/%c_%s",
|
|
|
|
|
|
|
|
echotest_dir.c_str(),'C',"voicemail.dat");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (access(vm[i].file, F_OK) != 0)
|
|
|
|
if (access(vm[i].file, F_OK) != 0)
|
|
|
|
memset(vm[i].file, 0, sizeof(vm[i].file));
|
|
|
|
memset(vm[i].file, 0, sizeof(vm[i].file));
|
|
|
|
else
|
|
|
|
else
|
|
|
|
traceit("Loaded voicemail file: %s for mod %d\n",
|
|
|
|
traceit("Loaded voicemail file: %s for mod %d\n", vm[i].file, i);
|
|
|
|
vm[i].file, i);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* the repeater modules run on these ports */
|
|
|
|
// the repeater modules run on these ports
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
|
|
|
|
memset(&toRptr[i],0,sizeof(toRptr[i]));
|
|
|
|
memset(&toRptr[i],0,sizeof(toRptr[i]));
|
|
|
|
|
|
|
|
|
|
|
|
memset(toRptr[i].saved_hdr, 0, sizeof(toRptr[i].saved_hdr));
|
|
|
|
memset(toRptr[i].saved_hdr, 0, sizeof(toRptr[i].saved_hdr));
|
|
|
|
toRptr[i].saved_adr = 0;
|
|
|
|
toRptr[i].saved_adr = 0;
|
|
|
|
|
|
|
|
|
|
|
|
toRptr[i].streamid[0] = '\0';
|
|
|
|
toRptr[i].streamid[0] = toRptr[i].streamid[1] = '\0';
|
|
|
|
toRptr[i].streamid[1] = '\0';
|
|
|
|
|
|
|
|
toRptr[i].adr = 0;
|
|
|
|
toRptr[i].adr = 0;
|
|
|
|
|
|
|
|
|
|
|
|
toRptr[i].band_addr.sin_family = AF_INET;
|
|
|
|
toRptr[i].band_addr.sin_family = AF_INET;
|
|
|
|
@ -3010,7 +2829,7 @@ int main(int argc, char **argv)
|
|
|
|
toRptr[i].last_time = 0;
|
|
|
|
toRptr[i].last_time = 0;
|
|
|
|
toRptr[i].G2_COUNTER = 0;
|
|
|
|
toRptr[i].G2_COUNTER = 0;
|
|
|
|
|
|
|
|
|
|
|
|
toRptr[i].sequence = 0x00;
|
|
|
|
toRptr[i].sequence = 0x0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
@ -3032,14 +2851,14 @@ int main(int argc, char **argv)
|
|
|
|
|
|
|
|
|
|
|
|
/* to remote systems */
|
|
|
|
/* to remote systems */
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
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].streamid[0] = '\0';
|
|
|
|
to_remote_g2[i].streamid[0] = '\0';
|
|
|
|
to_remote_g2[i].streamid[1] = '\0';
|
|
|
|
to_remote_g2[i].streamid[1] = '\0';
|
|
|
|
to_remote_g2[i].last_time = 0;
|
|
|
|
to_remote_g2[i].last_time = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* where to send packets to g2_link */
|
|
|
|
/* where to send packets to g2_link */
|
|
|
|
memset(&plug,0,sizeof(struct sockaddr_in));
|
|
|
|
memset(&plug, 0, sizeof(struct sockaddr_in));
|
|
|
|
plug.sin_family = AF_INET;
|
|
|
|
plug.sin_family = AF_INET;
|
|
|
|
plug.sin_port = htons(g2_link.port);
|
|
|
|
plug.sin_port = htons(g2_link.port);
|
|
|
|
plug.sin_addr.s_addr = inet_addr(g2_link.ip.c_str());
|
|
|
|
plug.sin_addr.s_addr = inet_addr(g2_link.ip.c_str());
|
|
|
|
@ -3069,11 +2888,12 @@ int main(int argc, char **argv)
|
|
|
|
close(aprs->GetSock());
|
|
|
|
close(aprs->GetSock());
|
|
|
|
traceit("Closed APRS\n");
|
|
|
|
traceit("Closed APRS\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
delete aprs;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
recd[i].last_time = 0;
|
|
|
|
recd[i].last_time = 0;
|
|
|
|
recd[i].streamid[0] = 0x00;
|
|
|
|
recd[i].streamid[0] = recd[i].streamid[1] = 0x0;
|
|
|
|
recd[i].streamid[1] = 0x00;
|
|
|
|
|
|
|
|
if (recd[i].fd >= 0) {
|
|
|
|
if (recd[i].fd >= 0) {
|
|
|
|
close(recd[i].fd);
|
|
|
|
close(recd[i].fd);
|
|
|
|
unlink(recd[i].file);
|
|
|
|
unlink(recd[i].file);
|
|
|
|
@ -3082,9 +2902,7 @@ int main(int argc, char **argv)
|
|
|
|
|
|
|
|
|
|
|
|
ii->close();
|
|
|
|
ii->close();
|
|
|
|
delete ii;
|
|
|
|
delete ii;
|
|
|
|
if (bool_send_aprs)
|
|
|
|
|
|
|
|
delete aprs;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
traceit("g2_ircddb exiting\n");
|
|
|
|
traceit("g2_ircddb exiting\n");
|
|
|
|
return rc;
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -3281,18 +3099,10 @@ static void build_aprs_from_gps_and_send(short int rptr_idx)
|
|
|
|
|
|
|
|
|
|
|
|
rc = aprs->WriteSock(buf, strlen(buf));
|
|
|
|
rc = aprs->WriteSock(buf, strlen(buf));
|
|
|
|
if (rc == -1) {
|
|
|
|
if (rc == -1) {
|
|
|
|
if ((errno == EPIPE) ||
|
|
|
|
if ((errno == EPIPE) || (errno == ECONNRESET) || (errno == ETIMEDOUT) || (errno == ECONNABORTED) ||
|
|
|
|
(errno == ECONNRESET) ||
|
|
|
|
(errno == ESHUTDOWN) || (errno == EHOSTUNREACH) || (errno == ENETRESET) || (errno == ENETDOWN) ||
|
|
|
|
(errno == ETIMEDOUT) ||
|
|
|
|
(errno == ENETUNREACH) || (errno == EHOSTDOWN) || (errno == ENOTCONN)) {
|
|
|
|
(errno == ECONNABORTED) ||
|
|
|
|
traceit("build_aprs_from_gps_and_send: APRS_HOST closed connection, error=%d\n", errno);
|
|
|
|
(errno == ESHUTDOWN) ||
|
|
|
|
|
|
|
|
(errno == EHOSTUNREACH) ||
|
|
|
|
|
|
|
|
(errno == ENETRESET) ||
|
|
|
|
|
|
|
|
(errno == ENETDOWN) ||
|
|
|
|
|
|
|
|
(errno == ENETUNREACH) ||
|
|
|
|
|
|
|
|
(errno == EHOSTDOWN) ||
|
|
|
|
|
|
|
|
(errno == ENOTCONN)) {
|
|
|
|
|
|
|
|
traceit("build_aprs_from_gps_and_send: APRS_HOST closed connection,error=%d\n",errno);
|
|
|
|
|
|
|
|
close(aprs->GetSock());
|
|
|
|
close(aprs->GetSock());
|
|
|
|
aprs->SetSock( -1 );
|
|
|
|
aprs->SetSock( -1 );
|
|
|
|
} else
|
|
|
|
} else
|
|
|
|
|