process cracked into 3

lastudp
Tom Early 7 years ago
parent f9acf25f85
commit b4adc4417f

@ -662,104 +662,16 @@ bool CQnetGateway::get_yrcall_rptr(char *call, char *arearp_cs, char *zonerp_cs,
return false; return false;
} }
/* run the main loop for QnetGateway */ bool CQnetGateway::Flag_is_ok(unsigned char flag)
void CQnetGateway::process()
{ {
SDSVT g2buf; // normal break emr emr+break
fd_set fdset; return 0x00U==flag || 0x08U==flag || 0x20U==flag || 0x28U==flag;
}
char temp_radio_user[CALL_SIZE + 1];
char temp_mod;
time_t t_now;
char arearp_cs[CALL_SIZE + 1];
char zonerp_cs[CALL_SIZE + 1];
char ip[IP_SIZE + 1];
char tempfile[FILENAME_MAX + 1];
long num_recs = 0L;
short int rec_len = 56;
std::future<void> aprs_future, irc_data_future;
// dtmf stuff
int dtmf_buf_count[3] = {0, 0, 0};
char dtmf_buf[3][MAX_DTMF_BUF + 1] = { {""}, {""}, {""} };
int dtmf_last_frame[3] = { 0, 0, 0 };
unsigned int dtmf_counter[3] = { 0, 0, 0 };
/* START: TEXT crap */
bool new_group[3] = { true, true, true };
int header_type = 0;
short to_print[3] = { 0, 0, 0 };
bool ABC_grp[3] = { false, false, false };
bool C_seen[3] = { false, false, false };
unsigned char tmp_txt[3];
/* END: TEXT crap */
int max_nfds = 0;
dstar_dv_init();
if (g2_sock > max_nfds)
max_nfds = g2_sock;
if (srv_sock > max_nfds)
max_nfds = srv_sock;
printf("g2=%d, srv=%d, MAX+1=%d\n", g2_sock, srv_sock, max_nfds + 1);
/* start the beacon thread */
if (bool_send_aprs) {
try {
aprs_future = std::async(std::launch::async, &CQnetGateway::APRSBeaconThread, this);
} catch (const std::exception &e) {
printf("Failed to start the APRSBeaconThread. Exception: %s\n", e.what());
}
if (aprs_future.valid())
printf("APRS beacon thread started\n");
}
try {
irc_data_future = std::async(std::launch::async, &CQnetGateway::GetIRCDataThread, this);
} catch (const std::exception &e) {
printf("Failed to start GetIRCDataThread. Exception: %s\n", e.what());
keep_running = false;
}
if (keep_running)
printf("get_irc_data thread started\n");
ii->kickWatchdog(IRCDDB_VERSION);
if (is_icom) {
// send INIT to Icom Stack
unsigned char buf[500];
memset(buf, 0, 10);
memcpy(buf, "INIT", 4);
buf[6] = 0x73U;
// we can use the module a band_addr for INIT
sendto(srv_sock, buf, 10, 0, (struct sockaddr *)&toRptr[0].band_addr, sizeof(struct sockaddr_in));
printf("Waiting for ICOM controller...\n");
// get the acknowledgement from the ICOM Stack
while (keep_running) {
socklen_t fromlength = sizeof(struct sockaddr_in);
int recvlen = recvfrom(srv_sock, buf, 500, 0, (struct sockaddr *)&fromRptr, &fromlength);
if (10==recvlen && 0==memcmp(buf, "INIT", 4) && 0x72U==buf[6] && 0x0U==buf[7]) {
OLD_REPLY_SEQ = 256U * buf[4] + buf[5];
NEW_REPLY_SEQ = OLD_REPLY_SEQ + 1;
G2_COUNTER_OUT = NEW_REPLY_SEQ;
unsigned int ui = G2_COUNTER_OUT;
printf("SYNC: old=%u, new=%u out=%u\n", OLD_REPLY_SEQ, NEW_REPLY_SEQ, ui);
break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
printf("Detected ICOM controller!\n");
} else
printf("Skipping ICOM initialization\n");
while (keep_running) { void CQnetGateway::ProcessTimeouts()
{
for (int i=0; i<3; i++) { for (int i=0; i<3; i++) {
time_t t_now;
/* echotest recording timed out? */ /* echotest recording timed out? */
if (recd[i].last_time != 0) { if (recd[i].last_time != 0) {
time(&t_now); time(&t_now);
@ -873,18 +785,11 @@ void CQnetGateway::process()
} }
} }
} }
}
/* wait 20 ms max */ void CQnetGateway::ProcessRouting()
FD_ZERO(&fdset); {
FD_SET(g2_sock, &fdset); SDSVT g2buf;
FD_SET(srv_sock, &fdset);
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 20000; /* 20 ms */
(void)select(max_nfds + 1, &fdset, 0, 0, &tv);
/* process packets coming from remote G2 */
if (FD_ISSET(g2_sock, &fdset)) {
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);
@ -899,9 +804,7 @@ void CQnetGateway::process()
} }
} }
if ( (g2buflen==56 || g2buflen==27) && 0==memcmp(g2buf.title, "DSVT", 4) && (g2buf.config==0x10 || g2buf.config==0x20) && g2buf.id==0x20) {
if ( (g2buflen==56 || g2buflen==27) && 0==memcmp(g2buf.title, "DSVT", 4) &&
(g2buf.config==0x10 || g2buf.config==0x20) && g2buf.id==0x20) {
if (g2buflen == 56) { if (g2buflen == 56) {
// Find out the local repeater module IP/port to send the data to // Find out the local repeater module IP/port to send the data to
@ -911,17 +814,9 @@ void CQnetGateway::process()
if (i>=0 && i<3) { 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
if ((toRptr[i].last_time == 0) && (band_txt[i].last_time == 0) && if (0==toRptr[i].last_time && 0==band_txt[i].last_time && (Flag_is_ok(g2buf.hdr.flag[0]) || 0x01U==g2buf.hdr.flag[0] || 0x40U==g2buf.hdr.flag[0])) {
((g2buf.hdr.flag[0] == 0x00) ||
(g2buf.hdr.flag[0] == 0x01) || /* allow the announcements from g2_link */
(g2buf.hdr.flag[0] == 0x08) ||
(g2buf.hdr.flag[0] == 0x20) ||
(g2buf.hdr.flag[0] == 0x28) ||
(g2buf.hdr.flag[0] == 0x40))) {
if (bool_qso_details) if (bool_qso_details)
printf("id=%04x G2 start, ur=%.8s r1=%.8s r2=%.8s my=%.8s/%.4s IP=%s:%u\n", printf("id=%04x G2 start, ur=%.8s r1=%.8s r2=%.8s my=%.8s/%.4s IP=%s:%u\n", ntohs(g2buf.streamid), g2buf.hdr.urcall, g2buf.hdr.rpt1, g2buf.hdr.rpt2, g2buf.hdr.mycall, g2buf.hdr.sfx, inet_ntoa(fromDst4.sin_addr), ntohs(fromDst4.sin_port));
ntohs(g2buf.streamid), g2buf.hdr.urcall, g2buf.hdr.rpt1, g2buf.hdr.rpt2,
g2buf.hdr.mycall, g2buf.hdr.sfx, inet_ntoa(fromDst4.sin_addr), ntohs(fromDst4.sin_port));
memcpy(rptrbuf.pkt_id, "DSTR", 4); memcpy(rptrbuf.pkt_id, "DSTR", 4);
rptrbuf.counter = htons(is_icom ? G2_COUNTER_OUT++ : toRptr[i].G2_COUNTER++); // bump the counter rptrbuf.counter = htons(is_icom ? G2_COUNTER_OUT++ : toRptr[i].G2_COUNTER++); // bump the counter
@ -1054,11 +949,37 @@ void CQnetGateway::process()
} }
} }
} }
FD_CLR (g2_sock,&fdset); }
}
void CQnetGateway::ProcessRepeater()
{
// dtmf stuff
int dtmf_buf_count[3] = {0, 0, 0};
char dtmf_buf[3][MAX_DTMF_BUF + 1] = { {""}, {""}, {""} };
int dtmf_last_frame[3] = { 0, 0, 0 };
unsigned int dtmf_counter[3] = { 0, 0, 0 };
// text stuff
bool new_group[3] = { true, true, true };
int header_type = 0;
short to_print[3] = { 0, 0, 0 };
bool ABC_grp[3] = { false, false, false };
bool C_seen[3] = { false, false, false };
unsigned char tmp_txt[3];
char temp_radio_user[CALL_SIZE + 1];
char temp_mod;
char arearp_cs[CALL_SIZE + 1];
char zonerp_cs[CALL_SIZE + 1];
char ip[IP_SIZE + 1];
char tempfile[FILENAME_MAX + 1];
long num_recs = 0L;
short int rec_len = 56;
SDSVT g2buf;
/* process data coming from local repeater modules */
if (FD_ISSET(srv_sock, &fdset)) {
socklen_t fromlen = sizeof(struct sockaddr_in); socklen_t fromlen = sizeof(struct sockaddr_in);
int recvlen = recvfrom(srv_sock, rptrbuf.pkt_id, 58, 0, (struct sockaddr *)&fromRptr, &fromlen); int recvlen = recvfrom(srv_sock, rptrbuf.pkt_id, 58, 0, (struct sockaddr *)&fromRptr, &fromlen);
@ -1078,9 +999,7 @@ void CQnetGateway::process()
sendto(srv_sock, rptrbuf.pkt_id, 10, 0, (struct sockaddr *)&toRptr[0].band_addr, sizeof(struct sockaddr_in)); sendto(srv_sock, rptrbuf.pkt_id, 10, 0, (struct sockaddr *)&toRptr[0].band_addr, sizeof(struct sockaddr_in));
// end of ICOM handshaking // end of ICOM handshaking
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
} else if ( (recvlen==58 || recvlen==29 || recvlen==32) && } else if ( (recvlen==58 || recvlen==29 || recvlen==32) && rptrbuf.flag[0]==0x73 && rptrbuf.flag[1]==0x12 && rptrbuf.flag[2]==0x0 && rptrbuf.vpkt.icm_id==0x20 && (rptrbuf.remaining==0x30 || rptrbuf.remaining==0x13 || rptrbuf.remaining==0x16) ) {
rptrbuf.flag[0]==0x73 && rptrbuf.flag[1]==0x12 && rptrbuf.flag[2]==0x0 && rptrbuf.vpkt.icm_id==0x20 &&
(rptrbuf.remaining==0x30 || rptrbuf.remaining==0x13 || rptrbuf.remaining==0x16) ) {
if (is_icom) { // acknowledge packet to ICOM if (is_icom) { // acknowledge packet to ICOM
SDSTR reply; SDSTR reply;
memcpy(reply.pkt_id, "DSTR", 4); memcpy(reply.pkt_id, "DSTR", 4);
@ -1093,15 +1012,9 @@ void CQnetGateway::process()
if (recvlen == 58) { if (recvlen == 58) {
if (bool_qso_details) if (bool_qso_details)
printf("id=%04x cntr=%04x start RPTR ur=%.8s r1=%.8s r2=%.8s my=%.8s/%.4s ip=%s\n", printf("id=%04x cntr=%04x start RPTR ur=%.8s r1=%.8s r2=%.8s my=%.8s/%.4s ip=%s\n", ntohs(rptrbuf.vpkt.streamid), ntohs(rptrbuf.counter), rptrbuf.vpkt.hdr.ur, rptrbuf.vpkt.hdr.r1, rptrbuf.vpkt.hdr.r2, rptrbuf.vpkt.hdr.my, rptrbuf.vpkt.hdr.nm, inet_ntoa(fromRptr.sin_addr));
ntohs(rptrbuf.vpkt.streamid), ntohs(rptrbuf.counter), rptrbuf.vpkt.hdr.ur, rptrbuf.vpkt.hdr.r1,
rptrbuf.vpkt.hdr.r2, rptrbuf.vpkt.hdr.my, rptrbuf.vpkt.hdr.nm, inet_ntoa(fromRptr.sin_addr));
if (0==memcmp(rptrbuf.vpkt.hdr.r1, OWNER.c_str(), 7) && // rpt1 is this repeater if (0==memcmp(rptrbuf.vpkt.hdr.r1, OWNER.c_str(), 7) && Flag_is_ok(rptrbuf.vpkt.hdr.flag[0])) {
(rptrbuf.vpkt.hdr.flag[0]==0x00 || // normal
rptrbuf.vpkt.hdr.flag[0]==0x08 || // EMR
rptrbuf.vpkt.hdr.flag[0]==0x20 || // BREAK
rptrbuf.vpkt.hdr.flag[0]==0x28)) { // EMR + BREAK (0x1, announcements are not allowed)
int i = rptrbuf.vpkt.hdr.r1[7] - 'A'; int i = rptrbuf.vpkt.hdr.r1[7] - 'A';
@ -1184,22 +1097,20 @@ void CQnetGateway::process()
if (mycall_valid == REG_NOERROR) if (mycall_valid == REG_NOERROR)
sendto(srv_sock, rptrbuf.pkt_id, recvlen, 0, (struct sockaddr *)&plug, sizeof(struct sockaddr_in)); sendto(srv_sock, rptrbuf.pkt_id, recvlen, 0, (struct sockaddr *)&plug, sizeof(struct sockaddr_in));
if (mycall_valid==REG_NOERROR && if ( mycall_valid==REG_NOERROR &&
memcmp(rptrbuf.vpkt.hdr.ur, "XRF", 3) && // not a reflector memcmp(rptrbuf.vpkt.hdr.ur, "XRF", 3) && // not a reflector
memcmp(rptrbuf.vpkt.hdr.ur, "REF", 3) && memcmp(rptrbuf.vpkt.hdr.ur, "REF", 3) &&
memcmp(rptrbuf.vpkt.hdr.ur, "DCS", 3) && memcmp(rptrbuf.vpkt.hdr.ur, "DCS", 3) &&
rptrbuf.vpkt.hdr.ur[0]!=' ' && // must have something rptrbuf.vpkt.hdr.ur[0]!=' ' && // must have something
memcmp(rptrbuf.vpkt.hdr.ur, "CQCQCQ", 6)) { // urcall is NOT CQCQCQ memcmp(rptrbuf.vpkt.hdr.ur, "CQCQCQ", 6) ) // urcall is NOT CQCQCQ
if (rptrbuf.vpkt.hdr.ur[0]=='/' && // repeater routing! {
if ( rptrbuf.vpkt.hdr.ur[0]=='/' && // repeater routing!
0==memcmp(rptrbuf.vpkt.hdr.r1, OWNER.c_str(), 7) && // rpt1 this repeater 0==memcmp(rptrbuf.vpkt.hdr.r1, OWNER.c_str(), 7) && // rpt1 this repeater
(rptrbuf.vpkt.hdr.r1[7]>='A' && rptrbuf.vpkt.hdr.r1[7]<='C') && // with a valid module (rptrbuf.vpkt.hdr.r1[7]>='A' && rptrbuf.vpkt.hdr.r1[7]<='C') && // with a valid module
0==memcmp(rptrbuf.vpkt.hdr.r2, OWNER.c_str(), 7) && // rpt2 is this repeater 0==memcmp(rptrbuf.vpkt.hdr.r2, OWNER.c_str(), 7) && // rpt2 is this repeater
rptrbuf.vpkt.hdr.r2[7]=='G' && // local Gateway rptrbuf.vpkt.hdr.r2[7]=='G' && // local Gateway
(rptrbuf.vpkt.hdr.flag[0]== 0x00 || // normal Flag_is_ok(rptrbuf.vpkt.hdr.flag[0]) )
rptrbuf.vpkt.hdr.flag[0]== 0x08 || // EMR {
rptrbuf.vpkt.hdr.flag[0]== 0x20 || // BK
rptrbuf.vpkt.hdr.flag[0]== 0x28)) {// EMR + BK
if (memcmp(rptrbuf.vpkt.hdr.ur+1, OWNER.c_str(), 6)) { // the value after the slash is NOT this repeater if (memcmp(rptrbuf.vpkt.hdr.ur+1, OWNER.c_str(), 6)) { // the value after the slash is NOT this repeater
int i = rptrbuf.vpkt.hdr.r1[7] - 'A'; int i = rptrbuf.vpkt.hdr.r1[7] - 'A';
@ -1273,16 +1184,13 @@ void CQnetGateway::process()
} }
} }
} }
} else if (memcmp(rptrbuf.vpkt.hdr.ur, OWNER.c_str(), 7) && // urcall is not this repeater }
else if (memcmp(rptrbuf.vpkt.hdr.ur, OWNER.c_str(), 7) && // urcall is not this repeater
0==memcmp(rptrbuf.vpkt.hdr.r1, OWNER.c_str(), 7) && // rpt1 is this repeater 0==memcmp(rptrbuf.vpkt.hdr.r1, OWNER.c_str(), 7) && // rpt1 is this repeater
(rptrbuf.vpkt.hdr.r1[7]>='A'&& rptrbuf.vpkt.hdr.r1[7]<='C') && // mod is A,B,C (rptrbuf.vpkt.hdr.r1[7]>='A'&& rptrbuf.vpkt.hdr.r1[7]<='C') && // mod is A,B,C
0==memcmp(rptrbuf.vpkt.hdr.r2, OWNER.c_str(), 7) && // rpt2 is this repeater 0==memcmp(rptrbuf.vpkt.hdr.r2, OWNER.c_str(), 7) && // rpt2 is this repeater
rptrbuf.vpkt.hdr.r2[7]=='G' && // local Gateway rptrbuf.vpkt.hdr.r2[7]=='G' && // local Gateway
Flag_is_ok(rptrbuf.vpkt.hdr.flag[0])) {
(rptrbuf.vpkt.hdr.flag[0]==0x00 || // normal
rptrbuf.vpkt.hdr.flag[0]==0x08 || // EMR
rptrbuf.vpkt.hdr.flag[0]==0x20 || // BK
rptrbuf.vpkt.hdr.flag[0]==0x28)) { // EMR + BK
memset(temp_radio_user, ' ', 8); memset(temp_radio_user, ' ', 8);
@ -1348,7 +1256,9 @@ void CQnetGateway::process()
time(&(to_remote_g2[i].last_time)); time(&(to_remote_g2[i].last_time));
} }
} }
} else { }
else
{
int i = rptrbuf.vpkt.hdr.r1[7] - 'A'; int i = rptrbuf.vpkt.hdr.r1[7] - 'A';
if (i>=0 && i<3) { if (i>=0 && i<3) {
@ -1396,13 +1306,15 @@ void CQnetGateway::process()
toRptr[i].sequence = rptrbuf.vpkt.ctrl; toRptr[i].sequence = rptrbuf.vpkt.ctrl;
} }
} }
} else }
else
printf("icom rule: no routing from %.8s to %s%c\n", rptrbuf.vpkt.hdr.r1, arearp_cs, temp_mod); printf("icom rule: no routing from %.8s to %s%c\n", rptrbuf.vpkt.hdr.r1, arearp_cs, temp_mod);
} }
} }
} }
} }
} else if (0 == memcmp(rptrbuf.vpkt.hdr.ur, " C0", 8)) { }
else if (0 == memcmp(rptrbuf.vpkt.hdr.ur, " C0", 8)) {
int i = rptrbuf.vpkt.hdr.r1[7] - 'A'; int i = rptrbuf.vpkt.hdr.r1[7] - 'A';
if (i>=0 && i<3) { if (i>=0 && i<3) {
@ -1414,7 +1326,8 @@ void CQnetGateway::process()
} else } else
printf("No voicemail to clear or still recording\n"); printf("No voicemail to clear or still recording\n");
} }
} else if (0 == memcmp(rptrbuf.vpkt.hdr.ur, " R0", 8)) { }
else if (0 == memcmp(rptrbuf.vpkt.hdr.ur, " R0", 8)) {
int i = rptrbuf.vpkt.hdr.r1[7] - 'A'; int i = rptrbuf.vpkt.hdr.r1[7] - 'A';
if (i>=0 && i<3) { if (i>=0 && i<3) {
@ -1428,7 +1341,8 @@ void CQnetGateway::process()
} else } else
printf("No voicemail to recall or still recording\n"); printf("No voicemail to recall or still recording\n");
} }
} else if (0 == memcmp(rptrbuf.vpkt.hdr.ur, " S0", 8)) { }
else if (0 == memcmp(rptrbuf.vpkt.hdr.ur, " S0", 8)) {
int i = rptrbuf.vpkt.hdr.r1[7] - 'A'; int i = rptrbuf.vpkt.hdr.r1[7] - 'A';
if (i>=0 && i<3) { if (i>=0 && i<3) {
@ -1474,7 +1388,8 @@ void CQnetGateway::process()
} }
} }
} }
} else if (0 == memcmp(rptrbuf.vpkt.hdr.ur, " E", 8)) { }
else if (0 == memcmp(rptrbuf.vpkt.hdr.ur, " E", 8)) {
int i = rptrbuf.vpkt.hdr.r1[7] - 'A'; int i = rptrbuf.vpkt.hdr.r1[7] - 'A';
if (i>=0 && i<3) { if (i>=0 && i<3) {
@ -1521,7 +1436,8 @@ void CQnetGateway::process()
} }
} }
/* check for cross-banding */ /* check for cross-banding */
} else if ( 0==memcmp(rptrbuf.vpkt.hdr.ur, "CQCQCQ", 6) && // yrcall is CQCQCQ }
else if ( 0==memcmp(rptrbuf.vpkt.hdr.ur, "CQCQCQ", 6) && // yrcall is CQCQCQ
0==memcmp(rptrbuf.vpkt.hdr.r2, OWNER.c_str(), 7) && // rpt1 is this repeater 0==memcmp(rptrbuf.vpkt.hdr.r2, OWNER.c_str(), 7) && // rpt1 is this repeater
0==memcmp(rptrbuf.vpkt.hdr.r1, OWNER.c_str(), 7) && // rpt2 is this repeater 0==memcmp(rptrbuf.vpkt.hdr.r1, OWNER.c_str(), 7) && // rpt2 is this repeater
(rptrbuf.vpkt.hdr.r1[7]>='A' && rptrbuf.vpkt.hdr.r1[7]<='C') && // mod of rpt1 is A,B,C (rptrbuf.vpkt.hdr.r1[7]>='A' && rptrbuf.vpkt.hdr.r1[7]<='C') && // mod of rpt1 is A,B,C
@ -1567,7 +1483,9 @@ void CQnetGateway::process()
} }
} }
} }
} else { // recvlen is 29 or 32 }
else
{ // recvlen is 29 or 32
for (int i=0; i<3; i++) { for (int i=0; i<3; i++) {
if (band_txt[i].streamID == rptrbuf.vpkt.streamid) { if (band_txt[i].streamID == rptrbuf.vpkt.streamid) {
time(&band_txt[i].last_time); time(&band_txt[i].last_time);
@ -1596,9 +1514,7 @@ void CQnetGateway::process()
dtmf_last_frame[i] = 0; dtmf_last_frame[i] = 0;
} }
ii->sendHeardWithTXStats(band_txt[i].lh_mycall, band_txt[i].lh_sfx, band_txt[i].lh_yrcall, band_txt[i].lh_rpt1, ii->sendHeardWithTXStats(band_txt[i].lh_mycall, band_txt[i].lh_sfx, band_txt[i].lh_yrcall, band_txt[i].lh_rpt1, band_txt[i].lh_rpt2, band_txt[i].flags[0], band_txt[i].flags[1], band_txt[i].flags[2], band_txt[i].num_dv_frames, band_txt[i].num_dv_silent_frames, band_txt[i].num_bit_errors);
band_txt[i].lh_rpt2, band_txt[i].flags[0], band_txt[i].flags[1], band_txt[i].flags[2], band_txt[i].num_dv_frames,
band_txt[i].num_dv_silent_frames, band_txt[i].num_bit_errors);
band_txt[i].streamID = 0; band_txt[i].streamID = 0;
band_txt[i].flags[0] = band_txt[i].flags[1] = band_txt[i].flags[2] = 0; band_txt[i].flags[0] = band_txt[i].flags[1] = band_txt[i].flags[2] = 0;
@ -1619,7 +1535,9 @@ void CQnetGateway::process()
band_txt[i].num_dv_silent_frames = 0; band_txt[i].num_dv_silent_frames = 0;
band_txt[i].num_bit_errors = 0; band_txt[i].num_bit_errors = 0;
} else { // not the end of the voice stream }
else
{ // not the end of the voice stream
int ber_data[3]; int ber_data[3];
int ber_errs = dstar_dv_decode(rptrbuf.vpkt.vasd.voice, ber_data); int ber_errs = dstar_dv_decode(rptrbuf.vpkt.vasd.voice, ber_data);
if (ber_data[0] == 0xf85) if (ber_data[0] == 0xf85)
@ -1670,7 +1588,8 @@ void CQnetGateway::process()
new_group[i] = false; new_group[i] = false;
to_print[i] = 0; to_print[i] = 0;
ABC_grp[i] = false; ABC_grp[i] = false;
} else if (header_type == 0x30) { /* GPS or GPS id or APRS */ }
else if (header_type == 0x30) { /* GPS or GPS id or APRS */
new_group[i] = false; new_group[i] = false;
to_print[i] = tmp_txt[0] & 0x0f; to_print[i] = tmp_txt[0] & 0x0f;
ABC_grp[i] = false; ABC_grp[i] = false;
@ -1720,7 +1639,9 @@ void CQnetGateway::process()
band_txt[i].temp_line_cnt = 0; band_txt[i].temp_line_cnt = 0;
} }
to_print[i] -= 2; to_print[i] -= 2;
} else { }
else
{
/* something went wrong? all bets are off */ /* something went wrong? all bets are off */
if (band_txt[i].temp_line_cnt > 200) { if (band_txt[i].temp_line_cnt > 200) {
printf("Reached the limit in the OLD gps mode\n"); printf("Reached the limit in the OLD gps mode\n");
@ -1752,7 +1673,8 @@ void CQnetGateway::process()
} }
to_print[i] --; to_print[i] --;
} }
} else if (header_type == 0x40) { /* ABC text */ }
else if (header_type == 0x40) { /* ABC text */
new_group[i] = false; new_group[i] = false;
to_print[i] = 3; to_print[i] = 3;
ABC_grp[i] = true; ABC_grp[i] = true;
@ -1790,7 +1712,9 @@ void CQnetGateway::process()
to_print[i] = 0; to_print[i] = 0;
ABC_grp[i] = false; ABC_grp[i] = false;
} }
} else { }
else
{
if (to_print[i] == 3) { if (to_print[i] == 3) {
if (ABC_grp[i]) { if (ABC_grp[i]) {
band_txt[i].txt[band_txt[i].txt_cnt] = tmp_txt[0] ^ 0x70; band_txt[i].txt[band_txt[i].txt_cnt] = tmp_txt[0] ^ 0x70;
@ -1828,9 +1752,7 @@ void CQnetGateway::process()
// band_txt[i].dest_rptr[0] = '\0'; // band_txt[i].dest_rptr[0] = '\0';
} }
ii->sendHeardWithTXMsg(band_txt[i].lh_mycall, band_txt[i].lh_sfx,band_txt[i].lh_yrcall, ii->sendHeardWithTXMsg(band_txt[i].lh_mycall, band_txt[i].lh_sfx,band_txt[i].lh_yrcall, band_txt[i].lh_rpt1, band_txt[i].lh_rpt2, band_txt[i].flags[0], band_txt[i].flags[1], band_txt[i].flags[2], band_txt[i].dest_rptr, band_txt[i].txt);
band_txt[i].lh_rpt1, band_txt[i].lh_rpt2, band_txt[i].flags[0], band_txt[i].flags[1],
band_txt[i].flags[2], band_txt[i].dest_rptr, band_txt[i].txt);
band_txt[i].txt_stats_sent = true; band_txt[i].txt_stats_sent = true;
} }
band_txt[i].txt_cnt = 0; band_txt[i].txt_cnt = 0;
@ -1875,9 +1797,7 @@ void CQnetGateway::process()
} }
band_txt[i].temp_line[0] = '\0'; band_txt[i].temp_line[0] = '\0';
band_txt[i].temp_line_cnt = 0; band_txt[i].temp_line_cnt = 0;
} else if (((tmp_txt[0] ^ 0x70) == '\n') || } else if (((tmp_txt[0] ^ 0x70) == '\n') || ((tmp_txt[1] ^ 0x4f) == '\n') || ((tmp_txt[2] ^ 0x93) == '\n')) {
((tmp_txt[1] ^ 0x4f) == '\n') ||
((tmp_txt[2] ^ 0x93) == '\n')) {
band_txt[i].temp_line[0] = '\0'; band_txt[i].temp_line[0] = '\0';
band_txt[i].temp_line_cnt = 0; band_txt[i].temp_line_cnt = 0;
} }
@ -1991,9 +1911,8 @@ void CQnetGateway::process()
to_remote_g2[i].last_time = 0; to_remote_g2[i].last_time = 0;
} }
break; break;
} else }
/* Is the data to be recorded for echotest */ else if (recd[i].fd>=0 && recd[i].streamid==rptrbuf.vpkt.streamid) { // Is the data to be recorded for echotest
if (recd[i].fd>=0 && recd[i].streamid==rptrbuf.vpkt.streamid) {
time(&recd[i].last_time); time(&recd[i].last_time);
memcpy(recbuf.title, "DSVT", 4); memcpy(recbuf.title, "DSVT", 4);
@ -2031,9 +1950,8 @@ void CQnetGateway::process()
} }
} }
break; break;
} else }
/* Is the data to be recorded for voicemail */ else if ((vm[i].fd >= 0) && (vm[i].streamid==rptrbuf.vpkt.streamid)) { // Is the data to be recorded for voicemail
if ((vm[i].fd >= 0) && (vm[i].streamid==rptrbuf.vpkt.streamid)) {
time(&vm[i].last_time); time(&vm[i].last_time);
memcpy(recbuf.title, "DSVT", 4); memcpy(recbuf.title, "DSVT", 4);
@ -2061,9 +1979,8 @@ void CQnetGateway::process()
// printf("Closed voicemail audio file:[%s]\n", vm[i].file); // printf("Closed voicemail audio file:[%s]\n", vm[i].file);
} }
break; break;
} else }
/* or maybe this is cross-banding data */ else if ((toRptr[i].streamid==rptrbuf.vpkt.streamid) && (toRptr[i].adr == fromRptr.sin_addr.s_addr)) { // or maybe this is cross-banding data
if ((toRptr[i].streamid==rptrbuf.vpkt.streamid) && (toRptr[i].adr == fromRptr.sin_addr.s_addr)) {
sendto(srv_sock, rptrbuf.pkt_id, 29, 0, (struct sockaddr *)&toRptr[i].band_addr, sizeof(struct sockaddr_in)); sendto(srv_sock, rptrbuf.pkt_id, 29, 0, (struct sockaddr *)&toRptr[i].band_addr, sizeof(struct sockaddr_in));
/* timeit */ /* timeit */
@ -2092,6 +2009,93 @@ void CQnetGateway::process()
} }
} }
} }
}
/* run the main loop for QnetGateway */
void CQnetGateway::Process()
{
dstar_dv_init();
int max_nfds = 0;
if (g2_sock > max_nfds)
max_nfds = g2_sock;
if (srv_sock > max_nfds)
max_nfds = srv_sock;
printf("g2=%d, srv=%d, MAX+1=%d\n", g2_sock, srv_sock, max_nfds + 1);
std::future<void> aprs_future, irc_data_future;
if (bool_send_aprs) { // start the beacon thread
try {
aprs_future = std::async(std::launch::async, &CQnetGateway::APRSBeaconThread, this);
} catch (const std::exception &e) {
printf("Failed to start the APRSBeaconThread. Exception: %s\n", e.what());
}
if (aprs_future.valid())
printf("APRS beacon thread started\n");
}
try { // start the IRC read thread
irc_data_future = std::async(std::launch::async, &CQnetGateway::GetIRCDataThread, this);
} catch (const std::exception &e) {
printf("Failed to start GetIRCDataThread. Exception: %s\n", e.what());
keep_running = false;
}
if (keep_running)
printf("get_irc_data thread started\n");
ii->kickWatchdog(IRCDDB_VERSION);
if (is_icom) {
// send INIT to Icom Stack
unsigned char buf[500];
memset(buf, 0, 10);
memcpy(buf, "INIT", 4);
buf[6] = 0x73U;
// we can use the module a band_addr for INIT
sendto(srv_sock, buf, 10, 0, (struct sockaddr *)&toRptr[0].band_addr, sizeof(struct sockaddr_in));
printf("Waiting for ICOM controller...\n");
// get the acknowledgement from the ICOM Stack
while (keep_running) {
socklen_t fromlength = sizeof(struct sockaddr_in);
int recvlen = recvfrom(srv_sock, buf, 500, 0, (struct sockaddr *)&fromRptr, &fromlength);
if (10==recvlen && 0==memcmp(buf, "INIT", 4) && 0x72U==buf[6] && 0x0U==buf[7]) {
OLD_REPLY_SEQ = 256U * buf[4] + buf[5];
NEW_REPLY_SEQ = OLD_REPLY_SEQ + 1;
G2_COUNTER_OUT = NEW_REPLY_SEQ;
unsigned int ui = G2_COUNTER_OUT;
printf("SYNC: old=%u, new=%u out=%u\n", OLD_REPLY_SEQ, NEW_REPLY_SEQ, ui);
break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
printf("Detected ICOM controller!\n");
} else
printf("Skipping ICOM initialization\n");
while (keep_running) {
ProcessTimeouts();
// wait 20 ms max
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(g2_sock, &fdset);
FD_SET(srv_sock, &fdset);
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 20000; // 20 ms
(void)select(max_nfds + 1, &fdset, 0, 0, &tv);
// process packets coming from remote G2
if (FD_ISSET(g2_sock, &fdset)) {
ProcessRouting();
FD_CLR (g2_sock,&fdset);
}
// process packets coming from local repeater modules
if (FD_ISSET(srv_sock, &fdset)) {
ProcessRepeater();
FD_CLR (srv_sock,&fdset); FD_CLR (srv_sock,&fdset);
} }
} }
@ -2461,7 +2465,7 @@ void CQnetGateway::qrgs_and_maps()
return; return;
} }
int CQnetGateway::init(char *cfgfile) int CQnetGateway::Init(char *cfgfile)
{ {
short int i; short int i;
struct sigaction act; struct sigaction act;
@ -2932,8 +2936,8 @@ int main(int argc, char **argv)
return 1; return 1;
} }
CQnetGateway QnetGateway; CQnetGateway QnetGateway;
if (QnetGateway.init(argv[1])) if (QnetGateway.Init(argv[1]))
return 1; return 1;
QnetGateway.process(); QnetGateway.Process();
printf("Leaving processing loop...\n"); printf("Leaving processing loop...\n");
} }

@ -85,8 +85,8 @@ class CQnetGateway {
public: public:
CQnetGateway(); CQnetGateway();
~CQnetGateway(); ~CQnetGateway();
void process(); void Process();
int init(char *cfgfile); int Init(char *cfgfile);
private: private:
bool is_icom, is_not_icom; bool is_icom, is_not_icom;
@ -157,6 +157,10 @@ private:
void PlayFileThread(char *file); void PlayFileThread(char *file);
void compute_aprs_hash(); void compute_aprs_hash();
void APRSBeaconThread(); void APRSBeaconThread();
void ProcessTimeouts();
void ProcessRouting();
void ProcessRepeater();
bool Flag_is_ok(unsigned char flag);
// read configuration file // read configuration file
bool read_config(char *); bool read_config(char *);

Loading…
Cancel
Save

Powered by TurnKey Linux.