|
|
|
@ -961,11 +961,11 @@ void CQnetGateway::ProcessRepeater()
|
|
|
|
|
|
|
|
|
|
|
|
// text stuff
|
|
|
|
// text stuff
|
|
|
|
bool new_group[3] = { true, true, true };
|
|
|
|
bool new_group[3] = { true, true, true };
|
|
|
|
int header_type = 0;
|
|
|
|
//int header_type = 0;
|
|
|
|
short to_print[3] = { 0, 0, 0 };
|
|
|
|
short to_print[3] = { 0, 0, 0 };
|
|
|
|
bool ABC_grp[3] = { false, false, false };
|
|
|
|
bool ABC_grp[3] = { false, false, false };
|
|
|
|
bool C_seen[3] = { false, false, false };
|
|
|
|
bool C_seen[3] = { false, false, false };
|
|
|
|
unsigned char tmp_txt[3];
|
|
|
|
//unsigned char tmp_txt[3];
|
|
|
|
|
|
|
|
|
|
|
|
char temp_radio_user[CALL_SIZE + 1];
|
|
|
|
char temp_radio_user[CALL_SIZE + 1];
|
|
|
|
char temp_mod;
|
|
|
|
char temp_mod;
|
|
|
|
@ -1572,22 +1572,161 @@ void CQnetGateway::ProcessRepeater()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (recvlen == 29)
|
|
|
|
if (recvlen == 29)
|
|
|
|
memcpy(tmp_txt, rptrbuf.vpkt.vasd.text, 3);
|
|
|
|
ProcessSlowData(rptrbuf.vpkt.vasd.text, rptrbuf.vpkt.streamid, new_group, to_print, ABC_grp, C_seen);
|
|
|
|
else
|
|
|
|
else
|
|
|
|
memcpy(tmp_txt, rptrbuf.vpkt.vasd1.text, 3);
|
|
|
|
ProcessSlowData(rptrbuf.vpkt.vasd1.text, rptrbuf.vpkt.streamid, new_group, to_print, ABC_grp, C_seen);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* send data to qnlink */
|
|
|
|
|
|
|
|
sendto(srv_sock, rptrbuf.pkt_id, recvlen, 0, (struct sockaddr *)&plug, sizeof(struct sockaddr_in));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* aprs processing */
|
|
|
|
|
|
|
|
if (bool_send_aprs)
|
|
|
|
|
|
|
|
// streamID seq audio+text size
|
|
|
|
|
|
|
|
aprs->ProcessText(rptrbuf.vpkt.streamid, rptrbuf.vpkt.ctrl, rptrbuf.vpkt.vasd.voice, (recvlen == 29)?12:15);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i=0; i<3; i++) {
|
|
|
|
|
|
|
|
/* find out if data must go to the remote G2 */
|
|
|
|
|
|
|
|
if (to_remote_g2[i].streamid == rptrbuf.vpkt.streamid) {
|
|
|
|
|
|
|
|
memcpy(g2buf.title, "DSVT", 4);
|
|
|
|
|
|
|
|
g2buf.config = 0x20;
|
|
|
|
|
|
|
|
g2buf.flaga[0] = g2buf.flaga[1] = g2buf.flaga[2] = 0;
|
|
|
|
|
|
|
|
memcpy(&g2buf.id, &rptrbuf.vpkt.icm_id, 7);
|
|
|
|
|
|
|
|
if (recvlen == 29)
|
|
|
|
|
|
|
|
memcpy(g2buf.vasd.voice, rptrbuf.vpkt.vasd.voice, 12);
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
memcpy(g2buf.vasd.voice, rptrbuf.vpkt.vasd1.voice, 12);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t address = to_remote_g2[i].toDst4.sin_addr.s_addr;
|
|
|
|
|
|
|
|
// if the address is in the portmap, we'll use that 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);
|
|
|
|
|
|
|
|
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));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Is this the end-of-stream */
|
|
|
|
|
|
|
|
if (rptrbuf.vpkt.ctrl & 0x40) {
|
|
|
|
|
|
|
|
memset(&to_remote_g2[i].toDst4,0,sizeof(struct sockaddr_in));
|
|
|
|
|
|
|
|
to_remote_g2[i].streamid = 0;
|
|
|
|
|
|
|
|
to_remote_g2[i].last_time = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (recd[i].fd>=0 && recd[i].streamid==rptrbuf.vpkt.streamid) { // Is the data to be recorded for echotest
|
|
|
|
|
|
|
|
time(&recd[i].last_time);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
memcpy(recbuf.title, "DSVT", 4);
|
|
|
|
|
|
|
|
recbuf.config = 0x20;
|
|
|
|
|
|
|
|
recbuf.id = rptrbuf.vpkt.icm_id;
|
|
|
|
|
|
|
|
recbuf.flaga[0] = recbuf.flaga[1] = recbuf.flaga[20] = 0;
|
|
|
|
|
|
|
|
recbuf.flagb[0] = rptrbuf.vpkt.dst_rptr_id;
|
|
|
|
|
|
|
|
recbuf.flagb[1] = rptrbuf.vpkt.snd_rptr_id;
|
|
|
|
|
|
|
|
recbuf.flagb[2] = rptrbuf.vpkt.snd_term_id;
|
|
|
|
|
|
|
|
memcpy(&recbuf.streamid, &rptrbuf.vpkt.streamid, 3);
|
|
|
|
|
|
|
|
if (recvlen == 29)
|
|
|
|
|
|
|
|
memcpy(recbuf.vasd.voice, rptrbuf.vpkt.vasd.voice, 12);
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
memcpy(recbuf.vasd.voice, rptrbuf.vpkt.vasd1.voice, 12);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rec_len = 27;
|
|
|
|
|
|
|
|
(void)write(recd[i].fd, &rec_len, 2);
|
|
|
|
|
|
|
|
(void)write(recd[i].fd, &recbuf, rec_len);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((rptrbuf.vpkt.ctrl & 0x40) != 0) {
|
|
|
|
|
|
|
|
recd[i].streamid = 0;
|
|
|
|
|
|
|
|
recd[i].last_time = 0;
|
|
|
|
|
|
|
|
close(recd[i].fd);
|
|
|
|
|
|
|
|
recd[i].fd = -1;
|
|
|
|
|
|
|
|
// printf("Closed echotest audio file:[%s]\n", recd[i].file);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* we are in echotest mode, so play it back */
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
std::async(std::launch::async, &CQnetGateway::PlayFileThread, this, recd[i].file);
|
|
|
|
|
|
|
|
} catch (const std::exception &e) {
|
|
|
|
|
|
|
|
printf("failed to start PlayFileThread. Exception: %s\n", e.what());
|
|
|
|
|
|
|
|
// When the echotest thread runs, it deletes the file,
|
|
|
|
|
|
|
|
// Because the echotest thread did NOT start, we delete the file here
|
|
|
|
|
|
|
|
unlink(recd[i].file);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if ((vm[i].fd >= 0) && (vm[i].streamid==rptrbuf.vpkt.streamid)) { // Is the data to be recorded for voicemail
|
|
|
|
|
|
|
|
time(&vm[i].last_time);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
memcpy(recbuf.title, "DSVT", 4);
|
|
|
|
|
|
|
|
recbuf.config = 0x20;
|
|
|
|
|
|
|
|
recbuf.flaga[0] = recbuf.flaga[1] = recbuf.flaga[2] = 0;
|
|
|
|
|
|
|
|
recbuf.id = rptrbuf.vpkt.icm_id;
|
|
|
|
|
|
|
|
recbuf.flagb[0] = rptrbuf.vpkt.dst_rptr_id;
|
|
|
|
|
|
|
|
recbuf.flagb[1] = rptrbuf.vpkt.snd_rptr_id;
|
|
|
|
|
|
|
|
recbuf.flagb[2] = rptrbuf.vpkt.snd_term_id;
|
|
|
|
|
|
|
|
memcpy(&recbuf.streamid, &rptrbuf.vpkt.streamid, 3);
|
|
|
|
|
|
|
|
if (recvlen == 29)
|
|
|
|
|
|
|
|
memcpy(recbuf.vasd.voice, rptrbuf.vpkt.vasd.voice, 12);
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
memcpy(recbuf.vasd.voice, rptrbuf.vpkt.vasd1.voice, 12);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rec_len = 27;
|
|
|
|
|
|
|
|
(void)write(vm[i].fd, &rec_len, 2);
|
|
|
|
|
|
|
|
(void)write(vm[i].fd, &recbuf, rec_len);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((rptrbuf.vpkt.ctrl & 0x40) != 0) {
|
|
|
|
|
|
|
|
vm[i].streamid = 0;
|
|
|
|
|
|
|
|
vm[i].last_time = 0;
|
|
|
|
|
|
|
|
close(vm[i].fd);
|
|
|
|
|
|
|
|
vm[i].fd = -1;
|
|
|
|
|
|
|
|
// printf("Closed voicemail audio file:[%s]\n", vm[i].file);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if ((toRptr[i].streamid==rptrbuf.vpkt.streamid) && (toRptr[i].adr == fromRptr.sin_addr.s_addr)) { // or maybe this is cross-banding data
|
|
|
|
|
|
|
|
sendto(srv_sock, rptrbuf.pkt_id, 29, 0, (struct sockaddr *)&toRptr[i].band_addr, sizeof(struct sockaddr_in));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* timeit */
|
|
|
|
|
|
|
|
time(&toRptr[i].last_time);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* bump G2 counter */
|
|
|
|
|
|
|
|
if (is_icom)
|
|
|
|
|
|
|
|
G2_COUNTER_OUT++;
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
toRptr[i].G2_COUNTER ++;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
toRptr[i].sequence = rptrbuf.vpkt.ctrl;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* End of stream ? */
|
|
|
|
|
|
|
|
if (rptrbuf.vpkt.ctrl & 0x40) {
|
|
|
|
|
|
|
|
toRptr[i].last_time = 0;
|
|
|
|
|
|
|
|
toRptr[i].streamid = 0;
|
|
|
|
|
|
|
|
toRptr[i].adr = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (bool_qso_details && rptrbuf.vpkt.ctrl&0x40)
|
|
|
|
|
|
|
|
printf("id=%04x cntr=%04x END RPTR\n", ntohs(rptrbuf.vpkt.streamid), ntohs(rptrbuf.counter));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CQnetGateway::ProcessSlowData(unsigned char *data, unsigned short sid, bool *new_group, short *to_print, bool *ABC_grp, bool *C_seen)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
unsigned char header_type;
|
|
|
|
|
|
|
|
|
|
|
|
/* extract 20-byte RADIO ID */
|
|
|
|
/* extract 20-byte RADIO ID */
|
|
|
|
if ((tmp_txt[0] != 0x55) || (tmp_txt[1] != 0x2d) || (tmp_txt[2] != 0x16)) {
|
|
|
|
if ((data[0] != 0x55) || (data[1] != 0x2d) || (data[2] != 0x16)) {
|
|
|
|
|
|
|
|
|
|
|
|
// first, unscramble
|
|
|
|
// first, unscramble
|
|
|
|
tmp_txt[0] ^= 0x70u;
|
|
|
|
unsigned char tmp0 = data[0] ^ 0x70u;
|
|
|
|
tmp_txt[1] ^= 0x4fu;
|
|
|
|
unsigned char tmp1 = data[1] ^ 0x4fu;
|
|
|
|
tmp_txt[2] ^= 0x93u;
|
|
|
|
unsigned char tmp2 = data[2] ^ 0x93u;
|
|
|
|
|
|
|
|
|
|
|
|
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 == sid) {
|
|
|
|
if (new_group[i]) {
|
|
|
|
if (new_group[i]) {
|
|
|
|
header_type = tmp_txt[0] & 0xf0;
|
|
|
|
header_type = tmp0 & 0xf0;
|
|
|
|
|
|
|
|
|
|
|
|
// header squelch
|
|
|
|
// header squelch
|
|
|
|
if ((header_type == 0x50) || (header_type == 0xc0)) {
|
|
|
|
if ((header_type == 0x50) || (header_type == 0xc0)) {
|
|
|
|
@ -1597,7 +1736,7 @@ void CQnetGateway::ProcessRepeater()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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] = tmp0 & 0x0f;
|
|
|
|
ABC_grp[i] = false;
|
|
|
|
ABC_grp[i] = false;
|
|
|
|
if (to_print[i] > 5)
|
|
|
|
if (to_print[i] > 5)
|
|
|
|
to_print[i] = 5;
|
|
|
|
to_print[i] = 5;
|
|
|
|
@ -1613,22 +1752,22 @@ void CQnetGateway::ProcessRepeater()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* fresh GPS string, re-initialize */
|
|
|
|
/* fresh GPS string, re-initialize */
|
|
|
|
if ((to_print[i] == 5) && (tmp_txt[1] == '$')) {
|
|
|
|
if ((to_print[i] == 5) && (tmp1 == '$')) {
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* do not copy CR, NL */
|
|
|
|
/* do not copy CR, NL */
|
|
|
|
if ((tmp_txt[1] != '\r') && (tmp_txt[1] != '\n')) {
|
|
|
|
if ((tmp1 != '\r') && (tmp1 != '\n')) {
|
|
|
|
band_txt[i].temp_line[band_txt[i].temp_line_cnt] = tmp_txt[1];
|
|
|
|
band_txt[i].temp_line[band_txt[i].temp_line_cnt] = tmp1;
|
|
|
|
band_txt[i].temp_line_cnt++;
|
|
|
|
band_txt[i].temp_line_cnt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((tmp_txt[2] != '\r') && (tmp_txt[2] != '\n')) {
|
|
|
|
if ((tmp2 != '\r') && (tmp2 != '\n')) {
|
|
|
|
band_txt[i].temp_line[band_txt[i].temp_line_cnt] = tmp_txt[2];
|
|
|
|
band_txt[i].temp_line[band_txt[i].temp_line_cnt] = tmp2;
|
|
|
|
band_txt[i].temp_line_cnt++;
|
|
|
|
band_txt[i].temp_line_cnt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ((tmp_txt[1] == '\r') || (tmp_txt[2] == '\r')) {
|
|
|
|
if ((tmp1 == '\r') || (tmp2 == '\r')) {
|
|
|
|
if (memcmp(band_txt[i].temp_line, "$GPRMC", 6) == 0) {
|
|
|
|
if (memcmp(band_txt[i].temp_line, "$GPRMC", 6) == 0) {
|
|
|
|
memcpy(band_txt[i].gprmc, band_txt[i].temp_line, band_txt[i].temp_line_cnt);
|
|
|
|
memcpy(band_txt[i].gprmc, band_txt[i].temp_line, band_txt[i].temp_line_cnt);
|
|
|
|
band_txt[i].gprmc[band_txt[i].temp_line_cnt] = '\0';
|
|
|
|
band_txt[i].gprmc[band_txt[i].temp_line_cnt] = '\0';
|
|
|
|
@ -1640,7 +1779,7 @@ void CQnetGateway::ProcessRepeater()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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[1] == '\n') || (tmp_txt[2] == '\n')) {
|
|
|
|
} else if ((tmp1 == '\n') || (tmp2 == '\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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -1654,12 +1793,12 @@ void CQnetGateway::ProcessRepeater()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* do not copy CR, NL */
|
|
|
|
/* do not copy CR, NL */
|
|
|
|
if ((tmp_txt[1] != '\r') && (tmp_txt[1] != '\n')) {
|
|
|
|
if ((tmp1 != '\r') && (tmp1 != '\n')) {
|
|
|
|
band_txt[i].temp_line[band_txt[i].temp_line_cnt] = tmp_txt[1];
|
|
|
|
band_txt[i].temp_line[band_txt[i].temp_line_cnt] = tmp1;
|
|
|
|
band_txt[i].temp_line_cnt++;
|
|
|
|
band_txt[i].temp_line_cnt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (tmp_txt[1] == '\r') {
|
|
|
|
if (tmp1 == '\r') {
|
|
|
|
if (memcmp(band_txt[i].temp_line, "$GPRMC", 6) == 0) {
|
|
|
|
if (memcmp(band_txt[i].temp_line, "$GPRMC", 6) == 0) {
|
|
|
|
memcpy(band_txt[i].gprmc, band_txt[i].temp_line, band_txt[i].temp_line_cnt);
|
|
|
|
memcpy(band_txt[i].gprmc, band_txt[i].temp_line, band_txt[i].temp_line_cnt);
|
|
|
|
band_txt[i].gprmc[band_txt[i].temp_line_cnt] = '\0';
|
|
|
|
band_txt[i].gprmc[band_txt[i].temp_line_cnt] = '\0';
|
|
|
|
@ -1671,7 +1810,7 @@ void CQnetGateway::ProcessRepeater()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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[1] == '\n') {
|
|
|
|
} else if (tmp1 == '\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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -1682,12 +1821,12 @@ void CQnetGateway::ProcessRepeater()
|
|
|
|
new_group[i] = false;
|
|
|
|
new_group[i] = false;
|
|
|
|
to_print[i] = 3;
|
|
|
|
to_print[i] = 3;
|
|
|
|
ABC_grp[i] = true;
|
|
|
|
ABC_grp[i] = true;
|
|
|
|
C_seen[i] = ((tmp_txt[0] & 0x0f) == 0x03) ? true : false;
|
|
|
|
C_seen[i] = ((tmp0 & 0x0f) == 0x03) ? true : false;
|
|
|
|
|
|
|
|
|
|
|
|
band_txt[i].txt[band_txt[i].txt_cnt] = tmp_txt[1];
|
|
|
|
band_txt[i].txt[band_txt[i].txt_cnt] = tmp1;
|
|
|
|
band_txt[i].txt_cnt++;
|
|
|
|
band_txt[i].txt_cnt++;
|
|
|
|
|
|
|
|
|
|
|
|
band_txt[i].txt[band_txt[i].txt_cnt] = tmp_txt[2];
|
|
|
|
band_txt[i].txt[band_txt[i].txt_cnt] = tmp2;
|
|
|
|
band_txt[i].txt_cnt++;
|
|
|
|
band_txt[i].txt_cnt++;
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
@ -1696,15 +1835,9 @@ void CQnetGateway::ProcessRepeater()
|
|
|
|
so blank out the codes.
|
|
|
|
so blank out the codes.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
if (band_txt[i].txt_stats_sent) {
|
|
|
|
if (band_txt[i].txt_stats_sent) {
|
|
|
|
if (recvlen == 29) {
|
|
|
|
data[0] = 0x70;
|
|
|
|
rptrbuf.vpkt.vasd.text[0] = 0x70;
|
|
|
|
data[1] = 0x4f;
|
|
|
|
rptrbuf.vpkt.vasd.text[1] = 0x4f;
|
|
|
|
data[2] = 0x93;
|
|
|
|
rptrbuf.vpkt.vasd.text[2] = 0x93;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
rptrbuf.vpkt.vasd1.text[0] = 0x70;
|
|
|
|
|
|
|
|
rptrbuf.vpkt.vasd1.text[1] = 0x4f;
|
|
|
|
|
|
|
|
rptrbuf.vpkt.vasd1.text[2] = 0x93;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (band_txt[i].txt_cnt >= 20) {
|
|
|
|
if (band_txt[i].txt_cnt >= 20) {
|
|
|
|
@ -1733,28 +1866,22 @@ void CQnetGateway::ProcessRepeater()
|
|
|
|
} 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];
|
|
|
|
band_txt[i].txt[band_txt[i].txt_cnt] = tmp0;
|
|
|
|
band_txt[i].txt_cnt++;
|
|
|
|
band_txt[i].txt_cnt++;
|
|
|
|
|
|
|
|
|
|
|
|
band_txt[i].txt[band_txt[i].txt_cnt] = tmp_txt[1];
|
|
|
|
band_txt[i].txt[band_txt[i].txt_cnt] = tmp1;
|
|
|
|
band_txt[i].txt_cnt++;
|
|
|
|
band_txt[i].txt_cnt++;
|
|
|
|
|
|
|
|
|
|
|
|
band_txt[i].txt[band_txt[i].txt_cnt] = tmp_txt[2];
|
|
|
|
band_txt[i].txt[band_txt[i].txt_cnt] = tmp2;
|
|
|
|
band_txt[i].txt_cnt++;
|
|
|
|
band_txt[i].txt_cnt++;
|
|
|
|
|
|
|
|
|
|
|
|
/* We should NOT see any more text,
|
|
|
|
/* We should NOT see any more text,
|
|
|
|
if we already processed text,
|
|
|
|
if we already processed text,
|
|
|
|
so blank out the codes. */
|
|
|
|
so blank out the codes. */
|
|
|
|
if (band_txt[i].txt_stats_sent) {
|
|
|
|
if (band_txt[i].txt_stats_sent) {
|
|
|
|
if (recvlen == 29) {
|
|
|
|
data[0] = 0x70;
|
|
|
|
rptrbuf.vpkt.vasd.text[0] = 0x70;
|
|
|
|
data[1] = 0x4f;
|
|
|
|
rptrbuf.vpkt.vasd.text[1] = 0x4f;
|
|
|
|
data[2] = 0x93;
|
|
|
|
rptrbuf.vpkt.vasd.text[2] = 0x93;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
rptrbuf.vpkt.vasd1.text[0] = 0x70;
|
|
|
|
|
|
|
|
rptrbuf.vpkt.vasd1.text[1] = 0x4f;
|
|
|
|
|
|
|
|
rptrbuf.vpkt.vasd1.text[2] = 0x93;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ((band_txt[i].txt_cnt >= 20) || C_seen[i]) {
|
|
|
|
if ((band_txt[i].txt_cnt >= 20) || C_seen[i]) {
|
|
|
|
@ -1793,20 +1920,20 @@ void CQnetGateway::ProcessRepeater()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* do not copy CR, NL */
|
|
|
|
/* do not copy CR, NL */
|
|
|
|
if ((tmp_txt[0] != '\r') && (tmp_txt[0] != '\n')) {
|
|
|
|
if ((tmp0 != '\r') && (tmp0 != '\n')) {
|
|
|
|
band_txt[i].temp_line[band_txt[i].temp_line_cnt] = tmp_txt[0];
|
|
|
|
band_txt[i].temp_line[band_txt[i].temp_line_cnt] = tmp0;
|
|
|
|
band_txt[i].temp_line_cnt++;
|
|
|
|
band_txt[i].temp_line_cnt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((tmp_txt[1] != '\r') && (tmp_txt[1] != '\n')) {
|
|
|
|
if ((tmp1 != '\r') && (tmp1 != '\n')) {
|
|
|
|
band_txt[i].temp_line[band_txt[i].temp_line_cnt] = tmp_txt[1];
|
|
|
|
band_txt[i].temp_line[band_txt[i].temp_line_cnt] = tmp1;
|
|
|
|
band_txt[i].temp_line_cnt++;
|
|
|
|
band_txt[i].temp_line_cnt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((tmp_txt[2] != '\r') && (tmp_txt[2] != '\n')) {
|
|
|
|
if ((tmp2 != '\r') && (tmp2 != '\n')) {
|
|
|
|
band_txt[i].temp_line[band_txt[i].temp_line_cnt] = tmp_txt[2];
|
|
|
|
band_txt[i].temp_line[band_txt[i].temp_line_cnt] = tmp2;
|
|
|
|
band_txt[i].temp_line_cnt++;
|
|
|
|
band_txt[i].temp_line_cnt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ( (tmp_txt[0] == '\r') || (tmp_txt[1] == '\r') || (tmp_txt[2] == '\r') ) {
|
|
|
|
if ( (tmp0 == '\r') || (tmp1 == '\r') || (tmp2 == '\r') ) {
|
|
|
|
if (memcmp(band_txt[i].temp_line, "$GPRMC", 6) == 0) {
|
|
|
|
if (memcmp(band_txt[i].temp_line, "$GPRMC", 6) == 0) {
|
|
|
|
memcpy(band_txt[i].gprmc, band_txt[i].temp_line, band_txt[i].temp_line_cnt);
|
|
|
|
memcpy(band_txt[i].gprmc, band_txt[i].temp_line, band_txt[i].temp_line_cnt);
|
|
|
|
band_txt[i].gprmc[band_txt[i].temp_line_cnt] = '\0';
|
|
|
|
band_txt[i].gprmc[band_txt[i].temp_line_cnt] = '\0';
|
|
|
|
@ -1819,7 +1946,7 @@ void CQnetGateway::ProcessRepeater()
|
|
|
|
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] == '\n') || (tmp_txt[1] == '\n') ||(tmp_txt[2] == '\n')) {
|
|
|
|
else if ((tmp0 == '\n') || (tmp1 == '\n') ||(tmp2 == '\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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -1833,16 +1960,16 @@ void CQnetGateway::ProcessRepeater()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* do not copy CR, NL */
|
|
|
|
/* do not copy CR, NL */
|
|
|
|
if ((tmp_txt[0] != '\r') && (tmp_txt[0] != '\n')) {
|
|
|
|
if ((tmp0 != '\r') && (tmp0 != '\n')) {
|
|
|
|
band_txt[i].temp_line[band_txt[i].temp_line_cnt] = tmp_txt[0];
|
|
|
|
band_txt[i].temp_line[band_txt[i].temp_line_cnt] = tmp0;
|
|
|
|
band_txt[i].temp_line_cnt++;
|
|
|
|
band_txt[i].temp_line_cnt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((tmp_txt[1] != '\r') && (tmp_txt[1] != '\n')) {
|
|
|
|
if ((tmp1 != '\r') && (tmp1 != '\n')) {
|
|
|
|
band_txt[i].temp_line[band_txt[i].temp_line_cnt] = tmp_txt[1];
|
|
|
|
band_txt[i].temp_line[band_txt[i].temp_line_cnt] = tmp1;
|
|
|
|
band_txt[i].temp_line_cnt++;
|
|
|
|
band_txt[i].temp_line_cnt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ((tmp_txt[0] == '\r') || (tmp_txt[1] == '\r')) {
|
|
|
|
if ((tmp0 == '\r') || (tmp1 == '\r')) {
|
|
|
|
if (memcmp(band_txt[i].temp_line, "$GPRMC", 6) == 0) {
|
|
|
|
if (memcmp(band_txt[i].temp_line, "$GPRMC", 6) == 0) {
|
|
|
|
memcpy(band_txt[i].gprmc, band_txt[i].temp_line, band_txt[i].temp_line_cnt);
|
|
|
|
memcpy(band_txt[i].gprmc, band_txt[i].temp_line, band_txt[i].temp_line_cnt);
|
|
|
|
band_txt[i].gprmc[band_txt[i].temp_line_cnt] = '\0';
|
|
|
|
band_txt[i].gprmc[band_txt[i].temp_line_cnt] = '\0';
|
|
|
|
@ -1854,7 +1981,7 @@ void CQnetGateway::ProcessRepeater()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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] == '\n') || (tmp_txt[1] == '\n')) {
|
|
|
|
} else if ((tmp0 == '\n') || (tmp1 == '\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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -1867,12 +1994,12 @@ void CQnetGateway::ProcessRepeater()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* do not copy CR, NL */
|
|
|
|
/* do not copy CR, NL */
|
|
|
|
if ((tmp_txt[0] != '\r') && (tmp_txt[0] != '\n')) {
|
|
|
|
if ((tmp0 != '\r') && (tmp0 != '\n')) {
|
|
|
|
band_txt[i].temp_line[band_txt[i].temp_line_cnt] = tmp_txt[0];
|
|
|
|
band_txt[i].temp_line[band_txt[i].temp_line_cnt] = tmp0;
|
|
|
|
band_txt[i].temp_line_cnt++;
|
|
|
|
band_txt[i].temp_line_cnt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (tmp_txt[0] == '\r') {
|
|
|
|
if (tmp0 == '\r') {
|
|
|
|
if (memcmp(band_txt[i].temp_line, "$GPRMC", 6) == 0) {
|
|
|
|
if (memcmp(band_txt[i].temp_line, "$GPRMC", 6) == 0) {
|
|
|
|
memcpy(band_txt[i].gprmc, band_txt[i].temp_line, band_txt[i].temp_line_cnt);
|
|
|
|
memcpy(band_txt[i].gprmc, band_txt[i].temp_line, band_txt[i].temp_line_cnt);
|
|
|
|
band_txt[i].gprmc[band_txt[i].temp_line_cnt] = '\0';
|
|
|
|
band_txt[i].gprmc[band_txt[i].temp_line_cnt] = '\0';
|
|
|
|
@ -1884,7 +2011,7 @@ void CQnetGateway::ProcessRepeater()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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] == '\n') {
|
|
|
|
} else if (tmp0 == '\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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -1897,140 +2024,6 @@ void CQnetGateway::ProcessRepeater()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* send data to qnlink */
|
|
|
|
|
|
|
|
sendto(srv_sock, rptrbuf.pkt_id, recvlen, 0, (struct sockaddr *)&plug, sizeof(struct sockaddr_in));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* aprs processing */
|
|
|
|
|
|
|
|
if (bool_send_aprs)
|
|
|
|
|
|
|
|
// streamID seq audio+text size
|
|
|
|
|
|
|
|
aprs->ProcessText(rptrbuf.vpkt.streamid, rptrbuf.vpkt.ctrl, rptrbuf.vpkt.vasd.voice, (recvlen == 29)?12:15);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i=0; i<3; i++) {
|
|
|
|
|
|
|
|
/* find out if data must go to the remote G2 */
|
|
|
|
|
|
|
|
if (to_remote_g2[i].streamid == rptrbuf.vpkt.streamid) {
|
|
|
|
|
|
|
|
memcpy(g2buf.title, "DSVT", 4);
|
|
|
|
|
|
|
|
g2buf.config = 0x20;
|
|
|
|
|
|
|
|
g2buf.flaga[0] = g2buf.flaga[1] = g2buf.flaga[2] = 0;
|
|
|
|
|
|
|
|
memcpy(&g2buf.id, &rptrbuf.vpkt.icm_id, 7);
|
|
|
|
|
|
|
|
if (recvlen == 29)
|
|
|
|
|
|
|
|
memcpy(g2buf.vasd.voice, rptrbuf.vpkt.vasd.voice, 12);
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
memcpy(g2buf.vasd.voice, rptrbuf.vpkt.vasd1.voice, 12);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t address = to_remote_g2[i].toDst4.sin_addr.s_addr;
|
|
|
|
|
|
|
|
// if the address is in the portmap, we'll use that 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);
|
|
|
|
|
|
|
|
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));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Is this the end-of-stream */
|
|
|
|
|
|
|
|
if (rptrbuf.vpkt.ctrl & 0x40) {
|
|
|
|
|
|
|
|
memset(&to_remote_g2[i].toDst4,0,sizeof(struct sockaddr_in));
|
|
|
|
|
|
|
|
to_remote_g2[i].streamid = 0;
|
|
|
|
|
|
|
|
to_remote_g2[i].last_time = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (recd[i].fd>=0 && recd[i].streamid==rptrbuf.vpkt.streamid) { // Is the data to be recorded for echotest
|
|
|
|
|
|
|
|
time(&recd[i].last_time);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
memcpy(recbuf.title, "DSVT", 4);
|
|
|
|
|
|
|
|
recbuf.config = 0x20;
|
|
|
|
|
|
|
|
recbuf.id = rptrbuf.vpkt.icm_id;
|
|
|
|
|
|
|
|
recbuf.flaga[0] = recbuf.flaga[1] = recbuf.flaga[20] = 0;
|
|
|
|
|
|
|
|
recbuf.flagb[0] = rptrbuf.vpkt.dst_rptr_id;
|
|
|
|
|
|
|
|
recbuf.flagb[1] = rptrbuf.vpkt.snd_rptr_id;
|
|
|
|
|
|
|
|
recbuf.flagb[2] = rptrbuf.vpkt.snd_term_id;
|
|
|
|
|
|
|
|
memcpy(&recbuf.streamid, &rptrbuf.vpkt.streamid, 3);
|
|
|
|
|
|
|
|
if (recvlen == 29)
|
|
|
|
|
|
|
|
memcpy(recbuf.vasd.voice, rptrbuf.vpkt.vasd.voice, 12);
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
memcpy(recbuf.vasd.voice, rptrbuf.vpkt.vasd1.voice, 12);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rec_len = 27;
|
|
|
|
|
|
|
|
(void)write(recd[i].fd, &rec_len, 2);
|
|
|
|
|
|
|
|
(void)write(recd[i].fd, &recbuf, rec_len);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((rptrbuf.vpkt.ctrl & 0x40) != 0) {
|
|
|
|
|
|
|
|
recd[i].streamid = 0;
|
|
|
|
|
|
|
|
recd[i].last_time = 0;
|
|
|
|
|
|
|
|
close(recd[i].fd);
|
|
|
|
|
|
|
|
recd[i].fd = -1;
|
|
|
|
|
|
|
|
// printf("Closed echotest audio file:[%s]\n", recd[i].file);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* we are in echotest mode, so play it back */
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
std::async(std::launch::async, &CQnetGateway::PlayFileThread, this, recd[i].file);
|
|
|
|
|
|
|
|
} catch (const std::exception &e) {
|
|
|
|
|
|
|
|
printf("failed to start PlayFileThread. Exception: %s\n", e.what());
|
|
|
|
|
|
|
|
// When the echotest thread runs, it deletes the file,
|
|
|
|
|
|
|
|
// Because the echotest thread did NOT start, we delete the file here
|
|
|
|
|
|
|
|
unlink(recd[i].file);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if ((vm[i].fd >= 0) && (vm[i].streamid==rptrbuf.vpkt.streamid)) { // Is the data to be recorded for voicemail
|
|
|
|
|
|
|
|
time(&vm[i].last_time);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
memcpy(recbuf.title, "DSVT", 4);
|
|
|
|
|
|
|
|
recbuf.config = 0x20;
|
|
|
|
|
|
|
|
recbuf.flaga[0] = recbuf.flaga[1] = recbuf.flaga[2] = 0;
|
|
|
|
|
|
|
|
recbuf.id = rptrbuf.vpkt.icm_id;
|
|
|
|
|
|
|
|
recbuf.flagb[0] = rptrbuf.vpkt.dst_rptr_id;
|
|
|
|
|
|
|
|
recbuf.flagb[1] = rptrbuf.vpkt.snd_rptr_id;
|
|
|
|
|
|
|
|
recbuf.flagb[2] = rptrbuf.vpkt.snd_term_id;
|
|
|
|
|
|
|
|
memcpy(&recbuf.streamid, &rptrbuf.vpkt.streamid, 3);
|
|
|
|
|
|
|
|
if (recvlen == 29)
|
|
|
|
|
|
|
|
memcpy(recbuf.vasd.voice, rptrbuf.vpkt.vasd.voice, 12);
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
memcpy(recbuf.vasd.voice, rptrbuf.vpkt.vasd1.voice, 12);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rec_len = 27;
|
|
|
|
|
|
|
|
(void)write(vm[i].fd, &rec_len, 2);
|
|
|
|
|
|
|
|
(void)write(vm[i].fd, &recbuf, rec_len);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((rptrbuf.vpkt.ctrl & 0x40) != 0) {
|
|
|
|
|
|
|
|
vm[i].streamid = 0;
|
|
|
|
|
|
|
|
vm[i].last_time = 0;
|
|
|
|
|
|
|
|
close(vm[i].fd);
|
|
|
|
|
|
|
|
vm[i].fd = -1;
|
|
|
|
|
|
|
|
// printf("Closed voicemail audio file:[%s]\n", vm[i].file);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if ((toRptr[i].streamid==rptrbuf.vpkt.streamid) && (toRptr[i].adr == fromRptr.sin_addr.s_addr)) { // or maybe this is cross-banding data
|
|
|
|
|
|
|
|
sendto(srv_sock, rptrbuf.pkt_id, 29, 0, (struct sockaddr *)&toRptr[i].band_addr, sizeof(struct sockaddr_in));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* timeit */
|
|
|
|
|
|
|
|
time(&toRptr[i].last_time);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* bump G2 counter */
|
|
|
|
|
|
|
|
if (is_icom)
|
|
|
|
|
|
|
|
G2_COUNTER_OUT++;
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
toRptr[i].G2_COUNTER ++;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
toRptr[i].sequence = rptrbuf.vpkt.ctrl;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* End of stream ? */
|
|
|
|
|
|
|
|
if (rptrbuf.vpkt.ctrl & 0x40) {
|
|
|
|
|
|
|
|
toRptr[i].last_time = 0;
|
|
|
|
|
|
|
|
toRptr[i].streamid = 0;
|
|
|
|
|
|
|
|
toRptr[i].adr = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (bool_qso_details && rptrbuf.vpkt.ctrl&0x40)
|
|
|
|
|
|
|
|
printf("id=%04x cntr=%04x END RPTR\n", ntohs(rptrbuf.vpkt.streamid), ntohs(rptrbuf.counter));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* run the main loop for QnetGateway */
|
|
|
|
/* run the main loop for QnetGateway */
|
|
|
|
|