diff --git a/src/ccodecstream.cpp b/src/ccodecstream.cpp
index 2a6e1dc..cd4c224 100644
--- a/src/ccodecstream.cpp
+++ b/src/ccodecstream.cpp
@@ -89,31 +89,32 @@ CCodecStream::~CCodecStream()
bool CCodecStream::Init(uint16 uiPort)
{
- bool ok;
-
// reset stop flag
- m_bStopThread = false;
+ m_bConnected = m_bStopThread = false;
// create server's IP
- m_Ip = g_Reflector.GetTranscoderIp();
m_uiPort = uiPort;
+ auto s = g_Reflector.GetTranscoderIp();
+ m_Ip.Initialize(strchr(s, ':') ? AF_INET6 : AF_INET, m_uiPort, s);
// create our socket
- ok = m_Socket.Open(uiPort);
- if ( ok )
- {
- // start thread;
- m_pThread = new std::thread(CCodecStream::Thread, this);
- m_bConnected = true;
- }
- else
- {
- std::cout << "Error opening socket on port UDP" << uiPort << " on ip " << g_Reflector.GetListenIp() << std::endl;
- m_bConnected = false;
- }
-
- // done
- return ok;
+ if (m_Ip.IsSet())
+ {
+ if (! m_Socket.Open(m_Ip)) {
+ std::cerr << "Error opening socket on port UDP" << uiPort << " on ip " << m_Ip << std::endl;
+ return false;
+ }
+ }
+ else
+ {
+ std::cerr << "Could not initialize Codec Stream on " << m_Ip << std::endl;
+ return false;
+ }
+
+ m_pThread = new std::thread(CCodecStream::Thread, this);
+ m_bConnected = true;
+
+ return true;
}
void CCodecStream::Close(void)
diff --git a/src/cdcsprotocol.cpp b/src/cdcsprotocol.cpp
index 536e0a2..b275a83 100644
--- a/src/cdcsprotocol.cpp
+++ b/src/cdcsprotocol.cpp
@@ -35,26 +35,15 @@
bool CDcsProtocol::Init(void)
{
- bool ok;
-
// base class
- ok = CProtocol::Init();
-
- // update the reflector callsign
- m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"DCS", 3);
-
- // create our socket
- ok &= m_Socket.Open(DCS_PORT);
- if ( !ok )
- {
- std::cout << "Error opening socket on port UDP" << DCS_PORT << " on ip " << g_Reflector.GetListenIp() << std::endl;
- }
+ if (! Initialize("DCS", DCS_PORT))
+ return false;
// update time
m_LastKeepaliveTime.Now();
// done
- return ok;
+ return true;
}
@@ -72,7 +61,7 @@ void CDcsProtocol::Task(void)
CDvFramePacket *Frame;
// handle incoming packets
- if ( m_Socket.Receive(Buffer, Ip, 20) )
+ if ( m_Socket6.Receive(Buffer, Ip, 10) || m_Socket4.Receive(Buffer, Ip, 10) )
{
// crack the packet
if ( IsValidDvPacket(Buffer, &Header, &Frame) )
@@ -114,7 +103,7 @@ void CDcsProtocol::Task(void)
{
// acknowledge the request
EncodeConnectAckPacket(Callsign, ToLinkModule, &Buffer);
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
// create the client
CDcsClient *client = new CDcsClient(Callsign, Ip, ToLinkModule);
@@ -129,14 +118,14 @@ void CDcsProtocol::Task(void)
// deny the request
EncodeConnectNackPacket(Callsign, ToLinkModule, &Buffer);
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
}
}
else
{
// deny the request
EncodeConnectNackPacket(Callsign, ToLinkModule, &Buffer);
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
}
}
@@ -153,7 +142,7 @@ void CDcsProtocol::Task(void)
clients->RemoveClient(client);
// and acknowledge the disconnect
EncodeConnectNackPacket(Callsign, ' ', &Buffer);
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
}
g_Reflector.ReleaseClients();
}
@@ -310,7 +299,7 @@ void CDcsProtocol::HandleQueue(void)
if ( !client->IsAMaster() && (client->GetReflectorModule() == packet->GetModuleId()) )
{
// no, send the packet
- m_Socket.Send(buffer, client->GetIp());
+ Send(buffer, client->GetIp());
}
}
@@ -346,8 +335,8 @@ void CDcsProtocol::HandleKeepalives(void)
EncodeKeepAlivePacket(&keepalive2, client);
// send keepalive
- m_Socket.Send(keepalive1, client->GetIp());
- m_Socket.Send(keepalive2, client->GetIp());
+ Send(keepalive1, client->GetIp());
+ Send(keepalive2, client->GetIp());
// is this client busy ?
if ( client->IsAMaster() )
@@ -361,7 +350,7 @@ void CDcsProtocol::HandleKeepalives(void)
// no, disconnect
CBuffer disconnect;
EncodeDisconnectPacket(&disconnect, client);
- m_Socket.Send(disconnect, client->GetIp());
+ Send(disconnect, client->GetIp());
// remove it
std::cout << "DCS client " << client->GetCallsign() << " keepalive timeout" << std::endl;
diff --git a/src/cdcsprotocol.h b/src/cdcsprotocol.h
index b455dc2..36501ff 100644
--- a/src/cdcsprotocol.h
+++ b/src/cdcsprotocol.h
@@ -19,7 +19,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 .
// ----------------------------------------------------------------------------
#ifndef cdcsprotocol_h
@@ -42,7 +42,7 @@ class CDcsStreamCacheItem
public:
CDcsStreamCacheItem() { m_iSeqCounter = 0; }
~CDcsStreamCacheItem() {}
-
+
CDvHeaderPacket m_dvHeader;
uint32 m_iSeqCounter;
};
@@ -50,35 +50,29 @@ public:
class CDcsProtocol : public CProtocol
{
public:
- // constructor
- CDcsProtocol() {};
-
- // destructor
- virtual ~CDcsProtocol() {};
-
// initialization
bool Init(void);
-
+
// task
void Task(void);
-
+
protected:
// queue helper
void HandleQueue(void);
-
+
// keepalive helpers
void HandleKeepalives(void);
-
+
// stream helpers
bool OnDvHeaderPacketIn(CDvHeaderPacket *, const CIp &);
-
+
// packet decoding helpers
bool IsValidConnectPacket(const CBuffer &, CCallsign *, char *);
bool IsValidDisconnectPacket(const CBuffer &, CCallsign *);
bool IsValidKeepAlivePacket(const CBuffer &, CCallsign *);
bool IsValidDvPacket(const CBuffer &, CDvHeaderPacket **, CDvFramePacket **);
bool IsIgnorePacket(const CBuffer &);
-
+
// packet encoding helpers
void EncodeKeepAlivePacket(CBuffer *);
void EncodeKeepAlivePacket(CBuffer *, CClient *);
@@ -87,11 +81,11 @@ protected:
void EncodeDisconnectPacket(CBuffer *, CClient *);
void EncodeDvPacket(const CDvHeaderPacket &, const CDvFramePacket &, uint32, CBuffer *) const;
void EncodeDvLastPacket(const CDvHeaderPacket &, const CDvFramePacket &, uint32, CBuffer *) const;
-
+
protected:
// for keep alive
CTimePoint m_LastKeepaliveTime;
-
+
// for queue header caches
std::array m_StreamsCache;
};
diff --git a/src/cdextraprotocol.cpp b/src/cdextraprotocol.cpp
index 568f7cb..07bf6d6 100644
--- a/src/cdextraprotocol.cpp
+++ b/src/cdextraprotocol.cpp
@@ -37,27 +37,16 @@
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;
- }
+ if (! Initialize("XRF", DEXTRA_PORT))
+ return false;
// update time
m_LastKeepaliveTime.Now();
m_LastPeersLinkTime.Now();
// done
- return ok;
+ return true;
}
////////////////////////////////////////////////////////////////////////////////////////
@@ -75,7 +64,7 @@ void CDextraProtocol::Task(void)
CDvLastFramePacket *LastFrame;
// any incoming packet ?
- if ( m_Socket.Receive(Buffer, Ip, 20) )
+ if ( m_Socket6.Receive(Buffer, Ip, 10) || m_Socket4.Receive(Buffer, Ip, 10) )
{
// crack the packet
if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL )
@@ -143,7 +132,7 @@ void CDextraProtocol::Task(void)
{
// acknowledge the request
EncodeConnectAckPacket(&Buffer, ProtRev);
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
// create the client
CDextraClient *client = new CDextraClient(Callsign, Ip, ToLinkModule, ProtRev);
@@ -160,14 +149,14 @@ void CDextraProtocol::Task(void)
// deny the request
EncodeConnectNackPacket(&Buffer);
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
}
}
else
{
// deny the request
EncodeConnectNackPacket(&Buffer);
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
}
}
else if ( IsValidDisconnectPacket(Buffer, &Callsign) )
@@ -183,11 +172,11 @@ void CDextraProtocol::Task(void)
if ( client->GetProtocolRevision() == 1 )
{
EncodeDisconnectedPacket(&Buffer);
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
}
else if ( client->GetProtocolRevision() == 2 )
{
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
}
// and remove it
clients->RemoveClient(client);
@@ -271,7 +260,7 @@ void CDextraProtocol::HandleQueue(void)
int n = packet->IsDvHeader() ? 5 : 1;
for ( int i = 0; i < n; i++ )
{
- m_Socket.Send(buffer, client->GetIp());
+ Send(buffer, client->GetIp());
}
}
}
@@ -303,7 +292,7 @@ void CDextraProtocol::HandleKeepalives(void)
while ( (client = clients->FindNextClient(PROTOCOL_DEXTRA, it)) != NULL )
{
// send keepalive
- m_Socket.Send(keepalive, client->GetIp());
+ Send(keepalive, client->GetIp());
// client busy ?
if ( client->IsAMaster() )
@@ -325,7 +314,7 @@ void CDextraProtocol::HandleKeepalives(void)
// no, disconnect
CBuffer disconnect;
EncodeDisconnectPacket(&disconnect, client->GetReflectorModule());
- m_Socket.Send(disconnect, client->GetIp());
+ Send(disconnect, client->GetIp());
// remove it
std::cout << "DExtra client " << client->GetCallsign() << " keepalive timeout" << std::endl;
@@ -354,7 +343,7 @@ void CDextraProtocol::HandleKeepalives(void)
CClients *clients = g_Reflector.GetClients();
for ( auto cit=peer->cbegin(); cit!=peer->cend(); cit++ )
{
- m_Socket.Send(disconnect, (*cit)->GetIp());
+ Send(disconnect, (*cit)->GetIp());
}
g_Reflector.ReleaseClients();
@@ -387,7 +376,7 @@ void CDextraProtocol::HandlePeerLinks(void)
{
// send disconnect packet
EncodeDisconnectPacket(&buffer, peer->GetReflectorModules()[0]);
- m_Socket.Send(buffer, peer->GetIp());
+ Send(buffer, peer->GetIp());
std::cout << "Sending disconnect packet to XRF peer " << peer->GetCallsign() << std::endl;
// remove client
peers->RemovePeer(peer);
@@ -408,7 +397,7 @@ void CDextraProtocol::HandlePeerLinks(void)
(*it).ResolveIp();
// send connect packet to re-initiate peer link
EncodeConnectPacket(&buffer, (*it).GetModules());
- m_Socket.Send(buffer, (*it).GetIp(), DEXTRA_PORT);
+ 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;
}
}
diff --git a/src/cdextraprotocol.h b/src/cdextraprotocol.h
index 4512295..ab4889f 100644
--- a/src/cdextraprotocol.h
+++ b/src/cdextraprotocol.h
@@ -19,7 +19,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 .
// ----------------------------------------------------------------------------
#ifndef cdextraprotocol_h
@@ -58,15 +58,9 @@
class CDextraProtocol : public CProtocol
{
public:
- // constructor
- CDextraProtocol() {};
-
- // destructor
- virtual ~CDextraProtocol() {};
-
// initialization
bool Init(void);
-
+
// task
void Task(void);
@@ -80,7 +74,7 @@ protected:
// stream helpers
bool OnDvHeaderPacketIn(CDvHeaderPacket *, const CIp &);
-
+
// packet decoding helpers
bool IsValidConnectPacket(const CBuffer &, CCallsign *, char *, int *);
bool IsValidDisconnectPacket(const CBuffer &, CCallsign *);
@@ -88,7 +82,7 @@ protected:
CDvHeaderPacket *IsValidDvHeaderPacket(const CBuffer &);
CDvFramePacket *IsValidDvFramePacket(const CBuffer &);
CDvLastFramePacket *IsValidDvLastFramePacket(const CBuffer &);
-
+
// packet encoding helpers
void EncodeKeepAlivePacket(CBuffer *);
void EncodeConnectPacket(CBuffer *, const char *);
@@ -99,7 +93,7 @@ protected:
bool EncodeDvHeaderPacket(const CDvHeaderPacket &, CBuffer *) const;
bool EncodeDvFramePacket(const CDvFramePacket &, CBuffer *) const;
bool EncodeDvLastFramePacket(const CDvLastFramePacket &, CBuffer *) const;
-
+
protected:
// time
CTimePoint m_LastKeepaliveTime;
diff --git a/src/cdmrmmdvmprotocol.cpp b/src/cdmrmmdvmprotocol.cpp
index 8e05bb2..4bb646d 100644
--- a/src/cdmrmmdvmprotocol.cpp
+++ b/src/cdmrmmdvmprotocol.cpp
@@ -56,16 +56,9 @@ static uint8 g_DmrSyncMSData[] = { 0x0D,0x5D,0x7F,0x77,0xFD,0x75,0x70 };
bool CDmrmmdvmProtocol::Init(void)
{
- bool ok;
-
// base class
- ok = CProtocol::Init();
-
- // update the reflector callsign
- //m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"DMR", 3);
-
- // create our socket
- ok &= m_Socket.Open(DMRMMDVM_PORT);
+ if (! Initialize(NULL, DMRMMDVM_PORT))
+ return false;
// update time
m_LastKeepaliveTime.Now();
@@ -76,7 +69,7 @@ bool CDmrmmdvmProtocol::Init(void)
m_uiAuthSeed = (uint32)rand();
// done
- return ok;
+ return true;
}
@@ -97,7 +90,7 @@ void CDmrmmdvmProtocol::Task(void)
CDvLastFramePacket *LastFrame;
// handle incoming packets
- if ( m_Socket.Receive(Buffer, Ip, 20) )
+ if ( m_Socket6.Receive(Buffer, Ip, 10) || m_Socket6.Receive(Buffer, Ip, 10) )
{
//Buffer.DebugDump(g_Reflector.m_DebugFile);
// crack the packet
@@ -141,13 +134,13 @@ void CDmrmmdvmProtocol::Task(void)
{
// acknowledge the request
EncodeConnectAckPacket(&Buffer, Callsign, m_uiAuthSeed);
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
}
else
{
// deny the request
EncodeNackPacket(&Buffer, Callsign);
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
}
}
@@ -160,7 +153,7 @@ void CDmrmmdvmProtocol::Task(void)
{
// acknowledge the request
EncodeAckPacket(&Buffer, Callsign);
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
// add client if needed
CClients *clients = g_Reflector.GetClients();
@@ -187,7 +180,7 @@ void CDmrmmdvmProtocol::Task(void)
{
// deny the request
EncodeNackPacket(&Buffer, Callsign);
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
}
}
@@ -210,7 +203,7 @@ void CDmrmmdvmProtocol::Task(void)
// acknowledge the request
EncodeAckPacket(&Buffer, Callsign);
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
}
else if ( IsValidKeepAlivePacket(Buffer, &Callsign) )
{
@@ -224,7 +217,7 @@ void CDmrmmdvmProtocol::Task(void)
{
// acknowledge
EncodeKeepAlivePacket(&Buffer, client);
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
// and mark as alive
client->Alive();
@@ -243,7 +236,7 @@ void CDmrmmdvmProtocol::Task(void)
// acknowledge the request
EncodeAckPacket(&Buffer, Callsign);
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
}
else if ( Buffer.size() != 55 )
{
@@ -450,7 +443,7 @@ void CDmrmmdvmProtocol::HandleQueue(void)
if ( !client->IsAMaster() && (client->GetReflectorModule() == packet->GetModuleId()) )
{
// no, send the packet
- m_Socket.Send(buffer, client->GetIp());
+ Send(buffer, client->GetIp());
}
}
@@ -489,7 +482,7 @@ void CDmrmmdvmProtocol::HandleKeepalives(void)
{
// no, disconnect
CBuffer disconnect;
- m_Socket.Send(disconnect, client->GetIp());
+ Send(disconnect, client->GetIp());
// remove it
std::cout << "DMRmmdvm client " << client->GetCallsign() << " keepalive timeout" << std::endl;
diff --git a/src/cdmrmmdvmprotocol.h b/src/cdmrmmdvmprotocol.h
index 54e34b6..0155b9a 100644
--- a/src/cdmrmmdvmprotocol.h
+++ b/src/cdmrmmdvmprotocol.h
@@ -54,11 +54,11 @@ class CDmrmmdvmStreamCacheItem
public:
CDmrmmdvmStreamCacheItem() {}
~CDmrmmdvmStreamCacheItem() {}
-
+
CDvHeaderPacket m_dvHeader;
CDvFramePacket m_dvFrame0;
CDvFramePacket m_dvFrame1;
-
+
uint8 m_uiSeqId;
};
@@ -66,28 +66,22 @@ public:
class CDmrmmdvmProtocol : public CProtocol
{
public:
- // constructor
- CDmrmmdvmProtocol() {};
-
- // destructor
- virtual ~CDmrmmdvmProtocol() {};
-
// initialization
bool Init(void);
-
+
// task
void Task(void);
-
+
protected:
// queue helper
void HandleQueue(void);
-
+
// keepalive helpers
void HandleKeepalives(void);
-
+
// stream helpers
bool OnDvHeaderPacketIn(CDvHeaderPacket *, const CIp &, uint8, uint8);
-
+
// packet decoding helpers
bool IsValidConnectPacket(const CBuffer &, CCallsign *, const CIp &);
bool IsValidAuthenticationPacket(const CBuffer &, CCallsign *, const CIp &);
@@ -99,7 +93,7 @@ protected:
bool IsValidDvHeaderPacket(const CBuffer &, CDvHeaderPacket **, uint8 *, uint8 *);
bool IsValidDvFramePacket(const CBuffer &, CDvFramePacket **);
bool IsValidDvLastFramePacket(const CBuffer &, CDvLastFramePacket **);
-
+
// packet encoding helpers
void EncodeKeepAlivePacket(CBuffer *, CClient *);
void EncodeAckPacket(CBuffer *, const CCallsign &);
@@ -109,11 +103,11 @@ protected:
bool EncodeDvHeaderPacket(const CDvHeaderPacket &, uint8, CBuffer *) const;
void EncodeDvPacket(const CDvHeaderPacket &, const CDvFramePacket &, const CDvFramePacket &, const CDvFramePacket &, uint8, CBuffer *) const;
void EncodeDvLastPacket(const CDvHeaderPacket &, uint8, CBuffer *) const;
-
+
// dmr DstId to Module helper
char DmrDstIdToModule(uint32) const;
uint32 ModuleToDmrDestId(char) const;
-
+
// Buffer & LC helpers
void AppendVoiceLCToBuffer(CBuffer *, uint32) const;
void AppendTerminatorLCToBuffer(CBuffer *, uint32) const;
@@ -125,13 +119,13 @@ protected:
protected:
// for keep alive
CTimePoint m_LastKeepaliveTime;
-
+
// for stream id
uint16 m_uiStreamId;
-
+
// for queue header caches
std::array m_StreamsCache;
-
+
// for authentication
uint32 m_uiAuthSeed;
};
diff --git a/src/cdmrplusprotocol.cpp b/src/cdmrplusprotocol.cpp
index 2323732..c0a246f 100644
--- a/src/cdmrplusprotocol.cpp
+++ b/src/cdmrplusprotocol.cpp
@@ -47,18 +47,11 @@ static uint8 g_DmrSyncMSData[] = { 0x0D,0x5D,0x7F,0x77,0xFD,0x75,0x70 };
////////////////////////////////////////////////////////////////////////////////////////
// operation
-bool CDmrplusProtocol::Init(void)
+bool CDmrplusProtocol::Init()
{
- bool ok;
-
// base class
- ok = CProtocol::Init();
-
- // update the reflector callsign
- //m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"DMR", 3);
-
- // create our socket
- ok &= m_Socket.Open(DMRPLUS_PORT);
+ if (! Initialize(NULL, DMRPLUS_PORT))
+ return false;
// update time
m_LastKeepaliveTime.Now();
@@ -68,7 +61,7 @@ bool CDmrplusProtocol::Init(void)
::srand((unsigned) time(&t));
// done
- return ok;
+ return true;
}
@@ -86,7 +79,7 @@ void CDmrplusProtocol::Task(void)
CDvFramePacket *Frames[3];
// handle incoming packets
- if ( m_Socket.Receive(Buffer, Ip, 20) )
+ if ( m_Socket6.Receive(Buffer, Ip, 10) && m_Socket4.Receive(Buffer, Ip, 10) )
{
// crack the packet
if ( IsValidDvFramePacket(Ip, Buffer, Frames) )
@@ -135,7 +128,7 @@ void CDmrplusProtocol::Task(void)
{
// acknowledge the request
EncodeConnectAckPacket(&Buffer);
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
// add client if needed
CClients *clients = g_Reflector.GetClients();
@@ -162,7 +155,7 @@ void CDmrplusProtocol::Task(void)
{
// deny the request
EncodeConnectNackPacket(&Buffer);
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
}
}
@@ -324,7 +317,7 @@ void CDmrplusProtocol::HandleQueue(void)
if ( !client->IsAMaster() && (client->GetReflectorModule() == packet->GetModuleId()) )
{
// no, send the packet
- m_Socket.Send(buffer, client->GetIp());
+ Send(buffer, client->GetIp());
}
}
g_Reflector.ReleaseClients();
@@ -353,7 +346,7 @@ void CDmrplusProtocol::SendBufferToClients(const CBuffer &buffer, uint8 module)
if ( !client->IsAMaster() && (client->GetReflectorModule() == module) )
{
// no, send the packet
- m_Socket.Send(buffer, client->GetIp());
+ Send(buffer, client->GetIp());
}
}
g_Reflector.ReleaseClients();
@@ -391,7 +384,7 @@ void CDmrplusProtocol::HandleKeepalives(void)
// no, disconnect
//CBuffer disconnect;
//EncodeDisconnectPacket(&disconnect, client);
- //m_Socket.Send(disconnect, client->GetIp());
+ //Send(disconnect, client->GetIp());
// remove it
std::cout << "DMRplus client " << client->GetCallsign() << " keepalive timeout" << std::endl;
diff --git a/src/cdmrplusprotocol.h b/src/cdmrplusprotocol.h
index e9d4c1e..5c02ba0 100644
--- a/src/cdmrplusprotocol.h
+++ b/src/cdmrplusprotocol.h
@@ -44,12 +44,11 @@ class CDmrplusStreamCacheItem
{
public:
CDmrplusStreamCacheItem() { m_uiSeqId = 0x77; }
- ~CDmrplusStreamCacheItem() {}
-
+
CDvHeaderPacket m_dvHeader;
CDvFramePacket m_dvFrame0;
CDvFramePacket m_dvFrame1;
-
+
uint8 m_uiSeqId;
};
@@ -57,35 +56,29 @@ public:
class CDmrplusProtocol : public CProtocol
{
public:
- // constructor
- CDmrplusProtocol() {};
-
- // destructor
- virtual ~CDmrplusProtocol() {};
-
// initialization
- bool Init(void);
-
+ bool Init();
+
// task
void Task(void);
-
+
protected:
// queue helper
void HandleQueue(void);
void SendBufferToClients(const CBuffer &, uint8);
-
+
// keepalive helpers
void HandleKeepalives(void);
-
+
// stream helpers
bool OnDvHeaderPacketIn(CDvHeaderPacket *, const CIp &);
-
+
// packet decoding helpers
bool IsValidConnectPacket(const CBuffer &, CCallsign *, char *, const CIp &);
bool IsValidDisconnectPacket(const CBuffer &, CCallsign *, char *);
bool IsValidDvHeaderPacket(const CIp &, const CBuffer &, CDvHeaderPacket **);
bool IsValidDvFramePacket(const CIp &, const CBuffer &, CDvFramePacket **);
-
+
// packet encoding helpers
void EncodeConnectAckPacket(CBuffer *);
void EncodeConnectNackPacket(CBuffer *);
@@ -93,27 +86,27 @@ protected:
void EncodeDvPacket(const CDvHeaderPacket &, const CDvFramePacket &, const CDvFramePacket &, const CDvFramePacket &, uint8, CBuffer *) const;
void EncodeDvLastPacket(const CDvHeaderPacket &, const CDvFramePacket &, const CDvFramePacket &, const CDvFramePacket &, uint8, CBuffer *) const;
void SwapEndianess(uint8 *, int) const;
-
+
// dmr SeqId helper
uint8 GetNextSeqId(uint8) const;
-
+
// dmr DstId to Module helper
char DmrDstIdToModule(uint32) const;
uint32 ModuleToDmrDestId(char) const;
-
+
// uiStreamId helpers
uint32 IpToStreamId(const CIp &) const;
-
+
// Buffer & LC helpers
void AppendVoiceLCToBuffer(CBuffer *, uint32) const;
void AppendTerminatorLCToBuffer(CBuffer *, uint32) const;
void ReplaceEMBInBuffer(CBuffer *, uint8) const;
-
+
protected:
// for keep alive
CTimePoint m_LastKeepaliveTime;
-
+
// for queue header caches
std::array m_StreamsCache;
};
diff --git a/src/cdplusprotocol.cpp b/src/cdplusprotocol.cpp
index 7d59c41..7cafc3c 100644
--- a/src/cdplusprotocol.cpp
+++ b/src/cdplusprotocol.cpp
@@ -36,26 +36,15 @@
bool CDplusProtocol::Init(void)
{
- bool ok;
-
// base class
- ok = CProtocol::Init();
-
- // update the reflector callsign
- m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"REF", 3);
-
- // create our socket
- ok &= m_Socket.Open(DPLUS_PORT);
- if ( !ok )
- {
- std::cout << "Error opening socket on port UDP" << DPLUS_PORT << " on ip " << g_Reflector.GetListenIp() << std::endl;
- }
+ if (Initialize("REF", DPLUS_PORT))
+ return false;
// update time
m_LastKeepaliveTime.Now();
// done
- return ok;
+ return true;
}
@@ -73,7 +62,7 @@ void CDplusProtocol::Task(void)
CDvLastFramePacket *LastFrame;
// handle incoming packets
- if ( m_Socket.Receive(Buffer, Ip, 20) )
+ if ( m_Socket6.Receive(Buffer, Ip, 10) && m_Socket4.Receive(Buffer, Ip, 10) )
{
// crack the packet
if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL )
@@ -110,7 +99,7 @@ void CDplusProtocol::Task(void)
std::cout << "DPlus connect request packet from " << Ip << std::endl;
// acknowledge the request
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
}
else if ( IsValidLoginPacket(Buffer, &Callsign) )
{
@@ -121,7 +110,7 @@ void CDplusProtocol::Task(void)
{
// acknowledge the request
EncodeLoginAckPacket(&Buffer);
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
// create the client
CDplusClient *client = new CDplusClient(Callsign, Ip);
@@ -134,7 +123,7 @@ void CDplusProtocol::Task(void)
{
// deny the request
EncodeLoginNackPacket(&Buffer);
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
}
}
@@ -151,7 +140,7 @@ void CDplusProtocol::Task(void)
clients->RemoveClient(client);
// and acknowledge the disconnect
EncodeDisconnectPacket(&Buffer);
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
}
g_Reflector.ReleaseClients();
}
@@ -313,7 +302,7 @@ void CDplusProtocol::HandleQueue(void)
else if ( packet->IsDvFrame() )
{
// and send the DV frame
- m_Socket.Send(buffer, client->GetIp());
+ Send(buffer, client->GetIp());
// is it time to insert a DVheader copy ?
if ( (m_StreamsCache[iModId].m_iSeqCounter++ % 21) == 20 )
@@ -327,7 +316,7 @@ void CDplusProtocol::HandleQueue(void)
else
{
// otherwise, send the original packet
- m_Socket.Send(buffer, client->GetIp());
+ Send(buffer, client->GetIp());
}
}
}
@@ -360,20 +349,20 @@ void CDplusProtocol::SendDvHeader(CDvHeaderPacket *packet, CDplusClient *client)
if ( EncodeDvPacket(packet2, &buffer2) )
{
// and send it
- m_Socket.Send(buffer2, client->GetIp());
+ Send(buffer2, client->GetIp());
}
// client type known ?
if ( !client->HasModule() )
{
// no, send also the genuine packet
- m_Socket.Send(buffer, client->GetIp());
+ Send(buffer, client->GetIp());
}
}
else
{
// otherwise, send the original packet
- m_Socket.Send(buffer, client->GetIp());
+ Send(buffer, client->GetIp());
}
}
}
@@ -395,7 +384,7 @@ void CDplusProtocol::HandleKeepalives(void)
{
// send keepalive
//std::cout << "Sending DPlus packet @ " << client->GetIp() << std::endl;
- m_Socket.Send(keepalive, client->GetIp());
+ Send(keepalive, client->GetIp());
// is this client busy ?
if ( client->IsAMaster() )
@@ -409,7 +398,7 @@ void CDplusProtocol::HandleKeepalives(void)
// no, disconnect
CBuffer disconnect;
EncodeDisconnectPacket(&disconnect);
- m_Socket.Send(disconnect, client->GetIp());
+ Send(disconnect, client->GetIp());
// and remove it
std::cout << "DPlus client " << client->GetCallsign() << " keepalive timeout" << std::endl;
diff --git a/src/cdplusprotocol.h b/src/cdplusprotocol.h
index 80bf1be..bdbf45f 100644
--- a/src/cdplusprotocol.h
+++ b/src/cdplusprotocol.h
@@ -19,7 +19,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 .
// ----------------------------------------------------------------------------
#ifndef cdplusprotocol_h
@@ -43,8 +43,7 @@ class CDPlusStreamCacheItem
{
public:
CDPlusStreamCacheItem() { m_iSeqCounter = 0; }
- ~CDPlusStreamCacheItem() {}
-
+
CDvHeaderPacket m_dvHeader;
uint8 m_iSeqCounter;
};
@@ -52,12 +51,6 @@ public:
class CDplusProtocol : public CProtocol
{
public:
- // constructor
- CDplusProtocol() {};
-
- // destructor
- virtual ~CDplusProtocol() {};
-
// initialization
bool Init(void);
@@ -68,13 +61,13 @@ protected:
// queue helper
void HandleQueue(void);
void SendDvHeader(CDvHeaderPacket *, CDplusClient *);
-
+
// keepalive helpers
void HandleKeepalives(void);
-
+
// stream helpers
bool OnDvHeaderPacketIn(CDvHeaderPacket *, const CIp &);
-
+
// packet decoding helpers
bool IsValidConnectPacket(const CBuffer &);
bool IsValidLoginPacket(const CBuffer &, CCallsign *);
@@ -83,7 +76,7 @@ protected:
CDvHeaderPacket *IsValidDvHeaderPacket(const CBuffer &);
CDvFramePacket *IsValidDvFramePacket(const CBuffer &);
CDvLastFramePacket *IsValidDvLastFramePacket(const CBuffer &);
-
+
// packet encoding helpers
void EncodeKeepAlivePacket(CBuffer *);
void EncodeLoginAckPacket(CBuffer *);
@@ -93,11 +86,11 @@ protected:
bool EncodeDvFramePacket(const CDvFramePacket &, CBuffer *) const;
bool EncodeDvLastFramePacket(const CDvLastFramePacket &, CBuffer *) const;
-
+
protected:
// for keep alive
CTimePoint m_LastKeepaliveTime;
-
+
// for queue header caches
std::array m_StreamsCache;
};
diff --git a/src/cg3protocol.cpp b/src/cg3protocol.cpp
index 6f75be3..68ef97f 100644
--- a/src/cg3protocol.cpp
+++ b/src/cg3protocol.cpp
@@ -40,55 +40,58 @@
bool CG3Protocol::Init(void)
{
- bool ok;
-
ReadOptions();
- // base class
- ok = CProtocol::Init();
-
- // update reflector callsign
- m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"XLX", 3);
-
- // create our DV socket
- ok &= m_Socket.Open(G3_DV_PORT);
- if ( !ok )
- {
- std::cout << "Error opening socket on port UDP" << G3_DV_PORT << " on ip " << g_Reflector.GetListenIp() << std::endl;
- }
-
- //create helper sockets
- ok &= m_PresenceSocket.Open(G3_PRESENCE_PORT);
- if ( !ok )
- {
- std::cout << "Error opening socket on port UDP" << G3_PRESENCE_PORT << " on ip " << g_Reflector.GetListenIp() << std::endl;
+ // init reflector apparent callsign
+ m_ReflectorCallsign = g_Reflector.GetCallsign();
+
+ // reset stop flag
+ m_bStopThread = false;
+
+ // update the reflector callsign
+ m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"XLX", 3);
+
+ // create our sockets
+ CIp ip(AF_INET, G3_DV_PORT, g_Reflector.GetListenIPv4());
+ if ( ip.IsSet() )
+ {
+ if (! m_Socket4.Open(ip))
+ return false;
+ }
+ else
+ return false;
+
+ //create helper socket
+ ip.SetPort(G3_PRESENCE_PORT);
+ if (! m_PresenceSocket.Open(ip)) {
+ std::cout << "Error opening socket on port UDP" << G3_PRESENCE_PORT << " on ip " << ip << std::endl;
+ return false;
}
- ok &= m_ConfigSocket.Open(G3_CONFIG_PORT);
- if ( !ok )
- {
- std::cout << "Error opening socket on port UDP" << G3_CONFIG_PORT << " on ip " << g_Reflector.GetListenIp() << std::endl;
- }
+ ip.SetPort(G3_CONFIG_PORT);
+ if (! m_ConfigSocket.Open(ip))
+ {
+ std::cout << "Error opening G3 config socket on port UDP" << G3_CONFIG_PORT << " on ip " << ip << std::endl;
+ return false;
+ }
- ok &= m_IcmpRawSocket.Open(IPPROTO_ICMP);
- if ( !ok )
+ if (! m_IcmpRawSocket.Open(IPPROTO_ICMP))
{
std::cout << "Error opening raw socket for ICMP" << std::endl;
+ return false;
}
- if (ok)
- {
- // start helper threads
- m_pPresenceThread = new std::thread(PresenceThread, this);
- m_pPresenceThread = new std::thread(ConfigThread, this);
- m_pPresenceThread = new std::thread(IcmpThread, this);
- }
+ // start helper threads
+ m_pThread = new std::thread(CProtocol::Thread, this);
+ m_pPresenceThread = new std::thread(PresenceThread, this);
+ m_pPresenceThread = new std::thread(ConfigThread, this);
+ m_pPresenceThread = new std::thread(IcmpThread, this);
// update time
m_LastKeepaliveTime.Now();
// done
- return ok;
+ return true;
}
void CG3Protocol::Close(void)
@@ -390,7 +393,7 @@ void CG3Protocol::Task(void)
CDvLastFramePacket *LastFrame;
// any incoming packet ?
- if ( m_Socket.Receive(Buffer, Ip, 20) != -1 )
+ if ( m_Socket4.Receive(Buffer, Ip, 20) )
{
CIp ClIp;
CIp *BaseIp = NULL;
@@ -508,7 +511,7 @@ void CG3Protocol::HandleQueue(void)
int n = packet->IsDvHeader() ? 5 : 1;
for ( int i = 0; i < n; i++ )
{
- m_Socket.Send(buffer, client->GetIp());
+ Send(buffer, client->GetIp());
}
}
}
@@ -544,7 +547,7 @@ void CG3Protocol::HandleKeepalives(void)
else
{
// send keepalive packet
- m_Socket.Send(keepalive, client->GetIp());
+ Send(keepalive, client->GetIp());
}
}
g_Reflector.ReleaseClients();
diff --git a/src/cg3protocol.h b/src/cg3protocol.h
index 5ffdb79..1ae056b 100644
--- a/src/cg3protocol.h
+++ b/src/cg3protocol.h
@@ -19,7 +19,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 .
// ----------------------------------------------------------------------------
#ifndef cg3protocol_h
@@ -64,17 +64,14 @@ class CG3Protocol : public CProtocol
{
public:
// constructor
- CG3Protocol() : m_GwAddress(0u), m_Modules("*"), m_LastModTime(0) {};
-
- // destructor
- virtual ~CG3Protocol() {};
-
+ CG3Protocol() : m_GwAddress(0u), m_Modules("*"), m_LastModTime(0) {}
+
// initialization
bool Init(void);
// close
void Close(void);
-
+
// task
void Task(void);
diff --git a/src/cip.cpp b/src/cip.cpp
index 3c5c2ae..7e17c4f 100644
--- a/src/cip.cpp
+++ b/src/cip.cpp
@@ -22,14 +22,19 @@
#include
#include "cip.h"
-CIp::CIp()
+CIp::CIp() : is_set(false)
{
Clear();
}
-CIp::CIp(const char *address, int family, int type, uint16_t port)
+CIp::CIp(const char *address, int family, int type, uint16_t port) : is_set(true)
{
Clear();
+ if (0 == strncasecmp(address, "none", 4))
+ {
+ is_set = false;
+ return;
+ }
struct addrinfo hints, *result;
bzero(&hints, sizeof(struct addrinfo));
hints.ai_family = family;
@@ -41,7 +46,7 @@ CIp::CIp(const char *address, int family, int type, uint16_t port)
}
SetPort(port);
}
-CIp::CIp(const int family, const uint16_t port, const char *address)
+CIp::CIp(const int family, const uint16_t port, const char *address) : is_set(true)
{
Initialize(family, port, address);
}
@@ -49,50 +54,68 @@ CIp::CIp(const int family, const uint16_t port, const char *address)
void CIp::Initialize(const int family, const uint16_t port, const char *address)
{
Clear();
+ if (0 == strncasecmp(address, "none", 4))
+ {
+ is_set = false;
+ return;
+ }
+ is_set = true;
addr.ss_family = family;
- if (AF_INET == family) {
+ if (AF_INET == family)
+ {
auto addr4 = (struct sockaddr_in *)&addr;
addr4->sin_port = htons(port);
- if (address) {
+ if (address)
+ {
if (0 == strncasecmp(address, "loc", 3))
inet_pton(AF_INET, "127.0.0.1", &(addr4->sin_addr));
else if (0 == strncasecmp(address, "any", 3))
inet_pton(AF_INET, "0.0.0.0", &(addr4->sin_addr));
- else if (0 == strncasecmp(address, "none", 4))
- addr.ss_family = AF_UNSPEC;
- else {
+ else
+ {
if (1 > inet_pton(AF_INET, address, &(addr4->sin_addr)))
std::cerr << "Address Initialization Error: '" << address << "' is not a valdid IPV4 address!" << std::endl;
+ is_set = false;
}
}
- } else if (AF_INET6 == family) {
+ }
+ else if (AF_INET6 == family)
+ {
auto addr6 = (struct sockaddr_in6 *)&addr;
addr6->sin6_port = htons(port);
- if (address) {
+ if (address)
+ {
if (0 == strncasecmp(address, "loc", 3))
inet_pton(AF_INET6, "::1", &(addr6->sin6_addr));
else if (0 == strncasecmp(address, "any", 3))
inet_pton(AF_INET6, "::", &(addr6->sin6_addr));
- else if (0 == strncasecmp(address, "none", 4))
- addr.ss_family = AF_UNSPEC;
- else {
+ else
+ {
if (1 > inet_pton(AF_INET6, address, &(addr6->sin6_addr)))
std::cerr << "Address Initialization Error: '" << address << "' is not a valid IPV6 address!" << std::endl;
+ is_set = false;
}
}
- } else
+ }
+ else
+ {
std::cerr << "Error: Wrong address family type:" << family << " for [" << (address ? address : "NULL") << "]:" << port << std::endl;
+ is_set = false;
+ }
}
bool CIp::operator==(const CIp &rhs) const // doesn't compare ports, only addresses and families
{
if (addr.ss_family != rhs.addr.ss_family)
return false;
- if (AF_INET == addr.ss_family) {
+ if (AF_INET == addr.ss_family)
+ {
auto l = (struct sockaddr_in *)&addr;
auto r = (struct sockaddr_in *)&rhs.addr;
return (l->sin_addr.s_addr == r->sin_addr.s_addr);
- } else if (AF_INET6 == addr.ss_family) {
+ }
+ else if (AF_INET6 == addr.ss_family)
+ {
auto l = (struct sockaddr_in6 *)&addr;
auto r = (struct sockaddr_in6 *)&rhs.addr;
return (0 == memcmp(&(l->sin6_addr), &(r->sin6_addr), sizeof(struct in6_addr)));
@@ -104,11 +127,14 @@ bool CIp::operator!=(const CIp &rhs) const // doesn't compare ports, only addres
{
if (addr.ss_family != rhs.addr.ss_family)
return true;
- if (AF_INET == addr.ss_family) {
+ if (AF_INET == addr.ss_family)
+ {
auto l = (struct sockaddr_in *)&addr;
auto r = (struct sockaddr_in *)&rhs.addr;
return (l->sin_addr.s_addr != r->sin_addr.s_addr);
- } else if (AF_INET6 == addr.ss_family) {
+ }
+ else if (AF_INET6 == addr.ss_family)
+ {
auto l = (struct sockaddr_in6 *)&addr;
auto r = (struct sockaddr_in6 *)&rhs.addr;
return (0 != memcmp(&(l->sin6_addr), &(r->sin6_addr), sizeof(struct in6_addr)));
@@ -118,12 +144,16 @@ bool CIp::operator!=(const CIp &rhs) const // doesn't compare ports, only addres
bool CIp::AddressIsZero() const
{
- if (AF_INET == addr.ss_family) {
- auto addr4 = (struct sockaddr_in *)&addr;
+ if (AF_INET == addr.ss_family)
+ {
+ auto addr4 = (struct sockaddr_in *)&addr;
return (addr4->sin_addr.s_addr == 0U);
- } else {
+ }
+ else
+ {
auto addr6 = (struct sockaddr_in6 *)&addr;
- for (unsigned int i=0; i<16; i++) {
+ for (unsigned int i=0; i<16; i++)
+ {
if (addr6->sin6_addr.s6_addr[i])
return false;
}
@@ -133,11 +163,14 @@ bool CIp::AddressIsZero() const
void CIp::ClearAddress()
{
- if (AF_INET == addr.ss_family) {
+ if (AF_INET == addr.ss_family)
+ {
auto addr4 = (struct sockaddr_in *)&addr;
addr4->sin_addr.s_addr = 0U;
strcpy(straddr, "0.0.0.0");
- } else {
+ }
+ else
+ {
auto addr6 = (struct sockaddr_in6 *)&addr;
memset(&(addr6->sin6_addr.s6_addr), 0, 16);
strcpy(straddr, "::");
@@ -149,13 +182,18 @@ const char *CIp::GetAddress() const
if (straddr[0])
return straddr;
- if (AF_INET == addr.ss_family) {
+ if (AF_INET == addr.ss_family)
+ {
auto addr4 = (struct sockaddr_in *)&addr;
inet_ntop(AF_INET, &(addr4->sin_addr), straddr, INET6_ADDRSTRLEN);
- } else if (AF_INET6 == addr.ss_family) {
+ }
+ else if (AF_INET6 == addr.ss_family)
+ {
auto addr6 = (struct sockaddr_in6 *)&addr;
inet_ntop(AF_INET6, &(addr6->sin6_addr), straddr, INET6_ADDRSTRLEN);
- } else {
+ }
+ else
+ {
std::cerr << "CIp::GetAddress: unknown socket family=" << addr.ss_family << std::endl;
}
return straddr;
@@ -176,12 +214,15 @@ std::ostream &operator<<(std::ostream &stream, const CIp &Ip)
uint32_t CIp::GetAddr() const
{
- if (AF_INET6 == addr.ss_family) {
+ if (AF_INET6 == addr.ss_family)
+ {
auto addr6 = (struct sockaddr_in6 *)&addr;
// hash the results
auto *a = (const uint32_t *)&(addr6->sin6_addr.s6_addr);
return a[0] ^ a[1] ^ a[2] ^ a[3];
- } else {
+ }
+ else
+ {
auto addr4 = (struct sockaddr_in *)&addr;
return addr4->sin_addr.s_addr;
}
@@ -194,10 +235,13 @@ int CIp::GetFamily() const
uint16_t CIp::GetPort() const
{
- if (AF_INET == addr.ss_family) {
+ if (AF_INET == addr.ss_family)
+ {
auto addr4 = (struct sockaddr_in *)&addr;
return ntohs(addr4->sin_port);
- } else if (AF_INET6 == addr.ss_family) {
+ }
+ else if (AF_INET6 == addr.ss_family)
+ {
auto addr6 = (struct sockaddr_in6 *)&addr;
return ntohs(addr6->sin6_port);
} else
@@ -206,10 +250,13 @@ uint16_t CIp::GetPort() const
void CIp::SetPort(const uint16_t newport)
{
- if (AF_INET == addr.ss_family) {
+ if (AF_INET == addr.ss_family)
+ {
auto addr4 = (struct sockaddr_in *)&addr;
addr4->sin_port = htons(newport);
- } else if (AF_INET6 == addr.ss_family) {
+ }
+ else if (AF_INET6 == addr.ss_family)
+ {
auto addr6 = (struct sockaddr_in6 *)&addr;
addr6->sin6_port = htons(newport);
}
@@ -238,4 +285,5 @@ void CIp::Clear()
{
memset(&addr, 0, sizeof(struct sockaddr_storage));
memset(straddr, 0, INET6_ADDRSTRLEN);
+ is_set = false;
}
diff --git a/src/cip.h b/src/cip.h
index 78fc05d..ea969a2 100644
--- a/src/cip.h
+++ b/src/cip.h
@@ -46,6 +46,7 @@ public:
bool operator!=(const CIp &rhs) const;
// state methods
+ bool IsSet() const { return is_set; }
bool AddressIsZero() const;
void ClearAddress();
const char *GetAddress() const;
@@ -68,6 +69,7 @@ public:
private:
struct sockaddr_storage addr;
mutable char straddr[INET6_ADDRSTRLEN];
+ bool is_set;
};
std::ostream &operator<<(std::ostream &stream, const CIp &Ip);
diff --git a/src/cprotocol.cpp b/src/cprotocol.cpp
index 3904b07..968be53 100644
--- a/src/cprotocol.cpp
+++ b/src/cprotocol.cpp
@@ -33,11 +33,7 @@
// constructor
-CProtocol::CProtocol()
-{
- m_bStopThread = false;
- m_pThread = NULL;
-}
+CProtocol::CProtocol() : m_bStopThread(false), m_pThread(NULL) {}
////////////////////////////////////////////////////////////////////////////////////////
@@ -53,6 +49,10 @@ CProtocol::~CProtocol()
delete m_pThread;
}
+ // Close sockets
+ m_Socket6.Close();
+ m_Socket4.Close();
+
// empty queue
m_Queue.Lock();
while ( !m_Queue.empty() )
@@ -65,7 +65,7 @@ CProtocol::~CProtocol()
////////////////////////////////////////////////////////////////////////////////////////
// initialization
-bool CProtocol::Init(void)
+bool CProtocol::Initialize(const char *type, uint16 port)
{
// init reflector apparent callsign
m_ReflectorCallsign = g_Reflector.GetCallsign();
@@ -73,13 +73,49 @@ bool CProtocol::Init(void)
// reset stop flag
m_bStopThread = false;
+ // update the reflector callsign
+ if (type)
+ m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)type, 3);
+
+ // create our sockets
+ CIp ip4(AF_INET, port, g_Reflector.GetListenIPv4());
+ if ( ip4.IsSet() )
+ {
+ if (! m_Socket4.Open(ip4))
+ return false;
+ }
+ CIp ip6(AF_INET6, port, g_Reflector.GetListenIPv6());
+ if ( ip6.IsSet() )
+ {
+ if (! m_Socket6.Open(ip6))
+ {
+ m_Socket4.Close();
+ return false;
+ }
+ }
+
// start thread;
- m_pThread = new std::thread(CProtocol::Thread, this);
+ m_pThread = new std::thread(CProtocol::Thread, this);
+ if (m_pThread == NULL)
+ {
+ std::cerr << "Could not start DCS thread!" << std::endl;
+ m_Socket4.Close();
+ m_Socket6.Close();
+ return false;
+ }
// done
return true;
}
+void CProtocol::Thread(CProtocol *This)
+{
+ while (! This->m_bStopThread)
+ {
+ This->Task();
+ }
+}
+
void CProtocol::Close(void)
{
m_bStopThread = true;
@@ -89,18 +125,8 @@ void CProtocol::Close(void)
delete m_pThread;
m_pThread = NULL;
}
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////
-// thread
-
-void CProtocol::Thread(CProtocol *This)
-{
- while ( !This->m_bStopThread )
- {
- This->Task();
- }
+ m_Socket4.Close();
+ m_Socket6.Close();
}
////////////////////////////////////////////////////////////////////////////////////////
@@ -263,3 +289,66 @@ uint32 CProtocol::ModuleToDmrDestId(char m) const
{
return (uint32)(m - 'A')+1;
}
+
+////////////////////////////////////////////////////////////////////////////////////////
+// dual stack senders
+
+void CProtocol::Send(const CBuffer &buf, const CIp &Ip) const
+{
+ switch (Ip.GetFamily()) {
+ case AF_INET:
+ m_Socket4.Send(buf, Ip);
+ break;
+ case AF_INET6:
+ m_Socket6.Send(buf, Ip);
+ break;
+ default:
+ std::cerr << "Wrong family: " << Ip.GetFamily() << std::endl;
+ break;
+ }
+}
+
+void CProtocol::Send(const char *buf, const CIp &Ip) const
+{
+ switch (Ip.GetFamily()) {
+ case AF_INET:
+ m_Socket4.Send(buf, Ip);
+ break;
+ case AF_INET6:
+ m_Socket6.Send(buf, Ip);
+ break;
+ default:
+ std::cerr << "ERROR: wrong family: " << Ip.GetFamily() << std::endl;
+ break;
+ }
+}
+
+void CProtocol::Send(const CBuffer &buf, const CIp &Ip, uint16_t port) const
+{
+ switch (Ip.GetFamily()) {
+ case AF_INET:
+ m_Socket4.Send(buf, Ip, port);
+ break;
+ case AF_INET6:
+ m_Socket6.Send(buf, Ip, port);
+ break;
+ default:
+ std::cerr << "Wrong family: " << Ip.GetFamily() << " on port " << port << std::endl;
+ break;
+ }
+}
+
+void CProtocol::Send(const char *buf, const CIp &Ip, uint16_t port) const
+{
+ switch (Ip.GetFamily()) {
+ case AF_INET:
+ m_Socket4.Send(buf, Ip, port);
+ break;
+ case AF_INET6:
+ m_Socket6.Send(buf, Ip, port);
+ break;
+ default:
+ std::cerr << "Wrong family: " << Ip.GetFamily() << " on port " << port << std::endl;
+ break;
+ }
+}
diff --git a/src/cprotocol.h b/src/cprotocol.h
index f736ed7..b7a9fef 100644
--- a/src/cprotocol.h
+++ b/src/cprotocol.h
@@ -77,7 +77,7 @@ public:
virtual ~CProtocol();
// initialization
- virtual bool Init(void);
+ bool Initialize(const char *, uint16);
virtual void Close(void);
// queue
@@ -89,7 +89,7 @@ public:
// task
static void Thread(CProtocol *);
- virtual void Task(void) {}
+ virtual void Task(void) = 0;
protected:
// packet encoding helpers
@@ -122,9 +122,13 @@ protected:
virtual char DmrDstIdToModule(uint32) const;
virtual uint32 ModuleToDmrDestId(char) const;
-protected:
+ void Send(const CBuffer &buf, const CIp &Ip) const;
+ void Send(const char *buf, const CIp &Ip) const;
+ void Send(const CBuffer &buf, const CIp &Ip, uint16 port) const;
+ void Send(const char *buf, const CIp &Ip, uint16 port) const;
+
// socket
- CUdpSocket m_Socket;
+ CUdpSocket m_Socket4, m_Socket6;
// streams
std::list m_Streams;
diff --git a/src/cprotocols.cpp b/src/cprotocols.cpp
index bc6c4d4..3355f18 100644
--- a/src/cprotocols.cpp
+++ b/src/cprotocols.cpp
@@ -19,7 +19,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"
@@ -33,18 +33,6 @@
#include "cg3protocol.h"
#include "cprotocols.h"
-
-////////////////////////////////////////////////////////////////////////////////////////
-// constructor
-
-CProtocols::CProtocols()
-{
- for ( int i = 0; i < m_Protocols.size(); i++ )
- {
- m_Protocols[i] = NULL;
- }
-}
-
////////////////////////////////////////////////////////////////////////////////////////
// destructor
@@ -52,10 +40,12 @@ CProtocols::~CProtocols()
{
m_Mutex.lock();
{
- for ( int i = 0; i < m_Protocols.size(); i++ )
- {
- delete m_Protocols[i];
- }
+ for ( auto it=m_Protocols.begin(); it!=m_Protocols.end(); it++)
+ {
+ (*it)->Close();
+ delete *it;
+ }
+ m_Protocols.clear();
}
m_Mutex.unlock();
}
@@ -65,65 +55,105 @@ CProtocols::~CProtocols()
bool CProtocols::Init(void)
{
- bool ok = true;
-
m_Mutex.lock();
{
- // create and initialize DEXTRA
- delete m_Protocols[0];
- m_Protocols[0] = new CDextraProtocol;
- ok &= m_Protocols[0]->Init();
-
+ auto dextra = new CDextraProtocol;
+ if (dextra->Init())
+ m_Protocols.push_back(dextra);
+ else
+ {
+ delete dextra;
+ return false;
+ }
+
+
// create and initialize DPLUS
- delete m_Protocols[1];
- m_Protocols[1] = new CDplusProtocol;
- ok &= m_Protocols[1]->Init();
-
+ auto dplus = new CDplusProtocol;
+ if (dplus->Init())
+ m_Protocols.push_back(dplus);
+ else
+ {
+ delete dplus;
+ return false;
+ }
+
// create and initialize DCS
- delete m_Protocols[2];
- m_Protocols[2] = new CDcsProtocol;
- ok &= m_Protocols[2]->Init();
-
+ auto dcs = new CDcsProtocol;
+ if (dcs->Init())
+ m_Protocols.push_back(dcs);
+ else
+ {
+ delete dcs;
+ return false;
+ }
+
// create and initialize XLX - interlink
- delete m_Protocols[3];
- m_Protocols[3] = new CXlxProtocol;
- ok &= m_Protocols[3]->Init();
-
+ auto xlx = new CXlxProtocol;
+ if (xlx->Init())
+ m_Protocols.push_back(xlx);
+ else
+ {
+ delete xlx;
+ return false;
+ }
+
// create and initialize DMRPLUS
- delete m_Protocols[4];
- m_Protocols[4] = new CDmrplusProtocol;
- ok &= m_Protocols[4]->Init();
-
+ auto dmrplus = new CDmrplusProtocol;
+ if (dmrplus->Init())
+ m_Protocols.push_back(dmrplus);
+ else
+ {
+ delete dmrplus;
+ return false;
+ }
+
// create and initialize DMRMMDVM
- delete m_Protocols[5];
- m_Protocols[5] = new CDmrmmdvmProtocol;
- ok &= m_Protocols[5]->Init();
-
+ auto dmrmmdvm = new CDmrmmdvmProtocol;
+ if (dmrmmdvm->Init())
+ m_Protocols.push_back(dmrmmdvm);
+ else
+ {
+ delete dmrmmdvm;
+ return false;
+ }
+
// create and initialize YSF
- delete m_Protocols[6];
- m_Protocols[6] = new CYsfProtocol;
- ok &= m_Protocols[6]->Init();
+ auto ysf = new CYsfProtocol;
+ if (ysf->Init())
+ m_Protocols.push_back(ysf);
+ else
+ {
+ delete ysf;
+ return false;
+ }
// create and initialize G3
- delete m_Protocols[7];
- m_Protocols[7] = new CG3Protocol;
- ok &= m_Protocols[7]->Init();
+ auto g3 = new CG3Protocol;
+ if (g3->Init())
+ m_Protocols.push_back(g3);
+ else
+ {
+ delete g3;
+ return true;
+ }
}
m_Mutex.unlock();
-
+
// done
- return ok;
+ return true;
}
void CProtocols::Close(void)
{
m_Mutex.lock();
{
- for ( int i = 0; i < m_Protocols.size(); i++ )
- {
- m_Protocols[i]->Close();
- }
+ for ( auto it=m_Protocols.begin(); it!=m_Protocols.end(); it++)
+ {
+ (*it)->Close();
+ delete *it;
+ }
+ m_Protocols.clear();
}
m_Mutex.unlock();
}
diff --git a/src/cprotocols.h b/src/cprotocols.h
index c0194a7..3f0124b 100644
--- a/src/cprotocols.h
+++ b/src/cprotocols.h
@@ -19,7 +19,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 .
// ----------------------------------------------------------------------------
#ifndef cprotocols_h
@@ -38,24 +38,21 @@
class CProtocols
{
public:
- // constructors
- CProtocols();
-
// destructors
- virtual ~CProtocols();
-
+ ~CProtocols();
+
// initialization
bool Init(void);
void Close(void);
-
- // get
- int Size(void) const { return (int)m_Protocols.size(); }
- CProtocol *GetProtocol(int i) { return m_Protocols[i]; }
-
+
+ // pass-thru
+ std::list::iterator begin() { return m_Protocols.begin(); }
+ std::list::iterator end() { return m_Protocols.end(); }
+
protected:
// data
- std::mutex m_Mutex;
- std::array m_Protocols;
+ std::mutex m_Mutex;
+ std::list m_Protocols;
};
diff --git a/src/creflector.cpp b/src/creflector.cpp
index 41e5b7c..0d8da87 100644
--- a/src/creflector.cpp
+++ b/src/creflector.cpp
@@ -348,27 +348,24 @@ void CReflector::RouterThread(CReflector *This, CPacketStream *streamIn)
packet->SetModuleId(uiModuleId);
// iterate on all protocols
- for ( int i = 0; i < This->m_Protocols.Size(); i++ )
+ for ( auto it=This->m_Protocols.begin(); it!=This->m_Protocols.end(); it++ )
{
// duplicate packet
CPacket *packetClone = packet->Duplicate();
- // get protocol
- CProtocol *protocol = This->m_Protocols.GetProtocol(i);
-
// if packet is header, update RPT2 according to protocol
if ( packetClone->IsDvHeader() )
{
// get our callsign
- CCallsign csRPT = protocol->GetReflectorCallsign();
+ CCallsign csRPT = (*it)->GetReflectorCallsign();
csRPT.SetModule(This->GetStreamModule(streamIn));
((CDvHeaderPacket *)packetClone)->SetRpt2Callsign(csRPT);
}
// and push it
- CPacketQueue *queue = protocol->GetQueue();
+ CPacketQueue *queue = (*it)->GetQueue();
queue->push(packetClone);
- protocol->ReleaseQueue();
+ (*it)->ReleaseQueue();
}
// done
delete packet;
diff --git a/src/creflector.h b/src/creflector.h
index 1424453..bd6c913 100644
--- a/src/creflector.h
+++ b/src/creflector.h
@@ -4,6 +4,7 @@
//
// Created by Jean-Luc Deltombe (LX3JL) on 31/10/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 .
// ----------------------------------------------------------------------------
#ifndef creflector_h
@@ -50,96 +51,99 @@ public:
// constructor
CReflector();
CReflector(const CCallsign &);
-
+
// destructor
virtual ~CReflector();
-
+
// settings
- void SetCallsign(const CCallsign &callsign) { m_Callsign = callsign; }
- const CCallsign &GetCallsign(void) const { return m_Callsign; }
- void SetListenIp(const CIp &ip) { m_Ip = ip; }
- void SetTranscoderIp(const CIp &ip) { m_AmbedIp = ip; }
- const CIp &GetListenIp(void) const { return m_Ip; }
- const CIp &GetTranscoderIp(void) const { return m_AmbedIp; }
-
+ void SetCallsign(const CCallsign &callsign) { m_Callsign = callsign; }
+ const CCallsign &GetCallsign(void) const { return m_Callsign; }
+ void SetListenIPv4(const char *a, const int n) { memset(m_IPv4, 0, n); strncpy(m_IPv4, a, n-1); }
+ void SetListenIPv6(const char *a, const int n) { memset(m_IPv6, 0, n); strncpy(m_IPv6, a, n-1); }
+ void SetTranscoderIp(const char *a, const int n) { memset(m_AmbedIp, 0, n); strncpy(m_AmbedIp, a, n-1); }
+ const char *GetListenIPv4(void) const { return m_IPv4; }
+ const char *GetListenIPv6(void) const { return m_IPv6; }
+ const char *GetTranscoderIp(void) const { return m_AmbedIp; }
+
// operation
bool Start(void);
void Stop(void);
-
+
// clients
CClients *GetClients(void) { m_Clients.Lock(); return &m_Clients; }
void ReleaseClients(void) { m_Clients.Unlock(); }
-
+
// peers
CPeers *GetPeers(void) { m_Peers.Lock(); return &m_Peers; }
void ReleasePeers(void) { m_Peers.Unlock(); }
-
+
// stream opening & closing
CPacketStream *OpenStream(CDvHeaderPacket *, CClient *);
bool IsStreaming(char);
void CloseStream(CPacketStream *);
-
+
// users
CUsers *GetUsers(void) { m_Users.Lock(); return &m_Users; }
void ReleaseUsers(void) { m_Users.Unlock(); }
-
+
// get
bool IsValidModule(char c) const { return (GetModuleIndex(c) >= 0); }
int GetModuleIndex(char) const;
char GetModuleLetter(int i) const { return 'A' + (char)i; }
-
+
// notifications
void OnPeersChanged(void);
void OnClientsChanged(void);
void OnUsersChanged(void);
void OnStreamOpen(const CCallsign &);
void OnStreamClose(const CCallsign &);
-
+
protected:
// threads
static void RouterThread(CReflector *, CPacketStream *);
static void XmlReportThread(CReflector *);
static void JsonReportThread(CReflector *);
-
+
// streams
CPacketStream *GetStream(char);
bool IsStreamOpen(const CDvHeaderPacket *);
char GetStreamModule(CPacketStream *);
-
+
// xml helpers
void WriteXmlFile(std::ofstream &);
-
+
// json helpers
void SendJsonReflectorObject(CUdpSocket &, CIp &);
void SendJsonNodesObject(CUdpSocket &, CIp &);
void SendJsonStationsObject(CUdpSocket &, CIp &);
void SendJsonOnairObject(CUdpSocket &, CIp &, const CCallsign &);
void SendJsonOffairObject(CUdpSocket &, CIp &, const CCallsign &);
-
+
protected:
// identity
- CCallsign m_Callsign;
- CIp m_Ip;
- CIp m_AmbedIp;
-
+ CCallsign m_Callsign;
+ char m_IPv4[INET_ADDRSTRLEN];
+ char m_IPv6[INET6_ADDRSTRLEN];
+ char m_AmbedIp[INET6_ADDRSTRLEN];
+
// objects
CUsers m_Users; // sorted list of lastheard stations
CClients m_Clients; // list of linked repeaters/nodes/peers's modules
CPeers m_Peers; // list of linked peers
CProtocols m_Protocols; // list of supported protocol handlers
-
+
// queues
std::array m_Streams;
-
+
// threads
bool m_bStopThreads;
std::array m_RouterThreads;
std::thread *m_XmlReportThread;
std::thread *m_JsonReportThread;
-
+
// notifications
CNotificationQueue m_Notifications;
-
+
public:
#ifdef DEBUG_DUMPFILE
std::ofstream m_DebugFile;
diff --git a/src/ctranscoder.cpp b/src/ctranscoder.cpp
index e4d91b3..bf545d7 100644
--- a/src/ctranscoder.cpp
+++ b/src/ctranscoder.cpp
@@ -75,22 +75,27 @@ bool CTranscoder::Init(void)
m_bStopThread = false;
// create server's IP
- m_Ip = g_Reflector.GetTranscoderIp();
+ auto s = g_Reflector.GetTranscoderIp();
+ m_Ip.Initialize(strchr(s, ':') ? AF_INET6 : AF_INET, TRANSCODER_PORT, s);
// create our socket
- ok = m_Socket.Open(TRANSCODER_PORT);
- if ( ok )
- {
- // start thread;
- m_pThread = new std::thread(CTranscoder::Thread, this);
- }
- else
- {
- std::cout << "Error opening socket on port UDP" << TRANSCODER_PORT << " on ip " << g_Reflector.GetListenIp() << std::endl;
- }
-
- // done
- return ok;
+ if (m_Ip.IsSet())
+ {
+ if (! m_Socket.Open(TRANSCODER_PORT)) {
+ std::cerr << "Error opening socket on port UDP" << TRANSCODER_PORT << " on ip " << m_Ip << std::endl;
+ return false;
+ }
+ }
+ else
+ {
+ std::cerr << "Could not initialize transcoder socket on " << m_Ip << std::endl;
+ return false;
+ }
+
+ // start thread;
+ m_pThread = new std::thread(CTranscoder::Thread, this);
+
+ return true;
}
void CTranscoder::Close(void)
diff --git a/src/cudpmsgsocket.cpp b/src/cudpmsgsocket.cpp
index b90f702..39b09ec 100644
--- a/src/cudpmsgsocket.cpp
+++ b/src/cudpmsgsocket.cpp
@@ -28,12 +28,12 @@
////////////////////////////////////////////////////////////////////////////////////////
// open
-bool CUdpMsgSocket::Open(uint16 uiPort)
+bool CUdpMsgSocket::Open(const CIp &ip)
{
bool ret;
int on = 1;
- ret = CUdpSocket::Open(uiPort);
+ ret = CUdpSocket::Open(ip);
setsockopt(m_fd, IPPROTO_IP, IP_PKTINFO, (char *)&on, sizeof(on));
return ret;
diff --git a/src/cudpmsgsocket.h b/src/cudpmsgsocket.h
index f4245c1..32bb512 100644
--- a/src/cudpmsgsocket.h
+++ b/src/cudpmsgsocket.h
@@ -19,7 +19,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 .
// ----------------------------------------------------------------------------
// Description:
@@ -40,7 +40,7 @@ class CUdpMsgSocket : public CUdpSocket
{
public:
// open
- bool Open(uint16);
+ bool Open(const CIp &ip);
// read
int Receive(CBuffer *, CIp *, int);
diff --git a/src/cxlxprotocol.cpp b/src/cxlxprotocol.cpp
index d237aa4..83d0b71 100644
--- a/src/cxlxprotocol.cpp
+++ b/src/cxlxprotocol.cpp
@@ -37,27 +37,15 @@
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;
- }
+ if (! Initialize("XLX", XLX_PORT))
+ return false;
// update time
m_LastKeepaliveTime.Now();
m_LastPeersLinkTime.Now();
// done
- return ok;
+ return true;
}
////////////////////////////////////////////////////////////////////////////////////////
@@ -75,7 +63,7 @@ void CXlxProtocol::Task(void)
CDvLastFramePacket *LastFrame;
// any incoming packet ?
- if ( m_Socket.Receive(Buffer, Ip, 20) )
+ if ( m_Socket4.Receive(Buffer, Ip, 10) || m_Socket6.Receive(Buffer, Ip, 10) )
{
// crack the packet
if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL )
@@ -130,7 +118,7 @@ void CXlxProtocol::Task(void)
{
// acknowledge the request
EncodeConnectAckPacket(&Buffer, Modules);
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
}
g_Reflector.ReleasePeers();
@@ -141,7 +129,7 @@ void CXlxProtocol::Task(void)
default:
// acknowledge the request
EncodeConnectAckPacket(&Buffer, Modules);
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
break;
}
}
@@ -149,7 +137,7 @@ void CXlxProtocol::Task(void)
{
// deny the request
EncodeConnectNackPacket(&Buffer);
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
}
}
else if ( IsValidAckPacket(Buffer, &Callsign, Modules, &Version) )
@@ -284,17 +272,17 @@ void CXlxProtocol::HandleQueue(void)
{
case XLX_PROTOCOL_REVISION_0:
case XLX_PROTOCOL_REVISION_1:
- m_Socket.Send(bufferLegacy, client->GetIp());
+ Send(bufferLegacy, client->GetIp());
break;
case XLX_PROTOCOL_REVISION_2:
default:
if ( g_Transcoder.IsConnected() )
{
- m_Socket.Send(buffer, client->GetIp());
+ Send(buffer, client->GetIp());
}
else
{
- m_Socket.Send(bufferLegacy, client->GetIp());
+ Send(bufferLegacy, client->GetIp());
}
break;
}
@@ -328,7 +316,7 @@ void CXlxProtocol::HandleKeepalives(void)
while ( (peer = peers->FindNextPeer(PROTOCOL_XLX, pit)) != NULL )
{
// send keepalive
- m_Socket.Send(keepalive, peer->GetIp());
+ Send(keepalive, peer->GetIp());
// client busy ?
if ( peer->IsAMaster() )
@@ -342,7 +330,7 @@ void CXlxProtocol::HandleKeepalives(void)
// no, disconnect
CBuffer disconnect;
EncodeDisconnectPacket(&disconnect);
- m_Socket.Send(disconnect, peer->GetIp());
+ Send(disconnect, peer->GetIp());
// remove it
std::cout << "XLX peer " << peer->GetCallsign() << " keepalive timeout" << std::endl;
@@ -373,7 +361,7 @@ void CXlxProtocol::HandlePeerLinks(void)
{
// send disconnect packet
EncodeDisconnectPacket(&buffer);
- m_Socket.Send(buffer, peer->GetIp());
+ Send(buffer, peer->GetIp());
std::cout << "Sending disconnect packet to XLX peer " << peer->GetCallsign() << std::endl;
// remove client
peers->RemovePeer(peer);
@@ -392,7 +380,7 @@ void CXlxProtocol::HandlePeerLinks(void)
(*it).ResolveIp();
// send connect packet to re-initiate peer link
EncodeConnectPacket(&buffer, (*it).GetModules());
- m_Socket.Send(buffer, (*it).GetIp(), XLX_PORT);
+ Send(buffer, (*it).GetIp(), XLX_PORT);
std::cout << "Sending connect packet to XLX peer " << (*it).GetCallsign() << " @ " << (*it).GetIp() << " for modules " << (*it).GetModules() << std::endl;
}
}
diff --git a/src/cxlxprotocol.h b/src/cxlxprotocol.h
index c9b66a1..b36a469 100644
--- a/src/cxlxprotocol.h
+++ b/src/cxlxprotocol.h
@@ -40,31 +40,25 @@ class CPeer;
class CXlxProtocol : public CDextraProtocol
{
public:
- // constructor
- CXlxProtocol() {};
-
- // destructor
- virtual ~CXlxProtocol() {};
-
// initialization
bool Init(void);
-
+
// task
void Task(void);
-
+
protected:
// queue helper
void HandleQueue(void);
-
+
// keepalive helpers
void HandlePeerLinks(void);
void HandleKeepalives(void);
-
+
// stream helpers
bool OnDvHeaderPacketIn(CDvHeaderPacket *, const CIp &);
void OnDvFramePacketIn(CDvFramePacket *, const CIp * = NULL);
void OnDvLastFramePacketIn(CDvLastFramePacket *, const CIp * = NULL);
-
+
// packet decoding helpers
bool IsValidKeepAlivePacket(const CBuffer &, CCallsign *);
bool IsValidConnectPacket(const CBuffer &, CCallsign *, char *, CVersion *);
@@ -73,7 +67,7 @@ protected:
bool IsValidNackPacket(const CBuffer &, CCallsign *);
CDvFramePacket *IsValidDvFramePacket(const CBuffer &);
CDvLastFramePacket *IsValidDvLastFramePacket(const CBuffer &);
-
+
// packet encoding helpers
void EncodeKeepAlivePacket(CBuffer *);
void EncodeConnectPacket(CBuffer *, const char *);
@@ -82,11 +76,11 @@ protected:
void EncodeConnectNackPacket(CBuffer *);
bool EncodeDvFramePacket(const CDvFramePacket &, CBuffer *) const;
bool EncodeDvLastFramePacket(const CDvLastFramePacket &, CBuffer *) const;
-
+
// protocol revision helper
int GetConnectingPeerProtocolRevision(const CCallsign &, const CVersion &);
CPeer *CreateNewPeer(const CCallsign &, const CIp &, char *, const CVersion &);
-
+
protected:
// time
CTimePoint m_LastKeepaliveTime;
diff --git a/src/cysfprotocol.cpp b/src/cysfprotocol.cpp
index 968fcb8..983fa45 100644
--- a/src/cysfprotocol.cpp
+++ b/src/cysfprotocol.cpp
@@ -47,29 +47,19 @@ CYsfProtocol::CYsfProtocol()
bool CYsfProtocol::Init(void)
{
- bool ok;
-
// base class
- ok = CProtocol::Init();
-
- // update the reflector callsign
- m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"YSF", 3);
-
- // create our socket
- ok &= m_Socket.Open(YSF_PORT);
- if ( !ok )
- {
- std::cout << "Error opening socket on port UDP" << YSF_PORT << " on ip " << g_Reflector.GetListenIp() << std::endl;
- }
+ if (! Initialize("YSF", YSF_PORT))
+ return false;
// init the wiresx cmd handler
- ok &= m_WiresxCmdHandler.Init();
+ if (! m_WiresxCmdHandler.Init())
+ return false;
// update time
m_LastKeepaliveTime.Now();
// done
- return ok;
+ return true;
}
void CYsfProtocol::Close(void)
@@ -105,13 +95,13 @@ void CYsfProtocol::Task(void)
{
CWiresxPacket packet = queue->front();
queue->pop();
- m_Socket.Send(packet.GetBuffer(), packet.GetIp());
+ Send(packet.GetBuffer(), packet.GetIp());
}
m_WiresxCmdHandler.ReleasePacketQueue();
}
// handle incoming packets
- if ( m_Socket.Receive(Buffer, Ip, 20) )
+ if ( m_Socket6.Receive(Buffer, Ip, 10) || m_Socket4.Receive(Buffer, Ip, 10) )
{
// crack the packet
if ( IsValidDvPacket(Buffer, &Fich) )
@@ -164,7 +154,7 @@ void CYsfProtocol::Task(void)
{
// acknowledge the request
EncodeConnectAckPacket(&Buffer);
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
// add client if needed
CClients *clients = g_Reflector.GetClients();
@@ -207,7 +197,7 @@ void CYsfProtocol::Task(void)
std::cout << "YSF server status enquiry from " << Ip << std::endl;
// reply
EncodeServerStatusPacket(&Buffer);
- m_Socket.Send(Buffer, Ip);
+ Send(Buffer, Ip);
}
else
{
@@ -359,7 +349,7 @@ void CYsfProtocol::HandleQueue(void)
if ( !client->IsAMaster() && (client->GetReflectorModule() == packet->GetModuleId()) )
{
// no, send the packet
- m_Socket.Send(buffer, client->GetIp());
+ Send(buffer, client->GetIp());
}
}
diff --git a/src/main.cpp b/src/main.cpp
index 723ab5b..008e0d2 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -19,13 +19,12 @@
// 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"
#include "creflector.h"
-#include "syslog.h"
#include
@@ -41,99 +40,58 @@ CReflector g_Reflector;
int main(int argc, const char * argv[])
{
-#ifdef RUN_AS_DAEMON
-
- // redirect cout, cerr and clog to syslog
- syslog::redirect cout_redir(std::cout);
- syslog::redirect cerr_redir(std::cerr);
- syslog::redirect clog_redir(std::clog);
-
- //Fork the Parent Process
- pid_t pid, sid;
- pid = ::fork();
- if ( pid < 0 )
- {
- exit(EXIT_FAILURE);
- }
-
- // We got a good pid, Close the Parent Process
- if (pid > 0)
- {
- exit(EXIT_SUCCESS);
- }
-
- // Change File Mask
- ::umask(0);
-
- //Create a new Signature Id for our child
- sid = ::setsid();
- if (sid < 0)
- {
- exit(EXIT_FAILURE);
- }
-
- // Change Directory
- // If we cant find the directory we exit with failure.
- if ( (::chdir("/")) < 0)
- {
- exit(EXIT_FAILURE);
- }
-
- // Close Standard File Descriptors
- close(STDIN_FILENO);
- close(STDOUT_FILENO);
- close(STDERR_FILENO);
-
-#endif
// check arguments
- if ( argc != 4 )
+ if ( argc != 5 )
{
- std::cout << "Usage: xlxd callsign xlxdip ambedip" << std::endl;
- std::cout << "example: xlxd XLX999 192.168.178.212 127.0.0.1" << std::endl;
- return 1;
+ std::cout << "Usage: " << argv[0] << " callsign ipv4 ipv6 ambedip" << std::endl;
+ std::cout << "example: " << argv[0] << " XLX999 192.168.178.212 2001:400:534::675b 127.0.0.1" << std::endl;
+ return EXIT_FAILURE;
}
+ bool is4none = 0 == strncasecmp(argv[2], "none", 4);
+ bool is6none = 0 == strncasecmp(argv[3], "none", 4);
+ if (is4none && is6none) {
+ std::cerr << "Both IPv4 and 6 address can't both be 'none'" << std::endl;
+ return EXIT_FAILURE;
+ }
+
// splash
- std::cout << "Starting xlxd " << VERSION_MAJOR << "." << VERSION_MINOR << "." << VERSION_REVISION << std::endl << std::endl;
+ std::cout << "Starting " << argv[0] << " " << VERSION_MAJOR << "." << VERSION_MINOR << "." << VERSION_REVISION << std::endl << std::endl;
// initialize reflector
g_Reflector.SetCallsign(argv[1]);
- g_Reflector.SetListenIp(CIp(argv[2]));
- g_Reflector.SetTranscoderIp(CIp(CIp(argv[3])));
-
+ g_Reflector.SetListenIPv4(argv[2], INET_ADDRSTRLEN);
+ g_Reflector.SetListenIPv6(argv[3], INET6_ADDRSTRLEN);
+ g_Reflector.SetTranscoderIp(argv[4], INET6_ADDRSTRLEN);
+
+
// and let it run
if ( !g_Reflector.Start() )
{
std::cout << "Error starting reflector" << std::endl;
- exit(EXIT_FAILURE);
- }
- std::cout << "Reflector " << g_Reflector.GetCallsign()
- << "started and listening on " << g_Reflector.GetListenIp() << std::endl;
-
-#ifdef RUN_AS_DAEMON
- // run forever
- while ( true )
- {
- // sleep 60 seconds
- CTimePoint::TaskSleepFor(60000);
- }
-#else
- // wait any key
- for (;;)
- {
- // sleep 60 seconds
- CTimePoint::TaskSleepFor(60000);
-#ifdef DEBUG_DUMPFILE
- g_Reflector.m_DebugFile.close();
-#endif
+ return EXIT_FAILURE;
}
-#endif
-
- // and wait for end
+
+ std::cout << "Reflector " << g_Reflector.GetCallsign() << "started and listening on ";
+ if (! is4none)
+ {
+ std::cout << g_Reflector.GetListenIPv4();
+ if (! is6none)
+ {
+ std::cout << " and " << g_Reflector.GetListenIPv4() << std::endl;
+ }
+ }
+ else
+ {
+ std::cout << g_Reflector.GetListenIPv6() << std::endl;
+ }
+
+ pause(); // wait for any signal
+
g_Reflector.Stop();
std::cout << "Reflector stopped" << std::endl;
-
+
// done
- exit(EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}