From b7a77491a4bca930a956862a93536f2833916fa4 Mon Sep 17 00:00:00 2001 From: Tom Early Date: Fri, 3 Jul 2020 08:53:51 -0700 Subject: [PATCH] CCallsignList is a std::list --- .gitignore | 9 ++- src/ccallsignlist.cpp | 74 ++++++++------------ src/ccallsignlist.h | 13 ++-- src/cdextraprotocol.cpp | 117 ++++++++++++++++---------------- src/cpeercallsignlist.cpp | 22 +++--- src/cpeercallsignlist.h | 8 +-- src/cxlxprotocol.cpp | 139 +++++++++++++++++++------------------- src/main.h | 15 ++-- 8 files changed, 194 insertions(+), 203 deletions(-) diff --git a/.gitignore b/.gitignore index dffdf1c..3c2132a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ *.o -src/xlxd -ambed/ambed -ambedtest/ambedtest +*.d +.vscode +xlxd +xrfd +ambed +main.h diff --git a/src/ccallsignlist.cpp b/src/ccallsignlist.cpp index dfd9d35..a233735 100644 --- a/src/ccallsignlist.cpp +++ b/src/ccallsignlist.cpp @@ -4,6 +4,7 @@ // // Created by Jean-Luc Deltombe (LX3JL) on 30/12/2015. // Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved. +// Copyright © 2020 Thomas A. Early, N7TAE // // ---------------------------------------------------------------------------- // This file is part of xlxd. @@ -53,13 +54,13 @@ bool CCallsignList::LoadFromFile(const char *filename) Lock(); // empty list - clear(); + m_Callsigns.clear(); // fill with file content while ( file.getline(sz, sizeof(sz)).good() ) { // remove leading & trailing spaces char *szt = TrimWhiteSpaces(sz); - + // crack it if ( (::strlen(szt) > 0) && (szt[0] != '#') ) { @@ -75,7 +76,7 @@ bool CCallsignList::LoadFromFile(const char *filename) szt = szStar; } // and add to list - push_back(CCallsignListItem(callsign, CIp(), szt)); + m_Callsigns.push_back(CCallsignListItem(callsign, CIp(), szt)); } } } @@ -91,7 +92,7 @@ bool CCallsignList::LoadFromFile(const char *filename) // and done Unlock(); ok = true; - std::cout << "Gatekeeper loaded " << size() << " lines from " << filename << std::endl; + std::cout << "Gatekeeper loaded " << m_Callsigns.size() << " lines from " << filename << std::endl; } else { @@ -129,57 +130,46 @@ bool CCallsignList::NeedReload(void) bool CCallsignList::IsCallsignListedWithWildcard(const CCallsign &callsign) const { - bool listed = false; - - for ( int i = 0; (i < size()) && !listed; i++ ) + for ( const auto &item : m_Callsigns ) { - listed = (data()[i]).HasSameCallsignWithWildcard(callsign); + if (item.HasSameCallsignWithWildcard(callsign)) + return true; } - return listed; + return false; } bool CCallsignList::IsCallsignListedWithWildcard(const CCallsign &callsign, char module) const { - bool listed = false; - - for ( int i = 0; (i < size()) && !listed; i++ ) + for ( const auto &item : m_Callsigns ) { - const CCallsignListItem *item = &(data()[i]); - listed = (item->HasSameCallsignWithWildcard(callsign) && - ((module == ' ') || item->HasModuleListed(module)) ); - + if (item.HasSameCallsignWithWildcard(callsign) && ((module == ' ') || item.HasModuleListed(module)) ) + return true; } - - return listed; + + return false; } bool CCallsignList::IsCallsignListed(const CCallsign &callsign, char module) const { - bool listed = false; - - for ( int i = 0; (i < size()) && !listed; i++ ) + for ( const auto &item : m_Callsigns ) { - const CCallsignListItem *item = &(data()[i]); - listed = (item->HasSameCallsign(callsign) && item->HasModuleListed(module)); - + if (item.HasSameCallsign(callsign) && item.HasModuleListed(module)) + return true; } - - return listed; + + return false; } bool CCallsignList::IsCallsignListed(const CCallsign &callsign, char *modules) const { - bool listed = false; - - for ( int i = 0; (i < size()) && !listed; i++ ) + for ( const auto &item : m_Callsigns ) { - const CCallsignListItem *item = &(data()[i]); - listed = (item->HasSameCallsign(callsign) && item->CheckListedModules(modules)); - + if (item.HasSameCallsign(callsign) && item.CheckListedModules(modules)) + return true; } - - return listed; + + return false; } //////////////////////////////////////////////////////////////////////////////////////// @@ -187,20 +177,16 @@ bool CCallsignList::IsCallsignListed(const CCallsign &callsign, char *modules) c CCallsignListItem *CCallsignList::FindListItem(const CCallsign &Callsign) { - CCallsignListItem *item = NULL; - - // find client - for ( int i = 0; (i < size()) && (item == NULL); i++ ) + for ( auto &item : m_Callsigns ) { - if ( (data()[i]).GetCallsign().HasSameCallsign(Callsign) ) + if ( item.GetCallsign().HasSameCallsign(Callsign) ) { - item = &(data()[i]); + return &item; } } - - // done - return item; - + + return NULL; + } //////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/ccallsignlist.h b/src/ccallsignlist.h index b0f5362..4425461 100644 --- a/src/ccallsignlist.h +++ b/src/ccallsignlist.h @@ -4,6 +4,7 @@ // // Created by Jean-Luc Deltombe (LX3JL) on 30/12/2015. // Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved. +// Copyright © 2020 Thomas A. Early, N7TAE // // ---------------------------------------------------------------------------- // This file is part of xlxd. @@ -32,7 +33,7 @@ //////////////////////////////////////////////////////////////////////////////////////// // class -class CCallsignList : public std::vector +class CCallsignList { public: // constructor @@ -56,19 +57,23 @@ public: bool IsCallsignListed(const CCallsign &, char) const; bool IsCallsignListed(const CCallsign &, char*) const; + // pass-thru + bool empty() const { return m_Callsigns.empty(); } + std::list::iterator begin() { return m_Callsigns.begin(); } + std::list::iterator end() { return m_Callsigns.end(); } + // find CCallsignListItem *FindListItem(const CCallsign &); - + protected: - // bool GetLastModTime(time_t *); char *TrimWhiteSpaces(char *); -protected: // data std::mutex m_Mutex; const char * m_Filename; time_t m_LastModTime; + std::list m_Callsigns; }; diff --git a/src/cdextraprotocol.cpp b/src/cdextraprotocol.cpp index c8c887c..8e5866a 100644 --- a/src/cdextraprotocol.cpp +++ b/src/cdextraprotocol.cpp @@ -4,6 +4,7 @@ // // Created by Jean-Luc Deltombe (LX3JL) on 01/11/2015. // Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved. +// Copyright © 2020 Thomas A. Early, N7TAE // // ---------------------------------------------------------------------------- // This file is part of xlxd. @@ -19,7 +20,7 @@ // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License -// along with Foobar. If not, see . +// along with Foobar. If not, see . // ---------------------------------------------------------------------------- #include "main.h" @@ -37,24 +38,24 @@ bool CDextraProtocol::Init(void) { bool ok; - + // base class ok = CProtocol::Init(); - + // update the reflector callsign m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"XRF", 3); - + // create our socket ok &= m_Socket.Open(DEXTRA_PORT); if ( !ok ) { std::cout << "Error opening socket on port UDP" << DEXTRA_PORT << " on ip " << g_Reflector.GetListenIp() << std::endl; } - + // update time m_LastKeepaliveTime.Now(); m_LastPeersLinkTime.Now(); - + // done return ok; } @@ -72,7 +73,7 @@ void CDextraProtocol::Task(void) CDvHeaderPacket *Header; CDvFramePacket *Frame; CDvLastFramePacket *LastFrame; - + // any incoming packet ? if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 ) { @@ -80,7 +81,7 @@ void CDextraProtocol::Task(void) if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL ) { //std::cout << "DExtra DV frame" << std::endl; - + // handle it OnDvFramePacketIn(Frame, &Ip); } @@ -88,7 +89,7 @@ void CDextraProtocol::Task(void) { //std::cout << "DExtra DV header:" << std::endl << *Header << std::endl; //std::cout << "DExtra DV header:" << std::endl; - + // callsign muted? if ( g_GateKeeper.MayTransmit(Header->GetMyCallsign(), Ip, PROTOCOL_DEXTRA, Header->GetRpt2Module()) ) { @@ -103,14 +104,14 @@ void CDextraProtocol::Task(void) else if ( (LastFrame = IsValidDvLastFramePacket(Buffer)) != NULL ) { //std::cout << "DExtra DV last frame" << std::endl; - + // handle it OnDvLastFramePacketIn(LastFrame, &Ip); } else if ( IsValidConnectPacket(Buffer, &Callsign, &ToLinkModule, &ProtRev) ) { std::cout << "DExtra connect packet for module " << ToLinkModule << " from " << Callsign << " at " << Ip << " rev " << ProtRev << std::endl; - + // callsign authorized? if ( g_GateKeeper.MayLink(Callsign, Ip, PROTOCOL_DEXTRA) ) { @@ -123,7 +124,7 @@ void CDextraProtocol::Task(void) if ( item != NULL && Callsign.GetModule() == item->GetModules()[1] && ToLinkModule == item->GetModules()[0] ) { std::cout << "DExtra ack packet for module " << ToLinkModule << " from " << Callsign << " at " << Ip << std::endl; - + // already connected ? CPeers *peers = g_Reflector.GetPeers(); if ( peers->FindPeer(Callsign, Ip, PROTOCOL_DEXTRA) == NULL ) @@ -143,10 +144,10 @@ void CDextraProtocol::Task(void) // acknowledge the request EncodeConnectAckPacket(&Buffer, ProtRev); m_Socket.Send(Buffer, Ip); - + // create the client CDextraClient *client = new CDextraClient(Callsign, Ip, ToLinkModule, ProtRev); - + // and append g_Reflector.GetClients()->AddClient(client); g_Reflector.ReleaseClients(); @@ -156,7 +157,7 @@ void CDextraProtocol::Task(void) else { std::cout << "DExtra node " << Callsign << " connect attempt on non-existing module" << std::endl; - + // deny the request EncodeConnectNackPacket(&Buffer); m_Socket.Send(Buffer, Ip); @@ -172,7 +173,7 @@ void CDextraProtocol::Task(void) else if ( IsValidDisconnectPacket(Buffer, &Callsign) ) { std::cout << "DExtra disconnect packet from " << Callsign << " at " << Ip << std::endl; - + // find client & remove it CClients *clients = g_Reflector.GetClients(); CClient *client = clients->FindClient(Ip, PROTOCOL_DEXTRA); @@ -196,7 +197,7 @@ void CDextraProtocol::Task(void) else if ( IsValidKeepAlivePacket(Buffer, &Callsign) ) { //std::cout << "DExtra keepalive packet from " << Callsign << " at " << Ip << std::endl; - + // find all clients with that callsign & ip and keep them alive CClients *clients = g_Reflector.GetClients(); int index = -1; @@ -213,19 +214,19 @@ void CDextraProtocol::Task(void) //std::cout << Buffer.data() << std::endl; } } - + // handle end of streaming timeout CheckStreamsTimeout(); - + // handle queue from reflector HandleQueue(); - + // keep alive if ( m_LastKeepaliveTime.DurationSinceNow() > DEXTRA_KEEPALIVE_PERIOD ) { // handle keep alives HandleKeepalives(); - + // update time m_LastKeepaliveTime.Now(); } @@ -235,7 +236,7 @@ void CDextraProtocol::Task(void) { // handle remote peers connections HandlePeerLinks(); - + // update time m_LastPeersLinkTime.Now(); } @@ -252,7 +253,7 @@ void CDextraProtocol::HandleQueue(void) // get the packet CPacket *packet = m_Queue.front(); m_Queue.pop(); - + // encode it CBuffer buffer; if ( EncodeDvPacket(*packet, &buffer) ) @@ -276,8 +277,8 @@ void CDextraProtocol::HandleQueue(void) } g_Reflector.ReleaseClients(); } - - + + // done delete packet; } @@ -303,7 +304,7 @@ void CDextraProtocol::HandleKeepalives(void) { // send keepalive m_Socket.Send(keepalive, client->GetIp()); - + // client busy ? if ( client->IsAMaster() ) { @@ -325,14 +326,14 @@ void CDextraProtocol::HandleKeepalives(void) CBuffer disconnect; EncodeDisconnectPacket(&disconnect, client->GetReflectorModule()); m_Socket.Send(disconnect, client->GetIp()); - + // remove it std::cout << "DExtra client " << client->GetCallsign() << " keepalive timeout" << std::endl; clients->RemoveClient(client); } g_Reflector.ReleasePeers(); } - + } g_Reflector.ReleaseClients(); @@ -356,11 +357,11 @@ void CDextraProtocol::HandleKeepalives(void) m_Socket.Send(disconnect, peer->GetClient(i)->GetIp()); } g_Reflector.ReleaseClients(); - + // remove it std::cout << "DExtra peer " << peer->GetCallsign() << " keepalive timeout" << std::endl; peers->RemovePeer(peer); - } + } } g_Reflector.ReleasePeers(); } @@ -371,7 +372,7 @@ void CDextraProtocol::HandleKeepalives(void) void CDextraProtocol::HandlePeerLinks(void) { CBuffer buffer; - + // get the list of peers CPeerCallsignList *list = g_GateKeeper.GetPeerList(); CPeers *peers = g_Reflector.GetPeers(); @@ -392,27 +393,26 @@ void CDextraProtocol::HandlePeerLinks(void) peers->RemovePeer(peer); } } - + // check if all ours peers listed by gatekeeper are connected // if not, connect or reconnect - for ( int i = 0; i < list->size(); i++ ) + for ( auto it=list->begin(); it!=list->end(); it++ ) { - CCallsignListItem *item = &((list->data())[i]); - if ( !item->GetCallsign().HasSameCallsignWithWildcard(CCallsign("XRF*")) ) + if ( !(*it).GetCallsign().HasSameCallsignWithWildcard(CCallsign("XRF*")) ) continue; - if ( strlen(item->GetModules()) != 2 ) + if ( strlen((*it).GetModules()) != 2 ) continue; - if ( peers->FindPeer(item->GetCallsign(), PROTOCOL_DEXTRA) == NULL ) + if ( peers->FindPeer((*it).GetCallsign(), PROTOCOL_DEXTRA) == NULL ) { // resolve again peer's IP in case it's a dynamic IP - item->ResolveIp(); + (*it).ResolveIp(); // send connect packet to re-initiate peer link - EncodeConnectPacket(&buffer, item->GetModules()); - m_Socket.Send(buffer, item->GetIp(), DEXTRA_PORT); - std::cout << "Sending connect packet to XRF peer " << item->GetCallsign() << " @ " << item->GetIp() << " for module " << item->GetModules()[1] << " (module " << item->GetModules()[0] << ")" << std::endl; + EncodeConnectPacket(&buffer, (*it).GetModules()); + m_Socket.Send(buffer, (*it).GetIp(), DEXTRA_PORT); + std::cout << "Sending connect packet to XRF peer " << (*it).GetCallsign() << " @ " << (*it).GetIp() << " for module " << (*it).GetModules()[1] << " (module " << (*it).GetModules()[0] << ")" << std::endl; } } - + // done g_Reflector.ReleasePeers(); g_GateKeeper.ReleasePeerList(); @@ -424,14 +424,14 @@ void CDextraProtocol::HandlePeerLinks(void) bool CDextraProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip) { bool newstream = false; - + // find the stream CPacketStream *stream = GetStream(Header->GetStreamId()); if ( stream == NULL ) { // no stream open yet, open a new one CCallsign via(Header->GetRpt1Callsign()); - + // find this client CClient *client = g_Reflector.GetClients()->FindClient(Ip, PROTOCOL_DEXTRA); if ( client != NULL ) @@ -455,11 +455,11 @@ bool CDextraProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip) } // release g_Reflector.ReleaseClients(); - + // update last heard g_Reflector.GetUsers()->Hearing(Header->GetMyCallsign(), via, Header->GetRpt2Callsign()); g_Reflector.ReleaseUsers(); - + // delete header if needed if ( !newstream ) { @@ -474,7 +474,7 @@ bool CDextraProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip) // and delete packet delete Header; } - + // done return newstream; } @@ -535,7 +535,7 @@ bool CDextraProtocol::IsValidKeepAlivePacket(const CBuffer &Buffer, CCallsign *c CDvHeaderPacket *CDextraProtocol::IsValidDvHeaderPacket(const CBuffer &Buffer) { CDvHeaderPacket *header = NULL; - + if ( (Buffer.size() == 56) && (Buffer.Compare((uint8 *)"DSVT", 4) == 0) && (Buffer.data()[4] == 0x10) && (Buffer.data()[8] == 0x20) ) { @@ -555,7 +555,7 @@ CDvHeaderPacket *CDextraProtocol::IsValidDvHeaderPacket(const CBuffer &Buffer) CDvFramePacket *CDextraProtocol::IsValidDvFramePacket(const CBuffer &Buffer) { CDvFramePacket *dvframe = NULL; - + if ( (Buffer.size() == 27) && (Buffer.Compare((uint8 *)"DSVT", 4) == 0) && (Buffer.data()[4] == 0x20) && (Buffer.data()[8] == 0x20) && ((Buffer.data()[14] & 0x40) == 0) ) @@ -576,7 +576,7 @@ CDvFramePacket *CDextraProtocol::IsValidDvFramePacket(const CBuffer &Buffer) CDvLastFramePacket *CDextraProtocol::IsValidDvLastFramePacket(const CBuffer &Buffer) { CDvLastFramePacket *dvframe = NULL; - + if ( (Buffer.size() == 27) && (Buffer.Compare((uint8 *)"DSVT", 4) == 0) && (Buffer.data()[4] == 0x20) && (Buffer.data()[8] == 0x20) && ((Buffer.data()[14] & 0x40) != 0) ) @@ -660,41 +660,40 @@ bool CDextraProtocol::EncodeDvHeaderPacket(const CDvHeaderPacket &Packet, CBuffe { uint8 tag[] = { 'D','S','V','T',0x10,0x00,0x00,0x00,0x20,0x00,0x01,0x02 }; struct dstar_header DstarHeader; - + Packet.ConvertToDstarStruct(&DstarHeader); - + Buffer->Set(tag, sizeof(tag)); Buffer->Append(Packet.GetStreamId()); Buffer->Append((uint8)0x80); Buffer->Append((uint8 *)&DstarHeader, sizeof(struct dstar_header)); - + return true; } bool CDextraProtocol::EncodeDvFramePacket(const CDvFramePacket &Packet, CBuffer *Buffer) const { uint8 tag[] = { 'D','S','V','T',0x20,0x00,0x00,0x00,0x20,0x00,0x01,0x02 }; - + Buffer->Set(tag, sizeof(tag)); Buffer->Append(Packet.GetStreamId()); Buffer->Append((uint8)(Packet.GetPacketId() % 21)); Buffer->Append((uint8 *)Packet.GetAmbe(), AMBE_SIZE); Buffer->Append((uint8 *)Packet.GetDvData(), DVDATA_SIZE); - + return true; - + } bool CDextraProtocol::EncodeDvLastFramePacket(const CDvLastFramePacket &Packet, CBuffer *Buffer) const { uint8 tag1[] = { 'D','S','V','T',0x20,0x00,0x00,0x00,0x20,0x00,0x01,0x02 }; uint8 tag2[] = { 0x55,0xC8,0x7A,0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x1A,0xC6 }; - + Buffer->Set(tag1, sizeof(tag1)); Buffer->Append(Packet.GetStreamId()); Buffer->Append((uint8)((Packet.GetPacketId() % 21) | 0x40)); Buffer->Append(tag2, sizeof(tag2)); - + return true; } - diff --git a/src/cpeercallsignlist.cpp b/src/cpeercallsignlist.cpp index 375ebc0..1a605e0 100644 --- a/src/cpeercallsignlist.cpp +++ b/src/cpeercallsignlist.cpp @@ -34,21 +34,21 @@ bool CPeerCallsignList::LoadFromFile(const char *filename) { bool ok = false; char sz[256]; - + // and load std::ifstream file (filename); if ( file.is_open() ) { Lock(); - + // empty list - clear(); + m_Callsigns.clear(); // fill with file content while ( file.getline(sz, sizeof(sz)).good() ) { // remove leading & trailing spaces char *szt = TrimWhiteSpaces(sz); - + // crack it if ( (::strlen(szt) > 0) && (szt[0] != '#') ) { @@ -64,7 +64,7 @@ bool CPeerCallsignList::LoadFromFile(const char *filename) if ( (szt = ::strtok(NULL, " ,\t")) != NULL ) { // and load - push_back(CCallsignListItem(callsign, szip, szt)); + m_Callsigns.push_back(CCallsignListItem(callsign, szip, szt)); } } } @@ -72,24 +72,22 @@ bool CPeerCallsignList::LoadFromFile(const char *filename) } // close file file.close(); - + // keep file path m_Filename = filename; - + // update time GetLastModTime(&m_LastModTime); - + // and done Unlock(); ok = true; - std::cout << "Gatekeeper loaded " << size() << " lines from " << filename << std::endl; + std::cout << "Gatekeeper loaded " << m_Callsigns.size() << " lines from " << filename << std::endl; } else { std::cout << "Gatekeeper cannot find " << filename << std::endl; } - + return ok; } - - diff --git a/src/cpeercallsignlist.h b/src/cpeercallsignlist.h index 1c58f18..6472283 100644 --- a/src/cpeercallsignlist.h +++ b/src/cpeercallsignlist.h @@ -37,11 +37,11 @@ class CPeerCallsignList : public CCallsignList { public: // constructor - CPeerCallsignList() {}; - + CPeerCallsignList() {} + // destructor - virtual ~CPeerCallsignList() {}; - + virtual ~CPeerCallsignList() {} + // file io bool LoadFromFile(const char *); }; diff --git a/src/cxlxprotocol.cpp b/src/cxlxprotocol.cpp index c347275..ab029b3 100644 --- a/src/cxlxprotocol.cpp +++ b/src/cxlxprotocol.cpp @@ -4,6 +4,7 @@ // // Created by Jean-Luc Deltombe (LX3JL) on 28/01/2016. // Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved. +// Copyright © 2020 Thomas A. Early, N7TAE // // ---------------------------------------------------------------------------- // This file is part of xlxd. @@ -37,24 +38,24 @@ bool CXlxProtocol::Init(void) { bool ok; - + // base class ok = CProtocol::Init(); - + // update the reflector callsign m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"XLX", 3); - + // create our socket ok &= m_Socket.Open(XLX_PORT); if ( !ok ) { std::cout << "Error opening socket on port UDP" << XLX_PORT << " on ip " << g_Reflector.GetListenIp() << std::endl; } - + // update time m_LastKeepaliveTime.Now(); m_LastPeersLinkTime.Now(); - + // done return ok; } @@ -72,7 +73,7 @@ void CXlxProtocol::Task(void) CDvHeaderPacket *Header; CDvFramePacket *Frame; CDvLastFramePacket *LastFrame; - + // any incoming packet ? if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 ) { @@ -80,7 +81,7 @@ void CXlxProtocol::Task(void) if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL ) { //std::cout << "XLX (DExtra) DV frame" << std::endl; - + // handle it OnDvFramePacketIn(Frame, &Ip); } @@ -88,7 +89,7 @@ void CXlxProtocol::Task(void) { //std::cout << "XLX (DExtra) DV header:" << std::endl << *Header << std::endl; //std::cout << "XLX (DExtra) DV header on module " << Header->GetRpt2Module() << std::endl; - + // callsign muted? if ( g_GateKeeper.MayTransmit(Header->GetMyCallsign(), Ip) ) { @@ -103,7 +104,7 @@ void CXlxProtocol::Task(void) else if ( (LastFrame = IsValidDvLastFramePacket(Buffer)) != NULL ) { //std::cout << "XLX (DExtra) DV last frame" << std::endl; - + // handle it OnDvLastFramePacketIn(LastFrame, &Ip); } @@ -113,7 +114,7 @@ void CXlxProtocol::Task(void) << Version.GetMajor() << "." << Version.GetMinor() << "." << Version.GetRevision() << ") connect packet for modules " << Modules << " from " << Callsign << " at " << Ip << std::endl; - + // callsign authorized? if ( g_GateKeeper.MayLink(Callsign, Ip, PROTOCOL_XLX, Modules) ) { @@ -132,7 +133,7 @@ void CXlxProtocol::Task(void) m_Socket.Send(Buffer, Ip); } g_Reflector.ReleasePeers(); - + } break; case XLX_PROTOCOL_REVISION_1: @@ -154,7 +155,7 @@ void CXlxProtocol::Task(void) else if ( IsValidAckPacket(Buffer, &Callsign, Modules, &Version) ) { std::cout << "XLX ack packet for modules " << Modules << " from " << Callsign << " at " << Ip << std::endl; - + // callsign authorized? if ( g_GateKeeper.MayLink(Callsign, Ip, PROTOCOL_XLX, Modules) ) { @@ -176,7 +177,7 @@ void CXlxProtocol::Task(void) else if ( IsValidDisconnectPacket(Buffer, &Callsign) ) { std::cout << "XLX disconnect packet from " << Callsign << " at " << Ip << std::endl; - + // find peer CPeers *peers = g_Reflector.GetPeers(); CPeer *peer = peers->FindPeer(Ip, PROTOCOL_XLX); @@ -196,7 +197,7 @@ void CXlxProtocol::Task(void) else if ( IsValidKeepAlivePacket(Buffer, &Callsign) ) { //std::cout << "XLX keepalive packet from " << Callsign << " at " << Ip << std::endl; - + // find peer CPeers *peers = g_Reflector.GetPeers(); CPeer *peer = peers->FindPeer(Ip, PROTOCOL_XLX); @@ -212,29 +213,29 @@ void CXlxProtocol::Task(void) std::cout << "XLX packet (" << Buffer.size() << ")" << std::endl; } } - + // handle end of streaming timeout CheckStreamsTimeout(); - + // handle queue from reflector HandleQueue(); - + // keep alive if ( m_LastKeepaliveTime.DurationSinceNow() > XLX_KEEPALIVE_PERIOD ) { // handle keep alives HandleKeepalives(); - + // update time m_LastKeepaliveTime.Now(); } - + // peer connections if ( m_LastPeersLinkTime.DurationSinceNow() > XLX_RECONNECT_PERIOD ) { // handle remote peers connections HandlePeerLinks(); - + // update time m_LastPeersLinkTime.Now(); } @@ -251,7 +252,7 @@ void CXlxProtocol::HandleQueue(void) // get the packet CPacket *packet = m_Queue.front(); m_Queue.pop(); - + // check if origin of packet is local // if not, do not stream it out as it will cause // network loop between linked XLX peers @@ -267,7 +268,7 @@ void CXlxProtocol::HandleQueue(void) { bufferLegacy.resize(27); } - + // and push it to all our clients linked to the module and who are not streaming in CClients *clients = g_Reflector.GetClients(); int index = -1; @@ -302,7 +303,7 @@ void CXlxProtocol::HandleQueue(void) g_Reflector.ReleaseClients(); } } - + // done delete packet; } @@ -319,7 +320,7 @@ void CXlxProtocol::HandleKeepalives(void) // so, send keepalives to all CBuffer keepalive; EncodeKeepAlivePacket(&keepalive); - + // iterate on peers CPeers *peers = g_Reflector.GetPeers(); int index = -1; @@ -328,7 +329,7 @@ void CXlxProtocol::HandleKeepalives(void) { // send keepalive m_Socket.Send(keepalive, peer->GetIp()); - + // client busy ? if ( peer->IsAMaster() ) { @@ -342,11 +343,11 @@ void CXlxProtocol::HandleKeepalives(void) CBuffer disconnect; EncodeDisconnectPacket(&disconnect); m_Socket.Send(disconnect, peer->GetIp()); - + // remove it std::cout << "XLX peer " << peer->GetCallsign() << " keepalive timeout" << std::endl; peers->RemovePeer(peer); - } + } } g_Reflector.ReleasePeers(); } @@ -357,7 +358,7 @@ void CXlxProtocol::HandleKeepalives(void) void CXlxProtocol::HandlePeerLinks(void) { CBuffer buffer; - + // get the list of peers CPeerCallsignList *list = g_GateKeeper.GetPeerList(); CPeers *peers = g_Reflector.GetPeers(); @@ -378,25 +379,24 @@ void CXlxProtocol::HandlePeerLinks(void) peers->RemovePeer(peer); } } - + // check if all ours peers listed by gatekeeper are connected // if not, connect or reconnect - for ( int i = 0; i < list->size(); i++ ) + for ( auto it=list->begin(); it!=list->end(); it++ ) { - CCallsignListItem *item = &((list->data())[i]); - if ( item->GetCallsign().HasSameCallsignWithWildcard(CCallsign("XRF*")) ) + if ( (*it).GetCallsign().HasSameCallsignWithWildcard(CCallsign("XRF*")) ) continue; - if ( peers->FindPeer(item->GetCallsign(), PROTOCOL_XLX) == NULL ) + if ( peers->FindPeer((*it).GetCallsign(), PROTOCOL_XLX) == NULL ) { // resolve again peer's IP in case it's a dynamic IP - item->ResolveIp(); + (*it).ResolveIp(); // send connect packet to re-initiate peer link - EncodeConnectPacket(&buffer, item->GetModules()); - m_Socket.Send(buffer, item->GetIp(), XLX_PORT); - std::cout << "Sending connect packet to XLX peer " << item->GetCallsign() << " @ " << item->GetIp() << " for modules " << item->GetModules() << std::endl; + EncodeConnectPacket(&buffer, (*it).GetModules()); + m_Socket.Send(buffer, (*it).GetIp(), XLX_PORT); + std::cout << "Sending connect packet to XLX peer " << (*it).GetCallsign() << " @ " << (*it).GetIp() << " for modules " << (*it).GetModules() << std::endl; } } - + // done g_Reflector.ReleasePeers(); g_GateKeeper.ReleasePeerList(); @@ -410,13 +410,13 @@ bool CXlxProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip) { bool newstream = false; CCallsign peer; - + // todo: verify Packet.GetModuleId() is in authorized list of XLX of origin // todo: do the same for DVFrame and DVLAstFrame packets // tag packet as remote peer origin Header->SetRemotePeerOrigin(); - + // find the stream CPacketStream *stream = GetStream(Header->GetStreamId()); if ( stream == NULL ) @@ -445,17 +445,17 @@ bool CXlxProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip) // skip packet, but tickle the stream stream->Tickle(); } - + // update last heard g_Reflector.GetUsers()->Hearing(Header->GetMyCallsign(), Header->GetRpt1Callsign(), Header->GetRpt2Callsign(), peer); g_Reflector.ReleaseUsers(); - + // delete header if needed if ( !newstream ) { delete Header; } - + // done return newstream; } @@ -464,7 +464,7 @@ void CXlxProtocol::OnDvFramePacketIn(CDvFramePacket *DvFrame, const CIp *Ip) { // tag packet as remote peer origin DvFrame->SetRemotePeerOrigin(); - + // anc call base class CDextraProtocol::OnDvFramePacketIn(DvFrame, Ip); } @@ -473,7 +473,7 @@ void CXlxProtocol::OnDvLastFramePacketIn(CDvLastFramePacket *DvFrame, const CIp { // tag packet as remote peer origin DvFrame->SetRemotePeerOrigin(); - + // anc call base class CDextraProtocol::OnDvLastFramePacketIn(DvFrame, Ip); } @@ -553,10 +553,10 @@ bool CXlxProtocol::IsValidNackPacket(const CBuffer &Buffer, CCallsign *callsign) CDvFramePacket *CXlxProtocol::IsValidDvFramePacket(const CBuffer &Buffer) { CDvFramePacket *dvframe = NULL; - + // base class first (protocol revision 1 and lower) dvframe = CDextraProtocol::IsValidDvFramePacket(Buffer); - + // otherwise try protocol revision 2 if ( (dvframe == NULL) && (Buffer.size() == 45) && (Buffer.Compare((uint8 *)"DSVT", 4) == 0) && @@ -571,7 +571,7 @@ CDvFramePacket *CXlxProtocol::IsValidDvFramePacket(const CBuffer &Buffer) Buffer.data()[14], &(Buffer.data()[15]), &(Buffer.data()[24]), // dmr Buffer.data()[27], Buffer.data()[28], &(Buffer.data()[29]), &(Buffer.data()[38])); - + // check validity of packet if ( !dvframe->IsValid() ) { @@ -579,7 +579,7 @@ CDvFramePacket *CXlxProtocol::IsValidDvFramePacket(const CBuffer &Buffer) dvframe = NULL; } } - + // done return dvframe; } @@ -587,10 +587,10 @@ CDvFramePacket *CXlxProtocol::IsValidDvFramePacket(const CBuffer &Buffer) CDvLastFramePacket *CXlxProtocol::IsValidDvLastFramePacket(const CBuffer &Buffer) { CDvLastFramePacket *dvframe = NULL; - + // base class first (protocol revision 1 and lower) dvframe = CDextraProtocol::IsValidDvLastFramePacket(Buffer); - + // otherwise try protocol revision 2 if ( (dvframe == NULL) && (Buffer.size() == 45) && (Buffer.Compare((uint8 *)"DSVT", 4) == 0) && @@ -605,7 +605,7 @@ CDvLastFramePacket *CXlxProtocol::IsValidDvLastFramePacket(const CBuffer &Buffer Buffer.data()[14], &(Buffer.data()[15]), &(Buffer.data()[24]), // dmr Buffer.data()[27], Buffer.data()[28], &(Buffer.data()[29]), &(Buffer.data()[38])); - + // check validity of packet if ( !dvframe->IsValid() ) { @@ -613,7 +613,7 @@ CDvLastFramePacket *CXlxProtocol::IsValidDvLastFramePacket(const CBuffer &Buffer dvframe = NULL; } } - + // done return dvframe; } @@ -629,7 +629,7 @@ void CXlxProtocol::EncodeKeepAlivePacket(CBuffer *Buffer) void CXlxProtocol::EncodeConnectPacket(CBuffer *Buffer, const char *Modules) { uint8 tag[] = { 'L' }; - + // tag Buffer->Set(tag, sizeof(tag)); // our callsign @@ -647,7 +647,7 @@ void CXlxProtocol::EncodeConnectPacket(CBuffer *Buffer, const char *Modules) void CXlxProtocol::EncodeDisconnectPacket(CBuffer *Buffer) { uint8 tag[] = { 'U' }; - + // tag Buffer->Set(tag, sizeof(tag)); // our callsign @@ -659,7 +659,7 @@ void CXlxProtocol::EncodeDisconnectPacket(CBuffer *Buffer) void CXlxProtocol::EncodeConnectAckPacket(CBuffer *Buffer, const char *Modules) { uint8 tag[] = { 'A' }; - + // tag Buffer->Set(tag, sizeof(tag)); // our callsign @@ -677,7 +677,7 @@ void CXlxProtocol::EncodeConnectAckPacket(CBuffer *Buffer, const char *Modules) void CXlxProtocol::EncodeConnectNackPacket(CBuffer *Buffer) { uint8 tag[] = { 'N' }; - + // tag Buffer->Set(tag, sizeof(tag)); // our callsign @@ -689,20 +689,20 @@ void CXlxProtocol::EncodeConnectNackPacket(CBuffer *Buffer) bool CXlxProtocol::EncodeDvFramePacket(const CDvFramePacket &Packet, CBuffer *Buffer) const { uint8 tag[] = { 'D','S','V','T',0x20,0x00,0x00,0x00,0x20,0x00,0x01,0x02 }; - + Buffer->Set(tag, sizeof(tag)); Buffer->Append(Packet.GetStreamId()); Buffer->Append((uint8)(Packet.GetDstarPacketId() % 21)); Buffer->Append((uint8 *)Packet.GetAmbe(), AMBE_SIZE); Buffer->Append((uint8 *)Packet.GetDvData(), DVDATA_SIZE); - + Buffer->Append((uint8)Packet.GetDmrPacketId()); Buffer->Append((uint8)Packet.GetDmrPacketSubid()); Buffer->Append((uint8 *)Packet.GetAmbePlus(), AMBEPLUS_SIZE); Buffer->Append((uint8 *)Packet.GetDvSync(), DVSYNC_SIZE); - + return true; - + } bool CXlxProtocol::EncodeDvLastFramePacket(const CDvLastFramePacket &Packet, CBuffer *Buffer) const @@ -710,19 +710,19 @@ bool CXlxProtocol::EncodeDvLastFramePacket(const CDvLastFramePacket &Packet, CBu uint8 tag[] = { 'D','S','V','T',0x20,0x00,0x00,0x00,0x20,0x00,0x01,0x02 }; uint8 dstarambe[] = { 0x55,0xC8,0x7A,0x00,0x00,0x00,0x00,0x00,0x00 }; uint8 dstardvdata[] = { 0x25,0x1A,0xC6 }; - + Buffer->Set(tag, sizeof(tag)); Buffer->Append(Packet.GetStreamId()); Buffer->Append((uint8)((Packet.GetPacketId() % 21) | 0x40)); Buffer->Append(dstarambe, sizeof(dstarambe)); Buffer->Append(dstardvdata, sizeof(dstardvdata)); - - + + Buffer->Append((uint8)Packet.GetDmrPacketId()); Buffer->Append((uint8)Packet.GetDmrPacketSubid()); Buffer->Append((uint8 *)Packet.GetAmbePlus(), AMBEPLUS_SIZE); Buffer->Append((uint8 *)Packet.GetDvSync(), DVSYNC_SIZE); - + return true; } @@ -732,7 +732,7 @@ bool CXlxProtocol::EncodeDvLastFramePacket(const CDvLastFramePacket &Packet, CBu int CXlxProtocol::GetConnectingPeerProtocolRevision(const CCallsign &Callsign, const CVersion &Version) { int protrev; - + // BM ? if ( Callsign.HasSameCallsignWithWildcard(CCallsign("BM*")) ) { @@ -743,7 +743,7 @@ int CXlxProtocol::GetConnectingPeerProtocolRevision(const CCallsign &Callsign, c { protrev = CXlxPeer::GetProtocolRevision(Version); } - + // done return protrev; } @@ -751,7 +751,7 @@ int CXlxProtocol::GetConnectingPeerProtocolRevision(const CCallsign &Callsign, c CPeer *CXlxProtocol::CreateNewPeer(const CCallsign &Callsign, const CIp &Ip, char *Modules, const CVersion &Version) { CPeer *peer = NULL; - + // BM ? if ( Callsign.HasSameCallsignWithWildcard(CCallsign("BM*")) ) { @@ -761,8 +761,7 @@ CPeer *CXlxProtocol::CreateNewPeer(const CCallsign &Callsign, const CIp &Ip, cha { peer = new CXlxPeer(Callsign, Ip, Modules, Version); } - + // done return peer; } - diff --git a/src/main.h b/src/main.h index e453d21..4b6b01c 100644 --- a/src/main.h +++ b/src/main.h @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -54,17 +55,21 @@ // global ------------------------------------------------------ #define RUN_AS_DAEMON -#define JSON_MONITOR +//#define JSON_MONITOR // debug ------------------------------------------------------- //#define DEBUG_NO_ERROR_ON_XML_OPEN_FAIL //#define DEBUG_DUMPFILE +// system constants --------------------------------------------- + +#define NB_MODULES_MAX 26 + // reflector --------------------------------------------------- -#define NB_OF_MODULES 10 -//#define NB_OF_MODULES NB_MODULES_MAX +//#define NB_OF_MODULES 10 +#define NB_OF_MODULES NB_MODULES_MAX // protocols --------------------------------------------------- @@ -176,10 +181,6 @@ #define TERMINALOPTIONS_PATH "/xlxd/xlxd.terminal" #define DEBUGDUMP_PATH "/var/log/xlxd.debug" -// system constants --------------------------------------------- - -#define NB_MODULES_MAX 26 - //////////////////////////////////////////////////////////////////////////////////////// // typedefs