pull/1/head
Tom Early 6 years ago
parent 30a47e1bd3
commit ef252ec37a

@ -89,31 +89,32 @@ CCodecStream::~CCodecStream()
bool CCodecStream::Init(uint16 uiPort) bool CCodecStream::Init(uint16 uiPort)
{ {
bool ok;
// reset stop flag // reset stop flag
m_bStopThread = false; m_bConnected = m_bStopThread = false;
// create server's IP // create server's IP
m_Ip = g_Reflector.GetTranscoderIp();
m_uiPort = uiPort; m_uiPort = uiPort;
auto s = g_Reflector.GetTranscoderIp();
m_Ip.Initialize(strchr(s, ':') ? AF_INET6 : AF_INET, m_uiPort, s);
// create our socket // create our socket
ok = m_Socket.Open(uiPort); if (m_Ip.IsSet())
if ( ok ) {
{ if (! m_Socket.Open(m_Ip)) {
// start thread; std::cerr << "Error opening socket on port UDP" << uiPort << " on ip " << m_Ip << std::endl;
m_pThread = new std::thread(CCodecStream::Thread, this); return false;
m_bConnected = true; }
} }
else else
{ {
std::cout << "Error opening socket on port UDP" << uiPort << " on ip " << g_Reflector.GetListenIp() << std::endl; std::cerr << "Could not initialize Codec Stream on " << m_Ip << std::endl;
m_bConnected = false; return false;
} }
// done m_pThread = new std::thread(CCodecStream::Thread, this);
return ok; m_bConnected = true;
return true;
} }
void CCodecStream::Close(void) void CCodecStream::Close(void)

@ -35,26 +35,15 @@
bool CDcsProtocol::Init(void) bool CDcsProtocol::Init(void)
{ {
bool ok;
// base class // base class
ok = CProtocol::Init(); if (! Initialize("DCS", DCS_PORT))
return false;
// 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;
}
// update time // update time
m_LastKeepaliveTime.Now(); m_LastKeepaliveTime.Now();
// done // done
return ok; return true;
} }
@ -72,7 +61,7 @@ void CDcsProtocol::Task(void)
CDvFramePacket *Frame; CDvFramePacket *Frame;
// handle incoming packets // 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 // crack the packet
if ( IsValidDvPacket(Buffer, &Header, &Frame) ) if ( IsValidDvPacket(Buffer, &Header, &Frame) )
@ -114,7 +103,7 @@ void CDcsProtocol::Task(void)
{ {
// acknowledge the request // acknowledge the request
EncodeConnectAckPacket(Callsign, ToLinkModule, &Buffer); EncodeConnectAckPacket(Callsign, ToLinkModule, &Buffer);
m_Socket.Send(Buffer, Ip); Send(Buffer, Ip);
// create the client // create the client
CDcsClient *client = new CDcsClient(Callsign, Ip, ToLinkModule); CDcsClient *client = new CDcsClient(Callsign, Ip, ToLinkModule);
@ -129,14 +118,14 @@ void CDcsProtocol::Task(void)
// deny the request // deny the request
EncodeConnectNackPacket(Callsign, ToLinkModule, &Buffer); EncodeConnectNackPacket(Callsign, ToLinkModule, &Buffer);
m_Socket.Send(Buffer, Ip); Send(Buffer, Ip);
} }
} }
else else
{ {
// deny the request // deny the request
EncodeConnectNackPacket(Callsign, ToLinkModule, &Buffer); EncodeConnectNackPacket(Callsign, ToLinkModule, &Buffer);
m_Socket.Send(Buffer, Ip); Send(Buffer, Ip);
} }
} }
@ -153,7 +142,7 @@ void CDcsProtocol::Task(void)
clients->RemoveClient(client); clients->RemoveClient(client);
// and acknowledge the disconnect // and acknowledge the disconnect
EncodeConnectNackPacket(Callsign, ' ', &Buffer); EncodeConnectNackPacket(Callsign, ' ', &Buffer);
m_Socket.Send(Buffer, Ip); Send(Buffer, Ip);
} }
g_Reflector.ReleaseClients(); g_Reflector.ReleaseClients();
} }
@ -310,7 +299,7 @@ void CDcsProtocol::HandleQueue(void)
if ( !client->IsAMaster() && (client->GetReflectorModule() == packet->GetModuleId()) ) if ( !client->IsAMaster() && (client->GetReflectorModule() == packet->GetModuleId()) )
{ {
// no, send the packet // 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); EncodeKeepAlivePacket(&keepalive2, client);
// send keepalive // send keepalive
m_Socket.Send(keepalive1, client->GetIp()); Send(keepalive1, client->GetIp());
m_Socket.Send(keepalive2, client->GetIp()); Send(keepalive2, client->GetIp());
// is this client busy ? // is this client busy ?
if ( client->IsAMaster() ) if ( client->IsAMaster() )
@ -361,7 +350,7 @@ void CDcsProtocol::HandleKeepalives(void)
// no, disconnect // no, disconnect
CBuffer disconnect; CBuffer disconnect;
EncodeDisconnectPacket(&disconnect, client); EncodeDisconnectPacket(&disconnect, client);
m_Socket.Send(disconnect, client->GetIp()); Send(disconnect, client->GetIp());
// remove it // remove it
std::cout << "DCS client " << client->GetCallsign() << " keepalive timeout" << std::endl; std::cout << "DCS client " << client->GetCallsign() << " keepalive timeout" << std::endl;

@ -50,12 +50,6 @@ public:
class CDcsProtocol : public CProtocol class CDcsProtocol : public CProtocol
{ {
public: public:
// constructor
CDcsProtocol() {};
// destructor
virtual ~CDcsProtocol() {};
// initialization // initialization
bool Init(void); bool Init(void);

@ -37,27 +37,16 @@
bool CDextraProtocol::Init(void) bool CDextraProtocol::Init(void)
{ {
bool ok;
// base class // base class
ok = CProtocol::Init(); if (! Initialize("XRF", DEXTRA_PORT))
return false;
// 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 // update time
m_LastKeepaliveTime.Now(); m_LastKeepaliveTime.Now();
m_LastPeersLinkTime.Now(); m_LastPeersLinkTime.Now();
// done // done
return ok; return true;
} }
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
@ -75,7 +64,7 @@ void CDextraProtocol::Task(void)
CDvLastFramePacket *LastFrame; CDvLastFramePacket *LastFrame;
// any incoming packet ? // 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 // crack the packet
if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL ) if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL )
@ -143,7 +132,7 @@ void CDextraProtocol::Task(void)
{ {
// acknowledge the request // acknowledge the request
EncodeConnectAckPacket(&Buffer, ProtRev); EncodeConnectAckPacket(&Buffer, ProtRev);
m_Socket.Send(Buffer, Ip); Send(Buffer, Ip);
// create the client // create the client
CDextraClient *client = new CDextraClient(Callsign, Ip, ToLinkModule, ProtRev); CDextraClient *client = new CDextraClient(Callsign, Ip, ToLinkModule, ProtRev);
@ -160,14 +149,14 @@ void CDextraProtocol::Task(void)
// deny the request // deny the request
EncodeConnectNackPacket(&Buffer); EncodeConnectNackPacket(&Buffer);
m_Socket.Send(Buffer, Ip); Send(Buffer, Ip);
} }
} }
else else
{ {
// deny the request // deny the request
EncodeConnectNackPacket(&Buffer); EncodeConnectNackPacket(&Buffer);
m_Socket.Send(Buffer, Ip); Send(Buffer, Ip);
} }
} }
else if ( IsValidDisconnectPacket(Buffer, &Callsign) ) else if ( IsValidDisconnectPacket(Buffer, &Callsign) )
@ -183,11 +172,11 @@ void CDextraProtocol::Task(void)
if ( client->GetProtocolRevision() == 1 ) if ( client->GetProtocolRevision() == 1 )
{ {
EncodeDisconnectedPacket(&Buffer); EncodeDisconnectedPacket(&Buffer);
m_Socket.Send(Buffer, Ip); Send(Buffer, Ip);
} }
else if ( client->GetProtocolRevision() == 2 ) else if ( client->GetProtocolRevision() == 2 )
{ {
m_Socket.Send(Buffer, Ip); Send(Buffer, Ip);
} }
// and remove it // and remove it
clients->RemoveClient(client); clients->RemoveClient(client);
@ -271,7 +260,7 @@ void CDextraProtocol::HandleQueue(void)
int n = packet->IsDvHeader() ? 5 : 1; int n = packet->IsDvHeader() ? 5 : 1;
for ( int i = 0; i < n; i++ ) 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 ) while ( (client = clients->FindNextClient(PROTOCOL_DEXTRA, it)) != NULL )
{ {
// send keepalive // send keepalive
m_Socket.Send(keepalive, client->GetIp()); Send(keepalive, client->GetIp());
// client busy ? // client busy ?
if ( client->IsAMaster() ) if ( client->IsAMaster() )
@ -325,7 +314,7 @@ void CDextraProtocol::HandleKeepalives(void)
// no, disconnect // no, disconnect
CBuffer disconnect; CBuffer disconnect;
EncodeDisconnectPacket(&disconnect, client->GetReflectorModule()); EncodeDisconnectPacket(&disconnect, client->GetReflectorModule());
m_Socket.Send(disconnect, client->GetIp()); Send(disconnect, client->GetIp());
// remove it // remove it
std::cout << "DExtra client " << client->GetCallsign() << " keepalive timeout" << std::endl; std::cout << "DExtra client " << client->GetCallsign() << " keepalive timeout" << std::endl;
@ -354,7 +343,7 @@ void CDextraProtocol::HandleKeepalives(void)
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
for ( auto cit=peer->cbegin(); cit!=peer->cend(); cit++ ) for ( auto cit=peer->cbegin(); cit!=peer->cend(); cit++ )
{ {
m_Socket.Send(disconnect, (*cit)->GetIp()); Send(disconnect, (*cit)->GetIp());
} }
g_Reflector.ReleaseClients(); g_Reflector.ReleaseClients();
@ -387,7 +376,7 @@ void CDextraProtocol::HandlePeerLinks(void)
{ {
// send disconnect packet // send disconnect packet
EncodeDisconnectPacket(&buffer, peer->GetReflectorModules()[0]); 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; std::cout << "Sending disconnect packet to XRF peer " << peer->GetCallsign() << std::endl;
// remove client // remove client
peers->RemovePeer(peer); peers->RemovePeer(peer);
@ -408,7 +397,7 @@ void CDextraProtocol::HandlePeerLinks(void)
(*it).ResolveIp(); (*it).ResolveIp();
// send connect packet to re-initiate peer link // send connect packet to re-initiate peer link
EncodeConnectPacket(&buffer, (*it).GetModules()); 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; std::cout << "Sending connect packet to XRF peer " << (*it).GetCallsign() << " @ " << (*it).GetIp() << " for module " << (*it).GetModules()[1] << " (module " << (*it).GetModules()[0] << ")" << std::endl;
} }
} }

@ -58,12 +58,6 @@
class CDextraProtocol : public CProtocol class CDextraProtocol : public CProtocol
{ {
public: public:
// constructor
CDextraProtocol() {};
// destructor
virtual ~CDextraProtocol() {};
// initialization // initialization
bool Init(void); bool Init(void);

@ -56,16 +56,9 @@ static uint8 g_DmrSyncMSData[] = { 0x0D,0x5D,0x7F,0x77,0xFD,0x75,0x70 };
bool CDmrmmdvmProtocol::Init(void) bool CDmrmmdvmProtocol::Init(void)
{ {
bool ok;
// base class // base class
ok = CProtocol::Init(); if (! Initialize(NULL, DMRMMDVM_PORT))
return false;
// update the reflector callsign
//m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"DMR", 3);
// create our socket
ok &= m_Socket.Open(DMRMMDVM_PORT);
// update time // update time
m_LastKeepaliveTime.Now(); m_LastKeepaliveTime.Now();
@ -76,7 +69,7 @@ bool CDmrmmdvmProtocol::Init(void)
m_uiAuthSeed = (uint32)rand(); m_uiAuthSeed = (uint32)rand();
// done // done
return ok; return true;
} }
@ -97,7 +90,7 @@ void CDmrmmdvmProtocol::Task(void)
CDvLastFramePacket *LastFrame; CDvLastFramePacket *LastFrame;
// handle incoming packets // 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); //Buffer.DebugDump(g_Reflector.m_DebugFile);
// crack the packet // crack the packet
@ -141,13 +134,13 @@ void CDmrmmdvmProtocol::Task(void)
{ {
// acknowledge the request // acknowledge the request
EncodeConnectAckPacket(&Buffer, Callsign, m_uiAuthSeed); EncodeConnectAckPacket(&Buffer, Callsign, m_uiAuthSeed);
m_Socket.Send(Buffer, Ip); Send(Buffer, Ip);
} }
else else
{ {
// deny the request // deny the request
EncodeNackPacket(&Buffer, Callsign); EncodeNackPacket(&Buffer, Callsign);
m_Socket.Send(Buffer, Ip); Send(Buffer, Ip);
} }
} }
@ -160,7 +153,7 @@ void CDmrmmdvmProtocol::Task(void)
{ {
// acknowledge the request // acknowledge the request
EncodeAckPacket(&Buffer, Callsign); EncodeAckPacket(&Buffer, Callsign);
m_Socket.Send(Buffer, Ip); Send(Buffer, Ip);
// add client if needed // add client if needed
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
@ -187,7 +180,7 @@ void CDmrmmdvmProtocol::Task(void)
{ {
// deny the request // deny the request
EncodeNackPacket(&Buffer, Callsign); EncodeNackPacket(&Buffer, Callsign);
m_Socket.Send(Buffer, Ip); Send(Buffer, Ip);
} }
} }
@ -210,7 +203,7 @@ void CDmrmmdvmProtocol::Task(void)
// acknowledge the request // acknowledge the request
EncodeAckPacket(&Buffer, Callsign); EncodeAckPacket(&Buffer, Callsign);
m_Socket.Send(Buffer, Ip); Send(Buffer, Ip);
} }
else if ( IsValidKeepAlivePacket(Buffer, &Callsign) ) else if ( IsValidKeepAlivePacket(Buffer, &Callsign) )
{ {
@ -224,7 +217,7 @@ void CDmrmmdvmProtocol::Task(void)
{ {
// acknowledge // acknowledge
EncodeKeepAlivePacket(&Buffer, client); EncodeKeepAlivePacket(&Buffer, client);
m_Socket.Send(Buffer, Ip); Send(Buffer, Ip);
// and mark as alive // and mark as alive
client->Alive(); client->Alive();
@ -243,7 +236,7 @@ void CDmrmmdvmProtocol::Task(void)
// acknowledge the request // acknowledge the request
EncodeAckPacket(&Buffer, Callsign); EncodeAckPacket(&Buffer, Callsign);
m_Socket.Send(Buffer, Ip); Send(Buffer, Ip);
} }
else if ( Buffer.size() != 55 ) else if ( Buffer.size() != 55 )
{ {
@ -450,7 +443,7 @@ void CDmrmmdvmProtocol::HandleQueue(void)
if ( !client->IsAMaster() && (client->GetReflectorModule() == packet->GetModuleId()) ) if ( !client->IsAMaster() && (client->GetReflectorModule() == packet->GetModuleId()) )
{ {
// no, send the packet // no, send the packet
m_Socket.Send(buffer, client->GetIp()); Send(buffer, client->GetIp());
} }
} }
@ -489,7 +482,7 @@ void CDmrmmdvmProtocol::HandleKeepalives(void)
{ {
// no, disconnect // no, disconnect
CBuffer disconnect; CBuffer disconnect;
m_Socket.Send(disconnect, client->GetIp()); Send(disconnect, client->GetIp());
// remove it // remove it
std::cout << "DMRmmdvm client " << client->GetCallsign() << " keepalive timeout" << std::endl; std::cout << "DMRmmdvm client " << client->GetCallsign() << " keepalive timeout" << std::endl;

@ -66,12 +66,6 @@ public:
class CDmrmmdvmProtocol : public CProtocol class CDmrmmdvmProtocol : public CProtocol
{ {
public: public:
// constructor
CDmrmmdvmProtocol() {};
// destructor
virtual ~CDmrmmdvmProtocol() {};
// initialization // initialization
bool Init(void); bool Init(void);

@ -47,18 +47,11 @@ static uint8 g_DmrSyncMSData[] = { 0x0D,0x5D,0x7F,0x77,0xFD,0x75,0x70 };
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
// operation // operation
bool CDmrplusProtocol::Init(void) bool CDmrplusProtocol::Init()
{ {
bool ok;
// base class // base class
ok = CProtocol::Init(); if (! Initialize(NULL, DMRPLUS_PORT))
return false;
// update the reflector callsign
//m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"DMR", 3);
// create our socket
ok &= m_Socket.Open(DMRPLUS_PORT);
// update time // update time
m_LastKeepaliveTime.Now(); m_LastKeepaliveTime.Now();
@ -68,7 +61,7 @@ bool CDmrplusProtocol::Init(void)
::srand((unsigned) time(&t)); ::srand((unsigned) time(&t));
// done // done
return ok; return true;
} }
@ -86,7 +79,7 @@ void CDmrplusProtocol::Task(void)
CDvFramePacket *Frames[3]; CDvFramePacket *Frames[3];
// handle incoming packets // 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 // crack the packet
if ( IsValidDvFramePacket(Ip, Buffer, Frames) ) if ( IsValidDvFramePacket(Ip, Buffer, Frames) )
@ -135,7 +128,7 @@ void CDmrplusProtocol::Task(void)
{ {
// acknowledge the request // acknowledge the request
EncodeConnectAckPacket(&Buffer); EncodeConnectAckPacket(&Buffer);
m_Socket.Send(Buffer, Ip); Send(Buffer, Ip);
// add client if needed // add client if needed
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
@ -162,7 +155,7 @@ void CDmrplusProtocol::Task(void)
{ {
// deny the request // deny the request
EncodeConnectNackPacket(&Buffer); 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()) ) if ( !client->IsAMaster() && (client->GetReflectorModule() == packet->GetModuleId()) )
{ {
// no, send the packet // no, send the packet
m_Socket.Send(buffer, client->GetIp()); Send(buffer, client->GetIp());
} }
} }
g_Reflector.ReleaseClients(); g_Reflector.ReleaseClients();
@ -353,7 +346,7 @@ void CDmrplusProtocol::SendBufferToClients(const CBuffer &buffer, uint8 module)
if ( !client->IsAMaster() && (client->GetReflectorModule() == module) ) if ( !client->IsAMaster() && (client->GetReflectorModule() == module) )
{ {
// no, send the packet // no, send the packet
m_Socket.Send(buffer, client->GetIp()); Send(buffer, client->GetIp());
} }
} }
g_Reflector.ReleaseClients(); g_Reflector.ReleaseClients();
@ -391,7 +384,7 @@ void CDmrplusProtocol::HandleKeepalives(void)
// no, disconnect // no, disconnect
//CBuffer disconnect; //CBuffer disconnect;
//EncodeDisconnectPacket(&disconnect, client); //EncodeDisconnectPacket(&disconnect, client);
//m_Socket.Send(disconnect, client->GetIp()); //Send(disconnect, client->GetIp());
// remove it // remove it
std::cout << "DMRplus client " << client->GetCallsign() << " keepalive timeout" << std::endl; std::cout << "DMRplus client " << client->GetCallsign() << " keepalive timeout" << std::endl;

@ -44,7 +44,6 @@ class CDmrplusStreamCacheItem
{ {
public: public:
CDmrplusStreamCacheItem() { m_uiSeqId = 0x77; } CDmrplusStreamCacheItem() { m_uiSeqId = 0x77; }
~CDmrplusStreamCacheItem() {}
CDvHeaderPacket m_dvHeader; CDvHeaderPacket m_dvHeader;
CDvFramePacket m_dvFrame0; CDvFramePacket m_dvFrame0;
@ -57,14 +56,8 @@ public:
class CDmrplusProtocol : public CProtocol class CDmrplusProtocol : public CProtocol
{ {
public: public:
// constructor
CDmrplusProtocol() {};
// destructor
virtual ~CDmrplusProtocol() {};
// initialization // initialization
bool Init(void); bool Init();
// task // task
void Task(void); void Task(void);

@ -36,26 +36,15 @@
bool CDplusProtocol::Init(void) bool CDplusProtocol::Init(void)
{ {
bool ok;
// base class // base class
ok = CProtocol::Init(); if (Initialize("REF", DPLUS_PORT))
return false;
// 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;
}
// update time // update time
m_LastKeepaliveTime.Now(); m_LastKeepaliveTime.Now();
// done // done
return ok; return true;
} }
@ -73,7 +62,7 @@ void CDplusProtocol::Task(void)
CDvLastFramePacket *LastFrame; CDvLastFramePacket *LastFrame;
// handle incoming packets // 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 // crack the packet
if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL ) if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL )
@ -110,7 +99,7 @@ void CDplusProtocol::Task(void)
std::cout << "DPlus connect request packet from " << Ip << std::endl; std::cout << "DPlus connect request packet from " << Ip << std::endl;
// acknowledge the request // acknowledge the request
m_Socket.Send(Buffer, Ip); Send(Buffer, Ip);
} }
else if ( IsValidLoginPacket(Buffer, &Callsign) ) else if ( IsValidLoginPacket(Buffer, &Callsign) )
{ {
@ -121,7 +110,7 @@ void CDplusProtocol::Task(void)
{ {
// acknowledge the request // acknowledge the request
EncodeLoginAckPacket(&Buffer); EncodeLoginAckPacket(&Buffer);
m_Socket.Send(Buffer, Ip); Send(Buffer, Ip);
// create the client // create the client
CDplusClient *client = new CDplusClient(Callsign, Ip); CDplusClient *client = new CDplusClient(Callsign, Ip);
@ -134,7 +123,7 @@ void CDplusProtocol::Task(void)
{ {
// deny the request // deny the request
EncodeLoginNackPacket(&Buffer); EncodeLoginNackPacket(&Buffer);
m_Socket.Send(Buffer, Ip); Send(Buffer, Ip);
} }
} }
@ -151,7 +140,7 @@ void CDplusProtocol::Task(void)
clients->RemoveClient(client); clients->RemoveClient(client);
// and acknowledge the disconnect // and acknowledge the disconnect
EncodeDisconnectPacket(&Buffer); EncodeDisconnectPacket(&Buffer);
m_Socket.Send(Buffer, Ip); Send(Buffer, Ip);
} }
g_Reflector.ReleaseClients(); g_Reflector.ReleaseClients();
} }
@ -313,7 +302,7 @@ void CDplusProtocol::HandleQueue(void)
else if ( packet->IsDvFrame() ) else if ( packet->IsDvFrame() )
{ {
// and send the DV frame // and send the DV frame
m_Socket.Send(buffer, client->GetIp()); Send(buffer, client->GetIp());
// is it time to insert a DVheader copy ? // is it time to insert a DVheader copy ?
if ( (m_StreamsCache[iModId].m_iSeqCounter++ % 21) == 20 ) if ( (m_StreamsCache[iModId].m_iSeqCounter++ % 21) == 20 )
@ -327,7 +316,7 @@ void CDplusProtocol::HandleQueue(void)
else else
{ {
// otherwise, send the original packet // 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) ) if ( EncodeDvPacket(packet2, &buffer2) )
{ {
// and send it // and send it
m_Socket.Send(buffer2, client->GetIp()); Send(buffer2, client->GetIp());
} }
// client type known ? // client type known ?
if ( !client->HasModule() ) if ( !client->HasModule() )
{ {
// no, send also the genuine packet // no, send also the genuine packet
m_Socket.Send(buffer, client->GetIp()); Send(buffer, client->GetIp());
} }
} }
else else
{ {
// otherwise, send the original packet // 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 // send keepalive
//std::cout << "Sending DPlus packet @ " << client->GetIp() << std::endl; //std::cout << "Sending DPlus packet @ " << client->GetIp() << std::endl;
m_Socket.Send(keepalive, client->GetIp()); Send(keepalive, client->GetIp());
// is this client busy ? // is this client busy ?
if ( client->IsAMaster() ) if ( client->IsAMaster() )
@ -409,7 +398,7 @@ void CDplusProtocol::HandleKeepalives(void)
// no, disconnect // no, disconnect
CBuffer disconnect; CBuffer disconnect;
EncodeDisconnectPacket(&disconnect); EncodeDisconnectPacket(&disconnect);
m_Socket.Send(disconnect, client->GetIp()); Send(disconnect, client->GetIp());
// and remove it // and remove it
std::cout << "DPlus client " << client->GetCallsign() << " keepalive timeout" << std::endl; std::cout << "DPlus client " << client->GetCallsign() << " keepalive timeout" << std::endl;

@ -43,7 +43,6 @@ class CDPlusStreamCacheItem
{ {
public: public:
CDPlusStreamCacheItem() { m_iSeqCounter = 0; } CDPlusStreamCacheItem() { m_iSeqCounter = 0; }
~CDPlusStreamCacheItem() {}
CDvHeaderPacket m_dvHeader; CDvHeaderPacket m_dvHeader;
uint8 m_iSeqCounter; uint8 m_iSeqCounter;
@ -52,12 +51,6 @@ public:
class CDplusProtocol : public CProtocol class CDplusProtocol : public CProtocol
{ {
public: public:
// constructor
CDplusProtocol() {};
// destructor
virtual ~CDplusProtocol() {};
// initialization // initialization
bool Init(void); bool Init(void);

@ -40,55 +40,58 @@
bool CG3Protocol::Init(void) bool CG3Protocol::Init(void)
{ {
bool ok;
ReadOptions(); ReadOptions();
// base class // init reflector apparent callsign
ok = CProtocol::Init(); m_ReflectorCallsign = g_Reflector.GetCallsign();
// update reflector callsign // reset stop flag
m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"XLX", 3); m_bStopThread = false;
// create our DV socket // update the reflector callsign
ok &= m_Socket.Open(G3_DV_PORT); m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"XLX", 3);
if ( !ok )
{ // create our sockets
std::cout << "Error opening socket on port UDP" << G3_DV_PORT << " on ip " << g_Reflector.GetListenIp() << std::endl; CIp ip(AF_INET, G3_DV_PORT, g_Reflector.GetListenIPv4());
} if ( ip.IsSet() )
{
//create helper sockets if (! m_Socket4.Open(ip))
ok &= m_PresenceSocket.Open(G3_PRESENCE_PORT); return false;
if ( !ok ) }
{ else
std::cout << "Error opening socket on port UDP" << G3_PRESENCE_PORT << " on ip " << g_Reflector.GetListenIp() << std::endl; 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); ip.SetPort(G3_CONFIG_PORT);
if ( !ok ) if (! m_ConfigSocket.Open(ip))
{ {
std::cout << "Error opening socket on port UDP" << G3_CONFIG_PORT << " on ip " << g_Reflector.GetListenIp() << std::endl; 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 (! m_IcmpRawSocket.Open(IPPROTO_ICMP))
if ( !ok )
{ {
std::cout << "Error opening raw socket for ICMP" << std::endl; std::cout << "Error opening raw socket for ICMP" << std::endl;
return false;
} }
if (ok) // start helper threads
{ m_pThread = new std::thread(CProtocol::Thread, this);
// start helper threads m_pPresenceThread = new std::thread(PresenceThread, this);
m_pPresenceThread = new std::thread(PresenceThread, this); m_pPresenceThread = new std::thread(ConfigThread, this);
m_pPresenceThread = new std::thread(ConfigThread, this); m_pPresenceThread = new std::thread(IcmpThread, this);
m_pPresenceThread = new std::thread(IcmpThread, this);
}
// update time // update time
m_LastKeepaliveTime.Now(); m_LastKeepaliveTime.Now();
// done // done
return ok; return true;
} }
void CG3Protocol::Close(void) void CG3Protocol::Close(void)
@ -390,7 +393,7 @@ void CG3Protocol::Task(void)
CDvLastFramePacket *LastFrame; CDvLastFramePacket *LastFrame;
// any incoming packet ? // any incoming packet ?
if ( m_Socket.Receive(Buffer, Ip, 20) != -1 ) if ( m_Socket4.Receive(Buffer, Ip, 20) )
{ {
CIp ClIp; CIp ClIp;
CIp *BaseIp = NULL; CIp *BaseIp = NULL;
@ -508,7 +511,7 @@ void CG3Protocol::HandleQueue(void)
int n = packet->IsDvHeader() ? 5 : 1; int n = packet->IsDvHeader() ? 5 : 1;
for ( int i = 0; i < n; i++ ) 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 else
{ {
// send keepalive packet // send keepalive packet
m_Socket.Send(keepalive, client->GetIp()); Send(keepalive, client->GetIp());
} }
} }
g_Reflector.ReleaseClients(); g_Reflector.ReleaseClients();

@ -64,10 +64,7 @@ class CG3Protocol : public CProtocol
{ {
public: public:
// constructor // constructor
CG3Protocol() : m_GwAddress(0u), m_Modules("*"), m_LastModTime(0) {}; CG3Protocol() : m_GwAddress(0u), m_Modules("*"), m_LastModTime(0) {}
// destructor
virtual ~CG3Protocol() {};
// initialization // initialization
bool Init(void); bool Init(void);

@ -22,14 +22,19 @@
#include <netdb.h> #include <netdb.h>
#include "cip.h" #include "cip.h"
CIp::CIp() CIp::CIp() : is_set(false)
{ {
Clear(); 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(); Clear();
if (0 == strncasecmp(address, "none", 4))
{
is_set = false;
return;
}
struct addrinfo hints, *result; struct addrinfo hints, *result;
bzero(&hints, sizeof(struct addrinfo)); bzero(&hints, sizeof(struct addrinfo));
hints.ai_family = family; hints.ai_family = family;
@ -41,7 +46,7 @@ CIp::CIp(const char *address, int family, int type, uint16_t port)
} }
SetPort(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); 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) void CIp::Initialize(const int family, const uint16_t port, const char *address)
{ {
Clear(); Clear();
if (0 == strncasecmp(address, "none", 4))
{
is_set = false;
return;
}
is_set = true;
addr.ss_family = family; addr.ss_family = family;
if (AF_INET == family) { if (AF_INET == family)
{
auto addr4 = (struct sockaddr_in *)&addr; auto addr4 = (struct sockaddr_in *)&addr;
addr4->sin_port = htons(port); addr4->sin_port = htons(port);
if (address) { if (address)
{
if (0 == strncasecmp(address, "loc", 3)) if (0 == strncasecmp(address, "loc", 3))
inet_pton(AF_INET, "127.0.0.1", &(addr4->sin_addr)); inet_pton(AF_INET, "127.0.0.1", &(addr4->sin_addr));
else if (0 == strncasecmp(address, "any", 3)) else if (0 == strncasecmp(address, "any", 3))
inet_pton(AF_INET, "0.0.0.0", &(addr4->sin_addr)); inet_pton(AF_INET, "0.0.0.0", &(addr4->sin_addr));
else if (0 == strncasecmp(address, "none", 4)) else
addr.ss_family = AF_UNSPEC; {
else {
if (1 > inet_pton(AF_INET, address, &(addr4->sin_addr))) if (1 > inet_pton(AF_INET, address, &(addr4->sin_addr)))
std::cerr << "Address Initialization Error: '" << address << "' is not a valdid IPV4 address!" << std::endl; 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; auto addr6 = (struct sockaddr_in6 *)&addr;
addr6->sin6_port = htons(port); addr6->sin6_port = htons(port);
if (address) { if (address)
{
if (0 == strncasecmp(address, "loc", 3)) if (0 == strncasecmp(address, "loc", 3))
inet_pton(AF_INET6, "::1", &(addr6->sin6_addr)); inet_pton(AF_INET6, "::1", &(addr6->sin6_addr));
else if (0 == strncasecmp(address, "any", 3)) else if (0 == strncasecmp(address, "any", 3))
inet_pton(AF_INET6, "::", &(addr6->sin6_addr)); inet_pton(AF_INET6, "::", &(addr6->sin6_addr));
else if (0 == strncasecmp(address, "none", 4)) else
addr.ss_family = AF_UNSPEC; {
else {
if (1 > inet_pton(AF_INET6, address, &(addr6->sin6_addr))) if (1 > inet_pton(AF_INET6, address, &(addr6->sin6_addr)))
std::cerr << "Address Initialization Error: '" << address << "' is not a valid IPV6 address!" << std::endl; 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; 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 bool CIp::operator==(const CIp &rhs) const // doesn't compare ports, only addresses and families
{ {
if (addr.ss_family != rhs.addr.ss_family) if (addr.ss_family != rhs.addr.ss_family)
return false; return false;
if (AF_INET == addr.ss_family) { if (AF_INET == addr.ss_family)
{
auto l = (struct sockaddr_in *)&addr; auto l = (struct sockaddr_in *)&addr;
auto r = (struct sockaddr_in *)&rhs.addr; auto r = (struct sockaddr_in *)&rhs.addr;
return (l->sin_addr.s_addr == r->sin_addr.s_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 l = (struct sockaddr_in6 *)&addr;
auto r = (struct sockaddr_in6 *)&rhs.addr; auto r = (struct sockaddr_in6 *)&rhs.addr;
return (0 == memcmp(&(l->sin6_addr), &(r->sin6_addr), sizeof(struct in6_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) if (addr.ss_family != rhs.addr.ss_family)
return true; return true;
if (AF_INET == addr.ss_family) { if (AF_INET == addr.ss_family)
{
auto l = (struct sockaddr_in *)&addr; auto l = (struct sockaddr_in *)&addr;
auto r = (struct sockaddr_in *)&rhs.addr; auto r = (struct sockaddr_in *)&rhs.addr;
return (l->sin_addr.s_addr != r->sin_addr.s_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 l = (struct sockaddr_in6 *)&addr;
auto r = (struct sockaddr_in6 *)&rhs.addr; auto r = (struct sockaddr_in6 *)&rhs.addr;
return (0 != memcmp(&(l->sin6_addr), &(r->sin6_addr), sizeof(struct in6_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 bool CIp::AddressIsZero() const
{ {
if (AF_INET == addr.ss_family) { if (AF_INET == addr.ss_family)
auto addr4 = (struct sockaddr_in *)&addr; {
auto addr4 = (struct sockaddr_in *)&addr;
return (addr4->sin_addr.s_addr == 0U); return (addr4->sin_addr.s_addr == 0U);
} else { }
else
{
auto addr6 = (struct sockaddr_in6 *)&addr; 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]) if (addr6->sin6_addr.s6_addr[i])
return false; return false;
} }
@ -133,11 +163,14 @@ bool CIp::AddressIsZero() const
void CIp::ClearAddress() void CIp::ClearAddress()
{ {
if (AF_INET == addr.ss_family) { if (AF_INET == addr.ss_family)
{
auto addr4 = (struct sockaddr_in *)&addr; auto addr4 = (struct sockaddr_in *)&addr;
addr4->sin_addr.s_addr = 0U; addr4->sin_addr.s_addr = 0U;
strcpy(straddr, "0.0.0.0"); strcpy(straddr, "0.0.0.0");
} else { }
else
{
auto addr6 = (struct sockaddr_in6 *)&addr; auto addr6 = (struct sockaddr_in6 *)&addr;
memset(&(addr6->sin6_addr.s6_addr), 0, 16); memset(&(addr6->sin6_addr.s6_addr), 0, 16);
strcpy(straddr, "::"); strcpy(straddr, "::");
@ -149,13 +182,18 @@ const char *CIp::GetAddress() const
if (straddr[0]) if (straddr[0])
return straddr; return straddr;
if (AF_INET == addr.ss_family) { if (AF_INET == addr.ss_family)
{
auto addr4 = (struct sockaddr_in *)&addr; auto addr4 = (struct sockaddr_in *)&addr;
inet_ntop(AF_INET, &(addr4->sin_addr), straddr, INET6_ADDRSTRLEN); 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; auto addr6 = (struct sockaddr_in6 *)&addr;
inet_ntop(AF_INET6, &(addr6->sin6_addr), straddr, INET6_ADDRSTRLEN); inet_ntop(AF_INET6, &(addr6->sin6_addr), straddr, INET6_ADDRSTRLEN);
} else { }
else
{
std::cerr << "CIp::GetAddress: unknown socket family=" << addr.ss_family << std::endl; std::cerr << "CIp::GetAddress: unknown socket family=" << addr.ss_family << std::endl;
} }
return straddr; return straddr;
@ -176,12 +214,15 @@ std::ostream &operator<<(std::ostream &stream, const CIp &Ip)
uint32_t CIp::GetAddr() const uint32_t CIp::GetAddr() const
{ {
if (AF_INET6 == addr.ss_family) { if (AF_INET6 == addr.ss_family)
{
auto addr6 = (struct sockaddr_in6 *)&addr; auto addr6 = (struct sockaddr_in6 *)&addr;
// hash the results // hash the results
auto *a = (const uint32_t *)&(addr6->sin6_addr.s6_addr); auto *a = (const uint32_t *)&(addr6->sin6_addr.s6_addr);
return a[0] ^ a[1] ^ a[2] ^ a[3]; return a[0] ^ a[1] ^ a[2] ^ a[3];
} else { }
else
{
auto addr4 = (struct sockaddr_in *)&addr; auto addr4 = (struct sockaddr_in *)&addr;
return addr4->sin_addr.s_addr; return addr4->sin_addr.s_addr;
} }
@ -194,10 +235,13 @@ int CIp::GetFamily() const
uint16_t CIp::GetPort() const uint16_t CIp::GetPort() const
{ {
if (AF_INET == addr.ss_family) { if (AF_INET == addr.ss_family)
{
auto addr4 = (struct sockaddr_in *)&addr; auto addr4 = (struct sockaddr_in *)&addr;
return ntohs(addr4->sin_port); 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; auto addr6 = (struct sockaddr_in6 *)&addr;
return ntohs(addr6->sin6_port); return ntohs(addr6->sin6_port);
} else } else
@ -206,10 +250,13 @@ uint16_t CIp::GetPort() const
void CIp::SetPort(const uint16_t newport) 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; auto addr4 = (struct sockaddr_in *)&addr;
addr4->sin_port = htons(newport); 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; auto addr6 = (struct sockaddr_in6 *)&addr;
addr6->sin6_port = htons(newport); addr6->sin6_port = htons(newport);
} }
@ -238,4 +285,5 @@ void CIp::Clear()
{ {
memset(&addr, 0, sizeof(struct sockaddr_storage)); memset(&addr, 0, sizeof(struct sockaddr_storage));
memset(straddr, 0, INET6_ADDRSTRLEN); memset(straddr, 0, INET6_ADDRSTRLEN);
is_set = false;
} }

@ -46,6 +46,7 @@ public:
bool operator!=(const CIp &rhs) const; bool operator!=(const CIp &rhs) const;
// state methods // state methods
bool IsSet() const { return is_set; }
bool AddressIsZero() const; bool AddressIsZero() const;
void ClearAddress(); void ClearAddress();
const char *GetAddress() const; const char *GetAddress() const;
@ -68,6 +69,7 @@ public:
private: private:
struct sockaddr_storage addr; struct sockaddr_storage addr;
mutable char straddr[INET6_ADDRSTRLEN]; mutable char straddr[INET6_ADDRSTRLEN];
bool is_set;
}; };
std::ostream &operator<<(std::ostream &stream, const CIp &Ip); std::ostream &operator<<(std::ostream &stream, const CIp &Ip);

@ -33,11 +33,7 @@
// constructor // constructor
CProtocol::CProtocol() CProtocol::CProtocol() : m_bStopThread(false), m_pThread(NULL) {}
{
m_bStopThread = false;
m_pThread = NULL;
}
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
@ -53,6 +49,10 @@ CProtocol::~CProtocol()
delete m_pThread; delete m_pThread;
} }
// Close sockets
m_Socket6.Close();
m_Socket4.Close();
// empty queue // empty queue
m_Queue.Lock(); m_Queue.Lock();
while ( !m_Queue.empty() ) while ( !m_Queue.empty() )
@ -65,7 +65,7 @@ CProtocol::~CProtocol()
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
// initialization // initialization
bool CProtocol::Init(void) bool CProtocol::Initialize(const char *type, uint16 port)
{ {
// init reflector apparent callsign // init reflector apparent callsign
m_ReflectorCallsign = g_Reflector.GetCallsign(); m_ReflectorCallsign = g_Reflector.GetCallsign();
@ -73,13 +73,49 @@ bool CProtocol::Init(void)
// reset stop flag // reset stop flag
m_bStopThread = false; 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; // 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 // done
return true; return true;
} }
void CProtocol::Thread(CProtocol *This)
{
while (! This->m_bStopThread)
{
This->Task();
}
}
void CProtocol::Close(void) void CProtocol::Close(void)
{ {
m_bStopThread = true; m_bStopThread = true;
@ -89,18 +125,8 @@ void CProtocol::Close(void)
delete m_pThread; delete m_pThread;
m_pThread = NULL; m_pThread = NULL;
} }
} m_Socket4.Close();
m_Socket6.Close();
////////////////////////////////////////////////////////////////////////////////////////
// thread
void CProtocol::Thread(CProtocol *This)
{
while ( !This->m_bStopThread )
{
This->Task();
}
} }
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
@ -263,3 +289,66 @@ uint32 CProtocol::ModuleToDmrDestId(char m) const
{ {
return (uint32)(m - 'A')+1; 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;
}
}

@ -77,7 +77,7 @@ public:
virtual ~CProtocol(); virtual ~CProtocol();
// initialization // initialization
virtual bool Init(void); bool Initialize(const char *, uint16);
virtual void Close(void); virtual void Close(void);
// queue // queue
@ -89,7 +89,7 @@ public:
// task // task
static void Thread(CProtocol *); static void Thread(CProtocol *);
virtual void Task(void) {} virtual void Task(void) = 0;
protected: protected:
// packet encoding helpers // packet encoding helpers
@ -122,9 +122,13 @@ protected:
virtual char DmrDstIdToModule(uint32) const; virtual char DmrDstIdToModule(uint32) const;
virtual uint32 ModuleToDmrDestId(char) 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 // socket
CUdpSocket m_Socket; CUdpSocket m_Socket4, m_Socket6;
// streams // streams
std::list<CPacketStream *> m_Streams; std::list<CPacketStream *> m_Streams;

@ -33,18 +33,6 @@
#include "cg3protocol.h" #include "cg3protocol.h"
#include "cprotocols.h" #include "cprotocols.h"
////////////////////////////////////////////////////////////////////////////////////////
// constructor
CProtocols::CProtocols()
{
for ( int i = 0; i < m_Protocols.size(); i++ )
{
m_Protocols[i] = NULL;
}
}
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
// destructor // destructor
@ -52,10 +40,12 @@ CProtocols::~CProtocols()
{ {
m_Mutex.lock(); m_Mutex.lock();
{ {
for ( int i = 0; i < m_Protocols.size(); i++ ) for ( auto it=m_Protocols.begin(); it!=m_Protocols.end(); it++)
{ {
delete m_Protocols[i]; (*it)->Close();
} delete *it;
}
m_Protocols.clear();
} }
m_Mutex.unlock(); m_Mutex.unlock();
} }
@ -65,65 +55,105 @@ CProtocols::~CProtocols()
bool CProtocols::Init(void) bool CProtocols::Init(void)
{ {
bool ok = true;
m_Mutex.lock(); m_Mutex.lock();
{ {
// create and initialize DEXTRA auto dextra = new CDextraProtocol;
delete m_Protocols[0]; if (dextra->Init())
m_Protocols[0] = new CDextraProtocol; m_Protocols.push_back(dextra);
ok &= m_Protocols[0]->Init(); else
{
delete dextra;
return false;
}
// create and initialize DPLUS // create and initialize DPLUS
delete m_Protocols[1]; auto dplus = new CDplusProtocol;
m_Protocols[1] = new CDplusProtocol; if (dplus->Init())
ok &= m_Protocols[1]->Init(); m_Protocols.push_back(dplus);
else
{
delete dplus;
return false;
}
// create and initialize DCS // create and initialize DCS
delete m_Protocols[2]; auto dcs = new CDcsProtocol;
m_Protocols[2] = new CDcsProtocol; if (dcs->Init())
ok &= m_Protocols[2]->Init(); m_Protocols.push_back(dcs);
else
{
delete dcs;
return false;
}
// create and initialize XLX - interlink // create and initialize XLX - interlink
delete m_Protocols[3]; auto xlx = new CXlxProtocol;
m_Protocols[3] = new CXlxProtocol; if (xlx->Init())
ok &= m_Protocols[3]->Init(); m_Protocols.push_back(xlx);
else
{
delete xlx;
return false;
}
// create and initialize DMRPLUS // create and initialize DMRPLUS
delete m_Protocols[4]; auto dmrplus = new CDmrplusProtocol;
m_Protocols[4] = new CDmrplusProtocol; if (dmrplus->Init())
ok &= m_Protocols[4]->Init(); m_Protocols.push_back(dmrplus);
else
{
delete dmrplus;
return false;
}
// create and initialize DMRMMDVM // create and initialize DMRMMDVM
delete m_Protocols[5]; auto dmrmmdvm = new CDmrmmdvmProtocol;
m_Protocols[5] = new CDmrmmdvmProtocol; if (dmrmmdvm->Init())
ok &= m_Protocols[5]->Init(); m_Protocols.push_back(dmrmmdvm);
else
{
delete dmrmmdvm;
return false;
}
// create and initialize YSF // create and initialize YSF
delete m_Protocols[6]; auto ysf = new CYsfProtocol;
m_Protocols[6] = new CYsfProtocol; if (ysf->Init())
ok &= m_Protocols[6]->Init(); m_Protocols.push_back(ysf);
else
{
delete ysf;
return false;
}
// create and initialize G3 // create and initialize G3
delete m_Protocols[7]; auto g3 = new CG3Protocol;
m_Protocols[7] = new CG3Protocol; if (g3->Init())
ok &= m_Protocols[7]->Init(); m_Protocols.push_back(g3);
else
{
delete g3;
return true;
}
} }
m_Mutex.unlock(); m_Mutex.unlock();
// done // done
return ok; return true;
} }
void CProtocols::Close(void) void CProtocols::Close(void)
{ {
m_Mutex.lock(); m_Mutex.lock();
{ {
for ( int i = 0; i < m_Protocols.size(); i++ ) for ( auto it=m_Protocols.begin(); it!=m_Protocols.end(); it++)
{ {
m_Protocols[i]->Close(); (*it)->Close();
} delete *it;
}
m_Protocols.clear();
} }
m_Mutex.unlock(); m_Mutex.unlock();
} }

@ -38,24 +38,21 @@
class CProtocols class CProtocols
{ {
public: public:
// constructors
CProtocols();
// destructors // destructors
virtual ~CProtocols(); ~CProtocols();
// initialization // initialization
bool Init(void); bool Init(void);
void Close(void); void Close(void);
// get // pass-thru
int Size(void) const { return (int)m_Protocols.size(); } std::list<CProtocol *>::iterator begin() { return m_Protocols.begin(); }
CProtocol *GetProtocol(int i) { return m_Protocols[i]; } std::list<CProtocol *>::iterator end() { return m_Protocols.end(); }
protected: protected:
// data // data
std::mutex m_Mutex; std::mutex m_Mutex;
std::array<CProtocol *, NB_OF_PROTOCOLS> m_Protocols; std::list<CProtocol *> m_Protocols;
}; };

@ -348,27 +348,24 @@ void CReflector::RouterThread(CReflector *This, CPacketStream *streamIn)
packet->SetModuleId(uiModuleId); packet->SetModuleId(uiModuleId);
// iterate on all protocols // 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 // duplicate packet
CPacket *packetClone = packet->Duplicate(); CPacket *packetClone = packet->Duplicate();
// get protocol
CProtocol *protocol = This->m_Protocols.GetProtocol(i);
// if packet is header, update RPT2 according to protocol // if packet is header, update RPT2 according to protocol
if ( packetClone->IsDvHeader() ) if ( packetClone->IsDvHeader() )
{ {
// get our callsign // get our callsign
CCallsign csRPT = protocol->GetReflectorCallsign(); CCallsign csRPT = (*it)->GetReflectorCallsign();
csRPT.SetModule(This->GetStreamModule(streamIn)); csRPT.SetModule(This->GetStreamModule(streamIn));
((CDvHeaderPacket *)packetClone)->SetRpt2Callsign(csRPT); ((CDvHeaderPacket *)packetClone)->SetRpt2Callsign(csRPT);
} }
// and push it // and push it
CPacketQueue *queue = protocol->GetQueue(); CPacketQueue *queue = (*it)->GetQueue();
queue->push(packetClone); queue->push(packetClone);
protocol->ReleaseQueue(); (*it)->ReleaseQueue();
} }
// done // done
delete packet; delete packet;

@ -4,6 +4,7 @@
// //
// Created by Jean-Luc Deltombe (LX3JL) on 31/10/2015. // Created by Jean-Luc Deltombe (LX3JL) on 31/10/2015.
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved. // Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
// Copyright © 2020 Thomas A. Early, N7TAE
// //
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// This file is part of xlxd. // This file is part of xlxd.
@ -55,12 +56,14 @@ public:
virtual ~CReflector(); virtual ~CReflector();
// settings // settings
void SetCallsign(const CCallsign &callsign) { m_Callsign = callsign; } void SetCallsign(const CCallsign &callsign) { m_Callsign = callsign; }
const CCallsign &GetCallsign(void) const { return m_Callsign; } const CCallsign &GetCallsign(void) const { return m_Callsign; }
void SetListenIp(const CIp &ip) { m_Ip = ip; } void SetListenIPv4(const char *a, const int n) { memset(m_IPv4, 0, n); strncpy(m_IPv4, a, n-1); }
void SetTranscoderIp(const CIp &ip) { m_AmbedIp = ip; } void SetListenIPv6(const char *a, const int n) { memset(m_IPv6, 0, n); strncpy(m_IPv6, a, n-1); }
const CIp &GetListenIp(void) const { return m_Ip; } void SetTranscoderIp(const char *a, const int n) { memset(m_AmbedIp, 0, n); strncpy(m_AmbedIp, a, n-1); }
const CIp &GetTranscoderIp(void) const { return m_AmbedIp; } 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 // operation
bool Start(void); bool Start(void);
@ -118,9 +121,10 @@ protected:
protected: protected:
// identity // identity
CCallsign m_Callsign; CCallsign m_Callsign;
CIp m_Ip; char m_IPv4[INET_ADDRSTRLEN];
CIp m_AmbedIp; char m_IPv6[INET6_ADDRSTRLEN];
char m_AmbedIp[INET6_ADDRSTRLEN];
// objects // objects
CUsers m_Users; // sorted list of lastheard stations CUsers m_Users; // sorted list of lastheard stations

@ -75,22 +75,27 @@ bool CTranscoder::Init(void)
m_bStopThread = false; m_bStopThread = false;
// create server's IP // 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 // create our socket
ok = m_Socket.Open(TRANSCODER_PORT); if (m_Ip.IsSet())
if ( ok ) {
{ if (! m_Socket.Open(TRANSCODER_PORT)) {
// start thread; std::cerr << "Error opening socket on port UDP" << TRANSCODER_PORT << " on ip " << m_Ip << std::endl;
m_pThread = new std::thread(CTranscoder::Thread, this); return false;
} }
else }
{ else
std::cout << "Error opening socket on port UDP" << TRANSCODER_PORT << " on ip " << g_Reflector.GetListenIp() << std::endl; {
} std::cerr << "Could not initialize transcoder socket on " << m_Ip << std::endl;
return false;
// done }
return ok;
// start thread;
m_pThread = new std::thread(CTranscoder::Thread, this);
return true;
} }
void CTranscoder::Close(void) void CTranscoder::Close(void)

@ -28,12 +28,12 @@
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
// open // open
bool CUdpMsgSocket::Open(uint16 uiPort) bool CUdpMsgSocket::Open(const CIp &ip)
{ {
bool ret; bool ret;
int on = 1; int on = 1;
ret = CUdpSocket::Open(uiPort); ret = CUdpSocket::Open(ip);
setsockopt(m_fd, IPPROTO_IP, IP_PKTINFO, (char *)&on, sizeof(on)); setsockopt(m_fd, IPPROTO_IP, IP_PKTINFO, (char *)&on, sizeof(on));
return ret; return ret;

@ -40,7 +40,7 @@ class CUdpMsgSocket : public CUdpSocket
{ {
public: public:
// open // open
bool Open(uint16); bool Open(const CIp &ip);
// read // read
int Receive(CBuffer *, CIp *, int); int Receive(CBuffer *, CIp *, int);

@ -37,27 +37,15 @@
bool CXlxProtocol::Init(void) bool CXlxProtocol::Init(void)
{ {
bool ok; if (! Initialize("XLX", XLX_PORT))
return false;
// 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 // update time
m_LastKeepaliveTime.Now(); m_LastKeepaliveTime.Now();
m_LastPeersLinkTime.Now(); m_LastPeersLinkTime.Now();
// done // done
return ok; return true;
} }
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
@ -75,7 +63,7 @@ void CXlxProtocol::Task(void)
CDvLastFramePacket *LastFrame; CDvLastFramePacket *LastFrame;
// any incoming packet ? // 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 // crack the packet
if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL ) if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL )
@ -130,7 +118,7 @@ void CXlxProtocol::Task(void)
{ {
// acknowledge the request // acknowledge the request
EncodeConnectAckPacket(&Buffer, Modules); EncodeConnectAckPacket(&Buffer, Modules);
m_Socket.Send(Buffer, Ip); Send(Buffer, Ip);
} }
g_Reflector.ReleasePeers(); g_Reflector.ReleasePeers();
@ -141,7 +129,7 @@ void CXlxProtocol::Task(void)
default: default:
// acknowledge the request // acknowledge the request
EncodeConnectAckPacket(&Buffer, Modules); EncodeConnectAckPacket(&Buffer, Modules);
m_Socket.Send(Buffer, Ip); Send(Buffer, Ip);
break; break;
} }
} }
@ -149,7 +137,7 @@ void CXlxProtocol::Task(void)
{ {
// deny the request // deny the request
EncodeConnectNackPacket(&Buffer); EncodeConnectNackPacket(&Buffer);
m_Socket.Send(Buffer, Ip); Send(Buffer, Ip);
} }
} }
else if ( IsValidAckPacket(Buffer, &Callsign, Modules, &Version) ) else if ( IsValidAckPacket(Buffer, &Callsign, Modules, &Version) )
@ -284,17 +272,17 @@ void CXlxProtocol::HandleQueue(void)
{ {
case XLX_PROTOCOL_REVISION_0: case XLX_PROTOCOL_REVISION_0:
case XLX_PROTOCOL_REVISION_1: case XLX_PROTOCOL_REVISION_1:
m_Socket.Send(bufferLegacy, client->GetIp()); Send(bufferLegacy, client->GetIp());
break; break;
case XLX_PROTOCOL_REVISION_2: case XLX_PROTOCOL_REVISION_2:
default: default:
if ( g_Transcoder.IsConnected() ) if ( g_Transcoder.IsConnected() )
{ {
m_Socket.Send(buffer, client->GetIp()); Send(buffer, client->GetIp());
} }
else else
{ {
m_Socket.Send(bufferLegacy, client->GetIp()); Send(bufferLegacy, client->GetIp());
} }
break; break;
} }
@ -328,7 +316,7 @@ void CXlxProtocol::HandleKeepalives(void)
while ( (peer = peers->FindNextPeer(PROTOCOL_XLX, pit)) != NULL ) while ( (peer = peers->FindNextPeer(PROTOCOL_XLX, pit)) != NULL )
{ {
// send keepalive // send keepalive
m_Socket.Send(keepalive, peer->GetIp()); Send(keepalive, peer->GetIp());
// client busy ? // client busy ?
if ( peer->IsAMaster() ) if ( peer->IsAMaster() )
@ -342,7 +330,7 @@ void CXlxProtocol::HandleKeepalives(void)
// no, disconnect // no, disconnect
CBuffer disconnect; CBuffer disconnect;
EncodeDisconnectPacket(&disconnect); EncodeDisconnectPacket(&disconnect);
m_Socket.Send(disconnect, peer->GetIp()); Send(disconnect, peer->GetIp());
// remove it // remove it
std::cout << "XLX peer " << peer->GetCallsign() << " keepalive timeout" << std::endl; std::cout << "XLX peer " << peer->GetCallsign() << " keepalive timeout" << std::endl;
@ -373,7 +361,7 @@ void CXlxProtocol::HandlePeerLinks(void)
{ {
// send disconnect packet // send disconnect packet
EncodeDisconnectPacket(&buffer); EncodeDisconnectPacket(&buffer);
m_Socket.Send(buffer, peer->GetIp()); Send(buffer, peer->GetIp());
std::cout << "Sending disconnect packet to XLX peer " << peer->GetCallsign() << std::endl; std::cout << "Sending disconnect packet to XLX peer " << peer->GetCallsign() << std::endl;
// remove client // remove client
peers->RemovePeer(peer); peers->RemovePeer(peer);
@ -392,7 +380,7 @@ void CXlxProtocol::HandlePeerLinks(void)
(*it).ResolveIp(); (*it).ResolveIp();
// send connect packet to re-initiate peer link // send connect packet to re-initiate peer link
EncodeConnectPacket(&buffer, (*it).GetModules()); 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; std::cout << "Sending connect packet to XLX peer " << (*it).GetCallsign() << " @ " << (*it).GetIp() << " for modules " << (*it).GetModules() << std::endl;
} }
} }

@ -40,12 +40,6 @@ class CPeer;
class CXlxProtocol : public CDextraProtocol class CXlxProtocol : public CDextraProtocol
{ {
public: public:
// constructor
CXlxProtocol() {};
// destructor
virtual ~CXlxProtocol() {};
// initialization // initialization
bool Init(void); bool Init(void);

@ -47,29 +47,19 @@ CYsfProtocol::CYsfProtocol()
bool CYsfProtocol::Init(void) bool CYsfProtocol::Init(void)
{ {
bool ok;
// base class // base class
ok = CProtocol::Init(); if (! Initialize("YSF", YSF_PORT))
return false;
// 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;
}
// init the wiresx cmd handler // init the wiresx cmd handler
ok &= m_WiresxCmdHandler.Init(); if (! m_WiresxCmdHandler.Init())
return false;
// update time // update time
m_LastKeepaliveTime.Now(); m_LastKeepaliveTime.Now();
// done // done
return ok; return true;
} }
void CYsfProtocol::Close(void) void CYsfProtocol::Close(void)
@ -105,13 +95,13 @@ void CYsfProtocol::Task(void)
{ {
CWiresxPacket packet = queue->front(); CWiresxPacket packet = queue->front();
queue->pop(); queue->pop();
m_Socket.Send(packet.GetBuffer(), packet.GetIp()); Send(packet.GetBuffer(), packet.GetIp());
} }
m_WiresxCmdHandler.ReleasePacketQueue(); m_WiresxCmdHandler.ReleasePacketQueue();
} }
// handle incoming packets // 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 // crack the packet
if ( IsValidDvPacket(Buffer, &Fich) ) if ( IsValidDvPacket(Buffer, &Fich) )
@ -164,7 +154,7 @@ void CYsfProtocol::Task(void)
{ {
// acknowledge the request // acknowledge the request
EncodeConnectAckPacket(&Buffer); EncodeConnectAckPacket(&Buffer);
m_Socket.Send(Buffer, Ip); Send(Buffer, Ip);
// add client if needed // add client if needed
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
@ -207,7 +197,7 @@ void CYsfProtocol::Task(void)
std::cout << "YSF server status enquiry from " << Ip << std::endl; std::cout << "YSF server status enquiry from " << Ip << std::endl;
// reply // reply
EncodeServerStatusPacket(&Buffer); EncodeServerStatusPacket(&Buffer);
m_Socket.Send(Buffer, Ip); Send(Buffer, Ip);
} }
else else
{ {
@ -359,7 +349,7 @@ void CYsfProtocol::HandleQueue(void)
if ( !client->IsAMaster() && (client->GetReflectorModule() == packet->GetModuleId()) ) if ( !client->IsAMaster() && (client->GetReflectorModule() == packet->GetModuleId()) )
{ {
// no, send the packet // no, send the packet
m_Socket.Send(buffer, client->GetIp()); Send(buffer, client->GetIp());
} }
} }

@ -25,7 +25,6 @@
#include "main.h" #include "main.h"
#include "creflector.h" #include "creflector.h"
#include "syslog.h"
#include <sys/stat.h> #include <sys/stat.h>
@ -41,99 +40,58 @@ CReflector g_Reflector;
int main(int argc, const char * argv[]) 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 // check arguments
if ( argc != 4 ) if ( argc != 5 )
{ {
std::cout << "Usage: xlxd callsign xlxdip ambedip" << std::endl; std::cout << "Usage: " << argv[0] << " callsign ipv4 ipv6 ambedip" << std::endl;
std::cout << "example: xlxd XLX999 192.168.178.212 127.0.0.1" << std::endl; std::cout << "example: " << argv[0] << " XLX999 192.168.178.212 2001:400:534::675b 127.0.0.1" << std::endl;
return 1; 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 // 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 // initialize reflector
g_Reflector.SetCallsign(argv[1]); g_Reflector.SetCallsign(argv[1]);
g_Reflector.SetListenIp(CIp(argv[2])); g_Reflector.SetListenIPv4(argv[2], INET_ADDRSTRLEN);
g_Reflector.SetTranscoderIp(CIp(CIp(argv[3]))); g_Reflector.SetListenIPv6(argv[3], INET6_ADDRSTRLEN);
g_Reflector.SetTranscoderIp(argv[4], INET6_ADDRSTRLEN);
// and let it run // and let it run
if ( !g_Reflector.Start() ) if ( !g_Reflector.Start() )
{ {
std::cout << "Error starting reflector" << std::endl; std::cout << "Error starting reflector" << std::endl;
exit(EXIT_FAILURE); return EXIT_FAILURE;
} }
std::cout << "Reflector " << g_Reflector.GetCallsign()
<< "started and listening on " << g_Reflector.GetListenIp() << std::endl;
#ifdef RUN_AS_DAEMON std::cout << "Reflector " << g_Reflector.GetCallsign() << "started and listening on ";
// run forever if (! is4none)
while ( true ) {
{ std::cout << g_Reflector.GetListenIPv4();
// sleep 60 seconds if (! is6none)
CTimePoint::TaskSleepFor(60000); {
} std::cout << " and " << g_Reflector.GetListenIPv4() << std::endl;
#else }
// wait any key }
for (;;) else
{ {
// sleep 60 seconds std::cout << g_Reflector.GetListenIPv6() << std::endl;
CTimePoint::TaskSleepFor(60000); }
#ifdef DEBUG_DUMPFILE
g_Reflector.m_DebugFile.close(); pause(); // wait for any signal
#endif
}
#endif
// and wait for end
g_Reflector.Stop(); g_Reflector.Stop();
std::cout << "Reflector stopped" << std::endl; std::cout << "Reflector stopped" << std::endl;
// done // done
exit(EXIT_SUCCESS); return EXIT_SUCCESS;
} }

Loading…
Cancel
Save

Powered by TurnKey Linux.