diff --git a/aprs.cpp b/aprs.cpp index f129927..2c28ccb 100644 --- a/aprs.cpp +++ b/aprs.cpp @@ -27,7 +27,7 @@ #include "aprs.h" // This is called when header comes in from repeater -void CAPRS::SelectBand(short int rptr_idx, unsigned char *streamID) +void CAPRS::SelectBand(short int rptr_idx, unsigned short streamID) { if ((rptr_idx < 0) || (rptr_idx > 2)) { traceit("ERROR in aprs_select_band, invalid mod %d\n", rptr_idx); @@ -35,8 +35,7 @@ void CAPRS::SelectBand(short int rptr_idx, unsigned char *streamID) } /* lock on the streamID */ - aprs_streamID[rptr_idx].streamID[0] = streamID[0]; - aprs_streamID[rptr_idx].streamID[1] = streamID[1]; + aprs_streamID[rptr_idx].streamID = streamID; // aprs_streamID[rptr_idx].last_time = 0; Reset(rptr_idx); @@ -50,7 +49,7 @@ void CAPRS::SelectBand(short int rptr_idx, unsigned char *streamID) // Parameter len is either 12 or 15, because we took passed over the first 17 bytes // in the repeater data // Paramter seq is the byte at pos# 16(counting from zero) in the repeater data -void CAPRS::ProcessText(unsigned char *streamID, unsigned char seq, unsigned char *buf, unsigned int len) +void CAPRS::ProcessText(unsigned short streamID, unsigned char seq, unsigned char *buf, unsigned int len) { unsigned char aprs_data[200]; char aprs_buf[1024]; @@ -61,7 +60,7 @@ void CAPRS::ProcessText(unsigned char *streamID, unsigned char seq, unsigned cha len = len; for (short int i = 0; i < 3; i++) { - if (memcmp(streamID, aprs_streamID[i].streamID, 2) == 0) { + if (streamID == aprs_streamID[i].streamID) { rptr_idx = i; break; } @@ -150,8 +149,7 @@ void CAPRS::Init() } for (short int i = 0; i < 3; i++) { - aprs_streamID[i].streamID[0] = 0x00; - aprs_streamID[i].streamID[1] = 0x00; + aprs_streamID[i].streamID = 0; aprs_streamID[i].last_time = 0; } diff --git a/aprs.h b/aprs.h index c846e10..084c715 100644 --- a/aprs.h +++ b/aprs.h @@ -58,8 +58,8 @@ public: // functions CAPRS() {}; ~CAPRS() {}; - void SelectBand(short int rptr_idx, unsigned char *streamID); - void ProcessText(unsigned char *streamID, unsigned char seq, unsigned char *buf, unsigned int len); + void SelectBand(short int rptr_idx, unsigned short streamID); + void ProcessText(unsigned short streamID, unsigned char seq, unsigned char *buf, unsigned int len); ssize_t WriteSock(char *buffer, size_t n); void Open(const std::string OWNER); void Init(); @@ -82,7 +82,7 @@ private: } aprs_pack[3]; // lock down a stream per band struct { - unsigned char streamID[2]; + unsigned short streamID; time_t last_time; } aprs_streamID[3]; diff --git a/g2_ircddb.cpp b/g2_ircddb.cpp index 064013c..5d685b1 100644 --- a/g2_ircddb.cpp +++ b/g2_ircddb.cpp @@ -1,6 +1,8 @@ /* * Copyright (C) 2010 by Scott Lawson KI4LKF * + * Copyright 2017 by Thomas Early, AC2IE + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -99,7 +101,7 @@ typedef struct torepeater_tag { } STOREPEATER; typedef struct band_txt_tag { - unsigned char streamID[2]; + unsigned short streamID; unsigned char flags[3]; char lh_mycall[CALL_SIZE + 1]; char lh_sfx[5]; @@ -144,7 +146,6 @@ SRPTR rptr; // local repeater modules being recorded // This is for echotest and voicemail static SECHO recd[3], vm[3]; - SDSVT recbuf; // 56 or 27, max is 56 // the streamids going to remote Gateways from each local module @@ -160,7 +161,7 @@ static STOREPEATER toRptr[3]; // 0=A, 1=B, 2=C // input from our own local repeater modules static int srv_sock = -1; -static unsigned char readBuffer[2000]; // 58 or 29 or 32, max is 58 +static SPKT rptrbuf; // 58 or 29 or 32, max is 58 static struct sockaddr_in fromRptr; static SPKT end_of_audio; @@ -172,6 +173,7 @@ static struct sockaddr_in plug; // for talking with the irc server static CIRCDDB *ii; +// for handling APRS stuff static CAPRS *aprs; // text coming from local repeater bands @@ -906,9 +908,9 @@ static void runit() 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 */ if (to_remote_g2[i].toDst4.sin_addr.s_addr == 0) - traceit("Inactivity from local rptr band %d, removing stream id %d,%d\n", i, band_txt[i].streamID[0], band_txt[i].streamID[1]); + traceit("Inactivity from local rptr band %d, removing stream id %04x\n", i, band_txt[i].streamID); - band_txt[i].streamID[0] = band_txt[i].streamID[1] = 0x0; + band_txt[i].streamID = 0; band_txt[i].flags[0] = band_txt[i].flags[1] = band_txt[i].flags[2] = 0x0; band_txt[i].lh_mycall[0] = '\0'; band_txt[i].lh_sfx[0] = '\0'; @@ -986,19 +988,18 @@ static void runit() g2buf.hdr.rpt1, g2buf.hdr.rpt2, g2buflen, inet_ntoa(fromDst4.sin_addr)); - memcpy(readBuffer,"DSTR", 4); - readBuffer[5] = (unsigned char)(toRptr[i].G2_COUNTER & 0xff); - readBuffer[4] = (unsigned char)((toRptr[i].G2_COUNTER >> 8) & 0xff); - readBuffer[6] = 0x73; - readBuffer[7] = 0x12; - readBuffer[8] = 0x00; - readBuffer[9] = 0x30; - readBuffer[10] = 0x20; - memcpy(readBuffer + 11, g2buf.flagb, 47); - sendto(srv_sock, readBuffer, 58, 0, (struct sockaddr *)&toRptr[i].band_addr, sizeof(struct sockaddr_in)); + memcpy(rptrbuf.pkt_id, "DSTR", 4); + rptrbuf.counter = toRptr[i].G2_COUNTER; + rptrbuf.flag[0] = 0x73; + rptrbuf.flag[1] = 0x12; + rptrbuf.nothing2[0] = 0x00; + rptrbuf.nothing2[1] = 0x30; + rptrbuf.vpkt.icm_id = 0x20; + memcpy(&rptrbuf.vpkt.dst_rptr_id, g2buf.flagb, 47); + sendto(srv_sock, rptrbuf.pkt_id, 58, 0, (struct sockaddr *)&toRptr[i].band_addr, sizeof(struct sockaddr_in)); /* save the header */ - memcpy(toRptr[i].saved_hdr, readBuffer, 58); + memcpy(toRptr[i].saved_hdr, rptrbuf.pkt_id, 58); toRptr[i].saved_adr = fromDst4.sin_addr.s_addr; /* This is the active streamid */ @@ -1011,7 +1012,7 @@ static void runit() /* bump the G2 counter */ toRptr[i].G2_COUNTER++; - toRptr[i].sequence = readBuffer[16]; + toRptr[i].sequence = rptrbuf.vpkt.ctrl; } } } else { @@ -1026,17 +1027,16 @@ static void runit() /* streamid match ? */ if ((toRptr[i].streamid==g2buf.streamid) && (toRptr[i].adr == fromDst4.sin_addr.s_addr)) { - memcpy(readBuffer,"DSTR", 4); - readBuffer[5] = (unsigned char)(toRptr[i].G2_COUNTER & 0xff); - readBuffer[4] = (unsigned char)((toRptr[i].G2_COUNTER >> 8) & 0xff); - readBuffer[6] = 0x73; - readBuffer[7] = 0x12; - readBuffer[8] = 0x00; - readBuffer[9] = 0x13; - readBuffer[10] = 0x20; - memcpy(readBuffer+11, g2buf.flagb, 18); - - sendto(srv_sock, readBuffer, 29, 0, (struct sockaddr *)&toRptr[i].band_addr, sizeof(struct sockaddr_in)); + memcpy(rptrbuf.pkt_id, "DSTR", 4); + rptrbuf.counter = toRptr[i].G2_COUNTER; + rptrbuf.flag[0] = 0x73; + rptrbuf.flag[1] = 0x12; + rptrbuf.nothing2[0] = 0x00; + rptrbuf.nothing2[1]= 0x13; + rptrbuf.vpkt.icm_id = 0x20; + memcpy(&rptrbuf.vpkt.dst_rptr_id, g2buf.flagb, 18); + + sendto(srv_sock, rptrbuf.pkt_id, 29, 0, (struct sockaddr *)&toRptr[i].band_addr, sizeof(struct sockaddr_in)); /* timeit */ time(&toRptr[i].last_time); @@ -1044,7 +1044,7 @@ static void runit() /* bump G2 counter */ toRptr[i].G2_COUNTER++; - toRptr[i].sequence = readBuffer[16]; + toRptr[i].sequence = rptrbuf.vpkt.ctrl; /* End of stream ? */ if (g2buf.counter & 0x40) { @@ -1086,17 +1086,16 @@ static void runit() toRptr[i].G2_COUNTER++; /* send this audio packet to repeater */ - memcpy(readBuffer,"DSTR", 4); - readBuffer[5] = (unsigned char)(toRptr[i].G2_COUNTER & 0xff); - readBuffer[4] = (unsigned char)((toRptr[i].G2_COUNTER >> 8) & 0xff); - readBuffer[6] = 0x73; - readBuffer[7] = 0x12; - readBuffer[8] = 0x00; - readBuffer[9] = 0x13; - readBuffer[10] = 0x20; - memcpy(readBuffer + 11, g2buf.flagb, 18); - - sendto(srv_sock, readBuffer, 29, 0, (struct sockaddr *)&toRptr[i].band_addr, sizeof(struct sockaddr_in)); + memcpy(rptrbuf.pkt_id, "DSTR", 4); + rptrbuf.counter = toRptr[i].G2_COUNTER; + rptrbuf.flag[0] = 0x73; + rptrbuf.flag[1] = 0x12; + rptrbuf.nothing2[0] = 0x00; + rptrbuf.nothing2[1] = 0x13; + rptrbuf.vpkt.icm_id = 0x20; + memcpy(&rptrbuf.vpkt.dst_rptr_id, g2buf.flagb, 18); + + sendto(srv_sock, rptrbuf.pkt_id, 29, 0, (struct sockaddr *)&toRptr[i].band_addr, sizeof(struct sockaddr_in)); /* make sure that any more audio arriving will be accepted */ toRptr[i].streamid = g2buf.streamid; @@ -1108,7 +1107,7 @@ static void runit() /* bump the G2 counter */ toRptr[i].G2_COUNTER++; - toRptr[i].sequence = readBuffer[16]; + toRptr[i].sequence = rptrbuf.vpkt.ctrl; } break; @@ -1124,16 +1123,16 @@ static void runit() /* process data coming from local repeater modules */ if (FD_ISSET(srv_sock, &fdset)) { fromlen = sizeof(struct sockaddr_in); - recvlen = recvfrom(srv_sock,(char *)readBuffer, 2000, 0, (struct sockaddr *)&fromRptr, &fromlen); + recvlen = recvfrom(srv_sock, rptrbuf.pkt_id, 58, 0, (struct sockaddr *)&fromRptr, &fromlen); /* DV */ if ( ((recvlen == 58) || (recvlen == 29) || (recvlen == 32)) && - (readBuffer[6] == 0x73) && (readBuffer[7] == 0x12) && - (memcmp(readBuffer,"DSTR", 4) == 0) && - (readBuffer[10] == 0x20) && (readBuffer[8] == 0x00) && - ((readBuffer[9] == 0x30) || /* 48 bytes follow */ - (readBuffer[9] == 0x13) || /* 19 bytes follow */ - (readBuffer[9] == 0x16)) ) { /* 22 bytes follow */ + (rptrbuf.flag[0] == 0x73) && (rptrbuf.flag[1] == 0x12) && + (0 == memcmp(rptrbuf.pkt_id,"DSTR", 4)) && + (rptrbuf.vpkt.icm_id == 0x20) && (rptrbuf.nothing2[0] == 0x00) && + ((rptrbuf.nothing2[1] == 0x30) || /* 48 bytes follow */ + (rptrbuf.nothing2[1] == 0x13) || /* 19 bytes follow */ + (rptrbuf.nothing2[1] == 0x16)) ) { /* 22 bytes follow */ int dtmf_buf_count[3] = {0, 0, 0}; char dtmf_buf[3][MAX_DTMF_BUF + 1] = { {""}, {""}, {""} }; @@ -1142,21 +1141,21 @@ static void runit() if (recvlen == 58) { if (bool_qso_details) - traceit("START from rptr: cntr=%02x %02x, streamID=%d,%d, flags=%02x:%02x:%02x, my=%.8s, sfx=%.4s, ur=%.8s, rpt1=%.8s, rpt2=%.8s, %d bytes fromIP=%s\n", - readBuffer[4], readBuffer[5], - readBuffer[14], readBuffer[15], - readBuffer[17], readBuffer[18], readBuffer[19], - readBuffer + 44, readBuffer + 52, readBuffer + 36, - readBuffer + 28, readBuffer + 20, recvlen, inet_ntoa(fromRptr.sin_addr)); - - if ((memcmp(readBuffer + 28, OWNER.c_str(), 7) == 0) && /* rpt1 is this repeater */ - /*** (memcmp(readBuffer + 44, OWNER, 7) != 0) && ***/ /* MYCALL is NOT this repeater */ - ((readBuffer[17] == 0x00) || /* normal */ - (readBuffer[17] == 0x08) || /* EMR */ - (readBuffer[17] == 0x20) || /* BREAK */ - (readBuffer[17] == 0x28))) { /* EMR + BREAK */ - - i = readBuffer[35] - 'A'; + traceit("START from rptr: cntr=%04x, streamID=%04x, flags=%02x:%02x:%02x, my=%.8s, sfx=%.4s, ur=%.8s, rpt1=%.8s, rpt2=%.8s, %d bytes fromIP=%s\n", + rptrbuf.counter, + rptrbuf.vpkt.streamid, + rptrbuf.vpkt.hdr.flag[0], rptrbuf.vpkt.hdr.flag[1], rptrbuf.vpkt.hdr.flag[2], + rptrbuf.vpkt.hdr.mycall, rptrbuf.vpkt.hdr.sfx, rptrbuf.vpkt.hdr.urcall, + rptrbuf.vpkt.hdr.rpt2, rptrbuf.vpkt.hdr.rpt1, recvlen, inet_ntoa(fromRptr.sin_addr)); + + if ((memcmp(rptrbuf.vpkt.hdr.rpt2, OWNER.c_str(), 7) == 0) && /* rpt1 is this repeater */ + /*** (memcmp(rptrbuf + 44, OWNER, 7) != 0) && ***/ /* MYCALL is NOT this repeater */ + ((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 */ + + i = rptrbuf.vpkt.hdr.rpt2[7] - 'A'; if (i>=0 && i<3) { dtmf_last_frame[i] = 0; @@ -1166,27 +1165,24 @@ static void runit() /* Initialize the LAST HEARD data for the band */ - band_txt[i].streamID[0] = readBuffer[14]; - band_txt[i].streamID[1] = readBuffer[15]; + band_txt[i].streamID = rptrbuf.vpkt.streamid; - band_txt[i].flags[0] = readBuffer[17]; - band_txt[i].flags[1] = readBuffer[18]; - band_txt[i].flags[2] = readBuffer[19]; + memcpy(band_txt[i].flags, rptrbuf.vpkt.hdr.flag, 3); - memcpy(band_txt[i].lh_mycall, readBuffer + 44, CALL_SIZE); - band_txt[i].lh_mycall[CALL_SIZE] = '\0'; + memcpy(band_txt[i].lh_mycall, rptrbuf.vpkt.hdr.mycall, 8); + band_txt[i].lh_mycall[8] = '\0'; - memcpy(band_txt[i].lh_sfx, readBuffer + 52, 4); + memcpy(band_txt[i].lh_sfx, rptrbuf.vpkt.hdr.sfx, 4); band_txt[i].lh_sfx[4] = '\0'; - memcpy(band_txt[i].lh_yrcall, readBuffer + 36, CALL_SIZE); - band_txt[i].lh_yrcall[CALL_SIZE] = '\0'; + memcpy(band_txt[i].lh_yrcall, rptrbuf.vpkt.hdr.urcall, 8); + band_txt[i].lh_yrcall[8] = '\0'; - memcpy(band_txt[i].lh_rpt1, readBuffer + 28, CALL_SIZE); - band_txt[i].lh_rpt1[CALL_SIZE] = '\0'; + memcpy(band_txt[i].lh_rpt1, rptrbuf.vpkt.hdr.rpt2, 8); + band_txt[i].lh_rpt1[8] = '\0'; - memcpy(band_txt[i].lh_rpt2, readBuffer + 20, CALL_SIZE); - band_txt[i].lh_rpt2[CALL_SIZE] = '\0'; + memcpy(band_txt[i].lh_rpt2, rptrbuf.vpkt.hdr.rpt1, 8); + band_txt[i].lh_rpt2[8] = '\0'; time(&band_txt[i].last_time); @@ -1214,14 +1210,14 @@ static void runit() /* select the band for aprs processing, and lock on the stream ID */ if (bool_send_aprs) - aprs->SelectBand(i, readBuffer + 14); + aprs->SelectBand(i, rptrbuf.vpkt.streamid); } } /* Is MYCALL valid ? */ - memset(temp_radio_user, ' ', CALL_SIZE); - memcpy(temp_radio_user, readBuffer + 44, 8); - temp_radio_user[CALL_SIZE] = '\0'; + memset(temp_radio_user, ' ', 8); + memcpy(temp_radio_user, rptrbuf.vpkt.hdr.mycall, 8); + temp_radio_user[8] = '\0'; mycall_valid = regexec(&preg, temp_radio_user, 0, NULL, 0); @@ -1236,30 +1232,30 @@ static void runit() /* send data g2_link */ if (mycall_valid == REG_NOERROR) - sendto(srv_sock, readBuffer, 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) && - (memcmp(readBuffer + 36, "XRF", 3) != 0) && /* not a reflector */ - (memcmp(readBuffer + 36, "REF", 3) != 0) && /* not a reflector */ - (memcmp(readBuffer + 36, "DCS", 3) != 0) && /* not a reflector */ - (readBuffer[36] != ' ') && /* must have something */ - (memcmp(readBuffer + 36, "CQCQCQ", 6) != 0)) { /* urcall is NOT CQCQCQ */ - if ((readBuffer[36] == '/') && /* urcall starts with a slash */ - (memcmp(readBuffer + 28, OWNER.c_str(), 7) == 0) && /* rpt1 is this repeater */ - ((readBuffer[35] == 'A') || - (readBuffer[35] == 'B') || - (readBuffer[35] == 'C')) && /* mod is A,B,C */ - (memcmp(readBuffer + 20, OWNER.c_str(), 7) == 0) && /* rpt2 is this repeater */ - (readBuffer[27] == 'G') && /* local Gateway */ - /*** (memcmp(readBuffer + 44, OWNER, 7) != 0) && ***/ /* mycall is NOT this repeater */ - - ((readBuffer[17] == 0x00) || /* normal */ - (readBuffer[17] == 0x08) || /* EMR */ - (readBuffer[17] == 0x20) || /* BK */ - (readBuffer[17] == 0x28)) /* EMR + BK */ + (memcmp(rptrbuf.vpkt.hdr.urcall, "XRF", 3) != 0) && /* not a reflector */ + (memcmp(rptrbuf.vpkt.hdr.urcall, "REF", 3) != 0) && /* not a reflector */ + (memcmp(rptrbuf.vpkt.hdr.urcall, "DCS", 3) != 0) && /* not a reflector */ + (rptrbuf.vpkt.hdr.urcall[0] != ' ') && /* must have something */ + (memcmp(rptrbuf.vpkt.hdr.urcall, "CQCQCQ", 6) != 0)) { /* urcall is NOT CQCQCQ */ + if ((rptrbuf.vpkt.hdr.urcall[0] == '/') && /* urcall starts with a slash */ + (memcmp(rptrbuf.vpkt.hdr.rpt2, OWNER.c_str(), 7) == 0) && /* rpt1 is this repeater */ + ((rptrbuf.vpkt.hdr.rpt2[7] == 'A') || + (rptrbuf.vpkt.hdr.rpt2[7] == 'B') || + (rptrbuf.vpkt.hdr.rpt2[7] == 'C')) && /* mod is A,B,C */ + (memcmp(rptrbuf.vpkt.hdr.rpt1, OWNER.c_str(), 7) == 0) && /* rpt2 is this repeater */ + (rptrbuf.vpkt.hdr.rpt1[7] == 'G') && /* local Gateway */ + /*** (memcmp(rptrbuf + 44, OWNER, 7) != 0) && ***/ /* mycall is NOT this repeater */ + + ((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 */ ) { - if (memcmp(readBuffer + 37, OWNER.c_str(), 6) != 0) { /* the value after the slash in urcall, is NOT this repeater */ - i = readBuffer[35] - 'A'; + if (memcmp(rptrbuf.vpkt.hdr.urcall+1, OWNER.c_str(), 6) != 0) { /* the value after the slash in urcall, is NOT this repeater */ + i = rptrbuf.vpkt.hdr.rpt2[7] - 'A'; if (i>=0 && i<3) { /* one radio user on a repeater module at a time */ @@ -1267,10 +1263,10 @@ static void runit() /* YRCALL=/repeater + mod */ /* YRCALL=/KJ4NHFB */ - memset(temp_radio_user, ' ', CALL_SIZE); - memcpy(temp_radio_user, readBuffer + 37, 6); + memset(temp_radio_user, ' ', 8); + memcpy(temp_radio_user, rptrbuf.vpkt.hdr.urcall+1, 6); temp_radio_user[6] = ' '; - temp_radio_user[7] = readBuffer[43]; + temp_radio_user[7] = rptrbuf.vpkt.hdr.urcall[7]; if (temp_radio_user[7] == ' ') temp_radio_user[7] = 'A'; temp_radio_user[CALL_SIZE] = '\0'; @@ -1278,7 +1274,7 @@ static void runit() result = get_yrcall_rptr(temp_radio_user, arearp_cs, zonerp_cs, &temp_mod, ip, 'R'); if (result) { /* it is a repeater */ /* set the destination */ - memcpy(&to_remote_g2[i].streamid, readBuffer + 14, 2); + to_remote_g2[i].streamid = rptrbuf.vpkt.streamid; memset(&to_remote_g2[i].toDst4, 0, sizeof(struct sockaddr_in)); to_remote_g2[i].toDst4.sin_family = AF_INET; to_remote_g2[i].toDst4.sin_port = htons(g2_external.port); @@ -1287,17 +1283,17 @@ static void runit() memcpy(g2buf.title, "DSVT", 4); g2buf.config = 0x10; g2buf.flaga[0] = g2buf.flaga[1] = g2buf.flaga[2] = 0x00; - g2buf.id = readBuffer[10]; - g2buf.flagb[0] = readBuffer[11]; - g2buf.flagb[1] = readBuffer[12]; - g2buf.flagb[2] = readBuffer[13]; - memcpy(&g2buf.streamid, readBuffer + 14, 44); + g2buf.id = rptrbuf.vpkt.icm_id; + g2buf.flagb[0] = rptrbuf.vpkt.dst_rptr_id; + g2buf.flagb[1] = rptrbuf.vpkt.snd_rptr_id; + g2buf.flagb[2] = rptrbuf.vpkt.snd_term_id; + memcpy(&g2buf.streamid, &rptrbuf.vpkt.streamid, 44); /* set rpt1 */ - memset(g2buf.hdr.rpt1, ' ', CALL_SIZE); + memset(g2buf.hdr.rpt1, ' ', 8); memcpy(g2buf.hdr.rpt1, arearp_cs, strlen(arearp_cs)); g2buf.hdr.rpt1[7] = temp_mod; /* set rpt2 */ - memset(g2buf.hdr.rpt2, ' ', CALL_SIZE); + memset(g2buf.hdr.rpt2, ' ', 8); memcpy(g2buf.hdr.rpt2, zonerp_cs, strlen(zonerp_cs)); g2buf.hdr.rpt2[7] = 'G'; /* set yrcall, can NOT let it be slash and repeater + module */ @@ -1329,35 +1325,35 @@ static void runit() } } } - } else if ((memcmp(readBuffer + 36, OWNER.c_str(), 7) != 0) && /* urcall is not this repeater */ - (memcmp(readBuffer + 28, OWNER.c_str(), 7) == 0) && /* rpt1 is this repeater */ - ((readBuffer[35] == 'A') || - (readBuffer[35] == 'B') || - (readBuffer[35] == 'C')) && /* mod is A,B,C */ - (memcmp(readBuffer + 20, OWNER.c_str(), 7) == 0) && /* rpt2 is this repeater */ - (readBuffer[27] == 'G') && /* local Gateway */ - /*** (memcmp(readBuffer + 44, OWNER, 7) != 0) && ***/ /* mycall is NOT this repeater */ - - ((readBuffer[17] == 0x00) || /* normal */ - (readBuffer[17] == 0x08) || /* EMR */ - (readBuffer[17] == 0x20) || /* BK */ - (readBuffer[17] == 0x28)) /* EMR + BK */ + } else if ((memcmp(rptrbuf.vpkt.hdr.urcall, OWNER.c_str(), 7) != 0) && /* urcall is not this repeater */ + (memcmp(rptrbuf.vpkt.hdr.rpt2, OWNER.c_str(), 7) == 0) && /* rpt1 is this repeater */ + ((rptrbuf.vpkt.hdr.rpt2[7] == 'A') || + (rptrbuf.vpkt.hdr.rpt2[7] == 'B') || + (rptrbuf.vpkt.hdr.rpt2[7] == 'C')) && /* mod is A,B,C */ + (memcmp(rptrbuf.vpkt.hdr.rpt1, OWNER.c_str(), 7) == 0) && /* rpt2 is this repeater */ + (rptrbuf.vpkt.hdr.rpt1[7] == 'G') && /* local Gateway */ + /*** (memcmp(rptrbuf + 44, OWNER, 7) != 0) && ***/ /* mycall is NOT this repeater */ + + ((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, ' ', CALL_SIZE); - memcpy(temp_radio_user, readBuffer + 36, CALL_SIZE); - temp_radio_user[CALL_SIZE] = '\0'; + memset(temp_radio_user, ' ', 8); + memcpy(temp_radio_user, rptrbuf.vpkt.hdr.urcall, 8); + temp_radio_user[8] = '\0'; result = get_yrcall_rptr(temp_radio_user, arearp_cs, zonerp_cs, &temp_mod, ip, 'U'); if (result) { /* destination is a remote system */ if (memcmp(zonerp_cs, OWNER.c_str(), 7) != 0) { - i = readBuffer[35] - 'A'; + i = rptrbuf.vpkt.hdr.rpt2[7] - 'A'; if (i>=0 && i<3) { /* one radio user on a repeater module at a time */ if (to_remote_g2[i].toDst4.sin_addr.s_addr == 0) { /* set the destination */ - memcpy(&to_remote_g2[i].streamid, readBuffer + 14, 2); + to_remote_g2[i].streamid = rptrbuf.vpkt.streamid; memset(&to_remote_g2[i].toDst4, 0, sizeof(struct sockaddr_in)); to_remote_g2[i].toDst4.sin_family = AF_INET; to_remote_g2[i].toDst4.sin_port = htons(g2_external.port); @@ -1366,17 +1362,17 @@ static void runit() memcpy(g2buf.title, "DSVT", 4); g2buf.config = 0x10; g2buf.flaga[0] = g2buf.flaga[1] = g2buf.flaga[2] = 0x00; - g2buf.id = readBuffer[10]; - g2buf.flagb[0] = readBuffer[11]; - g2buf.flagb[1] = readBuffer[12]; - g2buf.flagb[2] = readBuffer[13]; - memcpy(&g2buf.streamid, readBuffer + 14, 44); + g2buf.id = rptrbuf.vpkt.icm_id; + g2buf.flagb[0] = rptrbuf.vpkt.dst_rptr_id; + g2buf.flagb[1] = rptrbuf.vpkt.snd_rptr_id; + g2buf.flagb[2] = rptrbuf.vpkt.snd_term_id; + memcpy(&g2buf.streamid, &rptrbuf.vpkt.streamid, 44); /* set rpt1 */ - memset(g2buf.hdr.rpt1, ' ', CALL_SIZE); + memset(g2buf.hdr.rpt1, ' ', 8); memcpy(g2buf.hdr.rpt1, arearp_cs, strlen(arearp_cs)); g2buf.hdr.rpt1[7] = temp_mod; /* set rpt2 */ - memset(g2buf.hdr.rpt2, ' ', CALL_SIZE); + memset(g2buf.hdr.rpt2, ' ', 8); memcpy(g2buf.hdr.rpt2, zonerp_cs, strlen(zonerp_cs)); g2buf.hdr.rpt2[7] = 'G'; /* set PFCS */ @@ -1402,19 +1398,19 @@ static void runit() } } } else { - i = readBuffer[35] - 'A'; + i = rptrbuf.vpkt.hdr.rpt2[7] - 'A'; if (i>=0 && i<3) { /* the user we are trying to contact is on our gateway */ /* make sure they are on a different module */ - if (temp_mod != readBuffer[35]) { + if (temp_mod != rptrbuf.vpkt.hdr.rpt2[7]) { /* 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, rptrbuf.vpkt.hdr.rpt1, 8); band_txt[i].dest_rptr[7] = temp_mod; - band_txt[i].dest_rptr[CALL_SIZE] = '\0'; + band_txt[i].dest_rptr[8] = '\0'; i = temp_mod - 'A'; @@ -1425,16 +1421,16 @@ static void runit() band_txt[i] : local RF is talking. */ if ((toRptr[i].last_time == 0) && (band_txt[i].last_time == 0)) { - traceit("CALLmode cross-banding from mod %c to %c\n", readBuffer[35], temp_mod); + traceit("CALLmode cross-banding from mod %c to %c\n", rptrbuf.vpkt.hdr.rpt2[7], temp_mod); - readBuffer[27] = temp_mod; - readBuffer[35] = 'G'; - calcPFCS(readBuffer, 58); + rptrbuf.vpkt.hdr.rpt1[7] = temp_mod; + rptrbuf.vpkt.hdr.rpt2[7] = 'G'; + calcPFCS(rptrbuf.pkt_id, 58); - sendto(srv_sock, readBuffer, 58, 0, (struct sockaddr *)&toRptr[i].band_addr, sizeof(struct sockaddr_in)); + sendto(srv_sock, rptrbuf.pkt_id, 58, 0, (struct sockaddr *)&toRptr[i].band_addr, sizeof(struct sockaddr_in)); /* This is the active streamid */ - toRptr[i].streamid = readBuffer[14] + 256u * readBuffer[15]; + toRptr[i].streamid = rptrbuf.vpkt.streamid; toRptr[i].adr = fromRptr.sin_addr.s_addr; /* time it, in case stream times out */ @@ -1443,19 +1439,19 @@ static void runit() /* bump the G2 counter */ toRptr[i].G2_COUNTER++; - toRptr[i].sequence = readBuffer[16]; + toRptr[i].sequence = rptrbuf.vpkt.ctrl; } } } else - traceit("icom rule: no routing from %.8s to %s%c\n", readBuffer + 28, arearp_cs,temp_mod); + traceit("icom rule: no routing from %.8s to %s%c\n", rptrbuf.vpkt.hdr.rpt2, arearp_cs, temp_mod); } } } } - } else if ((readBuffer[43] == '0') && - (readBuffer[42] == CLEAR_VM_CODE) && - (readBuffer[36] == ' ')) { - i = readBuffer[35] - 'A'; + } else if ((rptrbuf.vpkt.hdr.urcall[7] == '0') && + (rptrbuf.vpkt.hdr.urcall[6] == CLEAR_VM_CODE) && + (rptrbuf.vpkt.hdr.urcall[0] == ' ')) { + i = rptrbuf.vpkt.hdr.rpt2[7] - 'A'; if (i>=0 && i<3) { /* voicemail file is closed */ @@ -1466,16 +1462,21 @@ static void runit() } else traceit("No voicemail to clear or still recording\n"); } - } else if ((readBuffer[43] == '0') && - (readBuffer[42] == RECALL_VM_CODE) && - (readBuffer[36] == ' ')) { + } else if ((rptrbuf.vpkt.hdr.urcall[7] == '0') && + (rptrbuf.vpkt.hdr.urcall[6] == RECALL_VM_CODE) && + (rptrbuf.vpkt.hdr.urcall[0] == ' ')) { i = -1; - if (readBuffer[35] == 'A') - i = 0; - else if (readBuffer[35] == 'B') - i = 1; - else if (readBuffer[35] == 'C') - i = 2; + switch (rptrbuf.vpkt.hdr.rpt2[7]) { + case 'A': + i = 0; + break; + case 'B': + i = 1; + break; + case 'C': + i = 2; + break; + } if (i >= 0) { /* voicemail file is closed */ @@ -1488,10 +1489,10 @@ static void runit() } else traceit("No voicemail to recall or still recording\n"); } - } else if ((readBuffer[43] == '0') && - (readBuffer[42] == STORE_VM_CODE) && - (readBuffer[36] == ' ')) { - i = readBuffer[35] - 'A'; + } else if ((rptrbuf.vpkt.hdr.urcall[7] == '0') && + (rptrbuf.vpkt.hdr.urcall[6] == STORE_VM_CODE) && + (rptrbuf.vpkt.hdr.urcall[0] == ' ')) { + i = rptrbuf.vpkt.hdr.rpt2[7] - 'A'; if (i>=0 && i<3) { if (vm[i].fd >= 0) @@ -1500,7 +1501,7 @@ static void runit() memset(tempfile, '\0', sizeof(tempfile)); snprintf(tempfile, FILENAME_MAX, "%s/%c_%s", echotest_dir.c_str(), - readBuffer[35], + rptrbuf.vpkt.hdr.rpt2[7], "voicemail.dat"); vm[i].fd = open(tempfile, @@ -1511,23 +1512,23 @@ static void runit() else { strcpy(vm[i].file, tempfile); traceit("Recording mod %c for voicemail into file:[%s]\n", - readBuffer[35], + rptrbuf.vpkt.hdr.rpt2[7], vm[i].file); time(&vm[i].last_time); - memcpy(&vm[i].streamid, readBuffer + 14, 2); + vm[i].streamid = rptrbuf.vpkt.streamid; memcpy(recbuf.title, "DSVT", 4); recbuf.config = 0x10; - for (int k=0; k<3; k++) { - recbuf.flaga[k] = 0; - recbuf.flagb[k] = readBuffer[k+11]; - } - recbuf.id = readBuffer[10]; - memcpy(&recbuf.streamid, readBuffer + 14, 44); + 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, 44); memset(recbuf.hdr.rpt1, ' ', 8); memcpy(recbuf.hdr.rpt1, OWNER.c_str(), OWNER.length()); - recbuf.hdr.rpt1[7] = readBuffer[35]; + recbuf.hdr.rpt1[7] = rptrbuf.vpkt.hdr.rpt2[7]; memset(recbuf.hdr.rpt2, ' ', 8); memcpy(recbuf.hdr.rpt2, OWNER.c_str(), OWNER.length()); recbuf.hdr.rpt2[7] = 'G'; @@ -1543,19 +1544,16 @@ static void runit() } } } - } else if ((readBuffer[43] == ECHO_CODE) && - (readBuffer[36] == ' ')) { - i = readBuffer[35] - 'A'; + } else if ((rptrbuf.vpkt.hdr.urcall[7] == ECHO_CODE) && (rptrbuf.vpkt.hdr.urcall[0] == ' ')) { + i = rptrbuf.vpkt.hdr.rpt2[7] - 'A'; if (i>=0 && i<3) { if (recd[i].fd >= 0) traceit("Already recording for echotest on mod %d\n", i); else { memset(tempfile, '\0', sizeof(tempfile)); - snprintf(tempfile, FILENAME_MAX, "%s/%c_%s", - echotest_dir.c_str(), - readBuffer[35], - "echotest.dat"); + snprintf(tempfile, FILENAME_MAX, "%s/%c_%s", echotest_dir.c_str(), + rptrbuf.vpkt.hdr.rpt2[7], "echotest.dat"); recd[i].fd = open(tempfile, O_CREAT | O_WRONLY | O_EXCL | O_TRUNC | O_APPEND, @@ -1565,23 +1563,22 @@ static void runit() else { strcpy(recd[i].file, tempfile); traceit("Recording mod %c for echotest into file:[%s]\n", - readBuffer[35], - recd[i].file); + rptrbuf.vpkt.hdr.rpt2[7], recd[i].file); time(&recd[i].last_time); - memcpy(&recd[i].streamid, readBuffer + 14, 2); + recd[i].streamid = rptrbuf.vpkt.streamid; memcpy(recbuf.title, "DSVT", 4); recbuf.config = 0x10; - for (int k=0; k<3; k++) { - recbuf.flaga[k] = 0; - recbuf.flagb[k] = readBuffer[k+11]; - } - recbuf.id = readBuffer[10]; - memcpy(&recbuf.streamid, readBuffer + 14, 44); + recbuf.id = rptrbuf.vpkt.icm_id; + recbuf.flaga[0] = recbuf.flaga[1] = recbuf.flaga[2] = 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, 44); memset(recbuf.hdr.rpt1, ' ', 8); memcpy(recbuf.hdr.rpt1, OWNER.c_str(), OWNER.length()); - recbuf.hdr.rpt1[7] = readBuffer[35]; + recbuf.hdr.rpt1[7] = rptrbuf.vpkt.hdr.rpt2[7]; memset(recbuf.hdr.rpt2, ' ', 8); memcpy(recbuf.hdr.rpt2, OWNER.c_str(), OWNER.length()); recbuf.hdr.rpt2[7] = 'G'; @@ -1599,41 +1596,41 @@ static void runit() } } else /* check for cross-banding */ - if ((memcmp(readBuffer + 36, "CQCQCQ", 6) == 0) && /* yrcall is CQCQCQ */ - (memcmp(readBuffer + 28, OWNER.c_str(), 7) == 0) && /* rpt1 is this repeater */ - (memcmp(readBuffer + 20, OWNER.c_str(), 7) == 0) && /* rpt2 is this repeater */ - ((readBuffer[35] == 'A') || - (readBuffer[35] == 'B') || - (readBuffer[35] == 'C')) && /* mod of rpt1 is A,B,C */ - ((readBuffer[27] == 'A') || - (readBuffer[27] == 'B') || - (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 */ - i = readBuffer[35] - 'A'; + if (0 == (memcmp(rptrbuf.vpkt.hdr.urcall, "CQCQCQ", 6)) && /* yrcall is CQCQCQ */ + (0 == memcmp(rptrbuf.vpkt.hdr.rpt1, OWNER.c_str(), 7)) && /* rpt1 is this repeater */ + (0 == memcmp(rptrbuf.vpkt.hdr.rpt2, OWNER.c_str(), 7)) && /* rpt2 is this repeater */ + ((rptrbuf.vpkt.hdr.rpt2[7] == 'A') || + (rptrbuf.vpkt.hdr.rpt2[7] == 'B') || + (rptrbuf.vpkt.hdr.rpt2[7] == 'C')) && /* mod of rpt1 is A,B,C */ + ((rptrbuf.vpkt.hdr.rpt1[7] == 'A') || + (rptrbuf.vpkt.hdr.rpt1[7] == 'B') || + (rptrbuf.vpkt.hdr.rpt1[7] == 'C')) && /* !!! usually a G of rpt2, but we see A,B,C */ + (rptrbuf.vpkt.hdr.rpt1[7] != rptrbuf.vpkt.hdr.rpt2[7])) { /* cross-banding? make sure NOT the same */ + i = rptrbuf.vpkt.hdr.rpt2[7] - 'A'; if (i>=0 && i<3) { // 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); - band_txt[i].dest_rptr[CALL_SIZE] = '\0'; + memcpy(band_txt[i].dest_rptr, rptrbuf.vpkt.hdr.rpt1, 8); + band_txt[i].dest_rptr[8] = '\0'; } - i = readBuffer[27] - 'A'; + i = rptrbuf.vpkt.hdr.rpt1[7] - 'A'; /* valid destination repeater module? */ if (i>=0 && i<3) { // toRptr[i] : receiving from a remote system or cross-band // band_txt[i] : local RF is talking. 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", rptrbuf.vpkt.hdr.rpt2[7], rptrbuf.vpkt.hdr.rpt1[7]); - readBuffer[35] = 'G'; - calcPFCS(readBuffer, 58); + rptrbuf.vpkt.hdr.rpt2[7] = 'G'; + calcPFCS(rptrbuf.pkt_id, 58); - sendto(srv_sock, readBuffer,58,0, (struct sockaddr *)&toRptr[i].band_addr, sizeof(struct sockaddr_in)); + sendto(srv_sock, rptrbuf.pkt_id, 58, 0, (struct sockaddr *)&toRptr[i].band_addr, sizeof(struct sockaddr_in)); /* This is the active streamid */ - toRptr[i].streamid = readBuffer[14] + 256u * readBuffer[15]; + toRptr[i].streamid = rptrbuf.vpkt.streamid; toRptr[i].adr = fromRptr.sin_addr.s_addr; /* time it, in case stream times out */ @@ -1642,16 +1639,16 @@ static void runit() /* bump the G2 counter */ toRptr[i].G2_COUNTER ++; - toRptr[i].sequence = readBuffer[16]; + toRptr[i].sequence = rptrbuf.vpkt.ctrl; } } } } else { for (i = 0; i < 3; i++) { - if (memcmp(band_txt[i].streamID, readBuffer + 14, 2) == 0) { + if (band_txt[i].streamID == rptrbuf.vpkt.streamid) { time(&band_txt[i].last_time); - if ((readBuffer[16] & 0x40) != 0) { + if ((rptrbuf.vpkt.ctrl & 0x40) != 0) { if (dtmf_buf_count[i] > 0) { dtmf_file = dtmf_dir; dtmf_file.push_back('/'); @@ -1685,8 +1682,8 @@ static void runit() band_txt[i].num_dv_silent_frames, band_txt[i].num_bit_errors); - band_txt[i].streamID[0] = band_txt[i].streamID[1] = 0x0; - band_txt[i].flags[0] = band_txt[i].flags[1] = band_txt[i].flags[2] = 0x0; + band_txt[i].streamID = 0; + band_txt[i].flags[0] = band_txt[i].flags[1] = band_txt[i].flags[2] = 0; band_txt[i].lh_mycall[0] = '\0'; band_txt[i].lh_sfx[0] = '\0'; band_txt[i].lh_yrcall[0] = '\0'; @@ -1705,11 +1702,11 @@ static void runit() band_txt[i].num_bit_errors = 0; } else { - ber_errs = dstar_dv_decode(readBuffer + 17, ber_data); + ber_errs = dstar_dv_decode(rptrbuf.vpkt.vasd.voice, ber_data); if (ber_data[0] == 0xf85) - band_txt[i].num_dv_silent_frames ++; + band_txt[i].num_dv_silent_frames++; band_txt[i].num_bit_errors += ber_errs; - band_txt[i].num_dv_frames ++; + band_txt[i].num_dv_frames++; if ((ber_data[0] & 0x0ffc) == 0xfc0) { dtmf_digit = (ber_data[0] & 0x03) | ((ber_data[2] & 0x60) >> 3); @@ -1728,7 +1725,7 @@ static void runit() } } const unsigned char silence[9] = { 0x4e,0x8d,0x32,0x88,0x26,0x1a,0x3f,0x61,0xe8 }; - memcpy(readBuffer + 17, silence, 9); + memcpy(rptrbuf.vpkt.vasd.voice, silence, 9); } else dtmf_counter[i] = 0; } @@ -1737,9 +1734,9 @@ static void runit() } if (recvlen == 29) - memcpy(tmp_txt, readBuffer + 26, 3); + memcpy(tmp_txt, rptrbuf.vpkt.vasd.text, 3); else - memcpy(tmp_txt, readBuffer + 29, 3); + memcpy(tmp_txt, rptrbuf.vpkt.vasd1.text, 3); // traceit("%x%x%x\n", tmp_txt[0], tmp_txt[1], tmp_txt[2]); // traceit("%c%c%c\n", tmp_txt[0] ^ 0x70, tmp_txt[1] ^ 0x4f, tmp_txt[2] ^ 0x93); @@ -1750,7 +1747,7 @@ static void runit() // traceit("%c%c%c\n", tmp_txt[0] ^ 0x70, tmp_txt[1] ^ 0x4f, tmp_txt[2] ^ 0x93); for (i = 0; i < 3; i++) { - if (memcmp(band_txt[i].streamID, readBuffer + 14, 2) == 0) { + if (band_txt[i].streamID == rptrbuf.vpkt.streamid) { if (new_group[i]) { tmp_txt[0] = tmp_txt[0] ^ 0x70; header_type = tmp_txt[0] & 0xf0; @@ -1861,13 +1858,13 @@ static void runit() */ if (band_txt[i].txt_stats_sent) { if (recvlen == 29) { - readBuffer[26] = 0x70; - readBuffer[27] = 0x4f; - readBuffer[28] = 0x93; + rptrbuf.vpkt.vasd.text[0] = 0x70; + rptrbuf.vpkt.vasd.text[1] = 0x4f; + rptrbuf.vpkt.vasd.text[2] = 0x93; } else { - readBuffer[29] = 0x70; - readBuffer[30] = 0x4f; - readBuffer[31] = 0x93; + rptrbuf.vpkt.vasd1.text[0] = 0x70; + rptrbuf.vpkt.vasd1.text[1] = 0x4f; + rptrbuf.vpkt.vasd1.text[2] = 0x93; } } @@ -1912,13 +1909,13 @@ static void runit() */ if (band_txt[i].txt_stats_sent) { if (recvlen == 29) { - readBuffer[26] = 0x70; - readBuffer[27] = 0x4f; - readBuffer[28] = 0x93; + rptrbuf.vpkt.vasd.text[0] = 0x70; + rptrbuf.vpkt.vasd.text[1] = 0x4f; + rptrbuf.vpkt.vasd.text[2] = 0x93; } else { - readBuffer[29] = 0x70; - readBuffer[30] = 0x4f; - readBuffer[31] = 0x93; + rptrbuf.vpkt.vasd1.text[0] = 0x70; + rptrbuf.vpkt.vasd1.text[1] = 0x4f; + rptrbuf.vpkt.vasd1.text[2] = 0x93; } } @@ -2069,31 +2066,31 @@ static void runit() } /* send data to g2_link */ - sendto(srv_sock, readBuffer, recvlen, 0, (struct sockaddr *)&plug, sizeof(struct sockaddr_in)); + 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(readBuffer+14, readBuffer[16], readBuffer+17, (recvlen == 29)?12:15); + // streamID seq audio+text size + aprs->ProcessText(rptrbuf.vpkt.streamid, rptrbuf.vpkt.ctrl, rptrbuf.vpkt.vasd.voice, (recvlen == 29)?12:15); for (i = 0; i < 3; i++) { /* find out if data must go to the remote G2 */ - if (memcmp(&to_remote_g2[i].streamid, readBuffer + 14, 2) == 0) { + 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] = 0x00; - memcpy(&g2buf.id, readBuffer + 10, 7); + memcpy(&g2buf.id, &rptrbuf.vpkt.icm_id, 7); if (recvlen == 29) - memcpy(g2buf.vasd.voice, readBuffer + 17, 12); + memcpy(g2buf.vasd.voice, rptrbuf.vpkt.vasd.voice, 12); else - memcpy(g2buf.vasd.voice, readBuffer + 20, 12); + memcpy(g2buf.vasd.voice, rptrbuf.vpkt.vasd1.voice, 12); 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 (readBuffer[16] & 0x40) { + 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; @@ -2101,27 +2098,27 @@ static void runit() break; } else /* Is the data to be recorded for echotest */ - if (recd[i].fd>=0 && 0==memcmp(&recd[i].streamid, readBuffer + 14, 2)) { + if (recd[i].fd>=0 && recd[i].streamid==rptrbuf.vpkt.streamid) { time(&recd[i].last_time); memcpy(recbuf.title, "DSVT", 4); recbuf.config = 0x20; - for (int k=0; k<3; k++) { - recbuf.flaga[k] = 0; - recbuf.flagb[k] = readBuffer[k+11]; - } - recbuf.id = readBuffer[10]; - memcpy(&recbuf.streamid, readBuffer + 14, 3); + 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, readBuffer + 17, 12); + memcpy(recbuf.vasd.voice, rptrbuf.vpkt.vasd.voice, 12); else - memcpy(recbuf.vasd.voice, readBuffer + 20, 12); + 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 ((readBuffer[16] & 0x40) != 0) { + if ((rptrbuf.vpkt.ctrl & 0x40) != 0) { recd[i].streamid = 0; recd[i].last_time = 0; close(recd[i].fd); @@ -2141,28 +2138,27 @@ static void runit() break; } else /* Is the data to be recorded for voicemail */ - if ((vm[i].fd >= 0) && - (memcmp(&vm[i].streamid, readBuffer + 14, 2) == 0)) { + if ((vm[i].fd >= 0) && (vm[i].streamid==rptrbuf.vpkt.streamid)) { time(&vm[i].last_time); memcpy(recbuf.title, "DSVT", 4); recbuf.config = 0x20; - for (int k=0; k<3; k++) { - recbuf.flaga[k] = 0; - recbuf.flagb[k] = readBuffer[k+11]; - } - recbuf.id = readBuffer[10]; - memcpy(&recbuf.streamid, readBuffer + 14, 3); + 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, readBuffer + 17, 12); + memcpy(recbuf.vasd.voice, rptrbuf.vpkt.vasd.voice, 12); else - memcpy(recbuf.vasd.voice, readBuffer + 20, 12); + 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 ((readBuffer[16] & 0x40) != 0) { + if ((rptrbuf.vpkt.ctrl & 0x40) != 0) { vm[i].streamid = 0; vm[i].last_time = 0; close(vm[i].fd); @@ -2172,8 +2168,8 @@ static void runit() break; } else /* or maybe this is cross-banding data */ - if ((memcmp(&toRptr[i].streamid, readBuffer + 14, 2) == 0) && (toRptr[i].adr == fromRptr.sin_addr.s_addr)) { - sendto(srv_sock, readBuffer, 29, 0, (struct sockaddr *)&toRptr[i].band_addr, sizeof(struct sockaddr_in)); + 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)); /* timeit */ time(&toRptr[i].last_time); @@ -2181,10 +2177,10 @@ static void runit() /* bump G2 counter */ toRptr[i].G2_COUNTER ++; - toRptr[i].sequence = readBuffer[16]; + toRptr[i].sequence = rptrbuf.vpkt.ctrl; /* End of stream ? */ - if ((readBuffer[16] & 0x40) != 0) { + if (rptrbuf.vpkt.ctrl & 0x40) { toRptr[i].last_time = 0; toRptr[i].streamid = 0; toRptr[i].adr = 0; @@ -2193,11 +2189,9 @@ static void runit() } } - if ((readBuffer[16] & 0x40) != 0) { + if (rptrbuf.vpkt.ctrl & 0x40) { if (bool_qso_details) - traceit("END from rptr: cntr=%02x %02x, streamID=%02x,%02x, %d bytes\n", - readBuffer[4], readBuffer[5], - readBuffer[14],readBuffer[15],recvlen); + traceit("END from rptr: cntr=%04x, streamID=%04x, %d bytes\n", rptrbuf.counter, rptrbuf.vpkt.streamid, recvlen); } } } diff --git a/g2_link.cpp b/g2_link.cpp index ae5066f..9f3526a 100644 --- a/g2_link.cpp +++ b/g2_link.cpp @@ -1548,10 +1548,10 @@ static void runit() to_remote_g2[i].countdown = TIMEOUT; } } - } else + } else if (recvlen2 == (CALL_SIZE + 6)) { /* A packet of length (CALL_SIZE + 6) is either an ACK or a NAK from repeater-reflector */ /* Because we sent a request before asking to link */ - if (recvlen2 == (CALL_SIZE + 6)) { + for (i = 0; i < 3; i++) { if ((fromDst4.sin_addr.s_addr == to_remote_g2[i].toDst4.sin_addr.s_addr) && (to_remote_g2[i].toDst4.sin_port == htons(rmt_xrf_port))) { @@ -1598,545 +1598,543 @@ static void runit() } } } - } else - /* - A packet of length (CALL_SIZE + 3) is a request - from a remote repeater to link-unlink with our repeater - */ - if (recvlen2 == CALL_SIZE + 3) { - /* Check our linked repeaters/reflectors */ - for (i = 0; i < 3; i++) { - if ((fromDst4.sin_addr.s_addr == to_remote_g2[i].toDst4.sin_addr.s_addr) && - (to_remote_g2[i].toDst4.sin_port == htons(rmt_xrf_port))) { - if (to_remote_g2[i].to_mod == readBuffer2[8]) { - /* unlink request from remote repeater that we know */ - if (readBuffer2[9] == ' ') { - traceit("Received: %.*s\n", recvlen2 - 1, readBuffer2); - traceit("Module %c to [%s] %c is unlinked\n", - to_remote_g2[i].from_mod, - to_remote_g2[i].to_call, to_remote_g2[i].to_mod); - - sprintf(notify_msg, "%c_unlinked.dat_UNLINKED", to_remote_g2[i].from_mod); - audio_notify(notify_msg); - - to_remote_g2[i].to_call[0] = '\0'; - memset(&(to_remote_g2[i].toDst4),0,sizeof(struct sockaddr_in)); - to_remote_g2[i].from_mod = ' '; - to_remote_g2[i].to_mod = ' '; - to_remote_g2[i].countdown = 0; - to_remote_g2[i].is_connected = false; - to_remote_g2[i].in_streamid[0] = 0x00; - to_remote_g2[i].in_streamid[1] = 0x00; + } else if (recvlen2 == CALL_SIZE + 3) { + /* + A packet of length (CALL_SIZE + 3) is a request + from a remote repeater to link-unlink with our repeater + */ + + /* Check our linked repeaters/reflectors */ + for (i = 0; i < 3; i++) { + if ((fromDst4.sin_addr.s_addr == to_remote_g2[i].toDst4.sin_addr.s_addr) && + (to_remote_g2[i].toDst4.sin_port == htons(rmt_xrf_port))) { + if (to_remote_g2[i].to_mod == readBuffer2[8]) { + /* unlink request from remote repeater that we know */ + if (readBuffer2[9] == ' ') { + traceit("Received: %.*s\n", recvlen2 - 1, readBuffer2); + traceit("Module %c to [%s] %c is unlinked\n", + to_remote_g2[i].from_mod, + to_remote_g2[i].to_call, to_remote_g2[i].to_mod); + + sprintf(notify_msg, "%c_unlinked.dat_UNLINKED", to_remote_g2[i].from_mod); + audio_notify(notify_msg); - print_status_file(); - } else - /* link request from a remote repeater that we know */ - if ( - ((i == 0) && (readBuffer2[9] == 'A')) || - ((i == 1) && (readBuffer2[9] == 'B')) || - ((i == 2) && (readBuffer2[9] == 'C')) - ) { - - /* - I HAVE TO ADD CODE here to PREVENT the REMOTE NODE - from LINKING one of their remote modules to - more than one of our local modules - */ - - traceit("Received: %.*s\n", recvlen2 - 1, readBuffer2); - - strncpy(to_remote_g2[i].to_call, (char *)readBuffer2,CALL_SIZE); - to_remote_g2[i].to_call[CALL_SIZE] = '\0'; - memcpy(&(to_remote_g2[i].toDst4), &fromDst4, sizeof(struct sockaddr_in)); - to_remote_g2[i].toDst4.sin_port = htons(rmt_xrf_port); - to_remote_g2[i].to_mod = readBuffer2[8]; - to_remote_g2[i].countdown = TIMEOUT; - to_remote_g2[i].is_connected = true; - to_remote_g2[i].in_streamid[0] = 0x00; - to_remote_g2[i].in_streamid[1] = 0x00; - - traceit("Module %c to [%s] %c linked\n", - readBuffer2[9], - to_remote_g2[i].to_call, to_remote_g2[i].to_mod); - - tracing[i].last_time = time(NULL); - - print_status_file(); - - /* send back an ACK */ - memcpy(readBuffer2 + 10, "ACK", 4); - sendto(xrf_g2_sock, readBuffer2, CALL_SIZE+6, 0, (struct sockaddr *)&(to_remote_g2[i].toDst4), sizeof(struct sockaddr_in)); - - if (to_remote_g2[i].from_mod != readBuffer2[9]) { - to_remote_g2[i].from_mod = readBuffer2[9]; - - strcpy(linked_remote_system, to_remote_g2[i].to_call); - space_p = strchr(linked_remote_system, ' '); - if (space_p) - *space_p = '\0'; - sprintf(notify_msg, "%c_linked.dat_LINKED_%s_%c", - to_remote_g2[i].from_mod, - linked_remote_system, - to_remote_g2[i].to_mod); - audio_notify(notify_msg); - } - } - } - } - } + to_remote_g2[i].to_call[0] = '\0'; + memset(&(to_remote_g2[i].toDst4),0,sizeof(struct sockaddr_in)); + to_remote_g2[i].from_mod = ' '; + to_remote_g2[i].to_mod = ' '; + to_remote_g2[i].countdown = 0; + to_remote_g2[i].is_connected = false; + to_remote_g2[i].in_streamid[0] = 0x00; + to_remote_g2[i].in_streamid[1] = 0x00; - /* link request from remote repeater that is not yet linked to our system */ - /* find out which of our local modules the remote repeater is interested in */ - i = -1; - if (readBuffer2[9] == 'A') - i = 0; - else if (readBuffer2[9] == 'B') - i = 1; - else if (readBuffer2[9] == 'C') - i = 2; - - /* Is this repeater listed in gwys.txt? */ - gwy_pos = gwy_list.find(call); - if (gwy_pos == gwy_list.end()) { - /* We did NOT find this repeater in gwys.txt, reject the incoming link request */ - traceit("Incoming link from %s,%s but not found in gwys.txt\n",call,ip); - i = -1; - } else { - rc = regexec(&preg, call, 0, NULL, 0); - if (rc != 0) { - traceit("Invalid repeater %s,%s requesting to link\n", call, ip); - i = -1; - } - } + print_status_file(); + } else + /* link request from a remote repeater that we know */ + if ( + ((i == 0) && (readBuffer2[9] == 'A')) || + ((i == 1) && (readBuffer2[9] == 'B')) || + ((i == 2) && (readBuffer2[9] == 'C')) + ) { - if (i >= 0) { - /* Is the local repeater module linked to anything ? */ - if (to_remote_g2[i].to_mod == ' ') { - if ((readBuffer2[8] == 'A') || (readBuffer2[8] == 'B') || (readBuffer2[8] == 'C') || - (readBuffer2[8] == 'D') || (readBuffer2[8] == 'E')) { /* I HAVE TO ADD CODE here to PREVENT the REMOTE NODE from LINKING one of their remote modules to more than one of our local modules */ - /* now it can be added as a repeater */ - strcpy(to_remote_g2[i].to_call, call); + traceit("Received: %.*s\n", recvlen2 - 1, readBuffer2); + + strncpy(to_remote_g2[i].to_call, (char *)readBuffer2,CALL_SIZE); to_remote_g2[i].to_call[CALL_SIZE] = '\0'; memcpy(&(to_remote_g2[i].toDst4), &fromDst4, sizeof(struct sockaddr_in)); to_remote_g2[i].toDst4.sin_port = htons(rmt_xrf_port); - to_remote_g2[i].from_mod = readBuffer2[9]; to_remote_g2[i].to_mod = readBuffer2[8]; to_remote_g2[i].countdown = TIMEOUT; to_remote_g2[i].is_connected = true; to_remote_g2[i].in_streamid[0] = 0x00; to_remote_g2[i].in_streamid[1] = 0x00; - print_status_file(); + traceit("Module %c to [%s] %c linked\n", + readBuffer2[9], + to_remote_g2[i].to_call, to_remote_g2[i].to_mod); tracing[i].last_time = time(NULL); - traceit("Received: %.*s\n", recvlen2 - 1, readBuffer2); - traceit("Module %c to [%s] %c linked\n", - to_remote_g2[i].from_mod, - to_remote_g2[i].to_call, to_remote_g2[i].to_mod); - - strcpy(linked_remote_system, to_remote_g2[i].to_call); - space_p = strchr(linked_remote_system, ' '); - if (space_p) - *space_p = '\0'; - sprintf(notify_msg, "%c_linked.dat_LINKED_%s_%c", - to_remote_g2[i].from_mod, - linked_remote_system, - to_remote_g2[i].to_mod); - audio_notify(notify_msg); + print_status_file(); /* send back an ACK */ memcpy(readBuffer2 + 10, "ACK", 4); sendto(xrf_g2_sock, readBuffer2, CALL_SIZE+6, 0, (struct sockaddr *)&(to_remote_g2[i].toDst4), sizeof(struct sockaddr_in)); + + if (to_remote_g2[i].from_mod != readBuffer2[9]) { + to_remote_g2[i].from_mod = readBuffer2[9]; + + strcpy(linked_remote_system, to_remote_g2[i].to_call); + space_p = strchr(linked_remote_system, ' '); + if (space_p) + *space_p = '\0'; + sprintf(notify_msg, "%c_linked.dat_LINKED_%s_%c", + to_remote_g2[i].from_mod, + linked_remote_system, + to_remote_g2[i].to_mod); + audio_notify(notify_msg); + } } - } else { - if (fromDst4.sin_addr.s_addr != to_remote_g2[i].toDst4.sin_addr.s_addr) { - /* Our repeater module is linked to another repeater-reflector */ - memcpy(readBuffer2 + 10, "NAK", 4); - fromDst4.sin_port = htons(rmt_xrf_port); - sendto(xrf_g2_sock, readBuffer2, CALL_SIZE+6, 0, (struct sockaddr *)&fromDst4, sizeof(struct sockaddr_in)); - } - } } - } else if ( ((recvlen2 == 56) || - (recvlen2 == 27)) && - (memcmp(readBuffer2, "DSVT", 4) == 0) && - ((readBuffer2[4] == 0x10) || - (readBuffer2[4] == 0x20)) && - (readBuffer2[8] == 0x20)) { - /* reset countdown and protect against hackers */ - - found = false; - for (i = 0; i < 3; i++) { - if ((fromDst4.sin_addr.s_addr == to_remote_g2[i].toDst4.sin_addr.s_addr) && - (to_remote_g2[i].toDst4.sin_port == htons(rmt_xrf_port))) { - to_remote_g2[i].countdown = TIMEOUT; - found = true; - } + } + } + + /* link request from remote repeater that is not yet linked to our system */ + /* find out which of our local modules the remote repeater is interested in */ + i = -1; + if (readBuffer2[9] == 'A') + i = 0; + else if (readBuffer2[9] == 'B') + i = 1; + else if (readBuffer2[9] == 'C') + i = 2; + + /* Is this repeater listed in gwys.txt? */ + gwy_pos = gwy_list.find(call); + if (gwy_pos == gwy_list.end()) { + /* We did NOT find this repeater in gwys.txt, reject the incoming link request */ + traceit("Incoming link from %s,%s but not found in gwys.txt\n",call,ip); + i = -1; + } else { + rc = regexec(&preg, call, 0, NULL, 0); + if (rc != 0) { + traceit("Invalid repeater %s,%s requesting to link\n", call, ip); + i = -1; + } + } + + if (i >= 0) { + /* Is the local repeater module linked to anything ? */ + if (to_remote_g2[i].to_mod == ' ') { + if ((readBuffer2[8] == 'A') || (readBuffer2[8] == 'B') || (readBuffer2[8] == 'C') || + (readBuffer2[8] == 'D') || (readBuffer2[8] == 'E')) { + /* + I HAVE TO ADD CODE here to PREVENT the REMOTE NODE + from LINKING one of their remote modules to + more than one of our local modules + */ + + /* now it can be added as a repeater */ + strcpy(to_remote_g2[i].to_call, call); + to_remote_g2[i].to_call[CALL_SIZE] = '\0'; + memcpy(&(to_remote_g2[i].toDst4), &fromDst4, sizeof(struct sockaddr_in)); + to_remote_g2[i].toDst4.sin_port = htons(rmt_xrf_port); + to_remote_g2[i].from_mod = readBuffer2[9]; + to_remote_g2[i].to_mod = readBuffer2[8]; + to_remote_g2[i].countdown = TIMEOUT; + to_remote_g2[i].is_connected = true; + to_remote_g2[i].in_streamid[0] = 0x00; + to_remote_g2[i].in_streamid[1] = 0x00; + + print_status_file(); + + tracing[i].last_time = time(NULL); + + traceit("Received: %.*s\n", recvlen2 - 1, readBuffer2); + traceit("Module %c to [%s] %c linked\n", + to_remote_g2[i].from_mod, + to_remote_g2[i].to_call, to_remote_g2[i].to_mod); + + strcpy(linked_remote_system, to_remote_g2[i].to_call); + space_p = strchr(linked_remote_system, ' '); + if (space_p) + *space_p = '\0'; + sprintf(notify_msg, "%c_linked.dat_LINKED_%s_%c", + to_remote_g2[i].from_mod, + linked_remote_system, + to_remote_g2[i].to_mod); + audio_notify(notify_msg); + + /* send back an ACK */ + memcpy(readBuffer2 + 10, "ACK", 4); + sendto(xrf_g2_sock, readBuffer2, CALL_SIZE+6, 0, (struct sockaddr *)&(to_remote_g2[i].toDst4), sizeof(struct sockaddr_in)); } + } else { + if (fromDst4.sin_addr.s_addr != to_remote_g2[i].toDst4.sin_addr.s_addr) { + /* Our repeater module is linked to another repeater-reflector */ + memcpy(readBuffer2 + 10, "NAK", 4); + fromDst4.sin_port = htons(rmt_xrf_port); + sendto(xrf_g2_sock, readBuffer2, CALL_SIZE+6, 0, (struct sockaddr *)&fromDst4, sizeof(struct sockaddr_in)); + } + } + } + } else if ( ((recvlen2 == 56) || (recvlen2 == 27)) && + (0 == memcmp(readBuffer2, "DSVT", 4)) && + ((readBuffer2[4] == 0x10) || (readBuffer2[4] == 0x20)) && + (readBuffer2[8] == 0x20)) { + /* reset countdown and protect against hackers */ - /* process header */ - - if ((recvlen2 == 56) && found) { - memset(source_stn, ' ', 9); - source_stn[8] = '\0'; - - /* some bad hotspot programs out there using INCORRECT flag */ - if (readBuffer2[15] == 0x40) - readBuffer2[15] = 0x00; - else if (readBuffer2[15] == 0x48) - readBuffer2[15] = 0x08; - else if (readBuffer2[15] == 0x60) - readBuffer2[15] = 0x20; - else if (readBuffer2[15] == 0x68) - readBuffer2[15] = 0x28; - - /* A reflector will send to us its own RPT1 */ - /* A repeater will send to us our RPT1 */ - - for (i = 0; i < 3; i++) { - if ((fromDst4.sin_addr.s_addr == to_remote_g2[i].toDst4.sin_addr.s_addr) && - (to_remote_g2[i].toDst4.sin_port == htons(rmt_xrf_port))) { - /* it is a reflector, reflector's rpt1 */ - if ((memcmp(readBuffer2 + 18, to_remote_g2[i].to_call, 7) == 0) && - (readBuffer2[25] == to_remote_g2[i].to_mod)) { - memcpy(&readBuffer2[18], owner.c_str(), CALL_SIZE); - readBuffer2[25] = to_remote_g2[i].from_mod; - memcpy(&readBuffer2[34], "CQCQCQ ", 8); - - memcpy(source_stn, to_remote_g2[i].to_call, 8); - source_stn[7] = to_remote_g2[i].to_mod; - break; - } else - /* it is a repeater, our rpt1 */ - if ((memcmp(readBuffer2 + 18, owner.c_str(), CALL_SIZE-1)) && - (readBuffer2[25] == to_remote_g2[i].from_mod)) { - memcpy(source_stn, to_remote_g2[i].to_call, 8); - source_stn[7] = to_remote_g2[i].to_mod; - break; - } - } - } + found = false; + for (i = 0; i < 3; i++) { + if ((fromDst4.sin_addr.s_addr == to_remote_g2[i].toDst4.sin_addr.s_addr) && + (to_remote_g2[i].toDst4.sin_port == htons(rmt_xrf_port))) { + to_remote_g2[i].countdown = TIMEOUT; + found = true; + } + } - /* somebody's crazy idea of having a personal callsign in RPT2 */ - /* we must set it to our gateway callsign */ - memcpy(&readBuffer2[26], owner.c_str(), CALL_SIZE); - readBuffer2[33] = 'G'; - calcPFCS(readBuffer2,56); - - /* At this point, all data have our RPT1 and RPT2 */ - - /* send the data to the repeater/reflector that is linked to our RPT1 */ - i = -1; - if (readBuffer2[25] == 'A') - i = 0; - else if (readBuffer2[25] == 'B') - i = 1; - else if (readBuffer2[25] == 'C') - i = 2; - - /* are we sure that RPT1 is our system? */ - if ((memcmp(readBuffer2 + 18, owner.c_str(), CALL_SIZE-1) == 0) && (i >= 0)) { - /* Last Heard */ - if (memcmp(old_sid[i].sid, readBuffer2 + 12, 2) != 0) { - if (qso_details) - traceit("START from remote g2: streamID=%d,%d, flags=%02x:%02x:%02x, my=%.8s, sfx=%.4s, ur=%.8s, rpt1=%.8s, rpt2=%.8s, %d bytes fromIP=%s, source=%.8s\n", - readBuffer2[12],readBuffer2[13], - readBuffer2[15], readBuffer2[16], readBuffer2[17], - &readBuffer2[42], - &readBuffer2[50], &readBuffer2[34], - &readBuffer2[18], &readBuffer2[26], - recvlen2,inet_ntoa(fromDst4.sin_addr), source_stn); - - // put user into tmp1 - memcpy(tmp1, readBuffer2 + 42, 8); - tmp1[8] = '\0'; - - // delete the user if exists - for (dt_lh_pos = dt_lh_list.begin(); dt_lh_pos != dt_lh_list.end(); dt_lh_pos++) { - if (strcmp((char *)dt_lh_pos->second.c_str(), tmp1) == 0) { - dt_lh_list.erase(dt_lh_pos); - break; - } - } - /* Limit?, delete oldest user */ - if (dt_lh_list.size() == LH_MAX_SIZE) { - dt_lh_pos = dt_lh_list.begin(); - dt_lh_list.erase(dt_lh_pos); - } - // add user - time(&tnow); - sprintf(tmp2, "%ld=r%.6s%c%c", tnow, source_stn, source_stn[7], readBuffer2[25]); - dt_lh_list[tmp2] = tmp1; + /* process header */ - memcpy(old_sid[i].sid, readBuffer2 + 12, 2); - } + if ((recvlen2 == 56) && found) { + memset(source_stn, ' ', 9); + source_stn[8] = '\0'; - /* relay data to our local G2 */ - sendto(rptr_sock, readBuffer2,56,0,(struct sockaddr *)&toLocalg2,sizeof(struct sockaddr_in)); + /* some bad hotspot programs out there using INCORRECT flag */ + if (readBuffer2[15] == 0x40) + readBuffer2[15] = 0x00; + else if (readBuffer2[15] == 0x48) + readBuffer2[15] = 0x08; + else if (readBuffer2[15] == 0x60) + readBuffer2[15] = 0x20; + else if (readBuffer2[15] == 0x68) + readBuffer2[15] = 0x28; - /* send data to donglers */ - /* no changes here */ - for (pos = inbound_list.begin(); pos != inbound_list.end(); pos++) { - inbound_ptr = (inbound *)pos->second; - if (fromDst4.sin_addr.s_addr != inbound_ptr->sin.sin_addr.s_addr) { - readBuffer[0] = (unsigned char)(58 & 0xFF); - readBuffer[1] = (unsigned char)(58 >> 8 & 0x1F); - readBuffer[1] = (unsigned char)(readBuffer[1] | 0xFFFFFF80); - memcpy(readBuffer + 2, readBuffer2, 56); + /* A reflector will send to us its own RPT1 */ + /* A repeater will send to us our RPT1 */ - sendto(ref_g2_sock, readBuffer, 58, 0, (struct sockaddr *)&(inbound_ptr->sin), sizeof(struct sockaddr_in)); - } else - inbound_ptr->mod = readBuffer2[25]; + for (i = 0; i < 3; i++) { + if ((fromDst4.sin_addr.s_addr == to_remote_g2[i].toDst4.sin_addr.s_addr) && + (to_remote_g2[i].toDst4.sin_port == htons(rmt_xrf_port))) { + /* it is a reflector, reflector's rpt1 */ + if ((memcmp(readBuffer2 + 18, to_remote_g2[i].to_call, 7) == 0) && + (readBuffer2[25] == to_remote_g2[i].to_mod)) { + memcpy(&readBuffer2[18], owner.c_str(), CALL_SIZE); + readBuffer2[25] = to_remote_g2[i].from_mod; + memcpy(&readBuffer2[34], "CQCQCQ ", 8); + + memcpy(source_stn, to_remote_g2[i].to_call, 8); + source_stn[7] = to_remote_g2[i].to_mod; + break; + } else + /* it is a repeater, our rpt1 */ + if ((memcmp(readBuffer2 + 18, owner.c_str(), CALL_SIZE-1)) && + (readBuffer2[25] == to_remote_g2[i].from_mod)) { + memcpy(source_stn, to_remote_g2[i].to_call, 8); + source_stn[7] = to_remote_g2[i].to_mod; + break; } + } + } - /* send the data to the repeater/reflector that is linked to our RPT1 */ - - /* Is there another local module linked to the remote same xrf mod ? */ - /* If Yes, then broadcast */ - k = i + 1; - - if (k < 3) { - brd_from_xrf_idx = 0; - streamid_raw = (readBuffer2[12] * 256U) + readBuffer2[13]; - - /* We can only enter this loop up to 2 times max */ - for (j = k; j < 3; j++) { - /* it is a remote gateway, not a dongle user */ - if ((fromDst4.sin_addr.s_addr == to_remote_g2[j].toDst4.sin_addr.s_addr) && - /* it is xrf */ - (to_remote_g2[j].toDst4.sin_port == htons(rmt_xrf_port)) && - (memcmp(to_remote_g2[j].to_call, "XRF", 3) == 0) && - /* it is the same xrf and xrf module */ - (memcmp(to_remote_g2[j].to_call, to_remote_g2[i].to_call, 8) == 0) && - (to_remote_g2[j].to_mod == to_remote_g2[i].to_mod)) { - /* send the packet to another module of our local repeater: this is multi-link */ - - /* generate new packet */ - memcpy(from_xrf_torptr_brd, readBuffer2, 56); - - /* different repeater module */ - from_xrf_torptr_brd[25] = to_remote_g2[j].from_mod; - - /* assign new streamid */ - streamid_raw ++; - if (streamid_raw == 0) - streamid_raw ++; - from_xrf_torptr_brd[12] = streamid_raw / 256U; - from_xrf_torptr_brd[13] = streamid_raw % 256U; - - calcPFCS(from_xrf_torptr_brd, 56); - - /* send the data to the local gateway/repeater */ - sendto(rptr_sock, from_xrf_torptr_brd, 56, 0, (struct sockaddr *)&toLocalg2,sizeof(struct sockaddr_in)); - - /* save streamid for use with the audio packets that will arrive after this header */ - - brd_from_xrf.xrf_streamid[0] = readBuffer2[12]; - brd_from_xrf.xrf_streamid[1] = readBuffer2[13]; - brd_from_xrf.rptr_streamid[brd_from_xrf_idx][0] = from_xrf_torptr_brd[12]; - brd_from_xrf.rptr_streamid[brd_from_xrf_idx][1] = from_xrf_torptr_brd[13]; - brd_from_xrf_idx ++; - } - } - } + /* somebody's crazy idea of having a personal callsign in RPT2 */ + /* we must set it to our gateway callsign */ + memcpy(&readBuffer2[26], owner.c_str(), CALL_SIZE); + readBuffer2[33] = 'G'; + calcPFCS(readBuffer2,56); - if ((to_remote_g2[i].toDst4.sin_addr.s_addr != fromDst4.sin_addr.s_addr) && - to_remote_g2[i].is_connected) { - if (to_remote_g2[i].toDst4.sin_port == htons(rmt_xrf_port)) { - if ( /*** (memcmp(readBuffer2 + 42, owner, 8) != 0) && ***/ /* block repeater announcements */ - (memcmp(readBuffer2 + 34, "CQCQCQ", 6) == 0) && /* CQ calls only */ - ((readBuffer2[15] == 0x00) || /* normal */ - (readBuffer2[15] == 0x08) || /* EMR */ - (readBuffer2[15] == 0x20) || /* BK */ - (readBuffer2[15] == 0x28)) && /* EMR + BK */ - (memcmp(readBuffer2 + 26, owner.c_str(), CALL_SIZE-1) == 0) && /* rpt2 must be us */ - (readBuffer2[33] == 'G')) { - to_remote_g2[i].in_streamid[0] = readBuffer2[12]; - to_remote_g2[i].in_streamid[1] = readBuffer2[13]; - - /* inform XRF about the source */ - readBuffer2[11] = to_remote_g2[i].from_mod; - - memcpy((char *)readBuffer2 + 18, to_remote_g2[i].to_call, CALL_SIZE); - readBuffer2[25] = to_remote_g2[i].to_mod; - memcpy((char *)readBuffer2 + 26, to_remote_g2[i].to_call, CALL_SIZE); - readBuffer2[33] = 'G'; - calcPFCS(readBuffer2, 56); - - sendto(xrf_g2_sock, readBuffer2, 56, 0, (struct sockaddr *)&(to_remote_g2[i].toDst4), sizeof(struct sockaddr_in)); - } - } else if (to_remote_g2[i].toDst4.sin_port == htons(rmt_ref_port)) { - if ( /*** (memcmp(readBuffer2 + 42, owner, 8) != 0) && ***/ /* block repeater announcements */ - (memcmp(readBuffer2 + 34, "CQCQCQ", 6) == 0) && /* CQ calls only */ - ((readBuffer2[15] == 0x00) || /* normal */ - (readBuffer2[15] == 0x08) || /* EMR */ - (readBuffer2[15] == 0x20) || /* BK */ - (readBuffer2[15] == 0x28)) && /* EMR + BK */ - (memcmp(readBuffer2 + 26, owner.c_str(), CALL_SIZE-1) == 0) && /* rpt2 must be us */ - (readBuffer2[33] == 'G')) { - to_remote_g2[i].in_streamid[0] = readBuffer2[12]; - to_remote_g2[i].in_streamid[1] = readBuffer2[13]; - - readBuffer[0] = (unsigned char)(58 & 0xFF); - readBuffer[1] = (unsigned char)(58 >> 8 & 0x1F); - readBuffer[1] = (unsigned char)(readBuffer[1] | 0xFFFFFF80); - - memcpy(readBuffer + 2, readBuffer2, 56); - - memset(readBuffer + 20, ' ', CALL_SIZE); - memcpy(readBuffer + 20, to_remote_g2[i].to_call, - strlen(to_remote_g2[i].to_call)); - readBuffer[27] = to_remote_g2[i].to_mod; - memset(readBuffer + 28, ' ', CALL_SIZE); - memcpy(readBuffer + 28, to_remote_g2[i].to_call, - strlen(to_remote_g2[i].to_call)); - readBuffer[35] = 'G'; - memcpy(&readBuffer[36], "CQCQCQ ", 8); - - calcPFCS(readBuffer + 2, 56); - - sendto(ref_g2_sock, readBuffer, 58, 0, (struct sockaddr *)&(to_remote_g2[i].toDst4), sizeof(struct sockaddr_in)); - } - } else if (to_remote_g2[i].toDst4.sin_port == htons(rmt_dcs_port)) { - if ( /*** (memcmp(readBuffer2 + 42, owner, 8) != 0) && ***/ /* block repeater announcements */ - (memcmp(readBuffer2 + 34, "CQCQCQ", 6) == 0) && /* CQ calls only */ - ((readBuffer2[15] == 0x00) || /* normal */ - (readBuffer2[15] == 0x08) || /* EMR */ - (readBuffer2[15] == 0x20) || /* BK */ - (readBuffer2[15] == 0x28)) && /* EMR + BK */ - (memcmp(readBuffer2 + 26, owner.c_str(), CALL_SIZE-1) == 0) && /* rpt2 must be us */ - (readBuffer2[33] == 'G')) { - to_remote_g2[i].in_streamid[0] = readBuffer2[12]; - to_remote_g2[i].in_streamid[1] = readBuffer2[13]; - - memcpy(xrf_2_dcs[i].mycall, readBuffer2 + 42, 8); - memcpy(xrf_2_dcs[i].sfx, readBuffer2 + 50, 4); - xrf_2_dcs[i].dcs_rptr_seq = 0; - } - } - } - } - } else if (found) { - if ((readBuffer2[14] & 0x40) != 0) { - for (i = 0; i < 3; i++) { - if (memcmp(old_sid[i].sid, readBuffer2 + 12, 2) == 0) { - if (qso_details) - traceit("END from remote g2: streamID=%d,%d, %d bytes from IP=%s\n", - readBuffer2[12],readBuffer2[13],recvlen2,inet_ntoa(fromDst4.sin_addr)); + /* At this point, all data have our RPT1 and RPT2 */ + + /* send the data to the repeater/reflector that is linked to our RPT1 */ + i = -1; + if (readBuffer2[25] == 'A') + i = 0; + else if (readBuffer2[25] == 'B') + i = 1; + else if (readBuffer2[25] == 'C') + i = 2; + + /* are we sure that RPT1 is our system? */ + if ((memcmp(readBuffer2 + 18, owner.c_str(), CALL_SIZE-1) == 0) && (i >= 0)) { + /* Last Heard */ + if (memcmp(old_sid[i].sid, readBuffer2 + 12, 2) != 0) { + if (qso_details) + traceit("START from remote g2: streamID=%d,%d, flags=%02x:%02x:%02x, my=%.8s, sfx=%.4s, ur=%.8s, rpt1=%.8s, rpt2=%.8s, %d bytes fromIP=%s, source=%.8s\n", + readBuffer2[12],readBuffer2[13], + readBuffer2[15], readBuffer2[16], readBuffer2[17], + &readBuffer2[42], + &readBuffer2[50], &readBuffer2[34], + &readBuffer2[18], &readBuffer2[26], + recvlen2,inet_ntoa(fromDst4.sin_addr), source_stn); - memset(old_sid[i].sid, 0x00, 2); + // put user into tmp1 + memcpy(tmp1, readBuffer2 + 42, 8); + tmp1[8] = '\0'; - break; - } + // delete the user if exists + for (dt_lh_pos = dt_lh_list.begin(); dt_lh_pos != dt_lh_list.end(); dt_lh_pos++) { + if (strcmp((char *)dt_lh_pos->second.c_str(), tmp1) == 0) { + dt_lh_list.erase(dt_lh_pos); + break; } } + /* Limit?, delete oldest user */ + if (dt_lh_list.size() == LH_MAX_SIZE) { + dt_lh_pos = dt_lh_list.begin(); + dt_lh_list.erase(dt_lh_pos); + } + // add user + time(&tnow); + sprintf(tmp2, "%ld=r%.6s%c%c", tnow, source_stn, source_stn[7], readBuffer2[25]); + dt_lh_list[tmp2] = tmp1; - /* relay data to our local G2 */ - sendto(rptr_sock, readBuffer2, 27, 0, (struct sockaddr *)&toLocalg2, sizeof(struct sockaddr_in)); + memcpy(old_sid[i].sid, readBuffer2 + 12, 2); + } - /* send data to donglers */ - /* no changes here */ - for (pos = inbound_list.begin(); pos != inbound_list.end(); pos++) { - inbound_ptr = (inbound *)pos->second; - if (fromDst4.sin_addr.s_addr != inbound_ptr->sin.sin_addr.s_addr) { - readBuffer[0] = (unsigned char)(29 & 0xFF); - readBuffer[1] = (unsigned char)(29 >> 8 & 0x1F); - readBuffer[1] = (unsigned char)(readBuffer[1] | 0xFFFFFF80); + /* relay data to our local G2 */ + sendto(rptr_sock, readBuffer2,56,0,(struct sockaddr *)&toLocalg2,sizeof(struct sockaddr_in)); + + /* send data to donglers */ + /* no changes here */ + for (pos = inbound_list.begin(); pos != inbound_list.end(); pos++) { + inbound_ptr = (inbound *)pos->second; + if (fromDst4.sin_addr.s_addr != inbound_ptr->sin.sin_addr.s_addr) { + readBuffer[0] = (unsigned char)(58 & 0xFF); + readBuffer[1] = (unsigned char)(58 >> 8 & 0x1F); + readBuffer[1] = (unsigned char)(readBuffer[1] | 0xFFFFFF80); + memcpy(readBuffer + 2, readBuffer2, 56); + + sendto(ref_g2_sock, readBuffer, 58, 0, (struct sockaddr *)&(inbound_ptr->sin), sizeof(struct sockaddr_in)); + } else + inbound_ptr->mod = readBuffer2[25]; + } + + /* send the data to the repeater/reflector that is linked to our RPT1 */ + + /* Is there another local module linked to the remote same xrf mod ? */ + /* If Yes, then broadcast */ + k = i + 1; + + if (k < 3) { + brd_from_xrf_idx = 0; + streamid_raw = (readBuffer2[12] * 256U) + readBuffer2[13]; + + /* We can only enter this loop up to 2 times max */ + for (j = k; j < 3; j++) { + /* it is a remote gateway, not a dongle user */ + if ((fromDst4.sin_addr.s_addr == to_remote_g2[j].toDst4.sin_addr.s_addr) && + /* it is xrf */ + (to_remote_g2[j].toDst4.sin_port == htons(rmt_xrf_port)) && + (memcmp(to_remote_g2[j].to_call, "XRF", 3) == 0) && + /* it is the same xrf and xrf module */ + (memcmp(to_remote_g2[j].to_call, to_remote_g2[i].to_call, 8) == 0) && + (to_remote_g2[j].to_mod == to_remote_g2[i].to_mod)) { + /* send the packet to another module of our local repeater: this is multi-link */ + + /* generate new packet */ + memcpy(from_xrf_torptr_brd, readBuffer2, 56); + + /* different repeater module */ + from_xrf_torptr_brd[25] = to_remote_g2[j].from_mod; - memcpy(readBuffer + 2, readBuffer2, 27); + /* assign new streamid */ + streamid_raw ++; + if (streamid_raw == 0) + streamid_raw ++; + from_xrf_torptr_brd[12] = streamid_raw / 256U; + from_xrf_torptr_brd[13] = streamid_raw % 256U; + + calcPFCS(from_xrf_torptr_brd, 56); - sendto(ref_g2_sock, readBuffer, 29, 0, (struct sockaddr *)&(inbound_ptr->sin), sizeof(struct sockaddr_in)); + /* send the data to the local gateway/repeater */ + sendto(rptr_sock, from_xrf_torptr_brd, 56, 0, (struct sockaddr *)&toLocalg2,sizeof(struct sockaddr_in)); + + /* save streamid for use with the audio packets that will arrive after this header */ + + brd_from_xrf.xrf_streamid[0] = readBuffer2[12]; + brd_from_xrf.xrf_streamid[1] = readBuffer2[13]; + brd_from_xrf.rptr_streamid[brd_from_xrf_idx][0] = from_xrf_torptr_brd[12]; + brd_from_xrf.rptr_streamid[brd_from_xrf_idx][1] = from_xrf_torptr_brd[13]; + brd_from_xrf_idx ++; } } + } - /* do we have to broadcast ? */ - if (memcmp(brd_from_xrf.xrf_streamid, readBuffer2 + 12, 2) == 0) { - memcpy(from_xrf_torptr_brd, readBuffer2, 27); + if ((to_remote_g2[i].toDst4.sin_addr.s_addr != fromDst4.sin_addr.s_addr) && + to_remote_g2[i].is_connected) { + if (to_remote_g2[i].toDst4.sin_port == htons(rmt_xrf_port)) { + if ( /*** (memcmp(readBuffer2 + 42, owner, 8) != 0) && ***/ /* block repeater announcements */ + (memcmp(readBuffer2 + 34, "CQCQCQ", 6) == 0) && /* CQ calls only */ + ((readBuffer2[15] == 0x00) || /* normal */ + (readBuffer2[15] == 0x08) || /* EMR */ + (readBuffer2[15] == 0x20) || /* BK */ + (readBuffer2[15] == 0x28)) && /* EMR + BK */ + (memcmp(readBuffer2 + 26, owner.c_str(), CALL_SIZE-1) == 0) && /* rpt2 must be us */ + (readBuffer2[33] == 'G')) { + to_remote_g2[i].in_streamid[0] = readBuffer2[12]; + to_remote_g2[i].in_streamid[1] = readBuffer2[13]; - if ((brd_from_xrf.rptr_streamid[0][0] != 0x00) || - (brd_from_xrf.rptr_streamid[0][1] != 0x00)) { - from_xrf_torptr_brd[12] = brd_from_xrf.rptr_streamid[0][0]; - from_xrf_torptr_brd[13] = brd_from_xrf.rptr_streamid[0][1]; - sendto(rptr_sock, from_xrf_torptr_brd, 27, 0, (struct sockaddr *)&toLocalg2, sizeof(struct sockaddr_in)); - } + /* inform XRF about the source */ + readBuffer2[11] = to_remote_g2[i].from_mod; - if ((brd_from_xrf.rptr_streamid[1][0] != 0x00) || - (brd_from_xrf.rptr_streamid[1][1] != 0x00)) { - from_xrf_torptr_brd[12] = brd_from_xrf.rptr_streamid[1][0]; - from_xrf_torptr_brd[13] = brd_from_xrf.rptr_streamid[1][1]; - sendto(rptr_sock, from_xrf_torptr_brd, 27, 0, (struct sockaddr *)&toLocalg2, sizeof(struct sockaddr_in)); + memcpy((char *)readBuffer2 + 18, to_remote_g2[i].to_call, CALL_SIZE); + readBuffer2[25] = to_remote_g2[i].to_mod; + memcpy((char *)readBuffer2 + 26, to_remote_g2[i].to_call, CALL_SIZE); + readBuffer2[33] = 'G'; + calcPFCS(readBuffer2, 56); + + sendto(xrf_g2_sock, readBuffer2, 56, 0, (struct sockaddr *)&(to_remote_g2[i].toDst4), sizeof(struct sockaddr_in)); } + } else if (to_remote_g2[i].toDst4.sin_port == htons(rmt_ref_port)) { + if ( /*** (memcmp(readBuffer2 + 42, owner, 8) != 0) && ***/ /* block repeater announcements */ + (memcmp(readBuffer2 + 34, "CQCQCQ", 6) == 0) && /* CQ calls only */ + ((readBuffer2[15] == 0x00) || /* normal */ + (readBuffer2[15] == 0x08) || /* EMR */ + (readBuffer2[15] == 0x20) || /* BK */ + (readBuffer2[15] == 0x28)) && /* EMR + BK */ + (memcmp(readBuffer2 + 26, owner.c_str(), CALL_SIZE-1) == 0) && /* rpt2 must be us */ + (readBuffer2[33] == 'G')) { + to_remote_g2[i].in_streamid[0] = readBuffer2[12]; + to_remote_g2[i].in_streamid[1] = readBuffer2[13]; + + readBuffer[0] = (unsigned char)(58 & 0xFF); + readBuffer[1] = (unsigned char)(58 >> 8 & 0x1F); + readBuffer[1] = (unsigned char)(readBuffer[1] | 0xFFFFFF80); + + memcpy(readBuffer + 2, readBuffer2, 56); - if ((readBuffer2[14] & 0x40) != 0) { - brd_from_xrf.xrf_streamid[0] = brd_from_xrf.xrf_streamid[1] = 0x00; - brd_from_xrf.rptr_streamid[0][0] = brd_from_xrf.rptr_streamid[0][1] = 0x00; - brd_from_xrf.rptr_streamid[1][0] = brd_from_xrf.rptr_streamid[1][1] = 0x00; - brd_from_xrf_idx = 0; + memset(readBuffer + 20, ' ', CALL_SIZE); + memcpy(readBuffer + 20, to_remote_g2[i].to_call, + strlen(to_remote_g2[i].to_call)); + readBuffer[27] = to_remote_g2[i].to_mod; + memset(readBuffer + 28, ' ', CALL_SIZE); + memcpy(readBuffer + 28, to_remote_g2[i].to_call, + strlen(to_remote_g2[i].to_call)); + readBuffer[35] = 'G'; + memcpy(&readBuffer[36], "CQCQCQ ", 8); + + calcPFCS(readBuffer + 2, 56); + + sendto(ref_g2_sock, readBuffer, 58, 0, (struct sockaddr *)&(to_remote_g2[i].toDst4), sizeof(struct sockaddr_in)); + } + } else if (to_remote_g2[i].toDst4.sin_port == htons(rmt_dcs_port)) { + if ( /*** (memcmp(readBuffer2 + 42, owner, 8) != 0) && ***/ /* block repeater announcements */ + (memcmp(readBuffer2 + 34, "CQCQCQ", 6) == 0) && /* CQ calls only */ + ((readBuffer2[15] == 0x00) || /* normal */ + (readBuffer2[15] == 0x08) || /* EMR */ + (readBuffer2[15] == 0x20) || /* BK */ + (readBuffer2[15] == 0x28)) && /* EMR + BK */ + (memcmp(readBuffer2 + 26, owner.c_str(), CALL_SIZE-1) == 0) && /* rpt2 must be us */ + (readBuffer2[33] == 'G')) { + to_remote_g2[i].in_streamid[0] = readBuffer2[12]; + to_remote_g2[i].in_streamid[1] = readBuffer2[13]; + + memcpy(xrf_2_dcs[i].mycall, readBuffer2 + 42, 8); + memcpy(xrf_2_dcs[i].sfx, readBuffer2 + 50, 4); + xrf_2_dcs[i].dcs_rptr_seq = 0; } } + } + } + } else if (found) { + if ((readBuffer2[14] & 0x40) != 0) { + for (i = 0; i < 3; i++) { + if (memcmp(old_sid[i].sid, readBuffer2 + 12, 2) == 0) { + if (qso_details) + traceit("END from remote g2: streamID=%d,%d, %d bytes from IP=%s\n", + readBuffer2[12],readBuffer2[13],recvlen2,inet_ntoa(fromDst4.sin_addr)); - for (i = 0; i < 3; i++) { - if ((to_remote_g2[i].is_connected) && - (to_remote_g2[i].toDst4.sin_addr.s_addr != fromDst4.sin_addr.s_addr) && - (memcmp(to_remote_g2[i].in_streamid, readBuffer2 + 12, 2) == 0)) { - if (to_remote_g2[i].toDst4.sin_port == htons(rmt_xrf_port)) { - /* inform XRF about the source */ - readBuffer2[11] = to_remote_g2[i].from_mod; - - sendto(xrf_g2_sock, readBuffer2, 27, 0, (struct sockaddr *)&(to_remote_g2[i].toDst4), sizeof(struct sockaddr_in)); - } else if (to_remote_g2[i].toDst4.sin_port == htons(rmt_ref_port)) { - readBuffer[0] = (unsigned char)(29 & 0xFF); - readBuffer[1] = (unsigned char)(29 >> 8 & 0x1F); - readBuffer[1] = (unsigned char)(readBuffer[1] | 0xFFFFFF80); - - memcpy(readBuffer + 2, readBuffer2, 27); - - sendto(ref_g2_sock, readBuffer, 29, 0, (struct sockaddr *)&(to_remote_g2[i].toDst4), sizeof(struct sockaddr_in)); - } else if (to_remote_g2[i].toDst4.sin_port == htons(rmt_dcs_port)) { - memset(dcs_buf, 0x00, 600); - dcs_buf[0] = dcs_buf[1] = dcs_buf[2] = '0'; - dcs_buf[3] = '1'; - dcs_buf[4] = dcs_buf[5] = dcs_buf[6] = 0x00; - memcpy(dcs_buf + 7, to_remote_g2[i].to_call, 8); - dcs_buf[14] = to_remote_g2[i].to_mod; - memcpy(dcs_buf + 15, owner.c_str(), CALL_SIZE); - dcs_buf[22] = to_remote_g2[i].from_mod; - memcpy(dcs_buf + 23, "CQCQCQ ", 8); - memcpy(dcs_buf + 31, xrf_2_dcs[i].mycall, 8); - memcpy(dcs_buf + 39, xrf_2_dcs[i].sfx, 4); - dcs_buf[43] = readBuffer2[12]; /* streamid0 */ - dcs_buf[44] = readBuffer2[13]; /* streamid1 */ - dcs_buf[45] = readBuffer2[14]; /* cycle sequence */ - memcpy(dcs_buf + 46, readBuffer2 + 15, 12); - - dcs_buf[58] = (xrf_2_dcs[i].dcs_rptr_seq >> 0) & 0xff; - dcs_buf[59] = (xrf_2_dcs[i].dcs_rptr_seq >> 8) & 0xff; - dcs_buf[60] = (xrf_2_dcs[i].dcs_rptr_seq >> 16) & 0xff; - - xrf_2_dcs[i].dcs_rptr_seq ++; - - dcs_buf[61] = 0x01; - dcs_buf[62] = 0x00; - - sendto(dcs_g2_sock, dcs_buf, 100, 0, (struct sockaddr *)&(to_remote_g2[i].toDst4), sizeof(to_remote_g2[i].toDst4)); - } + memset(old_sid[i].sid, 0x00, 2); - if ((readBuffer2[14] & 0x40) != 0) { - to_remote_g2[i].in_streamid[0] = 0x00; - to_remote_g2[i].in_streamid[1] = 0x00; - } - break; - } + break; } } } + + /* relay data to our local G2 */ + sendto(rptr_sock, readBuffer2, 27, 0, (struct sockaddr *)&toLocalg2, sizeof(struct sockaddr_in)); + + /* send data to donglers */ + /* no changes here */ + for (pos = inbound_list.begin(); pos != inbound_list.end(); pos++) { + inbound_ptr = (inbound *)pos->second; + if (fromDst4.sin_addr.s_addr != inbound_ptr->sin.sin_addr.s_addr) { + readBuffer[0] = (unsigned char)(29 & 0xFF); + readBuffer[1] = (unsigned char)(29 >> 8 & 0x1F); + readBuffer[1] = (unsigned char)(readBuffer[1] | 0xFFFFFF80); + + memcpy(readBuffer + 2, readBuffer2, 27); + + sendto(ref_g2_sock, readBuffer, 29, 0, (struct sockaddr *)&(inbound_ptr->sin), sizeof(struct sockaddr_in)); + } + } + + /* do we have to broadcast ? */ + if (memcmp(brd_from_xrf.xrf_streamid, readBuffer2 + 12, 2) == 0) { + memcpy(from_xrf_torptr_brd, readBuffer2, 27); + + if ((brd_from_xrf.rptr_streamid[0][0] != 0x00) || + (brd_from_xrf.rptr_streamid[0][1] != 0x00)) { + from_xrf_torptr_brd[12] = brd_from_xrf.rptr_streamid[0][0]; + from_xrf_torptr_brd[13] = brd_from_xrf.rptr_streamid[0][1]; + sendto(rptr_sock, from_xrf_torptr_brd, 27, 0, (struct sockaddr *)&toLocalg2, sizeof(struct sockaddr_in)); + } + + if ((brd_from_xrf.rptr_streamid[1][0] != 0x00) || + (brd_from_xrf.rptr_streamid[1][1] != 0x00)) { + from_xrf_torptr_brd[12] = brd_from_xrf.rptr_streamid[1][0]; + from_xrf_torptr_brd[13] = brd_from_xrf.rptr_streamid[1][1]; + sendto(rptr_sock, from_xrf_torptr_brd, 27, 0, (struct sockaddr *)&toLocalg2, sizeof(struct sockaddr_in)); + } + + if ((readBuffer2[14] & 0x40) != 0) { + brd_from_xrf.xrf_streamid[0] = brd_from_xrf.xrf_streamid[1] = 0x00; + brd_from_xrf.rptr_streamid[0][0] = brd_from_xrf.rptr_streamid[0][1] = 0x00; + brd_from_xrf.rptr_streamid[1][0] = brd_from_xrf.rptr_streamid[1][1] = 0x00; + brd_from_xrf_idx = 0; + } + } + + for (i = 0; i < 3; i++) { + if ((to_remote_g2[i].is_connected) && + (to_remote_g2[i].toDst4.sin_addr.s_addr != fromDst4.sin_addr.s_addr) && + (memcmp(to_remote_g2[i].in_streamid, readBuffer2 + 12, 2) == 0)) { + if (to_remote_g2[i].toDst4.sin_port == htons(rmt_xrf_port)) { + /* inform XRF about the source */ + readBuffer2[11] = to_remote_g2[i].from_mod; + + sendto(xrf_g2_sock, readBuffer2, 27, 0, (struct sockaddr *)&(to_remote_g2[i].toDst4), sizeof(struct sockaddr_in)); + } else if (to_remote_g2[i].toDst4.sin_port == htons(rmt_ref_port)) { + readBuffer[0] = (unsigned char)(29 & 0xFF); + readBuffer[1] = (unsigned char)(29 >> 8 & 0x1F); + readBuffer[1] = (unsigned char)(readBuffer[1] | 0xFFFFFF80); + + memcpy(readBuffer + 2, readBuffer2, 27); + + sendto(ref_g2_sock, readBuffer, 29, 0, (struct sockaddr *)&(to_remote_g2[i].toDst4), sizeof(struct sockaddr_in)); + } else if (to_remote_g2[i].toDst4.sin_port == htons(rmt_dcs_port)) { + memset(dcs_buf, 0x00, 600); + dcs_buf[0] = dcs_buf[1] = dcs_buf[2] = '0'; + dcs_buf[3] = '1'; + dcs_buf[4] = dcs_buf[5] = dcs_buf[6] = 0x00; + memcpy(dcs_buf + 7, to_remote_g2[i].to_call, 8); + dcs_buf[14] = to_remote_g2[i].to_mod; + memcpy(dcs_buf + 15, owner.c_str(), CALL_SIZE); + dcs_buf[22] = to_remote_g2[i].from_mod; + memcpy(dcs_buf + 23, "CQCQCQ ", 8); + memcpy(dcs_buf + 31, xrf_2_dcs[i].mycall, 8); + memcpy(dcs_buf + 39, xrf_2_dcs[i].sfx, 4); + dcs_buf[43] = readBuffer2[12]; /* streamid0 */ + dcs_buf[44] = readBuffer2[13]; /* streamid1 */ + dcs_buf[45] = readBuffer2[14]; /* cycle sequence */ + memcpy(dcs_buf + 46, readBuffer2 + 15, 12); + + dcs_buf[58] = (xrf_2_dcs[i].dcs_rptr_seq >> 0) & 0xff; + dcs_buf[59] = (xrf_2_dcs[i].dcs_rptr_seq >> 8) & 0xff; + dcs_buf[60] = (xrf_2_dcs[i].dcs_rptr_seq >> 16) & 0xff; + + xrf_2_dcs[i].dcs_rptr_seq ++; + + dcs_buf[61] = 0x01; + dcs_buf[62] = 0x00; + + sendto(dcs_g2_sock, dcs_buf, 100, 0, (struct sockaddr *)&(to_remote_g2[i].toDst4), sizeof(to_remote_g2[i].toDst4)); + } + + if ((readBuffer2[14] & 0x40) != 0) { + to_remote_g2[i].in_streamid[0] = 0x00; + to_remote_g2[i].in_streamid[1] = 0x00; + } + break; + } + } + } + } FD_CLR (xrf_g2_sock,&fdset); } @@ -2234,276 +2232,272 @@ static void runit() sendto(ref_g2_sock, readBuffer2, k_idx, 0, (struct sockaddr *)&fromDst4, sizeof(struct sockaddr_in)); } } - } else - /* linked repeaters request */ - if ((recvlen2 == 4) && - (readBuffer2[0] == 4) && - (readBuffer2[1] == 192) && - (readBuffer2[2] == 5) && - (readBuffer2[3] == 0)) { - unsigned short i_idx = 0; - unsigned short j_idx = 0; - unsigned short k_idx = 0; - unsigned char tmp[2]; - unsigned short total = 0; + /* linked repeaters request */ + } else if ((recvlen2 == 4) && + (readBuffer2[0] == 4) && + (readBuffer2[1] == 192) && + (readBuffer2[2] == 5) && + (readBuffer2[3] == 0)) { + unsigned short i_idx = 0; + unsigned short j_idx = 0; + unsigned short k_idx = 0; + unsigned char tmp[2]; + unsigned short total = 0; - pos = inbound_list.find(ip); - if (pos != inbound_list.end()) { - inbound_ptr = (inbound *)pos->second; - // traceit("Remote station %s %s requested linked repeaters list\n", inbound_ptr->call, ip); - - /* header is 8 bytes */ - - /* reply type */ - readBuffer2[2] = 5; - readBuffer2[3] = 1; - - /* we can have up to 3 linked systems */ - total = 3; - memcpy(tmp, (char *)&total, 2); - readBuffer2[6] = tmp[0]; - readBuffer2[7] = tmp[1]; - - for (i = 0, i_idx = 0; i < 3; i++, i_idx++) { - /* each entry has 20 bytes */ - if (to_remote_g2[i].to_mod != ' ') { - if (i == 0) - readBuffer2[8 + (20 * j_idx)] = 'A'; - else if (i == 1) - readBuffer2[8 + (20 * j_idx)] = 'B'; - else if (i == 2) - readBuffer2[8 + (20 * j_idx)] = 'C'; - - strcpy((char *)readBuffer2 + 9 + (20 * j_idx), to_remote_g2[i].to_call); - readBuffer2[16 + (20 * j_idx)] = to_remote_g2[i].to_mod; - - readBuffer2[17 + (20 * j_idx)] = 0; - readBuffer2[18 + (20 * j_idx)] = 0; - readBuffer2[19 + (20 * j_idx)] = 0; - readBuffer2[20 + (20 * j_idx)] = 0x50; - readBuffer2[21 + (20 * j_idx)] = 0x04; - readBuffer2[22 + (20 * j_idx)] = 0x32; - readBuffer2[23 + (20 * j_idx)] = 0x4d; - readBuffer2[24 + (20 * j_idx)] = 0x9f; - readBuffer2[25 + (20 * j_idx)] = 0xdb; - readBuffer2[26 + (20 * j_idx)] = 0x0e; - readBuffer2[27 + (20 * j_idx)] = 0; - - j_idx++; - - if (j_idx == 39) { - /* 20 bytes for each user, so 39 * 20 = 780 bytes + 8 bytes header = 788 */ - readBuffer2[0] = 0x14; - readBuffer2[1] = 0xc3; - - k_idx = i_idx - 38; - memcpy(tmp, (char *)&k_idx, 2); - readBuffer2[4] = tmp[0]; - readBuffer2[5] = tmp[1]; - - sendto(ref_g2_sock, readBuffer2,788,0, (struct sockaddr *)&fromDst4, sizeof(struct sockaddr_in)); - - j_idx = 0; - } + pos = inbound_list.find(ip); + if (pos != inbound_list.end()) { + inbound_ptr = (inbound *)pos->second; + // traceit("Remote station %s %s requested linked repeaters list\n", inbound_ptr->call, ip); + + /* header is 8 bytes */ + + /* reply type */ + readBuffer2[2] = 5; + readBuffer2[3] = 1; + + /* we can have up to 3 linked systems */ + total = 3; + memcpy(tmp, (char *)&total, 2); + readBuffer2[6] = tmp[0]; + readBuffer2[7] = tmp[1]; + + for (i = 0, i_idx = 0; i < 3; i++, i_idx++) { + /* each entry has 20 bytes */ + if (to_remote_g2[i].to_mod != ' ') { + if (i == 0) + readBuffer2[8 + (20 * j_idx)] = 'A'; + else if (i == 1) + readBuffer2[8 + (20 * j_idx)] = 'B'; + else if (i == 2) + readBuffer2[8 + (20 * j_idx)] = 'C'; + + strcpy((char *)readBuffer2 + 9 + (20 * j_idx), to_remote_g2[i].to_call); + readBuffer2[16 + (20 * j_idx)] = to_remote_g2[i].to_mod; + + readBuffer2[17 + (20 * j_idx)] = 0; + readBuffer2[18 + (20 * j_idx)] = 0; + readBuffer2[19 + (20 * j_idx)] = 0; + readBuffer2[20 + (20 * j_idx)] = 0x50; + readBuffer2[21 + (20 * j_idx)] = 0x04; + readBuffer2[22 + (20 * j_idx)] = 0x32; + readBuffer2[23 + (20 * j_idx)] = 0x4d; + readBuffer2[24 + (20 * j_idx)] = 0x9f; + readBuffer2[25 + (20 * j_idx)] = 0xdb; + readBuffer2[26 + (20 * j_idx)] = 0x0e; + readBuffer2[27 + (20 * j_idx)] = 0; + + j_idx++; + + if (j_idx == 39) { + /* 20 bytes for each user, so 39 * 20 = 780 bytes + 8 bytes header = 788 */ + readBuffer2[0] = 0x14; + readBuffer2[1] = 0xc3; + + k_idx = i_idx - 38; + memcpy(tmp, (char *)&k_idx, 2); + readBuffer2[4] = tmp[0]; + readBuffer2[5] = tmp[1]; + + sendto(ref_g2_sock, readBuffer2,788,0, (struct sockaddr *)&fromDst4, sizeof(struct sockaddr_in)); + + j_idx = 0; } } + } - if (j_idx != 0) { - k_idx = 8 + (j_idx * 20); - memcpy(tmp, (char *)&k_idx, 2); - readBuffer2[0] = tmp[0]; - readBuffer2[1] = tmp[1] | 0xc0; + if (j_idx != 0) { + k_idx = 8 + (j_idx * 20); + memcpy(tmp, (char *)&k_idx, 2); + readBuffer2[0] = tmp[0]; + readBuffer2[1] = tmp[1] | 0xc0; - if (i_idx > j_idx) - k_idx = i_idx - j_idx; - else - k_idx = 0; + if (i_idx > j_idx) + k_idx = i_idx - j_idx; + else + k_idx = 0; + + memcpy(tmp, (char *)&k_idx, 2); + readBuffer2[4] = tmp[0]; + readBuffer2[5] = tmp[1]; + + sendto(ref_g2_sock, readBuffer2, 8+(j_idx*20), 0, (struct sockaddr *)&fromDst4, sizeof(struct sockaddr_in)); + } + } + /* connected user list request */ + } else if ((recvlen2 == 4) && + (readBuffer2[0] == 4) && + (readBuffer2[1] == 192) && + (readBuffer2[2] == 6) && + (readBuffer2[3] == 0)) { + unsigned short i_idx = 0; + unsigned short j_idx = 0; + unsigned short k_idx = 0; + unsigned char tmp[2]; + unsigned short total = 0; + + pos = inbound_list.find(ip); + if (pos != inbound_list.end()) { + inbound_ptr = (inbound *)pos->second; + // traceit("Remote station %s %s requested connected user list\n", inbound_ptr->call, ip); + + /* header is 8 bytes */ + + /* reply type */ + readBuffer2[2] = 6; + readBuffer2[3] = 0; + + /* total connected users */ + total = inbound_list.size(); + memcpy(tmp, (char *)&total, 2); + readBuffer2[6] = tmp[0]; + readBuffer2[7] = tmp[1]; + + for (pos = inbound_list.begin(), i_idx = 0; pos != inbound_list.end(); pos++, i_idx++) { + /* each entry has 20 bytes */ + readBuffer2[8 + (20 * j_idx)] = ' '; + inbound_ptr = (inbound *)pos->second; + + readBuffer2[8 + (20 * j_idx)] = inbound_ptr->mod; + strcpy((char *)readBuffer2 + 9 + (20 * j_idx), inbound_ptr->call); + + readBuffer2[17 + (20 * j_idx)] = 0; + /* readBuffer2[18 + (20 * j_idx)] = 0; */ + readBuffer2[18 + (20 * j_idx)] = inbound_ptr->client; + readBuffer2[19 + (20 * j_idx)] = 0; + readBuffer2[20 + (20 * j_idx)] = 0x0d; + readBuffer2[21 + (20 * j_idx)] = 0x4d; + readBuffer2[22 + (20 * j_idx)] = 0x37; + readBuffer2[23 + (20 * j_idx)] = 0x4d; + readBuffer2[24 + (20 * j_idx)] = 0x6f; + readBuffer2[25 + (20 * j_idx)] = 0x98; + readBuffer2[26 + (20 * j_idx)] = 0x04; + readBuffer2[27 + (20 * j_idx)] = 0; + + j_idx++; + if (j_idx == 39) { + /* 20 bytes for each user, so 39 * 20 = 788 bytes + 8 bytes header = 788 */ + readBuffer2[0] = 0x14; + readBuffer2[1] = 0xc3; + + k_idx = i_idx - 38; memcpy(tmp, (char *)&k_idx, 2); readBuffer2[4] = tmp[0]; readBuffer2[5] = tmp[1]; - sendto(ref_g2_sock, readBuffer2, 8+(j_idx*20), 0, (struct sockaddr *)&fromDst4, sizeof(struct sockaddr_in)); + sendto(ref_g2_sock, readBuffer2, 788, 0, (struct sockaddr *)&fromDst4, sizeof(struct sockaddr_in)); + + j_idx = 0; } } - } else - /* connected user list request */ - if ((recvlen2 == 4) && - (readBuffer2[0] == 4) && - (readBuffer2[1] == 192) && - (readBuffer2[2] == 6) && - (readBuffer2[3] == 0)) { - unsigned short i_idx = 0; - unsigned short j_idx = 0; - unsigned short k_idx = 0; - unsigned char tmp[2]; - unsigned short total = 0; - pos = inbound_list.find(ip); - if (pos != inbound_list.end()) { - inbound_ptr = (inbound *)pos->second; - // traceit("Remote station %s %s requested connected user list\n", inbound_ptr->call, ip); + if (j_idx != 0) { + k_idx = 8 + (j_idx * 20); + memcpy(tmp, (char *)&k_idx, 2); + readBuffer2[0] = tmp[0]; + readBuffer2[1] = tmp[1] | 0xc0; - /* header is 8 bytes */ + if (i_idx > j_idx) + k_idx = i_idx - j_idx; + else + k_idx = 0; - /* reply type */ - readBuffer2[2] = 6; - readBuffer2[3] = 0; + memcpy(tmp, (char *)&k_idx, 2); + readBuffer2[4] = tmp[0]; + readBuffer2[5] = tmp[1]; - /* total connected users */ - total = inbound_list.size(); - memcpy(tmp, (char *)&total, 2); - readBuffer2[6] = tmp[0]; - readBuffer2[7] = tmp[1]; + sendto(ref_g2_sock, readBuffer2, 8+(j_idx*20), 0, (struct sockaddr *)&fromDst4, sizeof(struct sockaddr_in)); + } + } + /* date request */ + } else if ((recvlen2 == 4) && + (readBuffer2[0] == 4) && + (readBuffer2[1] == 192) && + (readBuffer2[2] == 8) && + (readBuffer2[3] == 0)) { + time_t ltime; + struct tm tm; - for (pos = inbound_list.begin(), i_idx = 0; pos != inbound_list.end(); pos++, i_idx++) { - /* each entry has 20 bytes */ - readBuffer2[8 + (20 * j_idx)] = ' '; - inbound_ptr = (inbound *)pos->second; + pos = inbound_list.find(ip); + if (pos != inbound_list.end()) { + inbound_ptr = (inbound *)pos->second; + // traceit("Remote station %s %s requested date\n", inbound_ptr->call, ip); - readBuffer2[8 + (20 * j_idx)] = inbound_ptr->mod; - strcpy((char *)readBuffer2 + 9 + (20 * j_idx), inbound_ptr->call); - - readBuffer2[17 + (20 * j_idx)] = 0; - /* readBuffer2[18 + (20 * j_idx)] = 0; */ - readBuffer2[18 + (20 * j_idx)] = inbound_ptr->client; - readBuffer2[19 + (20 * j_idx)] = 0; - readBuffer2[20 + (20 * j_idx)] = 0x0d; - readBuffer2[21 + (20 * j_idx)] = 0x4d; - readBuffer2[22 + (20 * j_idx)] = 0x37; - readBuffer2[23 + (20 * j_idx)] = 0x4d; - readBuffer2[24 + (20 * j_idx)] = 0x6f; - readBuffer2[25 + (20 * j_idx)] = 0x98; - readBuffer2[26 + (20 * j_idx)] = 0x04; - readBuffer2[27 + (20 * j_idx)] = 0; - - j_idx++; - - if (j_idx == 39) { - /* 20 bytes for each user, so 39 * 20 = 788 bytes + 8 bytes header = 788 */ - readBuffer2[0] = 0x14; - readBuffer2[1] = 0xc3; - - k_idx = i_idx - 38; - memcpy(tmp, (char *)&k_idx, 2); - readBuffer2[4] = tmp[0]; - readBuffer2[5] = tmp[1]; - - sendto(ref_g2_sock, readBuffer2, 788, 0, (struct sockaddr *)&fromDst4, sizeof(struct sockaddr_in)); - - j_idx = 0; - } - } + time(<ime); + localtime_r(<ime,&tm); - if (j_idx != 0) { - k_idx = 8 + (j_idx * 20); - memcpy(tmp, (char *)&k_idx, 2); - readBuffer2[0] = tmp[0]; - readBuffer2[1] = tmp[1] | 0xc0; + readBuffer2[0] = 34; + readBuffer2[1] = 192; + readBuffer2[2] = 8; + readBuffer2[3] = 0; + readBuffer2[4] = 0xb5; + readBuffer2[5] = 0xae; + readBuffer2[6] = 0x37; + readBuffer2[7] = 0x4d; + snprintf((char *)readBuffer2 + 8, 1024 - 1, + "20%02d/%02d/%02d %02d:%02d:%02d %5.5s", + tm.tm_year % 100, tm.tm_mon+1,tm.tm_mday, + tm.tm_hour,tm.tm_min,tm.tm_sec, + (tzname[0] == NULL)?" ":tzname[0]); + + sendto(ref_g2_sock, readBuffer2, 34, 0, (struct sockaddr *)&fromDst4, sizeof(struct sockaddr_in)); + } + /* version request */ + } else if ((recvlen2 == 4) && + (readBuffer2[0] == 4) && + (readBuffer2[1] == 192) && + (readBuffer2[2] == 3) && + (readBuffer2[3] == 0)) { + pos = inbound_list.find(ip); + if (pos != inbound_list.end()) { + inbound_ptr = (inbound *)pos->second; + // traceit("Remote station %s %s requested version\n", inbound_ptr->call, ip); - if (i_idx > j_idx) - k_idx = i_idx - j_idx; - else - k_idx = 0; + readBuffer2[0] = 9; + readBuffer2[1] = 192; + readBuffer2[2] = 3; + readBuffer2[3] = 0; + strncpy((char *)readBuffer2 + 4, VERSION, 4); + readBuffer2[8] = 0; - memcpy(tmp, (char *)&k_idx, 2); - readBuffer2[4] = tmp[0]; - readBuffer2[5] = tmp[1]; + sendto(ref_g2_sock, readBuffer2, 9, 0, (struct sockaddr *)&fromDst4, sizeof(struct sockaddr_in)); + } + } else if ((recvlen2 == 5) && + (readBuffer2[0] == 5) && + (readBuffer2[1] == 0) && + (readBuffer2[2] == 24) && + (readBuffer2[3] == 0) && + (readBuffer2[4] == 0)) { + /* reply with the same DISCONNECT */ + sendto(ref_g2_sock, readBuffer2, 5, 0, (struct sockaddr *)&fromDst4, sizeof(struct sockaddr_in)); - sendto(ref_g2_sock, readBuffer2, 8+(j_idx*20), 0, (struct sockaddr *)&fromDst4, sizeof(struct sockaddr_in)); - } - } - } else - /* date request */ - if ((recvlen2 == 4) && - (readBuffer2[0] == 4) && - (readBuffer2[1] == 192) && - (readBuffer2[2] == 8) && - (readBuffer2[3] == 0)) { - time_t ltime; - struct tm tm; - - pos = inbound_list.find(ip); - if (pos != inbound_list.end()) { - inbound_ptr = (inbound *)pos->second; - // traceit("Remote station %s %s requested date\n", inbound_ptr->call, ip); - - time(<ime); - localtime_r(<ime,&tm); - - readBuffer2[0] = 34; - readBuffer2[1] = 192; - readBuffer2[2] = 8; - readBuffer2[3] = 0; - readBuffer2[4] = 0xb5; - readBuffer2[5] = 0xae; - readBuffer2[6] = 0x37; - readBuffer2[7] = 0x4d; - snprintf((char *)readBuffer2 + 8, 1024 - 1, - "20%02d/%02d/%02d %02d:%02d:%02d %5.5s", - tm.tm_year % 100, tm.tm_mon+1,tm.tm_mday, - tm.tm_hour,tm.tm_min,tm.tm_sec, - (tzname[0] == NULL)?" ":tzname[0]); - - sendto(ref_g2_sock, readBuffer2, 34, 0, (struct sockaddr *)&fromDst4, sizeof(struct sockaddr_in)); - } - } else - /* version request */ - if ((recvlen2 == 4) && - (readBuffer2[0] == 4) && - (readBuffer2[1] == 192) && - (readBuffer2[2] == 3) && - (readBuffer2[3] == 0)) { - pos = inbound_list.find(ip); - if (pos != inbound_list.end()) { - inbound_ptr = (inbound *)pos->second; - // traceit("Remote station %s %s requested version\n", inbound_ptr->call, ip); - - readBuffer2[0] = 9; - readBuffer2[1] = 192; - readBuffer2[2] = 3; - readBuffer2[3] = 0; - strncpy((char *)readBuffer2 + 4, VERSION, 4); - readBuffer2[8] = 0; - - sendto(ref_g2_sock, readBuffer2, 9, 0, (struct sockaddr *)&fromDst4, sizeof(struct sockaddr_in)); - } - } else if ((recvlen2 == 5) && - (readBuffer2[0] == 5) && - (readBuffer2[1] == 0) && - (readBuffer2[2] == 24) && - (readBuffer2[3] == 0) && - (readBuffer2[4] == 0)) { - /* reply with the same DISCONNECT */ - sendto(ref_g2_sock, readBuffer2, 5, 0, (struct sockaddr *)&fromDst4, sizeof(struct sockaddr_in)); - - for (i = 0; i < 3; i++) { - if ((fromDst4.sin_addr.s_addr == to_remote_g2[i].toDst4.sin_addr.s_addr) && - (to_remote_g2[i].toDst4.sin_port == htons(rmt_ref_port))) { - traceit("Call %s disconnected\n", to_remote_g2[i].to_call); - - to_remote_g2[i].to_call[0] = '\0'; - memset(&(to_remote_g2[i].toDst4),0,sizeof(struct sockaddr_in)); - to_remote_g2[i].from_mod = ' '; - to_remote_g2[i].to_mod = ' '; - to_remote_g2[i].countdown = 0; - to_remote_g2[i].is_connected = false; - to_remote_g2[i].in_streamid[0] = 0x00; - to_remote_g2[i].in_streamid[1] = 0x00; - } - } + for (i = 0; i < 3; i++) { + if ((fromDst4.sin_addr.s_addr == to_remote_g2[i].toDst4.sin_addr.s_addr) && + (to_remote_g2[i].toDst4.sin_port == htons(rmt_ref_port))) { + traceit("Call %s disconnected\n", to_remote_g2[i].to_call); - pos = inbound_list.find(ip); - if (pos != inbound_list.end()) { - inbound_ptr = (inbound *)pos->second; - if (memcmp(inbound_ptr->call, "1NFO", 4) != 0) - traceit("Call %s disconnected\n", inbound_ptr->call); - free(pos->second); - pos->second = NULL; - inbound_list.erase(pos); - } - print_status_file(); - } + to_remote_g2[i].to_call[0] = '\0'; + memset(&(to_remote_g2[i].toDst4),0,sizeof(struct sockaddr_in)); + to_remote_g2[i].from_mod = ' '; + to_remote_g2[i].to_mod = ' '; + to_remote_g2[i].countdown = 0; + to_remote_g2[i].is_connected = false; + to_remote_g2[i].in_streamid[0] = 0x00; + to_remote_g2[i].in_streamid[1] = 0x00; + } + } + + pos = inbound_list.find(ip); + if (pos != inbound_list.end()) { + inbound_ptr = (inbound *)pos->second; + if (memcmp(inbound_ptr->call, "1NFO", 4) != 0) + traceit("Call %s disconnected\n", inbound_ptr->call); + free(pos->second); + pos->second = NULL; + inbound_list.erase(pos); + } + print_status_file(); + } for (i = 0; i < 3; i++) { if ((fromDst4.sin_addr.s_addr == to_remote_g2[i].toDst4.sin_addr.s_addr) && @@ -3182,30 +3176,67 @@ static void runit() ; else if (recvlen2 == 35) ; - else - /* is this a keepalive 22 bytes */ - if (recvlen2 == 22) { - i = -1; - if (dcs_buf[17] == 'A') - i = 0; - else if (dcs_buf[17] == 'B') - i = 1; - else if (dcs_buf[17] == 'C') - i = 2; + /* is this a keepalive 22 bytes */ + else if (recvlen2 == 22) { + i = -1; + if (dcs_buf[17] == 'A') + i = 0; + else if (dcs_buf[17] == 'B') + i = 1; + else if (dcs_buf[17] == 'C') + i = 2; + + /* It is one of our valid repeaters */ + // DG1HT from owner 8 to 7 + if ((i >= 0) && (memcmp(dcs_buf + 9, owner.c_str(), CALL_SIZE-1) == 0)) { + /* is that the remote system that we asked to connect to? */ + if ((fromDst4.sin_addr.s_addr == to_remote_g2[i].toDst4.sin_addr.s_addr) && + (to_remote_g2[i].toDst4.sin_port == htons(rmt_dcs_port)) && + (memcmp(to_remote_g2[i].to_call, dcs_buf, 7) == 0) && + (to_remote_g2[i].to_mod == dcs_buf[7])) { + if (!to_remote_g2[i].is_connected) { + tracing[i].last_time = time(NULL); - /* It is one of our valid repeaters */ - // DG1HT from owner 8 to 7 - if ((i >= 0) && (memcmp(dcs_buf + 9, owner.c_str(), CALL_SIZE-1) == 0)) { - /* is that the remote system that we asked to connect to? */ - if ((fromDst4.sin_addr.s_addr == to_remote_g2[i].toDst4.sin_addr.s_addr) && - (to_remote_g2[i].toDst4.sin_port == htons(rmt_dcs_port)) && - (memcmp(to_remote_g2[i].to_call, dcs_buf, 7) == 0) && - (to_remote_g2[i].to_mod == dcs_buf[7])) { + to_remote_g2[i].is_connected = true; + traceit("Connected from: %.*s\n", 8, dcs_buf); + print_status_file(); + + strcpy(linked_remote_system, to_remote_g2[i].to_call); + space_p = strchr(linked_remote_system, ' '); + if (space_p) + *space_p = '\0'; + sprintf(notify_msg, "%c_linked.dat_LINKED_%s_%c", + to_remote_g2[i].from_mod, + linked_remote_system, + to_remote_g2[i].to_mod); + audio_notify(notify_msg); + } + to_remote_g2[i].countdown = TIMEOUT; + } + } + } else if (recvlen2 == 14) { /* is this a reply to our link/unlink request: 14 bytes */ + i = -1; + if (dcs_buf[8] == 'A') + i = 0; + else if (dcs_buf[8] == 'B') + i = 1; + else if (dcs_buf[8] == 'C') + i = 2; + + /* It is one of our valid repeaters */ + if ((i >= 0) && (memcmp(dcs_buf, owner.c_str(), CALL_SIZE) == 0)) { + /* It is from a remote that we contacted */ + if ((fromDst4.sin_addr.s_addr == to_remote_g2[i].toDst4.sin_addr.s_addr) && + (to_remote_g2[i].toDst4.sin_port == htons(rmt_dcs_port)) && + (to_remote_g2[i].from_mod == dcs_buf[8])) { + if ((to_remote_g2[i].to_mod == dcs_buf[9]) && + (memcmp(dcs_buf + 10, "ACK", 3) == 0)) { + to_remote_g2[i].countdown = TIMEOUT; if (!to_remote_g2[i].is_connected) { tracing[i].last_time = time(NULL); to_remote_g2[i].is_connected = true; - traceit("Connected from: %.*s\n", 8, dcs_buf); + traceit("Connected from: %.*s\n", 8, to_remote_g2[i].to_call); print_status_file(); strcpy(linked_remote_system, to_remote_g2[i].to_call); @@ -3213,74 +3244,34 @@ static void runit() if (space_p) *space_p = '\0'; sprintf(notify_msg, "%c_linked.dat_LINKED_%s_%c", - to_remote_g2[i].from_mod, - linked_remote_system, - to_remote_g2[i].to_mod); + to_remote_g2[i].from_mod, + linked_remote_system, + to_remote_g2[i].to_mod); audio_notify(notify_msg); } - to_remote_g2[i].countdown = TIMEOUT; - } - } - } - /* is this a reply to our link/unlink request: 14 bytes */ - else if (recvlen2 == 14) { - i = -1; - if (dcs_buf[8] == 'A') - i = 0; - else if (dcs_buf[8] == 'B') - i = 1; - else if (dcs_buf[8] == 'C') - i = 2; - - /* It is one of our valid repeaters */ - if ((i >= 0) && (memcmp(dcs_buf, owner.c_str(), CALL_SIZE) == 0)) { - /* It is from a remote that we contacted */ - if ((fromDst4.sin_addr.s_addr == to_remote_g2[i].toDst4.sin_addr.s_addr) && - (to_remote_g2[i].toDst4.sin_port == htons(rmt_dcs_port)) && - (to_remote_g2[i].from_mod == dcs_buf[8])) { - if ((to_remote_g2[i].to_mod == dcs_buf[9]) && - (memcmp(dcs_buf + 10, "ACK", 3) == 0)) { - to_remote_g2[i].countdown = TIMEOUT; - if (!to_remote_g2[i].is_connected) { - tracing[i].last_time = time(NULL); - - to_remote_g2[i].is_connected = true; - traceit("Connected from: %.*s\n", 8, to_remote_g2[i].to_call); - print_status_file(); - - strcpy(linked_remote_system, to_remote_g2[i].to_call); - space_p = strchr(linked_remote_system, ' '); - if (space_p) - *space_p = '\0'; - sprintf(notify_msg, "%c_linked.dat_LINKED_%s_%c", - to_remote_g2[i].from_mod, - linked_remote_system, - to_remote_g2[i].to_mod); - audio_notify(notify_msg); - } - } else if (memcmp(dcs_buf + 10, "NAK", 3) == 0) { - traceit("Link module %c to [%s] %c is unlinked\n", - to_remote_g2[i].from_mod, to_remote_g2[i].to_call, - to_remote_g2[i].to_mod); + } else if (memcmp(dcs_buf + 10, "NAK", 3) == 0) { + traceit("Link module %c to [%s] %c is unlinked\n", + to_remote_g2[i].from_mod, to_remote_g2[i].to_call, + to_remote_g2[i].to_mod); - sprintf(notify_msg, "%c_failed_linked.dat_UNLINKED", - to_remote_g2[i].from_mod); - audio_notify(notify_msg); + sprintf(notify_msg, "%c_failed_linked.dat_UNLINKED", + to_remote_g2[i].from_mod); + audio_notify(notify_msg); - to_remote_g2[i].to_call[0] = '\0'; - memset(&(to_remote_g2[i].toDst4),0,sizeof(struct sockaddr_in)); - to_remote_g2[i].from_mod = ' '; - to_remote_g2[i].to_mod = ' '; - to_remote_g2[i].countdown = 0; - to_remote_g2[i].is_connected = false; - to_remote_g2[i].in_streamid[0] = 0x00; - to_remote_g2[i].in_streamid[1] = 0x00; + to_remote_g2[i].to_call[0] = '\0'; + memset(&(to_remote_g2[i].toDst4),0,sizeof(struct sockaddr_in)); + to_remote_g2[i].from_mod = ' '; + to_remote_g2[i].to_mod = ' '; + to_remote_g2[i].countdown = 0; + to_remote_g2[i].is_connected = false; + to_remote_g2[i].in_streamid[0] = 0x00; + to_remote_g2[i].in_streamid[1] = 0x00; - print_status_file(); - } + print_status_file(); } } } + } FD_CLR (dcs_g2_sock,&fdset); } diff --git a/g2_typedefs.h b/g2_typedefs.h index d3d9c54..3608214 100644 --- a/g2_typedefs.h +++ b/g2_typedefs.h @@ -21,10 +21,10 @@ #pragma pack(push, 1) // we need to be sure these structures don't have any dead space typedef struct pkt_tag { - unsigned char pkt_id[4]; // 0 - unsigned short counter; // 4 - unsigned char flag[2]; // 6 - unsigned char nothing2[2]; // 8 + unsigned char pkt_id[4]; // 0 + unsigned short counter; // 4 + unsigned char flag[2]; // 6 + unsigned char nothing2[2]; // 8 nothing[1] is the number of bytes left in the packet union { struct { unsigned char mycall[8]; // 10 @@ -47,10 +47,17 @@ typedef struct pkt_tag { unsigned char sfx[4]; // 52 unsigned char pfcs[2]; // 56 } hdr; // total 58 - struct { - unsigned char voice[9]; // 17 - unsigned char text[3]; // 26 - } vasd; // total 29 + union { + struct { + unsigned char voice[9]; // 17 + unsigned char text[3]; // 26 + } vasd; // total 29 + struct { + unsigned char UNKNOWN[3]; // 17 not sure what this is, but g2_ doesn't seem to need it + unsigned char voice[9]; // 20 + unsigned char text[3]; // 29 + } vasd1; // total 32 + }; }; } vpkt; }; @@ -75,11 +82,11 @@ typedef struct dsvt_tag { unsigned char mycall[8];// 42 unsigned char sfx[4]; // 50 unsigned char pfcs[2]; // 54 - } hdr; + } hdr; // total 56 struct { unsigned char voice[9]; // 15 unsigned char text[3]; // 24 - } vasd; + } vasd; // total 27 }; } SDSVT; #pragma pack(pop)