mirror of https://github.com/ShaYmez/xlxd.git
parent
8885b72295
commit
706013449f
|
@ -3,7 +3,7 @@
|
|||
// ambed
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 09/07/2017.
|
||||
// Copyright © 2017 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
// Copyright © 2017-2019 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of ambed.
|
||||
|
|
|
@ -182,6 +182,7 @@ CBuffer::operator const char *() const
|
|||
|
||||
void CBuffer::DebugDump(std::ofstream &debugout) const
|
||||
{
|
||||
// dump an hex line
|
||||
for ( int i = 0; i < size(); i++ )
|
||||
{
|
||||
char sz[16];
|
||||
|
@ -199,3 +200,29 @@ void CBuffer::DebugDump(std::ofstream &debugout) const
|
|||
}
|
||||
}
|
||||
|
||||
void CBuffer::DebugDumpAscii(std::ofstream &debugout) const
|
||||
{
|
||||
// dump an ascii line
|
||||
for ( int i = 0; i < size(); i++ )
|
||||
{
|
||||
char c = data()[i];
|
||||
if ( isascii(c) )
|
||||
{
|
||||
debugout << c;
|
||||
}
|
||||
else
|
||||
{
|
||||
debugout << '.';
|
||||
}
|
||||
if ( i == size()-1 )
|
||||
{
|
||||
debugout << std::endl;
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// debugout << ',';
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@ public:
|
|||
|
||||
// debug
|
||||
void DebugDump(std::ofstream &) const;
|
||||
void DebugDumpAscii(std::ofstream &) const;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
12
src/ccrc.cpp
12
src/ccrc.cpp
|
@ -237,3 +237,15 @@ unsigned char CCRC::crc8(const unsigned char *in, unsigned int length)
|
|||
|
||||
return crc;
|
||||
}
|
||||
|
||||
unsigned char CCRC::addCRC(const unsigned char* in, unsigned int length)
|
||||
{
|
||||
assert(in != NULL);
|
||||
|
||||
unsigned char crc = 0U;
|
||||
|
||||
for (unsigned int i = 0U; i < length; i++)
|
||||
crc += in[i];
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@ public:
|
|||
static bool checkCCITT162(const unsigned char* in, unsigned int length);
|
||||
|
||||
static unsigned char crc8(const unsigned char* in, unsigned int length);
|
||||
|
||||
static unsigned char addCRC(const unsigned char* in, unsigned int length);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
// compare function for std::map::find
|
||||
|
||||
struct CallsignCompare
|
||||
struct CDmridDirCallsignCompare
|
||||
{
|
||||
bool operator() (const CCallsign &cs1, const CCallsign &cs2) const
|
||||
{ return cs1.HasLowerCallsign(cs2);}
|
||||
|
@ -80,7 +80,7 @@ protected:
|
|||
protected:
|
||||
// data
|
||||
std::map <uint32, CCallsign> m_CallsignMap;
|
||||
std::map <CCallsign, uint32, CallsignCompare> m_DmridMap;
|
||||
std::map <CCallsign, uint32, CDmridDirCallsignCompare> m_DmridMap;
|
||||
|
||||
// Lock()
|
||||
std::mutex m_Mutex;
|
||||
|
|
|
@ -144,7 +144,7 @@ bool CDmridDirFile::RefreshContent(const CBuffer &buffer)
|
|||
}
|
||||
|
||||
// report
|
||||
std::cout << "Read " << m_DmridMap.size() << " DMR id from file " << DMRIDDB_PATH << std::endl;
|
||||
std::cout << "Read " << m_DmridMap.size() << " DMR ids from file " << DMRIDDB_PATH << std::endl;
|
||||
|
||||
// done
|
||||
return ok;
|
||||
|
|
|
@ -85,7 +85,7 @@ bool CDmridDirHttp::RefreshContent(const CBuffer &buffer)
|
|||
}
|
||||
|
||||
// report
|
||||
std::cout << "Read " << m_DmridMap.size() << " DMR id from xlxapi.rlx.lu database " << std::endl;
|
||||
std::cout << "Read " << m_DmridMap.size() << " DMR ids from xlxapi.rlx.lu database " << std::endl;
|
||||
|
||||
// done
|
||||
return ok;
|
||||
|
@ -96,7 +96,6 @@ bool CDmridDirHttp::RefreshContent(const CBuffer &buffer)
|
|||
// httpd helpers
|
||||
|
||||
#define DMRID_HTTPGET_SIZEMAX (256)
|
||||
#define DMRID_TEXTFILE_SIZEMAX (10*1024*1024)
|
||||
|
||||
bool CDmridDirHttp::HttpGet(const char *hostname, const char *filename, int port, CBuffer *buffer)
|
||||
{
|
||||
|
|
|
@ -61,13 +61,24 @@ CDvFramePacket::CDvFramePacket(const uint8 *ambe, const uint8 *sync, uint16 sid,
|
|||
::memset(m_uiDvData, 0, sizeof(m_uiDvData));
|
||||
}
|
||||
|
||||
// dstar + dmr constructor
|
||||
// ysf constructor
|
||||
|
||||
CDvFramePacket::CDvFramePacket(const uint8 *ambe, uint16 sid, uint8 pid, uint8 spid, uint8 fid)
|
||||
: CPacket(sid, pid, spid, fid)
|
||||
{
|
||||
::memcpy(m_uiAmbePlus, ambe, sizeof(m_uiAmbePlus));
|
||||
::memset(m_uiDvSync, 0, sizeof(m_uiDvSync));
|
||||
::memset(m_uiAmbe, 0, sizeof(m_uiAmbe));
|
||||
::memset(m_uiDvData, 0, sizeof(m_uiDvData));
|
||||
}
|
||||
|
||||
// xlx constructor
|
||||
|
||||
CDvFramePacket::CDvFramePacket
|
||||
(uint16 sid,
|
||||
uint8 dstarpid, const uint8 *dstarambe, const uint8 *dstardvdata,
|
||||
uint8 dmrpid, uint8 dprspid, const uint8 *dmrambe, const uint8 *dmrsync)
|
||||
: CPacket(sid, dstarpid, dmrpid, dprspid)
|
||||
: CPacket(sid, dstarpid, dmrpid, dprspid, 0xFF, 0xFF, 0xFF)
|
||||
{
|
||||
::memcpy(m_uiAmbe, dstarambe, sizeof(m_uiAmbe));
|
||||
::memcpy(m_uiDvData, dstardvdata, sizeof(m_uiDvData));
|
||||
|
|
|
@ -55,6 +55,7 @@ public:
|
|||
CDvFramePacket();
|
||||
CDvFramePacket(const struct dstar_dvframe *, uint16, uint8);
|
||||
CDvFramePacket(const uint8 *, const uint8 *, uint16, uint8, uint8);
|
||||
CDvFramePacket(const uint8 *, uint16, uint8, uint8, uint8);
|
||||
CDvFramePacket(uint16, uint8, const uint8 *, const uint8 *, uint8, uint8, const uint8 *, const uint8 *);
|
||||
CDvFramePacket(const CDvFramePacket &);
|
||||
|
||||
|
|
|
@ -70,6 +70,22 @@ CDvHeaderPacket::CDvHeaderPacket(uint32 my, const CCallsign &ur, const CCallsign
|
|||
m_csMY = CCallsign("", my);
|
||||
}
|
||||
|
||||
// YSF constructor
|
||||
|
||||
CDvHeaderPacket::CDvHeaderPacket(const CCallsign &my, const CCallsign &ur, const CCallsign &rpt1, const CCallsign &rpt2, uint16 sid, uint8 pid)
|
||||
: CPacket(sid, pid, 0, 0)
|
||||
{
|
||||
m_uiFlag1 = 0;
|
||||
m_uiFlag2 = 0;
|
||||
m_uiFlag3 = 0;
|
||||
m_uiCrc = 0;
|
||||
m_csUR = ur;
|
||||
m_csRPT1 = rpt1;
|
||||
m_csRPT2 = rpt2;
|
||||
m_csMY = my;
|
||||
}
|
||||
|
||||
|
||||
// copy constructor
|
||||
|
||||
CDvHeaderPacket::CDvHeaderPacket(const CDvHeaderPacket &Header)
|
||||
|
|
|
@ -63,7 +63,8 @@ public:
|
|||
CDvHeaderPacket();
|
||||
CDvHeaderPacket(const struct dstar_header *, uint16, uint8);
|
||||
CDvHeaderPacket(uint32, const CCallsign &, const CCallsign &, const CCallsign &, uint16, uint8, uint8);
|
||||
CDvHeaderPacket(const CDvHeaderPacket &);
|
||||
CDvHeaderPacket(const CCallsign &, const CCallsign &, const CCallsign &, const CCallsign &, uint16, uint8);
|
||||
CDvHeaderPacket(const CDvHeaderPacket &);
|
||||
|
||||
// destructor
|
||||
virtual ~CDvHeaderPacket(){};
|
||||
|
|
|
@ -57,6 +57,14 @@ CDvLastFramePacket::CDvLastFramePacket
|
|||
{
|
||||
}
|
||||
|
||||
// ysf constructor
|
||||
|
||||
CDvLastFramePacket::CDvLastFramePacket(const uint8 *ambe, uint16 sid, uint8 pid, uint8 spid, uint8 fid)
|
||||
: CDvFramePacket(ambe, sid, pid, spid, fid)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// copy constructor
|
||||
|
||||
CDvLastFramePacket::CDvLastFramePacket(const CDvLastFramePacket &DvFrame)
|
||||
|
|
|
@ -42,6 +42,7 @@ public:
|
|||
CDvLastFramePacket();
|
||||
CDvLastFramePacket(const struct dstar_dvframe *, uint16, uint8);
|
||||
CDvLastFramePacket(const uint8 *, const uint8 *, uint16, uint8, uint8);
|
||||
CDvLastFramePacket(const uint8 *, uint16, uint8, uint8, uint8);
|
||||
CDvLastFramePacket(uint16, uint8, const uint8 *, const uint8 *, uint8, uint8, const uint8 *, const uint8 *);
|
||||
CDvLastFramePacket(const CDvLastFramePacket &);
|
||||
|
||||
|
|
|
@ -101,6 +101,7 @@ bool CGateKeeper::MayLink(const CCallsign &callsign, const CIp &ip, int protocol
|
|||
case PROTOCOL_DCS:
|
||||
case PROTOCOL_DMRPLUS:
|
||||
case PROTOCOL_DMRMMDVM:
|
||||
case PROTOCOL_YSF:
|
||||
// first check is IP & callsigned listed OK
|
||||
ok &= IsNodeListedOk(callsign, ip);
|
||||
// todo: then apply any protocol specific authorisation for the operation
|
||||
|
@ -141,6 +142,7 @@ bool CGateKeeper::MayTransmit(const CCallsign &callsign, const CIp &ip, int prot
|
|||
case PROTOCOL_DCS:
|
||||
case PROTOCOL_DMRPLUS:
|
||||
case PROTOCOL_DMRMMDVM:
|
||||
case PROTOCOL_YSF:
|
||||
// first check is IP & callsigned listed OK
|
||||
ok &= IsNodeListedOk(callsign, ip, module);
|
||||
// todo: then apply any protocol specific authorisation for the operation
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (C) 2010,2016 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef Golay24128_H
|
||||
#define Golay24128_H
|
||||
|
||||
class CGolay24128 {
|
||||
public:
|
||||
static unsigned int encode23127(unsigned int data);
|
||||
static unsigned int encode24128(unsigned int data);
|
||||
|
||||
static unsigned int decode23127(unsigned int code);
|
||||
static unsigned int decode24128(unsigned int code);
|
||||
static unsigned int decode24128(unsigned char* bytes);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -35,36 +35,70 @@ CPacket::CPacket()
|
|||
m_uiStreamId = 0;
|
||||
m_uiDstarPacketId = 0;
|
||||
m_uiDmrPacketId = 0;
|
||||
m_uiDmrPacketSubid = 0;
|
||||
m_uiYsfPacketId = 0;
|
||||
m_uiYsfPacketSubId = 0;
|
||||
m_uiYsfPacketFrameId = 0;
|
||||
m_uiModuleId = ' ';
|
||||
m_uiOriginId = ORIGIN_LOCAL;
|
||||
};
|
||||
|
||||
// dstar contrsuctor
|
||||
|
||||
CPacket::CPacket(uint16 sid, uint8 dstarpid)
|
||||
{
|
||||
m_uiStreamId = sid;
|
||||
m_uiDstarPacketId = dstarpid;
|
||||
m_uiDmrPacketId = 0xFF;
|
||||
m_uiDmrPacketSubid = 0xFF;
|
||||
m_uiYsfPacketId = 0xFF;
|
||||
m_uiYsfPacketSubId = 0xFF;
|
||||
m_uiYsfPacketFrameId = 0xFF;
|
||||
m_uiModuleId = ' ';
|
||||
m_uiOriginId = ORIGIN_LOCAL;
|
||||
};
|
||||
|
||||
// dmr constructor
|
||||
|
||||
CPacket::CPacket(uint16 sid, uint8 dmrpid, uint8 dmrspid)
|
||||
{
|
||||
m_uiStreamId = sid;
|
||||
m_uiDmrPacketId = dmrpid;
|
||||
m_uiDmrPacketSubid = dmrspid;
|
||||
m_uiDstarPacketId = 0xFF;
|
||||
m_uiYsfPacketId = 0xFF;
|
||||
m_uiYsfPacketSubId = 0xFF;
|
||||
m_uiYsfPacketFrameId = 0xFF;
|
||||
m_uiModuleId = ' ';
|
||||
m_uiOriginId = ORIGIN_LOCAL;
|
||||
};
|
||||
|
||||
CPacket::CPacket(uint16 sid, uint8 dstarpid, uint8 dmrpid, uint8 dmrsubpid)
|
||||
// ysf constructor
|
||||
|
||||
CPacket::CPacket(uint16 sid, uint8 ysfpid, uint8 ysfsubpid, uint8 ysffrid)
|
||||
{
|
||||
m_uiStreamId = sid;
|
||||
m_uiYsfPacketId = ysfpid;
|
||||
m_uiYsfPacketSubId = ysfsubpid;
|
||||
m_uiYsfPacketFrameId = ysffrid;
|
||||
m_uiDstarPacketId = 0xFF;
|
||||
m_uiDmrPacketId = 0xFF;
|
||||
m_uiDmrPacketSubid = 0xFF;
|
||||
m_uiModuleId = ' ';
|
||||
m_uiOriginId = ORIGIN_LOCAL;
|
||||
}
|
||||
|
||||
// xlx constructor
|
||||
|
||||
CPacket::CPacket(uint16 sid, uint8 dstarpid, uint8 dmrpid, uint8 dmrsubpid, uint8 ysfpid, uint8 ysfsubpid, uint8 ysffrid)
|
||||
{
|
||||
m_uiStreamId = sid;
|
||||
m_uiDstarPacketId = dstarpid;
|
||||
m_uiDmrPacketId = dmrpid;
|
||||
m_uiDmrPacketSubid = dmrsubpid;
|
||||
m_uiYsfPacketId = ysfpid;
|
||||
m_uiYsfPacketSubId = ysfsubpid;
|
||||
m_uiYsfPacketFrameId = ysffrid;
|
||||
m_uiModuleId = ' ';
|
||||
m_uiOriginId = ORIGIN_LOCAL;
|
||||
}
|
||||
|
@ -99,4 +133,11 @@ void CPacket::UpdatePids(uint32 pid)
|
|||
m_uiDmrPacketId = ((pid / 3) % 6);
|
||||
m_uiDmrPacketSubid = ((pid % 3) + 1);
|
||||
}
|
||||
// ysf pids need update ?
|
||||
if ( m_uiYsfPacketId == 0xFF )
|
||||
{
|
||||
m_uiYsfPacketId = ((pid / 5) % 8);
|
||||
m_uiYsfPacketSubId = pid % 5;
|
||||
m_uiYsfPacketFrameId = ((pid / 5) & 0x7FU) << 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,8 @@ public:
|
|||
CPacket();
|
||||
CPacket(uint16 sid, uint8 dstarpid);
|
||||
CPacket(uint16 sid, uint8 dmrpid, uint8 dmrsubpid);
|
||||
CPacket(uint16 sid, uint8 dstarpid, uint8 dmrpid, uint8 dmrsubpid);
|
||||
CPacket(uint16 sid, uint8 ysfpid, uint8 ysfsubpid, uint8 ysfsubpidmax);
|
||||
CPacket(uint16 sid, uint8 dstarpid, uint8 dmrpid, uint8 dmrsubpid, uint8 ysfpid, uint8 ysfsubpid, uint8 ysfsubpidmax);
|
||||
|
||||
// destructor
|
||||
virtual ~CPacket() {};
|
||||
|
@ -63,6 +64,9 @@ public:
|
|||
uint8 GetDstarPacketId(void) const { return m_uiDstarPacketId; }
|
||||
uint8 GetDmrPacketId(void) const { return m_uiDmrPacketId; }
|
||||
uint8 GetDmrPacketSubid(void) const { return m_uiDmrPacketSubid; }
|
||||
uint8 GetYsfPacketId(void) const { return m_uiYsfPacketId; }
|
||||
uint8 GetYsfPacketSubId(void) const { return m_uiYsfPacketSubId; }
|
||||
uint8 GetYsfPacketFrameId(void) const { return m_uiYsfPacketFrameId; }
|
||||
uint8 GetModuleId(void) const { return m_uiModuleId; }
|
||||
bool IsLocalOrigin(void) const { return (m_uiOriginId == ORIGIN_LOCAL); }
|
||||
|
||||
|
@ -78,6 +82,9 @@ protected:
|
|||
uint8 m_uiDstarPacketId;
|
||||
uint8 m_uiDmrPacketId;
|
||||
uint8 m_uiDmrPacketSubid;
|
||||
uint8 m_uiYsfPacketId;
|
||||
uint8 m_uiYsfPacketSubId;
|
||||
uint8 m_uiYsfPacketFrameId;
|
||||
uint8 m_uiModuleId;
|
||||
uint8 m_uiOriginId;
|
||||
};
|
||||
|
|
|
@ -139,7 +139,7 @@ protected:
|
|||
CCallsign m_ReflectorCallsign;
|
||||
|
||||
// debug
|
||||
CTimePoint m_DebugTimer;
|
||||
CTimePoint m_DebugTimer;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "cxlxprotocol.h"
|
||||
#include "cdmrplusprotocol.h"
|
||||
#include "cdmrmmdvmprotocol.h"
|
||||
#include "cysfprotocol.h"
|
||||
#include "cprotocols.h"
|
||||
|
||||
|
||||
|
@ -96,6 +97,11 @@ bool CProtocols::Init(void)
|
|||
delete m_Protocols[5];
|
||||
m_Protocols[5] = new CDmrmmdvmProtocol;
|
||||
ok &= m_Protocols[5]->Init();
|
||||
|
||||
// create and initialize YSF
|
||||
delete m_Protocols[6];
|
||||
m_Protocols[6] = new CYsfProtocol;
|
||||
ok &= m_Protocols[6]->Init();
|
||||
}
|
||||
m_Mutex.unlock();
|
||||
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include "cdmriddirfile.h"
|
||||
#include "cdmriddirhttp.h"
|
||||
#include "ctranscoder.h"
|
||||
#include "cysfnodedirfile.h"
|
||||
#include "cysfnodedirhttp.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructor
|
||||
|
@ -43,7 +45,7 @@ CReflector::CReflector()
|
|||
m_RouterThreads[i] = NULL;
|
||||
}
|
||||
#ifdef DEBUG_DUMPFILE
|
||||
m_DebugFile.open("/Users/jeanluc/Desktop/dmrdebug.txt");
|
||||
m_DebugFile.open("/Users/jeanluc/Desktop/xlxdebug.txt");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -105,6 +107,9 @@ bool CReflector::Start(void)
|
|||
// init dmrid directory
|
||||
g_DmridDir.Init();
|
||||
|
||||
// init wiresx node directory
|
||||
g_YsfNodeDir.Init();
|
||||
|
||||
// init the transcoder
|
||||
g_Transcoder.Init();
|
||||
|
||||
|
@ -173,6 +178,11 @@ void CReflector::Stop(void)
|
|||
|
||||
// close gatekeeper
|
||||
g_GateKeeper.Close();
|
||||
|
||||
// close databases
|
||||
g_DmridDir.Close();
|
||||
g_YsfNodeDir.Close();
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -389,7 +399,7 @@ void CReflector::XmlReportThread(CReflector *This)
|
|||
// and close file
|
||||
xmlFile.close();
|
||||
}
|
||||
#ifndef NO_ERROR_ON_XML_OPEN_FAIL
|
||||
#ifndef DEBUG_NO_ERROR_ON_XML_OPEN_FAIL
|
||||
else
|
||||
{
|
||||
std::cout << "Failed to open " << XML_PATH << std::endl;
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
//
|
||||
// cwiresxcmd.cpp
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 09/10/2019.
|
||||
// Copyright © 2019 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "main.h"
|
||||
#include "cwiresxcmd.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructor
|
||||
|
||||
CWiresxCmd::CWiresxCmd()
|
||||
{
|
||||
m_iCmd = WIRESX_CMD_UNKNOWN;
|
||||
m_Time.Now();
|
||||
}
|
||||
|
||||
CWiresxCmd::CWiresxCmd(const CIp &Ip, const CCallsign &Callsign, int iCmd, int iArg)
|
||||
{
|
||||
m_Ip = Ip;
|
||||
m_Callsign = Callsign;
|
||||
m_iCmd = iCmd;
|
||||
m_iArg = iArg;
|
||||
m_Time.Now();
|
||||
}
|
||||
|
||||
CWiresxCmd::CWiresxCmd(const CWiresxCmd &Cmd)
|
||||
{
|
||||
m_Ip = Cmd.m_Ip;
|
||||
m_Callsign = Cmd.m_Callsign;
|
||||
m_iCmd = Cmd.m_iCmd;
|
||||
m_iArg = Cmd.m_iArg;
|
||||
m_Time = Cmd.m_Time;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
//
|
||||
// cwiresxcmd.h
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 09/10/2019.
|
||||
// Copyright © 2019 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef cwiresxcmd_h
|
||||
#define cwiresxcmd_h
|
||||
|
||||
#include "ccallsign.h"
|
||||
#include "cip.h"
|
||||
#include "ctimepoint.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// defines
|
||||
|
||||
// Wires-X commands
|
||||
#define WIRESX_CMD_UNKNOWN 0
|
||||
#define WIRESX_CMD_DX_REQ 1
|
||||
#define WIRESX_CMD_ALL_REQ 2
|
||||
#define WIRESX_CMD_SEARCH_REQ 3
|
||||
#define WIRESX_CMD_CONN_REQ 4
|
||||
#define WIRESX_CMD_DISC_REQ 5
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CWiresxCmd
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CWiresxCmd();
|
||||
CWiresxCmd(const CIp &, const CCallsign &, int, int);
|
||||
CWiresxCmd(const CWiresxCmd &);
|
||||
|
||||
// destructor
|
||||
virtual ~CWiresxCmd() {}
|
||||
|
||||
// get
|
||||
const CCallsign &GetCallsign(void) const { return m_Callsign; }
|
||||
const CIp &GetIp(void) const { return m_Ip; }
|
||||
int GetCmd(void) const { return m_iCmd; }
|
||||
int GetArg(void) const { return m_iArg; }
|
||||
const CTimePoint &GetTime(void) const { return m_Time; }
|
||||
|
||||
protected:
|
||||
// data
|
||||
CIp m_Ip;
|
||||
CCallsign m_Callsign;
|
||||
int m_iCmd;
|
||||
int m_iArg;
|
||||
CTimePoint m_Time;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#endif /* cwiresxcmd_h */
|
|
@ -0,0 +1,774 @@
|
|||
//
|
||||
// cwiresxcmdhandler.cpp
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 09/10/2019.
|
||||
// Copyright © 2019 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include <string.h>
|
||||
#include "main.h"
|
||||
#include "ccrc.h"
|
||||
#include "cysffich.h"
|
||||
#include "cysfpayload.h"
|
||||
#include "cysfclient.h"
|
||||
#include "cysfnodedirfile.h"
|
||||
#include "cysfnodedirhttp.h"
|
||||
#include "cysfutils.h"
|
||||
#include "creflector.h"
|
||||
#include "cwiresxcmdhandler.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructor
|
||||
|
||||
CWiresxCmdHandler::CWiresxCmdHandler()
|
||||
{
|
||||
m_seqNo = 0;
|
||||
m_bStopThread = false;
|
||||
m_pThread = NULL;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// destructor
|
||||
|
||||
CWiresxCmdHandler::~CWiresxCmdHandler()
|
||||
{
|
||||
// kill threads
|
||||
m_bStopThread = true;
|
||||
if ( m_pThread != NULL )
|
||||
{
|
||||
m_pThread->join();
|
||||
delete m_pThread;
|
||||
}
|
||||
|
||||
// empty queue
|
||||
m_CmdQueue.Lock();
|
||||
while ( !m_CmdQueue.empty() )
|
||||
{
|
||||
m_CmdQueue.pop();
|
||||
}
|
||||
m_CmdQueue.Unlock();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// initialization
|
||||
|
||||
bool CWiresxCmdHandler::Init(void)
|
||||
{
|
||||
// fill our wiresx info
|
||||
m_ReflectorWiresxInfo.SetCallsign(g_Reflector.GetCallsign());
|
||||
m_ReflectorWiresxInfo.SetNode(g_Reflector.GetCallsign());
|
||||
m_ReflectorWiresxInfo.SetName("Reflector");
|
||||
|
||||
// reset stop flag
|
||||
m_bStopThread = false;
|
||||
|
||||
// start thread;
|
||||
m_pThread = new std::thread(CWiresxCmdHandler::Thread, this);
|
||||
|
||||
// done
|
||||
return true;
|
||||
}
|
||||
|
||||
void CWiresxCmdHandler::Close(void)
|
||||
{
|
||||
m_bStopThread = true;
|
||||
if ( m_pThread != NULL )
|
||||
{
|
||||
m_pThread->join();
|
||||
delete m_pThread;
|
||||
m_pThread = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// thread
|
||||
|
||||
void CWiresxCmdHandler::Thread(CWiresxCmdHandler *This)
|
||||
{
|
||||
while ( !This->m_bStopThread )
|
||||
{
|
||||
This->Task();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// task
|
||||
|
||||
void CWiresxCmdHandler::Task(void)
|
||||
{
|
||||
CWiresxInfo Info;
|
||||
CWiresxCmd Cmd;
|
||||
uint32 uiNodeTxFreq;
|
||||
uint32 uiNodeRxFreq;
|
||||
char cModule;
|
||||
bool bCmd;
|
||||
|
||||
// anything to do ?
|
||||
bCmd = false;
|
||||
m_CmdQueue.Lock();
|
||||
{
|
||||
// any cmd in our queue ?
|
||||
if ( !m_CmdQueue.empty() )
|
||||
{
|
||||
// yes, get the command
|
||||
Cmd = m_CmdQueue.front();
|
||||
// check that the command is at least one second old
|
||||
// so that the so delayed processing of the command
|
||||
// introduce the delay the radio needs to switch
|
||||
// from tx to rx
|
||||
if ( Cmd.GetTime().DurationSinceNow() >= WIRESX_REPLY_DELAY )
|
||||
{
|
||||
m_CmdQueue.pop();
|
||||
bCmd = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_CmdQueue.Unlock();
|
||||
|
||||
|
||||
// handle it
|
||||
if ( bCmd )
|
||||
{
|
||||
// fill our info object
|
||||
Info = m_ReflectorWiresxInfo;
|
||||
g_YsfNodeDir.FindFrequencies(Cmd.GetCallsign(), &uiNodeTxFreq, &uiNodeRxFreq);
|
||||
Info.SetFrequencies(uiNodeTxFreq, uiNodeRxFreq);
|
||||
|
||||
// find our client and the module it's currentlink linked to
|
||||
cModule = ' ';
|
||||
CClients *clients = g_Reflector.GetClients();
|
||||
CClient *client = clients->FindClient(Cmd.GetCallsign(), Cmd.GetIp(), PROTOCOL_YSF);
|
||||
if ( client != NULL )
|
||||
{
|
||||
cModule = client->GetReflectorModule();
|
||||
}
|
||||
g_Reflector.ReleaseClients();
|
||||
|
||||
// and crack the cmd
|
||||
switch ( Cmd.GetCmd() )
|
||||
{
|
||||
case WIRESX_CMD_DX_REQ:
|
||||
std::cout << "Wires-X DX_REQ command from " << Cmd.GetCallsign() << " at " << Cmd.GetIp() << std::endl;
|
||||
// reply
|
||||
ReplyToWiresxDxReqPacket(Cmd.GetIp(), Info, cModule);
|
||||
break;
|
||||
case WIRESX_CMD_ALL_REQ:
|
||||
case WIRESX_CMD_SEARCH_REQ:
|
||||
std::cout << "Wires-X ALL_REQ command from " << Cmd.GetCallsign() << " at " << Cmd.GetIp() << std::endl;
|
||||
// reply
|
||||
ReplyToWiresxAllReqPacket(Cmd.GetIp(), Info, Cmd.GetArg());
|
||||
break;
|
||||
case WIRESX_CMD_CONN_REQ:
|
||||
if ( (Cmd.GetArg() >= 1) && (Cmd.GetArg() <= NB_OF_MODULES) )
|
||||
{
|
||||
cModule = 'A' + (char)(Cmd.GetArg() - 1);
|
||||
std::cout << "Wires-X CONN_REQ command to link on module " << cModule << " from " << Cmd.GetCallsign() << " at " << Cmd.GetIp() << std::endl;
|
||||
// acknowledge
|
||||
ReplyToWiresxConnReqPacket(Cmd.GetIp(), Info, cModule);
|
||||
// change client's module
|
||||
CClients *clients = g_Reflector.GetClients();
|
||||
CClient *client = clients->FindClient(Cmd.GetCallsign(), Cmd.GetIp(), PROTOCOL_YSF);
|
||||
if ( client != NULL )
|
||||
{
|
||||
client->SetReflectorModule(cModule);
|
||||
}
|
||||
g_Reflector.ReleaseClients();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Wires-X CONN_REQ command with illegal argument from " << Cmd.GetCallsign() << " at " << Cmd.GetIp() << std::endl;
|
||||
}
|
||||
break;
|
||||
case WIRESX_CMD_DISC_REQ:
|
||||
std::cout << "Wires-X DISC_REQ command from " << Cmd.GetCallsign() << " at " << Cmd.GetIp() << std::endl;
|
||||
// and reply
|
||||
ReplyToWiresxDiscReqPacket(Cmd.GetIp(), Info);
|
||||
// change client's module
|
||||
{
|
||||
CClients *clients = g_Reflector.GetClients();
|
||||
CClient *client = clients->FindClient(Cmd.GetCallsign(), Cmd.GetIp(), PROTOCOL_YSF);
|
||||
if ( client != NULL )
|
||||
{
|
||||
client->SetReflectorModule(' ');
|
||||
}
|
||||
g_Reflector.ReleaseClients();
|
||||
}
|
||||
break;
|
||||
case WIRESX_CMD_UNKNOWN:
|
||||
default:
|
||||
std::cout << "Wires-X non implemented command from " << Cmd.GetCallsign() << " at " << Cmd.GetIp() << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if nothing to do, sleep a bit
|
||||
CTimePoint::TaskSleepFor(10);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// packet encoding
|
||||
|
||||
bool CWiresxCmdHandler::ReplyToWiresxDxReqPacket(const CIp &Ip, const CWiresxInfo &WiresxInfo, char Module)
|
||||
{
|
||||
uint8 DX_RESP[] = {0x5DU, 0x51U, 0x5FU, 0x26U};
|
||||
bool ok;
|
||||
uint8 data[150U];
|
||||
uint8 RoomId;
|
||||
bool IsLinked;
|
||||
|
||||
// linked module
|
||||
// module A == 0
|
||||
IsLinked = (Module != ' ');
|
||||
RoomId = (uint8)(Module - 'A');
|
||||
|
||||
// fill data buffer
|
||||
::memset(data, 0x00U, 150U);
|
||||
::memset(data, ' ', 128U);
|
||||
// seq no
|
||||
data[0U] = m_seqNo;
|
||||
// command
|
||||
::memcpy(data + 1U, DX_RESP, 4U);
|
||||
// node info
|
||||
::memcpy(data + 5U, WiresxInfo.GetId(), 5U);
|
||||
::memcpy(data + 10U, WiresxInfo.GetNode(), 10U);
|
||||
::memcpy(data + 20U, WiresxInfo.GetName(), 14U);
|
||||
// linked room
|
||||
if (!IsLinked)
|
||||
{
|
||||
data[34U] = '1';
|
||||
data[35U] = '2';
|
||||
// no room linked
|
||||
data[57U] = '0';
|
||||
data[58U] = '0';
|
||||
data[59U] = '0';
|
||||
}
|
||||
else
|
||||
{
|
||||
data[34U] = '1';
|
||||
data[35U] = '5';
|
||||
// linked room
|
||||
char item[16U];
|
||||
// refl->m_id
|
||||
::sprintf(item, "%05d", 4001U + RoomId);
|
||||
::memcpy(data + 36U, item, 5U);
|
||||
// refl->name
|
||||
::memset(item, ' ', 16U);
|
||||
::memcpy(item, "Module", 6U);
|
||||
item[7] = 'A' + RoomId;
|
||||
::memcpy(data + 41U, item, 16U);
|
||||
// refl->count
|
||||
::sprintf(item, "%03d", RoomId + 1);
|
||||
::memcpy(data + 57U, item, 3U);
|
||||
// other
|
||||
::memset(data + 60U, ' ', 10U);
|
||||
// refl->m_desc
|
||||
::memcpy(data + 70U, "Description ", 14U);
|
||||
}
|
||||
|
||||
// frequencies
|
||||
{
|
||||
unsigned int offset;
|
||||
char sign;
|
||||
if (WiresxInfo.GetTxFrequency() >= WiresxInfo.GetRxFrequency())
|
||||
{
|
||||
offset = WiresxInfo.GetTxFrequency() - WiresxInfo.GetRxFrequency();
|
||||
sign = '-';
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = WiresxInfo.GetRxFrequency() - WiresxInfo.GetTxFrequency();
|
||||
sign = '+';
|
||||
}
|
||||
unsigned int freqHz = WiresxInfo.GetTxFrequency() % 1000000U;
|
||||
unsigned int freqkHz = (freqHz + 500U) / 1000U;
|
||||
|
||||
char freq[30U];
|
||||
::sprintf(freq, "%05u.%03u000%c%03u.%06u",
|
||||
WiresxInfo.GetTxFrequency() / 1000000U,
|
||||
freqkHz, sign, offset / 1000000U, offset % 1000000U);
|
||||
|
||||
::memcpy(data + 84U, freq, 23U);
|
||||
}
|
||||
|
||||
// EOD & CRC
|
||||
data[127U] = 0x03U;
|
||||
data[128U] = CCRC::addCRC(data, 128U);
|
||||
|
||||
// and encode the reply
|
||||
CBuffer Data;
|
||||
Data.Set(data, 129U);
|
||||
ok = EncodeAndSendWiresxPacket(Ip, Data, WiresxInfo);
|
||||
|
||||
// done
|
||||
m_seqNo++;
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool CWiresxCmdHandler::ReplyToWiresxAllReqPacket(const CIp &Ip, const CWiresxInfo &WiresxInfo, int Start)
|
||||
{
|
||||
bool ok = false;
|
||||
uint8 ALL_RESP[] = {0x5DU, 0x46U, 0x5FU, 0x29U};
|
||||
uint8 data[1100U];
|
||||
|
||||
// fill data buffer
|
||||
::memset(data, 0x00U, 1100U);
|
||||
// seq no
|
||||
data[0U] = m_seqNo;
|
||||
// command
|
||||
::memcpy(data + 1U, ALL_RESP, 4U);
|
||||
data[5U] = '2';
|
||||
data[6U] = '1';
|
||||
// node info
|
||||
::memcpy(data + 7U, WiresxInfo.GetId(), 5U);
|
||||
::memcpy(data + 12U, WiresxInfo.GetNode(), 10U);
|
||||
|
||||
// number of entries
|
||||
uint total = NB_OF_MODULES;
|
||||
uint n = NB_OF_MODULES - Start;
|
||||
if (n > 20U)
|
||||
n = 20U;
|
||||
::sprintf((char*)(data + 22U), "%03u%03u", n, total);
|
||||
data[28U] = 0x0DU;
|
||||
|
||||
// entries
|
||||
uint offset = 29U;
|
||||
for ( uint i = 0; i < n; i++ )
|
||||
{
|
||||
char item[16U];
|
||||
// module A == 0
|
||||
int RoomId = i + Start;
|
||||
|
||||
// prepare
|
||||
::memset(data + offset, ' ', 50U);
|
||||
data[offset + 0U] = '5';
|
||||
|
||||
// refl->m_id
|
||||
::sprintf(item, "%05d", 4001U + RoomId);
|
||||
::memcpy(data + offset + 1U, item, 5U);
|
||||
// refl->name
|
||||
::memset(item, ' ', 16U);
|
||||
::memcpy(item, "Module", 6U);
|
||||
item[7] = 'A' + RoomId;
|
||||
::memcpy(data + offset + 6U, item, 16U);
|
||||
// refl->count
|
||||
::sprintf(item, "%03d", RoomId + 1);
|
||||
::memcpy(data + offset + 22U, item, 3U);
|
||||
// other
|
||||
::memset(data + offset + 25U, ' ', 10U);
|
||||
// refl->m_desc
|
||||
::memcpy(data + offset + 35U, "Description ", 14U);
|
||||
data[offset + 49U] = 0x0DU;
|
||||
// next
|
||||
offset += 50U;
|
||||
}
|
||||
|
||||
// the following is a workaround for FT2D which
|
||||
// do not accept less than 20 items frames.
|
||||
// first send a 'patched' frame
|
||||
if ( n < 20 )
|
||||
{
|
||||
// FT2D workaround
|
||||
uint offset2 = offset;
|
||||
// patch the remaining
|
||||
uint k = 1029U - offset2;
|
||||
::memset(data+offset2, ' ', k);
|
||||
offset2 += k;
|
||||
|
||||
// EOD + CRC
|
||||
data[offset2 + 0U] = 0x03U;
|
||||
data[offset2 + 1U] = CCRC::addCRC(data, offset2 + 1U);
|
||||
offset2 += 2U;
|
||||
|
||||
// and encode the reply
|
||||
CBuffer Data;
|
||||
Data.Set(data, offset2 + 2U);
|
||||
ok = EncodeAndSendWiresxPacket(Ip, Data, WiresxInfo);
|
||||
}
|
||||
|
||||
|
||||
// and next repeat with normal frame
|
||||
{
|
||||
// EOD + CRC
|
||||
data[offset + 0U] = 0x03U;
|
||||
data[offset + 1U] = CCRC::addCRC(data, offset + 1U);
|
||||
offset += 2U;
|
||||
|
||||
// patch the remaining
|
||||
//uint k = 1031U - offset;
|
||||
//::memset(data+offset, ' ', k);
|
||||
//offset += k;
|
||||
|
||||
// and encode the reply
|
||||
CBuffer Data;
|
||||
Data.Set(data, offset + 2U);
|
||||
ok = EncodeAndSendWiresxPacket(Ip, Data, WiresxInfo);
|
||||
}
|
||||
|
||||
|
||||
// done
|
||||
m_seqNo++;
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool CWiresxCmdHandler::ReplyToWiresxConnReqPacket(const CIp &Ip, const CWiresxInfo &WiresxInfo, char Module)
|
||||
{
|
||||
uint8 CONN_RESP[] = {0x5DU, 0x41U, 0x5FU, 0x26U};
|
||||
bool ok = false;
|
||||
uint8 data[110U];
|
||||
uint RoomId;
|
||||
|
||||
// linked room
|
||||
// Module A == 0
|
||||
RoomId = (uint8)(Module - 'A');
|
||||
|
||||
// prepare buffer
|
||||
::memset(data, 0x00U, 110U);
|
||||
::memset(data, ' ', 90U);
|
||||
|
||||
// seq no
|
||||
data[0U] = m_seqNo;
|
||||
// command
|
||||
::memcpy(data + 1U, CONN_RESP, 4U);
|
||||
// node info
|
||||
::memcpy(data + 5U, WiresxInfo.GetId(), 5U);
|
||||
::memcpy(data + 10U, WiresxInfo.GetNode(), 10U);
|
||||
::memcpy(data + 20U, WiresxInfo.GetName(), 14U);
|
||||
data[34U] = '1';
|
||||
data[35U] = '5';
|
||||
// entry info
|
||||
{
|
||||
char item[16U];
|
||||
|
||||
// refl->m_id
|
||||
::sprintf(item, "%05d", 4001U + RoomId);
|
||||
::memcpy(data + 36U, item, 5U);
|
||||
// refl->name
|
||||
::memset(item, ' ', 16U);
|
||||
::memcpy(item, "Module", 6U);
|
||||
item[7] = 'A' + RoomId;
|
||||
::memcpy(data + 41U, item, 16U);
|
||||
// refl->count
|
||||
::sprintf(item, "%03d", RoomId + 1);
|
||||
::memcpy(data + 57U, item, 3U);
|
||||
// refl->m_desc
|
||||
::memcpy(data + 70U, "Description ", 14U);
|
||||
}
|
||||
data[84U] = '0';
|
||||
data[85U] = '0';
|
||||
data[86U] = '0';
|
||||
data[87U] = '0';
|
||||
data[88U] = '0';
|
||||
|
||||
// EOD + CRC
|
||||
data[89U] = 0x03U;
|
||||
data[90U] = CCRC::addCRC(data, 90U);
|
||||
|
||||
// and encode the reply
|
||||
CBuffer Data;
|
||||
Data.Set(data, 91U);
|
||||
ok = EncodeAndSendWiresxPacket(Ip, Data, WiresxInfo);
|
||||
|
||||
// done
|
||||
m_seqNo++;
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool CWiresxCmdHandler::ReplyToWiresxDiscReqPacket(const CIp &Ip, const CWiresxInfo &WiresxInfo)
|
||||
{
|
||||
uint8 DISC_RESP[] = {0x5DU, 0x41U, 0x5FU, 0x26U};
|
||||
bool ok = false;
|
||||
uint8 data[110U];
|
||||
|
||||
// prepare buffer
|
||||
::memset(data, 0x00U, 110U);
|
||||
::memset(data, ' ', 90U);
|
||||
|
||||
// seq no
|
||||
data[0U] = m_seqNo;
|
||||
// command
|
||||
::memcpy(data + 1U, DISC_RESP, 4U);
|
||||
// node info
|
||||
::memcpy(data + 5U, WiresxInfo.GetId(), 5U);
|
||||
::memcpy(data + 10U, WiresxInfo.GetNode(), 10U);
|
||||
::memcpy(data + 20U, WiresxInfo.GetName(), 14U);
|
||||
// data
|
||||
data[34U] = '1';
|
||||
data[35U] = '2';
|
||||
|
||||
data[57U] = '0';
|
||||
data[58U] = '0';
|
||||
data[59U] = '0';
|
||||
|
||||
// EOD + CRC
|
||||
data[89U] = 0x03U;
|
||||
data[90U] = CCRC::addCRC(data, 90U);
|
||||
|
||||
// and encode the reply
|
||||
CBuffer Data;
|
||||
Data.Set(data, 91U);
|
||||
ok = EncodeAndSendWiresxPacket(Ip, Data, WiresxInfo);
|
||||
|
||||
// done
|
||||
m_seqNo++;
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
///// packet encoding helpers
|
||||
|
||||
bool CWiresxCmdHandler::EncodeAndSendWiresxPacket(const CIp &Ip, const CBuffer &DataOrg, const CWiresxInfo &WiresxInfo)
|
||||
{
|
||||
uint8 DEFAULT_FICH[] = {0x20U, 0x00U, 0x01U, 0x00U};
|
||||
uint8 NET_HEADER[] = "YSFD ALL ";
|
||||
CYSFFICH fich;
|
||||
CYSFPayload payload;
|
||||
uint8 buffer[200U];
|
||||
|
||||
|
||||
CBuffer Data(DataOrg);
|
||||
|
||||
// seq no
|
||||
uint8 seqNo = 0U;
|
||||
|
||||
// calculate bt and adjust length
|
||||
uint length = (uint)Data.size();
|
||||
uint8 bt = 0;
|
||||
if (length > 260U)
|
||||
{
|
||||
bt = 1U;
|
||||
bt += (length - 260U) / 259U;
|
||||
length += bt;
|
||||
}
|
||||
if (length > 20U)
|
||||
{
|
||||
uint blocks = (length - 20U) / 40U;
|
||||
if ((length % 40U) > 0U)
|
||||
blocks++;
|
||||
length = blocks * 40U + 20U;
|
||||
}
|
||||
else
|
||||
{
|
||||
length = 20U;
|
||||
}
|
||||
if ( length > (uint)Data.size() )
|
||||
{
|
||||
Data.Append((uint8)0x20U, (int)(length - (uint)Data.size()));
|
||||
}
|
||||
|
||||
// ft
|
||||
uint8 ft = WiresxCalcFt(length, 0U);
|
||||
|
||||
// Write the header
|
||||
{
|
||||
//header
|
||||
::memcpy(buffer, NET_HEADER, 34U);
|
||||
::memcpy(buffer + 4U, WiresxInfo.GetCallsign(), 10U);
|
||||
::memcpy(buffer + 14U, WiresxInfo.GetNode(), 10U);
|
||||
// sync
|
||||
::memcpy(buffer + 35U, YSF_SYNC_BYTES, YSF_SYNC_LENGTH_BYTES);
|
||||
// Fich
|
||||
fich.load(DEFAULT_FICH);
|
||||
fich.setFI(YSF_FI_HEADER);
|
||||
fich.setBT(bt);
|
||||
fich.setFT(ft);
|
||||
fich.encode(buffer + 35U + 5U);
|
||||
// payload
|
||||
payload.writeDataFRModeData1(WiresxInfo.GetCsd1(), buffer + 35U);
|
||||
payload.writeDataFRModeData2(WiresxInfo.GetCsd2(), buffer + 35U);
|
||||
// seqno
|
||||
buffer[34U] = seqNo;
|
||||
seqNo += 2U;
|
||||
// and post it
|
||||
SendPacket(Ip, buffer);
|
||||
}
|
||||
|
||||
// write the payload
|
||||
fich.setFI(YSF_FI_COMMUNICATIONS);
|
||||
uint offset = 0;
|
||||
for ( uint8 bn = 0; bn <= bt; bn++ )
|
||||
{
|
||||
for ( uint8 fn = 0; fn <= ft; fn++ )
|
||||
{
|
||||
// fich
|
||||
fich.setFT(ft);
|
||||
fich.setFN(fn);
|
||||
fich.setBT(bt);
|
||||
fich.setBN(bn);
|
||||
fich.encode(buffer + 35U + 5U);
|
||||
// seq no
|
||||
buffer[34U] = seqNo;
|
||||
seqNo += 2U;
|
||||
// data
|
||||
//if ( (bn == 0) && (fn == 0) )
|
||||
if ( fn == 0 )
|
||||
{
|
||||
payload.writeDataFRModeData1(WiresxInfo.GetCsd1(), buffer + 35);
|
||||
payload.writeDataFRModeData2(WiresxInfo.GetCsd2(), buffer + 35);
|
||||
}
|
||||
//else if ( (bn == 0) && (fn == 1) )
|
||||
else if ( fn == 1 )
|
||||
{
|
||||
if ( bn == 0 )
|
||||
{
|
||||
payload.writeDataFRModeData1(WiresxInfo.GetCsd3(), buffer + 35);
|
||||
payload.writeDataFRModeData2(Data.data() + offset, buffer + 35);
|
||||
offset += 20;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8 temp[20U];
|
||||
temp[0U] = 0x00U;
|
||||
::memcpy(temp + 1U, Data.data() + offset, 19U);
|
||||
payload.writeDataFRModeData2(temp, buffer + 35U);
|
||||
offset += 19U;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
payload.writeDataFRModeData1(Data.data() + offset, buffer + 35);
|
||||
offset += 20;
|
||||
payload.writeDataFRModeData2(Data.data() + offset, buffer + 35);
|
||||
offset += 20;
|
||||
}
|
||||
// and post it
|
||||
SendPacket(Ip, buffer);
|
||||
// and some delay before next packet
|
||||
CTimePoint::TaskSleepFor(100);
|
||||
}
|
||||
}
|
||||
|
||||
// Write the trailer
|
||||
{
|
||||
// fich
|
||||
fich.setFI(YSF_FI_TERMINATOR);
|
||||
fich.setFN(ft);
|
||||
fich.setBN(bt);
|
||||
fich.encode(buffer + 35U + 5U);
|
||||
// payload
|
||||
payload.writeDataFRModeData1(WiresxInfo.GetCsd1(), buffer + 35U);
|
||||
payload.writeDataFRModeData2(WiresxInfo.GetCsd2(), buffer + 35U);
|
||||
// seq no
|
||||
buffer[34U] = seqNo | 0x01U;
|
||||
// and post it
|
||||
SendPacket(Ip, buffer);
|
||||
}
|
||||
|
||||
// done
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
uint8 CWiresxCmdHandler::WiresxCalcFt(uint length, uint offset) const
|
||||
{
|
||||
length -= offset;
|
||||
if (length > 220U) return 7U;
|
||||
if (length > 180U) return 6U;
|
||||
if (length > 140U) return 5U;
|
||||
if (length > 100U) return 4U;
|
||||
if (length > 60U) return 3U;
|
||||
if (length > 20U) return 2U;
|
||||
return 1U;
|
||||
}
|
||||
|
||||
|
||||
void CWiresxCmdHandler::SendPacket(const CIp &Ip, uint8 *Buffer)
|
||||
{
|
||||
//CBuffer packet(Buffer, 155);
|
||||
//DebugTestDecodePacket(packet);
|
||||
|
||||
// and push in queue
|
||||
m_PacketQueue.Lock();
|
||||
{
|
||||
m_PacketQueue.push(CWiresxPacket(CBuffer(Buffer, 155), Ip));
|
||||
}
|
||||
m_PacketQueue.Unlock();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// debug
|
||||
|
||||
#ifdef DEBUG_DUMPFILE
|
||||
bool CWiresxCmdHandler::DebugTestDecodePacket(const CBuffer &Buffer)
|
||||
{
|
||||
uint8 tag[] = { 'Y','S','F','D' };
|
||||
static uint8 command[4098];
|
||||
static int len;
|
||||
CYSFFICH Fich;
|
||||
CYSFPayload payload;
|
||||
CBuffer dump;
|
||||
bool valid = false;
|
||||
|
||||
if ( (Buffer.size() == 155) && (Buffer.Compare(tag, sizeof(tag)) == 0) )
|
||||
{
|
||||
// decode YSH fich
|
||||
if ( Fich.decode(&(Buffer.data()[40])) )
|
||||
{
|
||||
std::cout << (int)Fich.getDT() << ","
|
||||
<< (int)Fich.getFI() << ","
|
||||
<< (int)Fich.getBN() << ","
|
||||
<< (int)Fich.getBT() << ","
|
||||
<< (int)Fich.getFN() << ","
|
||||
<< (int)Fich.getFT() << " : ";
|
||||
|
||||
switch ( Fich.getFI() )
|
||||
{
|
||||
case YSF_FI_HEADER:
|
||||
len = 0;
|
||||
::memset(command, 0x00, sizeof(command));
|
||||
std::cout << "Header" << std::endl;
|
||||
break;
|
||||
case YSF_FI_TERMINATOR:
|
||||
std::cout << "Trailer" << std::endl;
|
||||
std::cout << "length of payload : " << len << std::endl;
|
||||
dump.Set(command, len);
|
||||
dump.DebugDump(g_Reflector.m_DebugFile);
|
||||
dump.DebugDumpAscii(g_Reflector.m_DebugFile);
|
||||
break;
|
||||
case YSF_FI_COMMUNICATIONS:
|
||||
if ( Fich.getDT() == YSF_DT_DATA_FR_MODE )
|
||||
{
|
||||
valid = payload.readDataFRModeData1(&(Buffer.data()[35]), command + len);
|
||||
len += 20;
|
||||
valid &= payload.readDataFRModeData2(&(Buffer.data()[35]), command + len);
|
||||
len += 20;
|
||||
std::cout << "decoded ok" << std::endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "invalid fich in packet" << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "invalid size packet" << std::endl;
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,94 @@
|
|||
//
|
||||
// cwiresxcmdhandler.h
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 09/10/2019.
|
||||
// Copyright © 2019 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef cwiresxcmdhandler_h
|
||||
#define cwiresxcmdhandler_h
|
||||
|
||||
#include "cwiresxinfo.h"
|
||||
#include "cwiresxcmdqueue.h"
|
||||
#include "cwiresxpacketqueue.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define WIRESX_REPLY_DELAY (1.000)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CWiresxCmdHandler
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CWiresxCmdHandler();
|
||||
|
||||
// destructor
|
||||
virtual ~CWiresxCmdHandler();
|
||||
|
||||
// initialization
|
||||
virtual bool Init(void);
|
||||
virtual void Close(void);
|
||||
|
||||
// queues
|
||||
CWiresxCmdQueue *GetCmdQueue(void) { m_CmdQueue.Lock(); return &m_CmdQueue; }
|
||||
void ReleaseCmdQueue(void) { m_CmdQueue.Unlock(); }
|
||||
CWiresxPacketQueue *GetPacketQueue(void) { m_PacketQueue.Lock(); return &m_PacketQueue; }
|
||||
void ReleasePacketQueue(void) { m_PacketQueue.Unlock(); }
|
||||
|
||||
// get
|
||||
|
||||
// task
|
||||
static void Thread(CWiresxCmdHandler *);
|
||||
virtual void Task(void);
|
||||
|
||||
protected:
|
||||
// packet encoding
|
||||
bool ReplyToWiresxDxReqPacket(const CIp &, const CWiresxInfo &, char);
|
||||
bool ReplyToWiresxAllReqPacket(const CIp &, const CWiresxInfo &, int);
|
||||
bool ReplyToWiresxConnReqPacket(const CIp &, const CWiresxInfo &, char);
|
||||
bool ReplyToWiresxDiscReqPacket(const CIp &, const CWiresxInfo &);
|
||||
|
||||
// packet encoding helpers
|
||||
bool EncodeAndSendWiresxPacket(const CIp &, const CBuffer &, const CWiresxInfo &);
|
||||
uint8 WiresxCalcFt(uint, uint) const;
|
||||
void SendPacket(const CIp &, uint8 *);
|
||||
|
||||
// debug
|
||||
bool DebugTestDecodePacket(const CBuffer &);
|
||||
|
||||
protected:
|
||||
// data
|
||||
CWiresxInfo m_ReflectorWiresxInfo;
|
||||
uint8_t m_seqNo;
|
||||
|
||||
// queues
|
||||
CWiresxCmdQueue m_CmdQueue;
|
||||
CWiresxPacketQueue m_PacketQueue;
|
||||
|
||||
// thread
|
||||
bool m_bStopThread;
|
||||
std::thread *m_pThread;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#endif /* cwiresxcmdhandler_h */
|
|
@ -0,0 +1,55 @@
|
|||
//
|
||||
// cwiresxcmdqueue.h
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 09/10/2019.
|
||||
// Copyright © 2019 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef cwiresxcmdqueue_h
|
||||
#define cwiresxcmdqueue_h
|
||||
|
||||
|
||||
#include "cwiresxcmd.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CWiresxCmdQueue : public std::queue<CWiresxCmd>
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CWiresxCmdQueue() {};
|
||||
|
||||
// destructor
|
||||
~CWiresxCmdQueue() {};
|
||||
|
||||
// lock
|
||||
void Lock() { m_Mutex.lock(); }
|
||||
void Unlock() { m_Mutex.unlock(); }
|
||||
|
||||
protected:
|
||||
// status
|
||||
std::mutex m_Mutex;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#endif /* cwiresxcmdqueue_h */
|
|
@ -0,0 +1,107 @@
|
|||
//
|
||||
// cwiresxinfo.cpp
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 29/09/2019.
|
||||
// Copyright © 2019 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include <string.h>
|
||||
#include "main.h"
|
||||
#include "ccallsign.h"
|
||||
#include "cwiresxinfo.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructor
|
||||
|
||||
CWiresxInfo::CWiresxInfo()
|
||||
{
|
||||
::memset(m_callsign, ' ', YSF_CALLSIGN_LENGTH);
|
||||
::memset(m_node, ' ', YSF_CALLSIGN_LENGTH);
|
||||
::memset(m_name, ' ', 14);
|
||||
::memset(m_id, ' ', 6);
|
||||
m_txFrequency = 0U;
|
||||
m_rxFrequency = 0U;
|
||||
|
||||
::memset(m_csd1, '*', 20U);
|
||||
::memset(m_csd2, ' ', 20U);
|
||||
::memset(m_csd3, ' ', 20U);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
///// set
|
||||
|
||||
void CWiresxInfo::SetCallsign(const CCallsign &callsign)
|
||||
{
|
||||
::memset(m_callsign, ' ', YSF_CALLSIGN_LENGTH);
|
||||
callsign.GetCallsign(m_callsign);
|
||||
UpdateCsds();
|
||||
}
|
||||
|
||||
void CWiresxInfo::SetNode(const char *node)
|
||||
{
|
||||
::memset(m_node, ' ', YSF_CALLSIGN_LENGTH);
|
||||
::memcpy(m_node, node, MIN(::strlen(node), YSF_CALLSIGN_LENGTH));
|
||||
UpdateCsds();
|
||||
}
|
||||
|
||||
void CWiresxInfo::SetName(const char *name)
|
||||
{
|
||||
::memset(m_name, ' ', 14);
|
||||
::memcpy(m_name, name, MIN(::strlen(name), 14));
|
||||
UpdateId();
|
||||
}
|
||||
|
||||
void CWiresxInfo::SetFrequencies(uint txFreq, uint rxFreq)
|
||||
{
|
||||
m_txFrequency = txFreq;
|
||||
m_rxFrequency = rxFreq;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// updates
|
||||
|
||||
void CWiresxInfo::UpdateCsds(void)
|
||||
{
|
||||
::memset(m_csd1, '*', 20U);
|
||||
::memset(m_csd2, ' ', 20U);
|
||||
::memset(m_csd3, ' ', 20U);
|
||||
::memcpy(m_csd1 + 10U, m_node, 10U);
|
||||
::memcpy(m_csd2 + 0U, m_callsign, 10U);
|
||||
::memcpy(m_csd3 + 0U, m_id, 5U);
|
||||
::memcpy(m_csd3 + 15U, m_id, 5U);
|
||||
}
|
||||
|
||||
void CWiresxInfo::UpdateId(void)
|
||||
{
|
||||
uint hash = 0U;
|
||||
for (uint i = 0U; i < 14; i++)
|
||||
{
|
||||
hash += m_name[i];
|
||||
hash += (hash << 10);
|
||||
hash ^= (hash >> 6);
|
||||
}
|
||||
hash += (hash << 3);
|
||||
hash ^= (hash >> 11);
|
||||
hash += (hash << 15);
|
||||
::sprintf((char *)m_id, "%05u", hash % 100000U);
|
||||
UpdateCsds();
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
//
|
||||
// cwiresxinfo.h
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 29/09/2019.
|
||||
// Copyright © 2019 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef cwiresxinfo_h
|
||||
#define cwiresxinfo_h
|
||||
|
||||
#include "ysfdefines.h"
|
||||
#include "ccallsign.h"
|
||||
|
||||
class CWiresxInfo
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CWiresxInfo();
|
||||
|
||||
// destructor
|
||||
virtual ~CWiresxInfo() {}
|
||||
|
||||
// get
|
||||
const uint8 *GetCallsign(void) const { return m_callsign; }
|
||||
const uint8 *GetNode(void) const { return m_node; }
|
||||
const uint8 *GetName(void) const { return m_name; }
|
||||
const uint8 *GetId(void) const { return m_id; }
|
||||
uint GetTxFrequency(void) const { return m_txFrequency; }
|
||||
uint GetRxFrequency(void) const { return m_rxFrequency; }
|
||||
const uint8 *GetCsd1(void) const { return m_csd1; }
|
||||
const uint8 *GetCsd2(void) const { return m_csd2; }
|
||||
const uint8 *GetCsd3(void) const { return m_csd3; }
|
||||
|
||||
// set
|
||||
void SetCallsign(const CCallsign &);
|
||||
void SetNode(const char *);
|
||||
void SetName(const char *);
|
||||
void SetFrequencies(uint, uint);
|
||||
|
||||
// uodates
|
||||
void UpdateCsds(void);
|
||||
void UpdateId(void);
|
||||
|
||||
protected:
|
||||
// data
|
||||
uint8 m_callsign[YSF_CALLSIGN_LENGTH];
|
||||
uint8 m_node[YSF_CALLSIGN_LENGTH];
|
||||
uint8 m_name[14];
|
||||
uint8 m_id[6];
|
||||
uint m_txFrequency;
|
||||
uint m_rxFrequency;
|
||||
|
||||
uint8 m_csd1[20];
|
||||
uint8 m_csd2[20];
|
||||
uint8 m_csd3[20];
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#endif /* cwiresxinfo_h */
|
|
@ -0,0 +1,55 @@
|
|||
//
|
||||
// cwiresxpacket.h
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 09/10/2019.
|
||||
// Copyright © 2019 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef cwiresxpacket_h
|
||||
#define cwiresxpacket_h
|
||||
|
||||
#include "cbuffer.h"
|
||||
#include "cip.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CWiresxPacket
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CWiresxPacket() {}
|
||||
CWiresxPacket(const CBuffer &Buffer, const CIp &Ip) { m_Buffer = Buffer; m_Ip = Ip; }
|
||||
|
||||
// destructor
|
||||
virtual ~CWiresxPacket() {}
|
||||
|
||||
// get
|
||||
const CBuffer &GetBuffer(void) const { return m_Buffer; }
|
||||
const CIp &GetIp(void) const { return m_Ip; }
|
||||
|
||||
protected:
|
||||
// data
|
||||
CBuffer m_Buffer;
|
||||
CIp m_Ip;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#endif /* cwiresxpacket_h */
|
|
@ -0,0 +1,54 @@
|
|||
//
|
||||
// cwiresxpacketqueue.h
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 09/10/2019.
|
||||
// Copyright © 2019 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef cwiresxpacketqueue_h
|
||||
#define cwiresxpacketqueue_h
|
||||
|
||||
#include "cwiresxpacket.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CWiresxPacketQueue : public std::queue<CWiresxPacket>
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CWiresxPacketQueue() {};
|
||||
|
||||
// destructor
|
||||
~CWiresxPacketQueue() {};
|
||||
|
||||
// lock
|
||||
void Lock() { m_Mutex.lock(); }
|
||||
void Unlock() { m_Mutex.unlock(); }
|
||||
|
||||
protected:
|
||||
// status
|
||||
std::mutex m_Mutex;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#endif /* cwiresxpacketqueue_h */
|
|
@ -0,0 +1,52 @@
|
|||
//
|
||||
// cysfclient.cpp
|
||||
// xlxd
|
||||
//// Created by Jean-Luc on 20/05/2018.
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 20/05/2018.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "main.h"
|
||||
#include "cysfclient.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructors
|
||||
|
||||
CYsfClient::CYsfClient()
|
||||
{
|
||||
}
|
||||
|
||||
CYsfClient::CYsfClient(const CCallsign &callsign, const CIp &ip, char reflectorModule)
|
||||
: CClient(callsign, ip, reflectorModule)
|
||||
{
|
||||
}
|
||||
|
||||
CYsfClient::CYsfClient(const CYsfClient &client)
|
||||
: CClient(client)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// status
|
||||
|
||||
bool CYsfClient::IsAlive(void) const
|
||||
{
|
||||
return (m_LastKeepaliveTime.DurationSinceNow() < YSF_KEEPALIVE_TIMEOUT);
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
//
|
||||
// cysfclient.h
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 20/05/2018.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef cysfclient_h
|
||||
#define cysfclient_h
|
||||
|
||||
#include "cclient.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// define
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CYsfClient : public CClient
|
||||
{
|
||||
public:
|
||||
// constructors
|
||||
CYsfClient();
|
||||
CYsfClient(const CCallsign &, const CIp &, char = ' ');
|
||||
CYsfClient(const CYsfClient &);
|
||||
|
||||
// destructor
|
||||
virtual ~CYsfClient() {};
|
||||
|
||||
// identity
|
||||
int GetProtocol(void) const { return PROTOCOL_YSF; }
|
||||
const char *GetProtocolName(void) const { return "YSF"; }
|
||||
int GetCodec(void) const { return CODEC_AMBE2PLUS; }
|
||||
bool IsNode(void) const { return true; }
|
||||
|
||||
// status
|
||||
bool IsAlive(void) const;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#endif /* cysfclient_h */
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2016 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "cysfconvolution.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
||||
|
||||
#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
|
||||
#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
|
||||
|
||||
const uint8_t BRANCH_TABLE1[] = {0U, 0U, 0U, 0U, 1U, 1U, 1U, 1U};
|
||||
const uint8_t BRANCH_TABLE2[] = {0U, 1U, 1U, 0U, 0U, 1U, 1U, 0U};
|
||||
|
||||
const unsigned int NUM_OF_STATES_D2 = 8U;
|
||||
const unsigned int NUM_OF_STATES = 16U;
|
||||
const uint32_t M = 2U;
|
||||
const unsigned int K = 5U;
|
||||
|
||||
CYSFConvolution::CYSFConvolution() :
|
||||
m_metrics1(NULL),
|
||||
m_metrics2(NULL),
|
||||
m_oldMetrics(NULL),
|
||||
m_newMetrics(NULL),
|
||||
m_decisions(NULL),
|
||||
m_dp(NULL)
|
||||
{
|
||||
m_metrics1 = new uint16_t[16U];
|
||||
m_metrics2 = new uint16_t[16U];
|
||||
m_decisions = new uint64_t[180U];
|
||||
}
|
||||
|
||||
CYSFConvolution::~CYSFConvolution()
|
||||
{
|
||||
delete[] m_metrics1;
|
||||
delete[] m_metrics2;
|
||||
delete[] m_decisions;
|
||||
}
|
||||
|
||||
void CYSFConvolution::start()
|
||||
{
|
||||
::memset(m_metrics1, 0x00U, NUM_OF_STATES * sizeof(uint16_t));
|
||||
::memset(m_metrics2, 0x00U, NUM_OF_STATES * sizeof(uint16_t));
|
||||
|
||||
m_oldMetrics = m_metrics1;
|
||||
m_newMetrics = m_metrics2;
|
||||
m_dp = m_decisions;
|
||||
}
|
||||
|
||||
void CYSFConvolution::decode(uint8_t s0, uint8_t s1)
|
||||
{
|
||||
*m_dp = 0U;
|
||||
|
||||
for (uint8_t i = 0U; i < NUM_OF_STATES_D2; i++) {
|
||||
uint8_t j = i * 2U;
|
||||
|
||||
uint16_t metric = (BRANCH_TABLE1[i] ^ s0) + (BRANCH_TABLE2[i] ^ s1);
|
||||
|
||||
uint16_t m0 = m_oldMetrics[i] + metric;
|
||||
uint16_t m1 = m_oldMetrics[i + NUM_OF_STATES_D2] + (M - metric);
|
||||
uint8_t decision0 = (m0 >= m1) ? 1U : 0U;
|
||||
m_newMetrics[j + 0U] = decision0 != 0U ? m1 : m0;
|
||||
|
||||
m0 = m_oldMetrics[i] + (M - metric);
|
||||
m1 = m_oldMetrics[i + NUM_OF_STATES_D2] + metric;
|
||||
uint8_t decision1 = (m0 >= m1) ? 1U : 0U;
|
||||
m_newMetrics[j + 1U] = decision1 != 0U ? m1 : m0;
|
||||
|
||||
*m_dp |= (uint64_t(decision1) << (j + 1U)) | (uint64_t(decision0) << (j + 0U));
|
||||
}
|
||||
|
||||
++m_dp;
|
||||
|
||||
assert((m_dp - m_decisions) <= 180);
|
||||
|
||||
uint16_t* tmp = m_oldMetrics;
|
||||
m_oldMetrics = m_newMetrics;
|
||||
m_newMetrics = tmp;
|
||||
}
|
||||
|
||||
void CYSFConvolution::chainback(unsigned char* out, unsigned int nBits)
|
||||
{
|
||||
assert(out != NULL);
|
||||
|
||||
uint32_t state = 0U;
|
||||
|
||||
while (nBits-- > 0) {
|
||||
--m_dp;
|
||||
|
||||
uint32_t i = state >> (9 - K);
|
||||
uint8_t bit = uint8_t(*m_dp >> i) & 1;
|
||||
state = (bit << 7) | (state >> 1);
|
||||
|
||||
WRITE_BIT1(out, nBits, bit != 0U);
|
||||
}
|
||||
}
|
||||
|
||||
void CYSFConvolution::encode(const unsigned char* in, unsigned char* out, unsigned int nBits) const
|
||||
{
|
||||
assert(in != NULL);
|
||||
assert(out != NULL);
|
||||
assert(nBits > 0U);
|
||||
|
||||
uint8_t d1 = 0U, d2 = 0U, d3 = 0U, d4 = 0U;
|
||||
uint32_t k = 0U;
|
||||
for (unsigned int i = 0U; i < nBits; i++) {
|
||||
uint8_t d = READ_BIT1(in, i) ? 1U : 0U;
|
||||
|
||||
uint8_t g1 = (d + d3 + d4) & 1;
|
||||
uint8_t g2 = (d + d1 + d2 + d4) & 1;
|
||||
|
||||
d4 = d3;
|
||||
d3 = d2;
|
||||
d2 = d1;
|
||||
d1 = d;
|
||||
|
||||
WRITE_BIT1(out, k, g1 != 0U);
|
||||
k++;
|
||||
|
||||
WRITE_BIT1(out, k, g2 != 0U);
|
||||
k++;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#if !defined(YSFConvolution_H)
|
||||
#define YSFConvolution_H
|
||||
|
||||
#include "cysfconvolution.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class CYSFConvolution {
|
||||
public:
|
||||
CYSFConvolution();
|
||||
~CYSFConvolution();
|
||||
|
||||
void start();
|
||||
void decode(uint8_t s0, uint8_t s1);
|
||||
void chainback(unsigned char* out, unsigned int nBits);
|
||||
|
||||
void encode(const unsigned char* in, unsigned char* out, unsigned int nBits) const;
|
||||
|
||||
private:
|
||||
uint16_t* m_metrics1;
|
||||
uint16_t* m_metrics2;
|
||||
uint16_t* m_oldMetrics;
|
||||
uint16_t* m_newMetrics;
|
||||
uint64_t* m_decisions;
|
||||
uint64_t* m_dp;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,308 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2016 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2018 by Andy Uribe CA6JAU
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "cysfconvolution.h"
|
||||
#include "ysfdefines.h"
|
||||
#include "cgolay24128.h"
|
||||
#include "cysffich.h"
|
||||
#include "ccrc.h"
|
||||
//#include "Log.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
||||
|
||||
#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
|
||||
#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
|
||||
|
||||
const unsigned int INTERLEAVE_TABLE[] = {
|
||||
0U, 40U, 80U, 120U, 160U,
|
||||
2U, 42U, 82U, 122U, 162U,
|
||||
4U, 44U, 84U, 124U, 164U,
|
||||
6U, 46U, 86U, 126U, 166U,
|
||||
8U, 48U, 88U, 128U, 168U,
|
||||
10U, 50U, 90U, 130U, 170U,
|
||||
12U, 52U, 92U, 132U, 172U,
|
||||
14U, 54U, 94U, 134U, 174U,
|
||||
16U, 56U, 96U, 136U, 176U,
|
||||
18U, 58U, 98U, 138U, 178U,
|
||||
20U, 60U, 100U, 140U, 180U,
|
||||
22U, 62U, 102U, 142U, 182U,
|
||||
24U, 64U, 104U, 144U, 184U,
|
||||
26U, 66U, 106U, 146U, 186U,
|
||||
28U, 68U, 108U, 148U, 188U,
|
||||
30U, 70U, 110U, 150U, 190U,
|
||||
32U, 72U, 112U, 152U, 192U,
|
||||
34U, 74U, 114U, 154U, 194U,
|
||||
36U, 76U, 116U, 156U, 196U,
|
||||
38U, 78U, 118U, 158U, 198U};
|
||||
|
||||
CYSFFICH::CYSFFICH() :
|
||||
m_fich(NULL)
|
||||
{
|
||||
m_fich = new unsigned char[6U];
|
||||
::memset(m_fich, 0U, 6U);
|
||||
}
|
||||
|
||||
CYSFFICH::~CYSFFICH()
|
||||
{
|
||||
delete[] m_fich;
|
||||
}
|
||||
|
||||
bool CYSFFICH::decode(const unsigned char* bytes)
|
||||
{
|
||||
assert(bytes != NULL);
|
||||
|
||||
CYSFConvolution viterbi;
|
||||
viterbi.start();
|
||||
|
||||
// Deinterleave the FICH and send bits to the Viterbi decoder
|
||||
for (unsigned int i = 0U; i < 100U; i++) {
|
||||
unsigned int n = INTERLEAVE_TABLE[i];
|
||||
uint8_t s0 = READ_BIT1(bytes, n) ? 1U : 0U;
|
||||
|
||||
n++;
|
||||
uint8_t s1 = READ_BIT1(bytes, n) ? 1U : 0U;
|
||||
|
||||
viterbi.decode(s0, s1);
|
||||
}
|
||||
|
||||
unsigned char output[13U];
|
||||
viterbi.chainback(output, 96U);
|
||||
|
||||
unsigned int b0 = CGolay24128::decode24128(output + 0U);
|
||||
unsigned int b1 = CGolay24128::decode24128(output + 3U);
|
||||
unsigned int b2 = CGolay24128::decode24128(output + 6U);
|
||||
unsigned int b3 = CGolay24128::decode24128(output + 9U);
|
||||
|
||||
m_fich[0U] = (b0 >> 4) & 0xFFU;
|
||||
m_fich[1U] = ((b0 << 4) & 0xF0U) | ((b1 >> 8) & 0x0FU);
|
||||
m_fich[2U] = (b1 >> 0) & 0xFFU;
|
||||
m_fich[3U] = (b2 >> 4) & 0xFFU;
|
||||
m_fich[4U] = ((b2 << 4) & 0xF0U) | ((b3 >> 8) & 0x0FU);
|
||||
m_fich[5U] = (b3 >> 0) & 0xFFU;
|
||||
|
||||
return CCRC::checkCCITT162(m_fich, 6U);
|
||||
}
|
||||
|
||||
void CYSFFICH::encode(unsigned char* bytes)
|
||||
{
|
||||
assert(bytes != NULL);
|
||||
|
||||
CCRC::addCCITT162(m_fich, 6U);
|
||||
|
||||
unsigned int b0 = ((m_fich[0U] << 4) & 0xFF0U) | ((m_fich[1U] >> 4) & 0x00FU);
|
||||
unsigned int b1 = ((m_fich[1U] << 8) & 0xF00U) | ((m_fich[2U] >> 0) & 0x0FFU);
|
||||
unsigned int b2 = ((m_fich[3U] << 4) & 0xFF0U) | ((m_fich[4U] >> 4) & 0x00FU);
|
||||
unsigned int b3 = ((m_fich[4U] << 8) & 0xF00U) | ((m_fich[5U] >> 0) & 0x0FFU);
|
||||
|
||||
unsigned int c0 = CGolay24128::encode24128(b0);
|
||||
unsigned int c1 = CGolay24128::encode24128(b1);
|
||||
unsigned int c2 = CGolay24128::encode24128(b2);
|
||||
unsigned int c3 = CGolay24128::encode24128(b3);
|
||||
|
||||
unsigned char conv[13U];
|
||||
conv[0U] = (c0 >> 16) & 0xFFU;
|
||||
conv[1U] = (c0 >> 8) & 0xFFU;
|
||||
conv[2U] = (c0 >> 0) & 0xFFU;
|
||||
conv[3U] = (c1 >> 16) & 0xFFU;
|
||||
conv[4U] = (c1 >> 8) & 0xFFU;
|
||||
conv[5U] = (c1 >> 0) & 0xFFU;
|
||||
conv[6U] = (c2 >> 16) & 0xFFU;
|
||||
conv[7U] = (c2 >> 8) & 0xFFU;
|
||||
conv[8U] = (c2 >> 0) & 0xFFU;
|
||||
conv[9U] = (c3 >> 16) & 0xFFU;
|
||||
conv[10U] = (c3 >> 8) & 0xFFU;
|
||||
conv[11U] = (c3 >> 0) & 0xFFU;
|
||||
conv[12U] = 0x00U;
|
||||
|
||||
CYSFConvolution convolution;
|
||||
unsigned char convolved[25U];
|
||||
convolution.encode(conv, convolved, 100U);
|
||||
|
||||
unsigned int j = 0U;
|
||||
for (unsigned int i = 0U; i < 100U; i++) {
|
||||
unsigned int n = INTERLEAVE_TABLE[i];
|
||||
|
||||
bool s0 = READ_BIT1(convolved, j) != 0U;
|
||||
j++;
|
||||
|
||||
bool s1 = READ_BIT1(convolved, j) != 0U;
|
||||
j++;
|
||||
|
||||
WRITE_BIT1(bytes, n, s0);
|
||||
|
||||
n++;
|
||||
WRITE_BIT1(bytes, n, s1);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char CYSFFICH::getFI() const
|
||||
{
|
||||
return (m_fich[0U] >> 6) & 0x03U;
|
||||
}
|
||||
|
||||
unsigned char CYSFFICH::getCS() const
|
||||
{
|
||||
return (m_fich[0U] >> 4) & 0x03U;
|
||||
}
|
||||
|
||||
unsigned char CYSFFICH::getCM() const
|
||||
{
|
||||
return (m_fich[0U] >> 2) & 0x03U;
|
||||
}
|
||||
|
||||
unsigned char CYSFFICH::getBN() const
|
||||
{
|
||||
return m_fich[0U] & 0x03U;
|
||||
}
|
||||
|
||||
unsigned char CYSFFICH::getBT() const
|
||||
{
|
||||
return (m_fich[1U] >> 6) & 0x03U;
|
||||
}
|
||||
|
||||
unsigned char CYSFFICH::getFN() const
|
||||
{
|
||||
return (m_fich[1U] >> 3) & 0x07U;
|
||||
}
|
||||
|
||||
unsigned char CYSFFICH::getFT() const
|
||||
{
|
||||
return m_fich[1U] & 0x07U;
|
||||
}
|
||||
|
||||
unsigned char CYSFFICH::getDT() const
|
||||
{
|
||||
return m_fich[2U] & 0x03U;
|
||||
}
|
||||
|
||||
unsigned char CYSFFICH::getMR() const
|
||||
{
|
||||
return (m_fich[2U] >> 3) & 0x03U;
|
||||
}
|
||||
|
||||
bool CYSFFICH::getDev() const
|
||||
{
|
||||
return (m_fich[2U] & 0x40U) == 0x40U;
|
||||
}
|
||||
|
||||
bool CYSFFICH::getSQL() const
|
||||
{
|
||||
return (m_fich[3U] & 0x80U) == 0x80U;
|
||||
}
|
||||
|
||||
unsigned char CYSFFICH::getSQ() const
|
||||
{
|
||||
return m_fich[3U] & 0x7FU;
|
||||
}
|
||||
|
||||
void CYSFFICH::setFI(unsigned char fi)
|
||||
{
|
||||
m_fich[0U] &= 0x3FU;
|
||||
m_fich[0U] |= (fi << 6) & 0xC0U;
|
||||
}
|
||||
|
||||
void CYSFFICH::setCS(unsigned char cs)
|
||||
{
|
||||
m_fich[0U] &= 0xCFU;
|
||||
m_fich[0U] |= (cs << 4) & 0x30U;
|
||||
}
|
||||
|
||||
void CYSFFICH::setCM(unsigned char cm)
|
||||
{
|
||||
m_fich[0U] &= 0xF3U;
|
||||
m_fich[0U] |= (cm << 2) & 0x0CU;
|
||||
}
|
||||
|
||||
void CYSFFICH::setFN(unsigned char fn)
|
||||
{
|
||||
m_fich[1U] &= 0xC7U;
|
||||
m_fich[1U] |= (fn << 3) & 0x38U;
|
||||
}
|
||||
|
||||
void CYSFFICH::setFT(unsigned char ft)
|
||||
{
|
||||
m_fich[1U] &= 0xF8U;
|
||||
m_fich[1U] |= ft & 0x07U;
|
||||
}
|
||||
|
||||
void CYSFFICH::setMR(unsigned char mr)
|
||||
{
|
||||
m_fich[2U] &= 0xC7U;
|
||||
m_fich[2U] |= (mr << 3) & 0x38U;
|
||||
}
|
||||
|
||||
void CYSFFICH::setVoIP(bool on)
|
||||
{
|
||||
if (on)
|
||||
m_fich[2U] |= 0x04U;
|
||||
else
|
||||
m_fich[2U] &= 0xFBU;
|
||||
}
|
||||
|
||||
void CYSFFICH::setDev(bool on)
|
||||
{
|
||||
if (on)
|
||||
m_fich[2U] |= 0x40U;
|
||||
else
|
||||
m_fich[2U] &= 0xBFU;
|
||||
}
|
||||
|
||||
void CYSFFICH::setDT(unsigned char dt)
|
||||
{
|
||||
m_fich[2U] &= 0xFCU;
|
||||
m_fich[2U] |= dt & 0x03U;
|
||||
}
|
||||
|
||||
void CYSFFICH::setSQL(bool on)
|
||||
{
|
||||
if (on)
|
||||
m_fich[3U] |= 0x80U;
|
||||
else
|
||||
m_fich[3U] &= 0x7FU;
|
||||
}
|
||||
|
||||
void CYSFFICH::setSQ(unsigned char sq)
|
||||
{
|
||||
m_fich[3U] &= 0x80U;
|
||||
m_fich[3U] |= sq & 0x7FU;
|
||||
}
|
||||
|
||||
void CYSFFICH::setBN(unsigned char bn)
|
||||
{
|
||||
m_fich[0U] &= 0xFCU;
|
||||
m_fich[0U] |= bn & 0x03U;
|
||||
}
|
||||
|
||||
void CYSFFICH::setBT(unsigned char bt)
|
||||
{
|
||||
m_fich[1U] &= 0x3FU;
|
||||
m_fich[1U] |= (bt << 6) & 0xC0U;
|
||||
}
|
||||
|
||||
void CYSFFICH::load(const unsigned char* fich)
|
||||
{
|
||||
assert(fich != NULL);
|
||||
|
||||
::memcpy(m_fich, fich, 4U);
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2018 by Andy Uribe CA6JAU
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#if !defined(YSFFICH_H)
|
||||
#define YSFFICH_H
|
||||
|
||||
class CYSFFICH {
|
||||
public:
|
||||
CYSFFICH();
|
||||
~CYSFFICH();
|
||||
|
||||
bool decode(const unsigned char* bytes);
|
||||
|
||||
void encode(unsigned char* bytes);
|
||||
|
||||
unsigned char getFI() const;
|
||||
unsigned char getCS() const;
|
||||
unsigned char getCM() const;
|
||||
unsigned char getBN() const;
|
||||
unsigned char getBT() const;
|
||||
unsigned char getFN() const;
|
||||
unsigned char getFT() const;
|
||||
unsigned char getDT() const;
|
||||
unsigned char getMR() const;
|
||||
bool getDev() const;
|
||||
bool getSQL() const;
|
||||
unsigned char getSQ() const;
|
||||
|
||||
void setFI(unsigned char fi);
|
||||
void setCS(unsigned char cs);
|
||||
void setCM(unsigned char cm);
|
||||
void setFN(unsigned char fn);
|
||||
void setFT(unsigned char ft);
|
||||
void setBN(unsigned char bn);
|
||||
void setBT(unsigned char bt);
|
||||
void setDT(unsigned char dt);
|
||||
void setMR(unsigned char mr);
|
||||
void setVoIP(bool set);
|
||||
void setDev(bool set);
|
||||
void setSQL(bool set);
|
||||
void setSQ(unsigned char sq);
|
||||
|
||||
void load(const unsigned char* fich);
|
||||
|
||||
private:
|
||||
unsigned char* m_fich;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,60 @@
|
|||
//
|
||||
// cysfnode.cpp
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 08/10/2019.
|
||||
// Copyright © 2019 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include <string.h>
|
||||
#include "main.h"
|
||||
#include "cysfnode.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
///// constructor
|
||||
|
||||
CYsfNode::CYsfNode()
|
||||
{
|
||||
m_uiTxFreq = 0;
|
||||
m_uiRxFreq = 0;
|
||||
}
|
||||
|
||||
CYsfNode::CYsfNode(const CCallsign &callsign, uint32 txfreq, uint32 rxfreq)
|
||||
{
|
||||
m_Callsign = callsign;
|
||||
m_uiTxFreq = txfreq;
|
||||
m_uiRxFreq = rxfreq;
|
||||
}
|
||||
|
||||
CYsfNode::CYsfNode(const CYsfNode &node)
|
||||
{
|
||||
m_Callsign = node.m_Callsign;
|
||||
m_uiTxFreq = node.m_uiTxFreq;
|
||||
m_uiRxFreq = node.m_uiRxFreq;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// get
|
||||
|
||||
bool CYsfNode::IsValid(void) const
|
||||
{
|
||||
return m_Callsign.IsValid();
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
//
|
||||
// cysfnode.h
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 08/10/2019.
|
||||
// Copyright © 2019 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef cysfnode_h
|
||||
#define cysfnode_h
|
||||
|
||||
#include "main.h"
|
||||
#include "ccallsign.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// define
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CYsfNode
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CYsfNode();
|
||||
CYsfNode(const CCallsign &, uint32, uint32);
|
||||
CYsfNode(const CYsfNode &);
|
||||
|
||||
// destructor
|
||||
virtual ~CYsfNode() {}
|
||||
|
||||
// get
|
||||
uint32 GetTxFrequency(void) const { return m_uiTxFreq; }
|
||||
uint32 GetRxFrequency(void) const { return m_uiRxFreq; }
|
||||
bool IsValid(void) const;
|
||||
|
||||
protected:
|
||||
// data
|
||||
CCallsign m_Callsign;
|
||||
uint32 m_uiTxFreq;
|
||||
uint32 m_uiRxFreq;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#endif /* cysfnode_h */
|
|
@ -0,0 +1,135 @@
|
|||
//
|
||||
// cysfnodedir.cpp
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 08/10/2019.
|
||||
// Copyright © 2019 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include <string.h>
|
||||
#include "main.h"
|
||||
#include "creflector.h"
|
||||
#include "cysfnodedir.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructor & destructor
|
||||
|
||||
CYsfNodeDir::CYsfNodeDir()
|
||||
{
|
||||
m_bStopThread = false;
|
||||
m_pThread = NULL;
|
||||
}
|
||||
|
||||
CYsfNodeDir::~CYsfNodeDir()
|
||||
{
|
||||
// kill threads
|
||||
m_bStopThread = true;
|
||||
if ( m_pThread != NULL )
|
||||
{
|
||||
m_pThread->join();
|
||||
delete m_pThread;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// init & close
|
||||
|
||||
bool CYsfNodeDir::Init(void)
|
||||
{
|
||||
// load content
|
||||
Reload();
|
||||
|
||||
// reset stop flag
|
||||
m_bStopThread = false;
|
||||
|
||||
// start thread;
|
||||
m_pThread = new std::thread(CYsfNodeDir::Thread, this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CYsfNodeDir::Close(void)
|
||||
{
|
||||
m_bStopThread = true;
|
||||
if ( m_pThread != NULL )
|
||||
{
|
||||
m_pThread->join();
|
||||
delete m_pThread;
|
||||
m_pThread = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// thread
|
||||
|
||||
void CYsfNodeDir::Thread(CYsfNodeDir *This)
|
||||
{
|
||||
while ( !This->m_bStopThread )
|
||||
{
|
||||
// Wait 30 seconds
|
||||
CTimePoint::TaskSleepFor(YSFNODEDB_REFRESH_RATE * 60000);
|
||||
|
||||
// have lists files changed ?
|
||||
if ( This->NeedReload() )
|
||||
{
|
||||
This->Reload();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Reload
|
||||
|
||||
bool CYsfNodeDir::Reload(void)
|
||||
{
|
||||
CBuffer buffer;
|
||||
bool ok = false;
|
||||
|
||||
if ( LoadContent(&buffer) )
|
||||
{
|
||||
Lock();
|
||||
{
|
||||
ok = RefreshContent(buffer);
|
||||
}
|
||||
Unlock();
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// find
|
||||
|
||||
bool CYsfNodeDir::FindFrequencies(const CCallsign &callsign, uint32 *txfreq, uint32 *rxfreq)
|
||||
{
|
||||
auto found = find(callsign);
|
||||
if ( found != end() )
|
||||
{
|
||||
*txfreq = found->second.GetTxFrequency();
|
||||
*rxfreq = found->second.GetRxFrequency();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
*txfreq = YSF_DEFAULT_NODE_TX_FREQ;
|
||||
*rxfreq = YSF_DEFAULT_NODE_RX_FREQ;
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
//
|
||||
// cysfnodedir.h
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 08/10/2019.
|
||||
// Copyright © 2019 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef cysfnodedir_h
|
||||
#define cysfnodedir_h
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include "cbuffer.h"
|
||||
#include "ccallsign.h"
|
||||
#include "cysfnode.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// define
|
||||
|
||||
|
||||
// compare function for std::map::find
|
||||
|
||||
struct CYsfNodeDirCallsignCompare
|
||||
{
|
||||
bool operator() (const CCallsign &cs1, const CCallsign &cs2) const
|
||||
{ return cs1.HasLowerCallsign(cs2);}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CYsfNodeDir : public std::map <CCallsign, CYsfNode, CYsfNodeDirCallsignCompare>
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CYsfNodeDir();
|
||||
// destructor
|
||||
virtual ~CYsfNodeDir();
|
||||
|
||||
// init & close
|
||||
virtual bool Init(void);
|
||||
virtual void Close(void);
|
||||
|
||||
// locks
|
||||
void Lock(void) { m_Mutex.lock(); }
|
||||
void Unlock(void) { m_Mutex.unlock(); }
|
||||
|
||||
// refresh
|
||||
virtual bool LoadContent(CBuffer *) { return false; }
|
||||
virtual bool RefreshContent(const CBuffer &) { return false; }
|
||||
|
||||
// find
|
||||
bool FindFrequencies(const CCallsign &, uint32 *, uint32 *);
|
||||
|
||||
protected:
|
||||
// thread
|
||||
static void Thread(CYsfNodeDir *);
|
||||
|
||||
// reload helpers
|
||||
bool Reload(void);
|
||||
virtual bool NeedReload(void) { return false; }
|
||||
//bool IsValidDmrid(const char *);
|
||||
|
||||
|
||||
protected:
|
||||
// Lock()
|
||||
std::mutex m_Mutex;
|
||||
|
||||
// thread
|
||||
bool m_bStopThread;
|
||||
std::thread *m_pThread;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#endif /* cysfnodedir_h */
|
|
@ -0,0 +1,167 @@
|
|||
//
|
||||
// cysfnodedirfile.cpp
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 08/10/2019.
|
||||
// Copyright © 2019 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include "main.h"
|
||||
#include "cysfnodedirfile.h"
|
||||
|
||||
|
||||
#if (YSFNODEDB_USE_RLX_SERVER == 0)
|
||||
CYsfNodeDirFile g_YsfNodeDir;
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructor & destructor
|
||||
|
||||
CYsfNodeDirFile::CYsfNodeDirFile()
|
||||
{
|
||||
::memset(&m_LastModTime, 0, sizeof(time_t));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// init & close
|
||||
|
||||
bool CYsfNodeDirFile::Init(void)
|
||||
{
|
||||
return CYsfNodeDir::Init();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// refresh
|
||||
|
||||
bool CYsfNodeDirFile::NeedReload(void)
|
||||
{
|
||||
bool needReload = false;
|
||||
|
||||
time_t time;
|
||||
if ( GetLastModTime(&time) )
|
||||
{
|
||||
needReload = time != m_LastModTime;
|
||||
}
|
||||
return needReload;
|
||||
}
|
||||
|
||||
bool CYsfNodeDirFile::LoadContent(CBuffer *buffer)
|
||||
{
|
||||
bool ok = false;
|
||||
std::ifstream file;
|
||||
std::streampos size;
|
||||
|
||||
// open file
|
||||
file.open(YSFNODEDB_PATH, std::ios::in | std::ios::binary | std::ios::ate);
|
||||
if ( file.is_open() )
|
||||
{
|
||||
// read file
|
||||
size = file.tellg();
|
||||
if ( size > 0 )
|
||||
{
|
||||
// read file into buffer
|
||||
buffer->resize((int)size+1);
|
||||
file.seekg (0, std::ios::beg);
|
||||
file.read((char *)buffer->data(), (int)size);
|
||||
|
||||
// close file
|
||||
file.close();
|
||||
|
||||
// update time
|
||||
GetLastModTime(&m_LastModTime);
|
||||
|
||||
// done
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
// done
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool CYsfNodeDirFile::RefreshContent(const CBuffer &buffer)
|
||||
{
|
||||
bool ok = false;
|
||||
|
||||
// clear directory
|
||||
clear();
|
||||
|
||||
// scan buffer
|
||||
if ( buffer.size() > 0 )
|
||||
{
|
||||
// crack it
|
||||
char *ptr1 = (char *)buffer.data();
|
||||
char *ptr2;
|
||||
|
||||
// get next line
|
||||
while ( (ptr2 = ::strchr(ptr1, '\n')) != NULL )
|
||||
{
|
||||
*ptr2 = 0;
|
||||
// get items
|
||||
char *callsign;
|
||||
char *txfreq;
|
||||
char *rxfreq;
|
||||
if ( ((callsign = ::strtok(ptr1, ";")) != NULL) )
|
||||
{
|
||||
if ( ((txfreq = ::strtok(NULL, ";")) != NULL) )
|
||||
{
|
||||
if ( ((rxfreq = ::strtok(NULL, ";")) != NULL) )
|
||||
{
|
||||
// new entry
|
||||
CCallsign cs(callsign);
|
||||
CYsfNode node(cs, atoi(txfreq), atoi(rxfreq));
|
||||
if ( cs.IsValid() && node.IsValid() )
|
||||
{
|
||||
insert(std::pair<CCallsign, CYsfNode>(cs, node));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// next line
|
||||
ptr1 = ptr2+1;
|
||||
}
|
||||
|
||||
// done
|
||||
ok = true;
|
||||
}
|
||||
|
||||
|
||||
// report
|
||||
std::cout << "Read " << size() << " YSF nodes from file " << YSFNODEDB_PATH << std::endl;
|
||||
|
||||
// done
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
bool CYsfNodeDirFile::GetLastModTime(time_t *time)
|
||||
{
|
||||
bool ok = false;
|
||||
|
||||
struct stat fileStat;
|
||||
if( ::stat(YSFNODEDB_PATH, &fileStat) != -1 )
|
||||
{
|
||||
*time = fileStat.st_mtime;
|
||||
ok = true;
|
||||
}
|
||||
return ok;
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
//
|
||||
// cysfnodedirfile.h
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 08/10/2019.
|
||||
// Copyright © 2019 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef cysfnodedirfile_h
|
||||
#define cysfnodedirfile_h
|
||||
|
||||
#include "cysfnodedir.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CYsfNodeDirFile : public CYsfNodeDir
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CYsfNodeDirFile();
|
||||
|
||||
// destructor
|
||||
~CYsfNodeDirFile() {}
|
||||
|
||||
// init & close
|
||||
bool Init(void);
|
||||
|
||||
// refresh
|
||||
bool LoadContent(CBuffer *);
|
||||
bool RefreshContent(const CBuffer &);
|
||||
|
||||
protected:
|
||||
// reload helpers
|
||||
bool NeedReload(void);
|
||||
bool GetLastModTime(time_t *);
|
||||
|
||||
protected:
|
||||
// data
|
||||
time_t m_LastModTime;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#endif /* cysfnodedirfile_h */
|
|
@ -0,0 +1,184 @@
|
|||
//
|
||||
// cysfnodedirhttp.cpp
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 08/10/2019.
|
||||
// Copyright © 2019 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include <string.h>
|
||||
#include "main.h"
|
||||
#include "creflector.h"
|
||||
#include "cysfnodedirhttp.h"
|
||||
|
||||
#if (YSFNODEDB_USE_RLX_SERVER == 1)
|
||||
CYsfNodeDirHttp g_YsfNodeDir;
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// refresh
|
||||
|
||||
bool CYsfNodeDirHttp::LoadContent(CBuffer *buffer)
|
||||
{
|
||||
// get file from xlxapi server
|
||||
return HttpGet("xlxapi.rlx.lu", "api/exportysfrepeaters.php", 80, buffer);
|
||||
}
|
||||
|
||||
bool CYsfNodeDirHttp::RefreshContent(const CBuffer &buffer)
|
||||
{
|
||||
bool ok = false;
|
||||
|
||||
// clear directory
|
||||
clear();
|
||||
|
||||
// scan buffer
|
||||
if ( buffer.size() > 0 )
|
||||
{
|
||||
// crack it
|
||||
char *ptr1 = (char *)buffer.data();
|
||||
char *ptr2;
|
||||
|
||||
// get next line
|
||||
while ( (ptr2 = ::strchr(ptr1, '\n')) != NULL )
|
||||
{
|
||||
*ptr2 = 0;
|
||||
// get items
|
||||
char *callsign;
|
||||
char *txfreq;
|
||||
char *rxfreq;
|
||||
if ( ((callsign = ::strtok(ptr1, ";")) != NULL) )
|
||||
{
|
||||
if ( ((txfreq = ::strtok(NULL, ";")) != NULL) )
|
||||
{
|
||||
if ( ((rxfreq = ::strtok(NULL, ";")) != NULL) )
|
||||
{
|
||||
// new entry
|
||||
CCallsign cs(callsign);
|
||||
CYsfNode node(cs, atoi(txfreq), atoi(rxfreq));
|
||||
if ( cs.IsValid() && node.IsValid() )
|
||||
{
|
||||
insert(std::pair<CCallsign, CYsfNode>(cs, node));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// next line
|
||||
ptr1 = ptr2+1;
|
||||
}
|
||||
|
||||
// done
|
||||
ok = true;
|
||||
}
|
||||
|
||||
// report
|
||||
std::cout << "Read " << size() << " YSF nodes from xlxapi.rlx.lu database " << std::endl;
|
||||
|
||||
// done
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// httpd helpers
|
||||
|
||||
#define YSFNODE_HTTPGET_SIZEMAX (256)
|
||||
|
||||
bool CYsfNodeDirHttp::HttpGet(const char *hostname, const char *filename, int port, CBuffer *buffer)
|
||||
{
|
||||
bool ok = false;
|
||||
int sock_id;
|
||||
|
||||
// open socket
|
||||
if ( (sock_id = ::socket(AF_INET, SOCK_STREAM, 0)) >= 0 )
|
||||
{
|
||||
// get hostname address
|
||||
struct sockaddr_in servaddr;
|
||||
struct hostent *hp;
|
||||
::memset(&servaddr,0,sizeof(servaddr));
|
||||
if( (hp = gethostbyname(hostname)) != NULL )
|
||||
{
|
||||
// dns resolved
|
||||
::memcpy((char *)&servaddr.sin_addr.s_addr, (char *)hp->h_addr, hp->h_length);
|
||||
servaddr.sin_port = htons(port);
|
||||
servaddr.sin_family = AF_INET;
|
||||
|
||||
// connect
|
||||
if ( ::connect(sock_id, (struct sockaddr *)&servaddr, sizeof(servaddr)) == 0)
|
||||
{
|
||||
// send the GET request
|
||||
char request[YSFNODE_HTTPGET_SIZEMAX];
|
||||
::sprintf(request, "GET /%s HTTP/1.0\r\nFrom: %s\r\nUser-Agent: xlxd\r\n\r\n",
|
||||
filename, (const char *)g_Reflector.GetCallsign());
|
||||
::write(sock_id, request, strlen(request));
|
||||
|
||||
// config receive timeouts
|
||||
fd_set read_set;
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = 5;
|
||||
timeout.tv_usec = 0;
|
||||
FD_ZERO(&read_set);
|
||||
FD_SET(sock_id, &read_set);
|
||||
|
||||
// get the reply back
|
||||
buffer->clear();
|
||||
bool done = false;
|
||||
do
|
||||
{
|
||||
char buf[1440];
|
||||
ssize_t len = 0;
|
||||
select(sock_id+1, &read_set, NULL, NULL, &timeout);
|
||||
//if ( (ret > 0) || ((ret < 0) && (errno == EINPROGRESS)) )
|
||||
//if ( ret >= 0 )
|
||||
//{
|
||||
usleep(5000);
|
||||
len = read(sock_id, buf, 1440);
|
||||
if ( len > 0 )
|
||||
{
|
||||
buffer->Append((uint8 *)buf, (int)len);
|
||||
ok = true;
|
||||
}
|
||||
//}
|
||||
done = (len <= 0);
|
||||
|
||||
} while (!done);
|
||||
buffer->Append((uint8)0);
|
||||
|
||||
// and disconnect
|
||||
close(sock_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Cannot establish connection with host " << hostname << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Host " << hostname << " not found" << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Failed to open wget socket" << std::endl;
|
||||
}
|
||||
|
||||
// done
|
||||
return ok;
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
//
|
||||
// cysfnodedirhttp.h
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 08/10/2019.
|
||||
// Copyright © 2019 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef cysfnodedirhttp_h
|
||||
#define cysfnodedirhttp_h
|
||||
|
||||
|
||||
#include "cysfnodedir.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CYsfNodeDirHttp : public CYsfNodeDir
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CYsfNodeDirHttp() {}
|
||||
|
||||
// destructor
|
||||
~CYsfNodeDirHttp() {}
|
||||
|
||||
// refresh
|
||||
bool LoadContent(CBuffer *);
|
||||
bool RefreshContent(const CBuffer &);
|
||||
|
||||
protected:
|
||||
// reload helpers
|
||||
bool NeedReload(void) { return true; }
|
||||
bool HttpGet(const char *, const char *, int, CBuffer *);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#endif /* cysfnodedirhttp_h */
|
|
@ -0,0 +1,626 @@
|
|||
/*
|
||||
* Copyright (C) 2016,2017 Jonathan Naylor, G4KLX
|
||||
* Copyright (C) 2016 Mathias Weyland, HB9FRV
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "cysfconvolution.h"
|
||||
#include "cysfpayload.h"
|
||||
#include "ysfdefines.h"
|
||||
#include "cutils.h"
|
||||
#include "ccrc.h"
|
||||
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <cstdint>
|
||||
|
||||
const unsigned int INTERLEAVE_TABLE_9_20[] = {
|
||||
0U, 40U, 80U, 120U, 160U, 200U, 240U, 280U, 320U,
|
||||
2U, 42U, 82U, 122U, 162U, 202U, 242U, 282U, 322U,
|
||||
4U, 44U, 84U, 124U, 164U, 204U, 244U, 284U, 324U,
|
||||
6U, 46U, 86U, 126U, 166U, 206U, 246U, 286U, 326U,
|
||||
8U, 48U, 88U, 128U, 168U, 208U, 248U, 288U, 328U,
|
||||
10U, 50U, 90U, 130U, 170U, 210U, 250U, 290U, 330U,
|
||||
12U, 52U, 92U, 132U, 172U, 212U, 252U, 292U, 332U,
|
||||
14U, 54U, 94U, 134U, 174U, 214U, 254U, 294U, 334U,
|
||||
16U, 56U, 96U, 136U, 176U, 216U, 256U, 296U, 336U,
|
||||
18U, 58U, 98U, 138U, 178U, 218U, 258U, 298U, 338U,
|
||||
20U, 60U, 100U, 140U, 180U, 220U, 260U, 300U, 340U,
|
||||
22U, 62U, 102U, 142U, 182U, 222U, 262U, 302U, 342U,
|
||||
24U, 64U, 104U, 144U, 184U, 224U, 264U, 304U, 344U,
|
||||
26U, 66U, 106U, 146U, 186U, 226U, 266U, 306U, 346U,
|
||||
28U, 68U, 108U, 148U, 188U, 228U, 268U, 308U, 348U,
|
||||
30U, 70U, 110U, 150U, 190U, 230U, 270U, 310U, 350U,
|
||||
32U, 72U, 112U, 152U, 192U, 232U, 272U, 312U, 352U,
|
||||
34U, 74U, 114U, 154U, 194U, 234U, 274U, 314U, 354U,
|
||||
36U, 76U, 116U, 156U, 196U, 236U, 276U, 316U, 356U,
|
||||
38U, 78U, 118U, 158U, 198U, 238U, 278U, 318U, 358U};
|
||||
|
||||
const unsigned int INTERLEAVE_TABLE_5_20[] = {
|
||||
0U, 40U, 80U, 120U, 160U,
|
||||
2U, 42U, 82U, 122U, 162U,
|
||||
4U, 44U, 84U, 124U, 164U,
|
||||
6U, 46U, 86U, 126U, 166U,
|
||||
8U, 48U, 88U, 128U, 168U,
|
||||
10U, 50U, 90U, 130U, 170U,
|
||||
12U, 52U, 92U, 132U, 172U,
|
||||
14U, 54U, 94U, 134U, 174U,
|
||||
16U, 56U, 96U, 136U, 176U,
|
||||
18U, 58U, 98U, 138U, 178U,
|
||||
20U, 60U, 100U, 140U, 180U,
|
||||
22U, 62U, 102U, 142U, 182U,
|
||||
24U, 64U, 104U, 144U, 184U,
|
||||
26U, 66U, 106U, 146U, 186U,
|
||||
28U, 68U, 108U, 148U, 188U,
|
||||
30U, 70U, 110U, 150U, 190U,
|
||||
32U, 72U, 112U, 152U, 192U,
|
||||
34U, 74U, 114U, 154U, 194U,
|
||||
36U, 76U, 116U, 156U, 196U,
|
||||
38U, 78U, 118U, 158U, 198U};
|
||||
|
||||
// This one differs from the others in that it interleaves bits and not dibits
|
||||
const unsigned char WHITENING_DATA[] = {0x93U, 0xD7U, 0x51U, 0x21U, 0x9CU, 0x2FU, 0x6CU, 0xD0U, 0xEFU, 0x0FU,
|
||||
0xF8U, 0x3DU, 0xF1U, 0x73U, 0x20U, 0x94U, 0xEDU, 0x1EU, 0x7CU, 0xD8U};
|
||||
|
||||
const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
||||
|
||||
#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
|
||||
#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
|
||||
|
||||
CYSFPayload::CYSFPayload() :
|
||||
m_uplink(NULL),
|
||||
m_downlink(NULL),
|
||||
m_source(NULL),
|
||||
m_dest(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
CYSFPayload::~CYSFPayload()
|
||||
{
|
||||
delete[] m_uplink;
|
||||
delete[] m_downlink;
|
||||
delete[] m_source;
|
||||
delete[] m_dest;
|
||||
}
|
||||
|
||||
bool CYSFPayload::processHeaderData(unsigned char* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
|
||||
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||
|
||||
unsigned char dch[45U];
|
||||
|
||||
unsigned char* p1 = data;
|
||||
unsigned char* p2 = dch;
|
||||
for (unsigned int i = 0U; i < 5U; i++) {
|
||||
::memcpy(p2, p1, 9U);
|
||||
p1 += 18U; p2 += 9U;
|
||||
}
|
||||
|
||||
CYSFConvolution conv;
|
||||
conv.start();
|
||||
|
||||
for (unsigned int i = 0U; i < 180U; i++) {
|
||||
unsigned int n = INTERLEAVE_TABLE_9_20[i];
|
||||
uint8_t s0 = READ_BIT1(dch, n) ? 1U : 0U;
|
||||
|
||||
n++;
|
||||
uint8_t s1 = READ_BIT1(dch, n) ? 1U : 0U;
|
||||
|
||||
conv.decode(s0, s1);
|
||||
}
|
||||
|
||||
unsigned char output[23U];
|
||||
conv.chainback(output, 176U);
|
||||
|
||||
bool valid1 = CCRC::checkCCITT162(output, 22U);
|
||||
if (valid1) {
|
||||
for (unsigned int i = 0U; i < 20U; i++)
|
||||
output[i] ^= WHITENING_DATA[i];
|
||||
|
||||
if (m_dest == NULL) {
|
||||
m_dest = new unsigned char[YSF_CALLSIGN_LENGTH];
|
||||
::memcpy(m_dest, output + 0U, YSF_CALLSIGN_LENGTH);
|
||||
}
|
||||
|
||||
if (m_source == NULL) {
|
||||
m_source = new unsigned char[YSF_CALLSIGN_LENGTH];
|
||||
::memcpy(m_source, output + YSF_CALLSIGN_LENGTH, YSF_CALLSIGN_LENGTH);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0U; i < 20U; i++)
|
||||
output[i] ^= WHITENING_DATA[i];
|
||||
|
||||
CCRC::addCCITT162(output, 22U);
|
||||
output[22U] = 0x00U;
|
||||
|
||||
unsigned char convolved[45U];
|
||||
conv.encode(output, convolved, 180U);
|
||||
|
||||
unsigned char bytes[45U];
|
||||
unsigned int j = 0U;
|
||||
for (unsigned int i = 0U; i < 180U; i++) {
|
||||
unsigned int n = INTERLEAVE_TABLE_9_20[i];
|
||||
|
||||
bool s0 = READ_BIT1(convolved, j) != 0U;
|
||||
j++;
|
||||
|
||||
bool s1 = READ_BIT1(convolved, j) != 0U;
|
||||
j++;
|
||||
|
||||
WRITE_BIT1(bytes, n, s0);
|
||||
|
||||
n++;
|
||||
WRITE_BIT1(bytes, n, s1);
|
||||
}
|
||||
|
||||
p1 = data;
|
||||
p2 = bytes;
|
||||
for (unsigned int i = 0U; i < 5U; i++) {
|
||||
::memcpy(p1, p2, 9U);
|
||||
p1 += 18U; p2 += 9U;
|
||||
}
|
||||
}
|
||||
|
||||
p1 = data + 9U;
|
||||
p2 = dch;
|
||||
for (unsigned int i = 0U; i < 5U; i++) {
|
||||
::memcpy(p2, p1, 9U);
|
||||
p1 += 18U; p2 += 9U;
|
||||
}
|
||||
|
||||
conv.start();
|
||||
|
||||
for (unsigned int i = 0U; i < 180U; i++) {
|
||||
unsigned int n = INTERLEAVE_TABLE_9_20[i];
|
||||
uint8_t s0 = READ_BIT1(dch, n) ? 1U : 0U;
|
||||
|
||||
n++;
|
||||
uint8_t s1 = READ_BIT1(dch, n) ? 1U : 0U;
|
||||
|
||||
conv.decode(s0, s1);
|
||||
}
|
||||
|
||||
conv.chainback(output, 176U);
|
||||
|
||||
bool valid2 = CCRC::checkCCITT162(output, 22U);
|
||||
if (valid2) {
|
||||
for (unsigned int i = 0U; i < 20U; i++)
|
||||
output[i] ^= WHITENING_DATA[i];
|
||||
|
||||
if (m_downlink != NULL)
|
||||
::memcpy(output + 0U, m_downlink, YSF_CALLSIGN_LENGTH);
|
||||
|
||||
if (m_uplink != NULL)
|
||||
::memcpy(output + YSF_CALLSIGN_LENGTH, m_uplink, YSF_CALLSIGN_LENGTH);
|
||||
|
||||
for (unsigned int i = 0U; i < 20U; i++)
|
||||
output[i] ^= WHITENING_DATA[i];
|
||||
|
||||
CCRC::addCCITT162(output, 22U);
|
||||
output[22U] = 0x00U;
|
||||
|
||||
unsigned char convolved[45U];
|
||||
conv.encode(output, convolved, 180U);
|
||||
|
||||
unsigned char bytes[45U];
|
||||
unsigned int j = 0U;
|
||||
for (unsigned int i = 0U; i < 180U; i++) {
|
||||
unsigned int n = INTERLEAVE_TABLE_9_20[i];
|
||||
|
||||
bool s0 = READ_BIT1(convolved, j) != 0U;
|
||||
j++;
|
||||
|
||||
bool s1 = READ_BIT1(convolved, j) != 0U;
|
||||
j++;
|
||||
|
||||
WRITE_BIT1(bytes, n, s0);
|
||||
|
||||
n++;
|
||||
WRITE_BIT1(bytes, n, s1);
|
||||
}
|
||||
|
||||
p1 = data + 9U;
|
||||
p2 = bytes;
|
||||
for (unsigned int i = 0U; i < 5U; i++) {
|
||||
::memcpy(p1, p2, 9U);
|
||||
p1 += 18U; p2 += 9U;
|
||||
}
|
||||
}
|
||||
|
||||
return valid1;
|
||||
}
|
||||
|
||||
bool CYSFPayload::readDataFRModeData1(const unsigned char* data, unsigned char* dt)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(dt != NULL);
|
||||
|
||||
::memset(dt, ' ', 20U);
|
||||
|
||||
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||
|
||||
unsigned char dch[45U];
|
||||
|
||||
const unsigned char* p1 = data;
|
||||
unsigned char* p2 = dch;
|
||||
for (unsigned int i = 0U; i < 5U; i++) {
|
||||
::memcpy(p2, p1, 9U);
|
||||
p1 += 18U; p2 += 9U;
|
||||
}
|
||||
|
||||
CYSFConvolution conv;
|
||||
conv.start();
|
||||
|
||||
for (unsigned int i = 0U; i < 180U; i++) {
|
||||
unsigned int n = INTERLEAVE_TABLE_9_20[i];
|
||||
uint8_t s0 = READ_BIT1(dch, n) ? 1U : 0U;
|
||||
|
||||
n++;
|
||||
uint8_t s1 = READ_BIT1(dch, n) ? 1U : 0U;
|
||||
|
||||
conv.decode(s0, s1);
|
||||
}
|
||||
|
||||
unsigned char output[23U];
|
||||
conv.chainback(output, 176U);
|
||||
|
||||
bool ret = CCRC::checkCCITT162(output, 22U);
|
||||
if (ret) {
|
||||
for (unsigned int i = 0U; i < 20U; i++)
|
||||
output[i] ^= WHITENING_DATA[i];
|
||||
|
||||
// CUtils::dump(1U, "FR Mode Data 1", output, 20U);
|
||||
|
||||
::memcpy(dt, output, 20U);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CYSFPayload::readDataFRModeData2(const unsigned char* data, unsigned char* dt)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(dt != NULL);
|
||||
|
||||
::memset(dt, ' ', 20U);
|
||||
|
||||
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||
|
||||
unsigned char dch[45U];
|
||||
|
||||
const unsigned char* p1 = data + 9U;
|
||||
unsigned char* p2 = dch;
|
||||
for (unsigned int i = 0U; i < 5U; i++) {
|
||||
::memcpy(p2, p1, 9U);
|
||||
p1 += 18U; p2 += 9U;
|
||||
}
|
||||
|
||||
CYSFConvolution conv;
|
||||
conv.start();
|
||||
|
||||
for (unsigned int i = 0U; i < 180U; i++) {
|
||||
unsigned int n = INTERLEAVE_TABLE_9_20[i];
|
||||
uint8_t s0 = READ_BIT1(dch, n) ? 1U : 0U;
|
||||
|
||||
n++;
|
||||
uint8_t s1 = READ_BIT1(dch, n) ? 1U : 0U;
|
||||
|
||||
conv.decode(s0, s1);
|
||||
}
|
||||
|
||||
unsigned char output[23U];
|
||||
conv.chainback(output, 176U);
|
||||
|
||||
bool ret = CCRC::checkCCITT162(output, 22U);
|
||||
if (ret) {
|
||||
for (unsigned int i = 0U; i < 20U; i++)
|
||||
output[i] ^= WHITENING_DATA[i];
|
||||
|
||||
// CUtils::dump(1U, "FR Mode Data 2", output, 20U);
|
||||
|
||||
::memcpy(dt, output, 20U);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CYSFPayload::writeVDMode2Data(unsigned char* data, const unsigned char* dt)
|
||||
{
|
||||
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||
|
||||
unsigned char dt_tmp[13];
|
||||
::memcpy(dt_tmp, dt, YSF_CALLSIGN_LENGTH);
|
||||
|
||||
for (unsigned int i = 0U; i < 10U; i++)
|
||||
dt_tmp[i] ^= WHITENING_DATA[i];
|
||||
|
||||
CCRC::addCCITT162(dt_tmp, 12U);
|
||||
dt_tmp[12U] = 0x00U;
|
||||
|
||||
unsigned char convolved[25U];
|
||||
CYSFConvolution conv;
|
||||
conv.start();
|
||||
conv.encode(dt_tmp, convolved, 100U);
|
||||
|
||||
unsigned char bytes[25U];
|
||||
unsigned int j = 0U;
|
||||
for (unsigned int i = 0U; i < 100U; i++) {
|
||||
unsigned int n = INTERLEAVE_TABLE_5_20[i];
|
||||
|
||||
bool s0 = READ_BIT1(convolved, j) != 0U;
|
||||
j++;
|
||||
|
||||
bool s1 = READ_BIT1(convolved, j) != 0U;
|
||||
j++;
|
||||
|
||||
WRITE_BIT1(bytes, n, s0);
|
||||
|
||||
n++;
|
||||
WRITE_BIT1(bytes, n, s1);
|
||||
}
|
||||
|
||||
unsigned char* p1 = data;
|
||||
unsigned char* p2 = bytes;
|
||||
for (unsigned int i = 0U; i < 5U; i++) {
|
||||
::memcpy(p1, p2, 5U);
|
||||
p1 += 18U; p2 += 5U;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CYSFPayload::readVDMode1Data(const unsigned char* data, unsigned char* dt)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(dt != NULL);
|
||||
|
||||
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||
|
||||
unsigned char dch[45U];
|
||||
|
||||
const unsigned char* p1 = data;
|
||||
unsigned char* p2 = dch;
|
||||
for (unsigned int i = 0U; i < 5U; i++) {
|
||||
::memcpy(p2, p1, 9U);
|
||||
p1 += 18U; p2 += 9U;
|
||||
}
|
||||
|
||||
CYSFConvolution conv;
|
||||
conv.start();
|
||||
|
||||
for (unsigned int i = 0U; i < 180U; i++) {
|
||||
unsigned int n = INTERLEAVE_TABLE_9_20[i];
|
||||
uint8_t s0 = READ_BIT1(dch, n) ? 1U : 0U;
|
||||
|
||||
n++;
|
||||
uint8_t s1 = READ_BIT1(dch, n) ? 1U : 0U;
|
||||
|
||||
conv.decode(s0, s1);
|
||||
}
|
||||
|
||||
unsigned char output[23U];
|
||||
conv.chainback(output, 176U);
|
||||
|
||||
bool ret = CCRC::checkCCITT162(output, 22U);
|
||||
if (ret) {
|
||||
for (unsigned int i = 0U; i < 20U; i++)
|
||||
output[i] ^= WHITENING_DATA[i];
|
||||
|
||||
// CUtils::dump(1U, "V/D Mode 1 Data", output, 20U);
|
||||
|
||||
::memcpy(dt, output, 20U);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool CYSFPayload::readVDMode2Data(const unsigned char* data, unsigned char* dt)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(dt != NULL);
|
||||
|
||||
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||
|
||||
unsigned char dch[25U];
|
||||
|
||||
const unsigned char* p1 = data;
|
||||
unsigned char* p2 = dch;
|
||||
for (unsigned int i = 0U; i < 5U; i++) {
|
||||
::memcpy(p2, p1, 5U);
|
||||
p1 += 18U; p2 += 5U;
|
||||
}
|
||||
|
||||
CYSFConvolution conv;
|
||||
conv.start();
|
||||
|
||||
for (unsigned int i = 0U; i < 100U; i++) {
|
||||
unsigned int n = INTERLEAVE_TABLE_5_20[i];
|
||||
uint8_t s0 = READ_BIT1(dch, n) ? 1U : 0U;
|
||||
|
||||
n++;
|
||||
uint8_t s1 = READ_BIT1(dch, n) ? 1U : 0U;
|
||||
|
||||
conv.decode(s0, s1);
|
||||
}
|
||||
|
||||
unsigned char output[13U];
|
||||
conv.chainback(output, 96U);
|
||||
|
||||
bool ret = CCRC::checkCCITT162(output, 12U);
|
||||
if (ret) {
|
||||
for (unsigned int i = 0U; i < 10U; i++)
|
||||
output[i] ^= WHITENING_DATA[i];
|
||||
|
||||
// CUtils::dump(1U, "V/D Mode 2 Data", output, YSF_CALLSIGN_LENGTH);
|
||||
|
||||
::memcpy(dt, output, YSF_CALLSIGN_LENGTH);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CYSFPayload::writeHeader(unsigned char* data, const unsigned char* csd1, const unsigned char* csd2)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(csd1 != NULL);
|
||||
assert(csd2 != NULL);
|
||||
|
||||
writeDataFRModeData1(csd1, data);
|
||||
|
||||
writeDataFRModeData2(csd2, data);
|
||||
}
|
||||
|
||||
void CYSFPayload::writeDataFRModeData1(const unsigned char* dt, unsigned char* data)
|
||||
{
|
||||
assert(dt != NULL);
|
||||
assert(data != NULL);
|
||||
|
||||
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||
|
||||
unsigned char output[25U];
|
||||
for (unsigned int i = 0U; i < 20U; i++)
|
||||
output[i] = dt[i] ^ WHITENING_DATA[i];
|
||||
|
||||
CCRC::addCCITT162(output, 22U);
|
||||
output[22U] = 0x00U;
|
||||
|
||||
unsigned char convolved[45U];
|
||||
|
||||
CYSFConvolution conv;
|
||||
conv.encode(output, convolved, 180U);
|
||||
|
||||
unsigned char bytes[45U];
|
||||
unsigned int j = 0U;
|
||||
for (unsigned int i = 0U; i < 180U; i++) {
|
||||
unsigned int n = INTERLEAVE_TABLE_9_20[i];
|
||||
|
||||
bool s0 = READ_BIT1(convolved, j) != 0U;
|
||||
j++;
|
||||
|
||||
bool s1 = READ_BIT1(convolved, j) != 0U;
|
||||
j++;
|
||||
|
||||
WRITE_BIT1(bytes, n, s0);
|
||||
|
||||
n++;
|
||||
WRITE_BIT1(bytes, n, s1);
|
||||
}
|
||||
|
||||
unsigned char* p1 = data;
|
||||
unsigned char* p2 = bytes;
|
||||
for (unsigned int i = 0U; i < 5U; i++) {
|
||||
::memcpy(p1, p2, 9U);
|
||||
p1 += 18U; p2 += 9U;
|
||||
}
|
||||
}
|
||||
|
||||
void CYSFPayload::writeDataFRModeData2(const unsigned char* dt, unsigned char* data)
|
||||
{
|
||||
assert(dt != NULL);
|
||||
assert(data != NULL);
|
||||
|
||||
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||
|
||||
unsigned char output[25U];
|
||||
for (unsigned int i = 0U; i < 20U; i++)
|
||||
output[i] = dt[i] ^ WHITENING_DATA[i];
|
||||
|
||||
CCRC::addCCITT162(output, 22U);
|
||||
output[22U] = 0x00U;
|
||||
|
||||
unsigned char convolved[45U];
|
||||
|
||||
CYSFConvolution conv;
|
||||
conv.encode(output, convolved, 180U);
|
||||
|
||||
unsigned char bytes[45U];
|
||||
unsigned int j = 0U;
|
||||
for (unsigned int i = 0U; i < 180U; i++) {
|
||||
unsigned int n = INTERLEAVE_TABLE_9_20[i];
|
||||
|
||||
bool s0 = READ_BIT1(convolved, j) != 0U;
|
||||
j++;
|
||||
|
||||
bool s1 = READ_BIT1(convolved, j) != 0U;
|
||||
j++;
|
||||
|
||||
WRITE_BIT1(bytes, n, s0);
|
||||
|
||||
n++;
|
||||
WRITE_BIT1(bytes, n, s1);
|
||||
}
|
||||
|
||||
unsigned char* p1 = data + 9U;
|
||||
unsigned char* p2 = bytes;
|
||||
for (unsigned int i = 0U; i < 5U; i++) {
|
||||
::memcpy(p1, p2, 9U);
|
||||
p1 += 18U; p2 += 9U;
|
||||
}
|
||||
}
|
||||
|
||||
void CYSFPayload::setUplink(const std::string& callsign)
|
||||
{
|
||||
m_uplink = new unsigned char[YSF_CALLSIGN_LENGTH];
|
||||
|
||||
std::string uplink = callsign;
|
||||
uplink.resize(YSF_CALLSIGN_LENGTH, ' ');
|
||||
|
||||
for (unsigned int i = 0U; i < YSF_CALLSIGN_LENGTH; i++)
|
||||
m_uplink[i] = uplink.at(i);
|
||||
}
|
||||
|
||||
void CYSFPayload::setDownlink(const std::string& callsign)
|
||||
{
|
||||
m_downlink = new unsigned char[YSF_CALLSIGN_LENGTH];
|
||||
|
||||
std::string downlink = callsign;
|
||||
downlink.resize(YSF_CALLSIGN_LENGTH, ' ');
|
||||
|
||||
for (unsigned int i = 0U; i < YSF_CALLSIGN_LENGTH; i++)
|
||||
m_downlink[i] = downlink.at(i);
|
||||
}
|
||||
|
||||
std::string CYSFPayload::getSource()
|
||||
{
|
||||
std::string tmp;
|
||||
|
||||
if (m_dest)
|
||||
tmp.assign((const char *)m_source, YSF_CALLSIGN_LENGTH);
|
||||
else
|
||||
tmp = "";
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
std::string CYSFPayload::getDest()
|
||||
{
|
||||
std::string tmp;
|
||||
|
||||
if (m_dest)
|
||||
tmp.assign((const char *)m_dest, YSF_CALLSIGN_LENGTH);
|
||||
else
|
||||
tmp = "";
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void CYSFPayload::reset()
|
||||
{
|
||||
delete[] m_source;
|
||||
delete[] m_dest;
|
||||
|
||||
m_source = NULL;
|
||||
m_dest = NULL;
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#if !defined(YSFPayload_H)
|
||||
#define YSFPayload_H
|
||||
|
||||
#include <string>
|
||||
|
||||
class CYSFPayload {
|
||||
public:
|
||||
CYSFPayload();
|
||||
~CYSFPayload();
|
||||
|
||||
bool processHeaderData(unsigned char* bytes);
|
||||
|
||||
void writeVDMode2Data(unsigned char* data, const unsigned char* dt);
|
||||
bool readVDMode1Data(const unsigned char* data, unsigned char* dt);
|
||||
bool readVDMode2Data(const unsigned char* data, unsigned char* dt);
|
||||
|
||||
void writeHeader(unsigned char* data, const unsigned char* csd1, const unsigned char* csd2);
|
||||
|
||||
void writeDataFRModeData1(const unsigned char* dt, unsigned char* data);
|
||||
void writeDataFRModeData2(const unsigned char* dt, unsigned char* data);
|
||||
bool readDataFRModeData1(const unsigned char* data, unsigned char* dt);
|
||||
bool readDataFRModeData2(const unsigned char* data, unsigned char* dt);
|
||||
|
||||
std::string getSource();
|
||||
std::string getDest();
|
||||
|
||||
void setUplink(const std::string& callsign);
|
||||
void setDownlink(const std::string& callsign);
|
||||
|
||||
void reset();
|
||||
|
||||
private:
|
||||
unsigned char* m_uplink;
|
||||
unsigned char* m_downlink;
|
||||
unsigned char* m_source;
|
||||
unsigned char* m_dest;
|
||||
};
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,137 @@
|
|||
//
|
||||
// cysfprotocol.h
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 20/05/2018.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef cysfprotocol_h
|
||||
#define cysfprotocol_h
|
||||
|
||||
|
||||
#include "ctimepoint.h"
|
||||
#include "cprotocol.h"
|
||||
#include "cdvheaderpacket.h"
|
||||
#include "cdvframepacket.h"
|
||||
#include "cdvlastframepacket.h"
|
||||
#include "ysfdefines.h"
|
||||
#include "cysffich.h"
|
||||
#include "cwiresxinfo.h"
|
||||
#include "cwiresxcmdhandler.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// define
|
||||
|
||||
|
||||
// Wires-X commands
|
||||
#define WIRESX_CMD_UNKNOWN 0
|
||||
#define WIRESX_CMD_DX_REQ 1
|
||||
#define WIRESX_CMD_ALL_REQ 2
|
||||
#define WIRESX_CMD_SEARCH_REQ 3
|
||||
#define WIRESX_CMD_CONN_REQ 4
|
||||
#define WIRESX_CMD_DISC_REQ 5
|
||||
|
||||
// YSF Module ID
|
||||
#define YSF_MODULE_ID 'B'
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CYsfStreamCacheItem
|
||||
{
|
||||
public:
|
||||
CYsfStreamCacheItem() {}
|
||||
~CYsfStreamCacheItem() {}
|
||||
|
||||
CDvHeaderPacket m_dvHeader;
|
||||
CDvFramePacket m_dvFrames[5];
|
||||
|
||||
//uint8 m_uiSeqId;
|
||||
};
|
||||
|
||||
class CYsfProtocol : public CProtocol
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CYsfProtocol();
|
||||
|
||||
// destructor
|
||||
virtual ~CYsfProtocol() {};
|
||||
|
||||
// initialization
|
||||
bool Init(void);
|
||||
void Close(void);
|
||||
|
||||
// task
|
||||
void Task(void);
|
||||
|
||||
protected:
|
||||
// queue helper
|
||||
void HandleQueue(void);
|
||||
|
||||
// keepalive helpers
|
||||
void HandleKeepalives(void);
|
||||
|
||||
// stream helpers
|
||||
bool OnDvHeaderPacketIn(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 **);
|
||||
|
||||
// DV packet encoding helpers
|
||||
void EncodeConnectAckPacket(CBuffer *) const;
|
||||
//void EncodeConnectNackPacket(const CCallsign &, char, CBuffer *);
|
||||
//void EncodeDisconnectPacket(CBuffer *, CClient *);
|
||||
bool EncodeDvHeaderPacket(const CDvHeaderPacket &, CBuffer *) const;
|
||||
bool EncodeDvPacket(const CDvHeaderPacket &, const CDvFramePacket *, CBuffer *) const;
|
||||
bool EncodeDvLastPacket(const CDvHeaderPacket &, CBuffer *) const;
|
||||
|
||||
// Wires-X packet decoding helpers
|
||||
bool IsValidwirexPacket(const CBuffer &, CYSFFICH *, CCallsign *, int *, int*);
|
||||
|
||||
// uiStreamId helpers
|
||||
uint32 IpToStreamId(const CIp &) const;
|
||||
|
||||
// debug
|
||||
bool DebugTestDecodePacket(const CBuffer &);
|
||||
bool DebugDumpHeaderPacket(const CBuffer &);
|
||||
bool DebugDumpDvPacket(const CBuffer &);
|
||||
bool DebugDumpLastDvPacket(const CBuffer &);
|
||||
|
||||
protected:
|
||||
// for keep alive
|
||||
CTimePoint m_LastKeepaliveTime;
|
||||
|
||||
// for queue header caches
|
||||
std::array<CYsfStreamCacheItem, NB_OF_MODULES> m_StreamsCache;
|
||||
|
||||
// for wires-x
|
||||
CWiresxCmdHandler m_WiresxCmdHandler;
|
||||
unsigned char m_seqNo;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#endif /* cysfprotocol_h */
|
|
@ -0,0 +1,641 @@
|
|||
//
|
||||
// cysfutils.cpp
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 14/04/2019.
|
||||
// Copyright © 2019 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
// Copyright (C) 2016,2017 by Jonathan Naylor G4KLX
|
||||
// Copyright (C) 2018 by Andy Uribe CA6JAU
|
||||
// Copyright (C) 2018 by Manuel Sanchez EA7EE
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "main.h"
|
||||
#include <string.h>
|
||||
#include "ysfdefines.h"
|
||||
#include "cysfutils.h"
|
||||
#include "cgolay24128.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constants & defines
|
||||
|
||||
const unsigned int PRNG_TABLE[] = {
|
||||
0x42CC47U, 0x19D6FEU, 0x304729U, 0x6B2CD0U, 0x60BF47U, 0x39650EU, 0x7354F1U, 0xEACF60U, 0x819C9FU, 0xDE25CEU,
|
||||
0xD7B745U, 0x8CC8B8U, 0x8D592BU, 0xF71257U, 0xBCA084U, 0xA5B329U, 0xEE6AFAU, 0xF7D9A7U, 0xBCC21CU, 0x4712D9U,
|
||||
0x4F2922U, 0x14FA37U, 0x5D43ECU, 0x564115U, 0x299A92U, 0x20A9EBU, 0x7B707DU, 0x3BE3A4U, 0x20D95BU, 0x6B085AU,
|
||||
0x5233A5U, 0x99A474U, 0xC0EDCBU, 0xCB5F12U, 0x918455U, 0xF897ECU, 0xE32E3BU, 0xAA7CC2U, 0xB1E7C9U, 0xFC561DU,
|
||||
0xA70DE6U, 0x8DBE73U, 0xD4F608U, 0x57658DU, 0x0E5E56U, 0x458DABU, 0x7E15B8U, 0x376645U, 0x2DFD86U, 0x64EC3BU,
|
||||
0x3F1F60U, 0x3481B4U, 0x4DA00FU, 0x067BCEU, 0x1B68B1U, 0xD19328U, 0xCA03FFU, 0xA31856U, 0xF8EB81U, 0xF9F2F8U,
|
||||
0xA26067U, 0xA91BB6U, 0xF19A59U, 0x9A6148U, 0x8372B6U, 0xC8E86FU, 0x9399DCU, 0x1A0291U, 0x619142U, 0x6DE9FFU,
|
||||
0x367A2CU, 0x7D2511U, 0x6484DAU, 0x2F1F0FU, 0x1E6DB4U, 0x55F6E1U, 0x0EA70AU, 0x061C96U, 0xDD0E45U, 0xB4D738U,
|
||||
0xAF64ABU, 0xE47F42U, 0xFDBE9DU, 0xB684ACU, 0xFE5773U, 0xC1E4A2U, 0x8AFD0DU, 0x932ED4U, 0xD814E3U, 0x81853AU,
|
||||
0x225EECU, 0x7A6945U, 0x31A112U, 0x2AB2EBU, 0x630974U, 0x785AB5U, 0x11E3CEU, 0x4A715BU, 0x402AA0U, 0x199B7DU,
|
||||
0x16C05EU, 0x6F5283U, 0xA4FB10U, 0xBFA8ECU, 0xF633B7U, 0xEC4012U, 0xADD8C9U, 0xD6EB1CU, 0xDD3027U, 0x84A1FAU,
|
||||
0xCF9E19U, 0xD64C80U, 0xBC4557U, 0xA7B62EU, 0x6E2DA1U, 0x311F50U, 0x38C68EU, 0x63D5BFU, 0x486E60U, 0x10BFE1U,
|
||||
0x5BAD1EU, 0x4A4647U, 0x0157F0U, 0x7ACC29U, 0x73BEEAU, 0x2825D7U, 0xA0940CU, 0xFBCFF9U, 0xB05C62U, 0x892426U,
|
||||
0xC6B3DDU, 0xDF3840U, 0x9449B3U, 0xCED3BEU, 0xE7804DU, 0xBC3B90U, 0xF5AA0BU, 0xE6D17EU, 0x2D43B5U, 0x345A04U,
|
||||
0x5EA9DBU, 0x07A202U, 0x0C7134U, 0x45C9FDU, 0x5EDA0AU, 0x310193U, 0x6830C4U, 0x62AA3DU, 0x3B59B2U, 0xB04043U,
|
||||
0xEB975CU, 0x82BCADU, 0x912E62U, 0xD8F7FBU, 0x82C489U, 0x895F54U, 0xF00FE7U, 0xFBBC2AU, 0xA2E771U, 0xE956C4U,
|
||||
0xF6CD1FU, 0x3F8FEAU, 0x0534E1U, 0x4C653CU, 0x17FE8FU, 0x1C4C52U, 0x4515A1U, 0x2E86A9U, 0x3FBD56U, 0x756C87U,
|
||||
0x6ED218U, 0x279179U, 0x7C0AA6U, 0xD53B17U, 0x8EE0C8U, 0x85F291U, 0xD94B36U, 0x9298EFU, 0xAB8318U, 0xE07301U,
|
||||
0xBB68DFU, 0xB2CB7CU, 0xE910A5U, 0xE101D2U, 0x92BB4BU, 0x59E8B4U, 0x407175U, 0x0B026AU, 0x12989BU, 0x792944U,
|
||||
0x2376EDU, 0x2EF5BAU, 0x758663U, 0x7C1ED5U, 0x078D0CU, 0x4EF6ABU, 0x5567F2U, 0x9F7C29U, 0xC68E9CU, 0xC51747U,
|
||||
0xBC6422U, 0xB7EFB9U, 0xECFD44U, 0xA50497U, 0xAF178AU, 0xD68C69U, 0xD97DB5U, 0x82670EU, 0xCBB45BU, 0x508D90U,
|
||||
0x190A25U, 0x63F0FEU, 0x68E3C7U, 0x317A10U, 0x3A09D9U, 0x6B926EU, 0x004237U, 0x1B79C8U, 0x53EA59U, 0x48B3B7U,
|
||||
0x811166U, 0xDE4A79U, 0xF5F988U, 0xAC6057U, 0xE733FEU, 0xFF89ADU, 0xB49830U, 0x8F4BC3U, 0xC6F00EU, 0x9DA135U,
|
||||
0x942FE0U, 0xC71C3BU, 0x4DC78FU, 0x3476C4U, 0x7F6C39U, 0x66BFAAU, 0x298657U, 0x725504U, 0x5B4E89U, 0x01FE72U,
|
||||
0x0835A3U, 0x53269CU, 0x189D4DU, 0x01CDC2U, 0xEA763BU, 0xF3A56DU, 0xB0BCD4U, 0xE80F13U, 0xE355CAU, 0x98C47DU,
|
||||
0x91AB24U, 0xCE38DBU, 0x87A35AU, 0x9CD3A5U, 0xD648F4U, 0xAF7B6FU, 0x24A292U, 0x7D3011U, 0x764B6DU, 0x2DDABEU,
|
||||
0x44D123U, 0x5E22D8U, 0x1FB09DU, 0x04A926U, 0x4F5AF3U, 0x064128U, 0x3DB105U, 0x70AAD6U, 0xAA392FU, 0xA1C4B8U,
|
||||
0xF8C7C0U, 0xD35D0FU, 0x8A2E9EU, 0xC1B761U, 0xDA44F0U, 0x925E8FU, 0x89CF4EU, 0xE8B4D1U, 0xB32728U, 0xB8FE7FU,
|
||||
0x61DCC6U, 0x2A4701U, 0x1614D8U, 0x5DADE2U, 0x46BE37U, 0x0F44DCU, 0x54D549U, 0x5D8E32U, 0x263DAFU, 0x2C237CU,
|
||||
0x75E291U, 0xBE5982U, 0xA74A7FU, 0xC493A4U, 0xDFA131U, 0x967A5AU, 0xCCCB8EU, 0xC1D835U, 0x9A02ECU, 0xF331BBU,
|
||||
0xE8B812U, 0xA3EBC5U, 0xBA507CU, 0x7080ABU, 0x099BC2U, 0x02285DU, 0x59718CU, 0x50C273U, 0x0B1862U, 0x4A1F8CU,
|
||||
0x70A655U, 0x3BF5C2U, 0x666FBBU, 0x6DDE68U, 0x3485C5U, 0x9F161EU, 0xC46F4BU, 0x8CFDF0U, 0x97C625U, 0xDE058EU,
|
||||
0xC59CD3U, 0xAEAE20U, 0xF775BCU, 0xFC647FU, 0xBD9F02U, 0xE70C91U, 0xCC1468U, 0x11E7B7U, 0x1AFC36U, 0x435B49U,
|
||||
0x080398U, 0x139027U, 0x7B63FEU, 0x607AF9U, 0x29E900U, 0x7293D6U, 0x79026FU, 0x00D930U, 0x0BEAF1U, 0xD3614EU,
|
||||
0x90119FU, 0x8B8AE4U, 0xC61969U, 0xBD609AU, 0xB4F247U, 0xEFA954U, 0xE518A9U, 0xBC0362U, 0xD7D0D6U, 0xCE7E8DU,
|
||||
0x856F18U, 0x1C94E3U, 0x578726U, 0x0D5F1DU, 0x24ECC0U, 0x7FF713U, 0x3E26AAU, 0x251D6DU, 0x6A8F14U, 0x53648BU,
|
||||
0x19757AU, 0x40AEB4U, 0xCB9CA5U, 0x90055AU, 0x9956C3U, 0xE2ED34U, 0xAB3C7DU, 0xB126EAU, 0xFA9513U, 0xA3D2C8U,
|
||||
0x886BFDU, 0xD9F836U, 0xD2A2E3U, 0x8D1359U, 0x454804U, 0x5EDBF7U, 0x37637AU, 0x2C3089U, 0x67ABD4U, 0x3E8847U,
|
||||
0x3551BAU, 0x4D6331U, 0x46B8C4U, 0x1D299FU, 0x54120EU, 0x5FC0E1U, 0x86D93BU, 0xE56A0EU, 0xFBB1D5U, 0xB2B600U,
|
||||
0xA94EABU, 0xE05DF6U, 0x9BE605U, 0x90B798U, 0xC92C6BU, 0xC3DE66U, 0x9AC7BDU, 0xD15448U, 0x6A3FD3U, 0x23ADA3U,
|
||||
0x78346CU, 0x7147F5U, 0x2BDC02U, 0x0EAD5BU, 0x553FFCU, 0x1EA425U, 0x07D5F2U, 0x4C4ECBU, 0x554C14U, 0x3EB3F5U,
|
||||
0xE4A26AU, 0xED799BU, 0xB6CA85U, 0xFFD25CU, 0xC421BFU, 0x8F3A22U, 0x96AB51U, 0xDC518CU, 0x895217U, 0x8289F2U,
|
||||
0xF9B8A9U, 0xF0231CU, 0x2BF1C7U, 0x62C80AU, 0x781B39U, 0x1320E5U, 0x4AB156U, 0x41EB8FU, 0x1848E0U, 0x13D771U,
|
||||
0x4886AEU, 0x203C5FU, 0x3B6F40U, 0x76F6A1U, 0xE5457EU, 0xAE1EE7U, 0xD7AC10U, 0xDCB549U, 0x8476EFU, 0x8FC536U,
|
||||
0xD49DE9U, 0x9D0ED8U, 0xA63513U, 0xEFE4A6U, 0xB4DF7DU, 0x3E0D00U, 0x779693U, 0x4CA75EU, 0x0568ADU, 0x527BB0U,
|
||||
0x59C34BU, 0x00109FU, 0x0A0B14U, 0x73FA61U, 0x38E0BAU, 0x23530FU, 0x6A88D4U, 0xB199DDU, 0x98322AU, 0xC260F3U,
|
||||
0xCBF944U, 0x908A0DU, 0xDB11F2U, 0xC28163U, 0xADFABDU, 0xBC694CU, 0xF65243U, 0xAD83BAU, 0xA40D6DU, 0x5F7EF4U,
|
||||
0x16E787U, 0x0DF44AU, 0x460EF1U, 0x5E1F24U, 0x15CC3FU, 0x6C77CAU, 0x676401U, 0x3C9CBDU, 0x359FEEU, 0x6A0413U,
|
||||
0x02F590U, 0x91EE4DU, 0xDA3C3EU, 0xC305A3U, 0x889658U, 0xF14D99U, 0xFA7F86U, 0xA1E677U, 0xE981E8U, 0xF21A10U,
|
||||
0xBB4BD7U, 0x80F1CEU, 0xCB6239U, 0x123BE0U, 0x1D885FU, 0x45921EU, 0x6641E1U, 0x3DE870U, 0x74BBAFU, 0x6F00C6U,
|
||||
0x261055U, 0x7DCBA8U, 0x57787AU, 0x0E2167U, 0x05B28CU, 0xCC8819U, 0x975BE2U, 0xBC52B7U, 0xE5E52CU, 0xEB37C9U,
|
||||
0xB20E12U, 0xF9DD2FU, 0xE8C6FCU, 0x837701U, 0xD8AD82U, 0xD1BE5AU, 0x0B0525U, 0x0244B4U, 0x79FE5BU, 0x322DCAU,
|
||||
0x2B3495U, 0x60876CU, 0x79DCFBU, 0x334C12U, 0x4C7745U, 0x45A4DCU, 0x1E3F23U, 0x175FF2U, 0xC4C0D8U, 0xAFF30DU,
|
||||
0xB72AF6U, 0xFCB96BU, 0xA5C338U, 0xAE5295U, 0xF54946U, 0xDCBABBU, 0x87A1A8U, 0xCF2165U, 0xD4DA9EU, 0x9FC90BU,
|
||||
0x223070U, 0x6922A4U, 0x30B92FU, 0x3348D6U, 0x695B01U, 0x20C038U, 0x1BB2EFU, 0x523B06U, 0x49EC99U, 0x02D7C8U,
|
||||
0x5B4777U, 0x713CA6U, 0xA8AF49U, 0xA3B650U, 0xF84586U, 0xB5DF7FU, 0xAE8CF8U, 0xC72581U, 0x9D3652U, 0x9EEDCFU,
|
||||
0xC75D34U, 0xCC0671U, 0xB5B5CAU, 0xFEAC1FU, 0x677EA4U, 0x2DC5F9U, 0x26D63AU, 0x7F1F86U, 0x142855U, 0x0DF2A8U,
|
||||
0x42E3B3U, 0x195872U, 0x108B8DU, 0x6AB31CU, 0x632063U, 0x307BAAU, 0xFBC83DU, 0xE201C4U, 0xA91393U, 0x90A82AU,
|
||||
0xDAF9E4U, 0x816A55U, 0x88D00AU, 0xD383DBU, 0xFA3A64U, 0xA569A5U, 0xEEE2DEU, 0x76D243U, 0x3D0D90U, 0x649E6DU,
|
||||
0x47E76EU, 0x1C7491U, 0x156E49U, 0x4E9DDEU, 0x0604B7U, 0x3D3720U, 0x76FDD9U, 0x6FEC06U, 0x2417B7U, 0xFD04F8U,
|
||||
0xF29D29U, 0x886F92U, 0xC1744FU, 0xDAC73CU, 0x939EB1U, 0x880C63U, 0xEBE79EU, 0xB2F285U, 0xB86970U, 0xE11ABBU,
|
||||
0xEA822EU, 0x311155U, 0x586AC0U, 0x43F92BU, 0x0A81F6U, 0x5412C5U, 0x5D111CU, 0x26E8CBU, 0x2D7B63U, 0x74213CU,
|
||||
0x3F90CDU, 0x2E8B52U, 0x645883U, 0xDFE36CU, 0x96F375U, 0xDD0882U, 0xC40B1BU, 0x8FD6CCU, 0xB464A5U, 0xFC7F3EU,
|
||||
0xA7AECBU, 0xAA9511U, 0xF10634U, 0xBA5CEFU, 0x83ED32U, 0x483681U, 0x5015DCU, 0x138D3FU, 0x48DEA2U, 0x616571U,
|
||||
0x3AF40CU, 0x33AF97U, 0x681D72U, 0x2246E9U, 0x3BD7B9U, 0x506C46U, 0x0D2FDFU, 0x869338U, 0xDDC061U, 0xD45BD6U,
|
||||
0xAF6A0FU, 0xE7B8C0U, 0xFC2371U, 0xBF102EU, 0xA6C9DFU, 0xEDDA40U, 0x943089U, 0x9FA1BFU, 0x459A66U, 0x0C4995U,
|
||||
0x175108U, 0x7AE243U, 0x6139B6U, 0x2A2A2DU, 0x73D3D8U, 0x79C183U, 0x204A26U, 0x0B3FFDU, 0x5AA420U, 0x111613U,
|
||||
0x8A4FDFU, 0xC3DC2CU, 0xF9A7B5U, 0xB034EAU, 0xEBAC5BU, 0xE0CF94U, 0xBD5465U, 0xF605FAU, 0xCFBEA3U, 0x85AC54U,
|
||||
0x9E55DDU, 0xD7C62AU, 0x0CDD73U, 0x252FCDU, 0x76361CU, 0x7DF5D3U, 0x3546E2U, 0x6E5B39U, 0x67A98CU, 0x1CB247U,
|
||||
0x57231AU, 0x4AD8A9U, 0x01CA74U, 0x191187U, 0xF2208AU, 0xA9AB50U, 0xA0F8A5U, 0xFB403EU, 0xF2D34BU, 0xA9A880U,
|
||||
0xCB393DU, 0xD262EEU, 0x99D0B7U, 0xC04B00U, 0xCB1AC9U, 0xB0B176U, 0x39E3A7U, 0x677EF8U, 0x2ECD58U, 0x359687U,
|
||||
0x7E277EU, 0x473D69U, 0x0CEEB0U, 0x55D557U, 0x5F04CEU, 0x0C8EBDU, 0x25BD60U, 0x7E64DBU, 0xB7771EU, 0xACCC05U,
|
||||
0xE51CF0U, 0xBF2F2AU, 0x90F497U, 0xC9E7D4U, 0xC25F09U, 0x9B9CBAU, 0xD08767U, 0xEB320CU, 0xA36999U, 0x38FB42U,
|
||||
0x7180B3U, 0x22112CU, 0x29AA45U, 0x50F9D2U, 0x1B610AU, 0x0202FDU, 0x4899E4U, 0x57080BU, 0x3E72DAU, 0x65E165U,
|
||||
0x6CFA34U, 0xB70BEBU, 0xBC104AU, 0xE4E295U, 0x8F7BECU, 0x96787FU, 0xD583B2U, 0x9E9740U, 0x870C5DU, 0xECFFA6U,
|
||||
0xF4E433U, 0xBF35F8U, 0xE00F8DU, 0x699C16U, 0x3265EBU, 0x1B6638U, 0x40F515U, 0x0A8DC6U, 0x131E1BU, 0x5845A0U,
|
||||
0x21F670U, 0x2A6E1FU, 0x791D8EU, 0x708651U, 0x2AD7E8U, 0xE37CAFU, 0xD8EE56U, 0x97B3C1U, 0x8E0018U, 0xC51B6FU,
|
||||
0x9CC9E6U, 0xB67019U, 0xEF23C8U, 0xE498F2U, 0xBF9927U, 0xF643ECU, 0xCD7051U, 0x04E902U, 0x563AFFU, 0x5D006CU,
|
||||
0x04D3A1U, 0x0FCA9AU, 0x72794FU, 0x39A2B4U, 0x228231U, 0x6A19EAU, 0x714E96U, 0x18F705U, 0x4324FCU, 0xC83E3BU,
|
||||
0x918D02U, 0xDADCD5U, 0xC2470CU, 0xA135B3U, 0xBABCF2U, 0xF30F4DU, 0xA8549EU, 0xA1C543U, 0xDEFF78U, 0xD42CBCU,
|
||||
0x0DB747U, 0x46C6D2U, 0x5F5C89U, 0x144F60U, 0x6FA6F7U, 0x66350EU, 0x2C0A59U, 0x35DAE0U, 0x7EC12FU, 0x0D32FEU,
|
||||
0x0429C1U, 0x5FB911U, 0xD642AEU, 0x895167U, 0xC3D8B0U, 0xFAAB89U, 0xB1315AU, 0xA8C0A7U, 0xE3DB24U, 0xB84879U,
|
||||
0x913382U, 0xCBA317U, 0x82F8FCU, 0x994BA9U, 0x50C213U, 0x4390CEU, 0x282F5DU, 0x713E30U, 0x7FCDE3U, 0x26565EU,
|
||||
0x2D0485U, 0x56BDD4U, 0x1FAE7BU, 0x0475AAU, 0x4DD555U, 0x17CE4CU, 0x9C1D9BU, 0xE52473U, 0xEEF7E4U, 0xB7CD1DU,
|
||||
0xF45E42U, 0xEF87E3U, 0x87B43CU, 0x986FADU, 0xD16FD2U, 0x8AD403U, 0x8103A8U, 0xD83A75U, 0x33A826U, 0x2BF39BU,
|
||||
0x604049U, 0x7B99A4U, 0x328ABFU, 0x49306AU, 0x407191U, 0x1BEA04U, 0x19D96FU, 0x4001F2U, 0x0FB201U, 0x36E9DCU,
|
||||
0xFD7ADFU, 0xE64326U, 0xAF91F9U, 0xF51249U, 0xDC2B16U, 0x87F8D7U, 0xCCE668U, 0xC517B1U, 0x9E8C46U, 0x97BF5FU,
|
||||
0xED6498U, 0xA67461U, 0x378FF6U, 0x788C8FU, 0x611514U, 0x0AE6F1U, 0x53FC2BU, 0x596F3EU, 0x0216C5U, 0x4B8508U,
|
||||
0x507FBBU, 0x396EE6U, 0x22F535U, 0xE99688U, 0xB10F43U, 0xBA1D36U, 0xC3E2ADU, 0xC07178U, 0x9B28C3U, 0xD69A8BU,
|
||||
0xCD817CU, 0x8570E5U, 0xFEEB12U, 0xF5E8CBU, 0xAC10C4U, 0x270335U, 0x7ED8EAU, 0x156B5BU, 0x0E7A14U, 0x46A0C5U,
|
||||
0x5D937AU, 0x144AA3U, 0x4F79D5U, 0x6CF35CU, 0x31228FU, 0x7A1932U, 0x628E69U, 0xA9D59CU, 0x926517U, 0xDBBEE2U,
|
||||
0x80ADB9U, 0x891424U, 0xD246D7U, 0xD8ED1AU, 0xA17C28U, 0xEA27F5U, 0xF3942EU, 0xB8CE8FU, 0xAB5FD0U, 0x466461U,
|
||||
0x1CB7BEU, 0x152F6FU, 0x4E1CC0U, 0x05D799U, 0x1CE66EU, 0x773DF7U, 0x7EAB00U, 0x249048U, 0x6D41D7U, 0x765A26U,
|
||||
0x1DA9F9U, 0x8431C8U, 0xCF0203U, 0x96C1DEU, 0x90D86DU, 0xCB6A30U, 0xA23193U, 0xB9A24EU, 0xF05B95U, 0xEB48A0U,
|
||||
0xA0D27AU, 0xD8A39FU, 0xD33804U, 0x0A9B79U, 0x01C3AAU, 0x5A5437U, 0x132FD4U, 0x28BC0DU, 0x60253AU, 0x3F57E3U,
|
||||
0x3CCC7CU, 0x65DD9DU, 0x4E26C2U, 0x172572U, 0xDCDDADU, 0xC64E64U, 0x8F5553U, 0x94A68AU, 0xFDBE7DU, 0xA66DE4U,
|
||||
0xADD68BU, 0xF4C75AU, 0xFE0CC1U, 0x873E34U, 0xC8A72FU, 0xDBD0C2U, 0x124B10U, 0x49998DU, 0x40A8FEU, 0x3A3323U,
|
||||
0x316088U, 0x68D95DU, 0x235B06U, 0x3A00B3U, 0x51B178U, 0x4AEA89U, 0x025816U, 0x59C36FU, 0xD092B8U, 0x8B2930U,
|
||||
0xE43AC7U, 0xF5E2DEU, 0xBEC121U, 0xA71AF0U, 0xED8B7FU, 0x94B40EU, 0x9F66D1U, 0xD45D68U, 0xCD8CBFU, 0x8617F6U,
|
||||
0x5F2545U, 0x75FC98U, 0x2EFF62U, 0x674467U, 0x7C959CU, 0x318F09U, 0x0A7CD2U, 0x4967AFU, 0x11D62CU, 0x1A8CD1U,
|
||||
0x431F02U, 0x48A69DU, 0xB3E5ECU, 0xFA7623U, 0xE10E9AU, 0xA99948U, 0xB20215U, 0xD971A6U, 0x80E86BU, 0x8BDA90U,
|
||||
0xD60185U, 0x9D907EU, 0x8FFBFBU, 0xE66920U, 0x7D705DU, 0x3483CEU, 0x6F9833U, 0x646BF1U, 0x1DF3E8U, 0x17E017U,
|
||||
0x4E1BC6U, 0x050A79U, 0x1E8038U, 0x5773E7U, 0x2C685EU, 0xA1BD89U, 0xFB86B0U, 0xF01477U, 0xA16D8EU, 0xCAFE19U,
|
||||
0xD365C1U, 0x9815AEU, 0x839E3FU, 0xCBCDC4U, 0x907611U, 0xB9E70AU, 0xE2BDE7U, 0x2B0E34U, 0x301789U, 0x7BE4DAU,
|
||||
0x477707U, 0x0C2FACU, 0x558C79U, 0x5E9743U, 0x0D4496U, 0x04786DU, 0x7FABE0U, 0x3730B3U, 0x3C014AU, 0xE7DADDU,
|
||||
0xEEE834U, 0x956163U, 0xDCB2FAU, 0xC78905U, 0x8D5BD4U, 0xD0427BU, 0xDBF12BU, 0xA22AB4U, 0xA93B4DU, 0xFA819AU,
|
||||
0xB3D2B3U, 0x287B64U, 0x40289DU, 0x5BB206U, 0x100153U, 0x495CB8U, 0x42CF2DU, 0x3BF4D6U, 0x70248BU, 0x6ABF19U,
|
||||
0x23CCF4U, 0x3C4527U, 0x75761AU, 0x8EACC1U, 0x853F44U, 0xD44EBFU, 0xDED5EEU, 0x87C751U, 0xEC3E80U, 0xF72D6FU,
|
||||
0xBEB676U, 0xE557A1U, 0xEC4D59U, 0xB6BECEU, 0x9DA527U, 0x443078U, 0x0BCAE9U, 0x12D916U, 0x594087U, 0x6033E8U,
|
||||
0x22A831U, 0x7948A2U, 0x70535FU, 0x2BC01CU, 0x62BBA1U, 0x592A7BU, 0x92308EU, 0x8AC395U, 0xC15A50U, 0x9809ABU,
|
||||
0xB3B336U, 0xECB245U, 0xE54998U, 0xBEDA1BU, 0xF681E6U, 0xED35F5U, 0x8E2E0CU, 0x87FDD3U, 0x5CC453U, 0x1556ACU,
|
||||
0x0E85FDU, 0x64AC42U, 0x3D7F8BU, 0x36447CU, 0x6FD665U, 0x640FB2U, 0x3B3C4BU, 0x52A7C4U, 0x48F7B5U, 0x014C2EU,
|
||||
0x9A9FFBU, 0xD19601U, 0xA0250CU, 0xAB7FFFU, 0xF2C822U, 0xB8D1B1U, 0xA302CCU, 0xEAB907U, 0xD1E9B2U, 0x987269U,
|
||||
0xC3411CU, 0xCC8897U, 0x141A42U, 0x3F61B8U, 0x66F2A1U, 0x2DCB56U, 0x3618DFU, 0x778208U, 0x2CB3F1U, 0x0468EEU,
|
||||
0x5F7B1FU, 0x5693D0U, 0x0D8041U, 0x461B3EU, 0xFFECE7U, 0xB4FD50U, 0xA94798U, 0xE314CFU, 0xB88D76U, 0xB17EADU,
|
||||
0xCA7508U, 0xC3E553U, 0x989EA6U, 0xDB0D3DU, 0xC396E8U, 0xA8E683U, 0x717D1EU, 0x7A0EEDU, 0x219730U, 0x288422U,
|
||||
0x736ECFU, 0x1BFF14U, 0x04A4A1U, 0x4F177AU, 0x56092BU, 0x1DD884U, 0x64635DU, 0xEF70EAU, 0xA589B3U, 0xF49B54U,
|
||||
0xFF50CDU, 0xA66312U, 0x8DFA62U, 0xD628FDU, 0x9F131CU, 0x8582C3U, 0xCCF9DAU, 0xF36A29U, 0xB8B2F4U, 0x618157U,
|
||||
0x6A020AU, 0x335999U, 0x79E864U, 0x4272BFU, 0x03259AU, 0x189C40U, 0x51CFB5U, 0x0A752EU, 0x216463U, 0x79BF90U,
|
||||
0x721C0DU, 0xAB47FEU, 0xE4D727U, 0xFDEC28U, 0x963FD9U, 0x8DA646U, 0xC594B7U, 0x9E4FE8U, 0x977E60U, 0xECA597U,
|
||||
0xAF264EU, 0xB61C79U, 0xFDCDA0U, 0x65D64FU, 0x2E61DCU, 0x553881U, 0x5CAA72U, 0x0351FBU, 0x0A400CU, 0x51FB55U,
|
||||
0x3BB9CAU, 0x22223AU, 0x6993B5U, 0x30C8C4U, 0x3B5B1BU, 0xE02B82U, 0xC1B075U, 0x9B23BCU, 0xD25A8BU, 0xC9C852U,
|
||||
0x82A3A9U, 0xBB303CU, 0xF42977U, 0xADDA82U, 0xA64418U, 0xFC55E5U, 0xB5AEE6U, 0x0EBD3BU, 0x4765C8U, 0x4CD655U,
|
||||
0x17DD2EU, 0x562EEBU, 0x6C3770U, 0x25A585U, 0x3E5EDEU, 0x754F6FU, 0x2C94A1U, 0x23A758U, 0x5A3F4FU, 0xD07C96U,
|
||||
0x8BC761U, 0xC254E8U, 0xD92C97U, 0xB0BF06U, 0xEBE0D9U, 0xE25138U, 0xB8CAA7U, 0xBB98DEU, 0xE22109U, 0x896291U,
|
||||
0x10F172U, 0x5BCB2FU, 0x401A94U, 0x0CA141U, 0x77B2BAU, 0x7E6BBFU, 0x255964U, 0x6E82D9U, 0x77130AU, 0x3C3877U,
|
||||
0x04EAF4U, 0x4FD129U, 0x9C40DBU, 0x959BC6U, 0xCEAC2DU, 0xE774FCU, 0xBC6763U, 0xF6DC12U, 0xEB8DCDU, 0xA00664U,
|
||||
0xF9F4B3U, 0xD2EF4AU, 0x895E5DU, 0x800584U, 0x5A972BU, 0x132EFBU, 0x287D84U, 0x63E615U, 0x7297CEU, 0x391D23U,
|
||||
0x608E30U, 0x6AF5CDU, 0x11641EU, 0x5C5E93U, 0x4789E0U, 0x0E903DU, 0x956386U, 0xFEF053U, 0xB6E879U, 0xAD0BACU,
|
||||
0xE41077U, 0xFF83CAU, 0xB47A99U, 0xCD6870U, 0xCE93E7U, 0x96823EU, 0x9D1941U, 0xC4EBD0U, 0x2BF23FU, 0x3031EEU,
|
||||
0x790A71U, 0x229909U, 0x2AC1CEU, 0x717677U, 0x5AEDA0U, 0x039C99U, 0x480646U, 0x515587U, 0x1AEC3CU, 0x296F69U,
|
||||
0xE13492U, 0xBA8607U, 0xB39FCCU, 0xEC4CB1U, 0xA77723U, 0x9EA7DEU, 0xD51C0DU, 0xCD0F00U, 0x86D4FBU, 0xDDF56EU,
|
||||
0xF46F95U, 0x2FBCD4U, 0x268D6BU, 0x7D52B2U, 0x374165U, 0x26F9DCU, 0x4D2A9BU, 0x141163U, 0x1FD2FCU, 0x40CA2DU,
|
||||
0x497952U, 0x3322D3U, 0x7AB32CU, 0xE108F5U, 0xAA5AE2U, 0xB3E31BU, 0xF8B098U, 0x812B65U, 0x8B8936U, 0xD0D08AU,
|
||||
0xD94341U, 0x8A7894U, 0xE3A9AFU, 0xF8377AU, 0xB74481U, 0x6FDD0CU, 0x64EE5FU, 0x3D35A2U, 0x163731U, 0x5F8ECCU,
|
||||
0x045DC7U, 0x0F4616U, 0x57B6E8U, 0x7CAD79U, 0x253E86U, 0x6EC7CFU, 0x7DD478U, 0xB426A1U, 0xCF2D76U, 0xC3BC5FU,
|
||||
0x984780U, 0x935571U, 0xCACCEEU, 0x81BBBFU, 0xB82054U, 0xF371C0U, 0xE9CB3BU, 0xA05826U, 0xFB33F5U, 0x52A218U,
|
||||
0x09B88BU, 0x424BF6U, 0x53D22DU, 0x198198U, 0x043A53U, 0x6F2A06U, 0x34F1BDU, 0x3DC260U, 0x664982U, 0x6FB81BU,
|
||||
0x15A24CU, 0xDE71F5U, 0xC7482AU, 0x8CDFCBU, 0x9505D4U, 0xDE3405U, 0xA5EFFAU, 0xA4FC63U, 0xFE5704U, 0xB387DDU,
|
||||
0xA8BC6AU, 0xC32FB2U, 0x5A7EE5U, 0x11C44CU, 0x489797U, 0x420E62U, 0x19BD79U, 0x30E6BCU, 0x6B6407U, 0x225DDAU,
|
||||
0x398EA9U, 0x703534U, 0x0A64F7U, 0x09FA0AU, 0xD4C910U, 0xDF10E5U, 0x86833EU, 0xCDB99BU, 0xE67A40U, 0xBE631BU,
|
||||
0xB590AEU, 0xEC8B75U, 0xA73BD0U, 0x9CE08BU, 0xD5F35EU, 0x8E0AE5U, 0x061828U, 0x5D835AU, 0x5660C7U, 0x277914U,
|
||||
0x68CAE9U, 0x7190E2U, 0x3A0113U, 0x20FECCU, 0x49ED7DU, 0x127522U, 0x1B06ABU, 0x40855CU, 0x8B9E85U, 0x926FB2U,
|
||||
0xF8F56AU, 0xE186A5U, 0xAA1F14U, 0xF10CCBU, 0xF0F7BAU, 0x8F6735U, 0x867CECU, 0xDC9F1FU, 0x978402U, 0x8E54F1U,
|
||||
0x45EF3CU, 0x7CFC8FU, 0x3705D2U, 0x6C1248U, 0x64C8BDU, 0x3FF976U, 0x566243U, 0x4DA198U, 0x069B45U, 0x1F0AF6U,
|
||||
0x5851BBU, 0x00E248U, 0xAB3BD1U, 0xF2090EU, 0xF9926FU, 0xA2C3F1U, 0xEB7800U, 0xD07B9FU, 0x98A1E6U, 0xC31021U,
|
||||
0xC84BB8U, 0x91D84FU, 0x9AEC96U, 0x6337A9U, 0x288468U, 0x369FB3U, 0x774E06U, 0x6C645DU, 0x05B7A9U, 0x4E2E22U,
|
||||
0x551DFFU, 0x1CC78CU, 0x47D611U, 0x4F2DF2U, 0x343E6FU, 0xBF8514U, 0xE655C1U, 0xAD5E5AU, 0xB4EDBFU, 0xDFB4E4U,
|
||||
0xC1265DU, 0x80DD8BU, 0xDBC852U, 0xD25375U, 0x8920ACU, 0xA2BA53U, 0xFB0BC2U, 0x31401DU, 0x28D33CU, 0x63AAE3U,
|
||||
0x18381AU, 0x11238DU, 0x4AD2E4U, 0x434933U, 0x195BABU, 0x56A058U, 0x6FB105U, 0x2C5AAEU, 0x35C97BU, 0xFED9A0U,
|
||||
0xA52295U, 0x8D314EU, 0xD6ECA3U, 0x9F5E30U, 0x84456DU, 0xCFB6DEU, 0xD6AF03U, 0xBD2CE9U, 0xE556FCU, 0xEEC707U,
|
||||
0xB71CD6U, 0x382F59U, 0x43B720U, 0x02E4F7U, 0x195F4EU, 0x51CC99U, 0x0AA550U, 0x013767U, 0x786CBEU, 0x73DD01U,
|
||||
0x2AC6D1U, 0x61159EU, 0x7BA92FU, 0x92BAF4U, 0x896109U, 0xC0521AU, 0x9F9AF7U, 0x942924U, 0xC532B9U, 0xEFE3C2U,
|
||||
0xA6D807U, 0xFD0ABCU, 0xF69369U, 0xAFA033U, 0x44738EU, 0x5D694DU, 0x17C8F0U, 0x0C93A3U, 0x45207AU, 0x1EF9C5U,
|
||||
0x37EB04U, 0x6850FBU, 0x6305EAU, 0x3B9E15U, 0x782DC4U, 0x41774BU, 0x8AF633U, 0xD18DE4U, 0xD81E5DU, 0x83A69AU,
|
||||
0x8AF583U, 0xF06E7CU, 0xBB5FADU, 0xA28416U, 0xE99653U, 0xF06D88U, 0x9FEC35U, 0xC4F7E6U, 0x4C059AU, 0x1F1C19U,
|
||||
0x56EFC4U, 0x4D743FU, 0x24612AU, 0x3F9BD1U, 0x748814U, 0x2C13AFU, 0x27F276U, 0x5EE861U, 0x553B88U, 0x0E0A5FU,
|
||||
0xC791E6U, 0xD8E2B0U, 0x907A69U, 0xABE9C6U, 0xE09217U, 0xB10168U, 0xBA48F9U, 0xE3FA26U, 0x8861CFU, 0x9230D8U,
|
||||
0xDB8B21U, 0xC099B2U, 0x09644FU, 0x52F704U, 0x79AC90U, 0x201F6BU, 0x2E17BEU, 0x77C495U, 0x3CFF48U, 0x172E9BU,
|
||||
0x4E9426U, 0x0D8775U, 0x145E98U, 0x5E6D03U, 0xC5F6D6U, 0xAC242DU, 0xF70D3CU, 0xFEDED2U, 0xA5C543U, 0xAE74BCU,
|
||||
0xD62EE5U, 0x9D9D72U, 0x80029BU, 0xCB534CU, 0x90E175U, 0x19BAAAU, 0x6A3B6BU, 0x6280D4U, 0x39D385U, 0x724B7AU,
|
||||
0x6B78E2U, 0x00A321U, 0x19101CU, 0x5248CFU, 0x0ADB30U, 0x01F0A9U, 0x5A21CEU, 0xB73A17U, 0xACC880U, 0xE55179U,
|
||||
0xFE42A6U, 0xB4B987U, 0xC5AF58U, 0xCE1688U, 0x97C533U, 0x9CCE76U, 0xC73F8DU, 0x8E2510U, 0xB4B6C3U, 0x7D4FFEU,
|
||||
0x665C3DU, 0x2DC7C0U, 0x70B55BU, 0x5B2C2EU, 0x025FF5U, 0x49D470U, 0x53448AU, 0x1A3FD7U, 0x09AC64U, 0x60BDBDU,
|
||||
0x3B467AU, 0xB0D043U, 0xE98B9CU, 0xE33A2DU, 0x9A21E2U, 0xD1C3B3U, 0xCA5A0CU, 0x8709DDU, 0xDCB222U, 0xF5A3AAU,
|
||||
0xBF79DDU, 0xA44A04U, 0xEDD193U, 0x3E006AU, 0x373B21U, 0x4CF994U, 0x47C04FU, 0x1F53DAU, 0x5488A1U, 0x4DB86CU,
|
||||
0x2623DFU, 0x7D7402U, 0x70CF50U, 0x2B9EFDU, 0x232426U, 0xF8A7D3U, 0x91FEC8U, 0x8A4D39U, 0xC117F6U, 0xD0866FU,
|
||||
0x9B3D18U, 0xE36EC1U, 0xE8F576U, 0xB3C5BFU, 0xBA1629U, 0xE1BD50U, 0xA8EC8FU, 0x17763EU, 0x5D45F1U, 0x049CA0U,
|
||||
0x0F8F1FU, 0x5630C6U, 0x7DE225U, 0x26FB38U, 0x6F08CBU, 0x7D0316U, 0x34B28DU, 0x2F68E9U, 0xC47B72U, 0x9DC287U,
|
||||
0x96915CU, 0xCF0B41U, 0x85F8A2U, 0xBAE17FU, 0xF372CCU, 0xE81991U, 0xA1894AU, 0xFAF2EBU, 0xF16134U, 0x89F845U,
|
||||
0x0A8ADBU, 0x53153AU, 0x1806E5U, 0x03FF7CU, 0x6A7C0BU, 0x312692U, 0x399775U, 0x628CACU, 0x6D7FB3U, 0x34EE42U,
|
||||
0x5FF49DU, 0x56073CU, 0x8D1C67U, 0x87CDBBU, 0xDEE708U, 0xB574D5U, 0xA4ADB6U, 0xEF9E2BU, 0xF605D0U, 0xBD7545U,
|
||||
0xE6EE0EU, 0xCE39FBU, 0x950260U, 0xD8929DU, 0x43D9CEU, 0x086A47U, 0x31B3B1U, 0x7AA068U, 0x221ADFU, 0x294B86U,
|
||||
0x72F049U, 0x73E3F8U, 0x083927U, 0x418856U, 0x5AC3C9U, 0x105020U, 0xC969B7U, 0xE2BBEEU, 0xBF2019U, 0xB41181U,
|
||||
0xEFCA6AU, 0xA6FD3FU, 0xBC27A4U, 0xD53651U, 0xCE9D9AU, 0x854EA7U, 0xDC5E74U, 0xDFE5A9U, 0x26B61AU, 0x6C0D57U,
|
||||
0x77DCECU, 0x3EC639U, 0x2575C3U, 0x682CD6U, 0x13AF1DU, 0x1855ECU, 0x404473U, 0x4BDF8AU, 0x12ACDDU, 0xF93754U,
|
||||
0xE207A3U, 0xABD87AU, 0xF04B45U, 0xF03284U, 0xABB05BU, 0x80ABEBU, 0xD95AB4U, 0x92C10DU, 0x8FD2CEU, 0xC42833U,
|
||||
0xEC3920U, 0x37C2FDU, 0x7C5106U, 0x654883U, 0x2EAAF8U, 0x37B12DU, 0x5C20B6U, 0x065B42U, 0x07C909U, 0x5C12B4U,
|
||||
0x152367U, 0x2EB4FAU, 0x65CF19U, 0xFC5F40U, 0xB294FFU, 0xEBA72EU, 0xE03ED1U, 0x9B6CD0U, 0x92D70FU, 0xC944F6U,
|
||||
0x801D60U, 0x9AAE19U, 0xF1F4DEU, 0xA85547U, 0xAB4EB8U, 0x729DE9U, 0x792456U, 0x223697U, 0x4BED0CU, 0x55DE71U,
|
||||
0x1C03A2U, 0x07910FU, 0x4CAADCU, 0x356BA0U, 0x3E5033U, 0x67C3EEU, 0x2D9B05U, 0xB62810U, 0xFFF3EBU, 0xC4E03EU,
|
||||
0x8558A5U, 0xDE0B48U, 0xD5905BU, 0x8D71A2U, 0xA26A75U, 0xFBD8ECU, 0xB08982U, 0xAB1253U, 0xE2A1ECU, 0x79FB3FU,
|
||||
0x116E52U, 0x4A15C9U, 0x43861CU, 0x188FE7U, 0x537DF2U, 0x62E619U, 0x29D7C0U, 0x310C57U, 0x7A1F2EU, 0x25E5B8U,
|
||||
0xAC7451U, 0xC76F86U, 0xDE9C9FU, 0x959460U, 0xCF27B1U, 0xC6FC1EU, 0xBDEDCFU, 0xF416B0U, 0xEF0429U, 0xA49FEEU,
|
||||
0xBDEA17U, 0xFF7104U, 0x06A3F8U, 0x0D8A63U, 0x5219A6U, 0x5B62DDU, 0x00F348U, 0x6969B3U, 0x731A6EU, 0x38816DU,
|
||||
0x61D090U, 0x6A6343U, 0x33F9FEU, 0x18B8A5U, 0xC30340U, 0x8B10DAU, 0x98E80BU, 0xD1FB74U, 0xEA20F5U, 0xA5930AU,
|
||||
0xFC8E93U, 0xF75CC4U, 0xAF673DU, 0xA4E6BAU, 0xDF3D43U, 0x960F9CU, 0x0DD68DU, 0x44E572U, 0x1F7EB2U, 0x35AD09U,
|
||||
0x6C9554U, 0x6746A7U, 0x365D3AU, 0x7DFCF9U, 0x64A6C4U, 0x0B351FU, 0x118CEAU, 0x58DF61U, 0x836434U, 0x8A36CFU,
|
||||
0xF1AB5BU, 0xBA18A0U, 0xA343EDU, 0xE8C27EU, 0xF0F887U, 0xBB2B50U, 0xC03A69U, 0xC9C1A6U, 0x9A5317U, 0x9368C8U,
|
||||
0x5CB919U, 0x26A226U, 0x2F01EFU, 0x74D919U, 0x3DCA80U, 0x2631D7U, 0x6D223EU, 0x54BAA1U, 0x1E4950U, 0x47520BU,
|
||||
0x4CA79EU, 0x97BC75U, 0xBE3EA8U, 0xED479BU, 0xA4D446U, 0xBA4FF5U, 0xF13C39U, 0xE8A46AU, 0x83D7D7U, 0xDA4C0CU,
|
||||
0xD1DDF9U, 0x8AA7F2U, 0xC22427U, 0x793DDCU, 0x30CE45U, 0x2B5522U, 0x6007FBU, 0x39BE6CU, 0x32AD95U, 0x42560BU,
|
||||
0x4D426AU, 0x16D1B5U, 0x5F3A04U, 0x442BDBU, 0x2DF082U, 0xF6C225U, 0xFE59FCU, 0xA5880FU, 0xAEB312U, 0xF761C9U,
|
||||
0x9C582CU, 0x85CBB7U, 0xCE00C3U, 0xD43118U, 0x9DAB9DU, 0xEAF866U, 0xE3437BU, 0x381288U, 0x738955U, 0x6A3BF6U,
|
||||
0x2066ABU, 0x19D570U, 0x52DEC1U, 0x090E1EU, 0x00B5FFU, 0x5BE6E1U, 0x727D38U, 0x284CCFU, 0x639656U, 0xFA8531U,
|
||||
0xBD3CA8U, 0xD4EF77U, 0xCFC586U, 0x841489U, 0x9C0F78U, 0xD7BCA7U, 0x8E671EU, 0xA5774DU, 0xFE8481U, 0xF79F32U,
|
||||
0xAC0AEFU, 0x65F09CU, 0x5FF301U, 0x144ACAU, 0x0D193FU, 0x468224U, 0x13F0D1U, 0x18694AU, 0x63FA87U, 0x2B81F4U,
|
||||
0x30106DU, 0x790A9BU, 0xE2E952U, 0x8970CDU, 0xD003BCU, 0xDB9963U, 0x838AD2U, 0x88731DU, 0xD1E064U, 0xBAFFF3U,
|
||||
0xA10F2AU, 0xEC049DU, 0xBFD7D4U, 0xB7EE2BU, 0x4C7CBBU, 0x478760U, 0x1E9415U, 0x554D9EU, 0x4C7E6BU, 0x07E4B0U,
|
||||
0x3D35ADU, 0x741E4EU, 0x2F8D93U, 0x26FC20U, 0x7D667DU, 0x16B586U, 0x8B8E02U, 0xC91FD9U, 0xD0456CU, 0x9BF237U,
|
||||
0xC0EBCEU, 0xE92849U, 0xB29390U, 0xBBC3E7U, 0xE1787EU, 0xAA6B81U, 0x93B040U, 0xD8005FU, 0x411BAEU, 0x0AC870U,
|
||||
0x51F1D1U, 0x5D328EU, 0x362837U, 0x6799E0U, 0x6C4239U, 0x37711AU, 0x3EABC7U, 0x45BA3CU, 0x0D01A9U, 0x16D6F2U,
|
||||
0xDDCF17U, 0xC46D8CU, 0x8F3670U, 0xF6A723U, 0xFD5CBCU, 0xA74F5DU, 0xEAF582U, 0xF1A43BU, 0x903768U, 0x8B0CC5U,
|
||||
0xC0DC16U, 0x9957CBU, 0x1324F0U, 0x4ABD25U, 0x61AECEU, 0x38545AU, 0x73C701U, 0x68FEF4U, 0x212D6FU, 0x5B3382U,
|
||||
0x52C2D1U, 0x09494CU, 0x065ABFU, 0xDFA126U, 0x9CB149U, 0xA56A98U, 0xEE5927U, 0xF4C0F6U, 0xBD33B8U, 0xE62901U,
|
||||
0xCFB8D6U, 0x94D32FU, 0x9F40B8U, 0xC69AF1U, 0x8CAB0EU, 0x15309FU, 0x7E6360U, 0x21DA31U, 0x2848BAU, 0x733747U,
|
||||
0x72A6D4U, 0x08EDA8U, 0x435F7BU, 0x5A4CD6U, 0x119505U, 0x082658U, 0x433DE3U, 0xB8ED26U, 0xB0D6DDU, 0xEB05C8U,
|
||||
0xA2BC13U, 0xA9BEEAU, 0xD6656DU, 0xDF5614U, 0x848F82U, 0xC41C5BU, 0xDF26A4U, 0x94F7A5U, 0xADCC5AU, 0x665B8BU,
|
||||
0x3F1234U, 0x34A0EDU, 0x6E7BAAU, 0x076813U, 0x1CD1C4U, 0x55833DU, 0x4E1836U, 0x03A9E2U, 0x58F219U, 0x72418CU,
|
||||
0x2B09F7U, 0xA89A72U, 0xF1A1A9U, 0xBA7254U, 0x81EA47U, 0xC899BAU, 0xD20279U, 0x9B13C4U, 0xC0E09FU, 0xCB7E4BU,
|
||||
0xB25FF0U, 0xF98431U, 0xE4974EU, 0x2E6CD7U, 0x35FC00U, 0x5CE7A9U, 0x07147EU, 0x060D07U, 0x5D9F98U, 0x56E449U,
|
||||
0x0E65A6U, 0x659EB7U, 0x7C8D49U, 0x371790U, 0x6C6623U, 0xE5FD6EU, 0x9E6EBDU, 0x921600U, 0xC985D3U, 0x82DAEEU,
|
||||
0x9B7B25U, 0xD0E0F0U, 0xE1924BU, 0xAA091EU, 0xF158F5U, 0xF9E369U, 0x22F1BAU, 0x4B28C7U, 0x509B54U, 0x1B80BDU,
|
||||
0x024162U, 0x497B53U, 0x01A88CU, 0x3E1B5DU, 0x7502F2U, 0x6CD12BU, 0x27EB1CU, 0x7E7AC5U, 0xDDA113U, 0x8596BAU,
|
||||
0xCE5EEDU, 0xD54D14U, 0x9CF68BU, 0x87A54AU, 0xEE1C31U, 0xB58EA4U, 0xBFD55FU, 0xE66482U, 0xE93FA1U, 0x90AD7CU,
|
||||
0x5B04EFU, 0x405713U, 0x09CC48U, 0x13BFEDU, 0x522736U, 0x2914E3U, 0x22CFD8U, 0x7B5E05U, 0x3061E6U, 0x29B37FU,
|
||||
0x43BAA8U, 0x5849D1U, 0x91D25EU, 0xCEE0AFU, 0xC73971U, 0x9C2A40U, 0xB7919FU, 0xEF401EU, 0xA452E1U, 0xB5B9B8U,
|
||||
0xFEA80FU, 0x8533D6U, 0x8C4115U, 0xD7DA28U, 0x5F6BF3U, 0x043006U, 0x4FA39DU, 0x76DBD9U, 0x394C22U, 0x20C7BFU,
|
||||
0x6BB64CU, 0x312C41U, 0x187FB2U, 0x43C46FU, 0x0A55F4U, 0x192E81U, 0xD2BC4AU, 0xCBA5FBU, 0xA15624U, 0xF85DFDU,
|
||||
0xF38ECBU, 0xBA3602U, 0xA125F5U, 0xCEFE6CU, 0x97CF3BU, 0x9D55C2U, 0xC4A64DU, 0x4FBFBCU, 0x1468A3U, 0x7D4352U,
|
||||
0x6ED19DU, 0x270804U, 0x7D3B76U, 0x76A0ABU, 0x0FF018U, 0x0443D5U, 0x5D188EU, 0x16A93BU, 0x0932E0U, 0xC07015U,
|
||||
0xFACB1EU, 0xB39AC3U, 0xE80170U, 0xE3B3ADU, 0xBAEA5EU, 0xD17956U, 0xC042A9U, 0x8A9378U, 0x912DE7U, 0xD86E86U,
|
||||
0x83F559U, 0x2AC4E8U, 0x711F37U, 0x7A0D6EU, 0x26B4C9U, 0x6D6710U, 0x547CE7U, 0x1F8CFEU, 0x449720U, 0x4D3483U,
|
||||
0x16EF5AU, 0x1EFE2DU, 0x6D44B4U, 0xA6174BU, 0xBF8E8AU, 0xF4FD95U, 0xED6764U, 0x86D6BBU, 0xDC8912U, 0xD10A45U,
|
||||
0x8A799CU, 0x83E12AU, 0xF872F3U, 0xB10954U, 0xAA980DU, 0x6083D6U, 0x397163U, 0x3AE8B8U, 0x439BDDU, 0x481046U,
|
||||
0x1302BBU, 0x5AFB68U, 0x50E875U, 0x297396U, 0x26824AU, 0x7D98F1U, 0x344BA4U, 0xAF726FU, 0xE6F5DAU, 0x9C0F01U,
|
||||
0x971C38U, 0xCE85EFU, 0xC5F626U, 0x946D91U, 0xFFBDC8U, 0xE48637U, 0xAC15A6U, 0xB74C48U, 0x7EEE99U, 0x21B586U,
|
||||
0x0A0677U, 0x539FA8U, 0x18CC01U, 0x007652U, 0x4B67CFU, 0x70B43CU, 0x390FF1U, 0x625ECAU, 0x6BD01FU, 0x38E3C4U,
|
||||
0xB23870U, 0xCB893BU, 0x8093C6U, 0x994055U, 0xD679A8U, 0x8DAAFBU, 0xA4B176U, 0xFE018DU, 0xF7CA5CU, 0xACD963U,
|
||||
0xE762B2U, 0xFE323DU, 0x1589C4U, 0x0C5A92U, 0x4F432BU, 0x17F0ECU, 0x1CAA35U, 0x673B82U, 0x6E54DBU, 0x31C724U,
|
||||
0x785CA5U, 0x632C5AU, 0x29B70BU, 0x508490U, 0xDB5D6DU, 0x82CFEEU, 0x89B492U, 0xD22541U, 0xBB2EDCU, 0xA1DD27U,
|
||||
0xE04F62U, 0xFB56D9U, 0xB0A50CU, 0xF9BED7U, 0xC24EFAU, 0x8F5529U, 0x55C6D0U, 0x5E3B47U, 0x07383FU, 0x2CA2F0U,
|
||||
0x75D161U, 0x3E489EU, 0x25BB0FU, 0x6DA170U, 0x7630B1U, 0x174B2EU, 0x4CD8D7U, 0x470180U, 0x9E2339U, 0xD5B8FEU,
|
||||
0xE9EB27U, 0xA2521DU, 0xB941C8U, 0xF0BB23U, 0xAB2AB6U, 0xA271CDU, 0xD9C250U, 0xD3DC83U, 0x8A1D6EU, 0x41A67DU,
|
||||
0x58B580U, 0x3B6C5BU, 0x205ECEU, 0x6985A5U, 0x333471U, 0x3E27CAU, 0x65FD13U, 0x0CCE44U, 0x1747EDU, 0x5C143AU,
|
||||
0x45AF83U, 0x8F7F54U, 0xF6643DU, 0xFDD7A2U, 0xA68E73U, 0xAF3D8CU, 0xF4E79DU, 0xB5E073U, 0x8F59AAU, 0xC40A3DU,
|
||||
0x999044U, 0x922197U, 0xCB7A3AU, 0x60E9E1U, 0x3B90B4U, 0x73020FU, 0x6839DAU, 0x21FA71U, 0x3A632CU, 0x5151DFU,
|
||||
0x088A43U, 0x039B80U, 0x4260FDU, 0x18F36EU, 0x33EB97U, 0xEE1848U, 0xE503C9U, 0xBCA4B6U, 0xF7FC67U, 0xEC6FD8U,
|
||||
0x849C01U, 0x9F8506U, 0xD616FFU, 0x8D6C29U, 0x86FD90U, 0xFF26CFU, 0xF4150EU, 0x2C9EB1U, 0x6FEE60U, 0x74751BU,
|
||||
0x39E696U, 0x429F65U, 0x4B0DB8U, 0x1056ABU, 0x1AE756U, 0x43FC9DU, 0x282F29U, 0x318172U, 0x7A90E7U, 0xE36B1CU,
|
||||
0xA878D9U, 0xF2A0E2U, 0xDB133FU, 0x8008ECU, 0xC1D955U, 0xDAE292U, 0x9570EBU, 0xAC9B74U, 0xE68A85U, 0xBF514BU,
|
||||
0x34635AU, 0x6FFAA5U, 0x66A93CU, 0x1D12CBU, 0x54C382U, 0x4ED915U, 0x056AECU, 0x5C2D37U, 0x779402U, 0x2607C9U,
|
||||
0x2D5D1CU, 0x72ECA6U, 0xBAB7FBU, 0xA12408U, 0xC89C85U, 0xD3CF76U, 0x98542BU, 0xC177B8U, 0xCAAE45U, 0xB29CCEU,
|
||||
0xB9473BU, 0xE2D660U, 0xABEDF1U, 0xA03F1EU, 0x7926C4U, 0x1A95F1U, 0x044E2AU, 0x4D49FFU, 0x56B154U, 0x1FA209U,
|
||||
0x6419FAU, 0x6F4867U, 0x36D394U, 0x3C2199U, 0x653842U, 0x2EABB7U, 0x95C02CU, 0xDC525CU, 0x87CB93U, 0x8EB80AU,
|
||||
0xD423FDU, 0xF152A4U, 0xAAC003U, 0xE15BDAU, 0xF82A0DU, 0xB3B134U, 0xAAB3EBU, 0xC14C0AU, 0x1B5D95U, 0x128664U,
|
||||
0x49357AU, 0x002DA3U, 0x3BDE40U, 0x70C5DDU, 0x6954AEU, 0x23AE73U, 0x76ADE8U, 0x7D760DU, 0x064756U, 0x0FDCE3U,
|
||||
0xD40E38U, 0x9D37F5U, 0x87E4C6U, 0xECDF1AU, 0xB54EA9U, 0xBE1470U, 0xE7B71FU, 0xEC288EU, 0xB77951U, 0xDFC3A0U,
|
||||
0xC490BFU, 0x89095EU, 0x1ABA81U, 0x51E118U, 0x2853EFU, 0x234AB6U, 0x7B8910U, 0x703AC9U, 0x2B6216U, 0x62F127U,
|
||||
0x59CAECU, 0x101B59U, 0x4B2082U, 0xC1F2FFU, 0x88696CU, 0xB358A1U, 0xFA9752U, 0xAD844FU, 0xA63CB4U, 0xFFEF60U,
|
||||
0xF5F4EBU, 0x8C059EU, 0xC71F45U, 0xDCACF0U, 0x95772BU, 0x4E6622U, 0x67CDD5U, 0x3D9F0CU, 0x3406BBU, 0x6F75F2U,
|
||||
0x24EE0DU, 0x3D7E9CU, 0x520542U, 0x4396B3U, 0x09ADBCU, 0x527C45U, 0x5BF292U, 0xA0810BU, 0xE91878U, 0xF20BB5U,
|
||||
0xB9F10EU, 0xA1E0DBU, 0xEA33C0U, 0x938835U, 0x989BFEU, 0xC36342U, 0xCA6011U, 0x95FBECU, 0xFD0A6FU, 0x6E11B2U,
|
||||
0x25C3C1U, 0x3CFA5CU, 0x7769A7U, 0x0EB266U, 0x058079U, 0x5E1988U, 0x167E17U, 0x0DE5EFU, 0x44B428U, 0x7F0E31U,
|
||||
0x349DC6U, 0xEDC41FU, 0xE277A0U, 0xBA6DE1U, 0x99BE1EU, 0xC2178FU, 0x8B4450U, 0x90FF39U, 0xD9EFAAU, 0x823457U,
|
||||
0xA88785U, 0xF1DE98U, 0xFA4D73U, 0x3377E6U, 0x68A41DU, 0x43AD48U, 0x1A1AD3U, 0x14C836U, 0x4DF1EDU, 0x0622D0U,
|
||||
0x173903U, 0x7C88FEU, 0x27527DU, 0x2E41A5U, 0xF4FADAU, 0xFDBB4BU, 0x8601A4U, 0xCDD235U, 0xD4CB6AU, 0x9F7893U,
|
||||
0x862304U, 0xCCB3EDU, 0xB388BAU, 0xBA5B23U, 0xE1C0DCU, 0xE8A00DU, 0x3B3F27U, 0x500CF2U, 0x48D509U, 0x034694U,
|
||||
0x5A3CC7U, 0x51AD6AU, 0x0AB6B9U, 0x234544U, 0x785E57U, 0x30DE9AU, 0x2B2561U, 0x6036F4U, 0xDDCF8FU, 0x96DD5BU,
|
||||
0xCF46D0U, 0xCCB729U, 0x96A4FEU, 0xDF3FC7U, 0xE44D10U, 0xADC4F9U, 0xB61366U, 0xFD2837U, 0xA4B888U, 0x8EC359U,
|
||||
0x5750B6U, 0x5C49AFU, 0x07BA79U, 0x4A2080U, 0x517307U, 0x38DA7EU, 0x62C9ADU, 0x611230U, 0x38A2CBU, 0x33F98EU,
|
||||
0x4A4A35U, 0x0153E0U, 0x98815BU, 0xD23A06U, 0xD929C5U, 0x80E079U, 0xEBD7AAU, 0xF20D57U, 0xBD1C4CU, 0xE6A78DU,
|
||||
0xEF7472U, 0x954CE3U, 0x9CDF9CU, 0xCF8455U, 0x0437C2U, 0x1DFE3BU, 0x56EC6CU, 0x6F57D5U, 0x25061BU, 0x7E95AAU,
|
||||
0x772FF5U, 0x2C7C24U, 0x05C59BU, 0x5A965AU, 0x111D21U, 0x892DBCU, 0xC2F26FU, 0x9B6192U, 0xB81891U, 0xE38B6EU,
|
||||
0xEA91B6U, 0xB16221U, 0xF9FB48U, 0xC2C8DFU, 0x890226U, 0x9013F9U, 0xDBE848U, 0x02FB07U, 0x0D62D6U, 0x77906DU,
|
||||
0x3E8BB0U, 0x2538C3U, 0x6C614EU, 0x77F39CU, 0x141861U, 0x4D0D7AU, 0x47968FU, 0x1EE544U, 0x157DD1U, 0xCEEEAAU,
|
||||
0xA7953FU, 0xBC06D4U, 0xF57E09U, 0xABED3AU, 0xA2EEE3U, 0xD91734U, 0xD2849CU, 0x8BDEC3U, 0xC06F32U, 0xD174ADU,
|
||||
0x9BA77CU, 0x201C93U, 0x690C8AU, 0x22F77DU, 0x3BF4E4U, 0x702933U, 0x4B9B5AU, 0x0380C1U, 0x585134U, 0x556AEEU,
|
||||
0x0EF9CBU, 0x45A310U, 0x7C12CDU, 0xB7C97EU, 0xAFEA23U, 0xEC72C0U, 0xB7215DU, 0x9E9A8EU, 0xC50BF3U, 0xCC5068U,
|
||||
0x97E28DU, 0xDDB916U, 0xC42846U, 0xAF93B9U, 0xF2D020U, 0x796CC7U, 0x223F9EU, 0x2BA429U, 0x5095F0U, 0x18473FU,
|
||||
0x03DC8EU, 0x40EFD1U, 0x593620U, 0x1225BFU, 0x6BCF76U, 0x605E40U, 0xBA6599U, 0xF3B66AU, 0xE8AEF7U, 0x851DBCU,
|
||||
0x9EC649U, 0xD5D5D2U, 0x8C2C27U, 0x863E7CU, 0xDFB5D9U, 0xF4C002U, 0xA55BDFU, 0xEEE9ECU, 0x75B020U, 0x3C23D3U,
|
||||
0x06584AU, 0x4FCB15U, 0x1453A4U, 0x1F306BU, 0x42AB9AU, 0x09FA05U, 0x30415CU, 0x7A53ABU, 0x61AA22U, 0x2839D5U,
|
||||
0xF3228CU, 0xDAD032U, 0x89C9E3U, 0x820A2CU, 0xCAB91DU, 0x91A4C6U, 0x985673U, 0xE34DB8U, 0xA8DCE5U, 0xB52756U,
|
||||
0xFE358BU, 0xE6EE78U, 0x0DDF75U, 0x5654AFU, 0x5F075AU, 0x04BFC1U, 0x0D2CB4U, 0x56577FU, 0x34C6C2U, 0x2D9D11U,
|
||||
0x662F48U, 0x3FB4FFU, 0x34E536U, 0x4F4E89U, 0xC61C58U, 0x988107U, 0xD132A7U, 0xCA6978U, 0x81D881U, 0xB8C296U,
|
||||
0xF3114FU, 0xAA2AA8U, 0xA0FB31U, 0xF37142U, 0xDA429FU, 0x819B24U, 0x4888E1U, 0x5333FAU, 0x1AE30FU, 0x40D0D5U,
|
||||
0x6F0B68U, 0x36182BU, 0x3DA0F6U, 0x646345U, 0x2F7898U, 0x14CDF3U, 0x5C9666U, 0xC704BDU, 0x8E7F4CU, 0xDDEED3U,
|
||||
0xD655BAU, 0xAF062DU, 0xE49EF5U, 0xFDFD02U, 0xB7661BU, 0xA8F7F4U, 0xC18D25U, 0x9A1E9AU, 0x9305CBU, 0x48F414U,
|
||||
0x43EFB5U, 0x1B1D6AU, 0x708413U, 0x698780U, 0x2A7C4DU, 0x6168BFU, 0x78F3A2U, 0x130059U, 0x0B1BCCU, 0x40CA07U,
|
||||
0x1FF072U, 0x9663E9U, 0xCD9A14U, 0xE499C7U, 0xBF0AEAU, 0xF57239U, 0xECE1E4U, 0xA7BA5FU, 0xDE098FU, 0xD591E0U,
|
||||
0x86E271U, 0x8F79AEU, 0xD52817U, 0x1C8350U, 0x2711A9U, 0x684C3EU, 0x71FFE7U, 0x3AE490U, 0x633619U, 0x498FE6U,
|
||||
0x10DC37U, 0x1B670DU, 0x4066D8U, 0x09BC13U, 0x328FAEU, 0xFB16FDU, 0xA9C500U, 0xA2FF93U, 0xFB2C5EU, 0xF03565U,
|
||||
0x8D86B0U, 0xC65D4BU, 0xDD7DCEU, 0x95E615U, 0x8EB169U, 0xE708FAU, 0xBCDB03U, 0x37C1C4U, 0x6E72FDU, 0x25232AU,
|
||||
0x3DB8F3U, 0x5ECA4CU, 0x45430DU, 0x0CF0B2U, 0x57AB61U, 0x5E3ABCU, 0x210087U, 0x2BD343U, 0xF248B8U, 0xB9392DU,
|
||||
0xA0A376U, 0xEBB09FU, 0x905908U, 0x99CAF1U, 0xD3F5A6U, 0xCA251FU, 0x813ED0U, 0xF2CD01U, 0xFBD63EU, 0xA046EEU,
|
||||
0x29BD51U, 0x76AE98U, 0x3C274FU, 0x055476U, 0x4ECEA5U, 0x573F58U, 0x1C24DBU, 0x47B786U, 0x6ECC7DU, 0x345CE8U,
|
||||
0x7D0703U, 0x66B456U, 0xAF3DECU, 0xBC6F31U, 0xD7D0A2U, 0x8EC1CFU, 0x80321CU, 0xD9A9A1U, 0xD2FB7AU, 0xA9422BU,
|
||||
0xE05184U, 0xFB8A55U, 0xB22AAAU, 0xE831B3U, 0x63E264U, 0x1ADB8CU, 0x11081BU, 0x4832E2U, 0x0BA1BDU, 0x10781CU,
|
||||
0x784BC3U, 0x679052U, 0x2E902DU, 0x752BFCU, 0x7EFC57U, 0x27C58AU, 0xCC57D9U, 0xD40C64U, 0x9FBFB6U, 0x84665BU,
|
||||
0xCD7540U, 0xB6CF95U, 0xBF8E6EU, 0xE415FBU, 0xE62690U, 0xBFFE0DU, 0xF04DFEU, 0xC91623U, 0x028520U, 0x19BCD9U,
|
||||
0x506E06U, 0x0AEDB6U, 0x23D4E9U, 0x780728U, 0x331997U, 0x3AE84EU, 0x6173B9U, 0x6840A0U, 0x129B67U, 0x598B9EU,
|
||||
0xC87009U, 0x877370U, 0x9EEAEBU, 0xF5190EU, 0xAC03D4U, 0xA690C1U, 0xFDE93AU, 0xB47AF7U, 0xAF8044U, 0xC69119U,
|
||||
0xDD0ACAU, 0x166977U, 0x4EF0BCU, 0x45E2C9U, 0x3C1D52U, 0x3F8E87U, 0x64D73CU, 0x296574U, 0x327E83U, 0x7A8F1AU,
|
||||
0x0114EDU, 0x0A1734U, 0x53EF3BU, 0xD8FCCAU, 0x812715U, 0xEA94A4U, 0xF185EBU, 0xB95F3AU, 0xA26C85U, 0xEBB55CU,
|
||||
0xB0862AU, 0x930CA3U, 0xCEDD70U, 0x85E6CDU, 0x9D7196U, 0x562A63U, 0x6D9AE8U, 0x24411DU, 0x7F5246U, 0x76EBDBU,
|
||||
0x2DB928U, 0x2712E5U, 0x5E83D7U, 0x15D80AU, 0x0C6BD1U, 0x473170U, 0x54A02FU, 0xB99B9EU, 0xE34841U, 0xEAD090U,
|
||||
0xB1E33FU, 0xFA2866U, 0xE31991U, 0x88C208U, 0x8154FFU, 0xDB6FB7U, 0x92BE28U, 0x89A5D9U, 0xE25606U, 0x7BCE37U,
|
||||
0x30FDFCU, 0x693E21U, 0x6F2792U, 0x3495CFU, 0x5DCE6CU, 0x465DB1U, 0x0FA46AU, 0x14B75FU, 0x5F2D85U, 0x275C60U,
|
||||
0x2CC7FBU, 0xF56486U, 0xFE3C55U, 0xA5ABC8U, 0xECD02BU, 0xD743F2U, 0x9FDAC5U, 0xC0A81CU, 0xC33383U, 0x9A2262U,
|
||||
0xB1D93DU, 0xE8DA8DU, 0x232252U, 0x39B19BU, 0x70AAACU, 0x6B5975U, 0x024182U, 0x59921BU, 0x522974U, 0x0B38A5U,
|
||||
0x01F33EU, 0x78C1CBU, 0x3758D0U, 0x242F3DU, 0xEDB4EFU, 0xB66672U, 0xBF5701U, 0xC5CCDCU, 0xCE9F77U, 0x9726A2U,
|
||||
0xDCA4F9U, 0xC5FF4CU, 0xAE4E87U, 0xB51576U, 0xFDA7E9U, 0xA63C90U, 0x2F6D47U, 0x74D6CFU, 0x1BC538U, 0x0A1D21U,
|
||||
0x413EDEU, 0x58E50FU, 0x127480U, 0x6B4BF1U, 0x60992EU, 0x2BA297U, 0x327340U, 0x79E809U, 0xA0DABAU, 0x8A0367U,
|
||||
0xD1009DU, 0x98BB98U, 0x836A63U, 0xCE70F6U, 0xF5832DU, 0xB69850U, 0xEE29D3U, 0xE5732EU, 0xBCE0FDU, 0xB75962U,
|
||||
0x4C1A13U, 0x0589DCU, 0x1EF165U, 0x5666B7U, 0x4DFDEAU, 0x268E59U, 0x7F1794U, 0x74256FU, 0x29FE7AU, 0x626F81U,
|
||||
0x700404U, 0x1996DFU, 0x828FA2U, 0xCB7C31U, 0x9067CCU, 0x9B940EU, 0xE20C17U, 0xE81FE8U, 0xB1E439U, 0xFAF586U,
|
||||
0xE17FC7U, 0xA88C18U, 0xD397A1U, 0x5E4276U, 0x04794FU, 0x0FEB88U, 0x5E9271U, 0x3501E6U, 0x2C9A3EU, 0x67EA51U,
|
||||
0x7C61C0U, 0x34323BU, 0x6F89EEU, 0x4618F5U, 0x1D4218U, 0xD4F1CBU, 0xCFE876U, 0x841B25U, 0xB888F8U, 0xF3D053U,
|
||||
0xAA7386U, 0xA168BCU, 0xF2BB69U, 0xFB8792U, 0x80541FU, 0xC8CF4CU, 0xC3FEB5U, 0x182522U, 0x1117CBU, 0x6A9E9CU,
|
||||
0x234D05U, 0x3876FAU, 0x72A42BU, 0x2FBD84U, 0x240ED4U, 0x5DD54BU, 0x56C4B2U, 0x057E65U, 0x4C2D4CU, 0xD7849BU,
|
||||
0xBFD762U, 0xA44DF9U, 0xEFFEACU, 0xB6A347U, 0xBD30D2U, 0xC40B29U, 0x8FDB74U, 0x9540E6U, 0xDC330BU, 0xC3BAD8U,
|
||||
0x8A89E5U, 0x71533EU, 0x7AC0BBU, 0x2BB140U, 0x212A11U, 0x7838AEU, 0x13C17FU, 0x08D290U, 0x414989U, 0x1AA85EU,
|
||||
0x13B2A6U, 0x494131U, 0x625AD8U, 0xBBCF87U, 0xF43516U, 0xED26E9U, 0xA6BF78U, 0x9FCC17U, 0xDD57CEU, 0x86B75DU,
|
||||
0x8FACA0U, 0xD43FE3U, 0x9D445EU, 0xA6D584U, 0x6DCF71U, 0x753C6AU, 0x3EA5AFU, 0x67F654U, 0x4C4CC9U, 0x134DBAU,
|
||||
0x1AB667U, 0x4125E4U, 0x097E19U, 0x12CA0AU, 0x71D1F3U, 0x78022CU, 0xA33BACU, 0xEAA953U, 0xF17A02U, 0x9B53BDU,
|
||||
0xC28074U, 0xC9BB83U, 0x90299AU, 0x9BF04DU, 0xC4C3B4U, 0xAD583BU, 0xB7084AU, 0xFEB3D1U, 0x656004U, 0x2E69FEU,
|
||||
0x5FDAF3U, 0x548000U, 0x0D37DDU, 0x472E4EU, 0x5CFD33U, 0x1546F8U, 0x2E164DU, 0x678D96U, 0x3CBEE3U, 0x337768U,
|
||||
0xEBE5BDU, 0xC09E47U, 0x990D5EU, 0xD234A9U, 0xC9E720U, 0x887DF7U, 0xD34C0EU, 0xFB9711U, 0xA084E0U, 0xA96C2FU,
|
||||
0xF27FBEU, 0xB9E4C1U, 0x001318U, 0x4B02AFU, 0x56B867U, 0x1CEB30U, 0x477289U, 0x4E8152U, 0x358AF7U, 0x3C1AACU,
|
||||
0x676159U, 0x24F2C2U, 0x3C6917U, 0x57197CU, 0x8E82E1U, 0x85F112U, 0xDE68CFU, 0xD77BDDU, 0x8C9130U, 0xE400EBU,
|
||||
0xFB5B5EU, 0xB0E885U, 0xA9F6D4U, 0xE2277BU, 0x9B9CA2U, 0x108F15U, 0x5A764CU, 0x0B64ABU, 0x00AF32U, 0x599CEDU,
|
||||
0x72059DU, 0x29D702U, 0x60ECE3U, 0x7A7D3CU, 0x330625U, 0x0C95D6U, 0x474D0BU, 0x9E7EA8U, 0x95FDF5U, 0xCCA666U,
|
||||
0x86179BU, 0xBD8D40U, 0xFCDA65U, 0xE763BFU, 0xAE304AU, 0xF58AD1U, 0xDE9B9CU, 0x86406FU, 0x8DE3F2U, 0x54B801U,
|
||||
0x1B28D8U, 0x0213D7U, 0x69C026U, 0x7259B9U, 0x3A6B48U, 0x61B017U, 0x68819FU, 0x135A68U, 0x50D9B1U, 0x49E386U,
|
||||
0x02325FU, 0x9A29B0U, 0xD19E23U, 0xAAC77EU, 0xA3558DU, 0xFCAE04U, 0xF5BFF3U, 0xAE04AAU, 0xC44635U, 0xDDDDC5U,
|
||||
0x966C4AU, 0xCF373BU, 0xC4A4E4U, 0x1FD47DU, 0x3E4F8AU, 0x64DC43U, 0x2DA574U, 0x3637ADU, 0x7D5C56U, 0x44CFC3U,
|
||||
0x0BD688U, 0x52257DU, 0x59BBE7U, 0x03AA1AU, 0x4A5119U, 0xF142C4U, 0xB89A37U, 0xB329AAU, 0xE822D1U, 0xA9D114U,
|
||||
0x93C88FU, 0xDA5A7AU, 0xC1A121U, 0x8AB090U, 0xD36B5EU, 0xDC58A7U, 0xA5C0B0U, 0x2F8369U, 0x74389EU, 0x3DAB17U,
|
||||
0x26D368U, 0x4F40F9U, 0x141F26U, 0x1DAEC7U, 0x473558U, 0x446721U, 0x1DDEF6U, 0x769D6EU, 0xEF0E8DU, 0xA434D0U,
|
||||
0xBFE56BU, 0xF35EBEU, 0x884D45U, 0x819440U, 0xDAA69BU, 0x917D26U, 0x88ECF5U, 0xC3C788U, 0xFB150BU, 0xB02ED6U,
|
||||
0x63BF24U, 0x6A6439U, 0x3153D2U, 0x188B03U, 0x43989CU, 0x0923EDU, 0x147232U, 0x5FF99BU, 0x060B4CU, 0x2D10B5U,
|
||||
0x76A1A2U, 0x7FFA7BU, 0xA568D4U, 0xECD104U, 0xD7827BU, 0x9C19EAU, 0x8D6831U, 0xC6E2DCU, 0x9F71CFU, 0x950A32U,
|
||||
0xEE9BE1U, 0xA3A16CU, 0xB8761FU, 0xF16FC2U, 0x6A9C79U, 0x010FACU, 0x491786U, 0x52F453U, 0x1BEF88U, 0x007C35U,
|
||||
0x4B8566U, 0x32978FU, 0x316C18U, 0x697DC1U, 0x62E6BEU, 0x3B142FU, 0xD40DC0U, 0xCFCE11U, 0x86F58EU, 0xDD66F6U,
|
||||
0xD53E31U, 0x8E8988U, 0xA5125FU, 0xFC6366U, 0xB7F9B9U, 0xAEAA78U, 0xE513C3U, 0xD69096U, 0x1ECB6DU, 0x4579F8U,
|
||||
0x4C6033U, 0x13B34EU, 0x5888DCU, 0x615821U, 0x2AE3F2U, 0x32F0FFU, 0x792B04U, 0x220A91U, 0x0B906AU, 0xD0432BU,
|
||||
0xD97294U, 0x82AD4DU, 0xC8BE9AU, 0xD90623U, 0xB2D564U, 0xEBEE9CU, 0xE02D03U, 0xBF35D2U, 0xB686ADU, 0xCCDD2CU,
|
||||
0x854CD3U, 0x1EF70AU, 0x55A51DU, 0x4C1CE4U, 0x074F67U, 0x7ED49AU, 0x7476C9U, 0x2F2F75U, 0x26BCBEU, 0x75876BU,
|
||||
0x1C5650U, 0x07C885U, 0x48BB7EU, 0x9022F3U, 0x9B11A0U, 0xC2CA5DU, 0xE9C8CEU, 0xA07133U, 0xFBA238U, 0xF0B9E9U,
|
||||
0xA84917U, 0x835286U, 0xDAC179U, 0x913830U, 0x822B87U, 0x4BD95EU, 0x30D289U, 0x3C43A0U, 0x67B87FU, 0x6CAA8EU,
|
||||
0x353311U, 0x7E4440U, 0x47DFABU, 0x0C8E3FU, 0x1634C4U, 0x5FA7D9U, 0x04CC0AU, 0xAD5DE7U, 0xF64774U, 0xBDB409U,
|
||||
0xAC2DD2U, 0xE67E67U, 0xFBC5ACU, 0x90D5F9U, 0xCB0E42U, 0xC23D9FU, 0x99B67DU, 0x9047E4U, 0xEA5DB3U, 0x218E0AU,
|
||||
0x38B7D5U, 0x732034U, 0x6AFA2BU, 0x21CBFAU, 0x5A1005U, 0x5B039CU, 0x01A8FBU, 0x4C7822U, 0x574395U, 0x3CD04DU,
|
||||
0xA5811AU, 0xEE3BB3U, 0xB76868U, 0xBDF19DU, 0xE64286U, 0xCF1943U, 0x949BF8U, 0xDDA225U, 0xC67156U, 0x8FCACBU,
|
||||
0xF59B08U, 0xF605F5U, 0x2B36EFU, 0x20EF1AU, 0x797CC1U, 0x324664U, 0x1985BFU, 0x419CE4U, 0x4A6F51U, 0x13748AU,
|
||||
0x58C42FU, 0x631F74U, 0x2A0CA1U, 0x71F51AU, 0xF9E7D7U, 0xA27CA5U, 0xA99F38U, 0xD886EBU, 0x973516U, 0x8E6F1DU,
|
||||
0xC5FEECU, 0xDF0133U, 0xB61282U, 0xED8ADDU, 0xE4F954U, 0xBF7AA3U, 0x74617AU, 0x6D904DU, 0x070A95U, 0x1E795AU,
|
||||
0x55E0EBU, 0x0EF334U, 0x0F0845U, 0x7098CAU, 0x798313U, 0x2360E0U, 0x687BFDU, 0x71AB0EU, 0xBA10C3U, 0x830370U,
|
||||
0xC8FA2DU, 0x93EDB7U, 0x9B3742U, 0xC00689U, 0xA99DBCU, 0xB25E67U, 0xF964BAU, 0xE0F509U, 0xA7AE44U, 0xFF1DB7U,
|
||||
0x54C42EU, 0x0DF6F1U, 0x066D90U, 0x5D3C0EU, 0x1487FFU, 0x2F8460U, 0x675E19U, 0x3CEFDEU, 0x37B447U, 0x6E27B0U,
|
||||
0x651369U, 0x9CC856U, 0xD77B97U, 0xC9604CU, 0x88B1F9U, 0x939BA2U, 0xFA4856U, 0xB1D1DDU, 0xAAE200U, 0xE33873U,
|
||||
0xB829EEU, 0xB0D20DU, 0xCBC190U, 0x407AEBU, 0x19AA3EU, 0x52A1A5U, 0x4B1240U, 0x204B1BU, 0x3ED9A2U, 0x7F2274U,
|
||||
0x2437ADU, 0x2DAC8AU, 0x76DF53U, 0x5D45ACU, 0x04F43DU, 0xCEBFE2U, 0xD72CC3U, 0x9C551CU, 0xE7C7E5U, 0xEEDC72U,
|
||||
0xB52D1BU, 0xBCB6CCU, 0xE6A454U, 0xA95FA7U, 0x904EFAU, 0xD3A551U, 0xCA3684U, 0x01265FU, 0x5ADD6AU, 0x72CEB1U,
|
||||
0x29135CU, 0x60A1CFU, 0x7BBA92U, 0x304921U, 0x2950FCU, 0x42D316U, 0x1AA903U, 0x1138F8U, 0x48E329U, 0xC7D0A6U,
|
||||
0xBC48DFU, 0xFD1B08U, 0xE6A0B1U, 0xAE3366U, 0xF55AAFU, 0xFEC898U, 0x879341U, 0x8C22FEU, 0xD5392EU, 0x9EEA61U,
|
||||
0x8456D0U, 0x6D450BU, 0x769EF6U, 0x3FADE5U, 0x606508U, 0x6BD6DBU, 0x3ACD46U, 0x101C3DU, 0x5927F8U, 0x02F543U,
|
||||
0x096C96U, 0x505FCCU, 0xBB8C71U, 0xA296B2U, 0xE8370FU, 0xF36C5CU, 0xBADF85U, 0xE1063AU, 0xC814FBU, 0x97AF04U,
|
||||
0x9CFA15U, 0xC461EAU, 0x87D23BU, 0xBE88B4U, 0x7509CCU, 0x2E721BU, 0x27E1A2U, 0x7C5965U, 0x750A7CU, 0x0F9183U,
|
||||
0x44A052U, 0x5D7BE9U, 0x1669ACU, 0x0F9277U, 0x6013CAU, 0x3B0819U, 0xB3FA65U, 0xE0E3E6U, 0xA9103BU, 0xB28BC0U,
|
||||
0xDB9ED5U, 0xC0642EU, 0x8B77EBU, 0xD3EC50U, 0xD80D89U, 0xA1179EU, 0xAAC477U, 0xF1F5A0U, 0x386E19U, 0x271D4FU,
|
||||
0x6F8596U, 0x541639U, 0x1F6DE8U, 0x4EFE97U, 0x45B706U, 0x1C05D9U, 0x779E30U, 0x6DCF27U, 0x2474DEU, 0x3F664DU,
|
||||
0xF69BB0U, 0xAD08FBU, 0x86536FU, 0xDFE094U, 0xD1E841U, 0x883B6AU, 0xC300B7U, 0xE8D164U, 0xB16BD9U, 0xF2788AU,
|
||||
0xEBA167U, 0xA192FCU, 0x3A0929U, 0x53DBD2U, 0x08F2C3U, 0x01212DU, 0x5A3ABCU, 0x518B43U, 0x29D11AU, 0x62628DU,
|
||||
0x7FFD64U, 0x34ACB3U, 0x6F1E8AU, 0xE64555U, 0x95C494U, 0x9D7F2BU, 0xC62C7AU, 0x8DB485U, 0x94871DU, 0xFF5CDEU,
|
||||
0xE6EFE3U, 0xADB730U, 0xF524CFU, 0xFE0F56U, 0xA5DE31U, 0x48C5E8U, 0x53377FU, 0x1AAE86U, 0x01BD59U, 0x4B4678U,
|
||||
0x3A50A7U, 0x31E977U, 0x683ACCU, 0x633189U, 0x38C072U, 0x71DAEFU, 0x4B493CU, 0x82B001U, 0x99A3C2U, 0xD2383FU,
|
||||
0x8F4AA4U, 0xA4D3D1U, 0xFDA00AU, 0xB62B8FU, 0xACBB75U, 0xE5C028U, 0xF6539BU, 0x9F4242U, 0xC4B985U, 0x4F2FBCU,
|
||||
0x167463U, 0x1CC5D2U, 0x65DE1DU, 0x2E3C4CU, 0x35A5F3U, 0x78F622U, 0x234DDDU, 0x0A5C55U, 0x408622U, 0x5BB5FBU,
|
||||
0x122E6CU, 0xC1FF95U, 0xC8C4DEU, 0xB3066BU, 0xB83FB0U, 0xE0AC25U, 0xAB775EU, 0xB24793U, 0xD9DC20U, 0x828BFDU,
|
||||
0x8F30AFU, 0xD46102U, 0xDCDBD9U, 0x07582CU, 0x6E0137U, 0x75B2C6U, 0x3EE809U, 0x2F7990U, 0x64C2E7U, 0x1C913EU,
|
||||
0x170A89U, 0x4C3A40U, 0x45E9D6U, 0x1E42AFU, 0x571370U, 0xE889C1U, 0xA2BA0EU, 0xFB635FU, 0xF070E0U, 0xA9CF39U,
|
||||
0x821DDAU, 0xD904C7U, 0x90F734U, 0x82FCE9U, 0xCB4D72U, 0xD09716U, 0x3B848DU, 0x623D78U, 0x696EA3U, 0x30F4BEU,
|
||||
0x7A075DU, 0x451E80U, 0x0C8D33U, 0x17E66EU, 0x5E76B5U, 0x050D14U, 0x0E9ECBU, 0x7607BAU, 0xF57524U, 0xACEAC5U,
|
||||
0xE7F91AU, 0xFC0083U, 0x9583F4U, 0xCED96DU, 0xC6688AU, 0x9D7353U, 0x92804CU, 0xCB11BDU, 0xA00B62U, 0xA9F8C3U,
|
||||
0x72E398U, 0x783244U, 0x2118F7U, 0x4A8B2AU, 0x5B5249U, 0x1061D4U, 0x09FA2FU, 0x428ABAU, 0x1911F1U, 0x31C604U,
|
||||
0x6AFD9FU, 0x276D62U, 0xBC2631U, 0xF795B8U, 0xCE4C4EU, 0x855F97U, 0xDDE520U, 0xD6B479U, 0x8D0FB6U, 0x8C1C07U,
|
||||
0xF7C6D8U, 0xBE77A9U, 0xA53C36U, 0xEFAFDFU, 0x369648U, 0x1D4411U, 0x40DFE6U, 0x4BEE7EU, 0x103595U, 0x5902C0U,
|
||||
0x43D85BU, 0x2AC9AEU, 0x316265U, 0x7AB158U, 0x23A18BU, 0x201A56U, 0xD949E5U, 0x93F2A8U, 0x882313U, 0xC139C6U,
|
||||
0xDA8A3CU, 0x97D329U, 0xEC50E2U, 0xE7AA13U, 0xBFBB8CU, 0xB42075U, 0xED5322U, 0x06C8ABU, 0x1DF85CU, 0x542785U,
|
||||
0x0FB4BAU, 0x0FCD7BU, 0x544FA4U, 0x7F5414U, 0x26A54BU, 0x6D3EF2U, 0x702D31U, 0x3BD7CCU, 0x13C6DFU, 0xC83D02U,
|
||||
0x83AEF9U, 0x9AB77CU, 0xD15507U, 0xC84ED2U, 0xA3DF49U, 0xF9A4BDU, 0xF836F6U, 0xA3ED4BU, 0xEADC98U, 0xD14B05U,
|
||||
0x9A30E6U, 0x03A0BFU, 0x4D6B00U, 0x1458D1U, 0x1FC12EU, 0x64932FU, 0x6D28F0U, 0x36BB09U, 0x7FE29FU, 0x6551E6U,
|
||||
0x0E0B21U, 0x57AAB8U, 0x54B147U, 0x8D6216U, 0x86DBA9U, 0xDDC968U, 0xB412F3U, 0xAA218EU, 0xE3FC5DU, 0xF86EF0U,
|
||||
0xB35523U, 0xCA945FU, 0xC1AFCCU, 0x983C11U, 0xD264FAU, 0x49D7EFU, 0x000C14U, 0x3B1FC1U, 0x7AA75AU, 0x21F4B7U,
|
||||
0x2A6FA4U, 0x728E5DU, 0x5D958AU, 0x042713U, 0x4F767DU, 0x54EDACU, 0x1D5E13U, 0x8604C0U, 0xEE91ADU, 0xB5EA36U,
|
||||
0xBC79E3U, 0xE77018U, 0xAC820DU, 0x9D19E6U, 0xD6283FU, 0xCEF3A8U, 0x85E0D1U, 0xDA1A47U, 0x538BAEU, 0x389079U,
|
||||
0x216360U, 0x6A6B9FU, 0x30D84EU, 0x3903E1U, 0x421230U, 0x0BE94FU, 0x10FBD6U, 0x5B6011U, 0x4215E8U, 0x008EFBU,
|
||||
0xF95C07U, 0xF2759CU, 0xADE659U, 0xA49D22U, 0xFF0CB7U, 0x96964CU, 0x8CE591U, 0xC77E92U, 0x9E2F6FU, 0x959CBCU,
|
||||
0xCC0601U, 0xE7475AU, 0x3CFCBFU, 0x74EF25U, 0x6717F4U, 0x2E048BU, 0x15DF0AU, 0x5A6CF5U, 0x03716CU, 0x08A33BU,
|
||||
0x5098C2U, 0x5B1945U, 0x20C2BCU, 0x69F063U, 0xF22972U, 0xBB1A8DU, 0xE0814DU, 0xCA52F6U, 0x936AABU, 0x98B958U,
|
||||
0xC9A2C5U, 0x820306U, 0x9B593BU, 0xF4CAE0U, 0xEE7315U, 0xA7209EU, 0x7C9BCBU, 0x75C930U, 0x0E54A4U, 0x45E75FU,
|
||||
0x5CBC12U, 0x173D81U, 0x0F0778U, 0x44D4AFU, 0x3FC596U, 0x363E59U, 0x65ACE8U, 0x6C9737U, 0xA346E6U, 0xD95DD9U,
|
||||
0xD0FE10U, 0x8B26E6U, 0xC2357FU, 0xD9CE28U, 0x92DDC1U, 0xAB455EU, 0xE1B6AFU, 0xB8ADF4U, 0xB35861U, 0x68438AU,
|
||||
0x41C157U, 0x12B864U, 0x5B2BB9U, 0x45B00AU, 0x0EC3C6U, 0x175B95U, 0x7C2828U, 0x25B3F3U, 0x2E2206U, 0x75580DU,
|
||||
0x3DDBD8U, 0x86C223U, 0xCF31BAU, 0xD4AADDU, 0x9FF804U, 0xC64193U, 0xCD526AU, 0xBDA9F4U, 0xB2BD95U, 0xE92E4AU,
|
||||
0xA0C5FBU, 0xBBD424U, 0xD20F7DU, 0x093DDAU, 0x01A603U, 0x5A77F0U, 0x514CEDU, 0x089E36U, 0x63A7D3U, 0x7A3448U,
|
||||
0x31FF3CU, 0x2BCEE7U, 0x625462U, 0x150799U, 0x1CBC84U, 0xC7ED77U, 0x8C76AAU, 0x95C409U, 0xDF9954U, 0xE62A8FU,
|
||||
0xAD213EU, 0xF6F1E1U, 0xFF4A00U, 0xA4191EU, 0x8D82C7U, 0xD7B330U, 0x9C69A9U, 0x057ACEU, 0x42C357U, 0x2B1088U,
|
||||
0x303A79U, 0x7BEB76U, 0x63F087U, 0x284358U, 0x7198E1U, 0x5A88B2U, 0x017B7EU, 0x0860CDU, 0x53F510U, 0x9A0F63U,
|
||||
0xA00CFEU, 0xEBB535U, 0xF2E6C0U, 0xB97DDBU, 0xEC0F2EU, 0xE796B5U, 0x9C0578U, 0xD47E0BU, 0xCFEF92U, 0x86F564U,
|
||||
0x1D16ADU, 0x768F32U, 0x2FFC43U, 0x24669CU, 0x7C752DU, 0x778CE2U, 0x2E1F9BU, 0x45000CU, 0x5EF0D5U, 0x13FB62U,
|
||||
0x40282BU, 0x4811D4U, 0xB38344U, 0xB8789FU, 0xE16BEAU, 0xAAB261U, 0xB38194U, 0xF81B4FU, 0xC2CA52U, 0x8BE1B1U,
|
||||
0xD0726CU, 0xD903DFU, 0x829982U, 0xE94A79U, 0x7471FDU, 0x36E026U, 0x2FBA93U, 0x640DC8U, 0x3F1431U, 0x16D7B6U,
|
||||
0x4D6C6FU, 0x443C18U, 0x1E8781U, 0x55947EU, 0x6C4FBFU, 0x27FFA0U, 0xBEE451U, 0xF5378FU, 0xAE0E2EU, 0xA2CD71U,
|
||||
0xC9D7C8U, 0x98661FU, 0x93BDC6U, 0xC88EE5U, 0xC15438U, 0xBA45C3U, 0xF2FE56U, 0xE9290DU, 0x2230E8U, 0x3B9273U,
|
||||
0x70C98FU, 0x0958DCU, 0x02A343U, 0x58B0A2U, 0x150A7DU, 0x0E5BC4U, 0x6FC897U, 0x74F33AU, 0x3F23E9U, 0x66A834U,
|
||||
0xECDB0FU, 0xB542DAU, 0x9E5131U, 0xC7ABA5U, 0x8C38FEU, 0x97010BU, 0xDED290U, 0xA4CC7DU, 0xAD3D2EU, 0xF6B6B3U,
|
||||
0xF9A540U, 0x205ED9U, 0x634EB6U, 0x5A9567U, 0x11A6D8U, 0x0B3F09U};
|
||||
|
||||
const unsigned int DMR_A_TABLE[] = {0U, 4U, 8U, 12U, 16U, 20U, 24U, 28U, 32U, 36U, 40U, 44U,
|
||||
48U, 52U, 56U, 60U, 64U, 68U, 1U, 5U, 9U, 13U, 17U, 21U};
|
||||
const unsigned int DMR_B_TABLE[] = {25U, 29U, 33U, 37U, 41U, 45U, 49U, 53U, 57U, 61U, 65U, 69U,
|
||||
2U, 6U, 10U, 14U, 18U, 22U, 26U, 30U, 34U, 38U, 42U};
|
||||
const unsigned int DMR_C_TABLE[] = {46U, 50U, 54U, 58U, 62U, 66U, 70U, 3U, 7U, 11U, 15U, 19U, 23U,
|
||||
27U, 31U, 35U, 39U, 43U, 47U, 51U, 55U, 59U, 63U, 67U, 71U};
|
||||
|
||||
|
||||
const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
||||
|
||||
const unsigned int INTERLEAVE_TABLE_26_4[] = {
|
||||
0U, 4U, 8U, 12U, 16U, 20U, 24U, 28U, 32U, 36U, 40U, 44U, 48U, 52U, 56U, 60U, 64U, 68U, 72U, 76U, 80U, 84U, 88U, 92U, 96U, 100U,
|
||||
1U, 5U, 9U, 13U, 17U, 21U, 25U, 29U, 33U, 37U, 41U, 45U, 49U, 53U, 57U, 61U, 65U, 69U, 73U, 77U, 81U, 85U, 89U, 93U, 97U, 101U,
|
||||
2U, 6U, 10U, 14U, 18U, 22U, 26U, 30U, 34U, 38U, 42U, 46U, 50U, 54U, 58U, 62U, 66U, 70U, 74U, 78U, 82U, 86U, 90U, 94U, 98U, 102U,
|
||||
3U, 7U, 11U, 15U, 19U, 23U, 27U, 31U, 35U, 39U, 43U, 47U, 51U, 55U, 59U, 63U, 67U, 71U, 75U, 79U, 83U, 87U, 91U, 95U, 99U, 103U};
|
||||
|
||||
const unsigned char WHITENING_DATA[] = {0x93U, 0xD7U, 0x51U, 0x21U, 0x9CU, 0x2FU, 0x6CU, 0xD0U, 0xEFU, 0x0FU,
|
||||
0xF8U, 0x3DU, 0xF1U, 0x73U, 0x20U, 0x94U, 0xEDU, 0x1EU, 0x7CU, 0xD8U};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// macros
|
||||
|
||||
#define WRITE_BIT(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
|
||||
#define READ_BIT(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
void CYsfUtils::DecodeVD2Vchs(uint8 *data, uint8 **ambe)
|
||||
{
|
||||
int frame = 0;
|
||||
|
||||
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||
|
||||
unsigned int offset = 40U; // DCH(0)
|
||||
|
||||
// We have a total of 5 VCH sections, iterate through each
|
||||
for (unsigned int j = 0U; j < 5U; j++, offset += 144U) {
|
||||
|
||||
unsigned char vch[13U];
|
||||
unsigned int dat_a = 0U;
|
||||
unsigned int dat_b = 0U;
|
||||
unsigned int dat_c = 0U;
|
||||
|
||||
// Deinterleave
|
||||
for (unsigned int i = 0U; i < 104U; i++) {
|
||||
unsigned int n = INTERLEAVE_TABLE_26_4[i];
|
||||
bool s = READ_BIT(data, offset + n);
|
||||
WRITE_BIT(vch, i, s);
|
||||
}
|
||||
|
||||
// "Un-whiten" (descramble)
|
||||
for (unsigned int i = 0U; i < 13U; i++)
|
||||
vch[i] ^= WHITENING_DATA[i];
|
||||
|
||||
for (unsigned int i = 0U; i < 12U; i++) {
|
||||
dat_a <<= 1U;
|
||||
if (READ_BIT(vch, 3U*i + 1U))
|
||||
dat_a |= 0x01U;;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0U; i < 12U; i++) {
|
||||
dat_b <<= 1U;
|
||||
if (READ_BIT(vch, 3U*(i + 12U) + 1U))
|
||||
dat_b |= 0x01U;;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0U; i < 3U; i++) {
|
||||
dat_c <<= 1U;
|
||||
if (READ_BIT(vch, 3U*(i + 24U) + 1U))
|
||||
dat_c |= 0x01U;;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0U; i < 22U; i++) {
|
||||
dat_c <<= 1U;
|
||||
if (READ_BIT(vch, i + 81U))
|
||||
dat_c |= 0x01U;;
|
||||
}
|
||||
|
||||
// convert to ambe2plus
|
||||
unsigned char v_dmr[9U];
|
||||
|
||||
unsigned int a = CGolay24128::encode24128(dat_a);
|
||||
unsigned int p = PRNG_TABLE[dat_a] >> 1;
|
||||
unsigned int b = CGolay24128::encode23127(dat_b) >> 1;
|
||||
b ^= p;
|
||||
|
||||
unsigned int MASK = 0x800000U;
|
||||
for (unsigned int i = 0U; i < 24U; i++, MASK >>= 1) {
|
||||
unsigned int aPos = DMR_A_TABLE[i];
|
||||
WRITE_BIT(v_dmr, aPos, a & MASK);
|
||||
}
|
||||
|
||||
MASK = 0x400000U;
|
||||
for (unsigned int i = 0U; i < 23U; i++, MASK >>= 1) {
|
||||
unsigned int bPos = DMR_B_TABLE[i];
|
||||
WRITE_BIT(v_dmr, bPos, b & MASK);
|
||||
}
|
||||
|
||||
MASK = 0x1000000U;
|
||||
for (unsigned int i = 0U; i < 25U; i++, MASK >>= 1) {
|
||||
unsigned int cPos = DMR_C_TABLE[i];
|
||||
WRITE_BIT(v_dmr, cPos, dat_c & MASK);
|
||||
}
|
||||
|
||||
::memcpy(ambe[frame++], v_dmr, 9);
|
||||
}
|
||||
}
|
||||
|
||||
void CYsfUtils::EncodeVD2Vch(uint8 *ambe, uint8 *data)
|
||||
{
|
||||
// convert from ambe2plus
|
||||
unsigned int a = 0U;
|
||||
unsigned int MASK = 0x800000U;
|
||||
for (unsigned int i = 0U; i < 24U; i++, MASK >>= 1) {
|
||||
unsigned int aPos = DMR_A_TABLE[i];
|
||||
|
||||
if (READ_BIT(ambe, aPos))
|
||||
a |= MASK;
|
||||
}
|
||||
|
||||
unsigned int b = 0U;
|
||||
MASK = 0x400000U;
|
||||
for (unsigned int i = 0U; i < 23U; i++, MASK >>= 1) {
|
||||
unsigned int bPos = DMR_B_TABLE[i];
|
||||
|
||||
if (READ_BIT(ambe, bPos))
|
||||
b |= MASK;
|
||||
}
|
||||
|
||||
unsigned int dat_c = 0U;
|
||||
MASK = 0x1000000U;
|
||||
for (unsigned int i = 0U; i < 25U; i++, MASK >>= 1) {
|
||||
unsigned int cPos = DMR_C_TABLE[i];
|
||||
|
||||
if (READ_BIT(ambe, cPos))
|
||||
dat_c |= MASK;
|
||||
}
|
||||
|
||||
// and to vch
|
||||
unsigned char vch[13U];
|
||||
unsigned char ysfFrame[13U];
|
||||
::memset(vch, 0U, 13U);
|
||||
::memset(ysfFrame, 0, 13U);
|
||||
|
||||
unsigned int dat_a = a >> 12;
|
||||
|
||||
// The PRNG
|
||||
b ^= (PRNG_TABLE[dat_a] >> 1);
|
||||
|
||||
unsigned int dat_b = b >> 11;
|
||||
|
||||
for (unsigned int i = 0U; i < 12U; i++) {
|
||||
bool s = (dat_a << (20U + i)) & 0x80000000U;
|
||||
WRITE_BIT(vch, 3*i + 0U, s);
|
||||
WRITE_BIT(vch, 3*i + 1U, s);
|
||||
WRITE_BIT(vch, 3*i + 2U, s);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0U; i < 12U; i++) {
|
||||
bool s = (dat_b << (20U + i)) & 0x80000000U;
|
||||
WRITE_BIT(vch, 3*(i + 12U) + 0U, s);
|
||||
WRITE_BIT(vch, 3*(i + 12U) + 1U, s);
|
||||
WRITE_BIT(vch, 3*(i + 12U) + 2U, s);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0U; i < 3U; i++) {
|
||||
bool s = (dat_c << (7U + i)) & 0x80000000U;
|
||||
WRITE_BIT(vch, 3*(i + 24U) + 0U, s);
|
||||
WRITE_BIT(vch, 3*(i + 24U) + 1U, s);
|
||||
WRITE_BIT(vch, 3*(i + 24U) + 2U, s);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0U; i < 22U; i++) {
|
||||
bool s = (dat_c << (10U + i)) & 0x80000000U;
|
||||
WRITE_BIT(vch, i + 81U, s);
|
||||
}
|
||||
|
||||
WRITE_BIT(vch, 103U, 0U);
|
||||
|
||||
// Scramble
|
||||
for (unsigned int i = 0U; i < 13U; i++)
|
||||
vch[i] ^= WHITENING_DATA[i];
|
||||
|
||||
// Interleave
|
||||
for (unsigned int i = 0U; i < 104U; i++) {
|
||||
unsigned int n = INTERLEAVE_TABLE_26_4[i];
|
||||
bool s = READ_BIT(vch, i);
|
||||
WRITE_BIT(ysfFrame, n, s);
|
||||
}
|
||||
|
||||
::memcpy(data, ysfFrame, 13U);
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
//
|
||||
// cysfutils.h
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 14/04/2019.
|
||||
// Copyright © 2019 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
// Copyright (C) 2016,2017 by Jonathan Naylor G4KLX
|
||||
// Copyright (C) 2018 by Andy Uribe CA6JAU
|
||||
// Copyright (C) 2018 by Manuel Sanchez EA7EE
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef cysfutils_h
|
||||
#define cysfutils_h
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CYsfUtils
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CYsfUtils() {};
|
||||
|
||||
// destructor
|
||||
virtual ~CYsfUtils() {};
|
||||
|
||||
// operation
|
||||
static void DecodeVD2Vchs(uint8 *, uint8 **);
|
||||
static void EncodeVD2Vch(uint8 *, uint8 *);
|
||||
|
||||
|
||||
protected:
|
||||
// data
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#endif /* cysfutils_h */
|
|
@ -125,7 +125,6 @@ int main(int argc, const char * argv[])
|
|||
std::cin.get();
|
||||
#ifdef DEBUG_DUMPFILE
|
||||
g_Reflector.m_DebugFile.close();
|
||||
g_Reflector.m_DebugFile.open("/Users/jeanluc/Desktop/dmrdebug.txt");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
40
src/main.h
40
src/main.h
|
@ -3,7 +3,7 @@
|
|||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 31/10/2015.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
// Copyright © 2015-2019 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
|
@ -48,14 +48,16 @@
|
|||
// version -----------------------------------------------------
|
||||
|
||||
#define VERSION_MAJOR 2
|
||||
#define VERSION_MINOR 2
|
||||
#define VERSION_REVISION 2
|
||||
#define VERSION_MINOR 3
|
||||
#define VERSION_REVISION 1
|
||||
|
||||
// global ------------------------------------------------------
|
||||
|
||||
#define RUN_AS_DAEMON
|
||||
#define JSON_MONITOR
|
||||
//#define NO_ERROR_ON_XML_OPEN_FAIL
|
||||
|
||||
// debug -------------------------------------------------------
|
||||
//#define DEBUG_NO_ERROR_ON_XML_OPEN_FAIL
|
||||
//#define DEBUG_DUMPFILE
|
||||
|
||||
// reflector ---------------------------------------------------
|
||||
|
@ -65,7 +67,7 @@
|
|||
|
||||
// protocols ---------------------------------------------------
|
||||
|
||||
#define NB_OF_PROTOCOLS 6
|
||||
#define NB_OF_PROTOCOLS 7
|
||||
|
||||
#define PROTOCOL_ANY -1
|
||||
#define PROTOCOL_NONE 0
|
||||
|
@ -75,6 +77,7 @@
|
|||
#define PROTOCOL_XLX 4
|
||||
#define PROTOCOL_DMRPLUS 5
|
||||
#define PROTOCOL_DMRMMDVM 6
|
||||
#define PROTOCOL_YSF 7
|
||||
|
||||
// DExtra
|
||||
#define DEXTRA_PORT 30001 // UDP port
|
||||
|
@ -111,6 +114,14 @@
|
|||
#define DMRMMDVM_REFLECTOR_SLOT DMR_SLOT2
|
||||
#define DMRMMDVM_REFLECTOR_COLOUR 1
|
||||
|
||||
// YSF
|
||||
#define YSF_PORT 42000 // UDP port
|
||||
#define YSF_KEEPALIVE_PERIOD 3 // in seconds
|
||||
#define YSF_KEEPALIVE_TIMEOUT (YSF_KEEPALIVE_PERIOD*10) // in seconds
|
||||
#define YSF_DEFAULT_NODE_TX_FREQ 437000000 // in Hz
|
||||
#define YSF_DEFAULT_NODE_RX_FREQ 437000000 // in Hz
|
||||
|
||||
|
||||
// Transcoder server --------------------------------------------
|
||||
|
||||
#define TRANSCODER_PORT 10100 // UDP port
|
||||
|
@ -120,9 +131,9 @@
|
|||
|
||||
// codec --------------------------------------------------------
|
||||
|
||||
#define CODEC_NONE 0
|
||||
#define CODEC_AMBEPLUS 1 // DStar
|
||||
#define CODEC_AMBE2PLUS 2 // DMR
|
||||
#define CODEC_NONE 0
|
||||
#define CODEC_AMBEPLUS 1 // DStar
|
||||
#define CODEC_AMBE2PLUS 2 // DMR
|
||||
|
||||
|
||||
// DMRid database -----------------------------------------------
|
||||
|
@ -131,6 +142,11 @@
|
|||
#define DMRIDDB_PATH "/xlxd/dmrid.dat" // local file path
|
||||
#define DMRIDDB_REFRESH_RATE 180 // in minutes
|
||||
|
||||
// Wires-X node database ----------------------------------------
|
||||
|
||||
#define YSFNODEDB_USE_RLX_SERVER 1 // 1 = use http, 0 = use local file
|
||||
#define YSFNODEDB_PATH "/xlxd/ysfnode.dat" // local file path
|
||||
#define YSFNODEDB_REFRESH_RATE 180 // in minutes
|
||||
|
||||
// xml & json reporting -----------------------------------------
|
||||
|
||||
|
@ -189,6 +205,14 @@ extern CGateKeeper g_GateKeeper;
|
|||
extern CDmridDirFile g_DmridDir;
|
||||
#endif
|
||||
|
||||
#if (YSFNODEDB_USE_RLX_SERVER == 1)
|
||||
class CYsfNodeDirHttp;
|
||||
extern CYsfNodeDirHttp g_YsfNodeDir;
|
||||
#else
|
||||
class CYsfNodeDirFile;
|
||||
extern CYsfNodeDirFile g_YsfNodeDir;
|
||||
#endif
|
||||
|
||||
class CTranscoder;
|
||||
extern CTranscoder g_Transcoder;
|
||||
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#if !defined(YSFDefines_H)
|
||||
#define YSFDefines_H
|
||||
|
||||
const unsigned int YSF_FRAME_LENGTH_BYTES = 120U;
|
||||
|
||||
const unsigned char YSF_SYNC_BYTES[] = {0xD4U, 0x71U, 0xC9U, 0x63U, 0x4DU};
|
||||
const unsigned int YSF_SYNC_LENGTH_BYTES = 5U;
|
||||
|
||||
const unsigned int YSF_FICH_LENGTH_BYTES = 25U;
|
||||
|
||||
const unsigned char YSF_SYNC_OK = 0x01U;
|
||||
|
||||
const unsigned int YSF_CALLSIGN_LENGTH = 10U;
|
||||
|
||||
const unsigned char YSF_FI_HEADER = 0x00U;
|
||||
const unsigned char YSF_FI_COMMUNICATIONS = 0x01U;
|
||||
const unsigned char YSF_FI_TERMINATOR = 0x02U;
|
||||
const unsigned char YSF_FI_TEST = 0x03U;
|
||||
|
||||
const unsigned char YSF_DT_VD_MODE1 = 0x00U;
|
||||
const unsigned char YSF_DT_DATA_FR_MODE = 0x01U;
|
||||
const unsigned char YSF_DT_VD_MODE2 = 0x02U;
|
||||
const unsigned char YSF_DT_VOICE_FR_MODE = 0x03U;
|
||||
|
||||
const unsigned char YSF_CM_GROUP = 0x00U;
|
||||
const unsigned char YSF_CM_INDIVIDUAL = 0x03U;
|
||||
|
||||
const unsigned char YSF_MR_NOT_BUSY = 0x01U;
|
||||
const unsigned char YSF_MR_BUSY = 0x02U;
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue