version 1.3.8

This commit is contained in:
LX3JL 2016-08-17 08:29:15 +02:00
parent dfb46e1266
commit 4be0cb5fa4
9 changed files with 121 additions and 31 deletions

View File

@ -32,11 +32,13 @@
CCallsignListItem::CCallsignListItem()
{
::memset(m_Modules, 0, sizeof(m_Modules));
::memset(m_szUrl, 0, sizeof(m_szUrl));
}
CCallsignListItem::CCallsignListItem(const CCallsign &callsign, const CIp &ip, const char *modules)
{
m_Callsign = callsign;
::memset(m_szUrl, 0, sizeof(m_szUrl));
m_Ip = ip;
if ( modules != NULL )
{
@ -45,9 +47,22 @@ CCallsignListItem::CCallsignListItem(const CCallsign &callsign, const CIp &ip, c
}
}
CCallsignListItem::CCallsignListItem(const CCallsign &callsign, const char *url, const char *modules)
{
m_Callsign = callsign;
::strncpy(m_szUrl, url, URL_MAXLEN);
m_Ip = CIp(m_szUrl);
if ( modules != NULL )
{
:: memset(m_Modules, 0, sizeof(m_Modules));
::memcpy(m_Modules, modules, MIN(strlen(modules), sizeof(m_Modules)-1));
}
}
CCallsignListItem::CCallsignListItem(const CCallsignListItem &item)
{
m_Callsign = item.m_Callsign;
::memcpy(m_szUrl, item.m_szUrl, sizeof(m_szUrl));
m_Ip = item.m_Ip;
::memcpy(m_Modules, item.m_Modules, sizeof(m_Modules));
}

View File

@ -29,6 +29,11 @@
#include "ccallsign.h"
#include "cip.h"
////////////////////////////////////////////////////////////////////////////////////////
// define
#define URL_MAXLEN 256
////////////////////////////////////////////////////////////////////////////////////////
// class
@ -38,6 +43,7 @@ public:
// constructor
CCallsignListItem();
CCallsignListItem(const CCallsign &, const CIp &, const char *);
CCallsignListItem(const CCallsign &, const char *, const char *);
CCallsignListItem(const CCallsignListItem &);
// destructor
@ -54,9 +60,13 @@ public:
const CIp &GetIp(void) const { return m_Ip; }
const char *GetModules(void) { return m_Modules; }
// update
void ResolveIp(void) { m_Ip = CIp(m_szUrl); }
protected:
// data
CCallsign m_Callsign;
char m_szUrl[URL_MAXLEN+1];
CIp m_Ip;
char m_Modules[NB_MODULES_MAX+1];
};

View File

@ -291,14 +291,14 @@ void CDcsProtocol::HandleQueue(void)
{
// encode it
CBuffer buffer;
if ( packet->IsDvFrame() )
{
EncodeDvPacket(m_DvHeadersCache[iModId], (const CDvFramePacket &)*packet, m_iSeqCounters[iModId]++, &buffer);
}
else if ( packet->IsLastPacket() )
if ( packet->IsLastPacket() )
{
EncodeDvLastPacket(m_DvHeadersCache[iModId], (const CDvFramePacket &)*packet, m_iSeqCounters[iModId]++, &buffer);
}
else if ( packet->IsDvFrame() )
{
EncodeDvPacket(m_DvHeadersCache[iModId], (const CDvFramePacket &)*packet, m_iSeqCounters[iModId]++, &buffer);
}
// send it
if ( buffer.size() > 0 )

View File

@ -30,6 +30,17 @@
#include "cgatekeeper.h"
////////////////////////////////////////////////////////////////////////////////////////
// constructor
CDplusProtocol::CDplusProtocol()
{
for ( int i = 0; i < m_iSeqCounters.size(); i++ )
{
m_iSeqCounters[i] = 0;
}
}
////////////////////////////////////////////////////////////////////////////////////////
// operation
@ -82,7 +93,7 @@ void CDplusProtocol::Task(void)
// handle it
OnDvFramePacketIn(Frame);
}
}
else if ( (Header = IsValidDvHeaderPacket(Buffer)) != NULL )
{
//std::cout << "DPlus DV header:" << std::endl << *Header << std::endl;
@ -270,6 +281,17 @@ void CDplusProtocol::HandleQueue(void)
CPacket *packet = m_Queue.front();
m_Queue.pop();
// get our sender's id
int iModId = g_Reflector.GetModuleIndex(packet->GetModuleId());
// check if it's header and update cache
if ( packet->IsDvHeader() )
{
// this relies on queue feeder setting valid module id
m_DvHeadersCache[iModId] = CDvHeaderPacket((const CDvHeaderPacket &)*packet);
m_iSeqCounters[iModId] = 0;
}
// encode it
CBuffer buffer;
if ( EncodeDvPacket(*packet, &buffer) )
@ -288,30 +310,28 @@ void CDplusProtocol::HandleQueue(void)
// check if client is a dextra dongle
// then replace RPT2 with XRF instead of REF
// if the client type is not yet known, send bothheaders
if ( packet->IsDvHeader() && (client->IsDextraDongle() || !client->HasModule()) )
if ( packet->IsDvHeader() )
{
// clone the packet and patch it
CDvHeaderPacket packet2(*((CDvHeaderPacket *)packet));
CCallsign rpt2 = packet2.GetRpt2Callsign();
rpt2.PatchCallsign(0, (const uint8 *)"XRF", 3);
packet2.SetRpt2Callsign(rpt2);
// encode it
CBuffer buffer2;
if ( EncodeDvPacket(packet2, &buffer2) )
// sending header in Dplus is client specific
SendDvHeader((CDvHeaderPacket *)packet, (CDplusClient *)client);
}
else if ( packet->IsDvFrame() )
{
// and send the DV frame
m_Socket.Send(buffer, client->GetIp());
// is it time to insert a DVheader copy ?
if ( (m_iSeqCounters[iModId]++ % 21) == 20 )
{
// and send it
m_Socket.Send(buffer2, client->GetIp());
}
// client type known ?
if ( !client->HasModule() )
{
// no, send also the genuine packet
m_Socket.Send(buffer, client->GetIp());
// yes, clone it
CDvHeaderPacket packet2(m_DvHeadersCache[iModId]);
// and send it
SendDvHeader(&packet2, (CDplusClient *)client);
}
}
else
{
// no, send the original packet
// otherwise, send the original packet
m_Socket.Send(buffer, client->GetIp());
}
}
@ -326,6 +346,43 @@ void CDplusProtocol::HandleQueue(void)
m_Queue.Unlock();
}
void CDplusProtocol::SendDvHeader(CDvHeaderPacket *packet, CDplusClient *client)
{
// encode it
CBuffer buffer;
if ( EncodeDvPacket(*packet, &buffer) )
{
if ( (client->IsDextraDongle() || !client->HasModule()) )
{
// clone the packet and patch it
CDvHeaderPacket packet2(*((CDvHeaderPacket *)packet));
CCallsign rpt2 = packet2.GetRpt2Callsign();
rpt2.PatchCallsign(0, (const uint8 *)"XRF", 3);
packet2.SetRpt2Callsign(rpt2);
// encode it
CBuffer buffer2;
if ( EncodeDvPacket(packet2, &buffer2) )
{
// and send it
m_Socket.Send(buffer2, client->GetIp());
}
// client type known ?
if ( !client->HasModule() )
{
// no, send also the genuine packet
m_Socket.Send(buffer, client->GetIp());
}
}
else
{
// otherwise, send the original packet
m_Socket.Send(buffer, client->GetIp());
}
}
}
////////////////////////////////////////////////////////////////////////////////////////
// keepalive helpers

View File

@ -37,11 +37,13 @@
////////////////////////////////////////////////////////////////////////////////////////
// class
class CDplusClient;
class CDplusProtocol : public CProtocol
{
public:
// constructor
CDplusProtocol() {};
CDplusProtocol();
// destructor
virtual ~CDplusProtocol() {};
@ -55,6 +57,7 @@ public:
protected:
// queue helper
void HandleQueue(void);
void SendDvHeader(CDvHeaderPacket *, CDplusClient *);
// keepalive helpers
void HandleKeepalives(void);
@ -84,6 +87,10 @@ protected:
protected:
// for keep alive
CTimePoint m_LastKeepaliveTime;
// for queue header caches
std::array<CDvHeaderPacket, NB_OF_MODULES> m_DvHeadersCache;
std::array<uint32, NB_OF_MODULES> m_iSeqCounters;
};
////////////////////////////////////////////////////////////////////////////////////////

View File

@ -57,14 +57,14 @@ bool CPeerCallsignList::LoadFromFile(const char *filename)
{
CCallsign callsign(szt);
// 2nd token is ip
if ( (szt = ::strtok(NULL, " ,\t")) != NULL )
char *szip;
if ( (szip = ::strtok(NULL, " ,\t")) != NULL )
{
CIp ip(szt);
// 3rd token is modules list
if ( (szt = ::strtok(NULL, " ,\t")) != NULL )
{
// and load
push_back(CCallsignListItem(callsign, ip, szt));
push_back(CCallsignListItem(callsign, szip, szt));
}
}
}

View File

@ -314,6 +314,8 @@ void CXlxProtocol::HandlePeerLinks(void)
CCallsignListItem *item = &((list->data())[i]);
if ( clients->FindClient(item->GetCallsign(), PROTOCOL_XLX) == NULL )
{
// resolve again peer's IP in case it's a dynamic IP
item->ResolveIp();
// send connect packet to re-initiate peer link
EncodeConnectPacket(&buffer, item->GetModules());
m_Socket.Send(buffer, item->GetIp(), XLX_PORT);

View File

@ -48,7 +48,7 @@
#define VERSION_MAJOR 1
#define VERSION_MINOR 3
#define VERSION_REVISION 7
#define VERSION_REVISION 8
// global ------------------------------------------------------

View File

@ -4,7 +4,6 @@ LDFLAGS=-std=c++11 -pthread
SOURCES=$(wildcard *.cpp)
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=xlxd
RM=rm -f
all: $(SOURCES) $(EXECUTABLE)
@ -15,7 +14,7 @@ $(EXECUTABLE): $(OBJECTS)
$(CC) $(CFLAGS) $< -o $@
clean:
$(RM) *.o
rm *.o
install:
mkdir -p /xlxd