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

@ -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)

@ -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;

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

@ -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;
}
}

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

@ -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;

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

@ -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;

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

@ -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;

@ -43,7 +43,6 @@ 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);

@ -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();

@ -64,10 +64,7 @@ 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);

@ -22,14 +22,19 @@
#include <netdb.h>
#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;
}

@ -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);

@ -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;
}
}

@ -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<CPacketStream *> m_Streams;

@ -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();
}

@ -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<CProtocol *>::iterator begin() { return m_Protocols.begin(); }
std::list<CProtocol *>::iterator end() { return m_Protocols.end(); }
protected:
// data
std::mutex m_Mutex;
std::array<CProtocol *, NB_OF_PROTOCOLS> m_Protocols;
std::mutex m_Mutex;
std::list<CProtocol *> m_Protocols;
};

@ -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;

@ -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.
@ -55,12 +56,14 @@ public:
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);
@ -118,9 +121,10 @@ protected:
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

@ -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)

@ -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;

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

@ -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;
}
}

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

@ -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());
}
}

@ -25,7 +25,6 @@
#include "main.h"
#include "creflector.h"
#include "syslog.h"
#include <sys/stat.h>
@ -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);
return 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
}
#endif
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
// and wait for end
g_Reflector.Stop();
std::cout << "Reflector stopped" << std::endl;
// done
exit(EXIT_SUCCESS);
return EXIT_SUCCESS;
}

Loading…
Cancel
Save

Powered by TurnKey Linux.