CClients::m_Clients is a list

pull/1/head
Tom Early 6 years ago
parent b7a77491a4
commit 811e950e91

@ -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.
@ -19,7 +20,7 @@
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>. // along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#include "main.h" #include "main.h"
@ -33,7 +34,6 @@
CClients::CClients() CClients::CClients()
{ {
m_Clients.reserve(100);
} }
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
@ -42,14 +42,11 @@ CClients::CClients()
CClients::~CClients() CClients::~CClients()
{ {
m_Mutex.lock(); m_Mutex.lock();
{ for ( auto it=begin(); it!=end(); it++ )
for ( int i = 0; i < m_Clients.size(); i++ ) {
{ delete *it;
delete m_Clients[i]; }
} m_Clients.clear();
m_Clients.clear();
}
m_Mutex.unlock(); m_Mutex.unlock();
} }
@ -59,93 +56,69 @@ CClients::~CClients()
void CClients::AddClient(CClient *client) void CClients::AddClient(CClient *client)
{ {
// first check if client already exists // first check if client already exists
bool found = false; for ( auto it=begin(); it!=end(); it++ )
for ( int i = 0; (i < m_Clients.size()) && !found; i++ )
{ {
found = (*client == *m_Clients[i]); if (*client == *(*it))
// if found, just do nothing // if found, just do nothing
// so *client keep pointing on a valid object // so *client keep pointing on a valid object
// on function return // on function return
if ( found )
{ {
// delete new one // delete new one
delete client; delete client;
//std::cout << "Adding existing client " << client->GetCallsign() << " at " << client->GetIp() << std::endl; return;
} }
} }
// if not, append to the vector // and append
if ( !found ) m_Clients.push_back(client);
{ std::cout << "New client " << client->GetCallsign() << " at " << client->GetIp()
// grow vector capacity if needed << " added with protocol " << client->GetProtocolName();
if ( m_Clients.capacity() == m_Clients.size() ) if ( client->GetReflectorModule() != ' ' )
{ {
m_Clients.reserve(m_Clients.capacity()+10); std::cout << " on module " << client->GetReflectorModule();
} }
// and append std::cout << std::endl;
m_Clients.push_back(client); // notify
std::cout << "New client " << client->GetCallsign() << " at " << client->GetIp() g_Reflector.OnClientsChanged();
<< " added with protocol " << client->GetProtocolName();
if ( client->GetReflectorModule() != ' ' )
{
std::cout << " on module " << client->GetReflectorModule();
}
std::cout << std::endl;
// notify
g_Reflector.OnClientsChanged();
}
} }
void CClients::RemoveClient(CClient *client) void CClients::RemoveClient(CClient *client)
{ {
// look for the client // look for the client
bool found = false; bool found = false;
for ( int i = 0; (i < m_Clients.size()) && !found; i++ ) for ( auto it=begin(); it!=end(); it++ )
{ {
// compare objetc pointers // compare objetc pointers
if ( (m_Clients[i]) == client ) if ( *it == client )
{ {
// found it ! // found it !
if ( !m_Clients[i]->IsAMaster() ) if ( !(*it)->IsAMaster() )
{ {
// remove it // remove it
std::cout << "Client " << m_Clients[i]->GetCallsign() << " at " << m_Clients[i]->GetIp() std::cout << "Client " << (*it)->GetCallsign() << " at " << (*it)->GetIp() << " removed with protocol " << (*it)->GetProtocolName();
<< " removed with protocol " << client->GetProtocolName(); if ( (*it)->GetReflectorModule() != ' ' )
if ( client->GetReflectorModule() != ' ' )
{ {
std::cout << " on module " << client->GetReflectorModule(); std::cout << " on module " << (*it)->GetReflectorModule();
} }
std::cout << std::endl; std::cout << std::endl;
delete m_Clients[i]; delete *it;
m_Clients.erase(m_Clients.begin()+i); m_Clients.erase(it);
found = true;
// notify // notify
g_Reflector.OnClientsChanged(); g_Reflector.OnClientsChanged();
break;
} }
} }
} }
} }
CClient *CClients::GetClient(int i)
{
if ( (i >= 0) && (i < m_Clients.size()) )
{
return m_Clients[i];
}
else
{
return NULL;
}
}
bool CClients::IsClient(CClient *client) const bool CClients::IsClient(CClient *client) const
{ {
bool found = false; for ( auto it=cbegin(); it!=cend(); it++ )
for ( int i = 0; (i < m_Clients.size()) && !found; i++ )
{ {
found = (m_Clients[i] == client); if (*it == client)
return true;
} }
return found; return false;
} }
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
@ -153,171 +126,140 @@ bool CClients::IsClient(CClient *client) const
CClient *CClients::FindClient(const CIp &Ip) CClient *CClients::FindClient(const CIp &Ip)
{ {
CClient *client = NULL;
// find client // find client
for ( int i = 0; (i < m_Clients.size()) && (client == NULL); i++ ) for ( auto it=begin(); it!=end(); it++ )
{ {
if ( m_Clients[i]->GetIp() == Ip ) if ( (*it)->GetIp() == Ip )
{ {
client = m_Clients[i]; return *it;
} }
} }
// done // done
return client; return NULL;
} }
CClient *CClients::FindClient(const CIp &Ip, int Protocol) CClient *CClients::FindClient(const CIp &Ip, int Protocol)
{ {
CClient *client = NULL;
// find client // find client
for ( int i = 0; (i < m_Clients.size()) && (client == NULL); i++ ) for ( auto it=begin(); it!=end(); it++ )
{ {
if ( (m_Clients[i]->GetIp() == Ip) && (m_Clients[i]->GetProtocol() == Protocol)) if ( ((*it)->GetIp() == Ip) && ((*it)->GetProtocol() == Protocol))
{ {
client = m_Clients[i]; return *it;
} }
} }
// done // done
return client; return NULL;
} }
CClient *CClients::FindClient(const CIp &Ip, int Protocol, char ReflectorModule) CClient *CClients::FindClient(const CIp &Ip, int Protocol, char ReflectorModule)
{ {
CClient *client = NULL;
// find client // find client
for ( int i = 0; (i < m_Clients.size()) && (client == NULL); i++ ) for ( auto it=begin(); it!=end(); it++ )
{ {
if ( (m_Clients[i]->GetIp() == Ip) && if ( ((*it)->GetIp() == Ip) &&
(m_Clients[i]->GetReflectorModule() == ReflectorModule) && ((*it)->GetReflectorModule() == ReflectorModule) &&
(m_Clients[i]->GetProtocol() == Protocol) ) ((*it)->GetProtocol() == Protocol) )
{ {
client = m_Clients[i]; return *it;
} }
} }
// done // done
return client; return NULL;
} }
CClient *CClients::FindClient(const CCallsign &Callsign, const CIp &Ip, int Protocol) CClient *CClients::FindClient(const CCallsign &Callsign, const CIp &Ip, int Protocol)
{ {
CClient *client = NULL;
// find client // find client
for ( int i = 0; (i < m_Clients.size()) && (client == NULL); i++ ) for ( auto it=begin(); it!=end(); it++ )
{ {
if ( m_Clients[i]->GetCallsign().HasSameCallsign(Callsign) && if ( (*it)->GetCallsign().HasSameCallsign(Callsign) &&
(m_Clients[i]->GetIp() == Ip) && ((*it)->GetIp() == Ip) &&
(m_Clients[i]->GetProtocol() == Protocol) ) ((*it)->GetProtocol() == Protocol) )
{ {
client = m_Clients[i]; return *it;
} }
} }
// done return NULL;
return client;
} }
CClient *CClients::FindClient(const CCallsign &Callsign, char module, const CIp &Ip, int Protocol) CClient *CClients::FindClient(const CCallsign &Callsign, char module, const CIp &Ip, int Protocol)
{ {
CClient *client = NULL;
// find client // find client
for ( int i = 0; (i < m_Clients.size()) && (client == NULL); i++ ) for ( auto it=begin(); it!=end(); it++ )
{ {
if ( m_Clients[i]->GetCallsign().HasSameCallsign(Callsign) && if ( (*it)->GetCallsign().HasSameCallsign(Callsign) &&
(m_Clients[i]->GetModule() == module) && ((*it)->GetModule() == module) &&
(m_Clients[i]->GetIp() == Ip) && ((*it)->GetIp() == Ip) &&
(m_Clients[i]->GetProtocol() == Protocol) ) ((*it)->GetProtocol() == Protocol) )
{ {
client = m_Clients[i]; return *it;
} }
} }
// done return NULL;
return client;
} }
CClient *CClients::FindClient(const CCallsign &Callsign, int Protocol) CClient *CClients::FindClient(const CCallsign &Callsign, int Protocol)
{ {
CClient *client = NULL;
// find client // find client
for ( int i = 0; (i < m_Clients.size()) && (client == NULL); i++ ) for ( auto it=begin(); it!=end(); it++ )
{ {
if ( (m_Clients[i]->GetProtocol() == Protocol) && if ( ((*it)->GetProtocol() == Protocol) &&
m_Clients[i]->GetCallsign().HasSameCallsign(Callsign) ) (*it)->GetCallsign().HasSameCallsign(Callsign) )
{ {
client = m_Clients[i]; return *it;
} }
} }
// done return NULL;
return client;
} }
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
// iterate on clients // iterate on clients
CClient *CClients::FindNextClient(int Protocol, int *index) CClient *CClients::FindNextClient(int Protocol, std::list<CClient *>::iterator &it)
{ {
CClient *client = NULL; while ( it != end() )
// find next client
bool found = false;
for ( int i = *index+1; (i < m_Clients.size()) && !found; i++ )
{ {
if ( m_Clients[i]->GetProtocol() == Protocol ) if ( (*it)->GetProtocol() == Protocol )
{ {
found = true; return *it++;
client = m_Clients[i];
*index = i;
} }
it++;
} }
return client; return NULL;
} }
CClient *CClients::FindNextClient(const CIp &Ip, int Protocol, int *index) CClient *CClients::FindNextClient(const CIp &Ip, int Protocol, std::list<CClient *>::iterator &it)
{ {
CClient *client = NULL; while ( it != end() )
// find next client
bool found = false;
for ( int i = *index+1; (i < m_Clients.size()) && !found; i++ )
{ {
if ( (m_Clients[i]->GetProtocol() == Protocol) && if ( ((*it)->GetProtocol() == Protocol) &&
(m_Clients[i]->GetIp() == Ip) ) ((*it)->GetIp() == Ip) )
{ {
found = true; return *it++;
client = m_Clients[i];
*index = i;
} }
it++;
} }
return client; return NULL;
} }
CClient *CClients::FindNextClient(const CCallsign &Callsign, const CIp &Ip, int Protocol, int *index) CClient *CClients::FindNextClient(const CCallsign &Callsign, const CIp &Ip, int Protocol, std::list<CClient *>::iterator &it)
{ {
CClient *client = NULL; while ( it != end() )
// find next client
bool found = false;
for ( int i = *index+1; (i < m_Clients.size()) && !found; i++ )
{ {
if ( (m_Clients[i]->GetProtocol() == Protocol) && if ( ((*it)->GetProtocol() == Protocol) &&
(m_Clients[i]->GetIp() == Ip) && ((*it)->GetIp() == Ip) &&
m_Clients[i]->GetCallsign().HasSameCallsign(Callsign) ) (*it)->GetCallsign().HasSameCallsign(Callsign) )
{ {
found = true; return *it++;
client = m_Clients[i];
*index = i;
} }
it++;
} }
return client; return NULL;
} }

@ -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.
@ -19,7 +20,7 @@
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>. // along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#ifndef cclients_h #ifndef cclients_h
@ -40,21 +41,26 @@ class CClients
public: public:
// constructors // constructors
CClients(); CClients();
// destructors // destructors
virtual ~CClients(); virtual ~CClients();
// locks // locks
void Lock(void) { m_Mutex.lock(); } void Lock(void) { m_Mutex.lock(); }
void Unlock(void) { m_Mutex.unlock(); } void Unlock(void) { m_Mutex.unlock(); }
// manage Clients // manage Clients
int GetSize(void) const { return (int)m_Clients.size(); } int GetSize(void) const { return (int)m_Clients.size(); }
void AddClient(CClient *); void AddClient(CClient *);
void RemoveClient(CClient *); void RemoveClient(CClient *);
CClient *GetClient(int);
bool IsClient(CClient *) const; bool IsClient(CClient *) const;
// pass-thru
std::list<CClient *>::iterator begin() { return m_Clients.begin(); }
std::list<CClient *>::iterator end() { return m_Clients.end(); }
std::list<CClient *>::const_iterator cbegin() const { return m_Clients.cbegin(); }
std::list<CClient *>::const_iterator cend() const { return m_Clients.cend(); }
// find clients // find clients
CClient *FindClient(const CIp &); CClient *FindClient(const CIp &);
CClient *FindClient(const CIp &, int); CClient *FindClient(const CIp &, int);
@ -62,16 +68,16 @@ public:
CClient *FindClient(const CCallsign &, const CIp &, int); CClient *FindClient(const CCallsign &, const CIp &, int);
CClient *FindClient(const CCallsign &, char, const CIp &, int); CClient *FindClient(const CCallsign &, char, const CIp &, int);
CClient *FindClient(const CCallsign &, int); CClient *FindClient(const CCallsign &, int);
// iterate on clients // iterate on clients
CClient *FindNextClient(int, int*); CClient *FindNextClient(int, std::list<CClient *>::iterator &);
CClient *FindNextClient(const CIp &, int, int *); CClient *FindNextClient(const CIp &, int, std::list<CClient *>::iterator &);
CClient *FindNextClient(const CCallsign &, const CIp &, int, int *); CClient *FindNextClient(const CCallsign &, const CIp &, int, std::list<CClient *>::iterator &);
protected: protected:
// data // data
std::mutex m_Mutex; std::mutex m_Mutex;
std::vector<CClient *> m_Clients; std::list<CClient *> m_Clients;
}; };

@ -4,6 +4,7 @@
// //
// Created by Jean-Luc Deltombe (LX3JL) on 07/11/2015. // Created by Jean-Luc Deltombe (LX3JL) on 07/11/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.
@ -19,7 +20,7 @@
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>. // along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#include "main.h" #include "main.h"
@ -35,23 +36,23 @@
bool CDcsProtocol::Init(void) bool CDcsProtocol::Init(void)
{ {
bool ok; bool ok;
// base class // base class
ok = CProtocol::Init(); ok = CProtocol::Init();
// update the reflector callsign // update the reflector callsign
m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"DCS", 3); m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"DCS", 3);
// create our socket // create our socket
ok &= m_Socket.Open(DCS_PORT); ok &= m_Socket.Open(DCS_PORT);
if ( !ok ) if ( !ok )
{ {
std::cout << "Error opening socket on port UDP" << DCS_PORT << " on ip " << g_Reflector.GetListenIp() << std::endl; 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 ok;
} }
@ -69,7 +70,7 @@ void CDcsProtocol::Task(void)
char ToLinkModule; char ToLinkModule;
CDvHeaderPacket *Header; CDvHeaderPacket *Header;
CDvFramePacket *Frame; CDvFramePacket *Frame;
// handle incoming packets // handle incoming packets
if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 ) if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 )
{ {
@ -77,13 +78,13 @@ void CDcsProtocol::Task(void)
if ( IsValidDvPacket(Buffer, &Header, &Frame) ) if ( IsValidDvPacket(Buffer, &Header, &Frame) )
{ {
//std::cout << "DCS DV packet" << std::endl; //std::cout << "DCS DV packet" << std::endl;
// callsign muted? // callsign muted?
if ( g_GateKeeper.MayTransmit(Header->GetMyCallsign(), Ip, PROTOCOL_DCS, Header->GetRpt2Module()) ) if ( g_GateKeeper.MayTransmit(Header->GetMyCallsign(), Ip, PROTOCOL_DCS, Header->GetRpt2Module()) )
{ {
// handle it // handle it
OnDvHeaderPacketIn(Header, Ip); OnDvHeaderPacketIn(Header, Ip);
if ( !Frame->IsLastPacket() ) if ( !Frame->IsLastPacket() )
{ {
//std::cout << "DCS DV frame" << std::endl; //std::cout << "DCS DV frame" << std::endl;
@ -104,7 +105,7 @@ void CDcsProtocol::Task(void)
else if ( IsValidConnectPacket(Buffer, &Callsign, &ToLinkModule) ) else if ( IsValidConnectPacket(Buffer, &Callsign, &ToLinkModule) )
{ {
std::cout << "DCS connect packet for module " << ToLinkModule << " from " << Callsign << " at " << Ip << std::endl; std::cout << "DCS connect packet for module " << ToLinkModule << " from " << Callsign << " at " << Ip << std::endl;
// callsign authorized? // callsign authorized?
if ( g_GateKeeper.MayLink(Callsign, Ip, PROTOCOL_DCS) && g_Reflector.IsValidModule(ToLinkModule) ) if ( g_GateKeeper.MayLink(Callsign, Ip, PROTOCOL_DCS) && g_Reflector.IsValidModule(ToLinkModule) )
{ {
@ -114,10 +115,10 @@ void CDcsProtocol::Task(void)
// acknowledge the request // acknowledge the request
EncodeConnectAckPacket(Callsign, ToLinkModule, &Buffer); EncodeConnectAckPacket(Callsign, ToLinkModule, &Buffer);
m_Socket.Send(Buffer, Ip); m_Socket.Send(Buffer, Ip);
// create the client // create the client
CDcsClient *client = new CDcsClient(Callsign, Ip, ToLinkModule); CDcsClient *client = new CDcsClient(Callsign, Ip, ToLinkModule);
// and append // and append
g_Reflector.GetClients()->AddClient(client); g_Reflector.GetClients()->AddClient(client);
g_Reflector.ReleaseClients(); g_Reflector.ReleaseClients();
@ -125,7 +126,7 @@ void CDcsProtocol::Task(void)
else else
{ {
std::cout << "DCS node " << Callsign << " connect attempt on non-existing module" << std::endl; std::cout << "DCS node " << Callsign << " connect attempt on non-existing module" << std::endl;
// deny the request // deny the request
EncodeConnectNackPacket(Callsign, ToLinkModule, &Buffer); EncodeConnectNackPacket(Callsign, ToLinkModule, &Buffer);
m_Socket.Send(Buffer, Ip); m_Socket.Send(Buffer, Ip);
@ -137,12 +138,12 @@ void CDcsProtocol::Task(void)
EncodeConnectNackPacket(Callsign, ToLinkModule, &Buffer); EncodeConnectNackPacket(Callsign, ToLinkModule, &Buffer);
m_Socket.Send(Buffer, Ip); m_Socket.Send(Buffer, Ip);
} }
} }
else if ( IsValidDisconnectPacket(Buffer, &Callsign) ) else if ( IsValidDisconnectPacket(Buffer, &Callsign) )
{ {
std::cout << "DCS disconnect packet from " << Callsign << " at " << Ip << std::endl; std::cout << "DCS disconnect packet from " << Callsign << " at " << Ip << std::endl;
// find client // find client
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
CClient *client = clients->FindClient(Ip, PROTOCOL_DCS); CClient *client = clients->FindClient(Ip, PROTOCOL_DCS);
@ -159,12 +160,12 @@ void CDcsProtocol::Task(void)
else if ( IsValidKeepAlivePacket(Buffer, &Callsign) ) else if ( IsValidKeepAlivePacket(Buffer, &Callsign) )
{ {
//std::cout << "DCS keepalive packet from " << Callsign << " at " << Ip << std::endl; //std::cout << "DCS keepalive packet from " << Callsign << " at " << Ip << std::endl;
// find all clients with that callsign & ip and keep them alive // find all clients with that callsign & ip and keep them alive
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
int index = -1; auto it = clients->begin();
CClient *client = NULL; CClient *client = NULL;
while ( (client = clients->FindNextClient(Callsign, Ip, PROTOCOL_DCS, &index)) != NULL ) while ( (client = clients->FindNextClient(Callsign, Ip, PROTOCOL_DCS, it)) != NULL )
{ {
client->Alive(); client->Alive();
} }
@ -181,19 +182,19 @@ void CDcsProtocol::Task(void)
std::cout << "DCS packet (" << Buffer.size() << ") from " << Ip << std::endl; std::cout << "DCS packet (" << Buffer.size() << ") from " << Ip << std::endl;
} }
} }
// handle end of streaming timeout // handle end of streaming timeout
CheckStreamsTimeout(); CheckStreamsTimeout();
// handle queue from reflector // handle queue from reflector
HandleQueue(); HandleQueue();
// keep client alive // keep client alive
if ( m_LastKeepaliveTime.DurationSinceNow() > DCS_KEEPALIVE_PERIOD ) if ( m_LastKeepaliveTime.DurationSinceNow() > DCS_KEEPALIVE_PERIOD )
{ {
// //
HandleKeepalives(); HandleKeepalives();
// update time // update time
m_LastKeepaliveTime.Now(); m_LastKeepaliveTime.Now();
} }
@ -205,14 +206,14 @@ void CDcsProtocol::Task(void)
bool CDcsProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip) bool CDcsProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
{ {
bool newstream = false; bool newstream = false;
// find the stream // find the stream
CPacketStream *stream = GetStream(Header->GetStreamId()); CPacketStream *stream = GetStream(Header->GetStreamId());
if ( stream == NULL ) if ( stream == NULL )
{ {
// no stream open yet, open a new one // no stream open yet, open a new one
CCallsign via(Header->GetRpt1Callsign()); CCallsign via(Header->GetRpt1Callsign());
// find this client // find this client
CClient *client = g_Reflector.GetClients()->FindClient(Ip, PROTOCOL_DCS); CClient *client = g_Reflector.GetClients()->FindClient(Ip, PROTOCOL_DCS);
if ( client != NULL ) if ( client != NULL )
@ -229,11 +230,11 @@ bool CDcsProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
} }
// release // release
g_Reflector.ReleaseClients(); g_Reflector.ReleaseClients();
// update last heard // update last heard
g_Reflector.GetUsers()->Hearing(Header->GetMyCallsign(), via, Header->GetRpt2Callsign()); g_Reflector.GetUsers()->Hearing(Header->GetMyCallsign(), via, Header->GetRpt2Callsign());
g_Reflector.ReleaseUsers(); g_Reflector.ReleaseUsers();
// delete header if needed // delete header if needed
if ( !newstream ) if ( !newstream )
{ {
@ -248,7 +249,7 @@ bool CDcsProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
// and delete packet // and delete packet
delete Header; delete Header;
} }
// done // done
return newstream; return newstream;
} }
@ -264,10 +265,10 @@ void CDcsProtocol::HandleQueue(void)
// get the packet // get the packet
CPacket *packet = m_Queue.front(); CPacket *packet = m_Queue.front();
m_Queue.pop(); m_Queue.pop();
// get our sender's id // get our sender's id
int iModId = g_Reflector.GetModuleIndex(packet->GetModuleId()); int iModId = g_Reflector.GetModuleIndex(packet->GetModuleId());
// check if it's header and update cache // check if it's header and update cache
if ( packet->IsDvHeader() ) if ( packet->IsDvHeader() )
{ {
@ -295,28 +296,28 @@ void CDcsProtocol::HandleQueue(void)
m_StreamsCache[iModId].m_iSeqCounter++, m_StreamsCache[iModId].m_iSeqCounter++,
&buffer); &buffer);
} }
// send it // send it
if ( buffer.size() > 0 ) if ( buffer.size() > 0 )
{ {
// and push it to all our clients linked to the module and who are not streaming in // and push it to all our clients linked to the module and who are not streaming in
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
int index = -1; auto it = clients->begin();
CClient *client = NULL; CClient *client = NULL;
while ( (client = clients->FindNextClient(PROTOCOL_DCS, &index)) != NULL ) while ( (client = clients->FindNextClient(PROTOCOL_DCS, it)) != NULL )
{ {
// is this client busy ? // is this client busy ?
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()); m_Socket.Send(buffer, client->GetIp());
} }
} }
g_Reflector.ReleaseClients(); g_Reflector.ReleaseClients();
} }
} }
// done // done
delete packet; delete packet;
} }
@ -333,21 +334,21 @@ void CDcsProtocol::HandleKeepalives(void)
// so, send keepalives to all // so, send keepalives to all
CBuffer keepalive1; CBuffer keepalive1;
EncodeKeepAlivePacket(&keepalive1); EncodeKeepAlivePacket(&keepalive1);
// iterate on clients // iterate on clients
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
int index = -1; auto it = clients->begin();
CClient *client = NULL; CClient *client = NULL;
while ( (client = clients->FindNextClient(PROTOCOL_DCS, &index)) != NULL ) while ( (client = clients->FindNextClient(PROTOCOL_DCS, it)) != NULL )
{ {
// encode client's specific keepalive packet // encode client's specific keepalive packet
CBuffer keepalive2; CBuffer keepalive2;
EncodeKeepAlivePacket(&keepalive2, client); EncodeKeepAlivePacket(&keepalive2, client);
// send keepalive // send keepalive
m_Socket.Send(keepalive1, client->GetIp()); m_Socket.Send(keepalive1, client->GetIp());
m_Socket.Send(keepalive2, client->GetIp()); m_Socket.Send(keepalive2, client->GetIp());
// is this client busy ? // is this client busy ?
if ( client->IsAMaster() ) if ( client->IsAMaster() )
{ {
@ -361,12 +362,12 @@ void CDcsProtocol::HandleKeepalives(void)
CBuffer disconnect; CBuffer disconnect;
EncodeDisconnectPacket(&disconnect, client); EncodeDisconnectPacket(&disconnect, client);
m_Socket.Send(disconnect, client->GetIp()); m_Socket.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;
clients->RemoveClient(client); clients->RemoveClient(client);
} }
} }
g_Reflector.ReleaseClients(); g_Reflector.ReleaseClients();
} }
@ -419,17 +420,17 @@ bool CDcsProtocol::IsValidKeepAlivePacket(const CBuffer &Buffer, CCallsign *call
bool CDcsProtocol::IsValidDvPacket(const CBuffer &Buffer, CDvHeaderPacket **header, CDvFramePacket **frame) bool CDcsProtocol::IsValidDvPacket(const CBuffer &Buffer, CDvHeaderPacket **header, CDvFramePacket **frame)
{ {
uint8 tag[] = { '0','0','0','1' }; uint8 tag[] = { '0','0','0','1' };
bool valid = false; bool valid = false;
*header = NULL; *header = NULL;
*frame = NULL; *frame = NULL;
if ( (Buffer.size() >= 100) && (Buffer.Compare(tag, sizeof(tag)) == 0) ) if ( (Buffer.size() >= 100) && (Buffer.Compare(tag, sizeof(tag)) == 0) )
{ {
// get the header // get the header
*header = new CDvHeaderPacket((struct dstar_header *)&(Buffer.data()[4]), *header = new CDvHeaderPacket((struct dstar_header *)&(Buffer.data()[4]),
*((uint16 *)&(Buffer.data()[43])), 0x80); *((uint16 *)&(Buffer.data()[43])), 0x80);
// get the frame // get the frame
if ( ((Buffer.data()[45]) & 0x40) != 0 ) if ( ((Buffer.data()[45]) & 0x40) != 0 )
{ {
@ -443,7 +444,7 @@ bool CDcsProtocol::IsValidDvPacket(const CBuffer &Buffer, CDvHeaderPacket **head
*frame = new CDvFramePacket((struct dstar_dvframe *)&(Buffer.data()[46]), *frame = new CDvFramePacket((struct dstar_dvframe *)&(Buffer.data()[46]),
*((uint16 *)&(Buffer.data()[43])), Buffer.data()[45]); *((uint16 *)&(Buffer.data()[43])), Buffer.data()[45]);
} }
// check validity of packets // check validity of packets
if ( !((*header)->IsValid() && (*frame)->IsValid()) ) if ( !((*header)->IsValid() && (*frame)->IsValid()) )
{ {
@ -465,7 +466,7 @@ bool CDcsProtocol::IsIgnorePacket(const CBuffer &Buffer)
{ {
bool valid = false; bool valid = false;
uint8 tag[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, }; uint8 tag[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, };
if ( Buffer.size() == 15 ) if ( Buffer.size() == 15 )
{ {
valid = (Buffer.Compare(tag, sizeof(tag)) == 0); valid = (Buffer.Compare(tag, sizeof(tag)) == 0);
@ -485,7 +486,7 @@ void CDcsProtocol::EncodeKeepAlivePacket(CBuffer *Buffer)
void CDcsProtocol::EncodeKeepAlivePacket(CBuffer *Buffer, CClient *Client) void CDcsProtocol::EncodeKeepAlivePacket(CBuffer *Buffer, CClient *Client)
{ {
uint8 tag[] = { 0x0A,0x00,0x20,0x20 }; uint8 tag[] = { 0x0A,0x00,0x20,0x20 };
Buffer->Set((uint8 *)(const char *)GetReflectorCallsign(), CALLSIGN_LEN-1); Buffer->Set((uint8 *)(const char *)GetReflectorCallsign(), CALLSIGN_LEN-1);
Buffer->Append((uint8)Client->GetReflectorModule()); Buffer->Append((uint8)Client->GetReflectorModule());
Buffer->Append((uint8)' '); Buffer->Append((uint8)' ');
@ -499,7 +500,7 @@ void CDcsProtocol::EncodeConnectAckPacket(const CCallsign &Callsign, char Reflec
{ {
uint8 tag[] = { 'A','C','K',0x00 }; uint8 tag[] = { 'A','C','K',0x00 };
uint8 cs[CALLSIGN_LEN]; uint8 cs[CALLSIGN_LEN];
Callsign.GetCallsign(cs); Callsign.GetCallsign(cs);
Buffer->Set(cs, CALLSIGN_LEN-1); Buffer->Set(cs, CALLSIGN_LEN-1);
Buffer->Append((uint8)' '); Buffer->Append((uint8)' ');
@ -512,7 +513,7 @@ void CDcsProtocol::EncodeConnectNackPacket(const CCallsign &Callsign, char Refle
{ {
uint8 tag[] = { 'N','A','K',0x00 }; uint8 tag[] = { 'N','A','K',0x00 };
uint8 cs[CALLSIGN_LEN]; uint8 cs[CALLSIGN_LEN];
Callsign.GetCallsign(cs); Callsign.GetCallsign(cs);
Buffer->Set(cs, CALLSIGN_LEN-1); Buffer->Set(cs, CALLSIGN_LEN-1);
Buffer->Append((uint8)' '); Buffer->Append((uint8)' ');

@ -200,9 +200,9 @@ void CDextraProtocol::Task(void)
// find all clients with that callsign & ip and keep them alive // find all clients with that callsign & ip and keep them alive
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
int index = -1; auto it = clients->begin();
CClient *client = NULL; CClient *client = NULL;
while ( (client = clients->FindNextClient(Callsign, Ip, PROTOCOL_DEXTRA, &index)) != NULL ) while ( (client = clients->FindNextClient(Callsign, Ip, PROTOCOL_DEXTRA, it)) != NULL )
{ {
client->Alive(); client->Alive();
} }
@ -260,9 +260,9 @@ void CDextraProtocol::HandleQueue(void)
{ {
// and push it to all our clients linked to the module and who are not streaming in // and push it to all our clients linked to the module and who are not streaming in
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
int index = -1; auto it = clients->begin();
CClient *client = NULL; CClient *client = NULL;
while ( (client = clients->FindNextClient(PROTOCOL_DEXTRA, &index)) != NULL ) while ( (client = clients->FindNextClient(PROTOCOL_DEXTRA, it)) != NULL )
{ {
// is this client busy ? // is this client busy ?
if ( !client->IsAMaster() && (client->GetReflectorModule() == packet->GetModuleId()) ) if ( !client->IsAMaster() && (client->GetReflectorModule() == packet->GetModuleId()) )
@ -298,9 +298,9 @@ void CDextraProtocol::HandleKeepalives(void)
// iterate on clients // iterate on clients
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
int index = -1; auto it = clients->begin();
CClient *client = NULL; CClient *client = NULL;
while ( (client = clients->FindNextClient(PROTOCOL_DEXTRA, &index)) != NULL ) while ( (client = clients->FindNextClient(PROTOCOL_DEXTRA, it)) != NULL )
{ {
// send keepalive // send keepalive
m_Socket.Send(keepalive, client->GetIp()); m_Socket.Send(keepalive, client->GetIp());
@ -339,7 +339,7 @@ void CDextraProtocol::HandleKeepalives(void)
// iterate on peers // iterate on peers
CPeers *peers = g_Reflector.GetPeers(); CPeers *peers = g_Reflector.GetPeers();
index = -1; int index = -1;
CPeer *peer = NULL; CPeer *peer = NULL;
while ( (peer = peers->FindNextPeer(PROTOCOL_DEXTRA, &index)) != NULL ) while ( (peer = peers->FindNextPeer(PROTOCOL_DEXTRA, &index)) != NULL )
{ {

@ -56,24 +56,24 @@ static uint8 g_DmrSyncMSData[] = { 0x0D,0x5D,0x7F,0x77,0xFD,0x75,0x70 };
bool CDmrmmdvmProtocol::Init(void) bool CDmrmmdvmProtocol::Init(void)
{ {
bool ok; bool ok;
// base class // base class
ok = CProtocol::Init(); ok = CProtocol::Init();
// update the reflector callsign // update the reflector callsign
//m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"DMR", 3); //m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"DMR", 3);
// create our socket // create our socket
ok &= m_Socket.Open(DMRMMDVM_PORT); ok &= m_Socket.Open(DMRMMDVM_PORT);
// update time // update time
m_LastKeepaliveTime.Now(); m_LastKeepaliveTime.Now();
// random number generator // random number generator
time_t t; time_t t;
::srand((unsigned) time(&t)); ::srand((unsigned) time(&t));
m_uiAuthSeed = (uint32)rand(); m_uiAuthSeed = (uint32)rand();
// done // done
return ok; return ok;
} }
@ -94,7 +94,7 @@ void CDmrmmdvmProtocol::Task(void)
CDvHeaderPacket *Header; CDvHeaderPacket *Header;
CDvFramePacket *Frames[3]; CDvFramePacket *Frames[3];
CDvLastFramePacket *LastFrame; CDvLastFramePacket *LastFrame;
// handle incoming packets // handle incoming packets
if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 ) if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 )
{ {
@ -103,7 +103,7 @@ void CDmrmmdvmProtocol::Task(void)
if ( IsValidDvFramePacket(Buffer, Frames) ) if ( IsValidDvFramePacket(Buffer, Frames) )
{ {
//std::cout << "DMRmmdvm DV frame" << std::endl; //std::cout << "DMRmmdvm DV frame" << std::endl;
for ( int i = 0; i < 3; i++ ) for ( int i = 0; i < 3; i++ )
{ {
OnDvFramePacketIn(Frames[i], &Ip); OnDvFramePacketIn(Frames[i], &Ip);
@ -113,7 +113,7 @@ void CDmrmmdvmProtocol::Task(void)
{ {
//std::cout << "DMRmmdvm DV header:" << std::endl << *Header << std::endl; //std::cout << "DMRmmdvm DV header:" << std::endl << *Header << std::endl;
//std::cout << "DMRmmdvm DV header" << std::endl; //std::cout << "DMRmmdvm DV header" << std::endl;
// callsign muted? // callsign muted?
if ( g_GateKeeper.MayTransmit(Header->GetMyCallsign(), Ip, PROTOCOL_DMRMMDVM) ) if ( g_GateKeeper.MayTransmit(Header->GetMyCallsign(), Ip, PROTOCOL_DMRMMDVM) )
{ {
@ -128,13 +128,13 @@ void CDmrmmdvmProtocol::Task(void)
else if ( IsValidDvLastFramePacket(Buffer, &LastFrame) ) else if ( IsValidDvLastFramePacket(Buffer, &LastFrame) )
{ {
//std::cout << "DMRmmdvm DV last frame" << std::endl; //std::cout << "DMRmmdvm DV last frame" << std::endl;
OnDvLastFramePacketIn(LastFrame, &Ip); OnDvLastFramePacketIn(LastFrame, &Ip);
} }
else if ( IsValidConnectPacket(Buffer, &Callsign, Ip) ) else if ( IsValidConnectPacket(Buffer, &Callsign, Ip) )
{ {
std::cout << "DMRmmdvm connect packet from " << Callsign << " at " << Ip << std::endl; std::cout << "DMRmmdvm connect packet from " << Callsign << " at " << Ip << std::endl;
// callsign authorized? // callsign authorized?
if ( g_GateKeeper.MayLink(Callsign, Ip, PROTOCOL_DMRMMDVM) ) if ( g_GateKeeper.MayLink(Callsign, Ip, PROTOCOL_DMRMMDVM) )
{ {
@ -148,19 +148,19 @@ void CDmrmmdvmProtocol::Task(void)
EncodeNackPacket(&Buffer, Callsign); EncodeNackPacket(&Buffer, Callsign);
m_Socket.Send(Buffer, Ip); m_Socket.Send(Buffer, Ip);
} }
} }
else if ( IsValidAuthenticationPacket(Buffer, &Callsign, Ip) ) else if ( IsValidAuthenticationPacket(Buffer, &Callsign, Ip) )
{ {
std::cout << "DMRmmdvm authentication packet from " << Callsign << " at " << Ip << std::endl; std::cout << "DMRmmdvm authentication packet from " << Callsign << " at " << Ip << std::endl;
// callsign authorized? // callsign authorized?
if ( g_GateKeeper.MayLink(Callsign, Ip, PROTOCOL_DMRMMDVM) ) if ( g_GateKeeper.MayLink(Callsign, Ip, PROTOCOL_DMRMMDVM) )
{ {
// acknowledge the request // acknowledge the request
EncodeAckPacket(&Buffer, Callsign); EncodeAckPacket(&Buffer, Callsign);
m_Socket.Send(Buffer, Ip); m_Socket.Send(Buffer, Ip);
// add client if needed // add client if needed
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
CClient *client = clients->FindClient(Callsign, Ip, PROTOCOL_DMRMMDVM); CClient *client = clients->FindClient(Callsign, Ip, PROTOCOL_DMRMMDVM);
@ -168,10 +168,10 @@ void CDmrmmdvmProtocol::Task(void)
if ( client == NULL ) if ( client == NULL )
{ {
std::cout << "DMRmmdvm login from " << Callsign << " at " << Ip << std::endl; std::cout << "DMRmmdvm login from " << Callsign << " at " << Ip << std::endl;
// create the client // create the client
CDmrmmdvmClient *newclient = new CDmrmmdvmClient(Callsign, Ip); CDmrmmdvmClient *newclient = new CDmrmmdvmClient(Callsign, Ip);
// and append // and append
clients->AddClient(newclient); clients->AddClient(newclient);
} }
@ -188,12 +188,12 @@ void CDmrmmdvmProtocol::Task(void)
EncodeNackPacket(&Buffer, Callsign); EncodeNackPacket(&Buffer, Callsign);
m_Socket.Send(Buffer, Ip); m_Socket.Send(Buffer, Ip);
} }
} }
else if ( IsValidDisconnectPacket(Buffer, &Callsign) ) else if ( IsValidDisconnectPacket(Buffer, &Callsign) )
{ {
std::cout << "DMRmmdvm disconnect packet from " << Callsign << " at " << Ip << std::endl; std::cout << "DMRmmdvm disconnect packet from " << Callsign << " at " << Ip << std::endl;
// find client & remove it // find client & remove it
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
CClient *client = clients->FindClient(Ip, PROTOCOL_DMRMMDVM); CClient *client = clients->FindClient(Ip, PROTOCOL_DMRMMDVM);
@ -206,7 +206,7 @@ void CDmrmmdvmProtocol::Task(void)
else if ( IsValidConfigPacket(Buffer, &Callsign, Ip) ) else if ( IsValidConfigPacket(Buffer, &Callsign, Ip) )
{ {
std::cout << "DMRmmdvm configuration packet from " << Callsign << " at " << Ip << std::endl; std::cout << "DMRmmdvm configuration packet from " << Callsign << " at " << Ip << std::endl;
// acknowledge the request // acknowledge the request
EncodeAckPacket(&Buffer, Callsign); EncodeAckPacket(&Buffer, Callsign);
m_Socket.Send(Buffer, Ip); m_Socket.Send(Buffer, Ip);
@ -214,17 +214,17 @@ void CDmrmmdvmProtocol::Task(void)
else if ( IsValidKeepAlivePacket(Buffer, &Callsign) ) else if ( IsValidKeepAlivePacket(Buffer, &Callsign) )
{ {
//std::cout << "DMRmmdvm keepalive packet from " << Callsign << " at " << Ip << std::endl; //std::cout << "DMRmmdvm keepalive packet from " << Callsign << " at " << Ip << std::endl;
// find all clients with that callsign & ip and keep them alive // find all clients with that callsign & ip and keep them alive
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
int index = -1; auto it = clients->begin();
CClient *client = NULL; CClient *client = NULL;
while ( (client = clients->FindNextClient(Callsign, Ip, PROTOCOL_DMRMMDVM, &index)) != NULL ) while ( (client = clients->FindNextClient(Callsign, Ip, PROTOCOL_DMRMMDVM, it)) != NULL )
{ {
// acknowledge // acknowledge
EncodeKeepAlivePacket(&Buffer, client); EncodeKeepAlivePacket(&Buffer, client);
m_Socket.Send(Buffer, Ip); m_Socket.Send(Buffer, Ip);
// and mark as alive // and mark as alive
client->Alive(); client->Alive();
} }
@ -233,13 +233,13 @@ void CDmrmmdvmProtocol::Task(void)
else if ( IsValidRssiPacket(Buffer, &Callsign, &iRssi) ) else if ( IsValidRssiPacket(Buffer, &Callsign, &iRssi) )
{ {
// std::cout << "DMRmmdvm RSSI packet from " << Callsign << " at " << Ip << std::endl // std::cout << "DMRmmdvm RSSI packet from " << Callsign << " at " << Ip << std::endl
// ignore... // ignore...
} }
else if ( IsValidOptionPacket(Buffer, &Callsign) ) else if ( IsValidOptionPacket(Buffer, &Callsign) )
{ {
std::cout << "DMRmmdvm options packet from " << Callsign << " at " << Ip << std::endl; std::cout << "DMRmmdvm options packet from " << Callsign << " at " << Ip << std::endl;
// acknowledge the request // acknowledge the request
EncodeAckPacket(&Buffer, Callsign); EncodeAckPacket(&Buffer, Callsign);
m_Socket.Send(Buffer, Ip); m_Socket.Send(Buffer, Ip);
@ -250,24 +250,24 @@ void CDmrmmdvmProtocol::Task(void)
//std::cout << Buffer << std::endl; //std::cout << Buffer << std::endl;
} }
} }
// handle end of streaming timeout // handle end of streaming timeout
CheckStreamsTimeout(); CheckStreamsTimeout();
// handle queue from reflector // handle queue from reflector
HandleQueue(); HandleQueue();
// keep client alive // keep client alive
if ( m_LastKeepaliveTime.DurationSinceNow() > DMRMMDVM_KEEPALIVE_PERIOD ) if ( m_LastKeepaliveTime.DurationSinceNow() > DMRMMDVM_KEEPALIVE_PERIOD )
{ {
// //
HandleKeepalives(); HandleKeepalives();
// update time // update time
m_LastKeepaliveTime.Now(); m_LastKeepaliveTime.Now();
} }
} }
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
@ -277,7 +277,7 @@ bool CDmrmmdvmProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &I
{ {
bool newstream = false; bool newstream = false;
bool lastheard = false; bool lastheard = false;
// //
CCallsign via(Header->GetRpt1Callsign()); CCallsign via(Header->GetRpt1Callsign());
@ -323,7 +323,7 @@ bool CDmrmmdvmProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &I
Header->SetRpt2Module(client->GetReflectorModule()); Header->SetRpt2Module(client->GetReflectorModule());
} }
} }
// and now, re-check module is valid && that it's not a private call // and now, re-check module is valid && that it's not a private call
if ( g_Reflector.IsValidModule(Header->GetRpt2Module()) && (CallType == DMR_GROUP_CALL) ) if ( g_Reflector.IsValidModule(Header->GetRpt2Module()) && (CallType == DMR_GROUP_CALL) )
{ {
@ -341,17 +341,17 @@ bool CDmrmmdvmProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &I
{ {
lastheard = true; lastheard = true;
} }
// release // release
g_Reflector.ReleaseClients(); g_Reflector.ReleaseClients();
// update last heard // update last heard
if ( lastheard ) if ( lastheard )
{ {
g_Reflector.GetUsers()->Hearing(Header->GetMyCallsign(), via, Header->GetRpt2Callsign()); g_Reflector.GetUsers()->Hearing(Header->GetMyCallsign(), via, Header->GetRpt2Callsign());
g_Reflector.ReleaseUsers(); g_Reflector.ReleaseUsers();
} }
// delete header if needed // delete header if needed
if ( !newstream ) if ( !newstream )
{ {
@ -366,7 +366,7 @@ bool CDmrmmdvmProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &I
// and delete packet // and delete packet
delete Header; delete Header;
} }
// done // done
return newstream; return newstream;
} }
@ -376,20 +376,20 @@ bool CDmrmmdvmProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &I
void CDmrmmdvmProtocol::HandleQueue(void) void CDmrmmdvmProtocol::HandleQueue(void)
{ {
m_Queue.Lock(); m_Queue.Lock();
while ( !m_Queue.empty() ) while ( !m_Queue.empty() )
{ {
// get the packet // get the packet
CPacket *packet = m_Queue.front(); CPacket *packet = m_Queue.front();
m_Queue.pop(); m_Queue.pop();
// get our sender's id // get our sender's id
int iModId = g_Reflector.GetModuleIndex(packet->GetModuleId()); int iModId = g_Reflector.GetModuleIndex(packet->GetModuleId());
// encode // encode
CBuffer buffer; CBuffer buffer;
// check if it's header // check if it's header
if ( packet->IsDvHeader() ) if ( packet->IsDvHeader() )
{ {
@ -397,7 +397,7 @@ void CDmrmmdvmProtocol::HandleQueue(void)
// this relies on queue feeder setting valid module id // this relies on queue feeder setting valid module id
m_StreamsCache[iModId].m_dvHeader = CDvHeaderPacket((const CDvHeaderPacket &)*packet); m_StreamsCache[iModId].m_dvHeader = CDvHeaderPacket((const CDvHeaderPacket &)*packet);
m_StreamsCache[iModId].m_uiSeqId = 0; m_StreamsCache[iModId].m_uiSeqId = 0;
// encode it // encode it
EncodeDvHeaderPacket((const CDvHeaderPacket &)*packet, m_StreamsCache[iModId].m_uiSeqId, &buffer); EncodeDvHeaderPacket((const CDvHeaderPacket &)*packet, m_StreamsCache[iModId].m_uiSeqId, &buffer);
m_StreamsCache[iModId].m_uiSeqId = 1; m_StreamsCache[iModId].m_uiSeqId = 1;
@ -435,27 +435,27 @@ void CDmrmmdvmProtocol::HandleQueue(void)
break; break;
} }
} }
// send it // send it
if ( buffer.size() > 0 ) if ( buffer.size() > 0 )
{ {
// and push it to all our clients linked to the module and who are not streaming in // and push it to all our clients linked to the module and who are not streaming in
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
int index = -1; auto it = clients->begin();
CClient *client = NULL; CClient *client = NULL;
while ( (client = clients->FindNextClient(PROTOCOL_DMRMMDVM, &index)) != NULL ) while ( (client = clients->FindNextClient(PROTOCOL_DMRMMDVM, it)) != NULL )
{ {
// is this client busy ? // is this client busy ?
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()); m_Socket.Send(buffer, client->GetIp());
} }
} }
g_Reflector.ReleaseClients(); g_Reflector.ReleaseClients();
} }
// done // done
delete packet; delete packet;
} }
@ -470,12 +470,12 @@ void CDmrmmdvmProtocol::HandleKeepalives(void)
// DMRhomebrew protocol keepalive request is client tasks // DMRhomebrew protocol keepalive request is client tasks
// here, just check that all clients are still alive // here, just check that all clients are still alive
// and disconnect them if not // and disconnect them if not
// iterate on clients // iterate on clients
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
int index = -1; auto it = clients->begin();
CClient *client = NULL; CClient *client = NULL;
while ( (client = clients->FindNextClient(PROTOCOL_DMRMMDVM, &index)) != NULL ) while ( (client = clients->FindNextClient(PROTOCOL_DMRMMDVM, it)) != NULL )
{ {
// is this client busy ? // is this client busy ?
if ( client->IsAMaster() ) if ( client->IsAMaster() )
@ -489,12 +489,12 @@ void CDmrmmdvmProtocol::HandleKeepalives(void)
// no, disconnect // no, disconnect
CBuffer disconnect; CBuffer disconnect;
m_Socket.Send(disconnect, client->GetIp()); m_Socket.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;
clients->RemoveClient(client); clients->RemoveClient(client);
} }
} }
g_Reflector.ReleaseClients(); g_Reflector.ReleaseClients();
} }
@ -505,7 +505,7 @@ void CDmrmmdvmProtocol::HandleKeepalives(void)
bool CDmrmmdvmProtocol::IsValidKeepAlivePacket(const CBuffer &Buffer, CCallsign *callsign) bool CDmrmmdvmProtocol::IsValidKeepAlivePacket(const CBuffer &Buffer, CCallsign *callsign)
{ {
uint8 tag[] = { 'R','P','T','P','I','N','G' }; uint8 tag[] = { 'R','P','T','P','I','N','G' };
bool valid = false; bool valid = false;
if ( (Buffer.size() == 11) && (Buffer.Compare(tag, sizeof(tag)) == 0) ) if ( (Buffer.size() == 11) && (Buffer.Compare(tag, sizeof(tag)) == 0) )
{ {
@ -520,7 +520,7 @@ bool CDmrmmdvmProtocol::IsValidKeepAlivePacket(const CBuffer &Buffer, CCallsign
bool CDmrmmdvmProtocol::IsValidConnectPacket(const CBuffer &Buffer, CCallsign *callsign, const CIp &Ip) bool CDmrmmdvmProtocol::IsValidConnectPacket(const CBuffer &Buffer, CCallsign *callsign, const CIp &Ip)
{ {
uint8 tag[] = { 'R','P','T','L' }; uint8 tag[] = { 'R','P','T','L' };
bool valid = false; bool valid = false;
if ( (Buffer.size() == 8) && (Buffer.Compare(tag, sizeof(tag)) == 0) ) if ( (Buffer.size() == 8) && (Buffer.Compare(tag, sizeof(tag)) == 0) )
{ {
@ -539,7 +539,7 @@ bool CDmrmmdvmProtocol::IsValidConnectPacket(const CBuffer &Buffer, CCallsign *c
bool CDmrmmdvmProtocol::IsValidAuthenticationPacket(const CBuffer &Buffer, CCallsign *callsign, const CIp &Ip) bool CDmrmmdvmProtocol::IsValidAuthenticationPacket(const CBuffer &Buffer, CCallsign *callsign, const CIp &Ip)
{ {
uint8 tag[] = { 'R','P','T','K' }; uint8 tag[] = { 'R','P','T','K' };
bool valid = false; bool valid = false;
if ( (Buffer.size() == 40) && (Buffer.Compare(tag, sizeof(tag)) == 0) ) if ( (Buffer.size() == 40) && (Buffer.Compare(tag, sizeof(tag)) == 0) )
{ {
@ -559,7 +559,7 @@ bool CDmrmmdvmProtocol::IsValidAuthenticationPacket(const CBuffer &Buffer, CCall
bool CDmrmmdvmProtocol::IsValidDisconnectPacket(const CBuffer &Buffer, CCallsign *callsign) bool CDmrmmdvmProtocol::IsValidDisconnectPacket(const CBuffer &Buffer, CCallsign *callsign)
{ {
uint8 tag[] = { 'R','P','T','C','L' }; uint8 tag[] = { 'R','P','T','C','L' };
bool valid = false; bool valid = false;
if ( (Buffer.size() == 13) && (Buffer.Compare(tag, sizeof(tag)) == 0) ) if ( (Buffer.size() == 13) && (Buffer.Compare(tag, sizeof(tag)) == 0) )
{ {
@ -574,7 +574,7 @@ bool CDmrmmdvmProtocol::IsValidDisconnectPacket(const CBuffer &Buffer, CCallsign
bool CDmrmmdvmProtocol::IsValidConfigPacket(const CBuffer &Buffer, CCallsign *callsign, const CIp &Ip) bool CDmrmmdvmProtocol::IsValidConfigPacket(const CBuffer &Buffer, CCallsign *callsign, const CIp &Ip)
{ {
uint8 tag[] = { 'R','P','T','C' }; uint8 tag[] = { 'R','P','T','C' };
bool valid = false; bool valid = false;
if ( (Buffer.size() == 302) && (Buffer.Compare(tag, sizeof(tag)) == 0) ) if ( (Buffer.size() == 302) && (Buffer.Compare(tag, sizeof(tag)) == 0) )
{ {
@ -594,7 +594,7 @@ bool CDmrmmdvmProtocol::IsValidConfigPacket(const CBuffer &Buffer, CCallsign *ca
bool CDmrmmdvmProtocol::IsValidOptionPacket(const CBuffer &Buffer, CCallsign *callsign) bool CDmrmmdvmProtocol::IsValidOptionPacket(const CBuffer &Buffer, CCallsign *callsign)
{ {
uint8 tag[] = { 'R','P','T','O' }; uint8 tag[] = { 'R','P','T','O' };
bool valid = false; bool valid = false;
if ( (Buffer.size() >= 8) && (Buffer.Compare(tag, sizeof(tag)) == 0) ) if ( (Buffer.size() >= 8) && (Buffer.Compare(tag, sizeof(tag)) == 0) )
{ {
@ -609,7 +609,7 @@ bool CDmrmmdvmProtocol::IsValidOptionPacket(const CBuffer &Buffer, CCallsign *ca
bool CDmrmmdvmProtocol::IsValidRssiPacket(const CBuffer &Buffer, CCallsign *callsign, int *rssi) bool CDmrmmdvmProtocol::IsValidRssiPacket(const CBuffer &Buffer, CCallsign *callsign, int *rssi)
{ {
uint8 tag[] = { 'R','P','T','I','N','T','R' }; uint8 tag[] = { 'R','P','T','I','N','T','R' };
bool valid = false; bool valid = false;
if ( (Buffer.size() == 17) && (Buffer.Compare(tag, sizeof(tag)) == 0) ) if ( (Buffer.size() == 17) && (Buffer.Compare(tag, sizeof(tag)) == 0) )
{ {
@ -624,11 +624,11 @@ bool CDmrmmdvmProtocol::IsValidRssiPacket(const CBuffer &Buffer, CCallsign *call
bool CDmrmmdvmProtocol::IsValidDvHeaderPacket(const CBuffer &Buffer, CDvHeaderPacket **header, uint8 *cmd, uint8 *CallType) bool CDmrmmdvmProtocol::IsValidDvHeaderPacket(const CBuffer &Buffer, CDvHeaderPacket **header, uint8 *cmd, uint8 *CallType)
{ {
uint8 tag[] = { 'D','M','R','D' }; uint8 tag[] = { 'D','M','R','D' };
bool valid = false; bool valid = false;
*header = NULL; *header = NULL;
*cmd = CMD_NONE; *cmd = CMD_NONE;
if ( (Buffer.size() == 55) && (Buffer.Compare(tag, sizeof(tag)) == 0) ) if ( (Buffer.size() == 55) && (Buffer.Compare(tag, sizeof(tag)) == 0) )
{ {
// frame details // frame details
@ -654,7 +654,7 @@ bool CDmrmmdvmProtocol::IsValidDvHeaderPacket(const CBuffer &Buffer, CDvHeaderPa
//CBPTC19696 bptc; //CBPTC19696 bptc;
//uint8 lcdata[12]; //uint8 lcdata[12];
//bptc.decode(&(Buffer.data()[20]), lcdata); //bptc.decode(&(Buffer.data()[20]), lcdata);
// crack DMR header // crack DMR header
//uint8 uiSeqId = Buffer.data()[4]; //uint8 uiSeqId = Buffer.data()[4];
uint32 uiSrcId = MAKEDWORD(MAKEWORD(Buffer.data()[7],Buffer.data()[6]),MAKEWORD(Buffer.data()[5],0)); uint32 uiSrcId = MAKEDWORD(MAKEWORD(Buffer.data()[7],Buffer.data()[6]),MAKEWORD(Buffer.data()[5],0));
@ -662,10 +662,10 @@ bool CDmrmmdvmProtocol::IsValidDvHeaderPacket(const CBuffer &Buffer, CDvHeaderPa
uint32 uiRptrId = MAKEDWORD(MAKEWORD(Buffer.data()[14],Buffer.data()[13]),MAKEWORD(Buffer.data()[12],Buffer.data()[11])); uint32 uiRptrId = MAKEDWORD(MAKEWORD(Buffer.data()[14],Buffer.data()[13]),MAKEWORD(Buffer.data()[12],Buffer.data()[11]));
//uint8 uiVoiceSeq = (Buffer.data()[15] & 0x0F); //uint8 uiVoiceSeq = (Buffer.data()[15] & 0x0F);
uint32 uiStreamId = *(uint32 *)(&Buffer.data()[16]); uint32 uiStreamId = *(uint32 *)(&Buffer.data()[16]);
// call type // call type
*CallType = uiCallType; *CallType = uiCallType;
// link/unlink command ? // link/unlink command ?
if ( uiDstId == 4000 ) if ( uiDstId == 4000 )
{ {
@ -679,14 +679,14 @@ bool CDmrmmdvmProtocol::IsValidDvHeaderPacket(const CBuffer &Buffer, CDvHeaderPa
{ {
*cmd = CMD_NONE; *cmd = CMD_NONE;
} }
// build DVHeader // build DVHeader
CCallsign csMY = CCallsign("", uiSrcId); CCallsign csMY = CCallsign("", uiSrcId);
CCallsign rpt1 = CCallsign("", uiRptrId); CCallsign rpt1 = CCallsign("", uiRptrId);
rpt1.SetModule(MMDVM_MODULE_ID); rpt1.SetModule(MMDVM_MODULE_ID);
CCallsign rpt2 = m_ReflectorCallsign; CCallsign rpt2 = m_ReflectorCallsign;
rpt2.SetModule(DmrDstIdToModule(uiDstId)); rpt2.SetModule(DmrDstIdToModule(uiDstId));
// and packet // and packet
*header = new CDvHeaderPacket(uiSrcId, CCallsign("CQCQCQ"), rpt1, rpt2, uiStreamId, 0, 0); *header = new CDvHeaderPacket(uiSrcId, CCallsign("CQCQCQ"), rpt1, rpt2, uiStreamId, 0, 0);
valid = (*header)->IsValid(); valid = (*header)->IsValid();
@ -705,12 +705,12 @@ bool CDmrmmdvmProtocol::IsValidDvHeaderPacket(const CBuffer &Buffer, CDvHeaderPa
bool CDmrmmdvmProtocol::IsValidDvFramePacket(const CBuffer &Buffer, CDvFramePacket **frames) bool CDmrmmdvmProtocol::IsValidDvFramePacket(const CBuffer &Buffer, CDvFramePacket **frames)
{ {
uint8 tag[] = { 'D','M','R','D' }; uint8 tag[] = { 'D','M','R','D' };
bool valid = false; bool valid = false;
frames[0] = NULL; frames[0] = NULL;
frames[1] = NULL; frames[1] = NULL;
frames[2] = NULL; frames[2] = NULL;
if ( (Buffer.size() == 55) && (Buffer.Compare(tag, sizeof(tag)) == 0) ) if ( (Buffer.size() == 55) && (Buffer.Compare(tag, sizeof(tag)) == 0) )
{ {
// frame details // frame details
@ -727,7 +727,7 @@ bool CDmrmmdvmProtocol::IsValidDvFramePacket(const CBuffer &Buffer, CDvFramePack
//uint32 uiRptrId = MAKEDWORD(MAKEWORD(Buffer.data()[14],Buffer.data()[13]),MAKEWORD(Buffer.data()[12],Buffer.data()[11])); //uint32 uiRptrId = MAKEDWORD(MAKEWORD(Buffer.data()[14],Buffer.data()[13]),MAKEWORD(Buffer.data()[12],Buffer.data()[11]));
uint8 uiVoiceSeq = (Buffer.data()[15] & 0x0F); uint8 uiVoiceSeq = (Buffer.data()[15] & 0x0F);
uint32 uiStreamId = *(uint32 *)(&Buffer.data()[16]); uint32 uiStreamId = *(uint32 *)(&Buffer.data()[16]);
// crack payload // crack payload
uint8 dmrframe[33]; uint8 dmrframe[33];
uint8 dmr3ambe[27]; uint8 dmr3ambe[27];
@ -744,25 +744,25 @@ bool CDmrmmdvmProtocol::IsValidDvFramePacket(const CBuffer &Buffer, CDvFramePack
dmrsync[0] = dmrframe[13] & 0x0F; dmrsync[0] = dmrframe[13] & 0x0F;
::memcpy(&dmrsync[1], &dmrframe[14], 5); ::memcpy(&dmrsync[1], &dmrframe[14], 5);
dmrsync[6] = dmrframe[19] & 0xF0; dmrsync[6] = dmrframe[19] & 0xF0;
// debug // debug
//CBuffer dump; //CBuffer dump;
//dump.Set(dmrsync, 6); //dump.Set(dmrsync, 6);
//dump.DebugDump(g_Reflector.m_DebugFile); //dump.DebugDump(g_Reflector.m_DebugFile);
// and create 3 dv frames // and create 3 dv frames
// frame1 // frame1
memcpy(dmrambe, &dmr3ambe[0], 9); memcpy(dmrambe, &dmr3ambe[0], 9);
frames[0] = new CDvFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 1); frames[0] = new CDvFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 1);
// frame2 // frame2
memcpy(dmrambe, &dmr3ambe[9], 9); memcpy(dmrambe, &dmr3ambe[9], 9);
frames[1] = new CDvFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 2); frames[1] = new CDvFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 2);
// frame3 // frame3
memcpy(dmrambe, &dmr3ambe[18], 9); memcpy(dmrambe, &dmr3ambe[18], 9);
frames[2] = new CDvFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 3); frames[2] = new CDvFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 3);
// check // check
valid = true; valid = true;
} }
@ -774,10 +774,10 @@ bool CDmrmmdvmProtocol::IsValidDvFramePacket(const CBuffer &Buffer, CDvFramePack
bool CDmrmmdvmProtocol::IsValidDvLastFramePacket(const CBuffer &Buffer, CDvLastFramePacket **frame) bool CDmrmmdvmProtocol::IsValidDvLastFramePacket(const CBuffer &Buffer, CDvLastFramePacket **frame)
{ {
uint8 tag[] = { 'D','M','R','D' }; uint8 tag[] = { 'D','M','R','D' };
bool valid = false; bool valid = false;
*frame = NULL; *frame = NULL;
if ( (Buffer.size() == 55) && (Buffer.Compare(tag, sizeof(tag)) == 0) ) if ( (Buffer.size() == 55) && (Buffer.Compare(tag, sizeof(tag)) == 0) )
{ {
// frame details // frame details
@ -803,7 +803,7 @@ bool CDmrmmdvmProtocol::IsValidDvLastFramePacket(const CBuffer &Buffer, CDvLastF
//CBPTC19696 bptc; //CBPTC19696 bptc;
//uint8 lcdata[12]; //uint8 lcdata[12];
//bptc.decode(&(Buffer.data()[20]), lcdata); //bptc.decode(&(Buffer.data()[20]), lcdata);
// crack DMR header // crack DMR header
//uint8 uiSeqId = Buffer.data()[4]; //uint8 uiSeqId = Buffer.data()[4];
//uint32 uiSrcId = MAKEDWORD(MAKEWORD(Buffer.data()[7],Buffer.data()[6]),MAKEWORD(Buffer.data()[5],0)); //uint32 uiSrcId = MAKEDWORD(MAKEWORD(Buffer.data()[7],Buffer.data()[6]),MAKEWORD(Buffer.data()[5],0));
@ -811,15 +811,15 @@ bool CDmrmmdvmProtocol::IsValidDvLastFramePacket(const CBuffer &Buffer, CDvLastF
//uint32 uiRptrId = MAKEDWORD(MAKEWORD(Buffer.data()[14],Buffer.data()[13]),MAKEWORD(Buffer.data()[12],Buffer.data()[11])); //uint32 uiRptrId = MAKEDWORD(MAKEWORD(Buffer.data()[14],Buffer.data()[13]),MAKEWORD(Buffer.data()[12],Buffer.data()[11]));
//uint8 uiVoiceSeq = (Buffer.data()[15] & 0x0F); //uint8 uiVoiceSeq = (Buffer.data()[15] & 0x0F);
uint32 uiStreamId = *(uint32 *)(&Buffer.data()[16]); uint32 uiStreamId = *(uint32 *)(&Buffer.data()[16]);
// dummy ambe // dummy ambe
uint8 ambe[9]; uint8 ambe[9];
::memset(ambe, 0, sizeof(ambe)); ::memset(ambe, 0, sizeof(ambe));
// and packet // and packet
*frame = new CDvLastFramePacket(ambe, dmrsync, uiStreamId, 0, 0); *frame = new CDvLastFramePacket(ambe, dmrsync, uiStreamId, 0, 0);
// check // check
valid = true; valid = true;
} }
@ -835,7 +835,7 @@ bool CDmrmmdvmProtocol::IsValidDvLastFramePacket(const CBuffer &Buffer, CDvLastF
void CDmrmmdvmProtocol::EncodeKeepAlivePacket(CBuffer *Buffer, CClient *Client) void CDmrmmdvmProtocol::EncodeKeepAlivePacket(CBuffer *Buffer, CClient *Client)
{ {
uint8 tag[] = { 'M','S','T','P','O','N','G' }; uint8 tag[] = { 'M','S','T','P','O','N','G' };
Buffer->Set(tag, sizeof(tag)); Buffer->Set(tag, sizeof(tag));
uint32 uiDmrId = Client->GetCallsign().GetDmrid(); uint32 uiDmrId = Client->GetCallsign().GetDmrid();
Buffer->Append((uint8 *)&uiDmrId, 4); Buffer->Append((uint8 *)&uiDmrId, 4);
@ -844,14 +844,14 @@ void CDmrmmdvmProtocol::EncodeKeepAlivePacket(CBuffer *Buffer, CClient *Client)
void CDmrmmdvmProtocol::EncodeAckPacket(CBuffer *Buffer, const CCallsign &Callsign) void CDmrmmdvmProtocol::EncodeAckPacket(CBuffer *Buffer, const CCallsign &Callsign)
{ {
uint8 tag[] = { 'R','P','T','A','C','K' }; uint8 tag[] = { 'R','P','T','A','C','K' };
Buffer->Set(tag, sizeof(tag)); Buffer->Set(tag, sizeof(tag));
} }
void CDmrmmdvmProtocol::EncodeConnectAckPacket(CBuffer *Buffer, const CCallsign &Callsign, uint32 AuthSeed) void CDmrmmdvmProtocol::EncodeConnectAckPacket(CBuffer *Buffer, const CCallsign &Callsign, uint32 AuthSeed)
{ {
uint8 tag[] = { 'R','P','T','A','C','K' }; uint8 tag[] = { 'R','P','T','A','C','K' };
Buffer->Set(tag, sizeof(tag)); Buffer->Set(tag, sizeof(tag));
Buffer->Append(AuthSeed); Buffer->Append(AuthSeed);
} }
@ -859,14 +859,14 @@ void CDmrmmdvmProtocol::EncodeConnectAckPacket(CBuffer *Buffer, const CCallsign
void CDmrmmdvmProtocol::EncodeNackPacket(CBuffer *Buffer, const CCallsign &Callsign) void CDmrmmdvmProtocol::EncodeNackPacket(CBuffer *Buffer, const CCallsign &Callsign)
{ {
uint8 tag[] = { 'M','S','T','N','A','K' }; uint8 tag[] = { 'M','S','T','N','A','K' };
Buffer->Set(tag, sizeof(tag)); Buffer->Set(tag, sizeof(tag));
} }
void CDmrmmdvmProtocol::EncodeClosePacket(CBuffer *Buffer, CClient *Client) void CDmrmmdvmProtocol::EncodeClosePacket(CBuffer *Buffer, CClient *Client)
{ {
uint8 tag[] = { 'M','S','T','C','L' }; uint8 tag[] = { 'M','S','T','C','L' };
Buffer->Set(tag, sizeof(tag)); Buffer->Set(tag, sizeof(tag));
} }
@ -874,9 +874,9 @@ void CDmrmmdvmProtocol::EncodeClosePacket(CBuffer *Buffer, CClient *Client)
bool CDmrmmdvmProtocol::EncodeDvHeaderPacket(const CDvHeaderPacket &Packet, uint8 seqid, CBuffer *Buffer) const bool CDmrmmdvmProtocol::EncodeDvHeaderPacket(const CDvHeaderPacket &Packet, uint8 seqid, CBuffer *Buffer) const
{ {
uint8 tag[] = { 'D','M','R','D' }; uint8 tag[] = { 'D','M','R','D' };
Buffer->Set(tag, sizeof(tag)); Buffer->Set(tag, sizeof(tag));
// DMR header // DMR header
// uiSeqId // uiSeqId
Buffer->Append((uint8)seqid); Buffer->Append((uint8)seqid);
@ -898,16 +898,16 @@ bool CDmrmmdvmProtocol::EncodeDvHeaderPacket(const CDvHeaderPacket &Packet, uint
// uiStreamId // uiStreamId
uint32 uiStreamId = Packet.GetStreamId(); uint32 uiStreamId = Packet.GetStreamId();
Buffer->Append((uint32)uiStreamId); Buffer->Append((uint32)uiStreamId);
// Payload // Payload
AppendVoiceLCToBuffer(Buffer, uiSrcId); AppendVoiceLCToBuffer(Buffer, uiSrcId);
// BER // BER
Buffer->Append((uint8)0); Buffer->Append((uint8)0);
// RSSI // RSSI
Buffer->Append((uint8)0); Buffer->Append((uint8)0);
// done // done
return true; return true;
} }
@ -919,7 +919,7 @@ void CDmrmmdvmProtocol::EncodeDvPacket(
{ {
uint8 tag[] = { 'D','M','R','D' }; uint8 tag[] = { 'D','M','R','D' };
Buffer->Set(tag, sizeof(tag)); Buffer->Set(tag, sizeof(tag));
// DMR header // DMR header
// uiSeqId // uiSeqId
Buffer->Append((uint8)seqid); Buffer->Append((uint8)seqid);
@ -945,11 +945,11 @@ void CDmrmmdvmProtocol::EncodeDvPacket(
} }
uiBitField |= (DvFrame0.GetDmrPacketId() & 0x0F); uiBitField |= (DvFrame0.GetDmrPacketId() & 0x0F);
Buffer->Append((uint8)uiBitField); Buffer->Append((uint8)uiBitField);
// uiStreamId // uiStreamId
uint32 uiStreamId = Header.GetStreamId(); uint32 uiStreamId = Header.GetStreamId();
Buffer->Append((uint32)uiStreamId); Buffer->Append((uint32)uiStreamId);
// Payload // Payload
// frame0 // frame0
Buffer->ReplaceAt(20, DvFrame0.GetAmbePlus(), 9); Buffer->ReplaceAt(20, DvFrame0.GetAmbePlus(), 9);
@ -961,7 +961,7 @@ void CDmrmmdvmProtocol::EncodeDvPacket(
Buffer->ReplaceAt(39, (uint8)(Buffer->at(39) & 0x0F)); Buffer->ReplaceAt(39, (uint8)(Buffer->at(39) & 0x0F));
// frame2 // frame2
Buffer->ReplaceAt(44, DvFrame2.GetAmbePlus(), 9); Buffer->ReplaceAt(44, DvFrame2.GetAmbePlus(), 9);
// sync or embedded signaling // sync or embedded signaling
ReplaceEMBInBuffer(Buffer, DvFrame0.GetDmrPacketId()); ReplaceEMBInBuffer(Buffer, DvFrame0.GetDmrPacketId());
@ -972,18 +972,18 @@ void CDmrmmdvmProtocol::EncodeDvPacket(
// BER // BER
Buffer->Append((uint8)0); Buffer->Append((uint8)0);
// RSSI // RSSI
Buffer->Append((uint8)0); Buffer->Append((uint8)0);
} }
void CDmrmmdvmProtocol::EncodeDvLastPacket(const CDvHeaderPacket &Packet, uint8 seqid, CBuffer *Buffer) const void CDmrmmdvmProtocol::EncodeDvLastPacket(const CDvHeaderPacket &Packet, uint8 seqid, CBuffer *Buffer) const
{ {
uint8 tag[] = { 'D','M','R','D' }; uint8 tag[] = { 'D','M','R','D' };
Buffer->Set(tag, sizeof(tag)); Buffer->Set(tag, sizeof(tag));
// DMR header // DMR header
// uiSeqId // uiSeqId
Buffer->Append((uint8)seqid); Buffer->Append((uint8)seqid);
@ -1005,13 +1005,13 @@ void CDmrmmdvmProtocol::EncodeDvLastPacket(const CDvHeaderPacket &Packet, uint8
// uiStreamId // uiStreamId
uint32 uiStreamId = Packet.GetStreamId(); uint32 uiStreamId = Packet.GetStreamId();
Buffer->Append((uint32)uiStreamId); Buffer->Append((uint32)uiStreamId);
// Payload // Payload
AppendTerminatorLCToBuffer(Buffer, uiSrcId); AppendTerminatorLCToBuffer(Buffer, uiSrcId);
// BER // BER
Buffer->Append((uint8)0); Buffer->Append((uint8)0);
// RSSI // RSSI
Buffer->Append((uint8)0); Buffer->Append((uint8)0);
} }
@ -1041,7 +1041,7 @@ uint32 CDmrmmdvmProtocol::ModuleToDmrDestId(char m) const
void CDmrmmdvmProtocol::AppendVoiceLCToBuffer(CBuffer *buffer, uint32 uiSrcId) const void CDmrmmdvmProtocol::AppendVoiceLCToBuffer(CBuffer *buffer, uint32 uiSrcId) const
{ {
uint8 payload[33]; uint8 payload[33];
// fill payload // fill payload
CBPTC19696 bptc; CBPTC19696 bptc;
::memset(payload, 0, sizeof(payload)); ::memset(payload, 0, sizeof(payload));
@ -1076,11 +1076,11 @@ void CDmrmmdvmProtocol::AppendVoiceLCToBuffer(CBuffer *buffer, uint32 uiSrcId) c
payload[13U] = (payload[13U] & 0x0FU) | ((slottype[0U] << 6) & 0xC0U) | ((slottype[1U] >> 2) & 0x30U); payload[13U] = (payload[13U] & 0x0FU) | ((slottype[0U] << 6) & 0xC0U) | ((slottype[1U] >> 2) & 0x30U);
payload[19U] = (payload[19U] & 0xF0U) | ((slottype[1U] >> 2) & 0x0FU); payload[19U] = (payload[19U] & 0xF0U) | ((slottype[1U] >> 2) & 0x0FU);
payload[20U] = (payload[20U] & 0x03U) | ((slottype[1U] << 6) & 0xC0U) | ((slottype[2U] >> 2) & 0x3CU); payload[20U] = (payload[20U] & 0x03U) | ((slottype[1U] << 6) & 0xC0U) | ((slottype[2U] >> 2) & 0x3CU);
} }
// and encode // and encode
bptc.encode(lc, payload); bptc.encode(lc, payload);
// and append // and append
buffer->Append(payload, sizeof(payload)); buffer->Append(payload, sizeof(payload));
} }
@ -1088,7 +1088,7 @@ void CDmrmmdvmProtocol::AppendVoiceLCToBuffer(CBuffer *buffer, uint32 uiSrcId) c
void CDmrmmdvmProtocol::AppendTerminatorLCToBuffer(CBuffer *buffer, uint32 uiSrcId) const void CDmrmmdvmProtocol::AppendTerminatorLCToBuffer(CBuffer *buffer, uint32 uiSrcId) const
{ {
uint8 payload[33]; uint8 payload[33];
// fill payload // fill payload
CBPTC19696 bptc; CBPTC19696 bptc;
::memset(payload, 0, sizeof(payload)); ::memset(payload, 0, sizeof(payload));
@ -1126,7 +1126,7 @@ void CDmrmmdvmProtocol::AppendTerminatorLCToBuffer(CBuffer *buffer, uint32 uiSrc
} }
// and encode // and encode
bptc.encode(lc, payload); bptc.encode(lc, payload);
// and append // and append
buffer->Append(payload, sizeof(payload)); buffer->Append(payload, sizeof(payload));
} }

@ -4,6 +4,7 @@
// //
// Created by Jean-Luc Deltombe (LX3JL) on 10/01/2016. // Created by Jean-Luc Deltombe (LX3JL) on 10/01/2016.
// 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.
@ -49,23 +50,23 @@ static uint8 g_DmrSyncMSData[] = { 0x0D,0x5D,0x7F,0x77,0xFD,0x75,0x70 };
bool CDmrplusProtocol::Init(void) bool CDmrplusProtocol::Init(void)
{ {
bool ok; bool ok;
// base class // base class
ok = CProtocol::Init(); ok = CProtocol::Init();
// update the reflector callsign // update the reflector callsign
//m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"DMR", 3); //m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"DMR", 3);
// create our socket // create our socket
ok &= m_Socket.Open(DMRPLUS_PORT); ok &= m_Socket.Open(DMRPLUS_PORT);
// update time // update time
m_LastKeepaliveTime.Now(); m_LastKeepaliveTime.Now();
// random number generator // random number generator
time_t t; time_t t;
::srand((unsigned) time(&t)); ::srand((unsigned) time(&t));
// done // done
return ok; return ok;
} }
@ -83,7 +84,7 @@ void CDmrplusProtocol::Task(void)
char ToLinkModule; char ToLinkModule;
CDvHeaderPacket *Header; CDvHeaderPacket *Header;
CDvFramePacket *Frames[3]; CDvFramePacket *Frames[3];
// handle incoming packets // handle incoming packets
if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 ) if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 )
{ {
@ -113,7 +114,7 @@ void CDmrplusProtocol::Task(void)
//std::cout << "DMRplus DV header:" << std::endl; //std::cout << "DMRplus DV header:" << std::endl;
//std::cout << "DMRplus DV header:" << std::endl << *Header << std::endl; //std::cout << "DMRplus DV header:" << std::endl << *Header << std::endl;
//Buffer.DebugDump(g_Reflector.m_DebugFile); //Buffer.DebugDump(g_Reflector.m_DebugFile);
// callsign muted? // callsign muted?
if ( g_GateKeeper.MayTransmit(Header->GetMyCallsign(), Ip, PROTOCOL_DMRPLUS) ) if ( g_GateKeeper.MayTransmit(Header->GetMyCallsign(), Ip, PROTOCOL_DMRPLUS) )
{ {
@ -128,14 +129,14 @@ void CDmrplusProtocol::Task(void)
else if ( IsValidConnectPacket(Buffer, &Callsign, &ToLinkModule, Ip) ) else if ( IsValidConnectPacket(Buffer, &Callsign, &ToLinkModule, Ip) )
{ {
//std::cout << "DMRplus keepalive/connect packet for module " << ToLinkModule << " from " << Callsign << " at " << Ip << std::endl; //std::cout << "DMRplus keepalive/connect packet for module " << ToLinkModule << " from " << Callsign << " at " << Ip << std::endl;
// callsign authorized? // callsign authorized?
if ( g_GateKeeper.MayLink(Callsign, Ip, PROTOCOL_DMRPLUS) ) if ( g_GateKeeper.MayLink(Callsign, Ip, PROTOCOL_DMRPLUS) )
{ {
// acknowledge the request // acknowledge the request
EncodeConnectAckPacket(&Buffer); EncodeConnectAckPacket(&Buffer);
m_Socket.Send(Buffer, Ip); m_Socket.Send(Buffer, Ip);
// add client if needed // add client if needed
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
CClient *client = clients->FindClient(Callsign, Ip, PROTOCOL_DMRPLUS); CClient *client = clients->FindClient(Callsign, Ip, PROTOCOL_DMRPLUS);
@ -143,10 +144,10 @@ void CDmrplusProtocol::Task(void)
if ( client == NULL ) if ( client == NULL )
{ {
std::cout << "DMRplus connect packet for module " << ToLinkModule << " from " << Callsign << " at " << Ip << std::endl; std::cout << "DMRplus connect packet for module " << ToLinkModule << " from " << Callsign << " at " << Ip << std::endl;
// create the client // create the client
CDmrplusClient *newclient = new CDmrplusClient(Callsign, Ip, ToLinkModule); CDmrplusClient *newclient = new CDmrplusClient(Callsign, Ip, ToLinkModule);
// and append // and append
clients->AddClient(newclient); clients->AddClient(newclient);
} }
@ -163,12 +164,12 @@ void CDmrplusProtocol::Task(void)
EncodeConnectNackPacket(&Buffer); EncodeConnectNackPacket(&Buffer);
m_Socket.Send(Buffer, Ip); m_Socket.Send(Buffer, Ip);
} }
} }
else if ( IsValidDisconnectPacket(Buffer, &Callsign, &ToLinkModule) ) else if ( IsValidDisconnectPacket(Buffer, &Callsign, &ToLinkModule) )
{ {
std::cout << "DMRplus disconnect packet for module " << ToLinkModule << " from " << Callsign << " at " << Ip << std::endl; std::cout << "DMRplus disconnect packet for module " << ToLinkModule << " from " << Callsign << " at " << Ip << std::endl;
// find client & remove it // find client & remove it
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
CClient *client = clients->FindClient(Ip, PROTOCOL_DMRPLUS); CClient *client = clients->FindClient(Ip, PROTOCOL_DMRPLUS);
@ -183,20 +184,20 @@ void CDmrplusProtocol::Task(void)
//std::cout << "DMRPlus packet (" << Buffer.size() << ")" << " at " << Ip << std::endl; //std::cout << "DMRPlus packet (" << Buffer.size() << ")" << " at " << Ip << std::endl;
} }
} }
// handle end of streaming timeout // handle end of streaming timeout
CheckStreamsTimeout(); CheckStreamsTimeout();
// handle queue from reflector // handle queue from reflector
HandleQueue(); HandleQueue();
// keep client alive // keep client alive
if ( m_LastKeepaliveTime.DurationSinceNow() > DMRPLUS_KEEPALIVE_PERIOD ) if ( m_LastKeepaliveTime.DurationSinceNow() > DMRPLUS_KEEPALIVE_PERIOD )
{ {
// //
HandleKeepalives(); HandleKeepalives();
// update time // update time
m_LastKeepaliveTime.Now(); m_LastKeepaliveTime.Now();
} }
@ -208,7 +209,7 @@ void CDmrplusProtocol::Task(void)
bool CDmrplusProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip) bool CDmrplusProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
{ {
bool newstream = false; bool newstream = false;
// find the stream // find the stream
CPacketStream *stream = GetStream(Header->GetStreamId()); CPacketStream *stream = GetStream(Header->GetStreamId());
if ( stream == NULL ) if ( stream == NULL )
@ -237,18 +238,18 @@ bool CDmrplusProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip
// and delete packet // and delete packet
delete Header; delete Header;
} }
// update last heard // update last heard
g_Reflector.GetUsers()->Hearing(Header->GetMyCallsign(), Header->GetRpt1Callsign(), Header->GetRpt2Callsign()); g_Reflector.GetUsers()->Hearing(Header->GetMyCallsign(), Header->GetRpt1Callsign(), Header->GetRpt2Callsign());
g_Reflector.ReleaseUsers(); g_Reflector.ReleaseUsers();
// delete header if needed // delete header if needed
if ( !newstream ) if ( !newstream )
{ {
delete Header; delete Header;
} }
// done // done
return newstream; return newstream;
} }
@ -258,17 +259,17 @@ bool CDmrplusProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip
void CDmrplusProtocol::HandleQueue(void) void CDmrplusProtocol::HandleQueue(void)
{ {
m_Queue.Lock(); m_Queue.Lock();
while ( !m_Queue.empty() ) while ( !m_Queue.empty() )
{ {
// get the packet // get the packet
CPacket *packet = m_Queue.front(); CPacket *packet = m_Queue.front();
m_Queue.pop(); m_Queue.pop();
// get our sender's id // get our sender's id
int iModId = g_Reflector.GetModuleIndex(packet->GetModuleId()); int iModId = g_Reflector.GetModuleIndex(packet->GetModuleId());
// encode // encode
CBuffer buffer; CBuffer buffer;
@ -279,7 +280,7 @@ void CDmrplusProtocol::HandleQueue(void)
// this relies on queue feeder setting valid module id // this relies on queue feeder setting valid module id
m_StreamsCache[iModId].m_dvHeader = CDvHeaderPacket((const CDvHeaderPacket &)*packet); m_StreamsCache[iModId].m_dvHeader = CDvHeaderPacket((const CDvHeaderPacket &)*packet);
m_StreamsCache[iModId].m_uiSeqId = 4; m_StreamsCache[iModId].m_uiSeqId = 4;
// encode it // encode it
EncodeDvHeaderPacket((const CDvHeaderPacket &)*packet, &buffer); EncodeDvHeaderPacket((const CDvHeaderPacket &)*packet, &buffer);
} }
@ -307,17 +308,17 @@ void CDmrplusProtocol::HandleQueue(void)
default: default:
break; break;
} }
} }
// send it // send it
if ( buffer.size() > 0 ) if ( buffer.size() > 0 )
{ {
// and push it to all our clients linked to the module and who are not streaming in // and push it to all our clients linked to the module and who are not streaming in
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
int index = -1; auto it = clients->begin();
CClient *client = NULL; CClient *client = NULL;
while ( (client = clients->FindNextClient(PROTOCOL_DMRPLUS, &index)) != NULL ) while ( (client = clients->FindNextClient(PROTOCOL_DMRPLUS, it)) != NULL )
{ {
// is this client busy ? // is this client busy ?
if ( !client->IsAMaster() && (client->GetReflectorModule() == packet->GetModuleId()) ) if ( !client->IsAMaster() && (client->GetReflectorModule() == packet->GetModuleId()) )
@ -327,7 +328,7 @@ void CDmrplusProtocol::HandleQueue(void)
} }
} }
g_Reflector.ReleaseClients(); g_Reflector.ReleaseClients();
// debug // debug
//buffer.DebugDump(g_Reflector.m_DebugFile); //buffer.DebugDump(g_Reflector.m_DebugFile);
} }
@ -344,9 +345,9 @@ void CDmrplusProtocol::SendBufferToClients(const CBuffer &buffer, uint8 module)
{ {
// and push it to all our clients linked to the module and who are not streaming in // and push it to all our clients linked to the module and who are not streaming in
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
int index = -1; auto it = clients->begin();
CClient *client = NULL; CClient *client = NULL;
while ( (client = clients->FindNextClient(PROTOCOL_DMRPLUS, &index)) != NULL ) while ( (client = clients->FindNextClient(PROTOCOL_DMRPLUS, it)) != NULL )
{ {
// is this client busy ? // is this client busy ?
if ( !client->IsAMaster() && (client->GetReflectorModule() == module) ) if ( !client->IsAMaster() && (client->GetReflectorModule() == module) )
@ -356,7 +357,7 @@ void CDmrplusProtocol::SendBufferToClients(const CBuffer &buffer, uint8 module)
} }
} }
g_Reflector.ReleaseClients(); g_Reflector.ReleaseClients();
// debug // debug
//buffer.DebugDump(g_Reflector.m_DebugFile); //buffer.DebugDump(g_Reflector.m_DebugFile);
} }
@ -371,12 +372,12 @@ void CDmrplusProtocol::HandleKeepalives(void)
// DMRplus protocol keepalive request is client tasks // DMRplus protocol keepalive request is client tasks
// here, just check that all clients are still alive // here, just check that all clients are still alive
// and disconnect them if not // and disconnect them if not
// iterate on clients // iterate on clients
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
int index = -1; auto it = clients->begin();
CClient *client = NULL; CClient *client = NULL;
while ( (client = clients->FindNextClient(PROTOCOL_DMRPLUS, &index)) != NULL ) while ( (client = clients->FindNextClient(PROTOCOL_DMRPLUS, it)) != NULL )
{ {
// is this client busy ? // is this client busy ?
if ( client->IsAMaster() ) if ( client->IsAMaster() )
@ -391,12 +392,12 @@ void CDmrplusProtocol::HandleKeepalives(void)
//CBuffer disconnect; //CBuffer disconnect;
//EncodeDisconnectPacket(&disconnect, client); //EncodeDisconnectPacket(&disconnect, client);
//m_Socket.Send(disconnect, client->GetIp()); //m_Socket.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;
clients->RemoveClient(client); clients->RemoveClient(client);
} }
} }
g_Reflector.ReleaseClients(); g_Reflector.ReleaseClients();
} }
@ -471,7 +472,7 @@ bool CDmrplusProtocol::IsValidDvHeaderPacket(const CIp &Ip, const CBuffer &Buffe
CCallsign rpt2 = m_ReflectorCallsign; CCallsign rpt2 = m_ReflectorCallsign;
rpt2.SetModule(DmrDstIdToModule(uiDstId)); rpt2.SetModule(DmrDstIdToModule(uiDstId));
uint32 uiStreamId = IpToStreamId(Ip); uint32 uiStreamId = IpToStreamId(Ip);
// and packet // and packet
*Header = new CDvHeaderPacket(uiSrcId, CCallsign("CQCQCQ"), rpt1, rpt2, uiStreamId, 0, 0); *Header = new CDvHeaderPacket(uiSrcId, CCallsign("CQCQCQ"), rpt1, rpt2, uiStreamId, 0, 0);
valid = (*Header)->IsValid(); valid = (*Header)->IsValid();
@ -492,7 +493,7 @@ bool CDmrplusProtocol::IsValidDvFramePacket(const CIp &Ip, const CBuffer &Buffer
frames[0] = NULL; frames[0] = NULL;
frames[1] = NULL; frames[1] = NULL;
frames[2] = NULL; frames[2] = NULL;
uint8 uiPacketType = Buffer.data()[8]; uint8 uiPacketType = Buffer.data()[8];
if ( (Buffer.size() == 72) && ((uiPacketType == 1) || (uiPacketType == 3)) ) if ( (Buffer.size() == 72) && ((uiPacketType == 1) || (uiPacketType == 3)) )
{ {
@ -507,7 +508,7 @@ bool CDmrplusProtocol::IsValidDvFramePacket(const CIp &Ip, const CBuffer &Buffer
uint8 uiVoiceSeq = (Buffer.data()[18] & 0x0F) - 7; // aka slot type uint8 uiVoiceSeq = (Buffer.data()[18] & 0x0F) - 7; // aka slot type
//uint32 uiDstId = *(uint32 *)(&Buffer.data()[64]) & 0x00FFFFFF; //uint32 uiDstId = *(uint32 *)(&Buffer.data()[64]) & 0x00FFFFFF;
//uint32 uiSrcId = *(uint32 *)(&Buffer.data()[68]) & 0x00FFFFFF; //uint32 uiSrcId = *(uint32 *)(&Buffer.data()[68]) & 0x00FFFFFF;
// crack payload // crack payload
uint8 dmrframe[33]; uint8 dmrframe[33];
uint8 dmr3ambe[27]; uint8 dmr3ambe[27];
@ -526,17 +527,17 @@ bool CDmrplusProtocol::IsValidDvFramePacket(const CIp &Ip, const CBuffer &Buffer
dmrsync[0] = dmrframe[13] & 0x0F; dmrsync[0] = dmrframe[13] & 0x0F;
::memcpy(&dmrsync[1], &dmrframe[14], 5); ::memcpy(&dmrsync[1], &dmrframe[14], 5);
dmrsync[6] = dmrframe[19] & 0xF0; dmrsync[6] = dmrframe[19] & 0xF0;
// and create 3 dv frames // and create 3 dv frames
uint32 uiStreamId = IpToStreamId(Ip); uint32 uiStreamId = IpToStreamId(Ip);
// frame1 // frame1
memcpy(dmrambe, &dmr3ambe[0], 9); memcpy(dmrambe, &dmr3ambe[0], 9);
frames[0] = new CDvFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 1); frames[0] = new CDvFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 1);
// frame2 // frame2
memcpy(dmrambe, &dmr3ambe[9], 9); memcpy(dmrambe, &dmr3ambe[9], 9);
frames[1] = new CDvFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 2); frames[1] = new CDvFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 2);
// frame3 // frame3
memcpy(dmrambe, &dmr3ambe[18], 9); memcpy(dmrambe, &dmr3ambe[18], 9);
if ( uiPacketType == 3 ) if ( uiPacketType == 3 )
@ -547,12 +548,12 @@ bool CDmrplusProtocol::IsValidDvFramePacket(const CIp &Ip, const CBuffer &Buffer
{ {
frames[2] = new CDvFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 3); frames[2] = new CDvFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 3);
} }
// check // check
valid = true; valid = true;
} }
} }
// done // done
return valid; return valid;
} }
@ -578,7 +579,7 @@ bool CDmrplusProtocol::EncodeDvHeaderPacket(const CDvHeaderPacket &Packet, CBuff
uint8 tag[] = { 0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02, uint8 tag[] = { 0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,
0x00,0x05,0x01,0x02,0x00,0x00,0x00 } ; 0x00,0x05,0x01,0x02,0x00,0x00,0x00 } ;
Buffer->Set(tag, sizeof(tag)); Buffer->Set(tag, sizeof(tag));
// uiSeqId // uiSeqId
//Buffer->ReplaceAt(4, 2); //Buffer->ReplaceAt(4, 2);
// uiPktType // uiPktType
@ -603,7 +604,7 @@ bool CDmrplusProtocol::EncodeDvHeaderPacket(const CDvHeaderPacket &Packet, CBuff
Buffer->ReplaceAt(38, LOBYTE(HIWORD(uiSrcId))); Buffer->ReplaceAt(38, LOBYTE(HIWORD(uiSrcId)));
Buffer->ReplaceAt(40, HIBYTE(LOWORD(uiSrcId))); Buffer->ReplaceAt(40, HIBYTE(LOWORD(uiSrcId)));
Buffer->ReplaceAt(42, LOBYTE(LOWORD(uiSrcId))); Buffer->ReplaceAt(42, LOBYTE(LOWORD(uiSrcId)));
// reserved // reserved
Buffer->Append((uint16)0x0000); Buffer->Append((uint16)0x0000);
// uiCallType // uiCallType
@ -614,7 +615,7 @@ bool CDmrplusProtocol::EncodeDvHeaderPacket(const CDvHeaderPacket &Packet, CBuff
Buffer->Append(uiDstId); Buffer->Append(uiDstId);
// uiSrcId // uiSrcId
Buffer->Append(uiSrcId); Buffer->Append(uiSrcId);
// done // done
return true; return true;
} }
@ -624,11 +625,11 @@ void CDmrplusProtocol::EncodeDvPacket
const CDvFramePacket &DvFrame0, const CDvFramePacket &DvFrame1, const CDvFramePacket &DvFrame2, const CDvFramePacket &DvFrame0, const CDvFramePacket &DvFrame1, const CDvFramePacket &DvFrame2,
uint8 seqid, CBuffer *Buffer) const uint8 seqid, CBuffer *Buffer) const
{ {
uint8 tag[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, uint8 tag[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x00,0x05,0x01,0x02,0x00,0x00,0x00 } ; 0x00,0x05,0x01,0x02,0x00,0x00,0x00 } ;
Buffer->Set(tag, sizeof(tag)); Buffer->Set(tag, sizeof(tag));
// uiSeqId // uiSeqId
Buffer->ReplaceAt(4, seqid); Buffer->ReplaceAt(4, seqid);
// uiPktType // uiPktType
@ -647,7 +648,7 @@ void CDmrplusProtocol::EncodeDvPacket
Buffer->Append((uint16)0x1111); Buffer->Append((uint16)0x1111);
// reserved // reserved
Buffer->Append((uint16)0x0000); Buffer->Append((uint16)0x0000);
// payload // payload
uint32 uiSrcId = Header.GetMyCallsign().GetDmrid() & 0x00FFFFFF; uint32 uiSrcId = Header.GetMyCallsign().GetDmrid() & 0x00FFFFFF;
uint32 uiDstId = ModuleToDmrDestId(Header.GetRpt2Module()) & 0x00FFFFFF; uint32 uiDstId = ModuleToDmrDestId(Header.GetRpt2Module()) & 0x00FFFFFF;
@ -735,7 +736,7 @@ uint32 CDmrplusProtocol::ModuleToDmrDestId(char m) const
void CDmrplusProtocol::AppendVoiceLCToBuffer(CBuffer *buffer, uint32 uiSrcId) const void CDmrplusProtocol::AppendVoiceLCToBuffer(CBuffer *buffer, uint32 uiSrcId) const
{ {
uint8 payload[34]; uint8 payload[34];
// fill payload // fill payload
CBPTC19696 bptc; CBPTC19696 bptc;
::memset(payload, 0, sizeof(payload)); ::memset(payload, 0, sizeof(payload));
@ -770,11 +771,11 @@ void CDmrplusProtocol::AppendVoiceLCToBuffer(CBuffer *buffer, uint32 uiSrcId) co
payload[13U] = (payload[13U] & 0x0FU) | ((slottype[0U] << 6) & 0xC0U) | ((slottype[1U] >> 2) & 0x30U); payload[13U] = (payload[13U] & 0x0FU) | ((slottype[0U] << 6) & 0xC0U) | ((slottype[1U] >> 2) & 0x30U);
payload[19U] = (payload[19U] & 0xF0U) | ((slottype[1U] >> 2) & 0x0FU); payload[19U] = (payload[19U] & 0xF0U) | ((slottype[1U] >> 2) & 0x0FU);
payload[20U] = (payload[20U] & 0x03U) | ((slottype[1U] << 6) & 0xC0U) | ((slottype[2U] >> 2) & 0x3CU); payload[20U] = (payload[20U] & 0x03U) | ((slottype[1U] << 6) & 0xC0U) | ((slottype[2U] >> 2) & 0x3CU);
} }
// and encode // and encode
bptc.encode(lc, payload); bptc.encode(lc, payload);
// and append // and append
buffer->Append(payload, sizeof(payload)); buffer->Append(payload, sizeof(payload));
} }

@ -4,6 +4,7 @@
// //
// Created by Jean-Luc Deltombe (LX3JL) on 01/11/2015. // Created by Jean-Luc Deltombe (LX3JL) on 01/11/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.
@ -19,7 +20,7 @@
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>. // along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#include "main.h" #include "main.h"
@ -36,23 +37,23 @@
bool CDplusProtocol::Init(void) bool CDplusProtocol::Init(void)
{ {
bool ok; bool ok;
// base class // base class
ok = CProtocol::Init(); ok = CProtocol::Init();
// update the reflector callsign // update the reflector callsign
m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"REF", 3); m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"REF", 3);
// create our socket // create our socket
ok &= m_Socket.Open(DPLUS_PORT); ok &= m_Socket.Open(DPLUS_PORT);
if ( !ok ) if ( !ok )
{ {
std::cout << "Error opening socket on port UDP" << DPLUS_PORT << " on ip " << g_Reflector.GetListenIp() << std::endl; 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 ok;
} }
@ -70,7 +71,7 @@ void CDplusProtocol::Task(void)
CDvHeaderPacket *Header; CDvHeaderPacket *Header;
CDvFramePacket *Frame; CDvFramePacket *Frame;
CDvLastFramePacket *LastFrame; CDvLastFramePacket *LastFrame;
// handle incoming packets // handle incoming packets
if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 ) if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 )
{ {
@ -78,14 +79,14 @@ void CDplusProtocol::Task(void)
if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL ) if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL )
{ {
//std::cout << "DPlus DV frame" << std::endl; //std::cout << "DPlus DV frame" << std::endl;
// handle it // handle it
OnDvFramePacketIn(Frame, &Ip); OnDvFramePacketIn(Frame, &Ip);
} }
else if ( (Header = IsValidDvHeaderPacket(Buffer)) != NULL ) else if ( (Header = IsValidDvHeaderPacket(Buffer)) != NULL )
{ {
//std::cout << "DPlus DV header:" << std::endl << *Header << std::endl; //std::cout << "DPlus DV header:" << std::endl << *Header << std::endl;
// callsign muted? // callsign muted?
if ( g_GateKeeper.MayTransmit(Header->GetMyCallsign(), Ip, PROTOCOL_DPLUS, Header->GetRpt2Module()) ) if ( g_GateKeeper.MayTransmit(Header->GetMyCallsign(), Ip, PROTOCOL_DPLUS, Header->GetRpt2Module()) )
{ {
@ -100,7 +101,7 @@ void CDplusProtocol::Task(void)
else if ( (LastFrame = IsValidDvLastFramePacket(Buffer)) != NULL ) else if ( (LastFrame = IsValidDvLastFramePacket(Buffer)) != NULL )
{ {
//std::cout << "DPlus DV last frame" << std::endl; //std::cout << "DPlus DV last frame" << std::endl;
// handle it // handle it
OnDvLastFramePacketIn(LastFrame, &Ip); OnDvLastFramePacketIn(LastFrame, &Ip);
} }
@ -114,17 +115,17 @@ void CDplusProtocol::Task(void)
else if ( IsValidLoginPacket(Buffer, &Callsign) ) else if ( IsValidLoginPacket(Buffer, &Callsign) )
{ {
std::cout << "DPlus login packet from " << Callsign << " at " << Ip << std::endl; std::cout << "DPlus login packet from " << Callsign << " at " << Ip << std::endl;
// callsign authorized? // callsign authorized?
if ( g_GateKeeper.MayLink(Callsign, Ip, PROTOCOL_DPLUS) ) if ( g_GateKeeper.MayLink(Callsign, Ip, PROTOCOL_DPLUS) )
{ {
// acknowledge the request // acknowledge the request
EncodeLoginAckPacket(&Buffer); EncodeLoginAckPacket(&Buffer);
m_Socket.Send(Buffer, Ip); m_Socket.Send(Buffer, Ip);
// create the client // create the client
CDplusClient *client = new CDplusClient(Callsign, Ip); CDplusClient *client = new CDplusClient(Callsign, Ip);
// and append // and append
g_Reflector.GetClients()->AddClient(client); g_Reflector.GetClients()->AddClient(client);
g_Reflector.ReleaseClients(); g_Reflector.ReleaseClients();
@ -135,12 +136,12 @@ void CDplusProtocol::Task(void)
EncodeLoginNackPacket(&Buffer); EncodeLoginNackPacket(&Buffer);
m_Socket.Send(Buffer, Ip); m_Socket.Send(Buffer, Ip);
} }
} }
else if ( IsValidDisconnectPacket(Buffer) ) else if ( IsValidDisconnectPacket(Buffer) )
{ {
std::cout << "DPlus disconnect packet from " << Ip << std::endl; std::cout << "DPlus disconnect packet from " << Ip << std::endl;
// find client // find client
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
CClient *client = clients->FindClient(Ip, PROTOCOL_DPLUS); CClient *client = clients->FindClient(Ip, PROTOCOL_DPLUS);
@ -157,12 +158,12 @@ void CDplusProtocol::Task(void)
else if ( IsValidKeepAlivePacket(Buffer) ) else if ( IsValidKeepAlivePacket(Buffer) )
{ {
//std::cout << "DPlus keepalive packet from " << Ip << std::endl; //std::cout << "DPlus keepalive packet from " << Ip << std::endl;
// find all clients with that callsign & ip and keep them alive // find all clients with that callsign & ip and keep them alive
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
int index = -1; auto it = clients->begin();
CClient *client = NULL; CClient *client = NULL;
while ( (client = clients->FindNextClient(Ip, PROTOCOL_DPLUS, &index)) != NULL ) while ( (client = clients->FindNextClient(Ip, PROTOCOL_DPLUS, it)) != NULL )
{ {
client->Alive(); client->Alive();
} }
@ -173,19 +174,19 @@ void CDplusProtocol::Task(void)
std::cout << "DPlus packet (" << Buffer.size() << ")" << std::endl; std::cout << "DPlus packet (" << Buffer.size() << ")" << std::endl;
} }
} }
// handle end of streaming timeout // handle end of streaming timeout
CheckStreamsTimeout(); CheckStreamsTimeout();
// handle queue from reflector // handle queue from reflector
HandleQueue(); HandleQueue();
// keep client alive // keep client alive
if ( m_LastKeepaliveTime.DurationSinceNow() > DPLUS_KEEPALIVE_PERIOD ) if ( m_LastKeepaliveTime.DurationSinceNow() > DPLUS_KEEPALIVE_PERIOD )
{ {
// //
HandleKeepalives(); HandleKeepalives();
// update time // update time
m_LastKeepaliveTime.Now(); m_LastKeepaliveTime.Now();
} }
@ -197,14 +198,14 @@ void CDplusProtocol::Task(void)
bool CDplusProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip) bool CDplusProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
{ {
bool newstream = false; bool newstream = false;
// find the stream // find the stream
CPacketStream *stream = GetStream(Header->GetStreamId()); CPacketStream *stream = GetStream(Header->GetStreamId());
if ( stream == NULL ) if ( stream == NULL )
{ {
// no stream open yet, open a new one // no stream open yet, open a new one
CCallsign via(Header->GetRpt1Callsign()); CCallsign via(Header->GetRpt1Callsign());
// first, check module is valid // first, check module is valid
if ( g_Reflector.IsValidModule(Header->GetRpt1Module()) ) if ( g_Reflector.IsValidModule(Header->GetRpt1Module()) )
{ {
@ -234,11 +235,11 @@ bool CDplusProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
} }
// release // release
g_Reflector.ReleaseClients(); g_Reflector.ReleaseClients();
// update last heard // update last heard
g_Reflector.GetUsers()->Hearing(Header->GetMyCallsign(), via, Header->GetRpt2Callsign()); g_Reflector.GetUsers()->Hearing(Header->GetMyCallsign(), via, Header->GetRpt2Callsign());
g_Reflector.ReleaseUsers(); g_Reflector.ReleaseUsers();
// delete header if needed // delete header if needed
if ( !newstream ) if ( !newstream )
{ {
@ -258,7 +259,7 @@ bool CDplusProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
// and delete packet // and delete packet
delete Header; delete Header;
} }
// done // done
return newstream; return newstream;
} }
@ -274,10 +275,10 @@ void CDplusProtocol::HandleQueue(void)
// get the packet // get the packet
CPacket *packet = m_Queue.front(); CPacket *packet = m_Queue.front();
m_Queue.pop(); m_Queue.pop();
// get our sender's id // get our sender's id
int iModId = g_Reflector.GetModuleIndex(packet->GetModuleId()); int iModId = g_Reflector.GetModuleIndex(packet->GetModuleId());
// check if it's header and update cache // check if it's header and update cache
if ( packet->IsDvHeader() ) if ( packet->IsDvHeader() )
{ {
@ -294,9 +295,9 @@ void CDplusProtocol::HandleQueue(void)
// note that for dplus protocol, all stream of all modules are push to all clients // note that for dplus protocol, all stream of all modules are push to all clients
// it's client who decide which stream he's interrrested in // it's client who decide which stream he's interrrested in
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
int index = -1; auto it = clients->begin();
CClient *client = NULL; CClient *client = NULL;
while ( (client = clients->FindNextClient(PROTOCOL_DPLUS, &index)) != NULL ) while ( (client = clients->FindNextClient(PROTOCOL_DPLUS, it)) != NULL )
{ {
// is this client busy ? // is this client busy ?
if ( !client->IsAMaster() ) if ( !client->IsAMaster() )
@ -332,8 +333,8 @@ void CDplusProtocol::HandleQueue(void)
} }
g_Reflector.ReleaseClients(); g_Reflector.ReleaseClients();
} }
// done // done
delete packet; delete packet;
} }
@ -368,13 +369,13 @@ void CDplusProtocol::SendDvHeader(CDvHeaderPacket *packet, CDplusClient *client)
// no, send also the genuine packet // no, send also the genuine packet
m_Socket.Send(buffer, client->GetIp()); m_Socket.Send(buffer, client->GetIp());
} }
} }
else else
{ {
// otherwise, send the original packet // otherwise, send the original packet
m_Socket.Send(buffer, client->GetIp()); m_Socket.Send(buffer, client->GetIp());
} }
} }
} }
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
@ -385,17 +386,17 @@ void CDplusProtocol::HandleKeepalives(void)
// send keepalives // send keepalives
CBuffer keepalive; CBuffer keepalive;
EncodeKeepAlivePacket(&keepalive); EncodeKeepAlivePacket(&keepalive);
// iterate on clients // iterate on clients
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
int index = -1; auto it = clients->begin();
CClient *client = NULL; CClient *client = NULL;
while ( (client = clients->FindNextClient(PROTOCOL_DPLUS, &index)) != NULL ) while ( (client = clients->FindNextClient(PROTOCOL_DPLUS, it)) != NULL )
{ {
// 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()); m_Socket.Send(keepalive, client->GetIp());
// is this client busy ? // is this client busy ?
if ( client->IsAMaster() ) if ( client->IsAMaster() )
{ {
@ -409,7 +410,7 @@ void CDplusProtocol::HandleKeepalives(void)
CBuffer disconnect; CBuffer disconnect;
EncodeDisconnectPacket(&disconnect); EncodeDisconnectPacket(&disconnect);
m_Socket.Send(disconnect, client->GetIp()); m_Socket.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;
clients->RemoveClient(client); clients->RemoveClient(client);
@ -431,7 +432,7 @@ bool CDplusProtocol::IsValidLoginPacket(const CBuffer &Buffer, CCallsign *Callsi
{ {
uint8 Tag[] = { 0x1C,0xC0,0x04,0x00 }; uint8 Tag[] = { 0x1C,0xC0,0x04,0x00 };
bool valid = false; bool valid = false;
if ( (Buffer.size() == 28) &&(::memcmp(Buffer.data(), Tag, sizeof(Tag)) == 0) ) if ( (Buffer.size() == 28) &&(::memcmp(Buffer.data(), Tag, sizeof(Tag)) == 0) )
{ {
Callsign->SetCallsign(&(Buffer.data()[4]), 8); Callsign->SetCallsign(&(Buffer.data()[4]), 8);
@ -455,7 +456,7 @@ bool CDplusProtocol::IsValidKeepAlivePacket(const CBuffer &Buffer)
CDvHeaderPacket *CDplusProtocol::IsValidDvHeaderPacket(const CBuffer &Buffer) CDvHeaderPacket *CDplusProtocol::IsValidDvHeaderPacket(const CBuffer &Buffer)
{ {
CDvHeaderPacket *header = NULL; CDvHeaderPacket *header = NULL;
if ( (Buffer.size() == 58) && if ( (Buffer.size() == 58) &&
(Buffer.data()[0] == 0x3A) && (Buffer.data()[1] == 0x80) && (Buffer.data()[0] == 0x3A) && (Buffer.data()[1] == 0x80) &&
(Buffer.Compare((uint8 *)"DSVT", 2, 4) == 0) && (Buffer.Compare((uint8 *)"DSVT", 2, 4) == 0) &&
@ -477,7 +478,7 @@ CDvHeaderPacket *CDplusProtocol::IsValidDvHeaderPacket(const CBuffer &Buffer)
CDvFramePacket *CDplusProtocol::IsValidDvFramePacket(const CBuffer &Buffer) CDvFramePacket *CDplusProtocol::IsValidDvFramePacket(const CBuffer &Buffer)
{ {
CDvFramePacket *dvframe = NULL; CDvFramePacket *dvframe = NULL;
if ( (Buffer.size() == 29) && if ( (Buffer.size() == 29) &&
(Buffer.data()[0] == 0x1D) && (Buffer.data()[1] == 0x80) && (Buffer.data()[0] == 0x1D) && (Buffer.data()[1] == 0x80) &&
(Buffer.Compare((uint8 *)"DSVT", 2, 4) == 0) && (Buffer.Compare((uint8 *)"DSVT", 2, 4) == 0) &&
@ -499,7 +500,7 @@ CDvFramePacket *CDplusProtocol::IsValidDvFramePacket(const CBuffer &Buffer)
CDvLastFramePacket *CDplusProtocol::IsValidDvLastFramePacket(const CBuffer &Buffer) CDvLastFramePacket *CDplusProtocol::IsValidDvLastFramePacket(const CBuffer &Buffer)
{ {
CDvLastFramePacket *dvframe = NULL; CDvLastFramePacket *dvframe = NULL;
if ( (Buffer.size() == 32) && if ( (Buffer.size() == 32) &&
(Buffer.Compare((uint8 *)"DSVT", 2, 4) == 0) && (Buffer.Compare((uint8 *)"DSVT", 2, 4) == 0) &&
(Buffer.data()[0] == 0x20) && (Buffer.data()[1] == 0x80) && (Buffer.data()[0] == 0x20) && (Buffer.data()[1] == 0x80) &&
@ -551,9 +552,9 @@ bool CDplusProtocol::EncodeDvHeaderPacket(const CDvHeaderPacket &Packet, CBuffer
{ {
uint8 tag[] = { 0x3A,0x80,0x44,0x53,0x56,0x54,0x10,0x00,0x00,0x00,0x20,0x00,0x01,0x02 }; uint8 tag[] = { 0x3A,0x80,0x44,0x53,0x56,0x54,0x10,0x00,0x00,0x00,0x20,0x00,0x01,0x02 };
struct dstar_header DstarHeader; struct dstar_header DstarHeader;
Packet.ConvertToDstarStruct(&DstarHeader); Packet.ConvertToDstarStruct(&DstarHeader);
Buffer->Set(tag, sizeof(tag)); Buffer->Set(tag, sizeof(tag));
Buffer->Append(Packet.GetStreamId()); Buffer->Append(Packet.GetStreamId());
Buffer->Append((uint8)0x80); Buffer->Append((uint8)0x80);
@ -571,9 +572,9 @@ bool CDplusProtocol::EncodeDvFramePacket(const CDvFramePacket &Packet, CBuffer *
Buffer->Append((uint8)(Packet.GetPacketId() % 21)); Buffer->Append((uint8)(Packet.GetPacketId() % 21));
Buffer->Append((uint8 *)Packet.GetAmbe(), AMBE_SIZE); Buffer->Append((uint8 *)Packet.GetAmbe(), AMBE_SIZE);
Buffer->Append((uint8 *)Packet.GetDvData(), DVDATA_SIZE); Buffer->Append((uint8 *)Packet.GetDvData(), DVDATA_SIZE);
return true; return true;
} }
bool CDplusProtocol::EncodeDvLastFramePacket(const CDvLastFramePacket &Packet, CBuffer *Buffer) const bool CDplusProtocol::EncodeDvLastFramePacket(const CDvLastFramePacket &Packet, CBuffer *Buffer) const
@ -585,6 +586,6 @@ bool CDplusProtocol::EncodeDvLastFramePacket(const CDvLastFramePacket &Packet, C
Buffer->Append(Packet.GetStreamId()); Buffer->Append(Packet.GetStreamId());
Buffer->Append((uint8)((Packet.GetPacketId() % 21) | 0x40)); Buffer->Append((uint8)((Packet.GetPacketId() % 21) | 0x40));
Buffer->Append(tag2, sizeof(tag2)); Buffer->Append(tag2, sizeof(tag2));
return true; return true;
} }

@ -4,6 +4,7 @@
// //
// Created by Marius Petrescu (YO2LOJ) on 03/06/2019. // Created by Marius Petrescu (YO2LOJ) on 03/06/2019.
// Copyright © 2019 Marius Petrescu (YO2LOJ). All rights reserved. // Copyright © 2019 Marius Petrescu (YO2LOJ). All rights reserved.
// Copyright © 2020 Thomas A. Early, N7TAE
// //
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// This file is part of xlxd. // This file is part of xlxd.
@ -19,7 +20,7 @@
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>. // along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#include "main.h" #include "main.h"
@ -167,7 +168,7 @@ void CG3Protocol::PresenceTask(void)
Owner.SetCallsign(&Buffer.data()[16], 8); Owner.SetCallsign(&Buffer.data()[16], 8);
Terminal.SetCallsign(&Buffer.data()[24], 8); Terminal.SetCallsign(&Buffer.data()[24], 8);
std::cout << "Presence from " << Ip << " as " << Callsign << " on terminal " << Terminal << std::endl; std::cout << "Presence from " << Ip << " as " << Callsign << " on terminal " << Terminal << std::endl;
// accept // accept
Buffer.data()[2] = 0x80; // response Buffer.data()[2] = 0x80; // response
@ -175,7 +176,7 @@ void CG3Protocol::PresenceTask(void)
if (m_GwAddress == 0) if (m_GwAddress == 0)
{ {
Buffer.Append(*(uint32 *)m_ConfigSocket.GetLocalAddr()); Buffer.Append(*(uint32 *)m_ConfigSocket.GetLocalAddr());
} }
else else
{ {
@ -183,10 +184,9 @@ void CG3Protocol::PresenceTask(void)
} }
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
auto it = clients->begin();
int index = -1;
CClient *extant = NULL; CClient *extant = NULL;
while ( (extant = clients->FindNextClient(PROTOCOL_G3, &index)) != NULL ) while ( (extant = clients->FindNextClient(PROTOCOL_G3, it)) != NULL )
{ {
CIp ClIp = extant->GetIp(); CIp ClIp = extant->GetIp();
if (ClIp.GetAddr() == Ip.GetAddr()) if (ClIp.GetAddr() == Ip.GetAddr())
@ -197,10 +197,10 @@ void CG3Protocol::PresenceTask(void)
if (extant == NULL) if (extant == NULL)
{ {
index = -1; it = clients->begin();
// do we already have a client with the same call (IP changed)? // do we already have a client with the same call (IP changed)?
while ( (extant = clients->FindNextClient(PROTOCOL_G3, &index)) != NULL ) while ( (extant = clients->FindNextClient(PROTOCOL_G3, it)) != NULL )
{ {
{ {
if (extant->GetCallsign().HasSameCallsign(Terminal)) if (extant->GetCallsign().HasSameCallsign(Terminal))
@ -328,7 +328,7 @@ void CG3Protocol::ConfigTask(void)
if (m_GwAddress == 0) if (m_GwAddress == 0)
{ {
Buffer.Append(*(uint32 *)m_ConfigSocket.GetLocalAddr()); Buffer.Append(*(uint32 *)m_ConfigSocket.GetLocalAddr());
} }
else else
{ {
@ -359,10 +359,9 @@ void CG3Protocol::IcmpTask(void)
if (iIcmpType == ICMP_DEST_UNREACH) if (iIcmpType == ICMP_DEST_UNREACH)
{ {
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
auto it = clients->begin();
int index = -1;
CClient *client = NULL; CClient *client = NULL;
while ( (client = clients->FindNextClient(PROTOCOL_G3, &index)) != NULL ) while ( (client = clients->FindNextClient(PROTOCOL_G3, it)) != NULL )
{ {
CIp ClientIp = client->GetIp(); CIp ClientIp = client->GetIp();
if (ClientIp.GetAddr() == Ip.GetAddr()) if (ClientIp.GetAddr() == Ip.GetAddr())
@ -396,9 +395,9 @@ void CG3Protocol::Task(void)
CIp ClIp; CIp ClIp;
CIp *BaseIp = NULL; CIp *BaseIp = NULL;
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
int index = -1; auto it = clients->begin();
CClient *client = NULL; CClient *client = NULL;
while ( (client = clients->FindNextClient(PROTOCOL_G3, &index)) != NULL ) while ( (client = clients->FindNextClient(PROTOCOL_G3, it)) != NULL )
{ {
ClIp = client->GetIp(); ClIp = client->GetIp();
if (ClIp.GetAddr() == Ip.GetAddr()) if (ClIp.GetAddr() == Ip.GetAddr())
@ -491,16 +490,16 @@ void CG3Protocol::HandleQueue(void)
// get the packet // get the packet
CPacket *packet = m_Queue.front(); CPacket *packet = m_Queue.front();
m_Queue.pop(); m_Queue.pop();
// encode it // encode it
CBuffer buffer; CBuffer buffer;
if ( EncodeDvPacket(*packet, &buffer) ) if ( EncodeDvPacket(*packet, &buffer) )
{ {
// and push it to all our clients linked to the module and who are not streaming in // and push it to all our clients linked to the module and who are not streaming in
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
int index = -1; auto it = clients->begin();
CClient *client = NULL; CClient *client = NULL;
while ( (client = clients->FindNextClient(PROTOCOL_G3, &index)) != NULL ) while ( (client = clients->FindNextClient(PROTOCOL_G3, it)) != NULL )
{ {
// is this client busy ? // is this client busy ?
if ( !client->IsAMaster() && (client->GetReflectorModule() == packet->GetModuleId()) ) if ( !client->IsAMaster() && (client->GetReflectorModule() == packet->GetModuleId()) )
@ -515,7 +514,7 @@ void CG3Protocol::HandleQueue(void)
} }
g_Reflector.ReleaseClients(); g_Reflector.ReleaseClients();
} }
// done // done
delete packet; delete packet;
} }
@ -534,9 +533,9 @@ void CG3Protocol::HandleKeepalives(void)
// iterate on clients // iterate on clients
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
int index = -1; auto it = clients->begin();
CClient *client = NULL; CClient *client = NULL;
while ( (client = clients->FindNextClient(PROTOCOL_G3, &index)) != NULL ) while ( (client = clients->FindNextClient(PROTOCOL_G3, it)) != NULL )
{ {
if (!client->IsAlive()) if (!client->IsAlive())
{ {
@ -568,10 +567,9 @@ bool CG3Protocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
// find this client // find this client
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
auto it = clients->begin();
int index = -1;
CClient *client = NULL; CClient *client = NULL;
while ( (client = clients->FindNextClient(PROTOCOL_G3, &index)) != NULL ) while ( (client = clients->FindNextClient(PROTOCOL_G3, it)) != NULL )
{ {
CIp ClIp = client->GetIp(); CIp ClIp = client->GetIp();
if (ClIp.GetAddr() == Ip.GetAddr()) if (ClIp.GetAddr() == Ip.GetAddr())
@ -653,7 +651,7 @@ bool CG3Protocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
CDvHeaderPacket *CG3Protocol::IsValidDvHeaderPacket(const CBuffer &Buffer) CDvHeaderPacket *CG3Protocol::IsValidDvHeaderPacket(const CBuffer &Buffer)
{ {
CDvHeaderPacket *header = NULL; CDvHeaderPacket *header = NULL;
if ( (Buffer.size() == 56) && (Buffer.Compare((uint8 *)"DSVT", 4) == 0) && if ( (Buffer.size() == 56) && (Buffer.Compare((uint8 *)"DSVT", 4) == 0) &&
(Buffer.data()[4] == 0x10) && (Buffer.data()[8] == 0x20) ) (Buffer.data()[4] == 0x10) && (Buffer.data()[8] == 0x20) )
{ {
@ -673,7 +671,7 @@ CDvHeaderPacket *CG3Protocol::IsValidDvHeaderPacket(const CBuffer &Buffer)
CDvFramePacket *CG3Protocol::IsValidDvFramePacket(const CBuffer &Buffer) CDvFramePacket *CG3Protocol::IsValidDvFramePacket(const CBuffer &Buffer)
{ {
CDvFramePacket *dvframe = NULL; CDvFramePacket *dvframe = NULL;
if ( (Buffer.size() == 27) && (Buffer.Compare((uint8 *)"DSVT", 4) == 0) && if ( (Buffer.size() == 27) && (Buffer.Compare((uint8 *)"DSVT", 4) == 0) &&
(Buffer.data()[4] == 0x20) && (Buffer.data()[8] == 0x20) && (Buffer.data()[4] == 0x20) && (Buffer.data()[8] == 0x20) &&
((Buffer.data()[14] & 0x40) == 0) ) ((Buffer.data()[14] & 0x40) == 0) )
@ -694,7 +692,7 @@ CDvFramePacket *CG3Protocol::IsValidDvFramePacket(const CBuffer &Buffer)
CDvLastFramePacket *CG3Protocol::IsValidDvLastFramePacket(const CBuffer &Buffer) CDvLastFramePacket *CG3Protocol::IsValidDvLastFramePacket(const CBuffer &Buffer)
{ {
CDvLastFramePacket *dvframe = NULL; CDvLastFramePacket *dvframe = NULL;
if ( (Buffer.size() == 27) && (Buffer.Compare((uint8 *)"DSVT", 4) == 0) && if ( (Buffer.size() == 27) && (Buffer.Compare((uint8 *)"DSVT", 4) == 0) &&
(Buffer.data()[4] == 0x20) && (Buffer.data()[8] == 0x20) && (Buffer.data()[4] == 0x20) && (Buffer.data()[8] == 0x20) &&
((Buffer.data()[14] & 0x40) != 0) ) ((Buffer.data()[14] & 0x40) != 0) )
@ -719,41 +717,41 @@ bool CG3Protocol::EncodeDvHeaderPacket(const CDvHeaderPacket &Packet, CBuffer *B
{ {
uint8 tag[] = { 'D','S','V','T',0x10,0x00,0x00,0x00,0x20,0x00,0x01,0x02 }; uint8 tag[] = { 'D','S','V','T',0x10,0x00,0x00,0x00,0x20,0x00,0x01,0x02 };
struct dstar_header DstarHeader; struct dstar_header DstarHeader;
Packet.ConvertToDstarStruct(&DstarHeader); Packet.ConvertToDstarStruct(&DstarHeader);
Buffer->Set(tag, sizeof(tag)); Buffer->Set(tag, sizeof(tag));
Buffer->Append(Packet.GetStreamId()); Buffer->Append(Packet.GetStreamId());
Buffer->Append((uint8)0x80); Buffer->Append((uint8)0x80);
Buffer->Append((uint8 *)&DstarHeader, sizeof(struct dstar_header)); Buffer->Append((uint8 *)&DstarHeader, sizeof(struct dstar_header));
return true; return true;
} }
bool CG3Protocol::EncodeDvFramePacket(const CDvFramePacket &Packet, CBuffer *Buffer) const bool CG3Protocol::EncodeDvFramePacket(const CDvFramePacket &Packet, CBuffer *Buffer) const
{ {
uint8 tag[] = { 'D','S','V','T',0x20,0x00,0x00,0x00,0x20,0x00,0x01,0x02 }; uint8 tag[] = { 'D','S','V','T',0x20,0x00,0x00,0x00,0x20,0x00,0x01,0x02 };
Buffer->Set(tag, sizeof(tag)); Buffer->Set(tag, sizeof(tag));
Buffer->Append(Packet.GetStreamId()); Buffer->Append(Packet.GetStreamId());
Buffer->Append((uint8)(Packet.GetPacketId() % 21)); Buffer->Append((uint8)(Packet.GetPacketId() % 21));
Buffer->Append((uint8 *)Packet.GetAmbe(), AMBE_SIZE); Buffer->Append((uint8 *)Packet.GetAmbe(), AMBE_SIZE);
Buffer->Append((uint8 *)Packet.GetDvData(), DVDATA_SIZE); Buffer->Append((uint8 *)Packet.GetDvData(), DVDATA_SIZE);
return true; return true;
} }
bool CG3Protocol::EncodeDvLastFramePacket(const CDvLastFramePacket &Packet, CBuffer *Buffer) const bool CG3Protocol::EncodeDvLastFramePacket(const CDvLastFramePacket &Packet, CBuffer *Buffer) const
{ {
uint8 tag1[] = { 'D','S','V','T',0x20,0x00,0x00,0x00,0x20,0x00,0x01,0x02 }; uint8 tag1[] = { 'D','S','V','T',0x20,0x00,0x00,0x00,0x20,0x00,0x01,0x02 };
uint8 tag2[] = { 0x55,0xC8,0x7A,0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x1A,0xC6 }; uint8 tag2[] = { 0x55,0xC8,0x7A,0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x1A,0xC6 };
Buffer->Set(tag1, sizeof(tag1)); Buffer->Set(tag1, sizeof(tag1));
Buffer->Append(Packet.GetStreamId()); Buffer->Append(Packet.GetStreamId());
Buffer->Append((uint8)((Packet.GetPacketId() % 21) | 0x40)); Buffer->Append((uint8)((Packet.GetPacketId() % 21) | 0x40));
Buffer->Append(tag2, sizeof(tag2)); Buffer->Append(tag2, sizeof(tag2));
return true; return true;
} }
@ -785,9 +783,9 @@ void CG3Protocol::NeedReload(void)
// we have new options - iterate on clients for potential removal // we have new options - iterate on clients for potential removal
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
int index = -1; auto it = clients->begin();
CClient *client = NULL; CClient *client = NULL;
while ( (client = clients->FindNextClient(PROTOCOL_G3, &index)) != NULL ) while ( (client = clients->FindNextClient(PROTOCOL_G3, it)) != NULL )
{ {
char module = client->GetReflectorModule(); char module = client->GetReflectorModule();
if (!strchr(m_Modules.c_str(), module) && !strchr(m_Modules.c_str(), '*')) if (!strchr(m_Modules.c_str(), module) && !strchr(m_Modules.c_str(), '*'))
@ -858,4 +856,3 @@ void CG3Protocol::ReadOptions(void)
} }
} }
} }

@ -103,19 +103,19 @@ bool CReflector::Start(void)
// init gate keeper // init gate keeper
ok &= g_GateKeeper.Init(); ok &= g_GateKeeper.Init();
// init dmrid directory // init dmrid directory
g_DmridDir.Init(); g_DmridDir.Init();
// init wiresx node directory // init wiresx node directory
g_YsfNodeDir.Init(); g_YsfNodeDir.Init();
// init the transcoder // init the transcoder
g_Transcoder.Init(); g_Transcoder.Init();
// create protocols // create protocols
ok &= m_Protocols.Init(); ok &= m_Protocols.Init();
// if ok, start threads // if ok, start threads
if ( ok ) if ( ok )
{ {
@ -135,7 +135,7 @@ bool CReflector::Start(void)
{ {
m_Protocols.Close(); m_Protocols.Close();
} }
// done // done
return ok; return ok;
} }
@ -175,10 +175,10 @@ void CReflector::Stop(void)
// close transcoder // close transcoder
g_Transcoder.Close(); g_Transcoder.Close();
// close gatekeeper // close gatekeeper
g_GateKeeper.Close(); g_GateKeeper.Close();
// close databases // close databases
g_DmridDir.Close(); g_DmridDir.Close();
g_YsfNodeDir.Close(); g_YsfNodeDir.Close();
@ -196,10 +196,10 @@ bool CReflector::IsStreaming(char module)
CPacketStream *CReflector::OpenStream(CDvHeaderPacket *DvHeader, CClient *client) CPacketStream *CReflector::OpenStream(CDvHeaderPacket *DvHeader, CClient *client)
{ {
CPacketStream *retStream = NULL; CPacketStream *retStream = NULL;
// clients MUST have bee locked by the caller // clients MUST have bee locked by the caller
// so we can freely access it within the fuction // so we can freely access it within the fuction
// check sid is not NULL // check sid is not NULL
if ( DvHeader->GetStreamId() != 0 ) if ( DvHeader->GetStreamId() != 0 )
{ {
@ -223,21 +223,21 @@ CPacketStream *CReflector::OpenStream(CDvHeaderPacket *DvHeader, CClient *client
// stream open, mark client as master // stream open, mark client as master
// so that it can't be deleted // so that it can't be deleted
client->SetMasterOfModule(module); client->SetMasterOfModule(module);
// update last heard time // update last heard time
client->Heard(); client->Heard();
retStream = stream; retStream = stream;
// and push header packet // and push header packet
stream->Push(DvHeader); stream->Push(DvHeader);
// report // report
std::cout << "Opening stream on module " << module << " for client " << client->GetCallsign() std::cout << "Opening stream on module " << module << " for client " << client->GetCallsign()
<< " with sid " << DvHeader->GetStreamId() << std::endl; << " with sid " << DvHeader->GetStreamId() << std::endl;
// notify // notify
g_Reflector.OnStreamOpen(stream->GetUserCallsign()); g_Reflector.OnStreamOpen(stream->GetUserCallsign());
} }
// unlock now // unlock now
stream->Unlock(); stream->Unlock();
@ -251,7 +251,7 @@ CPacketStream *CReflector::OpenStream(CDvHeaderPacket *DvHeader, CClient *client
} }
} }
} }
// done // done
return retStream; return retStream;
} }
@ -278,10 +278,10 @@ void CReflector::CloseStream(CPacketStream *stream)
CTimePoint::TaskSleepFor(10); CTimePoint::TaskSleepFor(10);
} }
} while (!bEmpty); } while (!bEmpty);
// lock clients // lock clients
GetClients(); GetClients();
// lock stream // lock stream
stream->Lock(); stream->Lock();
@ -300,12 +300,12 @@ void CReflector::CloseStream(CPacketStream *stream)
// release clients // release clients
ReleaseClients(); ReleaseClients();
// unlock before closing // unlock before closing
// to avoid double lock in assiociated // to avoid double lock in assiociated
// codecstream close/thread-join // codecstream close/thread-join
stream->Unlock(); stream->Unlock();
// and stop the queue // and stop the queue
stream->Close(); stream->Close();
@ -509,7 +509,7 @@ void CReflector::JsonReportThread(CReflector *This)
void CReflector::OnPeersChanged(void) void CReflector::OnPeersChanged(void)
{ {
CNotification notification(NOTIFICATION_PEERS); CNotification notification(NOTIFICATION_PEERS);
m_Notifications.Lock(); m_Notifications.Lock();
m_Notifications.push(notification); m_Notifications.push(notification);
m_Notifications.Unlock(); m_Notifications.Unlock();
@ -606,12 +606,12 @@ void CReflector::WriteXmlFile(std::ofstream &xmlFile)
{ {
// write header // write header
xmlFile << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl; xmlFile << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
// software version // software version
char sz[64]; char sz[64];
::sprintf(sz, "%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION); ::sprintf(sz, "%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION);
xmlFile << "<Version>" << sz << "</Version>" << std::endl; xmlFile << "<Version>" << sz << "</Version>" << std::endl;
// linked peers // linked peers
xmlFile << "<" << m_Callsign << "linked peers>" << std::endl; xmlFile << "<" << m_Callsign << "linked peers>" << std::endl;
// lock // lock
@ -624,23 +624,23 @@ void CReflector::WriteXmlFile(std::ofstream &xmlFile)
// unlock // unlock
ReleasePeers(); ReleasePeers();
xmlFile << "</" << m_Callsign << "linked peers>" << std::endl; xmlFile << "</" << m_Callsign << "linked peers>" << std::endl;
// linked nodes // linked nodes
xmlFile << "<" << m_Callsign << "linked nodes>" << std::endl; xmlFile << "<" << m_Callsign << "linked nodes>" << std::endl;
// lock // lock
CClients *clients = GetClients(); CClients *clients = GetClients();
// iterate on clients // iterate on clients
for ( int i = 0; i < clients->GetSize(); i++ ) for ( auto it=clients->cbegin(); it!=clients->cend(); it++ )
{ {
if ( clients->GetClient(i)->IsNode() ) if ( (*it)->IsNode() )
{ {
clients->GetClient(i)->WriteXml(xmlFile); (*it)->WriteXml(xmlFile);
} }
} }
// unlock // unlock
ReleaseClients(); ReleaseClients();
xmlFile << "</" << m_Callsign << "linked nodes>" << std::endl; xmlFile << "</" << m_Callsign << "linked nodes>" << std::endl;
// last heard users // last heard users
xmlFile << "<" << m_Callsign << "heard users>" << std::endl; xmlFile << "<" << m_Callsign << "heard users>" << std::endl;
// lock // lock
@ -696,10 +696,10 @@ void CReflector::SendJsonNodesObject(CUdpSocket &Socket, CIp &Ip)
// lock // lock
CClients *clients = GetClients(); CClients *clients = GetClients();
// iterate on clients // iterate on clients
for ( int i = 0; (i < clients->GetSize()) && (i < JSON_NBMAX_NODES); i++ ) for ( auto it=clients->cbegin(); it!=clients->cend(); )
{ {
clients->GetClient(i)->GetJsonObject(Buffer); (*it++)->GetJsonObject(Buffer);
if ( i < clients->GetSize()-1 ) if ( it != clients->cend() )
{ {
::strcat(Buffer, ","); ::strcat(Buffer, ",");
} }

@ -271,9 +271,9 @@ void CXlxProtocol::HandleQueue(void)
// and push it to all our clients linked to the module and who are not streaming in // and push it to all our clients linked to the module and who are not streaming in
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
int index = -1; auto it = clients->begin();
CClient *client = NULL; CClient *client = NULL;
while ( (client = clients->FindNextClient(PROTOCOL_XLX, &index)) != NULL ) while ( (client = clients->FindNextClient(PROTOCOL_XLX, it)) != NULL )
{ {
// is this client busy ? // is this client busy ?
if ( !client->IsAMaster() && (client->GetReflectorModule() == packet->GetModuleId()) ) if ( !client->IsAMaster() && (client->GetReflectorModule() == packet->GetModuleId()) )

@ -4,6 +4,7 @@
// //
// Created by Jean-Luc Deltombe (LX3JL) on 20/05/2018. // Created by Jean-Luc Deltombe (LX3JL) on 20/05/2018.
// 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.
@ -47,26 +48,26 @@ CYsfProtocol::CYsfProtocol()
bool CYsfProtocol::Init(void) bool CYsfProtocol::Init(void)
{ {
bool ok; bool ok;
// base class // base class
ok = CProtocol::Init(); ok = CProtocol::Init();
// update the reflector callsign // update the reflector callsign
m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"YSF", 3); m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"YSF", 3);
// create our socket // create our socket
ok &= m_Socket.Open(YSF_PORT); ok &= m_Socket.Open(YSF_PORT);
if ( !ok ) if ( !ok )
{ {
std::cout << "Error opening socket on port UDP" << YSF_PORT << " on ip " << g_Reflector.GetListenIp() << std::endl; 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(); ok &= m_WiresxCmdHandler.Init();
// update time // update time
m_LastKeepaliveTime.Now(); m_LastKeepaliveTime.Now();
// done // done
return ok; return ok;
} }
@ -75,7 +76,7 @@ void CYsfProtocol::Close(void)
{ {
// base class // base class
CProtocol::Close(); CProtocol::Close();
// and close wiresx handler // and close wiresx handler
m_WiresxCmdHandler.Close(); m_WiresxCmdHandler.Close();
} }
@ -92,7 +93,7 @@ void CYsfProtocol::Task(void)
CDvHeaderPacket *Header; CDvHeaderPacket *Header;
CDvFramePacket *Frames[5]; CDvFramePacket *Frames[5];
CWiresxCmd WiresxCmd; CWiresxCmd WiresxCmd;
int iWiresxCmd; int iWiresxCmd;
int iWiresxArg; int iWiresxArg;
@ -108,7 +109,7 @@ void CYsfProtocol::Task(void)
} }
m_WiresxCmdHandler.ReleasePacketQueue(); m_WiresxCmdHandler.ReleasePacketQueue();
} }
// handle incoming packets // handle incoming packets
if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 ) if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 )
{ {
@ -119,7 +120,7 @@ void CYsfProtocol::Task(void)
if ( IsValidDvFramePacket(Ip, Fich, Buffer, Frames) ) if ( IsValidDvFramePacket(Ip, Fich, Buffer, Frames) )
{ {
//std::cout << "YSF DV frame" << std::endl; //std::cout << "YSF DV frame" << std::endl;
// handle it // handle it
OnDvFramePacketIn(Frames[0], &Ip); OnDvFramePacketIn(Frames[0], &Ip);
OnDvFramePacketIn(Frames[1], &Ip); OnDvFramePacketIn(Frames[1], &Ip);
@ -131,7 +132,7 @@ void CYsfProtocol::Task(void)
{ {
//std::cout << "YSF DV header:" << std::endl << *Header << std::endl; //std::cout << "YSF DV header:" << std::endl << *Header << std::endl;
//std::cout << "YSF DV header:" << std::endl; //std::cout << "YSF DV header:" << std::endl;
// node linked and callsign muted? // node linked and callsign muted?
if ( g_GateKeeper.MayTransmit(Header->GetMyCallsign(), Ip, PROTOCOL_YSF, Header->GetRpt2Module()) ) if ( g_GateKeeper.MayTransmit(Header->GetMyCallsign(), Ip, PROTOCOL_YSF, Header->GetRpt2Module()) )
{ {
@ -157,14 +158,14 @@ void CYsfProtocol::Task(void)
else if ( IsValidConnectPacket(Buffer, &Callsign) ) else if ( IsValidConnectPacket(Buffer, &Callsign) )
{ {
//std::cout << "YSF keepalive/connect packet from " << Callsign << " at " << Ip << std::endl; //std::cout << "YSF keepalive/connect packet from " << Callsign << " at " << Ip << std::endl;
// callsign authorized? // callsign authorized?
if ( g_GateKeeper.MayLink(Callsign, Ip, PROTOCOL_YSF) ) if ( g_GateKeeper.MayLink(Callsign, Ip, PROTOCOL_YSF) )
{ {
// acknowledge the request // acknowledge the request
EncodeConnectAckPacket(&Buffer); EncodeConnectAckPacket(&Buffer);
m_Socket.Send(Buffer, Ip); m_Socket.Send(Buffer, Ip);
// add client if needed // add client if needed
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
CClient *client = clients->FindClient(Callsign, Ip, PROTOCOL_YSF); CClient *client = clients->FindClient(Callsign, Ip, PROTOCOL_YSF);
@ -172,15 +173,15 @@ void CYsfProtocol::Task(void)
if ( client == NULL ) if ( client == NULL )
{ {
std::cout << "YSF connect packet from " << Callsign << " at " << Ip << std::endl; std::cout << "YSF connect packet from " << Callsign << " at " << Ip << std::endl;
// create the client // create the client
CYsfClient *newclient = new CYsfClient(Callsign, Ip); CYsfClient *newclient = new CYsfClient(Callsign, Ip);
// aautolink, if enabled // aautolink, if enabled
#if YSF_AUTOLINK_ENABLE #if YSF_AUTOLINK_ENABLE
newclient->SetReflectorModule(YSF_AUTOLINK_MODULE); newclient->SetReflectorModule(YSF_AUTOLINK_MODULE);
#endif #endif
// and append // and append
clients->AddClient(newclient); clients->AddClient(newclient);
} }
@ -215,19 +216,19 @@ void CYsfProtocol::Task(void)
//Buffer.DebugDump(g_Reflector.m_DebugFile); //Buffer.DebugDump(g_Reflector.m_DebugFile);
} }
} }
// handle end of streaming timeout // handle end of streaming timeout
CheckStreamsTimeout(); CheckStreamsTimeout();
// handle queue from reflector // handle queue from reflector
HandleQueue(); HandleQueue();
// keep client alive // keep client alive
if ( m_LastKeepaliveTime.DurationSinceNow() > YSF_KEEPALIVE_PERIOD ) if ( m_LastKeepaliveTime.DurationSinceNow() > YSF_KEEPALIVE_PERIOD )
{ {
// //
HandleKeepalives(); HandleKeepalives();
// update time // update time
m_LastKeepaliveTime.Now(); m_LastKeepaliveTime.Now();
} }
@ -239,14 +240,14 @@ void CYsfProtocol::Task(void)
bool CYsfProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip) bool CYsfProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
{ {
bool newstream = false; bool newstream = false;
// find the stream // find the stream
CPacketStream *stream = GetStream(Header->GetStreamId()); CPacketStream *stream = GetStream(Header->GetStreamId());
if ( stream == NULL ) if ( stream == NULL )
{ {
// no stream open yet, open a new one // no stream open yet, open a new one
CCallsign via(Header->GetRpt1Callsign()); CCallsign via(Header->GetRpt1Callsign());
// find this client // find this client
CClient *client = g_Reflector.GetClients()->FindClient(Ip, PROTOCOL_YSF); CClient *client = g_Reflector.GetClients()->FindClient(Ip, PROTOCOL_YSF);
if ( client != NULL ) if ( client != NULL )
@ -266,14 +267,14 @@ bool CYsfProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
} }
// release // release
g_Reflector.ReleaseClients(); g_Reflector.ReleaseClients();
// update last heard // update last heard
if ( g_Reflector.IsValidModule(Header->GetRpt2Module()) ) if ( g_Reflector.IsValidModule(Header->GetRpt2Module()) )
{ {
g_Reflector.GetUsers()->Hearing(Header->GetMyCallsign(), via, Header->GetRpt2Callsign()); g_Reflector.GetUsers()->Hearing(Header->GetMyCallsign(), via, Header->GetRpt2Callsign());
g_Reflector.ReleaseUsers(); g_Reflector.ReleaseUsers();
} }
// delete header if needed // delete header if needed
if ( !newstream ) if ( !newstream )
{ {
@ -288,7 +289,7 @@ bool CYsfProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
// and delete packet // and delete packet
delete Header; delete Header;
} }
// done // done
return newstream; return newstream;
} }
@ -298,27 +299,27 @@ bool CYsfProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
void CYsfProtocol::HandleQueue(void) void CYsfProtocol::HandleQueue(void)
{ {
m_Queue.Lock(); m_Queue.Lock();
while ( !m_Queue.empty() ) while ( !m_Queue.empty() )
{ {
// get the packet // get the packet
CPacket *packet = m_Queue.front(); CPacket *packet = m_Queue.front();
m_Queue.pop(); m_Queue.pop();
// get our sender's id // get our sender's id
int iModId = g_Reflector.GetModuleIndex(packet->GetModuleId()); int iModId = g_Reflector.GetModuleIndex(packet->GetModuleId());
// encode // encode
CBuffer buffer; CBuffer buffer;
// check if it's header // check if it's header
if ( packet->IsDvHeader() ) if ( packet->IsDvHeader() )
{ {
// update local stream cache // update local stream cache
// this relies on queue feeder setting valid module id // this relies on queue feeder setting valid module id
m_StreamsCache[iModId].m_dvHeader = CDvHeaderPacket((const CDvHeaderPacket &)*packet); m_StreamsCache[iModId].m_dvHeader = CDvHeaderPacket((const CDvHeaderPacket &)*packet);
// encode it // encode it
EncodeDvHeaderPacket((const CDvHeaderPacket &)*packet, &buffer); EncodeDvHeaderPacket((const CDvHeaderPacket &)*packet, &buffer);
} }
@ -339,32 +340,32 @@ void CYsfProtocol::HandleQueue(void)
m_StreamsCache[iModId].m_dvFrames[sid] = CDvFramePacket((const CDvFramePacket &)*packet); m_StreamsCache[iModId].m_dvFrames[sid] = CDvFramePacket((const CDvFramePacket &)*packet);
if ( sid == 4 ) if ( sid == 4 )
{ {
EncodeDvPacket(m_StreamsCache[iModId].m_dvHeader, m_StreamsCache[iModId].m_dvFrames, &buffer); EncodeDvPacket(m_StreamsCache[iModId].m_dvHeader, m_StreamsCache[iModId].m_dvFrames, &buffer);
} }
} }
} }
// send it // send it
if ( buffer.size() > 0 ) if ( buffer.size() > 0 )
{ {
// and push it to all our clients linked to the module and who are not streaming in // and push it to all our clients linked to the module and who are not streaming in
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
int index = -1; auto it = clients->begin();
CClient *client = NULL; CClient *client = NULL;
while ( (client = clients->FindNextClient(PROTOCOL_YSF, &index)) != NULL ) while ( (client = clients->FindNextClient(PROTOCOL_YSF, it)) != NULL )
{ {
// is this client busy ? // is this client busy ?
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()); m_Socket.Send(buffer, client->GetIp());
} }
} }
g_Reflector.ReleaseClients(); g_Reflector.ReleaseClients();
} }
// done // done
delete packet; delete packet;
} }
@ -379,12 +380,12 @@ void CYsfProtocol::HandleKeepalives(void)
// YSF protocol keepalive request is client tasks // YSF protocol keepalive request is client tasks
// here, just check that all clients are still alive // here, just check that all clients are still alive
// and disconnect them if not // and disconnect them if not
// iterate on clients // iterate on clients
CClients *clients = g_Reflector.GetClients(); CClients *clients = g_Reflector.GetClients();
int index = -1; auto it = clients->begin();
CClient *client = NULL; CClient *client = NULL;
while ( (client = clients->FindNextClient(PROTOCOL_YSF, &index)) != NULL ) while ( (client = clients->FindNextClient(PROTOCOL_YSF, it)) != NULL )
{ {
// is this client busy ? // is this client busy ?
if ( client->IsAMaster() ) if ( client->IsAMaster() )
@ -399,7 +400,7 @@ void CYsfProtocol::HandleKeepalives(void)
std::cout << "YSF client " << client->GetCallsign() << " keepalive timeout" << std::endl; std::cout << "YSF client " << client->GetCallsign() << " keepalive timeout" << std::endl;
clients->RemoveClient(client); clients->RemoveClient(client);
} }
} }
g_Reflector.ReleaseClients(); g_Reflector.ReleaseClients();
} }
@ -424,7 +425,7 @@ bool CYsfProtocol::IsValidConnectPacket(const CBuffer &Buffer, CCallsign *callsi
bool CYsfProtocol::IsValidDvPacket(const CBuffer &Buffer, CYSFFICH *Fich) bool CYsfProtocol::IsValidDvPacket(const CBuffer &Buffer, CYSFFICH *Fich)
{ {
uint8 tag[] = { 'Y','S','F','D' }; uint8 tag[] = { 'Y','S','F','D' };
bool valid = false; bool valid = false;
if ( (Buffer.size() == 155) && (Buffer.Compare(tag, sizeof(tag)) == 0) ) if ( (Buffer.size() == 155) && (Buffer.Compare(tag, sizeof(tag)) == 0) )
@ -451,7 +452,7 @@ bool CYsfProtocol::IsValidDvHeaderPacket(const CIp &Ip, const CYSFFICH &Fich, co
{ {
// get stream id // get stream id
uint32 uiStreamId = IpToStreamId(Ip); uint32 uiStreamId = IpToStreamId(Ip);
// get header data // get header data
CYSFPayload ysfPayload; CYSFPayload ysfPayload;
if ( ysfPayload.processHeaderData((unsigned char *)&(Buffer.data()[35])) ) if ( ysfPayload.processHeaderData((unsigned char *)&(Buffer.data()[35])) )
@ -470,7 +471,7 @@ bool CYsfProtocol::IsValidDvHeaderPacket(const CIp &Ip, const CYSFFICH &Fich, co
// destid, set module to none and rely on OnDvHeaderPacketIn() // destid, set module to none and rely on OnDvHeaderPacketIn()
// to later fill it with proper value // to later fill it with proper value
rpt2.SetModule(' '); rpt2.SetModule(' ');
// and packet // and packet
*header = new CDvHeaderPacket(csMY, CCallsign("CQCQCQ"), rpt1, rpt2, uiStreamId, Fich.getFN()); *header = new CDvHeaderPacket(csMY, CCallsign("CQCQCQ"), rpt1, rpt2, uiStreamId, Fich.getFN());
} }
@ -481,7 +482,7 @@ bool CYsfProtocol::IsValidDvHeaderPacket(const CIp &Ip, const CYSFFICH &Fich, co
frames[0] = new CDvFramePacket(uiAmbe, uiStreamId, Fich.getFN(), 0, 0); frames[0] = new CDvFramePacket(uiAmbe, uiStreamId, Fich.getFN(), 0, 0);
frames[1] = new CDvFramePacket(uiAmbe, uiStreamId, Fich.getFN(), 1, 0); frames[1] = new CDvFramePacket(uiAmbe, uiStreamId, Fich.getFN(), 1, 0);
} }
// check validity of packets // check validity of packets
if ( ((*header) == NULL) || !(*header)->IsValid() || if ( ((*header) == NULL) || !(*header)->IsValid() ||
(frames[0] == NULL) || !(frames[0]->IsValid()) || (frames[0] == NULL) || !(frames[0]->IsValid()) ||
@ -501,7 +502,7 @@ bool CYsfProtocol::IsValidDvHeaderPacket(const CIp &Ip, const CYSFFICH &Fich, co
} }
} }
// done // done
return valid; return valid;
} }
@ -514,13 +515,13 @@ bool CYsfProtocol::IsValidDvFramePacket(const CIp &Ip, const CYSFFICH &Fich, con
frames[2] = NULL; frames[2] = NULL;
frames[3] = NULL; frames[3] = NULL;
frames[4] = NULL; frames[4] = NULL;
// is it DV frame ? // is it DV frame ?
if ( Fich.getFI() == YSF_FI_COMMUNICATIONS ) if ( Fich.getFI() == YSF_FI_COMMUNICATIONS )
{ {
// get stream id // get stream id
uint32 uiStreamId = IpToStreamId(Ip); uint32 uiStreamId = IpToStreamId(Ip);
// get DV frames // get DV frames
uint8 ambe0[AMBEPLUS_SIZE]; uint8 ambe0[AMBEPLUS_SIZE];
uint8 ambe1[AMBEPLUS_SIZE]; uint8 ambe1[AMBEPLUS_SIZE];
@ -537,7 +538,7 @@ bool CYsfProtocol::IsValidDvFramePacket(const CIp &Ip, const CYSFFICH &Fich, con
frames[2] = new CDvFramePacket(ambe2, uiStreamId, Fich.getFN(), 2, fid); frames[2] = new CDvFramePacket(ambe2, uiStreamId, Fich.getFN(), 2, fid);
frames[3] = new CDvFramePacket(ambe3, uiStreamId, Fich.getFN(), 3, fid); frames[3] = new CDvFramePacket(ambe3, uiStreamId, Fich.getFN(), 3, fid);
frames[4] = new CDvFramePacket(ambe4, uiStreamId, Fich.getFN(), 4, fid); frames[4] = new CDvFramePacket(ambe4, uiStreamId, Fich.getFN(), 4, fid);
// check validity of packets // check validity of packets
if ( (frames[0] == NULL) || !(frames[0]->IsValid()) || if ( (frames[0] == NULL) || !(frames[0]->IsValid()) ||
(frames[1] == NULL) || !(frames[1]->IsValid()) || (frames[1] == NULL) || !(frames[1]->IsValid()) ||
@ -571,13 +572,13 @@ bool CYsfProtocol::IsValidDvLastFramePacket(const CIp &Ip, const CYSFFICH &Fich,
bool valid = false; bool valid = false;
frames[0] = NULL; frames[0] = NULL;
frames[1] = NULL; frames[1] = NULL;
// DV header ? // DV header ?
if ( Fich.getFI() == YSF_FI_TERMINATOR ) if ( Fich.getFI() == YSF_FI_TERMINATOR )
{ {
// get stream id // get stream id
uint32 uiStreamId = IpToStreamId(Ip); uint32 uiStreamId = IpToStreamId(Ip);
// get DV frames // get DV frames
{ {
uint8 uiAmbe[AMBE_SIZE]; uint8 uiAmbe[AMBE_SIZE];
@ -585,11 +586,11 @@ bool CYsfProtocol::IsValidDvLastFramePacket(const CIp &Ip, const CYSFFICH &Fich,
frames[0] = new CDvFramePacket(uiAmbe, uiStreamId, Fich.getFN(), 0, 0); frames[0] = new CDvFramePacket(uiAmbe, uiStreamId, Fich.getFN(), 0, 0);
frames[1] = new CDvLastFramePacket(uiAmbe, uiStreamId, Fich.getFN(), 1, 0); frames[1] = new CDvLastFramePacket(uiAmbe, uiStreamId, Fich.getFN(), 1, 0);
} }
// check validity of packets // check validity of packets
if ( (frames[0] == NULL) || !(frames[0]->IsValid()) || if ( (frames[0] == NULL) || !(frames[0]->IsValid()) ||
(frames[1] == NULL) || !(frames[1]->IsValid()) ) (frames[1] == NULL) || !(frames[1]->IsValid()) )
{ {
delete frames[0]; delete frames[0];
delete frames[1]; delete frames[1];
@ -601,7 +602,7 @@ bool CYsfProtocol::IsValidDvLastFramePacket(const CIp &Ip, const CYSFFICH &Fich,
valid = true; valid = true;
} }
} }
// done // done
return valid; return valid;
} }
@ -666,7 +667,7 @@ bool CYsfProtocol::EncodeDvHeaderPacket(const CDvHeaderPacket &Header, CBuffer *
uint8 temp[120]; uint8 temp[120];
payload.writeHeader(temp, csd1, csd2); payload.writeHeader(temp, csd1, csd2);
Buffer->Append(temp+30, 120-30); Buffer->Append(temp+30, 120-30);
// done // done
return true; return true;
} }
@ -678,7 +679,7 @@ bool CYsfProtocol::EncodeDvPacket(const CDvHeaderPacket &Header, const CDvFrameP
uint8 gps[] = { 0x52,0x22,0x61,0x5F,0x27,0x03,0x5E,0x20,0x20,0x20 }; uint8 gps[] = { 0x52,0x22,0x61,0x5F,0x27,0x03,0x5E,0x20,0x20,0x20 };
char sz[YSF_CALLSIGN_LENGTH]; char sz[YSF_CALLSIGN_LENGTH];
uint8 fichd[YSF_FICH_LENGTH_BYTES]; uint8 fichd[YSF_FICH_LENGTH_BYTES];
// tag // tag
Buffer->Set(tag, sizeof(tag)); Buffer->Set(tag, sizeof(tag));
// rpt1 // rpt1
@ -769,7 +770,7 @@ bool CYsfProtocol::EncodeDvLastPacket(const CDvHeaderPacket &Header, CBuffer *Bu
uint8 dest[] = { 'A','L','L',' ',' ',' ',' ',' ',' ',' ' }; uint8 dest[] = { 'A','L','L',' ',' ',' ',' ',' ',' ',' ' };
char sz[YSF_CALLSIGN_LENGTH]; char sz[YSF_CALLSIGN_LENGTH];
uint8 fichd[YSF_FICH_LENGTH_BYTES]; uint8 fichd[YSF_FICH_LENGTH_BYTES];
// tag // tag
Buffer->Set(tag, sizeof(tag)); Buffer->Set(tag, sizeof(tag));
// rpt1 // rpt1
@ -813,7 +814,7 @@ bool CYsfProtocol::EncodeDvLastPacket(const CDvHeaderPacket &Header, CBuffer *Bu
uint8 temp[120]; uint8 temp[120];
payload.writeHeader(temp, csd1, csd2); payload.writeHeader(temp, csd1, csd2);
Buffer->Append(temp+30, 120-30); Buffer->Append(temp+30, 120-30);
// done // done
return true; return true;
} }
@ -939,7 +940,7 @@ bool CYsfProtocol::IsValidwirexPacket(const CBuffer &Buffer, CYSFFICH *Fich, CCa
bool CYsfProtocol::IsValidServerStatusPacket(const CBuffer &Buffer) const bool CYsfProtocol::IsValidServerStatusPacket(const CBuffer &Buffer) const
{ {
uint8 tag[] = { 'Y','S','F','S' }; uint8 tag[] = { 'Y','S','F','S' };
return ( (Buffer.size() >= 4) && (Buffer.Compare(tag, sizeof(tag)) == 0) ); return ( (Buffer.size() >= 4) && (Buffer.Compare(tag, sizeof(tag)) == 0) );
} }
@ -950,7 +951,7 @@ bool CYsfProtocol::EncodeServerStatusPacket(CBuffer *Buffer) const
uint8 tag[] = { 'Y','S','F','S' }; uint8 tag[] = { 'Y','S','F','S' };
uint8 description[] = { 'X','L','X',' ','r','e','f','l','e','c','t','o','r',' ' }; uint8 description[] = { 'X','L','X',' ','r','e','f','l','e','c','t','o','r',' ' };
uint8 callsign[16]; uint8 callsign[16];
// tag // tag
Buffer->Set(tag, sizeof(tag)); Buffer->Set(tag, sizeof(tag));
// hash // hash
@ -969,7 +970,7 @@ bool CYsfProtocol::EncodeServerStatusPacket(CBuffer *Buffer) const
g_Reflector.ReleaseClients(); g_Reflector.ReleaseClients();
::sprintf(sz, "%03u", count); ::sprintf(sz, "%03u", count);
Buffer->Append((uint8 *)sz, 3); Buffer->Append((uint8 *)sz, 3);
// done // done
return true; return true;
} }
@ -1015,7 +1016,7 @@ bool CYsfProtocol::DebugTestDecodePacket(const CBuffer &Buffer)
CYSFPayload payload; CYSFPayload payload;
CBuffer dump; CBuffer dump;
bool valid = false; bool valid = false;
if ( (Buffer.size() == 155) && (Buffer.Compare(tag, sizeof(tag)) == 0) ) if ( (Buffer.size() == 155) && (Buffer.Compare(tag, sizeof(tag)) == 0) )
{ {
// decode YSH fich // decode YSH fich
@ -1027,7 +1028,7 @@ bool CYsfProtocol::DebugTestDecodePacket(const CBuffer &Buffer)
<< (int)Fich.getBT() << "," << (int)Fich.getBT() << ","
<< (int)Fich.getFN() << "," << (int)Fich.getFN() << ","
<< (int)Fich.getFT() << " : "; << (int)Fich.getFT() << " : ";
switch ( Fich.getFI() ) switch ( Fich.getFI() )
{ {
case YSF_FI_HEADER: case YSF_FI_HEADER:
@ -1076,14 +1077,14 @@ bool CYsfProtocol::DebugDumpHeaderPacket(const CBuffer &Buffer)
uint8 data[200]; uint8 data[200];
:: memset(data, 0, sizeof(data)); :: memset(data, 0, sizeof(data));
ok = IsValidDvPacket(Buffer, &fich); ok = IsValidDvPacket(Buffer, &fich);
if ( ok && (fich.getFI() == YSF_FI_HEADER) ) if ( ok && (fich.getFI() == YSF_FI_HEADER) )
{ {
ok &= payload.processHeaderData((unsigned char *)&(Buffer.data()[35])); ok &= payload.processHeaderData((unsigned char *)&(Buffer.data()[35]));
} }
std::cout << "HD-" <<(ok ? "ok " : "xx ") << "src: " << payload.getSource() << "dest: " << payload.getDest() << std::endl; std::cout << "HD-" <<(ok ? "ok " : "xx ") << "src: " << payload.getSource() << "dest: " << payload.getDest() << std::endl;
return ok; return ok;
@ -1105,7 +1106,7 @@ bool CYsfProtocol::DebugDumpDvPacket(const CBuffer &Buffer)
} }
std::cout << "DV-" <<(ok ? "ok " : "xx ") << "FN:" << (int)fich.getFN() << " payload: " << (char *)data << std::endl; std::cout << "DV-" <<(ok ? "ok " : "xx ") << "FN:" << (int)fich.getFN() << " payload: " << (char *)data << std::endl;
return ok; return ok;
} }
@ -1117,14 +1118,14 @@ bool CYsfProtocol::DebugDumpLastDvPacket(const CBuffer &Buffer)
uint8 data[200]; uint8 data[200];
:: memset(data, 0, sizeof(data)); :: memset(data, 0, sizeof(data));
ok = IsValidDvPacket(Buffer, &fich); ok = IsValidDvPacket(Buffer, &fich);
if ( ok && (fich.getFI() == YSF_FI_TERMINATOR) ) if ( ok && (fich.getFI() == YSF_FI_TERMINATOR) )
{ {
ok &= payload.processHeaderData((unsigned char *)&(Buffer.data()[35])); ok &= payload.processHeaderData((unsigned char *)&(Buffer.data()[35]));
} }
std::cout << "TC-" <<(ok ? "ok " : "xx ") << "src: " << payload.getSource() << "dest: " << payload.getDest() << std::endl; std::cout << "TC-" <<(ok ? "ok " : "xx ") << "src: " << payload.getSource() << "dest: " << payload.getDest() << std::endl;
return ok; return ok;

Loading…
Cancel
Save

Powered by TurnKey Linux.