diff --git a/QnetGateway.cpp b/QnetGateway.cpp index 24908de..ce70537 100644 --- a/QnetGateway.cpp +++ b/QnetGateway.cpp @@ -56,8 +56,6 @@ extern int dstar_dv_decode(const unsigned char *d, int data[3]); static std::atomic keep_running(true); - - /* signal catching function */ static void sigCatch(int signum) { @@ -68,6 +66,21 @@ static void sigCatch(int signum) return; } +int CQnetGateway::FindIndex(const int i) const +{ + if (i<0 || i > 2) + return -1; + int index = Index[i]; + if (index < 0) { + if (AF_INET == link_family[i]) { + index = ii[1] ? 1 : 0; + } else if (AF_INET6 == link_family[i]) { + index = 0; + } + } + return index; +} + bool CQnetGateway::VoicePacketIsSync(const unsigned char *text) { return *text==0x55U && *(text+1)==0x2DU && *(text+2)==0x16U; @@ -920,11 +933,10 @@ void CQnetGateway::ProcessSlowData(unsigned char *data, unsigned short sid) if (memcmp(band_txt[i].dest_rptr, "REF", 3) == 0) band_txt[i].dest_rptr[0] = '\0'; } - // we have the 20-character message, send it to the server... - for (int x=0; x<2; x++) { - if (ii[x]) - ii[x]->sendHeardWithTXMsg(band_txt[i].lh_mycall, band_txt[i].lh_sfx, (strstr(band_txt[i].lh_yrcall,"REF") == NULL)?band_txt[i].lh_yrcall:"CQCQCQ ", band_txt[i].lh_rpt1, band_txt[i].lh_rpt2, band_txt[i].flags[0], band_txt[i].flags[1], band_txt[i].flags[2], band_txt[i].dest_rptr, band_txt[i].txt); - } + + int x = FindIndex(i); + if (x >= 0) + ii[x]->sendHeardWithTXMsg(band_txt[i].lh_mycall, band_txt[i].lh_sfx, (strstr(band_txt[i].lh_yrcall,"REF") == NULL)?band_txt[i].lh_yrcall:"CQCQCQ ", band_txt[i].lh_rpt1, band_txt[i].lh_rpt2, band_txt[i].flags[0], band_txt[i].flags[1], band_txt[i].flags[2], band_txt[i].dest_rptr, band_txt[i].txt); band_txt[i].sent_key_on_msg = true; } if (to_print[i] == 3) { @@ -957,8 +969,9 @@ void CQnetGateway::ProcessSlowData(unsigned char *data, unsigned short sid) band_txt[i].dest_rptr[0] = '\0'; } // we have the 20-character message, send it to the server... - if (Index[i] >= 0) - ii[Index[i]]->sendHeardWithTXMsg(band_txt[i].lh_mycall, band_txt[i].lh_sfx, (strstr(band_txt[i].lh_yrcall,"REF") == NULL)?band_txt[i].lh_yrcall:"CQCQCQ ", band_txt[i].lh_rpt1, band_txt[i].lh_rpt2, band_txt[i].flags[0], band_txt[i].flags[1], band_txt[i].flags[2], band_txt[i].dest_rptr, band_txt[i].txt); + int x = FindIndex(i); + if (x >= 0) + ii[x]->sendHeardWithTXMsg(band_txt[i].lh_mycall, band_txt[i].lh_sfx, (strstr(band_txt[i].lh_yrcall,"REF") == NULL)?band_txt[i].lh_yrcall:"CQCQCQ ", band_txt[i].lh_rpt1, band_txt[i].lh_rpt2, band_txt[i].flags[0], band_txt[i].flags[1], band_txt[i].flags[2], band_txt[i].dest_rptr, band_txt[i].txt); band_txt[i].sent_key_on_msg = true; } band_txt[i].txt_cnt = 0; @@ -1713,14 +1726,22 @@ void CQnetGateway::ProcessModem() if (memcmp(band_txt[i].dest_rptr, "REF", 3) == 0) band_txt[i].dest_rptr[0] = '\0'; } - // we have the 20-character message, send it to the server... - if (Index[i] >= 0) - ii[Index[i]]->sendHeardWithTXMsg(band_txt[i].lh_mycall, band_txt[i].lh_sfx, (strstr(band_txt[i].lh_yrcall,"REF") == NULL)?band_txt[i].lh_yrcall:"CQCQCQ ", band_txt[i].lh_rpt1, band_txt[i].lh_rpt2, band_txt[i].flags[0], band_txt[i].flags[1], band_txt[i].flags[2], band_txt[i].dest_rptr, band_txt[i].txt); + int x = FindIndex(i); + if (x >= 0) + ii[x]->sendHeardWithTXMsg(band_txt[i].lh_mycall, band_txt[i].lh_sfx, (strstr(band_txt[i].lh_yrcall,"REF") == NULL)?band_txt[i].lh_yrcall:"CQCQCQ ", band_txt[i].lh_rpt1, band_txt[i].lh_rpt2, band_txt[i].flags[0], band_txt[i].flags[1], band_txt[i].flags[2], band_txt[i].dest_rptr, band_txt[i].txt); band_txt[i].sent_key_on_msg = true; } // send the "key off" message, this will end up in the openquad.net Last Heard webpage. - if (Index[i] >= 0) - ii[Index[i]]->sendHeardWithTXStats(band_txt[i].lh_mycall, band_txt[i].lh_sfx, band_txt[i].lh_yrcall, band_txt[i].lh_rpt1, band_txt[i].lh_rpt2, band_txt[i].flags[0], band_txt[i].flags[1], band_txt[i].flags[2], band_txt[i].num_dv_frames, band_txt[i].num_dv_silent_frames, band_txt[i].num_bit_errors); + int index = Index[i]; + if (index < 0) { + if (AF_INET == link_family[i]) { + index = ii[1] ? 1 : 0; + } else if (AF_INET6 == link_family[i]) { + index = 0; + } + } + if (index >= 0) + ii[index]->sendHeardWithTXStats(band_txt[i].lh_mycall, band_txt[i].lh_sfx, band_txt[i].lh_yrcall, band_txt[i].lh_rpt1, band_txt[i].lh_rpt2, band_txt[i].flags[0], band_txt[i].flags[1], band_txt[i].flags[2], band_txt[i].num_dv_frames, band_txt[i].num_dv_silent_frames, band_txt[i].num_bit_errors); if (playNotInCache) { // Not in cache, please try again! @@ -1956,7 +1977,18 @@ void CQnetGateway::Process() if (keep_running && FD_ISSET(Link2Gate.GetFD(), &fdset)) { SDSVT dsvt; ssize_t g2buflen = Link2Gate.Read(dsvt.title, 56); - ProcessG2(g2buflen, dsvt, -1); + if (16==g2buflen && 0==memcmp(dsvt.title, "LINK", 4)) { + SLINKFAMILY fam; + memcpy(fam.title, dsvt.title, 16); + printf("Families of linked nodes: A=AF_%s, B=AF_%s, C=AF_%s\n", + (AF_UNSPEC==fam.family[0]) ? "UNSPEC" : ((AF_INET==fam.family[0]) ? "INET" : "INET6"), + (AF_UNSPEC==fam.family[1]) ? "UNSPEC" : ((AF_INET==fam.family[1]) ? "INET" : "INET6"), + (AF_UNSPEC==fam.family[2]) ? "UNSPEC" : ((AF_INET==fam.family[2]) ? "INET" : "INET6") + ); + memcpy(link_family, fam.family, 12); + } else { + ProcessG2(g2buflen, dsvt, -1); + } FD_CLR(Link2Gate.GetFD(), &fdset); } diff --git a/QnetGateway.h b/QnetGateway.h index 7fb646a..4c52862 100644 --- a/QnetGateway.h +++ b/QnetGateway.h @@ -82,6 +82,8 @@ public: bool Init(char *cfgfile); private: + // link type + int link_family[3] = { AF_UNSPEC, AF_UNSPEC, AF_UNSPEC }; // network type int af_family[2] = { AF_UNSPEC, AF_UNSPEC }; // text stuff @@ -176,6 +178,7 @@ private: bool Flag_is_ok(unsigned char flag); void UnpackCallsigns(const std::string &str, std::set &set, const std::string &delimiters = ","); void PrintCallsigns(const std::string &key, const std::set &set); + int FindIndex(const int i) const; // read configuration file bool ReadConfig(char *); diff --git a/QnetLink.cpp b/QnetLink.cpp index 3129a46..08ad776 100644 --- a/QnetLink.cpp +++ b/QnetLink.cpp @@ -316,11 +316,18 @@ void CQnetLink::print_status_file() } /* print linked repeaters-reflectors */ + SLINKFAMILY fam; + memcpy(fam.title, "LINK", 4); for (int i=0; i<3;i++) { if (to_remote_g2[i].is_connected) { fprintf(statusfp, fstr, to_remote_g2[i].from_mod, to_remote_g2[i].to_call, to_remote_g2[i].to_mod, to_remote_g2[i].addr.GetAddress(), tm1.tm_mon+1, tm1.tm_mday ,tm1.tm_year % 100, tm1.tm_hour, tm1.tm_min, tm1.tm_sec); - } - } + // also inform gateway + fam.family[i] = to_remote_g2[i].addr.GetFamily(); + } else { + fam.family[i] = AF_UNSPEC; + } + } + Link2Gate.Write(fam.title, sizeof(SLINKFAMILY)); fclose(statusfp); } } diff --git a/QnetTypeDefs.h b/QnetTypeDefs.h index 0e2cd79..02a0bbc 100644 --- a/QnetTypeDefs.h +++ b/QnetTypeDefs.h @@ -123,3 +123,10 @@ typedef struct dsrp_tag { // offset size }; } SDSRP; #pragma pack(pop) + +#pragma pack(push, 1) +typedef struct link_family_tag { + char title[4]; + int family[3]; +} SLINKFAMILY; +#pragma pack(pop)