From 4be0cb5fa48cd81b8bc84144048db81c50b095b9 Mon Sep 17 00:00:00 2001 From: LX3JL Date: Wed, 17 Aug 2016 08:29:15 +0200 Subject: [PATCH] version 1.3.8 --- src/ccallsignlistitem.cpp | 15 +++++++ src/ccallsignlistitem.h | 10 +++++ src/cdcsprotocol.cpp | 10 ++--- src/cdplusprotocol.cpp | 95 +++++++++++++++++++++++++++++++-------- src/cdplusprotocol.h | 9 +++- src/cpeercallsignlist.cpp | 6 +-- src/cxlxprotocol.cpp | 2 + src/main.h | 2 +- src/makefile | 3 +- 9 files changed, 121 insertions(+), 31 deletions(-) diff --git a/src/ccallsignlistitem.cpp b/src/ccallsignlistitem.cpp index 6e2817b..34e4129 100644 --- a/src/ccallsignlistitem.cpp +++ b/src/ccallsignlistitem.cpp @@ -32,11 +32,13 @@ CCallsignListItem::CCallsignListItem() { ::memset(m_Modules, 0, sizeof(m_Modules)); + ::memset(m_szUrl, 0, sizeof(m_szUrl)); } CCallsignListItem::CCallsignListItem(const CCallsign &callsign, const CIp &ip, const char *modules) { m_Callsign = callsign; + ::memset(m_szUrl, 0, sizeof(m_szUrl)); m_Ip = ip; if ( modules != NULL ) { @@ -45,9 +47,22 @@ CCallsignListItem::CCallsignListItem(const CCallsign &callsign, const CIp &ip, c } } +CCallsignListItem::CCallsignListItem(const CCallsign &callsign, const char *url, const char *modules) +{ + m_Callsign = callsign; + ::strncpy(m_szUrl, url, URL_MAXLEN); + m_Ip = CIp(m_szUrl); + if ( modules != NULL ) + { + :: memset(m_Modules, 0, sizeof(m_Modules)); + ::memcpy(m_Modules, modules, MIN(strlen(modules), sizeof(m_Modules)-1)); + } +} + CCallsignListItem::CCallsignListItem(const CCallsignListItem &item) { m_Callsign = item.m_Callsign; + ::memcpy(m_szUrl, item.m_szUrl, sizeof(m_szUrl)); m_Ip = item.m_Ip; ::memcpy(m_Modules, item.m_Modules, sizeof(m_Modules)); } diff --git a/src/ccallsignlistitem.h b/src/ccallsignlistitem.h index 1164ee7..fef2192 100644 --- a/src/ccallsignlistitem.h +++ b/src/ccallsignlistitem.h @@ -29,6 +29,11 @@ #include "ccallsign.h" #include "cip.h" +//////////////////////////////////////////////////////////////////////////////////////// +// define + +#define URL_MAXLEN 256 + //////////////////////////////////////////////////////////////////////////////////////// // class @@ -38,6 +43,7 @@ public: // constructor CCallsignListItem(); CCallsignListItem(const CCallsign &, const CIp &, const char *); + CCallsignListItem(const CCallsign &, const char *, const char *); CCallsignListItem(const CCallsignListItem &); // destructor @@ -54,9 +60,13 @@ public: const CIp &GetIp(void) const { return m_Ip; } const char *GetModules(void) { return m_Modules; } + // update + void ResolveIp(void) { m_Ip = CIp(m_szUrl); } + protected: // data CCallsign m_Callsign; + char m_szUrl[URL_MAXLEN+1]; CIp m_Ip; char m_Modules[NB_MODULES_MAX+1]; }; diff --git a/src/cdcsprotocol.cpp b/src/cdcsprotocol.cpp index bab9cf1..871a435 100644 --- a/src/cdcsprotocol.cpp +++ b/src/cdcsprotocol.cpp @@ -291,14 +291,14 @@ void CDcsProtocol::HandleQueue(void) { // encode it CBuffer buffer; - if ( packet->IsDvFrame() ) - { - EncodeDvPacket(m_DvHeadersCache[iModId], (const CDvFramePacket &)*packet, m_iSeqCounters[iModId]++, &buffer); - } - else if ( packet->IsLastPacket() ) + if ( packet->IsLastPacket() ) { EncodeDvLastPacket(m_DvHeadersCache[iModId], (const CDvFramePacket &)*packet, m_iSeqCounters[iModId]++, &buffer); } + else if ( packet->IsDvFrame() ) + { + EncodeDvPacket(m_DvHeadersCache[iModId], (const CDvFramePacket &)*packet, m_iSeqCounters[iModId]++, &buffer); + } // send it if ( buffer.size() > 0 ) diff --git a/src/cdplusprotocol.cpp b/src/cdplusprotocol.cpp index 9c019bf..08d3c3d 100644 --- a/src/cdplusprotocol.cpp +++ b/src/cdplusprotocol.cpp @@ -30,6 +30,17 @@ #include "cgatekeeper.h" +//////////////////////////////////////////////////////////////////////////////////////// +// constructor + +CDplusProtocol::CDplusProtocol() +{ + for ( int i = 0; i < m_iSeqCounters.size(); i++ ) + { + m_iSeqCounters[i] = 0; + } +} + //////////////////////////////////////////////////////////////////////////////////////// // operation @@ -82,7 +93,7 @@ void CDplusProtocol::Task(void) // handle it OnDvFramePacketIn(Frame); - } + } else if ( (Header = IsValidDvHeaderPacket(Buffer)) != NULL ) { //std::cout << "DPlus DV header:" << std::endl << *Header << std::endl; @@ -270,6 +281,17 @@ void CDplusProtocol::HandleQueue(void) CPacket *packet = m_Queue.front(); m_Queue.pop(); + // get our sender's id + int iModId = g_Reflector.GetModuleIndex(packet->GetModuleId()); + + // check if it's header and update cache + if ( packet->IsDvHeader() ) + { + // this relies on queue feeder setting valid module id + m_DvHeadersCache[iModId] = CDvHeaderPacket((const CDvHeaderPacket &)*packet); + m_iSeqCounters[iModId] = 0; + } + // encode it CBuffer buffer; if ( EncodeDvPacket(*packet, &buffer) ) @@ -288,30 +310,28 @@ void CDplusProtocol::HandleQueue(void) // check if client is a dextra dongle // then replace RPT2 with XRF instead of REF // if the client type is not yet known, send bothheaders - if ( packet->IsDvHeader() && (client->IsDextraDongle() || !client->HasModule()) ) + if ( packet->IsDvHeader() ) { - // clone the packet and patch it - CDvHeaderPacket packet2(*((CDvHeaderPacket *)packet)); - CCallsign rpt2 = packet2.GetRpt2Callsign(); - rpt2.PatchCallsign(0, (const uint8 *)"XRF", 3); - packet2.SetRpt2Callsign(rpt2); - // encode it - CBuffer buffer2; - if ( EncodeDvPacket(packet2, &buffer2) ) + // sending header in Dplus is client specific + SendDvHeader((CDvHeaderPacket *)packet, (CDplusClient *)client); + } + else if ( packet->IsDvFrame() ) + { + // and send the DV frame + m_Socket.Send(buffer, client->GetIp()); + + // is it time to insert a DVheader copy ? + if ( (m_iSeqCounters[iModId]++ % 21) == 20 ) { - // and send it - m_Socket.Send(buffer2, client->GetIp()); - } - // client type known ? - if ( !client->HasModule() ) - { - // no, send also the genuine packet - m_Socket.Send(buffer, client->GetIp()); + // yes, clone it + CDvHeaderPacket packet2(m_DvHeadersCache[iModId]); + // and send it + SendDvHeader(&packet2, (CDplusClient *)client); } } else { - // no, send the original packet + // otherwise, send the original packet m_Socket.Send(buffer, client->GetIp()); } } @@ -326,6 +346,43 @@ void CDplusProtocol::HandleQueue(void) m_Queue.Unlock(); } +void CDplusProtocol::SendDvHeader(CDvHeaderPacket *packet, CDplusClient *client) +{ + // encode it + CBuffer buffer; + if ( EncodeDvPacket(*packet, &buffer) ) + { + if ( (client->IsDextraDongle() || !client->HasModule()) ) + { + // clone the packet and patch it + CDvHeaderPacket packet2(*((CDvHeaderPacket *)packet)); + CCallsign rpt2 = packet2.GetRpt2Callsign(); + rpt2.PatchCallsign(0, (const uint8 *)"XRF", 3); + packet2.SetRpt2Callsign(rpt2); + + // encode it + CBuffer buffer2; + if ( EncodeDvPacket(packet2, &buffer2) ) + { + // and send it + m_Socket.Send(buffer2, client->GetIp()); + } + + // client type known ? + if ( !client->HasModule() ) + { + // no, send also the genuine packet + m_Socket.Send(buffer, client->GetIp()); + } + } + else + { + // otherwise, send the original packet + m_Socket.Send(buffer, client->GetIp()); + } + } +} + //////////////////////////////////////////////////////////////////////////////////////// // keepalive helpers diff --git a/src/cdplusprotocol.h b/src/cdplusprotocol.h index 799cc04..4a0b2f2 100644 --- a/src/cdplusprotocol.h +++ b/src/cdplusprotocol.h @@ -37,11 +37,13 @@ //////////////////////////////////////////////////////////////////////////////////////// // class +class CDplusClient; + class CDplusProtocol : public CProtocol { public: // constructor - CDplusProtocol() {}; + CDplusProtocol(); // destructor virtual ~CDplusProtocol() {}; @@ -55,6 +57,7 @@ public: protected: // queue helper void HandleQueue(void); + void SendDvHeader(CDvHeaderPacket *, CDplusClient *); // keepalive helpers void HandleKeepalives(void); @@ -84,6 +87,10 @@ protected: protected: // for keep alive CTimePoint m_LastKeepaliveTime; + + // for queue header caches + std::array m_DvHeadersCache; + std::array m_iSeqCounters; }; //////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cpeercallsignlist.cpp b/src/cpeercallsignlist.cpp index 45b826d..375ebc0 100644 --- a/src/cpeercallsignlist.cpp +++ b/src/cpeercallsignlist.cpp @@ -57,14 +57,14 @@ bool CPeerCallsignList::LoadFromFile(const char *filename) { CCallsign callsign(szt); // 2nd token is ip - if ( (szt = ::strtok(NULL, " ,\t")) != NULL ) + char *szip; + if ( (szip = ::strtok(NULL, " ,\t")) != NULL ) { - CIp ip(szt); // 3rd token is modules list if ( (szt = ::strtok(NULL, " ,\t")) != NULL ) { // and load - push_back(CCallsignListItem(callsign, ip, szt)); + push_back(CCallsignListItem(callsign, szip, szt)); } } } diff --git a/src/cxlxprotocol.cpp b/src/cxlxprotocol.cpp index b277925..97a3546 100644 --- a/src/cxlxprotocol.cpp +++ b/src/cxlxprotocol.cpp @@ -314,6 +314,8 @@ void CXlxProtocol::HandlePeerLinks(void) CCallsignListItem *item = &((list->data())[i]); if ( clients->FindClient(item->GetCallsign(), PROTOCOL_XLX) == NULL ) { + // resolve again peer's IP in case it's a dynamic IP + item->ResolveIp(); // send connect packet to re-initiate peer link EncodeConnectPacket(&buffer, item->GetModules()); m_Socket.Send(buffer, item->GetIp(), XLX_PORT); diff --git a/src/main.h b/src/main.h index 52c1a18..3229fd8 100644 --- a/src/main.h +++ b/src/main.h @@ -48,7 +48,7 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 3 -#define VERSION_REVISION 7 +#define VERSION_REVISION 8 // global ------------------------------------------------------ diff --git a/src/makefile b/src/makefile index 4c11c68..f04eff2 100644 --- a/src/makefile +++ b/src/makefile @@ -4,7 +4,6 @@ LDFLAGS=-std=c++11 -pthread SOURCES=$(wildcard *.cpp) OBJECTS=$(SOURCES:.cpp=.o) EXECUTABLE=xlxd -RM=rm -f all: $(SOURCES) $(EXECUTABLE) @@ -15,7 +14,7 @@ $(EXECUTABLE): $(OBJECTS) $(CC) $(CFLAGS) $< -o $@ clean: - $(RM) *.o + rm *.o install: mkdir -p /xlxd