All Packets are now managed by std::unique_ptr

pull/1/head
Tom Early 5 years ago
parent 264c3d0f6a
commit 08df566f6e

@ -67,19 +67,6 @@ CCodecStream::~CCodecStream()
{
m_Future.get();
}
// empty local queue
while ( !m_LocalQueue.empty() )
{
delete m_LocalQueue.front();
m_LocalQueue.pop();
}
// empty ourselves
while ( !empty() )
{
delete front();
pop();
}
}
////////////////////////////////////////////////////////////////////////////////////////
@ -200,15 +187,16 @@ void CCodecStream::Task(void)
// pop the original packet
if ( !m_LocalQueue.empty() )
{
CDvFramePacket *Packet = (CDvFramePacket *)m_LocalQueue.front();
auto Packet = m_LocalQueue.front();
auto Frame = (CDvFramePacket *)Packet.get();
m_LocalQueue.pop();
// todo: check the PID
// update content with transcoded ambe
Packet->SetAmbe(m_uiCodecOut, Ambe);
Frame->SetAmbe(m_uiCodecOut, Ambe);
// tag syncs in DvData
if ( (m_uiCodecOut == CODEC_AMBEPLUS) && (Packet->GetPacketId() % 21) == 0 )
if ( (m_uiCodecOut == CODEC_AMBEPLUS) && (Frame->GetPacketId() % 21) == 0 )
{
Packet->SetDvData(DStarSync);
Frame->SetDvData(DStarSync);
}
// and push it back to client
m_PacketStream->Lock();
@ -226,7 +214,8 @@ void CCodecStream::Task(void)
while ( !empty() )
{
// yes, pop it from queue
CPacket *Packet = front();
auto Packet = front();
auto Frame = (CDvFramePacket *)Packet.get();
pop();
// yes, send to ambed
@ -235,7 +224,7 @@ void CCodecStream::Task(void)
// and that the packet needs transcoding
m_StatsTimer.Now();
m_uiTotalPackets++;
EncodeAmbePacket(&Buffer, ((CDvFramePacket *)Packet)->GetAmbe(m_uiCodecIn));
EncodeAmbePacket(&Buffer, Frame->GetAmbe(m_uiCodecIn));
m_Socket.Send(Buffer, m_Ip, m_uiPort);
// and push to our local queue

@ -57,8 +57,8 @@ void CDcsProtocol::Task(void)
CIp Ip;
CCallsign Callsign;
char ToLinkModule;
CDvHeaderPacket *Header;
CDvFramePacket *Frame;
std::unique_ptr<CDvHeaderPacket> Header;
std::unique_ptr<CDvFramePacket> Frame;
// handle incoming packets
#if DSTAR_IPV6==true
@ -72,7 +72,7 @@ void CDcsProtocol::Task(void)
#endif
{
// crack the packet
if ( IsValidDvPacket(Buffer, &Header, &Frame) )
if ( IsValidDvPacket(Buffer, Header, Frame) )
{
//std::cout << "DCS DV packet" << std::endl;
@ -90,14 +90,9 @@ void CDcsProtocol::Task(void)
else
{
//std::cout << "DCS DV last frame" << std::endl;
OnDvLastFramePacketIn((CDvLastFramePacket *)Frame, &Ip);
OnDvLastFramePacketIn((std::unique_ptr<CDvLastFramePacket> &)Frame, &Ip);
}
}
else
{
delete Header;
delete Frame;
}
}
else if ( IsValidConnectPacket(Buffer, &Callsign, &ToLinkModule) )
{
@ -197,10 +192,8 @@ void CDcsProtocol::Task(void)
////////////////////////////////////////////////////////////////////////////////////////
// streams helpers
bool CDcsProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
void CDcsProtocol::OnDvHeaderPacketIn(std::unique_ptr<CDvHeaderPacket> &Header, const CIp &Ip)
{
bool newstream = false;
// find the stream
CPacketStream *stream = GetStream(Header->GetStreamId());
if ( stream == nullptr )
@ -219,7 +212,6 @@ bool CDcsProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
{
// keep the handle
m_Streams.push_back(stream);
newstream = true;
}
}
// release
@ -228,24 +220,13 @@ bool CDcsProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
// update last heard
g_Reflector.GetUsers()->Hearing(Header->GetMyCallsign(), via, Header->GetRpt2Callsign());
g_Reflector.ReleaseUsers();
// delete header if needed
if ( !newstream )
{
delete Header;
}
}
else
{
// stream already open
// skip packet, but tickle the stream
stream->Tickle();
// and delete packet
delete Header;
}
// done
return newstream;
}
////////////////////////////////////////////////////////////////////////////////////////
@ -257,7 +238,7 @@ void CDcsProtocol::HandleQueue(void)
while ( !m_Queue.empty() )
{
// get the packet
CPacket *packet = m_Queue.front();
auto packet = m_Queue.front();
m_Queue.pop();
// get our sender's id
@ -311,9 +292,6 @@ void CDcsProtocol::HandleQueue(void)
g_Reflector.ReleaseClients();
}
}
// done
delete packet;
}
m_Queue.Unlock();
}
@ -411,58 +389,41 @@ bool CDcsProtocol::IsValidKeepAlivePacket(const CBuffer &Buffer, CCallsign *call
return valid;
}
bool CDcsProtocol::IsValidDvPacket(const CBuffer &Buffer, CDvHeaderPacket **header, CDvFramePacket **frame)
bool CDcsProtocol::IsValidDvPacket(const CBuffer &Buffer, std::unique_ptr<CDvHeaderPacket> &header, std::unique_ptr<CDvFramePacket> &frame)
{
uint8 tag[] = { '0','0','0','1' };
bool valid = false;
*header = nullptr;
*frame = nullptr;
if ( (Buffer.size() >= 100) && (Buffer.Compare(tag, sizeof(tag)) == 0) )
{
// get the header
*header = new CDvHeaderPacket((struct dstar_header *)&(Buffer.data()[4]), *((uint16 *)&(Buffer.data()[43])), 0x80);
header = std::unique_ptr<CDvHeaderPacket>(new CDvHeaderPacket((struct dstar_header *)&(Buffer.data()[4]), *((uint16 *)&(Buffer.data()[43])), 0x80));
// get the frame
if ( ((Buffer.data()[45]) & 0x40) != 0 )
if ( Buffer.data()[45] & 0x40U )
{
// it's the last frame
*frame = new CDvLastFramePacket((struct dstar_dvframe *)&(Buffer.data()[46]), *((uint16 *)&(Buffer.data()[43])), Buffer.data()[45]);
frame = std::unique_ptr<CDvLastFramePacket>(new CDvLastFramePacket((struct dstar_dvframe *)&(Buffer.data()[46]), *((uint16 *)&(Buffer.data()[43])), Buffer.data()[45]));
}
else
{
// it's a regular DV frame
*frame = new CDvFramePacket((struct dstar_dvframe *)&(Buffer.data()[46]), *((uint16 *)&(Buffer.data()[43])), Buffer.data()[45]);
frame = std::unique_ptr<CDvFramePacket>(new CDvFramePacket((struct dstar_dvframe *)&(Buffer.data()[46]), *((uint16 *)&(Buffer.data()[43])), Buffer.data()[45]));
}
// check validity of packets
if ( !((*header)->IsValid() && (*frame)->IsValid()) )
{
delete *header;
delete *frame;
*header = nullptr;
*frame = nullptr;
}
else
{
valid = true;
}
if ( header && header->IsValid() && frame && frame->IsValid() )
return true;
}
// done
return valid;
return false;
}
bool CDcsProtocol::IsIgnorePacket(const CBuffer &Buffer)
{
bool valid = false;
uint8 tag[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, };
if ( Buffer.size() == 15 )
{
valid = (Buffer.Compare(tag, sizeof(tag)) == 0);
}
return valid;
if ( 15==Buffer.size() == 15 && 0==Buffer.Compare(tag, sizeof(tag)) )
return true;
return false;
}

@ -64,13 +64,13 @@ protected:
void HandleKeepalives(void);
// stream helpers
bool OnDvHeaderPacketIn(CDvHeaderPacket *, const CIp &);
void OnDvHeaderPacketIn(std::unique_ptr<CDvHeaderPacket> &, const CIp &);
// packet decoding helpers
bool IsValidConnectPacket(const CBuffer &, CCallsign *, char *);
bool IsValidDisconnectPacket(const CBuffer &, CCallsign *);
bool IsValidKeepAlivePacket(const CBuffer &, CCallsign *);
bool IsValidDvPacket(const CBuffer &, CDvHeaderPacket **, CDvFramePacket **);
bool IsValidDvPacket(const CBuffer &, std::unique_ptr<CDvHeaderPacket> &, std::unique_ptr<CDvFramePacket> &);
bool IsIgnorePacket(const CBuffer &);
// packet encoding helpers

@ -59,9 +59,9 @@ void CDextraProtocol::Task(void)
CCallsign Callsign;
char ToLinkModule;
int ProtRev;
CDvHeaderPacket *Header;
CDvFramePacket *Frame;
CDvLastFramePacket *LastFrame;
std::unique_ptr<CDvHeaderPacket> Header;
std::unique_ptr<CDvFramePacket> Frame;
std::unique_ptr<CDvLastFramePacket> LastFrame;
// any incoming packet ?
#if DSTAR_IPV6==true
@ -75,34 +75,20 @@ void CDextraProtocol::Task(void)
#endif
{
// crack the packet
if ( (Frame = IsValidDvFramePacket(Buffer)) != nullptr )
if ( IsValidDvFramePacket(Buffer, Frame) )
{
//std::cout << "DExtra DV frame" << std::endl;
// handle it
OnDvFramePacketIn(Frame, &Ip);
}
else if ( (Header = IsValidDvHeaderPacket(Buffer)) != nullptr )
else if ( IsValidDvHeaderPacket(Buffer, Header) )
{
//std::cout << "DExtra DV header:" << std::endl << *Header << std::endl;
//std::cout << "DExtra DV header:" << std::endl;
// callsign muted?
if ( g_GateKeeper.MayTransmit(Header->GetMyCallsign(), Ip, PROTOCOL_DEXTRA, Header->GetRpt2Module()) )
{
// handle it
OnDvHeaderPacketIn(Header, Ip);
}
else
{
delete Header;
}
}
else if ( (LastFrame = IsValidDvLastFramePacket(Buffer)) != nullptr )
else if ( IsValidDvLastFramePacket(Buffer, LastFrame) )
{
//std::cout << "DExtra DV last frame" << std::endl;
// handle it
OnDvLastFramePacketIn(LastFrame, &Ip);
}
else if ( IsValidConnectPacket(Buffer, &Callsign, &ToLinkModule, &ProtRev) )
@ -243,7 +229,7 @@ void CDextraProtocol::HandleQueue(void)
while ( !m_Queue.empty() )
{
// get the packet
CPacket *packet = m_Queue.front();
auto packet = m_Queue.front();
m_Queue.pop();
// encode it
@ -269,10 +255,6 @@ void CDextraProtocol::HandleQueue(void)
}
g_Reflector.ReleaseClients();
}
// done
delete packet;
}
m_Queue.Unlock();
}
@ -413,10 +395,8 @@ void CDextraProtocol::HandlePeerLinks(void)
////////////////////////////////////////////////////////////////////////////////////////
// streams helpers
bool CDextraProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
void CDextraProtocol::OnDvHeaderPacketIn(std::unique_ptr<CDvHeaderPacket> &Header, const CIp &Ip)
{
bool newstream = false;
// find the stream
CPacketStream *stream = GetStream(Header->GetStreamId());
if ( stream == nullptr )
@ -442,7 +422,6 @@ bool CDextraProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
{
// keep the handle
m_Streams.push_back(stream);
newstream = true;
}
}
// release
@ -451,24 +430,13 @@ bool CDextraProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
// update last heard
g_Reflector.GetUsers()->Hearing(Header->GetMyCallsign(), via, Header->GetRpt2Callsign());
g_Reflector.ReleaseUsers();
// delete header if needed
if ( !newstream )
{
delete Header;
}
}
else
{
// stream already open
// skip packet, but tickle the stream
stream->Tickle();
// and delete packet
delete Header;
}
// done
return newstream;
}
////////////////////////////////////////////////////////////////////////////////////////
@ -524,66 +492,43 @@ bool CDextraProtocol::IsValidKeepAlivePacket(const CBuffer &Buffer, CCallsign *c
return valid;
}
CDvHeaderPacket *CDextraProtocol::IsValidDvHeaderPacket(const CBuffer &Buffer)
bool CDextraProtocol::IsValidDvHeaderPacket(const CBuffer &Buffer, std::unique_ptr<CDvHeaderPacket> &header)
{
CDvHeaderPacket *header = nullptr;
if ( (Buffer.size() == 56) && (Buffer.Compare((uint8 *)"DSVT", 4) == 0) &&
(Buffer.data()[4] == 0x10) && (Buffer.data()[8] == 0x20) )
if ( 56==Buffer.size() && 0==Buffer.Compare((uint8 *)"DSVT", 4) && 0x10U==Buffer.data()[4] && 0x20U==Buffer.data()[8] )
{
// create packet
header = new CDvHeaderPacket((struct dstar_header *)&(Buffer.data()[15]),
*((uint16 *)&(Buffer.data()[12])), 0x80);
header = std::unique_ptr<CDvHeaderPacket>(new CDvHeaderPacket((struct dstar_header *)&(Buffer.data()[15]), *((uint16 *)&(Buffer.data()[12])), 0x80));
// check validity of packet
if ( !header->IsValid() )
{
delete header;
header = nullptr;
}
if ( header && header->IsValid() )
return true;
}
return header;
return false;
}
CDvFramePacket *CDextraProtocol::IsValidDvFramePacket(const CBuffer &Buffer)
bool CDextraProtocol::IsValidDvFramePacket(const CBuffer &Buffer, std::unique_ptr<CDvFramePacket> &dvframe)
{
CDvFramePacket *dvframe = nullptr;
if ( (Buffer.size() == 27) && (Buffer.Compare((uint8 *)"DSVT", 4) == 0) &&
(Buffer.data()[4] == 0x20) && (Buffer.data()[8] == 0x20) &&
((Buffer.data()[14] & 0x40) == 0) )
if ( 27==Buffer.size() && 0==Buffer.Compare((uint8 *)"DSVT", 4) && 0x20U==Buffer.data()[4] && 0x20U==Buffer.data()[8] && 0U==(Buffer.data()[14] & 0x40U) )
{
// create packet
dvframe = new CDvFramePacket((struct dstar_dvframe *)&(Buffer.data()[15]),
*((uint16 *)&(Buffer.data()[12])), Buffer.data()[14]);
dvframe = std::unique_ptr<CDvFramePacket>(new CDvFramePacket((struct dstar_dvframe *)&(Buffer.data()[15]), *((uint16 *)&(Buffer.data()[12])), Buffer.data()[14]));
// check validity of packet
if ( !dvframe->IsValid() )
{
delete dvframe;
dvframe = nullptr;
}
if ( dvframe && dvframe->IsValid() )
return true;
}
return dvframe;
return false;
}
CDvLastFramePacket *CDextraProtocol::IsValidDvLastFramePacket(const CBuffer &Buffer)
bool CDextraProtocol::IsValidDvLastFramePacket(const CBuffer &Buffer, std::unique_ptr<CDvLastFramePacket> &dvframe)
{
CDvLastFramePacket *dvframe = nullptr;
if ( (Buffer.size() == 27) && (Buffer.Compare((uint8 *)"DSVT", 4) == 0) &&
(Buffer.data()[4] == 0x20) && (Buffer.data()[8] == 0x20) &&
((Buffer.data()[14] & 0x40) != 0) )
if ( 27==Buffer.size() && 0==Buffer.Compare((uint8 *)"DSVT", 4) && 0x20U==Buffer.data()[4] && 0x20U==Buffer.data()[8] && (Buffer.data()[14] & 0x40) )
{
// create packet
dvframe = new CDvLastFramePacket((struct dstar_dvframe *)&(Buffer.data()[15]),
*((uint16 *)&(Buffer.data()[12])), Buffer.data()[14]);
dvframe = std::unique_ptr<CDvLastFramePacket>(new CDvLastFramePacket((struct dstar_dvframe *)&(Buffer.data()[15]), *((uint16 *)&(Buffer.data()[12])), Buffer.data()[14]));
// check validity of packet
if ( !dvframe->IsValid() )
{
delete dvframe;
dvframe = nullptr;
}
if ( dvframe && dvframe->IsValid() )
return true;
}
return dvframe;
return false;
}
////////////////////////////////////////////////////////////////////////////////////////

@ -73,15 +73,15 @@ protected:
void HandleKeepalives(void);
// stream helpers
bool OnDvHeaderPacketIn(CDvHeaderPacket *, const CIp &);
void OnDvHeaderPacketIn(std::unique_ptr<CDvHeaderPacket> &, const CIp &);
// packet decoding helpers
bool IsValidConnectPacket(const CBuffer &, CCallsign *, char *, int *);
bool IsValidDisconnectPacket(const CBuffer &, CCallsign *);
bool IsValidKeepAlivePacket(const CBuffer &, CCallsign *);
CDvHeaderPacket *IsValidDvHeaderPacket(const CBuffer &);
CDvFramePacket *IsValidDvFramePacket(const CBuffer &);
CDvLastFramePacket *IsValidDvLastFramePacket(const CBuffer &);
bool IsValidConnectPacket( const CBuffer &, CCallsign *, char *, int *);
bool IsValidDisconnectPacket( const CBuffer &, CCallsign *);
bool IsValidKeepAlivePacket( const CBuffer &, CCallsign *);
bool IsValidDvHeaderPacket( const CBuffer &, std::unique_ptr<CDvHeaderPacket> &);
bool IsValidDvFramePacket( const CBuffer &, std::unique_ptr<CDvFramePacket> &);
bool IsValidDvLastFramePacket(const CBuffer &, std::unique_ptr<CDvLastFramePacket> &);
// packet encoding helpers
void EncodeKeepAlivePacket(CBuffer *);

@ -85,9 +85,9 @@ void CDmrmmdvmProtocol::Task(void)
int iRssi;
uint8 Cmd;
uint8 CallType;
CDvHeaderPacket *Header;
CDvFramePacket *Frames[3];
CDvLastFramePacket *LastFrame;
std::unique_ptr<CDvHeaderPacket> Header;
std::unique_ptr<CDvLastFramePacket> LastFrame;
std::array<std::unique_ptr<CDvFramePacket>, 3> Frames;
// handle incoming packets
#if DMR_IPV6==true
@ -104,33 +104,22 @@ void CDmrmmdvmProtocol::Task(void)
// crack the packet
if ( IsValidDvFramePacket(Buffer, Frames) )
{
//std::cout << "DMRmmdvm DV frame" << std::endl;
for ( int i = 0; i < 3; i++ )
{
OnDvFramePacketIn(Frames[i], &Ip);
OnDvFramePacketIn(Frames.at(i), &Ip);
}
}
else if ( IsValidDvHeaderPacket(Buffer, &Header, &Cmd, &CallType) )
else if ( IsValidDvHeaderPacket(Buffer, Header, &Cmd, &CallType) )
{
//std::cout << "DMRmmdvm DV header:" << std::endl << *Header << std::endl;
//std::cout << "DMRmmdvm DV header" << std::endl;
// callsign muted?
if ( g_GateKeeper.MayTransmit(Header->GetMyCallsign(), Ip, PROTOCOL_DMRMMDVM) )
{
// handle it
OnDvHeaderPacketIn(Header, Ip, Cmd, CallType);
}
else
{
delete Header;
}
}
else if ( IsValidDvLastFramePacket(Buffer, &LastFrame) )
else if ( IsValidDvLastFramePacket(Buffer, LastFrame) )
{
//std::cout << "DMRmmdvm DV last frame" << std::endl;
OnDvLastFramePacketIn(LastFrame, &Ip);
}
else if ( IsValidConnectPacket(Buffer, &Callsign, Ip) )
@ -272,7 +261,7 @@ void CDmrmmdvmProtocol::Task(void)
////////////////////////////////////////////////////////////////////////////////////////
// streams helpers
bool CDmrmmdvmProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip, uint8 cmd, uint8 CallType)
bool CDmrmmdvmProtocol::OnDvHeaderPacketIn(std::unique_ptr<CDvHeaderPacket> &Header, const CIp &Ip, uint8 cmd, uint8 CallType)
{
bool newstream = false;
bool lastheard = false;
@ -350,20 +339,12 @@ bool CDmrmmdvmProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &I
g_Reflector.GetUsers()->Hearing(Header->GetMyCallsign(), via, Header->GetRpt2Callsign());
g_Reflector.ReleaseUsers();
}
// delete header if needed
if ( !newstream )
{
delete Header;
}
}
else
{
// stream already open
// skip packet, but tickle the stream
stream->Tickle();
// and delete packet
delete Header;
}
// done
@ -380,7 +361,7 @@ void CDmrmmdvmProtocol::HandleQueue(void)
while ( !m_Queue.empty() )
{
// get the packet
CPacket *packet = m_Queue.front();
auto packet = m_Queue.front();
m_Queue.pop();
// get our sender's id
@ -398,7 +379,7 @@ void CDmrmmdvmProtocol::HandleQueue(void)
m_StreamsCache[iModId].m_uiSeqId = 0;
// encode it
EncodeDvHeaderPacket((const CDvHeaderPacket &)*packet, m_StreamsCache[iModId].m_uiSeqId, &buffer);
EncodeDvHeaderPacket((CDvHeaderPacket &)*packet, m_StreamsCache[iModId].m_uiSeqId, &buffer);
m_StreamsCache[iModId].m_uiSeqId = 1;
}
// check if it's a last frame
@ -454,9 +435,6 @@ void CDmrmmdvmProtocol::HandleQueue(void)
}
g_Reflector.ReleaseClients();
}
// done
delete packet;
}
m_Queue.Unlock();
}
@ -620,12 +598,10 @@ bool CDmrmmdvmProtocol::IsValidRssiPacket(const CBuffer &Buffer, CCallsign *call
return valid;
}
bool CDmrmmdvmProtocol::IsValidDvHeaderPacket(const CBuffer &Buffer, CDvHeaderPacket **header, uint8 *cmd, uint8 *CallType)
bool CDmrmmdvmProtocol::IsValidDvHeaderPacket(const CBuffer &Buffer, std::unique_ptr<CDvHeaderPacket> &header, uint8 *cmd, uint8 *CallType)
{
uint8 tag[] = { 'D','M','R','D' };
bool valid = false;
*header = nullptr;
*cmd = CMD_NONE;
if ( (Buffer.size() == 55) && (Buffer.Compare(tag, sizeof(tag)) == 0) )
@ -687,29 +663,19 @@ bool CDmrmmdvmProtocol::IsValidDvHeaderPacket(const CBuffer &Buffer, CDvHeaderPa
rpt2.SetModule(DmrDstIdToModule(uiDstId));
// and packet
*header = new CDvHeaderPacket(uiSrcId, CCallsign("CQCQCQ"), rpt1, rpt2, uiStreamId, 0, 0);
valid = (*header)->IsValid();
if ( !valid )
{
delete *header;
*header = nullptr;
}
header = std::unique_ptr<CDvHeaderPacket>(new CDvHeaderPacket(uiSrcId, CCallsign("CQCQCQ"), rpt1, rpt2, uiStreamId, 0, 0));
if ( header && header->IsValid() )
return true;
}
}
}
// done
return valid;
return false;
}
bool CDmrmmdvmProtocol::IsValidDvFramePacket(const CBuffer &Buffer, CDvFramePacket **frames)
bool CDmrmmdvmProtocol::IsValidDvFramePacket(const CBuffer &Buffer, std::array<std::unique_ptr<CDvFramePacket>, 3> &frames)
{
uint8 tag[] = { 'D','M','R','D' };
bool valid = false;
frames[0] = nullptr;
frames[1] = nullptr;
frames[2] = nullptr;
if ( (Buffer.size() == 55) && (Buffer.Compare(tag, sizeof(tag)) == 0) )
{
// frame details
@ -752,31 +718,28 @@ bool CDmrmmdvmProtocol::IsValidDvFramePacket(const CBuffer &Buffer, CDvFramePack
// and create 3 dv frames
// frame1
memcpy(dmrambe, &dmr3ambe[0], 9);
frames[0] = new CDvFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 1);
frames[0] = std::unique_ptr<CDvFramePacket>(new CDvFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 1));
// frame2
memcpy(dmrambe, &dmr3ambe[9], 9);
frames[1] = new CDvFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 2);
frames[1] = std::unique_ptr<CDvFramePacket>(new CDvFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 2));
// frame3
memcpy(dmrambe, &dmr3ambe[18], 9);
frames[2] = new CDvFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 3);
frames[2] = std::unique_ptr<CDvFramePacket>(new CDvFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 3));
// check
valid = true;
if (frames[0] && frames[1] && frames[2])
return true;
}
}
// done
return valid;
return false;
}
bool CDmrmmdvmProtocol::IsValidDvLastFramePacket(const CBuffer &Buffer, CDvLastFramePacket **frame)
bool CDmrmmdvmProtocol::IsValidDvLastFramePacket(const CBuffer &Buffer, std::unique_ptr<CDvLastFramePacket> &frame)
{
uint8 tag[] = { 'D','M','R','D' };
bool valid = false;
*frame = nullptr;
if ( (Buffer.size() == 55) && (Buffer.Compare(tag, sizeof(tag)) == 0) )
{
// frame details
@ -817,15 +780,13 @@ bool CDmrmmdvmProtocol::IsValidDvLastFramePacket(const CBuffer &Buffer, CDvLastF
// and packet
*frame = new CDvLastFramePacket(ambe, dmrsync, uiStreamId, 0, 0);
// check
valid = true;
frame = std::unique_ptr<CDvLastFramePacket>(new CDvLastFramePacket(ambe, dmrsync, uiStreamId, 0, 0));
if (frame)
return true;
}
}
}
// done
return valid;
return false;
}
////////////////////////////////////////////////////////////////////////////////////////

@ -4,6 +4,7 @@
//
// Created by Jean-Luc Deltombe (LX3JL) on 04/03/2017.
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
// Copyright © 2020 Thomas A. Early, N7TAE
//
// ----------------------------------------------------------------------------
// This file is part of xlxd.
@ -80,7 +81,7 @@ protected:
void HandleKeepalives(void);
// stream helpers
bool OnDvHeaderPacketIn(CDvHeaderPacket *, const CIp &, uint8, uint8);
bool OnDvHeaderPacketIn(std::unique_ptr<CDvHeaderPacket> &, const CIp &, uint8, uint8);
// packet decoding helpers
bool IsValidConnectPacket(const CBuffer &, CCallsign *, const CIp &);
@ -90,9 +91,9 @@ protected:
bool IsValidOptionPacket(const CBuffer &, CCallsign *);
bool IsValidKeepAlivePacket(const CBuffer &, CCallsign *);
bool IsValidRssiPacket(const CBuffer &, CCallsign *, int *);
bool IsValidDvHeaderPacket(const CBuffer &, CDvHeaderPacket **, uint8 *, uint8 *);
bool IsValidDvFramePacket(const CBuffer &, CDvFramePacket **);
bool IsValidDvLastFramePacket(const CBuffer &, CDvLastFramePacket **);
bool IsValidDvHeaderPacket(const CBuffer &, std::unique_ptr<CDvHeaderPacket> &, uint8 *, uint8 *);
bool IsValidDvFramePacket(const CBuffer &, std::array<std::unique_ptr<CDvFramePacket>, 3> &);
bool IsValidDvLastFramePacket(const CBuffer &, std::unique_ptr<CDvLastFramePacket> &);
// packet encoding helpers
void EncodeKeepAlivePacket(CBuffer *, std::shared_ptr<CClient>);

@ -75,8 +75,8 @@ void CDmrplusProtocol::Task(void)
CIp Ip;
CCallsign Callsign;
char ToLinkModule;
CDvHeaderPacket *Header;
CDvFramePacket *Frames[3];
std::unique_ptr<CDvHeaderPacket> Header;
std::array<std::unique_ptr<CDvFramePacket>, 3> Frames;
// handle incoming packets
#if DMR_IPV6==true
@ -92,40 +92,19 @@ void CDmrplusProtocol::Task(void)
// crack the packet
if ( IsValidDvFramePacket(Ip, Buffer, Frames) )
{
//std::cout << "DMRplus DV frame" << std::endl;
//Buffer.DebugDump(g_Reflector.m_DebugFile);
for ( int i = 0; i < 3; i++ )
{
OnDvFramePacketIn(Frames[i], &Ip);
/*if ( !Frames[i]->IsLastPacket() )
{
//std::cout << "DMRplus DV frame" << std::endl;
OnDvFramePacketIn(Frames[i], &Ip);
}
else
{
//std::cout << "DMRplus DV last frame" << std::endl;
OnDvLastFramePacketIn((CDvLastFramePacket *)Frames[i], &Ip);
}*/
}
}
else if ( IsValidDvHeaderPacket(Ip, Buffer, &Header) )
else if ( IsValidDvHeaderPacket(Ip, Buffer, Header) )
{
//std::cout << "DMRplus DV header:" << std::endl;
//std::cout << "DMRplus DV header:" << std::endl << *Header << std::endl;
//Buffer.DebugDump(g_Reflector.m_DebugFile);
// callsign muted?
if ( g_GateKeeper.MayTransmit(Header->GetMyCallsign(), Ip, PROTOCOL_DMRPLUS) )
{
// handle it
OnDvHeaderPacketIn(Header, Ip);
}
else
{
delete Header;
}
}
else if ( IsValidConnectPacket(Buffer, &Callsign, &ToLinkModule, Ip) )
{
@ -204,10 +183,8 @@ void CDmrplusProtocol::Task(void)
////////////////////////////////////////////////////////////////////////////////////////
// streams helpers
bool CDmrplusProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
void CDmrplusProtocol::OnDvHeaderPacketIn(std::unique_ptr<CDvHeaderPacket> &Header, const CIp &Ip)
{
bool newstream = false;
// find the stream
CPacketStream *stream = GetStream(Header->GetStreamId());
if ( stream == nullptr )
@ -222,7 +199,6 @@ bool CDmrplusProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip
{
// keep the handle
m_Streams.push_back(stream);
newstream = true;
}
}
// release
@ -233,23 +209,11 @@ bool CDmrplusProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip
// stream already open
// skip packet, but tickle the stream
stream->Tickle();
// and delete packet
delete Header;
}
// update last heard
g_Reflector.GetUsers()->Hearing(Header->GetMyCallsign(), Header->GetRpt1Callsign(), Header->GetRpt2Callsign());
g_Reflector.ReleaseUsers();
// delete header if needed
if ( !newstream )
{
delete Header;
}
// done
return newstream;
}
////////////////////////////////////////////////////////////////////////////////////////
@ -262,7 +226,7 @@ void CDmrplusProtocol::HandleQueue(void)
while ( !m_Queue.empty() )
{
// get the packet
CPacket *packet = m_Queue.front();
auto packet = m_Queue.front();
m_Queue.pop();
// get our sender's id
@ -330,9 +294,6 @@ void CDmrplusProtocol::HandleQueue(void)
// debug
//buffer.DebugDump(g_Reflector.m_DebugFile);
}
// done
delete packet;
}
m_Queue.Unlock();
}
@ -443,11 +404,8 @@ bool CDmrplusProtocol::IsValidDisconnectPacket(const CBuffer &Buffer, CCallsign
return valid;
}
bool CDmrplusProtocol::IsValidDvHeaderPacket(const CIp &Ip, const CBuffer &Buffer, CDvHeaderPacket **Header)
bool CDmrplusProtocol::IsValidDvHeaderPacket(const CIp &Ip, const CBuffer &Buffer, std::unique_ptr<CDvHeaderPacket> &Header)
{
bool valid = false;
*Header = nullptr;
uint8 uiPacketType = Buffer.data()[8];
if ( (Buffer.size() == 72) && ( uiPacketType == 2 ) )
{
@ -472,26 +430,16 @@ bool CDmrplusProtocol::IsValidDvHeaderPacket(const CIp &Ip, const CBuffer &Buffe
uint32 uiStreamId = IpToStreamId(Ip);
// and packet
*Header = new CDvHeaderPacket(uiSrcId, CCallsign("CQCQCQ"), rpt1, rpt2, uiStreamId, 0, 0);
valid = (*Header)->IsValid();
if ( !valid )
{
delete *Header;
*Header = nullptr;
}
Header = std::unique_ptr<CDvHeaderPacket>(new CDvHeaderPacket(uiSrcId, CCallsign("CQCQCQ"), rpt1, rpt2, uiStreamId, 0, 0));
if (Header && Header->IsValid())
return true;
}
}
// done
return valid;
return false;
}
bool CDmrplusProtocol::IsValidDvFramePacket(const CIp &Ip, const CBuffer &Buffer, CDvFramePacket **frames)
bool CDmrplusProtocol::IsValidDvFramePacket(const CIp &Ip, const CBuffer &Buffer, std::array<std::unique_ptr<CDvFramePacket>, 3> &frames)
{
bool valid = false;
frames[0] = nullptr;
frames[1] = nullptr;
frames[2] = nullptr;
uint8 uiPacketType = Buffer.data()[8];
if ( (Buffer.size() == 72) && ((uiPacketType == 1) || (uiPacketType == 3)) )
{
@ -530,30 +478,29 @@ bool CDmrplusProtocol::IsValidDvFramePacket(const CIp &Ip, const CBuffer &Buffer
uint32 uiStreamId = IpToStreamId(Ip);
// frame1
memcpy(dmrambe, &dmr3ambe[0], 9);
frames[0] = new CDvFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 1);
frames[0] = std::unique_ptr<CDvFramePacket>(new CDvFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 1));
// frame2
memcpy(dmrambe, &dmr3ambe[9], 9);
frames[1] = new CDvFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 2);
frames[1] = std::unique_ptr<CDvFramePacket>(new CDvFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 2));
// frame3
memcpy(dmrambe, &dmr3ambe[18], 9);
if ( uiPacketType == 3 )
{
frames[2] = new CDvLastFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 3);
frames[2] = std::unique_ptr<CDvFramePacket>(new CDvLastFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 3));
}
else
{
frames[2] = new CDvFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 3);
frames[2] = std::unique_ptr<CDvFramePacket>(new CDvFramePacket(dmrambe, dmrsync, uiStreamId, uiVoiceSeq, 3));
}
// check
valid = true;
if (frames[0] && frames[1] && frames[2])
return true;
}
}
// done
return valid;
return false;
}

@ -71,13 +71,13 @@ protected:
void HandleKeepalives(void);
// stream helpers
bool OnDvHeaderPacketIn(CDvHeaderPacket *, const CIp &);
void OnDvHeaderPacketIn(std::unique_ptr<CDvHeaderPacket> &, const CIp &);
// packet decoding helpers
bool IsValidConnectPacket(const CBuffer &, CCallsign *, char *, const CIp &);
bool IsValidDisconnectPacket(const CBuffer &, CCallsign *, char *);
bool IsValidDvHeaderPacket(const CIp &, const CBuffer &, CDvHeaderPacket **);
bool IsValidDvFramePacket(const CIp &, const CBuffer &, CDvFramePacket **);
bool IsValidDvHeaderPacket(const CIp &, const CBuffer &, std::unique_ptr<CDvHeaderPacket> &);
bool IsValidDvFramePacket(const CIp &, const CBuffer &, std::array<std::unique_ptr<CDvFramePacket>, 3> &);
// packet encoding helpers
void EncodeConnectAckPacket(CBuffer *);

@ -57,9 +57,9 @@ void CDplusProtocol::Task(void)
CBuffer Buffer;
CIp Ip;
CCallsign Callsign;
CDvHeaderPacket *Header;
CDvFramePacket *Frame;
CDvLastFramePacket *LastFrame;
std::unique_ptr<CDvHeaderPacket> Header;
std::unique_ptr<CDvFramePacket> Frame;
std::unique_ptr<CDvLastFramePacket> LastFrame;
// handle incoming packets
#if DSTAR_IPV6==true
@ -73,33 +73,21 @@ void CDplusProtocol::Task(void)
#endif
{
// crack the packet
if ( (Frame = IsValidDvFramePacket(Buffer)) != nullptr )
if ( IsValidDvFramePacket(Buffer, Frame) )
{
//std::cout << "DPlus DV frame" << std::endl;
// handle it
OnDvFramePacketIn(Frame, &Ip);
}
else if ( (Header = IsValidDvHeaderPacket(Buffer)) != nullptr )
else if ( IsValidDvHeaderPacket(Buffer, Header) )
{
//std::cout << "DPlus DV header:" << std::endl << *Header << std::endl;
// callsign muted?
// is muted?
if ( g_GateKeeper.MayTransmit(Header->GetMyCallsign(), Ip, PROTOCOL_DPLUS, Header->GetRpt2Module()) )
{
// handle it
OnDvHeaderPacketIn(Header, Ip);
}
else
{
delete Header;
}
}
else if ( (LastFrame = IsValidDvLastFramePacket(Buffer)) != nullptr )
else if ( IsValidDvLastFramePacket(Buffer, LastFrame) )
{
//std::cout << "DPlus DV last frame" << std::endl;
// handle it
OnDvLastFramePacketIn(LastFrame, &Ip);
}
else if ( IsValidConnectPacket(Buffer) )
@ -189,10 +177,8 @@ void CDplusProtocol::Task(void)
////////////////////////////////////////////////////////////////////////////////////////
// streams helpers
bool CDplusProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
void CDplusProtocol::OnDvHeaderPacketIn(std::unique_ptr<CDvHeaderPacket> &Header, const CIp &Ip)
{
bool newstream = false;
// find the stream
CPacketStream *stream = GetStream(Header->GetStreamId());
if ( stream == nullptr )
@ -224,7 +210,6 @@ bool CDplusProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
{
// keep the handle
m_Streams.push_back(stream);
newstream = true;
}
}
// release
@ -233,12 +218,6 @@ bool CDplusProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
// update last heard
g_Reflector.GetUsers()->Hearing(Header->GetMyCallsign(), via, Header->GetRpt2Callsign());
g_Reflector.ReleaseUsers();
// delete header if needed
if ( !newstream )
{
delete Header;
}
}
else
{
@ -250,12 +229,7 @@ bool CDplusProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
// stream already open
// skip packet, but tickle the stream
stream->Tickle();
// and delete packet
delete Header;
}
// done
return newstream;
}
////////////////////////////////////////////////////////////////////////////////////////
@ -267,7 +241,7 @@ void CDplusProtocol::HandleQueue(void)
while ( !m_Queue.empty() )
{
// get the packet
CPacket *packet = m_Queue.front();
auto packet = m_Queue.front();
m_Queue.pop();
// get our sender's id
@ -302,7 +276,7 @@ void CDplusProtocol::HandleQueue(void)
if ( packet->IsDvHeader() )
{
// sending header in Dplus is client specific
SendDvHeader((CDvHeaderPacket *)packet, (CDplusClient *)client.get());
SendDvHeader((CDvHeaderPacket *)packet.get(), (CDplusClient *)client.get());
}
else if ( packet->IsDvFrame() )
{
@ -327,10 +301,6 @@ void CDplusProtocol::HandleQueue(void)
}
g_Reflector.ReleaseClients();
}
// done
delete packet;
}
m_Queue.Unlock();
}
@ -447,70 +417,43 @@ bool CDplusProtocol::IsValidKeepAlivePacket(const CBuffer &Buffer)
return (Buffer == CBuffer(tag, sizeof(tag)));
}
CDvHeaderPacket *CDplusProtocol::IsValidDvHeaderPacket(const CBuffer &Buffer)
bool CDplusProtocol::IsValidDvHeaderPacket(const CBuffer &Buffer, std::unique_ptr<CDvHeaderPacket> &header)
{
CDvHeaderPacket *header = nullptr;
if ( (Buffer.size() == 58) &&
(Buffer.data()[0] == 0x3A) && (Buffer.data()[1] == 0x80) &&
(Buffer.Compare((uint8 *)"DSVT", 2, 4) == 0) &&
(Buffer.data()[6] == 0x10) && (Buffer.data()[10] == 0x20) )
if ( 58==Buffer.size() && 0x3AU==Buffer.data()[0] && 0x80U==Buffer.data()[1] && 0==Buffer.Compare((uint8 *)"DSVT", 2, 4) && 0x10U==Buffer.data()[6] && 0x20U==Buffer.data()[10] )
{
// create packet
header = new CDvHeaderPacket((struct dstar_header *)&(Buffer.data()[17]),
*((uint16 *)&(Buffer.data()[14])), 0x80);
header = std::unique_ptr<CDvHeaderPacket>(new CDvHeaderPacket((struct dstar_header *)&(Buffer.data()[17]), *((uint16 *)&(Buffer.data()[14])), 0x80));
// check validity of packet
if ( !header->IsValid() )
{
delete header;
header = nullptr;
}
if ( header && header->IsValid() )
return true;
}
return header;
return false;
}
CDvFramePacket *CDplusProtocol::IsValidDvFramePacket(const CBuffer &Buffer)
bool CDplusProtocol::IsValidDvFramePacket(const CBuffer &Buffer, std::unique_ptr<CDvFramePacket> &dvframe)
{
CDvFramePacket *dvframe = nullptr;
if ( (Buffer.size() == 29) &&
(Buffer.data()[0] == 0x1D) && (Buffer.data()[1] == 0x80) &&
(Buffer.Compare((uint8 *)"DSVT", 2, 4) == 0) &&
(Buffer.data()[6] == 0x20) && (Buffer.data()[10] == 0x20) )
if ( 29==Buffer.size() && 0x1DU==Buffer.data()[0] && 0x80U==Buffer.data()[1] && 0==Buffer.Compare((uint8 *)"DSVT", 2, 4) && 0x20U==Buffer.data()[6] && 0x20U==Buffer.data()[10] )
{
// create packet
dvframe = new CDvFramePacket((struct dstar_dvframe *)&(Buffer.data()[17]),
*((uint16 *)&(Buffer.data()[14])), Buffer.data()[16]);
dvframe = std::unique_ptr<CDvFramePacket>(new CDvFramePacket((struct dstar_dvframe *)&(Buffer.data()[17]), *((uint16 *)&(Buffer.data()[14])), Buffer.data()[16]));
// check validity of packet
if ( !dvframe->IsValid() )
{
delete dvframe;
dvframe = nullptr;
}
if ( dvframe && dvframe->IsValid() )
return true;
}
return dvframe;
return false;
}
CDvLastFramePacket *CDplusProtocol::IsValidDvLastFramePacket(const CBuffer &Buffer)
bool CDplusProtocol::IsValidDvLastFramePacket(const CBuffer &Buffer, std::unique_ptr<CDvLastFramePacket> &dvframe)
{
CDvLastFramePacket *dvframe = nullptr;
if ( (Buffer.size() == 32) &&
(Buffer.Compare((uint8 *)"DSVT", 2, 4) == 0) &&
(Buffer.data()[0] == 0x20) && (Buffer.data()[1] == 0x80) &&
(Buffer.data()[6] == 0x20) && (Buffer.data()[10] == 0x20) )
if ( 32==Buffer.size() && 0==Buffer.Compare((uint8 *)"DSVT", 2, 4) && 0x20U==Buffer.data()[0] && 0x80U==Buffer.data()[1] && 0x20U==Buffer.data()[6] && 0x20U==Buffer.data()[10] )
{
// create packet
dvframe = new CDvLastFramePacket((struct dstar_dvframe *)&(Buffer.data()[17]),
*((uint16 *)&(Buffer.data()[14])), Buffer.data()[16]);
dvframe = std::unique_ptr<CDvLastFramePacket>(new CDvLastFramePacket((struct dstar_dvframe *)&(Buffer.data()[17]), *((uint16 *)&(Buffer.data()[14])), Buffer.data()[16]));
// check validity of packet
if ( !dvframe->IsValid() )
{
delete dvframe;
dvframe = nullptr;
}
if ( dvframe && dvframe->IsValid() )
return true;
}
return dvframe;
return false;
}

@ -66,16 +66,16 @@ protected:
void HandleKeepalives(void);
// stream helpers
bool OnDvHeaderPacketIn(CDvHeaderPacket *, const CIp &);
void OnDvHeaderPacketIn(std::unique_ptr<CDvHeaderPacket> &, const CIp &);
// packet decoding helpers
bool IsValidConnectPacket(const CBuffer &);
bool IsValidLoginPacket(const CBuffer &, CCallsign *);
bool IsValidDisconnectPacket(const CBuffer &);
bool IsValidKeepAlivePacket(const CBuffer &);
CDvHeaderPacket *IsValidDvHeaderPacket(const CBuffer &);
CDvFramePacket *IsValidDvFramePacket(const CBuffer &);
CDvLastFramePacket *IsValidDvLastFramePacket(const CBuffer &);
bool IsValidDvHeaderPacket(const CBuffer &, std::unique_ptr<CDvHeaderPacket> &);
bool IsValidDvFramePacket(const CBuffer &, std::unique_ptr<CDvFramePacket> &);
bool IsValidDvLastFramePacket(const CBuffer &, std::unique_ptr<CDvLastFramePacket> &);
// packet encoding helpers
void EncodeKeepAlivePacket(CBuffer *);

@ -95,9 +95,9 @@ CDvFramePacket::CDvFramePacket
////////////////////////////////////////////////////////////////////////////////////////
// virtual duplication
CPacket *CDvFramePacket::Duplicate(void) const
std::unique_ptr<CPacket> CDvFramePacket::Duplicate(void) const
{
return new CDvFramePacket(*this);
return std::unique_ptr<CPacket>(new CDvFramePacket(*this));
}
////////////////////////////////////////////////////////////////////////////////////////

@ -61,7 +61,7 @@ public:
#endif
// virtual duplication
CPacket *Duplicate(void) const;
std::unique_ptr<CPacket> Duplicate(void) const;
// identity
bool IsDvFrame(void) const { return true; }

@ -90,9 +90,9 @@ CDvHeaderPacket::CDvHeaderPacket(const CCallsign &my, const CCallsign &ur, const
////////////////////////////////////////////////////////////////////////////////////////
// virtual duplication
CPacket *CDvHeaderPacket::Duplicate(void) const
std::unique_ptr<CPacket> CDvHeaderPacket::Duplicate(void) const
{
return new CDvHeaderPacket(*this);
return std::unique_ptr<CPacket>(new CDvHeaderPacket(*this));
}
////////////////////////////////////////////////////////////////////////////////////////

@ -68,7 +68,7 @@ public:
#endif
// virtual duplication
CPacket *Duplicate(void) const;
std::unique_ptr<CPacket> Duplicate(void) const;
// identity
bool IsDvHeader(void) const { return true; }

@ -77,7 +77,7 @@ CDvLastFramePacket::CDvLastFramePacket(const CDvLastFramePacket &DvFrame)
////////////////////////////////////////////////////////////////////////////////////////
// virtual duplication
CPacket *CDvLastFramePacket::Duplicate(void) const
std::unique_ptr<CPacket> CDvLastFramePacket::Duplicate(void) const
{
return new CDvLastFramePacket(*this);
return std::unique_ptr<CPacket>(new CDvLastFramePacket(*this));
}

@ -49,7 +49,7 @@ public:
CDvLastFramePacket(const CDvLastFramePacket &);
// virtual duplication
CPacket *Duplicate(void) const;
std::unique_ptr<CPacket> Duplicate(void) const;
// identity
bool IsLastPacket(void) const { return true; }

@ -377,9 +377,9 @@ void CG3Protocol::Task(void)
CCallsign Callsign;
char ToLinkModule;
int ProtRev;
CDvHeaderPacket *Header;
CDvFramePacket *Frame;
CDvLastFramePacket *LastFrame;
std::unique_ptr<CDvHeaderPacket> Header;
std::unique_ptr<CDvFramePacket> Frame;
std::unique_ptr<CDvLastFramePacket> LastFrame;
// any incoming packet ?
if ( m_Socket4.Receive(Buffer, Ip, 20) )
@ -407,44 +407,23 @@ void CG3Protocol::Task(void)
if (BaseIp != nullptr)
{
// crack the packet
if ( (Frame = IsValidDvFramePacket(Buffer)) != nullptr )
if ( IsValidDvFramePacket(Buffer, Frame) )
{
//std::cout << "Terminal DV frame" << std::endl;
// handle it
OnDvFramePacketIn(Frame, BaseIp);
}
else if ( (Header = IsValidDvHeaderPacket(Buffer)) != nullptr )
else if ( IsValidDvHeaderPacket(Buffer, Header) )
{
//std::cout << "Terminal DV header" << std::endl;
// callsign muted?
if ( g_GateKeeper.MayTransmit(Header->GetMyCallsign(), Ip, PROTOCOL_G3, Header->GetRpt2Module()) )
{
// handle it
OnDvHeaderPacketIn(Header, *BaseIp);
}
else
{
delete Header;
}
}
else if ( (LastFrame = IsValidDvLastFramePacket(Buffer)) != nullptr )
else if ( IsValidDvLastFramePacket(Buffer, LastFrame) )
{
//std::cout << "Terminal DV last frame" << std::endl;
// handle it
OnDvLastFramePacketIn(LastFrame, BaseIp);
}
else
{
//std::cout << "Invalid terminal packet (" << Buffer.size() << ")" << std::endl;
//std::cout << Buffer.data() << std::endl;
}
}
else
{
//std::cout << "Invalid client " << Ip << std::endl;
}
}
@ -480,7 +459,7 @@ void CG3Protocol::HandleQueue(void)
m_LastKeepaliveTime.Now();
// get the packet
CPacket *packet = m_Queue.front();
auto packet = m_Queue.front();
m_Queue.pop();
// encode it
@ -506,9 +485,6 @@ void CG3Protocol::HandleQueue(void)
}
g_Reflector.ReleaseClients();
}
// done
delete packet;
}
m_Queue.Unlock();
}
@ -545,10 +521,8 @@ void CG3Protocol::HandleKeepalives(void)
////////////////////////////////////////////////////////////////////////////////////////
// streams helpers
bool CG3Protocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
void CG3Protocol::OnDvHeaderPacketIn(std::unique_ptr<CDvHeaderPacket> &Header, const CIp &Ip)
{
bool newstream = false;
// find the stream
CPacketStream *stream = GetStream(Header->GetStreamId(), &Ip);
@ -585,10 +559,8 @@ bool CG3Protocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
}
else
{
// drop if invalid module
delete Header;
g_Reflector.ReleaseClients();
return false;
return;
}
}
@ -600,24 +572,11 @@ bool CG3Protocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
{
// keep the handle
m_Streams.push_back(stream);
newstream = true;
}
// update last heard
g_Reflector.GetUsers()->Hearing(Header->GetMyCallsign(), via, Header->GetRpt2Callsign());
g_Reflector.ReleaseUsers();
// delete header if needed
if ( !newstream )
{
delete Header;
}
}
else
{
// drop
delete Header;
}
}
// release
@ -628,120 +587,92 @@ bool CG3Protocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
// stream already open
// skip packet, but tickle the stream
stream->Tickle();
// and delete packet
delete Header;
}
// done
return newstream;
}
////////////////////////////////////////////////////////////////////////////////////////
// packet decoding helpers
CDvHeaderPacket *CG3Protocol::IsValidDvHeaderPacket(const CBuffer &Buffer)
bool CG3Protocol::IsValidDvHeaderPacket(const CBuffer &Buffer, std::unique_ptr<CDvHeaderPacket> &header)
{
CDvHeaderPacket *header = nullptr;
if ( (Buffer.size() == 56) && (Buffer.Compare((uint8 *)"DSVT", 4) == 0) &&
(Buffer.data()[4] == 0x10) && (Buffer.data()[8] == 0x20) )
if ( 56==Buffer.size() && 0==Buffer.Compare((uint8 *)"DSVT", 4) && 0x10U==Buffer.data()[4] && 0x20U==Buffer.data()[8] )
{
// create packet
header = new CDvHeaderPacket((struct dstar_header *)&(Buffer.data()[15]),
*((uint16 *)&(Buffer.data()[12])), 0x80);
header = std::unique_ptr<CDvHeaderPacket>(new CDvHeaderPacket((struct dstar_header *)&(Buffer.data()[15]), *((uint16 *)&(Buffer.data()[12])), 0x80));
// check validity of packet
if ( !header->IsValid() )
{
delete header;
header = nullptr;
}
if ( header && header->IsValid() )
return true;
}
return header;
return false;
}
CDvFramePacket *CG3Protocol::IsValidDvFramePacket(const CBuffer &Buffer)
bool CG3Protocol::IsValidDvFramePacket(const CBuffer &Buffer, std::unique_ptr<CDvFramePacket> &dvframe)
{
CDvFramePacket *dvframe = nullptr;
if ( (Buffer.size() == 27) && (Buffer.Compare((uint8 *)"DSVT", 4) == 0) &&
(Buffer.data()[4] == 0x20) && (Buffer.data()[8] == 0x20) &&
((Buffer.data()[14] & 0x40) == 0) )
if ( 27==Buffer.size() && 0==Buffer.Compare((uint8 *)"DSVT", 4) && 0x20U==Buffer.data()[4] && 0x20U==Buffer.data()[8] && 0U==(Buffer.data()[14] & 0x40U) )
{
// create packet
dvframe = new CDvFramePacket((struct dstar_dvframe *)&(Buffer.data()[15]),
*((uint16 *)&(Buffer.data()[12])), Buffer.data()[14]);
dvframe = std::unique_ptr<CDvFramePacket>(new CDvFramePacket((struct dstar_dvframe *)&(Buffer.data()[15]), *((uint16 *)&(Buffer.data()[12])), Buffer.data()[14]));
// check validity of packet
if ( !dvframe->IsValid() )
{
delete dvframe;
dvframe = nullptr;
}
if ( dvframe && dvframe->IsValid() )
return true;
}
return dvframe;
return false;
}
CDvLastFramePacket *CG3Protocol::IsValidDvLastFramePacket(const CBuffer &Buffer)
bool CG3Protocol::IsValidDvLastFramePacket(const CBuffer &Buffer, std::unique_ptr<CDvLastFramePacket> &dvframe)
{
CDvLastFramePacket *dvframe = nullptr;
if ( (Buffer.size() == 27) && (Buffer.Compare((uint8 *)"DSVT", 4) == 0) &&
(Buffer.data()[4] == 0x20) && (Buffer.data()[8] == 0x20) &&
((Buffer.data()[14] & 0x40) != 0) )
if ( 27==Buffer.size() && 0==Buffer.Compare((uint8 *)"DSVT", 4) && 0x20U==Buffer.data()[4] && 0x20U==Buffer.data()[8] && (Buffer.data()[14] & 0x40U) )
{
// create packet
dvframe = new CDvLastFramePacket((struct dstar_dvframe *)&(Buffer.data()[15]),
*((uint16 *)&(Buffer.data()[12])), Buffer.data()[14]);
dvframe = std::unique_ptr<CDvLastFramePacket>(new CDvLastFramePacket((struct dstar_dvframe *)&(Buffer.data()[15]), *((uint16 *)&(Buffer.data()[12])), Buffer.data()[14]));
// check validity of packet
if ( !dvframe->IsValid() )
{
delete dvframe;
dvframe = nullptr;
}
if ( dvframe && dvframe->IsValid() )
return true;
}
return dvframe;
return false;
}
////////////////////////////////////////////////////////////////////////////////////////
// packet encoding helpers
bool CG3Protocol::EncodeDvHeaderPacket(const CDvHeaderPacket &Packet, CBuffer *Buffer) const
bool CG3Protocol::EncodeDvHeaderPacket(const std::unique_ptr<CDvHeaderPacket> &Packet, CBuffer *Buffer) const
{
uint8 tag[] = { 'D','S','V','T',0x10,0x00,0x00,0x00,0x20,0x00,0x01,0x02 };
struct dstar_header DstarHeader;
Packet.ConvertToDstarStruct(&DstarHeader);
Packet->ConvertToDstarStruct(&DstarHeader);
Buffer->Set(tag, sizeof(tag));
Buffer->Append(Packet.GetStreamId());
Buffer->Append(Packet->GetStreamId());
Buffer->Append((uint8)0x80);
Buffer->Append((uint8 *)&DstarHeader, sizeof(struct dstar_header));
return true;
}
bool CG3Protocol::EncodeDvFramePacket(const CDvFramePacket &Packet, CBuffer *Buffer) const
bool CG3Protocol::EncodeDvFramePacket(const std::unique_ptr<CDvFramePacket> &Packet, CBuffer *Buffer) const
{
uint8 tag[] = { 'D','S','V','T',0x20,0x00,0x00,0x00,0x20,0x00,0x01,0x02 };
Buffer->Set(tag, sizeof(tag));
Buffer->Append(Packet.GetStreamId());
Buffer->Append((uint8)(Packet.GetPacketId() % 21));
Buffer->Append((uint8 *)Packet.GetAmbe(), AMBE_SIZE);
Buffer->Append((uint8 *)Packet.GetDvData(), DVDATA_SIZE);
Buffer->Append(Packet->GetStreamId());
Buffer->Append((uint8)(Packet->GetPacketId() % 21));
Buffer->Append((uint8 *)Packet->GetAmbe(), AMBE_SIZE);
Buffer->Append((uint8 *)Packet->GetDvData(), DVDATA_SIZE);
return true;
}
bool CG3Protocol::EncodeDvLastFramePacket(const CDvLastFramePacket &Packet, CBuffer *Buffer) const
bool CG3Protocol::EncodeDvLastFramePacket(const std::unique_ptr<CDvLastFramePacket> &Packet, CBuffer *Buffer) const
{
uint8 tag1[] = { 'D','S','V','T',0x20,0x00,0x00,0x00,0x20,0x00,0x01,0x02 };
uint8 tag2[] = { 0x55,0xC8,0x7A,0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x1A,0xC6 };
Buffer->Set(tag1, sizeof(tag1));
Buffer->Append(Packet.GetStreamId());
Buffer->Append((uint8)((Packet.GetPacketId() % 21) | 0x40));
Buffer->Append(Packet->GetStreamId());
Buffer->Append((uint8)((Packet->GetPacketId() % 21) | 0x40));
Buffer->Append(tag2, sizeof(tag2));
return true;

@ -100,22 +100,20 @@ protected:
void HandleKeepalives(void);
// stream helpers
bool OnDvHeaderPacketIn(CDvHeaderPacket *, const CIp &);
void OnDvHeaderPacketIn(std::unique_ptr<CDvHeaderPacket> &, const CIp &);
// packet decoding helpers
CDvHeaderPacket *IsValidDvHeaderPacket(const CBuffer &);
CDvFramePacket *IsValidDvFramePacket(const CBuffer &);
CDvLastFramePacket *IsValidDvLastFramePacket(const CBuffer &);
bool IsValidDvHeaderPacket(const CBuffer &, std::unique_ptr<CDvHeaderPacket> &);
bool IsValidDvFramePacket(const CBuffer &, std::unique_ptr<CDvFramePacket> &);
bool IsValidDvLastFramePacket(const CBuffer &, std::unique_ptr<CDvLastFramePacket> &);
// packet encoding helpers
bool EncodeDvHeaderPacket(const CDvHeaderPacket &, CBuffer *) const;
bool EncodeDvFramePacket(const CDvFramePacket &, CBuffer *) const;
bool EncodeDvLastFramePacket(const CDvLastFramePacket &, CBuffer *) const;
bool EncodeDvHeaderPacket(const std::unique_ptr<CDvHeaderPacket> &, CBuffer *) const;
bool EncodeDvFramePacket(const std::unique_ptr<CDvFramePacket> &, CBuffer *) const;
bool EncodeDvLastFramePacket(const std::unique_ptr<CDvLastFramePacket> &, CBuffer *) const;
protected:
std::future<void> m_PresenceFuture;
std::future<void> m_ConfigFuture;
std::future<void> m_IcmpFuture;
std::future<void> m_PresenceFuture, m_ConfigFuture, m_IcmpFuture;
// time
CTimePoint m_LastKeepaliveTime;

@ -49,7 +49,7 @@ public:
virtual ~CPacket() {}
// virtual duplication
virtual CPacket *Duplicate(void) const = 0;
virtual std::unique_ptr<CPacket> Duplicate(void) const = 0;
// identity
virtual bool IsDvHeader(void) const { return false; }

@ -39,30 +39,18 @@ class CClient;
class CPacketQueue
{
public:
// constructor
CPacketQueue() {}
// destructor
~CPacketQueue()
{
Lock();
while (! queue.empty())
{
delete queue.front();
queue.pop();
}
Unlock();
}
virtual ~CPacketQueue() {}
// lock
void Lock() { m_Mutex.lock(); }
void Unlock() { m_Mutex.unlock(); }
// pass thru
CPacket *front() { return queue.front(); }
void pop() { queue.pop(); }
void push(CPacket *packet) { queue.push(packet); }
bool empty() const { return queue.empty(); }
std::unique_ptr<CPacket> front() { return std::move(queue.front()); }
void push(std::unique_ptr<CPacket> &packet) { queue.push(std::move(packet)); }
protected:
// status
@ -72,7 +60,7 @@ protected:
// owner
CClient *m_Client;
std::queue<CPacket *> queue;
std::queue<std::unique_ptr<CPacket>> queue;
};
////////////////////////////////////////////////////////////////////////////////////////

@ -82,7 +82,7 @@ void CPacketStream::Close(void)
////////////////////////////////////////////////////////////////////////////////////////
// push & pop
void CPacketStream::Push(CPacket *Packet)
void CPacketStream::Push(std::unique_ptr<CPacket> Packet)
{
// update stream dependent packet data
m_LastPacketTime.Now();

@ -44,15 +44,12 @@ public:
// constructor
CPacketStream();
// destructor
virtual ~CPacketStream() {}
// open / close
bool Open(const CDvHeaderPacket &, std::shared_ptr<CClient>);
void Close(void);
// push & pop
void Push(CPacket *);
void Push(std::unique_ptr<CPacket> packet);
void Tickle(void) { m_LastPacketTime.Now(); }
bool IsEmpty(void) const;

@ -162,39 +162,37 @@ bool CProtocol::EncodeDvPacket(const CPacket &packet, CBuffer *buffer) const
////////////////////////////////////////////////////////////////////////////////////////
// streams helpers
void CProtocol::OnDvFramePacketIn(CDvFramePacket *Frame, const CIp *Ip)
void CProtocol::OnDvFramePacketIn(std::unique_ptr<CDvFramePacket> &Frame, const CIp *Ip)
{
// find the stream
CPacketStream *stream = GetStream(Frame->GetStreamId(), Ip);
if ( stream == nullptr )
{
std::cout << "Deleting orphaned Frame with ID " << Frame->GetStreamId() << " on " << *Ip << std::endl;
delete Frame;
std::cout << "Orphaned Frame with ID " << Frame->GetStreamId() << " on " << *Ip << std::endl;
}
else
{
//std::cout << "DV frame" << "from " << *Ip << std::endl;
// and push
stream->Lock();
stream->Push(Frame);
stream->Push(std::move(Frame));
stream->Unlock();
}
}
void CProtocol::OnDvLastFramePacketIn(CDvLastFramePacket *Frame, const CIp *Ip)
void CProtocol::OnDvLastFramePacketIn(std::unique_ptr<CDvLastFramePacket> &Frame, const CIp *Ip)
{
// find the stream
CPacketStream *stream = GetStream(Frame->GetStreamId(), Ip);
if ( stream == nullptr )
{
std::cout << "Deleting orphaned Last Frame with ID " << Frame->GetStreamId() << " on " << *Ip << std::endl;
delete Frame;
std::cout << "Orphaned Last Frame with ID " << Frame->GetStreamId() << " on " << *Ip << std::endl;
}
else
{
// push
stream->Lock();
stream->Push(Frame);
stream->Push(std::move(Frame));
stream->Unlock();
// and close the stream
@ -246,21 +244,6 @@ void CProtocol::CheckStreamsTimeout(void)
}
}
////////////////////////////////////////////////////////////////////////////////////////
// queue helper
void CProtocol::HandleQueue(void)
{
// the default protocol just keep queue empty
m_Queue.Lock();
while ( !m_Queue.empty() )
{
delete m_Queue.front();
m_Queue.pop();
}
m_Queue.Unlock();
}
////////////////////////////////////////////////////////////////////////////////////////
// syntax helper

@ -99,19 +99,19 @@ protected:
virtual bool EncodeDvLastFramePacket(const CDvLastFramePacket &, CBuffer *) const { return false; }
// stream helpers
virtual bool OnDvHeaderPacketIn(CDvHeaderPacket *, const CIp &) { return false; }
virtual void OnDvFramePacketIn(CDvFramePacket *, const CIp * = nullptr);
virtual void OnDvLastFramePacketIn(CDvLastFramePacket *, const CIp * = nullptr);
virtual void OnDvHeaderPacketIn(std::unique_ptr<CDvHeaderPacket> &, const CIp &) {}
virtual void OnDvFramePacketIn(std::unique_ptr<CDvFramePacket> &, const CIp * = nullptr);
virtual void OnDvLastFramePacketIn(std::unique_ptr<CDvLastFramePacket> &, const CIp * = nullptr);
// stream handle helpers
CPacketStream *GetStream(uint16, const CIp * = nullptr);
void CheckStreamsTimeout(void);
// queue helper
virtual void HandleQueue(void);
virtual void HandleQueue(void) = 0;
// keepalive helpers
virtual void HandleKeepalives(void) {}
virtual void HandleKeepalives(void) = 0;
// syntax helper
bool IsNumber(char) const;

@ -178,29 +178,31 @@ bool CReflector::IsStreaming(char module)
return false;
}
CPacketStream *CReflector::OpenStream(CDvHeaderPacket *DvHeader, std::shared_ptr<CClient>client)
// clients MUST have bee locked by the caller so we can freely access it within the fuction
CPacketStream *CReflector::OpenStream(std::unique_ptr<CDvHeaderPacket> &DvHeader, std::shared_ptr<CClient>client)
{
CPacketStream *retStream = nullptr;
// clients MUST have bee locked by the caller
// so we can freely access it within the fuction
// check sid is not zero
if ( 0U == DvHeader->GetStreamId() )
return nullptr;
// check sid is not nullptr
if ( DvHeader->GetStreamId() != 0 )
{
// check if client is valid candidate
if ( m_Clients.IsClient(client) && !client->IsAMaster() )
{
if ( ! m_Clients.IsClient(client) || client->IsAMaster() )
return nullptr;
// check if no stream with same streamid already open
// to prevent loops
if ( !IsStreamOpen(DvHeader) )
if ( IsStreamOpen(DvHeader) )
{
std::cerr << "Detected stream loop on module " << DvHeader->GetRpt2Module() << " for client " << client->GetCallsign() << " with sid " << DvHeader->GetStreamId() << std::endl;
return nullptr;
}
// get the module's queue
char module = DvHeader->GetRpt2Module();
CPacketStream *stream = GetStream(module);
if ( stream != nullptr )
{
// lock it
if ( stream = nullptr )
return nullptr;
stream->Lock();
// is it available ?
if ( stream->Open(*DvHeader, client) )
@ -211,10 +213,9 @@ CPacketStream *CReflector::OpenStream(CDvHeaderPacket *DvHeader, std::shared_ptr
// update last heard time
client->Heard();
retStream = stream;
// and push header packet
stream->Push(DvHeader);
stream->Push(std::move(DvHeader));
// report
std::cout << "Opening stream on module " << module << " for client " << client->GetCallsign() << " with sid " << DvHeader->GetStreamId() << " by user " << DvHeader->GetMyCallsign() << std::endl;
@ -223,20 +224,8 @@ CPacketStream *CReflector::OpenStream(CDvHeaderPacket *DvHeader, std::shared_ptr
g_Reflector.OnStreamOpen(stream->GetUserCallsign());
}
// unlock now
stream->Unlock();
}
}
else
{
// report
std::cerr << "Detected stream loop on module " << DvHeader->GetRpt2Module() << " for client " << client->GetCallsign() << " with sid " << DvHeader->GetStreamId() << std::endl;
}
}
}
// done
return retStream;
return stream;
}
void CReflector::CloseStream(CPacketStream *stream)
@ -296,7 +285,7 @@ void CReflector::RouterThread(CPacketStream *streamIn)
uint8 uiModuleId = GetStreamModule(streamIn);
// get on input queue
CPacket *packet;
std::unique_ptr<CPacket> packet;
while (keep_running)
{
@ -325,7 +314,7 @@ void CReflector::RouterThread(CPacketStream *streamIn)
for ( auto it=m_Protocols.begin(); it!=m_Protocols.end(); it++ )
{
// duplicate packet
CPacket *packetClone = packet->Duplicate();
auto packetClone = packet->Duplicate();
// if packet is header, update RPT2 according to protocol
if ( packetClone->IsDvHeader() )
@ -333,7 +322,7 @@ void CReflector::RouterThread(CPacketStream *streamIn)
// get our callsign
CCallsign csRPT = (*it)->GetReflectorCallsign();
csRPT.SetModule(GetStreamModule(streamIn));
((CDvHeaderPacket *)packetClone)->SetRpt2Callsign(csRPT);
(dynamic_cast<CDvHeaderPacket *>(packetClone.get()))->SetRpt2Callsign(csRPT);
}
// and push it
@ -342,13 +331,9 @@ void CReflector::RouterThread(CPacketStream *streamIn)
(*it)->ReleaseQueue();
}
m_Protocols.Unlock();
// done
delete packet;
packet = nullptr;
}
else
{
// wait a bit
CTimePoint::TaskSleepFor(10);
}
}
@ -550,7 +535,7 @@ CPacketStream *CReflector::GetStream(char module)
return nullptr;
}
bool CReflector::IsStreamOpen(const CDvHeaderPacket *DvHeader)
bool CReflector::IsStreamOpen(const std::unique_ptr<CDvHeaderPacket> &DvHeader)
{
for ( unsigned i = 0; i < m_Stream.size(); i++ )
{

@ -87,7 +87,7 @@ public:
void ReleasePeers(void) { m_Peers.Unlock(); }
// stream opening & closing
CPacketStream *OpenStream(CDvHeaderPacket *, std::shared_ptr<CClient>);
CPacketStream *OpenStream(std::unique_ptr<CDvHeaderPacket> &, std::shared_ptr<CClient>);
bool IsStreaming(char);
void CloseStream(CPacketStream *);
@ -117,7 +117,7 @@ protected:
// streams
CPacketStream *GetStream(char);
bool IsStreamOpen(const CDvHeaderPacket *);
bool IsStreamOpen(const std::unique_ptr<CDvHeaderPacket> &);
char GetStreamModule(CPacketStream *);
// xml helpers

@ -58,9 +58,9 @@ void CXlxProtocol::Task(void)
CCallsign Callsign;
char Modules[27];
CVersion Version;
CDvHeaderPacket *Header;
CDvFramePacket *Frame;
CDvLastFramePacket *LastFrame;
std::unique_ptr<CDvHeaderPacket> Header;
std::unique_ptr<CDvFramePacket> Frame;
std::unique_ptr<CDvLastFramePacket> LastFrame;
// any incoming packet ?
#if XLX_IPV6==true
@ -74,42 +74,25 @@ void CXlxProtocol::Task(void)
#endif
{
// crack the packet
if ( (Frame = IsValidDvFramePacket(Buffer)) != nullptr )
if ( IsValidDvFramePacket(Buffer, Frame) )
{
//std::cout << "XLX (DExtra) DV frame" << std::endl;
// handle it
OnDvFramePacketIn(Frame, &Ip);
}
else if ( (Header = IsValidDvHeaderPacket(Buffer)) != nullptr )
else if ( IsValidDvHeaderPacket(Buffer, Header) )
{
//std::cout << "XLX (DExtra) DV header:" << std::endl << *Header << std::endl;
//std::cout << "XLX (DExtra) DV header on module " << Header->GetRpt2Module() << std::endl;
// callsign muted?
// callsign allowed?
if ( g_GateKeeper.MayTransmit(Header->GetMyCallsign(), Ip) )
{
// handle it
OnDvHeaderPacketIn(Header, Ip);
}
else
{
delete Header;
}
}
else if ( (LastFrame = IsValidDvLastFramePacket(Buffer)) != nullptr )
else if ( IsValidDvLastFramePacket(Buffer, LastFrame) )
{
//std::cout << "XLX (DExtra) DV last frame" << std::endl;
// handle it
OnDvLastFramePacketIn(LastFrame, &Ip);
}
else if ( IsValidConnectPacket(Buffer, &Callsign, Modules, &Version) )
{
std::cout << "XLX ("
<< Version.GetMajor() << "." << Version.GetMinor() << "." << Version.GetRevision()
<< ") connect packet for modules " << Modules
<< " from " << Callsign << " at " << Ip << std::endl;
std::cout << "XLX (" << Version.GetMajor() << "." << Version.GetMinor() << "." << Version.GetRevision() << ") connect packet for modules " << Modules << " from " << Callsign << " at " << Ip << std::endl;
// callsign authorized?
if ( g_GateKeeper.MayLink(Callsign, Ip, PROTOCOL_XLX, Modules) )
@ -246,7 +229,7 @@ void CXlxProtocol::HandleQueue(void)
while ( !m_Queue.empty() )
{
// get the packet
CPacket *packet = m_Queue.front();
auto packet = m_Queue.front();
m_Queue.pop();
// check if origin of packet is local
@ -301,9 +284,6 @@ void CXlxProtocol::HandleQueue(void)
g_Reflector.ReleaseClients();
}
}
// done
delete packet;
}
m_Queue.Unlock();
}
@ -404,9 +384,8 @@ void CXlxProtocol::HandlePeerLinks(void)
////////////////////////////////////////////////////////////////////////////////////////
// streams helpers
bool CXlxProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
void CXlxProtocol::OnDvHeaderPacketIn(std::unique_ptr<CDvHeaderPacket> &Header, const CIp &Ip)
{
bool newstream = false;
CCallsign peer;
// todo: verify Packet.GetModuleId() is in authorized list of XLX of origin
@ -429,7 +408,6 @@ bool CXlxProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
{
// keep the handle
m_Streams.push_back(stream);
newstream = true;
}
// get origin
peer = client->GetCallsign();
@ -447,18 +425,9 @@ bool CXlxProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
// update last heard
g_Reflector.GetUsers()->Hearing(Header->GetMyCallsign(), Header->GetRpt1Callsign(), Header->GetRpt2Callsign(), peer);
g_Reflector.ReleaseUsers();
// delete header if needed
if ( !newstream )
{
delete Header;
}
// done
return newstream;
}
void CXlxProtocol::OnDvFramePacketIn(CDvFramePacket *DvFrame, const CIp *Ip)
void CXlxProtocol::OnDvFramePacketIn(std::unique_ptr<CDvFramePacket> &DvFrame, const CIp *Ip)
{
// tag packet as remote peer origin
DvFrame->SetRemotePeerOrigin();
@ -467,7 +436,7 @@ void CXlxProtocol::OnDvFramePacketIn(CDvFramePacket *DvFrame, const CIp *Ip)
CDextraProtocol::OnDvFramePacketIn(DvFrame, Ip);
}
void CXlxProtocol::OnDvLastFramePacketIn(CDvLastFramePacket *DvFrame, const CIp *Ip)
void CXlxProtocol::OnDvLastFramePacketIn(std::unique_ptr<CDvLastFramePacket> &DvFrame, const CIp *Ip)
{
// tag packet as remote peer origin
DvFrame->SetRemotePeerOrigin();
@ -548,72 +517,54 @@ bool CXlxProtocol::IsValidNackPacket(const CBuffer &Buffer, CCallsign *callsign)
return valid;
}
CDvFramePacket *CXlxProtocol::IsValidDvFramePacket(const CBuffer &Buffer)
bool CXlxProtocol::IsValidDvFramePacket(const CBuffer &Buffer, std::unique_ptr<CDvFramePacket> &dvframe)
{
CDvFramePacket *dvframe = nullptr;
// base class first (protocol revision 1 and lower)
dvframe = CDextraProtocol::IsValidDvFramePacket(Buffer);
if (CDextraProtocol::IsValidDvFramePacket(Buffer, dvframe))
return true;
// otherwise try protocol revision 2
if ( (dvframe == nullptr) &&
(Buffer.size() == 45) && (Buffer.Compare((uint8 *)"DSVT", 4) == 0) &&
(Buffer.data()[4] == 0x20) && (Buffer.data()[8] == 0x20) &&
((Buffer.data()[14] & 0x40) == 0) )
if ( 45==Buffer.size() && 0==Buffer.Compare((uint8 *)"DSVT", 4) && 0x20U==Buffer.data()[4] && 0x20U==Buffer.data()[8] && 0==(Buffer.data()[14] & 0x40) )
{
// create packet
dvframe = new CDvFramePacket(
dvframe = std::unique_ptr<CDvFramePacket>(new CDvFramePacket(
// sid
*((uint16 *)&(Buffer.data()[12])),
// dstar
Buffer.data()[14], &(Buffer.data()[15]), &(Buffer.data()[24]),
// dmr
Buffer.data()[27], Buffer.data()[28], &(Buffer.data()[29]), &(Buffer.data()[38]));
Buffer.data()[27], Buffer.data()[28], &(Buffer.data()[29]), &(Buffer.data()[38])));
// check validity of packet
if ( !dvframe->IsValid() )
{
delete dvframe;
dvframe = nullptr;
}
if ( dvframe && dvframe->IsValid() )
return true;
}
// done
return dvframe;
return false;
}
CDvLastFramePacket *CXlxProtocol::IsValidDvLastFramePacket(const CBuffer &Buffer)
bool CXlxProtocol::IsValidDvLastFramePacket(const CBuffer &Buffer, std::unique_ptr<CDvLastFramePacket> &dvframe)
{
CDvLastFramePacket *dvframe = nullptr;
// base class first (protocol revision 1 and lower)
dvframe = CDextraProtocol::IsValidDvLastFramePacket(Buffer);
if (CDextraProtocol::IsValidDvLastFramePacket(Buffer, dvframe))
return true;
// otherwise try protocol revision 2
if ( (dvframe == nullptr) &&
(Buffer.size() == 45) && (Buffer.Compare((uint8 *)"DSVT", 4) == 0) &&
(Buffer.data()[4] == 0x20) && (Buffer.data()[8] == 0x20) &&
((Buffer.data()[14] & 0x40) != 0) )
if ( 45==Buffer.size() && 0==Buffer.Compare((uint8 *)"DSVT", 4) && 0x20U==Buffer.data()[4] && 0x20U==Buffer.data()[8] && (Buffer.data()[14] & 0x40U) )
{
// create packet
dvframe = new CDvLastFramePacket(
dvframe = std::unique_ptr<CDvLastFramePacket>(new CDvLastFramePacket(
// sid
*((uint16 *)&(Buffer.data()[12])),
// dstar
Buffer.data()[14], &(Buffer.data()[15]), &(Buffer.data()[24]),
// dmr
Buffer.data()[27], Buffer.data()[28], &(Buffer.data()[29]), &(Buffer.data()[38]));
Buffer.data()[27], Buffer.data()[28], &(Buffer.data()[29]), &(Buffer.data()[38])));
// check validity of packet
if ( !dvframe->IsValid() )
{
delete dvframe;
dvframe = nullptr;
}
if ( dvframe && dvframe->IsValid() )
return true;
}
// done
return dvframe;
return false;
}
////////////////////////////////////////////////////////////////////////////////////////

@ -55,9 +55,9 @@ protected:
void HandleKeepalives(void);
// stream helpers
bool OnDvHeaderPacketIn(CDvHeaderPacket *, const CIp &);
void OnDvFramePacketIn(CDvFramePacket *, const CIp * = nullptr);
void OnDvLastFramePacketIn(CDvLastFramePacket *, const CIp * = nullptr);
void OnDvHeaderPacketIn(std::unique_ptr<CDvHeaderPacket> &, const CIp &);
void OnDvFramePacketIn(std::unique_ptr<CDvFramePacket> &, const CIp * = nullptr);
void OnDvLastFramePacketIn(std::unique_ptr<CDvLastFramePacket> &, const CIp * = nullptr);
// packet decoding helpers
bool IsValidKeepAlivePacket(const CBuffer &, CCallsign *);
@ -65,8 +65,8 @@ protected:
bool IsValidDisconnectPacket(const CBuffer &, CCallsign *);
bool IsValidAckPacket(const CBuffer &, CCallsign *, char *, CVersion *);
bool IsValidNackPacket(const CBuffer &, CCallsign *);
CDvFramePacket *IsValidDvFramePacket(const CBuffer &);
CDvLastFramePacket *IsValidDvLastFramePacket(const CBuffer &);
bool IsValidDvFramePacket(const CBuffer &, std::unique_ptr<CDvFramePacket> &);
bool IsValidDvLastFramePacket(const CBuffer &, std::unique_ptr<CDvLastFramePacket> &);
// packet encoding helpers
void EncodeKeepAlivePacket(CBuffer *);

@ -76,16 +76,18 @@ void CYsfProtocol::Close(void)
void CYsfProtocol::Task(void)
{
int iWiresxCmd;
int iWiresxArg;
CBuffer Buffer;
CIp Ip;
CCallsign Callsign;
CYSFFICH Fich;
CDvHeaderPacket *Header;
CDvFramePacket *Frames[5];
CWiresxCmd WiresxCmd;
int iWiresxCmd;
int iWiresxArg;
std::unique_ptr<CDvHeaderPacket> Header;
std::array<std::unique_ptr<CDvFramePacket>, 5> Frames;
std::unique_ptr<CDvFramePacket> OneFrame;
std::unique_ptr<CDvLastFramePacket> LastFrame;
// handle outgoing packets
{
@ -114,23 +116,16 @@ void CYsfProtocol::Task(void)
// crack the packet
if ( IsValidDvPacket(Buffer, &Fich) )
{
//std::cout << "FN = " << (int)Fich.getFN() << " FT = " << (int)Fich.getFT() << std::endl;
if ( IsValidDvFramePacket(Ip, Fich, Buffer, Frames) )
{
//std::cout << "YSF DV frame" << std::endl;
// handle it
OnDvFramePacketIn(Frames[0], &Ip);
OnDvFramePacketIn(Frames[1], &Ip);
OnDvFramePacketIn(Frames[2], &Ip);
OnDvFramePacketIn(Frames[3], &Ip);
OnDvFramePacketIn(Frames[4], &Ip);
}
else if ( IsValidDvHeaderPacket(Ip, Fich, Buffer, &Header, Frames) )
else if ( IsValidDvHeaderPacket(Ip, Fich, Buffer, Header, Frames) )
{
//std::cout << "YSF DV header:" << std::endl << *Header << std::endl;
//std::cout << "YSF DV header:" << std::endl;
// node linked and callsign muted?
if ( g_GateKeeper.MayTransmit(Header->GetMyCallsign(), Ip, PROTOCOL_YSF, Header->GetRpt2Module()) )
{
@ -139,18 +134,11 @@ void CYsfProtocol::Task(void)
//OnDvFramePacketIn(Frames[0], &Ip);
//OnDvFramePacketIn(Frames[1], &Ip);
}
else
{
delete Header;
}
}
else if ( IsValidDvLastFramePacket(Ip, Fich, Buffer, Frames) )
else if ( IsValidDvLastFramePacket(Ip, Fich, Buffer, OneFrame, LastFrame) )
{
//std::cout << "YSF last DV frame" << std::endl;
// handle it
OnDvFramePacketIn(Frames[0], &Ip);
OnDvLastFramePacketIn((CDvLastFramePacket *)Frames[1], &Ip);
OnDvFramePacketIn(OneFrame, &Ip);
OnDvLastFramePacketIn(LastFrame, &Ip);
}
}
else if ( IsValidConnectPacket(Buffer, &Callsign) )
@ -235,10 +223,8 @@ void CYsfProtocol::Task(void)
////////////////////////////////////////////////////////////////////////////////////////
// streams helpers
bool CYsfProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
void CYsfProtocol::OnDvHeaderPacketIn(std::unique_ptr<CDvHeaderPacket> &Header, const CIp &Ip)
{
bool newstream = false;
// find the stream
CPacketStream *stream = GetStream(Header->GetStreamId());
if ( stream == nullptr )
@ -260,7 +246,6 @@ bool CYsfProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
{
// keep the handle
m_Streams.push_back(stream);
newstream = true;
}
}
// release
@ -272,24 +257,13 @@ bool CYsfProtocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
g_Reflector.GetUsers()->Hearing(Header->GetMyCallsign(), via, Header->GetRpt2Callsign());
g_Reflector.ReleaseUsers();
}
// delete header if needed
if ( !newstream )
{
delete Header;
}
}
else
{
// stream already open
// skip packet, but tickle the stream
stream->Tickle();
// and delete packet
delete Header;
}
// done
return newstream;
}
////////////////////////////////////////////////////////////////////////////////////////
@ -302,7 +276,7 @@ void CYsfProtocol::HandleQueue(void)
while ( !m_Queue.empty() )
{
// get the packet
CPacket *packet = m_Queue.front();
auto packet = m_Queue.front();
m_Queue.pop();
// get our sender's id
@ -319,7 +293,7 @@ void CYsfProtocol::HandleQueue(void)
m_StreamsCache[iModId].m_dvHeader = CDvHeaderPacket((const CDvHeaderPacket &)*packet);
// encode it
EncodeDvHeaderPacket((const CDvHeaderPacket &)*packet, &buffer);
EncodeDvHeaderPacket((const CDvHeaderPacket &)*packet.get(), &buffer);
}
// check if it's a last frame
else if ( packet->IsLastPacket() )
@ -363,9 +337,6 @@ void CYsfProtocol::HandleQueue(void)
}
g_Reflector.ReleaseClients();
}
// done
delete packet;
}
m_Queue.Unlock();
}
@ -438,13 +409,8 @@ bool CYsfProtocol::IsValidDvPacket(const CBuffer &Buffer, CYSFFICH *Fich)
}
bool CYsfProtocol::IsValidDvHeaderPacket(const CIp &Ip, const CYSFFICH &Fich, const CBuffer &Buffer, CDvHeaderPacket **header, CDvFramePacket **frames)
bool CYsfProtocol::IsValidDvHeaderPacket(const CIp &Ip, const CYSFFICH &Fich, const CBuffer &Buffer, std::unique_ptr<CDvHeaderPacket> &header, std::array<std::unique_ptr<CDvFramePacket>, 5> &frames)
{
bool valid = false;
*header = nullptr;
frames[0] = nullptr;
frames[1] = nullptr;
// DV header ?
if ( Fich.getFI() == YSF_FI_HEADER )
{
@ -471,49 +437,26 @@ bool CYsfProtocol::IsValidDvHeaderPacket(const CIp &Ip, const CYSFFICH &Fich, co
rpt2.SetModule(' ');
// and packet
*header = new CDvHeaderPacket(csMY, CCallsign("CQCQCQ"), rpt1, rpt2, uiStreamId, Fich.getFN());
header = std::unique_ptr<CDvHeaderPacket>(new CDvHeaderPacket(csMY, CCallsign("CQCQCQ"), rpt1, rpt2, uiStreamId, Fich.getFN()));
}
// and 2 DV Frames
{
uint8 uiAmbe[AMBE_SIZE];
::memset(uiAmbe, 0x00, sizeof(uiAmbe));
frames[0] = new CDvFramePacket(uiAmbe, uiStreamId, Fich.getFN(), 0, 0);
frames[1] = new CDvFramePacket(uiAmbe, uiStreamId, Fich.getFN(), 1, 0);
frames[0] = std::unique_ptr<CDvFramePacket>(new CDvFramePacket(uiAmbe, uiStreamId, Fich.getFN(), 0, 0));
frames[1] = std::unique_ptr<CDvFramePacket>(new CDvFramePacket(uiAmbe, uiStreamId, Fich.getFN(), 1, 0));
}
// check validity of packets
if ( ((*header) == nullptr) || !(*header)->IsValid() ||
(frames[0] == nullptr) || !(frames[0]->IsValid()) ||
(frames[1] == nullptr) || !(frames[1]->IsValid()) )
{
delete *header;
*header = nullptr;
delete frames[0];
delete frames[1];
frames[0] = nullptr;
frames[1] = nullptr;
}
else
{
valid = true;
}
if ( header && frames[0] && frames[1] && header->IsValid() && frames[0]->IsValid() && frames[1]->IsValid() )
return true;
}
// done
return valid;
return false;
}
bool CYsfProtocol::IsValidDvFramePacket(const CIp &Ip, const CYSFFICH &Fich, const CBuffer &Buffer, CDvFramePacket **frames)
bool CYsfProtocol::IsValidDvFramePacket(const CIp &Ip, const CYSFFICH &Fich, const CBuffer &Buffer, std::array<std::unique_ptr<CDvFramePacket>, 5> &frames)
{
bool valid = false;
frames[0] = nullptr;
frames[1] = nullptr;
frames[2] = nullptr;
frames[3] = nullptr;
frames[4] = nullptr;
// is it DV frame ?
if ( Fich.getFI() == YSF_FI_COMMUNICATIONS )
{
@ -531,46 +474,21 @@ bool CYsfProtocol::IsValidDvFramePacket(const CIp &Ip, const CYSFFICH &Fich, con
// get DV frames
uint8 fid = Buffer.data()[34];
frames[0] = new CDvFramePacket(ambe0, uiStreamId, Fich.getFN(), 0, fid);
frames[1] = new CDvFramePacket(ambe1, uiStreamId, Fich.getFN(), 1, fid);
frames[2] = new CDvFramePacket(ambe2, uiStreamId, Fich.getFN(), 2, fid);
frames[3] = new CDvFramePacket(ambe3, uiStreamId, Fich.getFN(), 3, fid);
frames[4] = new CDvFramePacket(ambe4, uiStreamId, Fich.getFN(), 4, fid);
frames[0] = std::unique_ptr<CDvFramePacket>(new CDvFramePacket(ambe0, uiStreamId, Fich.getFN(), 0, fid));
frames[1] = std::unique_ptr<CDvFramePacket>(new CDvFramePacket(ambe1, uiStreamId, Fich.getFN(), 1, fid));
frames[2] = std::unique_ptr<CDvFramePacket>(new CDvFramePacket(ambe2, uiStreamId, Fich.getFN(), 2, fid));
frames[3] = std::unique_ptr<CDvFramePacket>(new CDvFramePacket(ambe3, uiStreamId, Fich.getFN(), 3, fid));
frames[4] = std::unique_ptr<CDvFramePacket>(new CDvFramePacket(ambe4, uiStreamId, Fich.getFN(), 4, fid));
// check validity of packets
if ( (frames[0] == nullptr) || !(frames[0]->IsValid()) ||
(frames[1] == nullptr) || !(frames[1]->IsValid()) ||
(frames[2] == nullptr) || !(frames[2]->IsValid()) ||
(frames[3] == nullptr) || !(frames[3]->IsValid()) ||
(frames[4] == nullptr) || !(frames[4]->IsValid()) )
{
delete frames[0];
delete frames[1];
delete frames[2];
delete frames[3];
delete frames[4];
frames[0] = nullptr;
frames[1] = nullptr;
frames[2] = nullptr;
frames[3] = nullptr;
frames[4] = nullptr;
}
else
{
valid = true;
}
if ( frames[0] && frames[0]->IsValid() && frames[1] && frames[1]->IsValid() && frames[2] && frames[2]->IsValid() && frames[3] && frames[3]->IsValid() && frames[4] && frames[4]->IsValid() )
return true;
}
// done
return valid;
return false;
}
bool CYsfProtocol::IsValidDvLastFramePacket(const CIp &Ip, const CYSFFICH &Fich, const CBuffer &Buffer, CDvFramePacket **frames)
bool CYsfProtocol::IsValidDvLastFramePacket(const CIp &Ip, const CYSFFICH &Fich, const CBuffer &Buffer, std::unique_ptr<CDvFramePacket> &oneframe, std::unique_ptr<CDvLastFramePacket> &lastframe)
{
bool valid = false;
frames[0] = nullptr;
frames[1] = nullptr;
// DV header ?
if ( Fich.getFI() == YSF_FI_TERMINATOR )
{
@ -581,28 +499,15 @@ bool CYsfProtocol::IsValidDvLastFramePacket(const CIp &Ip, const CYSFFICH &Fich,
{
uint8 uiAmbe[AMBE_SIZE];
::memset(uiAmbe, 0x00, sizeof(uiAmbe));
frames[0] = new CDvFramePacket(uiAmbe, uiStreamId, Fich.getFN(), 0, 0);
frames[1] = new CDvLastFramePacket(uiAmbe, uiStreamId, Fich.getFN(), 1, 0);
oneframe = std::unique_ptr<CDvFramePacket>(new CDvFramePacket(uiAmbe, uiStreamId, Fich.getFN(), 0, 0));
lastframe = std::unique_ptr<CDvLastFramePacket>(new CDvLastFramePacket(uiAmbe, uiStreamId, Fich.getFN(), 1, 0));
}
// check validity of packets
if ( (frames[0] == nullptr) || !(frames[0]->IsValid()) ||
(frames[1] == nullptr) || !(frames[1]->IsValid()) )
{
delete frames[0];
delete frames[1];
frames[0] = nullptr;
frames[1] = nullptr;
}
else
{
valid = true;
}
if ( (oneframe && oneframe->IsValid()) && lastframe && lastframe->IsValid() )
return true;
}
// done
return valid;
return false;
}
////////////////////////////////////////////////////////////////////////////////////////

@ -73,9 +73,6 @@ public:
// constructor
CYsfProtocol();
// destructor
~CYsfProtocol() {}
// initialization
bool Initalize(const char *type, const uint16 port, const bool has_ipv4, const bool has_ipv6);
void Close(void);
@ -91,15 +88,15 @@ protected:
void HandleKeepalives(void);
// stream helpers
bool OnDvHeaderPacketIn(CDvHeaderPacket *, const CIp &);
void OnDvHeaderPacketIn(std::unique_ptr<CDvHeaderPacket> &, const CIp &);
// DV packet decoding helpers
bool IsValidConnectPacket(const CBuffer &, CCallsign *);
//bool IsValidDisconnectPacket(const CBuffer &, CCallsign *);
bool IsValidDvPacket(const CBuffer &, CYSFFICH *);
bool IsValidDvHeaderPacket(const CIp &, const CYSFFICH &, const CBuffer &, CDvHeaderPacket **, CDvFramePacket **);
bool IsValidDvFramePacket(const CIp &, const CYSFFICH &, const CBuffer &, CDvFramePacket **);
bool IsValidDvLastFramePacket(const CIp &, const CYSFFICH &, const CBuffer &, CDvFramePacket **);
bool IsValidDvHeaderPacket(const CIp &, const CYSFFICH &, const CBuffer &, std::unique_ptr<CDvHeaderPacket> &, std::array<std::unique_ptr<CDvFramePacket>, 5> &);
bool IsValidDvFramePacket(const CIp &, const CYSFFICH &, const CBuffer &, std::array<std::unique_ptr<CDvFramePacket>, 5> &);
bool IsValidDvLastFramePacket(const CIp &, const CYSFFICH &, const CBuffer &, std::unique_ptr<CDvFramePacket> &, std::unique_ptr<CDvLastFramePacket> &);
// DV packet encoding helpers
void EncodeConnectAckPacket(CBuffer *) const;

Loading…
Cancel
Save

Powered by TurnKey Linux.