mirror of
https://github.com/nostar/urfd.git
synced 2026-11-08 04:19:39 +00:00
M17 Protocol introduction
This commit is contained in:
1 parent
d013a3d532
commit
47abcf0fdc
46 files changed
+1733
-391
No files matched your search
+12
-12
@@ -25,7 +25,7 @@
|
||||
CBuffer::CBuffer(uint8_t *buffer, int len)
|
||||
{
|
||||
m_data.resize(len);
|
||||
::memcpy(m_data.data(), buffer, len);
|
||||
memcpy(m_data.data(), buffer, len);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -34,7 +34,7 @@ CBuffer::CBuffer(uint8_t *buffer, int len)
|
||||
void CBuffer::Set(uint8_t *buffer, int len)
|
||||
{
|
||||
m_data.resize(len);
|
||||
::memcpy(m_data.data(), buffer, len);
|
||||
memcpy(m_data.data(), buffer, len);
|
||||
}
|
||||
|
||||
void CBuffer::Set(const char *sz)
|
||||
@@ -47,35 +47,35 @@ void CBuffer::Append(const uint8_t *buffer, int len)
|
||||
{
|
||||
int n = (int)m_data.size();
|
||||
m_data.resize(n+len);
|
||||
::memcpy(&(m_data.data()[n]), buffer, len);
|
||||
memcpy(&(m_data.data()[n]), buffer, len);
|
||||
}
|
||||
|
||||
void CBuffer::Append(uint8_t ui, int len)
|
||||
{
|
||||
int n = (int)m_data.size();
|
||||
m_data.resize(n+len);
|
||||
::memset(&(m_data.data()[n]), ui, len);
|
||||
memset(&(m_data.data()[n]), ui, len);
|
||||
}
|
||||
|
||||
void CBuffer::Append(uint8_t ui)
|
||||
{
|
||||
int n = (int)m_data.size();
|
||||
m_data.resize(n+sizeof(uint8_t));
|
||||
::memcpy(&(m_data.data()[n]), &ui, sizeof(uint8_t));
|
||||
memcpy(&(m_data.data()[n]), &ui, sizeof(uint8_t));
|
||||
}
|
||||
|
||||
void CBuffer::Append(uint16_t ui)
|
||||
{
|
||||
int n = (int)m_data.size();
|
||||
m_data.resize(n+sizeof(uint16_t));
|
||||
::memcpy(&(m_data.data()[n]), &ui, sizeof(uint16_t));
|
||||
memcpy(&(m_data.data()[n]), &ui, sizeof(uint16_t));
|
||||
}
|
||||
|
||||
void CBuffer::Append(uint32_t ui)
|
||||
{
|
||||
int n = (int)m_data.size();
|
||||
m_data.resize(n+sizeof(uint32_t));
|
||||
::memcpy(&(m_data.data()[n]), &ui, sizeof(uint32_t));
|
||||
memcpy(&(m_data.data()[n]), &ui, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
void CBuffer::Append(const char *sz)
|
||||
@@ -117,7 +117,7 @@ void CBuffer::ReplaceAt(int i, const uint8_t *ptr, int len)
|
||||
{
|
||||
m_data.resize(i+len);
|
||||
}
|
||||
::memcpy(&(m_data.data()[i]), ptr, len);
|
||||
memcpy(&(m_data.data()[i]), ptr, len);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -128,7 +128,7 @@ int CBuffer::Compare(uint8_t *buffer, int len) const
|
||||
int result = -1;
|
||||
if ( m_data.size() >= unsigned(len) )
|
||||
{
|
||||
result = ::memcmp(m_data.data(), buffer, len);
|
||||
result = memcmp(m_data.data(), buffer, len);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -138,7 +138,7 @@ int CBuffer::Compare(uint8_t *buffer, int off, int len) const
|
||||
int result = -1;
|
||||
if ( m_data.size() >= unsigned(off+len) )
|
||||
{
|
||||
result = ::memcmp(&(m_data.data()[off]), buffer, len);
|
||||
result = memcmp(&(m_data.data()[off]), buffer, len);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -151,7 +151,7 @@ bool CBuffer::operator ==(const CBuffer &Buffer) const
|
||||
{
|
||||
if ( m_data.size() == Buffer.m_data.size() )
|
||||
{
|
||||
return (::memcmp((const char *)m_data.data(), (const char *)Buffer.m_data.data(), m_data.size()) == 0);
|
||||
return (memcmp((const char *)m_data.data(), (const char *)Buffer.m_data.data(), m_data.size()) == 0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -160,7 +160,7 @@ bool CBuffer::operator ==(const char *sz) const
|
||||
{
|
||||
if ( m_data.size() == ::strlen(sz) )
|
||||
{
|
||||
return (::memcmp((const char *)m_data.data(), sz, m_data.size()) == 0);
|
||||
return (memcmp((const char *)m_data.data(), sz, m_data.size()) == 0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
+110
-38
@@ -23,34 +23,41 @@
|
||||
#include "DMRIdDirHttp.h"
|
||||
#include "Callsign.h"
|
||||
|
||||
// if a client is using special characters ',', '-' or '/', he's out of luck!
|
||||
//#define M17CHARACTERS " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-/."
|
||||
#define M17CHARACTERS " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructors
|
||||
|
||||
CCallsign::CCallsign()
|
||||
{
|
||||
// blank all
|
||||
::memset(m_Callsign, ' ', sizeof(m_Callsign));
|
||||
::memset(m_Suffix, ' ', sizeof(m_Suffix));
|
||||
memset(m_Callsign, ' ', CALLSIGN_LEN);
|
||||
memset(m_Suffix, ' ', CALLSUFFIX_LEN);
|
||||
m_Module = ' ';
|
||||
m_uiDmrid = 0;
|
||||
m_coded = 0;
|
||||
}
|
||||
|
||||
CCallsign::CCallsign(const char *sz, uint32_t dmrid)
|
||||
{
|
||||
// blank all
|
||||
::memset(m_Callsign, ' ', sizeof(m_Callsign));
|
||||
::memset(m_Suffix, ' ', sizeof(m_Suffix));
|
||||
memset(m_Callsign, ' ', CALLSIGN_LEN);
|
||||
memset(m_Suffix, ' ', CALLSUFFIX_LEN);
|
||||
m_Module = ' ';
|
||||
m_uiDmrid = dmrid;
|
||||
|
||||
// and populate
|
||||
if ( ::strlen(sz) > 0 )
|
||||
{
|
||||
// Calculate the M17 coded callsign
|
||||
CSIn();
|
||||
// callsign valid
|
||||
::memcpy(m_Callsign, sz, MIN(strlen(sz), sizeof(m_Callsign)-1));
|
||||
if ( strlen(sz) >= sizeof(m_Callsign) )
|
||||
memcpy(m_Callsign, sz, MIN(strlen(sz), CALLSIGN_LEN-1));
|
||||
if ( strlen(sz) >= CALLSIGN_LEN )
|
||||
{
|
||||
m_Module = sz[sizeof(m_Callsign)-1];
|
||||
m_Module = sz[CALLSIGN_LEN-1];
|
||||
}
|
||||
// dmrid ok ?
|
||||
if ( m_uiDmrid == 0 )
|
||||
@@ -69,7 +76,7 @@ CCallsign::CCallsign(const char *sz, uint32_t dmrid)
|
||||
const CCallsign *callsign = g_DmridDir.FindCallsign(m_uiDmrid);
|
||||
if ( callsign != nullptr )
|
||||
{
|
||||
::memcpy(m_Callsign, callsign->m_Callsign, sizeof(m_Callsign));
|
||||
memcpy(m_Callsign, callsign->m_Callsign, CALLSIGN_LEN);
|
||||
}
|
||||
}
|
||||
g_DmridDir.Unlock();
|
||||
@@ -136,13 +143,15 @@ bool CCallsign::HasSuffix(void) const
|
||||
void CCallsign::SetCallsign(const char *sz, bool UpdateDmrid)
|
||||
{
|
||||
// set callsign
|
||||
::memset(m_Callsign, ' ', sizeof(m_Callsign));
|
||||
memset(m_Callsign, ' ', CALLSIGN_LEN);
|
||||
m_Module = ' ';
|
||||
::memcpy(m_Callsign, sz, MIN(strlen(sz), sizeof(m_Callsign)-1));
|
||||
if ( strlen(sz) >= sizeof(m_Callsign) )
|
||||
memcpy(m_Callsign, sz, MIN(strlen(sz), CALLSIGN_LEN-1));
|
||||
if ( strlen(sz) >= CALLSIGN_LEN )
|
||||
{
|
||||
m_Module = sz[sizeof(m_Callsign)-1];
|
||||
m_Module = sz[CALLSIGN_LEN-1];
|
||||
}
|
||||
// update M17 coded callsign
|
||||
CSIn();
|
||||
// and update dmrid
|
||||
if ( UpdateDmrid )
|
||||
{
|
||||
@@ -157,20 +166,21 @@ void CCallsign::SetCallsign(const char *sz, bool UpdateDmrid)
|
||||
void CCallsign::SetCallsign(const uint8_t *buffer, int len, bool UpdateDmrid)
|
||||
{
|
||||
// set callsign
|
||||
::memset(m_Callsign, ' ', sizeof(m_Callsign));
|
||||
memset(m_Callsign, ' ', CALLSIGN_LEN);
|
||||
m_Module = ' ';
|
||||
::memcpy(m_Callsign, buffer, MIN(len, (int)sizeof(m_Callsign)-1));
|
||||
for ( unsigned i = 0; i < sizeof(m_Callsign); i++ )
|
||||
memcpy(m_Callsign, buffer, MIN(len, (int)CALLSIGN_LEN-1));
|
||||
for ( unsigned i = 0; i < CALLSIGN_LEN; i++ )
|
||||
{
|
||||
if ( m_Callsign[i] == 0 )
|
||||
{
|
||||
m_Callsign[i] = ' ';
|
||||
}
|
||||
}
|
||||
if ( (len >= (int)sizeof(m_Callsign)) && ((char)buffer[sizeof(m_Callsign)-1] != 0) )
|
||||
if ( (len >= (int)CALLSIGN_LEN) && ((char)buffer[CALLSIGN_LEN-1] != 0) )
|
||||
{
|
||||
m_Module = (char)buffer[sizeof(m_Callsign)-1];
|
||||
m_Module = (char)buffer[CALLSIGN_LEN-1];
|
||||
}
|
||||
CSIn();
|
||||
if ( UpdateDmrid )
|
||||
{
|
||||
g_DmridDir.Lock();
|
||||
@@ -191,7 +201,7 @@ void CCallsign::SetDmrid(uint32_t dmrid, bool UpdateCallsign)
|
||||
const CCallsign *callsign = g_DmridDir.FindCallsign(dmrid);
|
||||
if ( callsign != nullptr )
|
||||
{
|
||||
::memcpy(m_Callsign, callsign->m_Callsign, sizeof(m_Callsign));
|
||||
memcpy(m_Callsign, callsign->m_Callsign, CALLSIGN_LEN);
|
||||
}
|
||||
}
|
||||
g_DmridDir.Unlock();
|
||||
@@ -201,7 +211,7 @@ void CCallsign::SetDmrid(uint32_t dmrid, bool UpdateCallsign)
|
||||
void CCallsign::SetDmrid(const uint8_t *buffer, bool UpdateCallsign)
|
||||
{
|
||||
char sz[9];
|
||||
::memcpy(sz, buffer, 8);
|
||||
memcpy(sz, buffer, 8);
|
||||
sz[8] = 0;
|
||||
SetDmrid((uint32_t)::strtol(sz, nullptr, 16), UpdateCallsign);
|
||||
}
|
||||
@@ -209,20 +219,21 @@ void CCallsign::SetDmrid(const uint8_t *buffer, bool UpdateCallsign)
|
||||
void CCallsign::SetModule(char c)
|
||||
{
|
||||
m_Module = c;
|
||||
CSIn();
|
||||
}
|
||||
|
||||
|
||||
void CCallsign::SetSuffix(const char *sz)
|
||||
{
|
||||
::memset(m_Suffix, ' ', sizeof(m_Suffix));
|
||||
::memcpy(m_Suffix, sz, MIN(strlen(sz), sizeof(m_Suffix)));
|
||||
memset(m_Suffix, ' ', CALLSUFFIX_LEN);
|
||||
memcpy(m_Suffix, sz, MIN(strlen(sz), CALLSUFFIX_LEN));
|
||||
}
|
||||
|
||||
void CCallsign::SetSuffix(const uint8_t *buffer, int len)
|
||||
{
|
||||
len = MIN(len, (int)sizeof(m_Suffix));
|
||||
::memset(m_Suffix, ' ', sizeof(m_Suffix));
|
||||
::memcpy(m_Suffix, buffer, len);
|
||||
len = MIN(len, (int)CALLSUFFIX_LEN);
|
||||
memset(m_Suffix, ' ', CALLSUFFIX_LEN);
|
||||
memcpy(m_Suffix, buffer, len);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -232,8 +243,9 @@ void CCallsign::PatchCallsign(int off, const uint8_t *patch, int len)
|
||||
{
|
||||
if ( off < CALLSIGN_LEN )
|
||||
{
|
||||
::memcpy(m_Callsign, patch, MIN(len, (int)sizeof(m_Callsign) - off));
|
||||
memcpy(m_Callsign, patch, MIN(len, (int)CALLSIGN_LEN - off));
|
||||
}
|
||||
CSIn();
|
||||
}
|
||||
|
||||
|
||||
@@ -242,26 +254,36 @@ void CCallsign::PatchCallsign(int off, const uint8_t *patch, int len)
|
||||
|
||||
void CCallsign::GetCallsign(uint8_t *buffer) const
|
||||
{
|
||||
::memcpy(buffer, m_Callsign, sizeof(m_Callsign));
|
||||
memcpy(buffer, m_Callsign, CALLSIGN_LEN);
|
||||
if ( HasModule() )
|
||||
{
|
||||
buffer[sizeof(m_Callsign)-1] = m_Module;
|
||||
buffer[CALLSIGN_LEN-1] = m_Module;
|
||||
}
|
||||
}
|
||||
|
||||
void CCallsign::GetCallsignString(char *sz) const
|
||||
{
|
||||
unsigned i;
|
||||
for ( i = 0; (i < sizeof(m_Callsign)) && (m_Callsign[i] != ' '); i++ )
|
||||
for ( i = 0; (i < CALLSIGN_LEN) && (m_Callsign[i] != ' '); i++ )
|
||||
{
|
||||
sz[i] = m_Callsign[i];
|
||||
}
|
||||
sz[i] = 0;
|
||||
}
|
||||
|
||||
const std::string CCallsign::GetCS(unsigned len) const
|
||||
{
|
||||
if (len > 8)
|
||||
len = 8;
|
||||
std::string rval(m_Callsign);
|
||||
if (len)
|
||||
rval.resize(len, ' ');
|
||||
return rval;
|
||||
}
|
||||
|
||||
void CCallsign::GetSuffix(uint8_t *buffer) const
|
||||
{
|
||||
::memcpy(buffer, m_Suffix, sizeof(m_Suffix));
|
||||
memcpy(buffer, m_Suffix, CALLSUFFIX_LEN);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -269,7 +291,7 @@ void CCallsign::GetSuffix(uint8_t *buffer) const
|
||||
|
||||
bool CCallsign::HasSameCallsign(const CCallsign &Callsign) const
|
||||
{
|
||||
return (::memcmp(m_Callsign, Callsign.m_Callsign, sizeof(m_Callsign)) == 0);
|
||||
return (memcmp(m_Callsign, Callsign.m_Callsign, CALLSIGN_LEN) == 0);
|
||||
}
|
||||
|
||||
bool CCallsign::HasSameCallsignWithWildcard(const CCallsign &callsign) const
|
||||
@@ -277,7 +299,7 @@ bool CCallsign::HasSameCallsignWithWildcard(const CCallsign &callsign) const
|
||||
bool same = true;
|
||||
bool done = false;
|
||||
|
||||
for ( unsigned i = 0; (i < sizeof(m_Callsign)) && same && !done; i++ )
|
||||
for ( unsigned i = 0; (i < CALLSIGN_LEN) && same && !done; i++ )
|
||||
{
|
||||
if ( !(done = ((m_Callsign[i] == '*') || (callsign[i] == '*'))) )
|
||||
{
|
||||
@@ -289,7 +311,7 @@ bool CCallsign::HasSameCallsignWithWildcard(const CCallsign &callsign) const
|
||||
|
||||
bool CCallsign::HasLowerCallsign(const CCallsign &Callsign) const
|
||||
{
|
||||
return (::memcmp(m_Callsign, Callsign.m_Callsign, sizeof(m_Callsign)) < 0);
|
||||
return (memcmp(m_Callsign, Callsign.m_Callsign, CALLSIGN_LEN) < 0);
|
||||
}
|
||||
|
||||
bool CCallsign::HasSameModule(const CCallsign &Callsign) const
|
||||
@@ -303,8 +325,8 @@ bool CCallsign::HasSameModule(const CCallsign &Callsign) const
|
||||
|
||||
bool CCallsign::operator ==(const CCallsign &callsign) const
|
||||
{
|
||||
return ((::memcmp(callsign.m_Callsign, m_Callsign, sizeof(m_Callsign)) == 0) && (m_Module == callsign.m_Module)
|
||||
&& (::memcmp(callsign.m_Suffix, m_Suffix, sizeof(m_Suffix)) == 0)
|
||||
return ((memcmp(callsign.m_Callsign, m_Callsign, CALLSIGN_LEN) == 0) && (m_Module == callsign.m_Module)
|
||||
&& (memcmp(callsign.m_Suffix, m_Suffix, CALLSUFFIX_LEN) == 0)
|
||||
&& (m_uiDmrid == callsign.m_uiDmrid)
|
||||
);
|
||||
}
|
||||
@@ -312,19 +334,19 @@ bool CCallsign::operator ==(const CCallsign &callsign) const
|
||||
CCallsign::operator const char *() const
|
||||
{
|
||||
// empty
|
||||
::memset(m_sz, 0, sizeof(m_sz));
|
||||
memset(m_sz, 0, sizeof(m_sz));
|
||||
// callsign
|
||||
::memcpy(m_sz, m_Callsign, sizeof(m_Callsign));
|
||||
memcpy(m_sz, m_Callsign, CALLSIGN_LEN);
|
||||
// module
|
||||
if ( HasModule() )
|
||||
{
|
||||
m_sz[sizeof(m_Callsign)] = m_Module;
|
||||
m_sz[CALLSIGN_LEN] = m_Module;
|
||||
}
|
||||
// suffix
|
||||
if ( HasSuffix() )
|
||||
{
|
||||
::strcat(m_sz, " / ");
|
||||
::strncat(m_sz, m_Suffix, sizeof(m_Suffix));
|
||||
::strncat(m_sz, m_Suffix, CALLSUFFIX_LEN);
|
||||
}
|
||||
|
||||
// done
|
||||
@@ -348,3 +370,53 @@ bool CCallsign::IsSpace(char c) const
|
||||
{
|
||||
return (c == ' ');
|
||||
}
|
||||
|
||||
void CCallsign::CodeIn(const uint8_t *in)
|
||||
{
|
||||
char cs[10];
|
||||
const std::string m17_alphabet(M17CHARACTERS);
|
||||
memset(cs, 0, 10);
|
||||
m_coded = in[0];
|
||||
for (int i=1; i<6; i++)
|
||||
m_coded = (m_coded << 8) | in[i];
|
||||
if (m_coded > 0xee6b27ffffffu) {
|
||||
std::cerr << "Callsign code is too large, 0x" << std::hex << m_coded << std::dec << std::endl;
|
||||
return;
|
||||
}
|
||||
auto c = m_coded;
|
||||
int i = 0;
|
||||
while (c) {
|
||||
cs[i++] = m17_alphabet[c % 40];
|
||||
c /= 40;
|
||||
}
|
||||
SetCallsign(cs);
|
||||
}
|
||||
|
||||
void CCallsign::CodeOut(uint8_t *out) const
|
||||
{
|
||||
memset(out, 0, 6);
|
||||
auto c = m_coded;
|
||||
auto pout = out+5;
|
||||
while (c)
|
||||
{
|
||||
*pout-- = c % 0x100u;
|
||||
c /= 0x100u;
|
||||
}
|
||||
}
|
||||
|
||||
// called to calculate the m17 encoded cs
|
||||
void CCallsign::CSIn()
|
||||
{
|
||||
const std::string m17_alphabet(M17CHARACTERS);
|
||||
auto pos = m17_alphabet.find(m_Module);
|
||||
m_coded = pos;
|
||||
m_coded *= 40;
|
||||
for( int i=CALLSIGN_LEN-2; i>=0; i-- ) {
|
||||
pos = m17_alphabet.find(m_Callsign[i]);
|
||||
if (pos == std::string::npos) {
|
||||
pos = 0;
|
||||
}
|
||||
m_coded *= 40;
|
||||
m_coded += pos;
|
||||
}
|
||||
}
|
||||
+13
-5
@@ -55,6 +55,7 @@ public:
|
||||
// get
|
||||
void GetCallsign(uint8_t *) const;
|
||||
void GetCallsignString(char *) const;
|
||||
const std::string GetCS(unsigned len = 9) const;
|
||||
uint32_t GetDmrid(void) const { return m_uiDmrid; }
|
||||
void GetSuffix(uint8_t *) const;
|
||||
char GetModule(void) const { return m_Module; }
|
||||
@@ -69,7 +70,13 @@ public:
|
||||
bool operator ==(const CCallsign &) const;
|
||||
operator const char *() const;
|
||||
|
||||
// M17
|
||||
void CodeIn(const uint8_t *code);
|
||||
void CodeOut(uint8_t *out) const;
|
||||
|
||||
protected:
|
||||
// M17
|
||||
void CSIn();
|
||||
// helper
|
||||
bool IsNumber(char) const;
|
||||
bool IsLetter(char) const;
|
||||
@@ -77,9 +84,10 @@ protected:
|
||||
|
||||
protected:
|
||||
// data
|
||||
char m_Callsign[CALLSIGN_LEN];
|
||||
char m_Suffix[CALLSUFFIX_LEN];
|
||||
char m_Module;
|
||||
mutable char m_sz[CALLSIGN_LEN+CALLSUFFIX_LEN+5];
|
||||
uint32_t m_uiDmrid;
|
||||
char m_Callsign[CALLSIGN_LEN];
|
||||
char m_Suffix[CALLSUFFIX_LEN];
|
||||
char m_Module;
|
||||
mutable char m_sz[CALLSIGN_LEN+CALLSUFFIX_LEN+5];
|
||||
uint32_t m_uiDmrid;
|
||||
uint64_t m_coded; // M17 encoded callsign
|
||||
};
|
||||
@@ -28,7 +28,7 @@
|
||||
CCallsignList::CCallsignList()
|
||||
{
|
||||
m_Filename = nullptr;
|
||||
::memset(&m_LastModTime, 0, sizeof(time_t));
|
||||
memset(&m_LastModTime, 0, sizeof(time_t));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -25,21 +25,21 @@
|
||||
|
||||
CCallsignListItem::CCallsignListItem()
|
||||
{
|
||||
::memset(m_Modules, 0, sizeof(m_Modules));
|
||||
::memset(m_szUrl, 0, sizeof(m_szUrl));
|
||||
memset(m_Modules, 0, sizeof(m_Modules));
|
||||
memset(m_szUrl, 0, sizeof(m_szUrl));
|
||||
}
|
||||
|
||||
CCallsignListItem::CCallsignListItem(const CCallsign &callsign, const CIp &ip, const char *modules)
|
||||
{
|
||||
m_Callsign = callsign;
|
||||
::memset(m_szUrl, 0, sizeof(m_szUrl));
|
||||
memset(m_szUrl, 0, sizeof(m_szUrl));
|
||||
m_Ip = ip;
|
||||
if ( modules != nullptr )
|
||||
{
|
||||
::memset(m_Modules, 0, sizeof(m_Modules));
|
||||
memset(m_Modules, 0, sizeof(m_Modules));
|
||||
if ( modules[0] == '*' )
|
||||
{
|
||||
::memcpy(m_Modules, ACTIVE_MODULES, sizeof(ACTIVE_MODULES));
|
||||
memcpy(m_Modules, ACTIVE_MODULES, sizeof(ACTIVE_MODULES));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -62,10 +62,10 @@ CCallsignListItem::CCallsignListItem(const CCallsign &callsign, const char *url,
|
||||
m_Ip = CIp(m_szUrl);
|
||||
if ( modules != nullptr )
|
||||
{
|
||||
::memset(m_Modules, 0, sizeof(m_Modules));
|
||||
memset(m_Modules, 0, sizeof(m_Modules));
|
||||
if ( modules[0] == '*' )
|
||||
{
|
||||
::memcpy(m_Modules, ACTIVE_MODULES, sizeof(ACTIVE_MODULES));
|
||||
memcpy(m_Modules, ACTIVE_MODULES, sizeof(ACTIVE_MODULES));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -84,9 +84,9 @@ CCallsignListItem::CCallsignListItem(const CCallsign &callsign, const char *url,
|
||||
CCallsignListItem::CCallsignListItem(const CCallsignListItem &item)
|
||||
{
|
||||
m_Callsign = item.m_Callsign;
|
||||
::memcpy(m_szUrl, item.m_szUrl, sizeof(m_szUrl));
|
||||
memcpy(m_szUrl, item.m_szUrl, sizeof(m_szUrl));
|
||||
m_Ip = item.m_Ip;
|
||||
::memcpy(m_Modules, item.m_Modules, sizeof(m_Modules));
|
||||
memcpy(m_Modules, item.m_Modules, sizeof(m_Modules));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ void CCodecStream::Task(void)
|
||||
{
|
||||
CBuffer Buffer;
|
||||
CIp Ip;
|
||||
uint8_t Ambe[AMBE_SIZE];
|
||||
uint8_t Ambe[9];
|
||||
uint8_t DStarSync[] = { 0x55,0x2D,0x16 };
|
||||
|
||||
// any packet from transcoder
|
||||
@@ -235,7 +235,7 @@ bool CCodecStream::IsValidAmbePacket(const CBuffer &Buffer, uint8_t *Ambe)
|
||||
|
||||
if ( (Buffer.size() == 11) && (Buffer.data()[0] == m_uiCodecOut) )
|
||||
{
|
||||
::memcpy(Ambe, &(Buffer.data()[2]), 9);
|
||||
memcpy(Ambe, &(Buffer.data()[2]), 9);
|
||||
valid = true;
|
||||
}
|
||||
return valid;
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
// define
|
||||
|
||||
// frame sizes
|
||||
#define AMBE_SIZE 9
|
||||
#define AMBEPLUS_SIZE 9
|
||||
#define 9 9
|
||||
#define 9 9
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -490,8 +490,8 @@ void CDcsProtocol::EncodeDvPacket(const CDvHeaderPacket &Header, const CDvFrameP
|
||||
Buffer->Append((uint8_t *)&DstarHeader, sizeof(struct dstar_header) - sizeof(uint16_t));
|
||||
Buffer->Append(DvFrame.GetStreamId());
|
||||
Buffer->Append((uint8_t)(DvFrame.GetPacketId() % 21));
|
||||
Buffer->Append((uint8_t *)DvFrame.GetAmbe(), AMBE_SIZE);
|
||||
Buffer->Append((uint8_t *)DvFrame.GetDvData(), DVDATA_SIZE);
|
||||
Buffer->Append((uint8_t *)DvFrame.GetCodecData(ECodecType::dstar), 9);
|
||||
Buffer->Append((uint8_t *)DvFrame.GetDvData(), 3);
|
||||
Buffer->Append((uint8_t)((iSeq >> 0) & 0xFF));
|
||||
Buffer->Append((uint8_t)((iSeq >> 8) & 0xFF));
|
||||
Buffer->Append((uint8_t)((iSeq >> 16) & 0xFF));
|
||||
|
||||
@@ -612,8 +612,8 @@ bool CDextraProtocol::EncodeDvFramePacket(const CDvFramePacket &Packet, CBuffer
|
||||
Buffer->Set(tag, sizeof(tag));
|
||||
Buffer->Append(Packet.GetStreamId());
|
||||
Buffer->Append((uint8_t)(Packet.GetPacketId() % 21));
|
||||
Buffer->Append((uint8_t *)Packet.GetAmbe(), AMBE_SIZE);
|
||||
Buffer->Append((uint8_t *)Packet.GetDvData(), DVDATA_SIZE);
|
||||
Buffer->Append((uint8_t *)Packet.GetCodecData(ECodecType::dstar), 9);
|
||||
Buffer->Append((uint8_t *)Packet.GetDvData(), 3);
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ CDmridDirFile g_DmridDir;
|
||||
|
||||
CDmridDirFile::CDmridDirFile()
|
||||
{
|
||||
::memset(&m_LastModTime, 0, sizeof(time_t));
|
||||
memset(&m_LastModTime, 0, sizeof(time_t));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -102,11 +102,11 @@ bool CDmridDirHttp::HttpGet(const char *hostname, const char *filename, int port
|
||||
// get hostname address
|
||||
struct sockaddr_in servaddr;
|
||||
struct hostent *hp;
|
||||
::memset(&servaddr,0,sizeof(servaddr));
|
||||
memset(&servaddr,0,sizeof(servaddr));
|
||||
if( (hp = gethostbyname(hostname)) != nullptr )
|
||||
{
|
||||
// dns resolved
|
||||
::memcpy((char *)&servaddr.sin_addr.s_addr, (char *)hp->h_addr, hp->h_length);
|
||||
memcpy((char *)&servaddr.sin_addr.s_addr, (char *)hp->h_addr, hp->h_length);
|
||||
servaddr.sin_port = htons(port);
|
||||
servaddr.sin_family = AF_INET;
|
||||
|
||||
|
||||
@@ -608,11 +608,11 @@ bool CDmrmmdvmProtocol::IsValidDvHeaderPacket(const CBuffer &Buffer, std::unique
|
||||
// extract sync
|
||||
uint8_t dmrsync[7];
|
||||
dmrsync[0] = Buffer.data()[33] & 0x0F;
|
||||
::memcpy(&dmrsync[1], &Buffer.data()[34], 5);
|
||||
memcpy(&dmrsync[1], &Buffer.data()[34], 5);
|
||||
dmrsync[6] = Buffer.data()[39] & 0xF0;
|
||||
// and check
|
||||
if ( (::memcmp(dmrsync, g_DmrSyncMSData, sizeof(dmrsync)) == 0) ||
|
||||
(::memcmp(dmrsync, g_DmrSyncBSData, sizeof(dmrsync)) == 0))
|
||||
if ( (memcmp(dmrsync, g_DmrSyncMSData, sizeof(dmrsync)) == 0) ||
|
||||
(memcmp(dmrsync, g_DmrSyncBSData, sizeof(dmrsync)) == 0))
|
||||
{
|
||||
// get payload
|
||||
//CBPTC19696 bptc;
|
||||
@@ -696,7 +696,7 @@ bool CDmrmmdvmProtocol::IsValidDvFramePacket(const CBuffer &Buffer, std::array<s
|
||||
memcpy(&dmr3ambe[14], &dmrframe[20], 13);
|
||||
// extract sync
|
||||
dmrsync[0] = dmrframe[13] & 0x0F;
|
||||
::memcpy(&dmrsync[1], &dmrframe[14], 5);
|
||||
memcpy(&dmrsync[1], &dmrframe[14], 5);
|
||||
dmrsync[6] = dmrframe[19] & 0xF0;
|
||||
|
||||
// debug
|
||||
@@ -744,11 +744,11 @@ bool CDmrmmdvmProtocol::IsValidDvLastFramePacket(const CBuffer &Buffer, std::uni
|
||||
// extract sync
|
||||
uint8_t dmrsync[7];
|
||||
dmrsync[0] = Buffer.data()[33] & 0x0F;
|
||||
::memcpy(&dmrsync[1], &Buffer.data()[34], 5);
|
||||
memcpy(&dmrsync[1], &Buffer.data()[34], 5);
|
||||
dmrsync[6] = Buffer.data()[39] & 0xF0;
|
||||
// and check
|
||||
if ( (::memcmp(dmrsync, g_DmrSyncMSData, sizeof(dmrsync)) == 0) ||
|
||||
(::memcmp(dmrsync, g_DmrSyncBSData, sizeof(dmrsync)) == 0))
|
||||
if ( (memcmp(dmrsync, g_DmrSyncMSData, sizeof(dmrsync)) == 0) ||
|
||||
(memcmp(dmrsync, g_DmrSyncBSData, sizeof(dmrsync)) == 0))
|
||||
{
|
||||
// get payload
|
||||
//CBPTC19696 bptc;
|
||||
@@ -765,7 +765,7 @@ bool CDmrmmdvmProtocol::IsValidDvLastFramePacket(const CBuffer &Buffer, std::uni
|
||||
|
||||
// dummy ambe
|
||||
uint8_t ambe[9];
|
||||
::memset(ambe, 0, sizeof(ambe));
|
||||
memset(ambe, 0, sizeof(ambe));
|
||||
|
||||
|
||||
// and packet
|
||||
@@ -901,15 +901,15 @@ void CDmrmmdvmProtocol::EncodeDvPacket(
|
||||
|
||||
// Payload
|
||||
// frame0
|
||||
Buffer->ReplaceAt(20, DvFrame0.GetAmbePlus(), 9);
|
||||
Buffer->ReplaceAt(20, DvFrame0.GetCodecData(ECodecType::dmr), 9);
|
||||
// 1/2 frame1
|
||||
Buffer->ReplaceAt(29, DvFrame1.GetAmbePlus(), 5);
|
||||
Buffer->ReplaceAt(29, DvFrame1.GetCodecData(ECodecType::dmr), 5);
|
||||
Buffer->ReplaceAt(33, (uint8_t)(Buffer->at(33) & 0xF0));
|
||||
// 1/2 frame1
|
||||
Buffer->ReplaceAt(39, DvFrame1.GetAmbePlus()+4, 5);
|
||||
Buffer->ReplaceAt(39, DvFrame1.GetCodecData(ECodecType::dmr)+4, 5);
|
||||
Buffer->ReplaceAt(39, (uint8_t)(Buffer->at(39) & 0x0F));
|
||||
// frame2
|
||||
Buffer->ReplaceAt(44, DvFrame2.GetAmbePlus(), 9);
|
||||
Buffer->ReplaceAt(44, DvFrame2.GetCodecData(ECodecType::dmr), 9);
|
||||
|
||||
// sync or embedded signaling
|
||||
ReplaceEMBInBuffer(Buffer, DvFrame0.GetDmrPacketId());
|
||||
@@ -997,11 +997,11 @@ void CDmrmmdvmProtocol::AppendVoiceLCToBuffer(CBuffer *buffer, uint32_t uiSrcId)
|
||||
|
||||
// fill payload
|
||||
CBPTC19696 bptc;
|
||||
::memset(payload, 0, sizeof(payload));
|
||||
memset(payload, 0, sizeof(payload));
|
||||
// LC data
|
||||
uint8_t lc[12];
|
||||
{
|
||||
::memset(lc, 0, sizeof(lc));
|
||||
memset(lc, 0, sizeof(lc));
|
||||
// uiDstId = TG9
|
||||
lc[5] = 9;
|
||||
// uiSrcId
|
||||
@@ -1016,12 +1016,12 @@ void CDmrmmdvmProtocol::AppendVoiceLCToBuffer(CBuffer *buffer, uint32_t uiSrcId)
|
||||
lc[11] = parity[0] ^ DMR_VOICE_LC_HEADER_CRC_MASK;
|
||||
}
|
||||
// sync
|
||||
::memcpy(payload+13, g_DmrSyncBSData, sizeof(g_DmrSyncBSData));
|
||||
memcpy(payload+13, g_DmrSyncBSData, sizeof(g_DmrSyncBSData));
|
||||
// slot type
|
||||
{
|
||||
// slot type
|
||||
uint8_t slottype[3];
|
||||
::memset(slottype, 0, sizeof(slottype));
|
||||
memset(slottype, 0, sizeof(slottype));
|
||||
slottype[0] = (DMRMMDVM_REFLECTOR_COLOUR << 4) & 0xF0;
|
||||
slottype[0] |= (DMR_DT_VOICE_LC_HEADER << 0) & 0x0FU;
|
||||
CGolay2087::encode(slottype);
|
||||
@@ -1044,11 +1044,11 @@ void CDmrmmdvmProtocol::AppendTerminatorLCToBuffer(CBuffer *buffer, uint32_t uiS
|
||||
|
||||
// fill payload
|
||||
CBPTC19696 bptc;
|
||||
::memset(payload, 0, sizeof(payload));
|
||||
memset(payload, 0, sizeof(payload));
|
||||
// LC data
|
||||
uint8_t lc[12];
|
||||
{
|
||||
::memset(lc, 0, sizeof(lc));
|
||||
memset(lc, 0, sizeof(lc));
|
||||
// uiDstId = TG9
|
||||
lc[5] = 9;
|
||||
// uiSrcId
|
||||
@@ -1063,12 +1063,12 @@ void CDmrmmdvmProtocol::AppendTerminatorLCToBuffer(CBuffer *buffer, uint32_t uiS
|
||||
lc[11] = parity[0] ^ DMR_TERMINATOR_WITH_LC_CRC_MASK;
|
||||
}
|
||||
// sync
|
||||
::memcpy(payload+13, g_DmrSyncBSData, sizeof(g_DmrSyncBSData));
|
||||
memcpy(payload+13, g_DmrSyncBSData, sizeof(g_DmrSyncBSData));
|
||||
// slot type
|
||||
{
|
||||
// slot type
|
||||
uint8_t slottype[3];
|
||||
::memset(slottype, 0, sizeof(slottype));
|
||||
memset(slottype, 0, sizeof(slottype));
|
||||
slottype[0] = (DMRMMDVM_REFLECTOR_COLOUR << 4) & 0xF0;
|
||||
slottype[0] |= (DMR_DT_TERMINATOR_WITH_LC << 0) & 0x0FU;
|
||||
CGolay2087::encode(slottype);
|
||||
|
||||
@@ -367,12 +367,12 @@ bool CDmrplusProtocol::IsValidConnectPacket(const CBuffer &Buffer, CCallsign *ca
|
||||
if ( Buffer.size() == 31 )
|
||||
{
|
||||
char sz[9];
|
||||
::memcpy(sz, Buffer.data(), 8);
|
||||
memcpy(sz, Buffer.data(), 8);
|
||||
sz[8] = 0;
|
||||
uint32_t dmrid = atoi(sz);
|
||||
callsign->SetDmrid(dmrid, true);
|
||||
callsign->SetModule(DMRPLUS_MODULE_ID);
|
||||
::memcpy(sz, &Buffer.data()[8], 4);
|
||||
memcpy(sz, &Buffer.data()[8], 4);
|
||||
sz[4] = 0;
|
||||
*reflectormodule = DmrDstIdToModule(atoi(sz));
|
||||
valid = (callsign->IsValid() && (std::isupper(*reflectormodule) || (*reflectormodule == ' ')) );
|
||||
@@ -390,7 +390,7 @@ bool CDmrplusProtocol::IsValidDisconnectPacket(const CBuffer &Buffer, CCallsign
|
||||
if ( Buffer.size() == 32 )
|
||||
{
|
||||
char sz[9];
|
||||
::memcpy(sz, Buffer.data(), 8);
|
||||
memcpy(sz, Buffer.data(), 8);
|
||||
sz[8] = 0;
|
||||
uint32_t dmrid = atoi(sz);
|
||||
callsign->SetDmrid(dmrid, true);
|
||||
@@ -468,7 +468,7 @@ bool CDmrplusProtocol::IsValidDvFramePacket(const CIp &Ip, const CBuffer &Buffer
|
||||
memcpy(&dmr3ambe[14], &dmrframe[20], 13);
|
||||
// extract sync
|
||||
dmrsync[0] = dmrframe[13] & 0x0F;
|
||||
::memcpy(&dmrsync[1], &dmrframe[14], 5);
|
||||
memcpy(&dmrsync[1], &dmrframe[14], 5);
|
||||
dmrsync[6] = dmrframe[19] & 0xF0;
|
||||
|
||||
// and create 3 dv frames
|
||||
@@ -597,15 +597,15 @@ void CDmrplusProtocol::EncodeDvPacket
|
||||
uint32_t uiSrcId = Header.GetMyCallsign().GetDmrid() & 0x00FFFFFF;
|
||||
uint32_t uiDstId = ModuleToDmrDestId(Header.GetRpt2Module()) & 0x00FFFFFF;
|
||||
// frame0
|
||||
Buffer->ReplaceAt(26, DvFrame0.GetAmbePlus(), 9);
|
||||
Buffer->ReplaceAt(26, DvFrame0.GetCodecData(ECodecType::dmr), 9);
|
||||
// 1/2 frame1
|
||||
Buffer->ReplaceAt(35, DvFrame1.GetAmbePlus(), 5);
|
||||
Buffer->ReplaceAt(35, DvFrame1.GetCodecData(ECodecType::dmr), 5);
|
||||
Buffer->ReplaceAt(39, (uint8_t)(Buffer->at(39) & 0xF0));
|
||||
// 1/2 frame1
|
||||
Buffer->ReplaceAt(45, DvFrame1.GetAmbePlus()+4, 5);
|
||||
Buffer->ReplaceAt(45, DvFrame1.GetCodecData(ECodecType::dmr)+4, 5);
|
||||
Buffer->ReplaceAt(45, (uint8_t)(Buffer->at(45) & 0x0F));
|
||||
// frame2
|
||||
Buffer->ReplaceAt(50, DvFrame2.GetAmbePlus(), 9);
|
||||
Buffer->ReplaceAt(50, DvFrame2.GetCodecData(ECodecType::dmr), 9);
|
||||
|
||||
// sync or embedded signaling
|
||||
ReplaceEMBInBuffer(Buffer, DvFrame0.GetDmrPacketId());
|
||||
@@ -675,11 +675,11 @@ void CDmrplusProtocol::AppendVoiceLCToBuffer(CBuffer *buffer, uint32_t uiSrcId)
|
||||
|
||||
// fill payload
|
||||
CBPTC19696 bptc;
|
||||
::memset(payload, 0, sizeof(payload));
|
||||
memset(payload, 0, sizeof(payload));
|
||||
// LC data
|
||||
uint8_t lc[12];
|
||||
{
|
||||
::memset(lc, 0, sizeof(lc));
|
||||
memset(lc, 0, sizeof(lc));
|
||||
// uiDstId = TG9
|
||||
lc[5] = 9;
|
||||
// uiSrcId
|
||||
@@ -694,12 +694,12 @@ void CDmrplusProtocol::AppendVoiceLCToBuffer(CBuffer *buffer, uint32_t uiSrcId)
|
||||
lc[11] = parity[0] ^ DMR_VOICE_LC_HEADER_CRC_MASK;
|
||||
}
|
||||
// sync
|
||||
::memcpy(payload+13, g_DmrSyncBSData, sizeof(g_DmrSyncBSData));
|
||||
memcpy(payload+13, g_DmrSyncBSData, sizeof(g_DmrSyncBSData));
|
||||
// slot type
|
||||
{
|
||||
// slot type
|
||||
uint8_t slottype[3];
|
||||
::memset(slottype, 0, sizeof(slottype));
|
||||
memset(slottype, 0, sizeof(slottype));
|
||||
slottype[0] = (DMRPLUS_REFLECTOR_COLOUR << 4) & 0xF0;
|
||||
slottype[0] |= (DMR_DT_VOICE_LC_HEADER << 0) & 0x0FU;
|
||||
CGolay2087::encode(slottype);
|
||||
|
||||
@@ -393,7 +393,7 @@ bool CDplusProtocol::IsValidLoginPacket(const CBuffer &Buffer, CCallsign *Callsi
|
||||
uint8_t Tag[] = { 0x1C,0xC0,0x04,0x00 };
|
||||
bool valid = false;
|
||||
|
||||
if ( (Buffer.size() == 28) &&(::memcmp(Buffer.data(), Tag, sizeof(Tag)) == 0) )
|
||||
if ( (Buffer.size() == 28) &&(memcmp(Buffer.data(), Tag, sizeof(Tag)) == 0) )
|
||||
{
|
||||
Callsign->SetCallsign(&(Buffer.data()[4]), 8);
|
||||
valid = Callsign->IsValid();
|
||||
@@ -503,8 +503,8 @@ bool CDplusProtocol::EncodeDvFramePacket(const CDvFramePacket &Packet, CBuffer *
|
||||
Buffer->Set(tag, sizeof(tag));
|
||||
Buffer->Append(Packet.GetStreamId());
|
||||
Buffer->Append((uint8_t)(Packet.GetPacketId() % 21));
|
||||
Buffer->Append((uint8_t *)Packet.GetAmbe(), AMBE_SIZE);
|
||||
Buffer->Append((uint8_t *)Packet.GetDvData(), DVDATA_SIZE);
|
||||
Buffer->Append((uint8_t *)Packet.GetCodecData(ECodecType::dstar), 9);
|
||||
Buffer->Append((uint8_t *)Packet.GetDvData(), 3);
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
+70
-40
@@ -1,5 +1,5 @@
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
|
||||
//
|
||||
// ulxd -- The universal reflector
|
||||
// Copyright © 2021 Thomas A. Early N7TAE
|
||||
//
|
||||
@@ -16,20 +16,21 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include <string.h>
|
||||
#include "Main.h"
|
||||
#include <string.h>
|
||||
#include "DVFramePacket.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructor
|
||||
|
||||
CDvFramePacket::CDvFramePacket()
|
||||
{
|
||||
::memset(m_uiAmbe, 0, sizeof(m_uiAmbe));
|
||||
::memset(m_uiDvData, 0, sizeof(m_uiDvData));
|
||||
::memset(m_uiAmbePlus, 0, sizeof(m_uiAmbePlus));
|
||||
::memset(m_uiDvSync, 0, sizeof(m_uiDvSync));
|
||||
memset(m_uiAmbe, 0, AMBE_SIZE);
|
||||
memset(m_uiDvData, 0, DVDATA_SIZE);
|
||||
memset(m_uiAmbePlus, 0, AMBEPLUS_SIZE);
|
||||
memset(m_uiDvSync, 0, DVSYNC_SIZE);
|
||||
memset(m_uiCodec2, 0, 16);
|
||||
memset(m_Nonce, 0, 14);
|
||||
};
|
||||
|
||||
// dstar constructor
|
||||
@@ -37,10 +38,12 @@ CDvFramePacket::CDvFramePacket()
|
||||
CDvFramePacket::CDvFramePacket(const struct dstar_dvframe *dvframe, uint16_t sid, uint8_t pid)
|
||||
: CPacket(sid, pid)
|
||||
{
|
||||
::memcpy(m_uiAmbe, dvframe->AMBE, sizeof(m_uiAmbe));
|
||||
::memcpy(m_uiDvData, dvframe->DVDATA, sizeof(m_uiDvData));
|
||||
::memset(m_uiAmbePlus, 0, sizeof(m_uiAmbePlus));
|
||||
::memset(m_uiDvSync, 0, sizeof(m_uiDvSync));
|
||||
memcpy(m_uiAmbe, dvframe->AMBE, AMBE_SIZE);
|
||||
memcpy(m_uiDvData, dvframe->DVDATA, DVDATA_SIZE);
|
||||
memset(m_uiAmbePlus, 0, AMBEPLUS_SIZE);
|
||||
memset(m_uiDvSync, 0, DVSYNC_SIZE);
|
||||
memset(m_uiCodec2, 0, 16);
|
||||
memset(m_Nonce, 0, 14);
|
||||
}
|
||||
|
||||
// dmr constructor
|
||||
@@ -48,10 +51,12 @@ CDvFramePacket::CDvFramePacket(const struct dstar_dvframe *dvframe, uint16_t sid
|
||||
CDvFramePacket::CDvFramePacket(const uint8_t *ambe, const uint8_t *sync, uint16_t sid, uint8_t pid, uint8_t spid)
|
||||
: CPacket(sid, pid, spid)
|
||||
{
|
||||
::memcpy(m_uiAmbePlus, ambe, sizeof(m_uiAmbePlus));
|
||||
::memcpy(m_uiDvSync, sync, sizeof(m_uiDvSync));
|
||||
::memset(m_uiAmbe, 0, sizeof(m_uiAmbe));
|
||||
::memset(m_uiDvData, 0, sizeof(m_uiDvData));
|
||||
memcpy(m_uiAmbePlus, ambe, AMBEPLUS_SIZE);
|
||||
memcpy(m_uiDvSync, sync, DVSYNC_SIZE);
|
||||
memset(m_uiAmbe, 0, AMBE_SIZE);
|
||||
memset(m_uiDvData, 0, DVDATA_SIZE);
|
||||
memset(m_uiCodec2, 0, 16);
|
||||
memset(m_Nonce, 0, 14);
|
||||
}
|
||||
|
||||
// ysf constructor
|
||||
@@ -59,10 +64,12 @@ CDvFramePacket::CDvFramePacket(const uint8_t *ambe, const uint8_t *sync, uint16_
|
||||
CDvFramePacket::CDvFramePacket(const uint8_t *ambe, uint16_t sid, uint8_t pid, uint8_t spid, uint8_t 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));
|
||||
memcpy(m_uiAmbePlus, ambe, AMBEPLUS_SIZE);
|
||||
memset(m_uiDvSync, 0, DVSYNC_SIZE);
|
||||
memset(m_uiAmbe, 0, AMBE_SIZE);
|
||||
memset(m_uiDvData, 0, DVDATA_SIZE);
|
||||
memset(m_uiCodec2, 0, 16);
|
||||
memset(m_Nonce, 0, 14);
|
||||
}
|
||||
|
||||
// xlx constructor
|
||||
@@ -70,13 +77,25 @@ CDvFramePacket::CDvFramePacket(const uint8_t *ambe, uint16_t sid, uint8_t pid, u
|
||||
CDvFramePacket::CDvFramePacket
|
||||
(uint16_t sid,
|
||||
uint8_t dstarpid, const uint8_t *dstarambe, const uint8_t *dstardvdata,
|
||||
uint8_t dmrpid, uint8_t dprspid, const uint8_t *dmrambe, const uint8_t *dmrsync)
|
||||
: CPacket(sid, dstarpid, dmrpid, dprspid, 0xFF, 0xFF, 0xFF)
|
||||
uint8_t dmrpid, uint8_t dprspid, const uint8_t *dmrambe, const uint8_t *dmrsync, ECodecType codecInType, const uint8_t *codec2, const uint8_t * nonce)
|
||||
: CPacket(sid, dstarpid, dmrpid, dprspid, 0xFF, 0xFF, 0xFF, codecInType)
|
||||
{
|
||||
::memcpy(m_uiAmbe, dstarambe, sizeof(m_uiAmbe));
|
||||
::memcpy(m_uiDvData, dstardvdata, sizeof(m_uiDvData));
|
||||
::memcpy(m_uiAmbePlus, dmrambe, sizeof(m_uiAmbePlus));
|
||||
::memcpy(m_uiDvSync, dmrsync, sizeof(m_uiDvSync));
|
||||
memcpy(m_uiAmbe, dstarambe, AMBE_SIZE);
|
||||
memcpy(m_uiDvData, dstardvdata, DVDATA_SIZE);
|
||||
memcpy(m_uiAmbePlus, dmrambe, AMBEPLUS_SIZE);
|
||||
memcpy(m_uiDvSync, dmrsync, DVSYNC_SIZE);
|
||||
memcpy(m_uiCodec2, codec2, 16);
|
||||
memcpy(m_Nonce, nonce, 14);
|
||||
}
|
||||
|
||||
CDvFramePacket::CDvFramePacket(const CM17Packet &m17) : CPacket(m17)
|
||||
{
|
||||
memset(m_uiAmbe, 0, AMBE_SIZE);
|
||||
memset(m_uiDvData, 0, DVDATA_SIZE);
|
||||
memset(m_uiAmbePlus, 0, AMBEPLUS_SIZE);
|
||||
memset(m_uiDvSync, 0, DVSYNC_SIZE);
|
||||
memcpy(m_uiCodec2, m17.GetPayload(), 16);
|
||||
memcpy(m_Nonce, m17.GetNonce(), 14);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -90,14 +109,17 @@ std::unique_ptr<CPacket> CDvFramePacket::Duplicate(void) const
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// get
|
||||
|
||||
const uint8_t *CDvFramePacket::GetAmbe(uint8_t uiCodec) const
|
||||
const uint8_t *CDvFramePacket::GetCodecData(ECodecType type) const
|
||||
{
|
||||
switch (uiCodec)
|
||||
switch (type)
|
||||
{
|
||||
case CODEC_AMBEPLUS:
|
||||
case ECodecType::dstar:
|
||||
return m_uiAmbe;
|
||||
case CODEC_AMBE2PLUS:
|
||||
case ECodecType::dmr:
|
||||
return m_uiAmbePlus;
|
||||
case ECodecType::c2_1600:
|
||||
case ECodecType::c2_3200:
|
||||
return m_uiCodec2;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
@@ -108,18 +130,24 @@ const uint8_t *CDvFramePacket::GetAmbe(uint8_t uiCodec) const
|
||||
|
||||
void CDvFramePacket::SetDvData(uint8_t *DvData)
|
||||
{
|
||||
::memcpy(m_uiDvData, DvData, sizeof(m_uiDvData));
|
||||
memcpy(m_uiDvData, DvData, DVDATA_SIZE);
|
||||
}
|
||||
|
||||
void CDvFramePacket::SetAmbe(uint8_t uiCodec, uint8_t *Ambe)
|
||||
void CDvFramePacket::SetCodecData(ECodecType type, uint8_t *data)
|
||||
{
|
||||
switch (uiCodec)
|
||||
switch (type)
|
||||
{
|
||||
case CODEC_AMBEPLUS:
|
||||
::memcpy(m_uiAmbe, Ambe, sizeof(m_uiAmbe));
|
||||
case ECodecType::dstar:
|
||||
memcpy(m_uiAmbe, data, AMBE_SIZE);
|
||||
break;
|
||||
case CODEC_AMBE2PLUS:
|
||||
::memcpy(m_uiAmbePlus, Ambe, sizeof(m_uiAmbe));
|
||||
case ECodecType::dmr:
|
||||
memcpy(m_uiAmbePlus, data, DVDATA_SIZE);
|
||||
break;
|
||||
case ECodecType::c2_1600:
|
||||
memcpy(m_uiCodec2, data, 8);
|
||||
break;
|
||||
case ECodecType::c2_3200:
|
||||
memcpy(m_uiCodec2, data, 16);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -130,9 +158,11 @@ void CDvFramePacket::SetAmbe(uint8_t uiCodec, uint8_t *Ambe)
|
||||
|
||||
bool CDvFramePacket::operator ==(const CDvFramePacket &DvFrame) const
|
||||
{
|
||||
return ( (::memcmp(m_uiAmbe, DvFrame.m_uiAmbe, sizeof(m_uiAmbe)) == 0)
|
||||
&& (::memcmp(m_uiDvData, DvFrame.m_uiDvData, sizeof(m_uiDvData)) == 0)
|
||||
&& (::memcmp(m_uiAmbePlus, DvFrame.m_uiAmbePlus, sizeof(m_uiAmbePlus)) == 0)
|
||||
&& (::memcmp(m_uiDvSync, DvFrame.m_uiDvSync, sizeof(m_uiDvSync)) == 0)
|
||||
return ( (memcmp(m_uiAmbe, DvFrame.m_uiAmbe, AMBE_SIZE) == 0)
|
||||
&& (memcmp(m_uiDvData, DvFrame.m_uiDvData, DVDATA_SIZE) == 0)
|
||||
#ifndef NO_XLX
|
||||
&& (memcmp(m_uiAmbePlus, DvFrame.m_uiAmbePlus, AMBEPLUS_SIZE) == 0)
|
||||
&& (memcmp(m_uiDvSync, DvFrame.m_uiDvSync, DVSYNC_SIZE) == 0)
|
||||
#endif
|
||||
);
|
||||
}
|
||||
+19
-21
@@ -1,5 +1,7 @@
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
#pragma once
|
||||
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ulxd -- The universal reflector
|
||||
// Copyright © 2021 Thomas A. Early N7TAE
|
||||
//
|
||||
@@ -16,8 +18,6 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Packet.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -49,39 +49,37 @@ public:
|
||||
CDvFramePacket(const struct dstar_dvframe *, uint16_t, uint8_t);
|
||||
CDvFramePacket(const uint8_t *, const uint8_t *, uint16_t, uint8_t, uint8_t);
|
||||
CDvFramePacket(const uint8_t *, uint16_t, uint8_t, uint8_t, uint8_t);
|
||||
CDvFramePacket(uint16_t, uint8_t, const uint8_t *, const uint8_t *, uint8_t, uint8_t, const uint8_t *, const uint8_t *);
|
||||
CDvFramePacket(uint16_t, uint8_t, const uint8_t *, const uint8_t *, uint8_t, uint8_t, const uint8_t *, const uint8_t *, ECodecType, const uint8_t *, const uint8_t *);
|
||||
CDvFramePacket(const CM17Packet &m17);
|
||||
|
||||
// virtual duplication
|
||||
std::unique_ptr<CPacket> Duplicate(void) const;
|
||||
|
||||
// identity
|
||||
bool IsDvFrame(void) const { return true; }
|
||||
bool HasTranscodableAmbe(void) const { return true; }
|
||||
bool IsDvFrame(void) const { return true; }
|
||||
bool HasTranscodableAmbe(void) const { return true; }
|
||||
|
||||
// get
|
||||
const uint8_t *GetAmbe(uint8_t) const;
|
||||
const uint8_t *GetAmbe(void) const { return m_uiAmbe; }
|
||||
const uint8_t *GetAmbePlus(void) const { return m_uiAmbePlus; }
|
||||
const uint8_t *GetDvSync(void) const { return m_uiDvSync; }
|
||||
const uint8_t *GetDvData(void) const { return m_uiDvData; }
|
||||
const uint8_t *GetCodecData(ECodecType) const;
|
||||
const uint8_t *GetDvSync(void) const { return m_uiDvSync; }
|
||||
const uint8_t *GetDvData(void) const { return m_uiDvData; }
|
||||
const uint8_t *GetNonce(void) const { return m_Nonce; }
|
||||
|
||||
// set
|
||||
void SetDvData(uint8_t *);
|
||||
void SetAmbe(uint8_t, uint8_t *);
|
||||
void SetCodecData(ECodecType, uint8_t *);
|
||||
|
||||
// operators
|
||||
bool operator ==(const CDvFramePacket &) const;
|
||||
|
||||
protected:
|
||||
// get
|
||||
uint8_t *GetAmbeData(void) { return m_uiAmbe; }
|
||||
uint8_t *GetAmbePlusData(void) { return m_uiAmbePlus; }
|
||||
|
||||
protected:
|
||||
// data (dstar)
|
||||
uint8_t m_uiAmbe[AMBE_SIZE];
|
||||
uint8_t m_uiDvData[DVDATA_SIZE];
|
||||
uint8_t m_uiAmbe[AMBE_SIZE];
|
||||
uint8_t m_uiDvData[DVDATA_SIZE];
|
||||
// data (dmr)
|
||||
uint8_t m_uiAmbePlus[AMBEPLUS_SIZE];
|
||||
uint8_t m_uiDvSync[DVSYNC_SIZE];
|
||||
uint8_t m_uiAmbePlus[AMBEPLUS_SIZE];
|
||||
uint8_t m_uiDvSync[DVSYNC_SIZE];
|
||||
|
||||
uint8_t m_uiCodec2[16];
|
||||
uint8_t m_Nonce[14];
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
|
||||
//
|
||||
// ulxd -- The universal reflector
|
||||
// Copyright © 2021 Thomas A. Early N7TAE
|
||||
//
|
||||
@@ -79,6 +79,17 @@ CDvHeaderPacket::CDvHeaderPacket(const CCallsign &my, const CCallsign &ur, const
|
||||
m_csMY = my;
|
||||
}
|
||||
|
||||
// M17
|
||||
|
||||
CDvHeaderPacket::CDvHeaderPacket(const CM17Packet &m17) : CPacket(m17)
|
||||
{
|
||||
m_uiFlag1 = m_uiFlag2 = m_uiFlag3 = 0;
|
||||
m_uiCrc = 0;
|
||||
m_csUR = CCallsign("CQCQCQ");
|
||||
m_csMY = m_csRPT1 = m_csRPT2 = m17.GetSourceCallsign();
|
||||
m_csRPT1.SetModule('G');
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// virtual duplication
|
||||
|
||||
@@ -92,7 +103,7 @@ std::unique_ptr<CPacket> CDvHeaderPacket::Duplicate(void) const
|
||||
|
||||
void CDvHeaderPacket::ConvertToDstarStruct(struct dstar_header *buffer) const
|
||||
{
|
||||
::memset(buffer, 0, sizeof(struct dstar_header));
|
||||
memset(buffer, 0, sizeof(struct dstar_header));
|
||||
buffer->Flag1 = m_uiFlag1;
|
||||
buffer->Flag2 = m_uiFlag2;
|
||||
buffer->Flag3 = m_uiFlag3;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
#pragma once
|
||||
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ulxd -- The universal reflector
|
||||
// Copyright © 2021 Thomas A. Early N7TAE
|
||||
//
|
||||
@@ -16,8 +18,6 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Callsign.h"
|
||||
#include "Packet.h"
|
||||
|
||||
@@ -57,6 +57,7 @@ public:
|
||||
CDvHeaderPacket(const struct dstar_header *, uint16_t, uint8_t);
|
||||
CDvHeaderPacket(uint32_t, const CCallsign &, const CCallsign &, const CCallsign &, uint16_t, uint8_t, uint8_t);
|
||||
CDvHeaderPacket(const CCallsign &, const CCallsign &, const CCallsign &, const CCallsign &, uint16_t, uint8_t);
|
||||
CDvHeaderPacket(const CM17Packet &);
|
||||
|
||||
// virtual duplication
|
||||
std::unique_ptr<CPacket> Duplicate(void) const;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
|
||||
//
|
||||
// ulxd -- The universal reflector
|
||||
// Copyright © 2021 Thomas A. Early N7TAE
|
||||
//
|
||||
@@ -41,22 +41,27 @@ CDvLastFramePacket::CDvLastFramePacket(const uint8_t *ambe, const uint8_t *sync,
|
||||
{
|
||||
}
|
||||
|
||||
// dstar + dmr constructor
|
||||
|
||||
CDvLastFramePacket::CDvLastFramePacket
|
||||
(uint16_t sid,
|
||||
uint8_t dstarpid, const uint8_t *dstarambe, const uint8_t *dstardvdata,
|
||||
uint8_t dmrpid, uint8_t dprspid, const uint8_t *dmrambe, const uint8_t *dmrsync)
|
||||
: CDvFramePacket(sid, dstarpid, dstarambe, dstardvdata, dmrpid, dprspid, dmrambe, dmrsync)
|
||||
{
|
||||
}
|
||||
|
||||
// ysf constructor
|
||||
|
||||
CDvLastFramePacket::CDvLastFramePacket(const uint8_t *ambe, uint16_t sid, uint8_t pid, uint8_t spid, uint8_t fid)
|
||||
: CDvFramePacket(ambe, sid, pid, spid, fid)
|
||||
{
|
||||
}
|
||||
|
||||
// urf constructor
|
||||
|
||||
CDvLastFramePacket::CDvLastFramePacket
|
||||
(uint16_t sid,
|
||||
uint8_t dstarpid, const uint8_t *dstarambe, const uint8_t *dstardvdata,
|
||||
uint8_t dmrpid, uint8_t dprspid, const uint8_t *dmrambe, const uint8_t *dmrsync, ECodecType type, const uint8_t *codec2)
|
||||
: CDvFramePacket(sid, dstarpid, dstarambe, dstardvdata, dmrpid, dprspid, dmrambe, dmrsync, type, codec2)
|
||||
{
|
||||
}
|
||||
|
||||
CDvLastFramePacket::CDvLastFramePacket(const CM17Packet &m17) : CDvFramePacket(m17)
|
||||
{
|
||||
}
|
||||
|
||||
// copy constructor
|
||||
|
||||
CDvLastFramePacket::CDvLastFramePacket(const CDvLastFramePacket &DvFrame)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
#pragma once
|
||||
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ulxd -- The universal reflector
|
||||
// Copyright © 2021 Thomas A. Early N7TAE
|
||||
//
|
||||
@@ -16,10 +18,15 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DVFramePacket.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// defines
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CDvLastFramePacket : public CDvFramePacket
|
||||
{
|
||||
public:
|
||||
@@ -28,7 +35,8 @@ public:
|
||||
CDvLastFramePacket(const struct dstar_dvframe *, uint16_t, uint8_t);
|
||||
CDvLastFramePacket(const uint8_t *, const uint8_t *, uint16_t, uint8_t, uint8_t);
|
||||
CDvLastFramePacket(const uint8_t *, uint16_t, uint8_t, uint8_t, uint8_t);
|
||||
CDvLastFramePacket(uint16_t, uint8_t, const uint8_t *, const uint8_t *, uint8_t, uint8_t, const uint8_t *, const uint8_t *);
|
||||
CDvLastFramePacket(uint16_t, uint8_t, const uint8_t *, const uint8_t *, uint8_t, uint8_t, const uint8_t *, const uint8_t *, ECodecType, const uint8_t *);
|
||||
CDvLastFramePacket(const CM17Packet &);
|
||||
CDvLastFramePacket(const CDvLastFramePacket &);
|
||||
|
||||
// virtual duplication
|
||||
|
||||
@@ -652,8 +652,8 @@ bool CG3Protocol::EncodeDvFramePacket(const CDvFramePacket &Packet, CBuffer *Buf
|
||||
Buffer->Set(tag, sizeof(tag));
|
||||
Buffer->Append(Packet.GetStreamId());
|
||||
Buffer->Append((uint8_t)(Packet.GetPacketId() % 21));
|
||||
Buffer->Append((uint8_t *)Packet.GetAmbe(), AMBE_SIZE);
|
||||
Buffer->Append((uint8_t *)Packet.GetDvData(), DVDATA_SIZE);
|
||||
Buffer->Append((uint8_t *)Packet.GetCodecData(ECodecType::dstar), 9);
|
||||
Buffer->Append((uint8_t *)Packet.GetDvData(), 3);
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
@@ -88,6 +88,7 @@ bool CGateKeeper::MayLink(const CCallsign &callsign, const CIp &ip, EProtocol pr
|
||||
case EProtocol::dmrplus:
|
||||
case EProtocol::dmrmmdvm:
|
||||
case EProtocol::ysf:
|
||||
case EProtocol::m17:
|
||||
#ifndef NO_G3
|
||||
case EProtocol::g3:
|
||||
#endif
|
||||
@@ -132,6 +133,7 @@ bool CGateKeeper::MayTransmit(const CCallsign &callsign, const CIp &ip, const EP
|
||||
case EProtocol::dmrplus:
|
||||
case EProtocol::dmrmmdvm:
|
||||
case EProtocol::ysf:
|
||||
case EProtocol::m17:
|
||||
#ifndef NO_G3
|
||||
case EProtocol::g3:
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Library: libcrc
|
||||
* Git: https://github.com/lammertb/libcrc
|
||||
* Author: Lammert Bies
|
||||
*
|
||||
* This file is licensed under the MIT License as stated below
|
||||
*
|
||||
* Copyright (c) 1999-2016 Lammert Bies
|
||||
* Copyright (c) 2020 Thomas A. Early, N7TAE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Description
|
||||
* -----------
|
||||
* The source file contains routines which calculate the CCITT CRC
|
||||
* values for an incomming byte string.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "M17CRC.h"
|
||||
|
||||
#define CRC_POLY_16 0x5935u
|
||||
#define CRC_START_16 0xFFFFu
|
||||
|
||||
CM17CRC::CM17CRC()
|
||||
{
|
||||
for (uint16_t i=0; i<256; i++)
|
||||
{
|
||||
uint16_t crc = 0;
|
||||
uint16_t c = i << 8;
|
||||
|
||||
for (uint16_t j=0; j<8; j++)
|
||||
{
|
||||
if ( (crc ^ c) & 0x8000 )
|
||||
crc = ( crc << 1 ) ^ CRC_POLY_16;
|
||||
else
|
||||
crc = crc << 1;
|
||||
|
||||
c = c << 1;
|
||||
}
|
||||
crc_tab16[i] = crc;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t CM17CRC::CalcCRC( const uint8_t *input_str, size_t num_bytes ) const
|
||||
{
|
||||
uint16_t crc = CRC_START_16;
|
||||
|
||||
if ( input_str )
|
||||
for (size_t a=0; a<num_bytes; a++)
|
||||
{
|
||||
crc = (crc << 8) ^ crc_tab16[ ((crc >> 8) ^ uint16_t(input_str[a])) & 0x00FF ];
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Library: libcrc
|
||||
* Git: https://github.com/lammertb/libcrc
|
||||
* Author: Lammert Bies
|
||||
*
|
||||
* This file is licensed under the MIT License as stated below
|
||||
*
|
||||
* Copyright (c) 1999-2016 Lammert Bies
|
||||
* Copyright (c) 2020 Thomas A. Early, N7TAE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Description
|
||||
* -----------
|
||||
* The source file contains routines which calculate the CCITT CRC
|
||||
* values for an incomming byte string.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
class CM17CRC
|
||||
{
|
||||
public:
|
||||
CM17CRC();
|
||||
uint16_t CalcCRC(const uint8_t *buf, size_t len) const;
|
||||
|
||||
private:
|
||||
uint16_t crc_tab16[256];
|
||||
};
|
||||
@@ -0,0 +1,44 @@
|
||||
// ulxd -- The universal reflector
|
||||
// Copyright © 2021 Thomas A. Early N7TAE
|
||||
//
|
||||
// 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Main.h"
|
||||
#include "M17Client.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructors
|
||||
|
||||
CM17Client::CM17Client()
|
||||
{
|
||||
}
|
||||
|
||||
CM17Client::CM17Client(const CCallsign &callsign, const CIp &ip, char reflectorModule)
|
||||
: CClient(callsign, ip, reflectorModule)
|
||||
{
|
||||
}
|
||||
|
||||
CM17Client::CM17Client(const CM17Client &client)
|
||||
: CClient(client)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// status
|
||||
|
||||
bool CM17Client::IsAlive(void) const
|
||||
{
|
||||
return (m_LastKeepaliveTime.time() < M17_KEEPALIVE_TIMEOUT);
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
// ulxd -- The universal reflector
|
||||
// Copyright © 2021 Thomas A. Early N7TAE
|
||||
//
|
||||
// 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Client.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// define
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CM17Client : public CClient
|
||||
{
|
||||
public:
|
||||
// constructors
|
||||
CM17Client();
|
||||
CM17Client(const CCallsign &, const CIp &, char);
|
||||
CM17Client(const CM17Client &);
|
||||
|
||||
// destructor
|
||||
virtual ~CM17Client() {};
|
||||
|
||||
// identity
|
||||
const char *GetProtocolName(void) const { return "M17"; }
|
||||
bool IsNode(void) const { return true; }
|
||||
|
||||
// status
|
||||
bool IsAlive(void) const;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,95 @@
|
||||
//
|
||||
// Copyright © 2020 Thomas A. Early, N7TAE
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// m17ref 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.
|
||||
//
|
||||
// m17ref 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
|
||||
// with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "M17Packet.h"
|
||||
|
||||
CM17Packet::CM17Packet(const uint8_t *buf)
|
||||
{
|
||||
memcpy(m17.magic, buf, sizeof(SM17Frame));
|
||||
|
||||
destination.CodeIn(m17.lich.addr_dst);
|
||||
source.CodeIn(m17.lich.addr_src);
|
||||
}
|
||||
|
||||
const CCallsign &CM17Packet::GetDestCallsign() const
|
||||
{
|
||||
return destination;
|
||||
}
|
||||
|
||||
const CCallsign &CM17Packet::GetSourceCallsign() const
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
char CM17Packet::GetDestModule() const
|
||||
{
|
||||
return destination.GetModule();
|
||||
}
|
||||
|
||||
uint16_t CM17Packet::GetFrameNumber() const
|
||||
{
|
||||
return ntohs(m17.framenumber);
|
||||
}
|
||||
|
||||
uint16_t CM17Packet::GetFrameType() const
|
||||
{
|
||||
return ntohs(m17.lich.frametype);
|
||||
}
|
||||
|
||||
const uint8_t *CM17Packet::GetPayload() const
|
||||
{
|
||||
return m17.payload;
|
||||
}
|
||||
|
||||
const uint8_t *CM17Packet::GetNonce() const
|
||||
{
|
||||
return m17.lich.nonce;
|
||||
}
|
||||
|
||||
void CM17Packet::SetPayload(const uint8_t *newpayload)
|
||||
{
|
||||
memcpy(m17.payload, newpayload, 16);
|
||||
}
|
||||
|
||||
uint16_t CM17Packet::GetStreamId() const
|
||||
{
|
||||
return ntohs(m17.streamid);
|
||||
}
|
||||
|
||||
uint16_t CM17Packet::GetCRC() const
|
||||
{
|
||||
return ntohs(m17.crc);
|
||||
}
|
||||
|
||||
void CM17Packet::SetCRC(uint16_t crc)
|
||||
{
|
||||
m17.crc = htons(crc);
|
||||
}
|
||||
|
||||
std::unique_ptr<CM17Packet> CM17Packet::Duplicate(void) const
|
||||
{
|
||||
return std::unique_ptr<CM17Packet>(new CM17Packet(*this));
|
||||
}
|
||||
|
||||
bool CM17Packet::IsLastPacket() const
|
||||
{
|
||||
return ((0x8000u & ntohs(m17.framenumber)) == 0x8000u);
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
//
|
||||
// Copyright © 2020 Thomas A. Early, N7TAE
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// m17ref 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.
|
||||
//
|
||||
// m17ref 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
|
||||
// with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string.h>
|
||||
#include <memory>
|
||||
|
||||
#include "Callsign.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// aliases
|
||||
|
||||
// M17 Packets
|
||||
//all structures must be big endian on the wire, so you'll want htonl (man byteorder 3) and such.
|
||||
using SM17Lich = struct __attribute__((__packed__)) lich_tag {
|
||||
uint8_t addr_dst[6];
|
||||
uint8_t addr_src[6];
|
||||
uint16_t frametype; //frametype flag field per the M17 spec
|
||||
uint8_t nonce[14]; //bytes for the nonce
|
||||
}; // 6 + 6 + 2 + 14 = 28 bytes
|
||||
|
||||
//without SYNC or other parts
|
||||
using SM17Frame = struct __attribute__((__packed__)) m17_tag {
|
||||
uint8_t magic[4];
|
||||
uint16_t streamid;
|
||||
SM17Lich lich;
|
||||
uint16_t framenumber;
|
||||
uint8_t payload[16];
|
||||
uint16_t crc; //16 bit CRC
|
||||
}; // 4 + 2 + 28 + 2 + 16 + 2 = 54 bytes
|
||||
|
||||
using SLinkPacket = struct __attribute__((__packed__)) link_tag {
|
||||
uint8_t magic[4];
|
||||
uint8_t fromcs[6];
|
||||
uint8_t mod;
|
||||
}; // 37 bytes
|
||||
|
||||
class CM17Packet
|
||||
{
|
||||
public:
|
||||
CM17Packet() {}
|
||||
CM17Packet(const uint8_t *buf);
|
||||
const CCallsign &GetDestCallsign() const;
|
||||
const CCallsign &GetSourceCallsign() const;
|
||||
char GetDestModule() const;
|
||||
uint16_t GetFrameNumber() const;
|
||||
uint16_t GetFrameType() const;
|
||||
const uint8_t *GetPayload() const;
|
||||
const uint8_t *GetNonce() const;
|
||||
void SetPayload(const uint8_t *newpayload);
|
||||
uint16_t GetStreamId() const;
|
||||
uint16_t GetCRC() const;
|
||||
void SetCRC(uint16_t crc);
|
||||
std::unique_ptr<CM17Packet> Duplicate(void) const;
|
||||
bool IsLastPacket() const;
|
||||
|
||||
private:
|
||||
CCallsign destination, source;
|
||||
SM17Frame m17;
|
||||
};
|
||||
@@ -0,0 +1,434 @@
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
|
||||
// ulxd -- The universal reflector
|
||||
// Copyright © 2021 Thomas A. Early N7TAE
|
||||
//
|
||||
// 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Main.h"
|
||||
#include <string.h>
|
||||
#include "M17Client.h"
|
||||
#include "M17Protocol.h"
|
||||
#include "M17Packet.h"
|
||||
#include "Reflector.h"
|
||||
#include "GateKeeper.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// operation
|
||||
|
||||
bool CM17Protocol::Initialize(const char *type, const EProtocol ptype, const uint16_t port, const bool has_ipv4, const bool has_ipv6)
|
||||
{
|
||||
// base class
|
||||
if (! CProtocol::Initialize(type, ptype, port, has_ipv4, has_ipv6))
|
||||
return false;
|
||||
|
||||
// update time
|
||||
m_LastKeepaliveTime.start();
|
||||
|
||||
// done
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// task
|
||||
|
||||
void CM17Protocol::Task(void)
|
||||
{
|
||||
CBuffer Buffer;
|
||||
CIp Ip;
|
||||
CCallsign Callsign;
|
||||
char ToLinkModule;
|
||||
std::unique_ptr<CDvHeaderPacket> Header;
|
||||
std::unique_ptr<CDvFramePacket> Frame;
|
||||
|
||||
// handle incoming packets
|
||||
#if DSTAR_IPV6==true
|
||||
#if DSTAR_IPV4==true
|
||||
if ( ReceiveDS(Buffer, Ip, 20) )
|
||||
#else
|
||||
if ( Receive6(Buffer, Ip, 20) )
|
||||
#endif
|
||||
#else
|
||||
if ( Receive4(Buffer, Ip, 20) )
|
||||
#endif
|
||||
{
|
||||
// crack the packet
|
||||
if ( IsValidDvPacket(Buffer, Header, Frame) )
|
||||
{
|
||||
// callsign muted?
|
||||
if ( g_GateKeeper.MayTransmit(Header->GetMyCallsign(), Ip, EProtocol::m17, Header->GetRpt2Module()) )
|
||||
{
|
||||
OnDvHeaderPacketIn(Header, Ip);
|
||||
|
||||
if ( !Frame->IsLastPacket() )
|
||||
{
|
||||
//std::cout << "M17 DV frame" << std::endl;
|
||||
OnDvFramePacketIn(Frame, &Ip);
|
||||
}
|
||||
else
|
||||
{
|
||||
//std::cout << "M17 DV last frame" << std::endl;
|
||||
OnDvLastFramePacketIn((std::unique_ptr<CDvLastFramePacket> &)Frame, &Ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( IsValidConnectPacket(Buffer, Callsign, ToLinkModule) )
|
||||
{
|
||||
std::cout << "M17 connect packet for module " << ToLinkModule << " from " << Callsign << " at " << Ip << std::endl;
|
||||
|
||||
// callsign authorized?
|
||||
if ( g_GateKeeper.MayLink(Callsign, Ip, EProtocol::m17) && g_Reflector.IsValidModule(ToLinkModule) )
|
||||
{
|
||||
// valid module ?
|
||||
if ( g_Reflector.IsValidModule(ToLinkModule) )
|
||||
{
|
||||
// acknowledge the request
|
||||
Buffer.Set("ACKN");
|
||||
Send(Buffer, Ip);
|
||||
|
||||
// create the client and append
|
||||
g_Reflector.GetClients()->AddClient(std::make_shared<CM17Client>(Callsign, Ip, ToLinkModule));
|
||||
g_Reflector.ReleaseClients();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "M17 node " << Callsign << " connect attempt on non-existing module" << std::endl;
|
||||
|
||||
// deny the request
|
||||
Buffer.Set("NACK");
|
||||
Send(Buffer, Ip);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// deny the request
|
||||
Buffer.Set("NACK");
|
||||
Send(Buffer, Ip);
|
||||
}
|
||||
|
||||
}
|
||||
else if ( IsValidDisconnectPacket(Buffer, Callsign) )
|
||||
{
|
||||
std::cout << "M17 disconnect packet from " << Callsign << " at " << Ip << std::endl;
|
||||
|
||||
// find client
|
||||
CClients *clients = g_Reflector.GetClients();
|
||||
std::shared_ptr<CClient>client = clients->FindClient(Ip, EProtocol::m17);
|
||||
if ( client != nullptr )
|
||||
{
|
||||
// remove it
|
||||
clients->RemoveClient(client);
|
||||
// and acknowledge the disconnect
|
||||
Buffer.Set("DISC");
|
||||
Send(Buffer, Ip);
|
||||
}
|
||||
g_Reflector.ReleaseClients();
|
||||
}
|
||||
else if ( IsValidKeepAlivePacket(Buffer, Callsign) )
|
||||
{
|
||||
//std::cout << "M17 keepalive packet from " << Callsign << " at " << Ip << std::endl;
|
||||
|
||||
// find all clients with that callsign & ip and keep them alive
|
||||
CClients *clients = g_Reflector.GetClients();
|
||||
auto it = clients->begin();
|
||||
std::shared_ptr<CClient>client = nullptr;
|
||||
while ( (client = clients->FindNextClient(Callsign, Ip, EProtocol::m17, it)) != nullptr )
|
||||
{
|
||||
client->Alive();
|
||||
}
|
||||
g_Reflector.ReleaseClients();
|
||||
}
|
||||
else
|
||||
{
|
||||
// invalid packet
|
||||
std::string title("Unknown M17 packet from ");
|
||||
title += Ip.GetAddress();
|
||||
Buffer.Dump(title);
|
||||
}
|
||||
}
|
||||
|
||||
// handle end of streaming timeout
|
||||
CheckStreamsTimeout();
|
||||
|
||||
// handle queue from reflector
|
||||
HandleQueue();
|
||||
|
||||
// keep client alive
|
||||
if ( m_LastKeepaliveTime.time() > M17_KEEPALIVE_PERIOD )
|
||||
{
|
||||
//
|
||||
HandleKeepalives();
|
||||
|
||||
// update time
|
||||
m_LastKeepaliveTime.start();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// streams helpers
|
||||
|
||||
void CM17Protocol::OnDvHeaderPacketIn(std::unique_ptr<CDvHeaderPacket> &Header, const CIp &Ip)
|
||||
{
|
||||
// find the stream
|
||||
auto stream = GetStream(Header->GetStreamId());
|
||||
if ( stream )
|
||||
{
|
||||
// stream already open
|
||||
// skip packet, but tickle the stream
|
||||
stream->Tickle();
|
||||
}
|
||||
else
|
||||
{
|
||||
// no stream open yet, open a new one
|
||||
CCallsign my(Header->GetMyCallsign());
|
||||
CCallsign rpt1(Header->GetRpt1Callsign());
|
||||
CCallsign rpt2(Header->GetRpt2Callsign());
|
||||
|
||||
// find this client
|
||||
std::shared_ptr<CClient>client = g_Reflector.GetClients()->FindClient(Ip, EProtocol::m17);
|
||||
if ( client )
|
||||
{
|
||||
// get client callsign
|
||||
rpt1 = client->GetCallsign();
|
||||
// and try to open the stream
|
||||
if ( (stream = g_Reflector.OpenStream(Header, client)) != nullptr )
|
||||
{
|
||||
// keep the handle
|
||||
m_Streams.push_back(stream);
|
||||
}
|
||||
}
|
||||
// release
|
||||
g_Reflector.ReleaseClients();
|
||||
|
||||
// update last heard
|
||||
g_Reflector.GetUsers()->Hearing(my, rpt1, rpt2);
|
||||
g_Reflector.ReleaseUsers();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// queue helper
|
||||
|
||||
void CM17Protocol::HandleQueue(void)
|
||||
{
|
||||
m_Queue.Lock();
|
||||
while ( !m_Queue.empty() )
|
||||
{
|
||||
// get the packet
|
||||
auto packet = m_Queue.pop();
|
||||
|
||||
// get our sender's id
|
||||
const auto module = packet->GetModule();
|
||||
|
||||
// check if it's header and update cache
|
||||
if ( packet->IsDvHeader() )
|
||||
{
|
||||
// this relies on queue feeder setting valid module id
|
||||
// m_StreamsCache[module] will be created if it doesn't exist
|
||||
m_StreamsCache[module].m_dvHeader = CDvHeaderPacket((const CDvHeaderPacket &)*packet.get());
|
||||
m_StreamsCache[module].m_iSeqCounter = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// encode it
|
||||
SM17Frame frame;
|
||||
memcpy(frame.magic, "M17 ", 4);
|
||||
if ( packet->IsLastPacket() )
|
||||
{
|
||||
EncodeDvLastPacket(frame, m_StreamsCache[module].m_dvHeader, (const CDvFramePacket &)*packet.get(), m_StreamsCache[module].m_iSeqCounter++);
|
||||
}
|
||||
else if ( packet->IsDvFrame() )
|
||||
{
|
||||
EncodeDvPacket(frame, m_StreamsCache[module].m_dvHeader, (const CDvFramePacket &)*packet.get(), m_StreamsCache[module].m_iSeqCounter++);
|
||||
}
|
||||
|
||||
// push it to all our clients linked to the module and who are not streaming in
|
||||
CClients *clients = g_Reflector.GetClients();
|
||||
auto it = clients->begin();
|
||||
std::shared_ptr<CClient>client = nullptr;
|
||||
while ( (client = clients->FindNextClient(EProtocol::m17, it)) != nullptr )
|
||||
{
|
||||
// is this client busy ?
|
||||
if ( !client->IsAMaster() && (client->GetReflectorModule() == module) )
|
||||
{
|
||||
CBuffer Buffer(frame.magic, sizeof(SM17Frame));
|
||||
// no, send the packet
|
||||
Send(Buffer, client->GetIp());
|
||||
|
||||
}
|
||||
}
|
||||
g_Reflector.ReleaseClients();
|
||||
}
|
||||
}
|
||||
m_Queue.Unlock();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// keepalive helpers
|
||||
|
||||
void CM17Protocol::HandleKeepalives(void)
|
||||
{
|
||||
// M17 protocol sends and monitors keepalives packets
|
||||
// event if the client is currently streaming
|
||||
// so, send keepalives to all
|
||||
CBuffer keepalive;
|
||||
EncodeKeepAlivePacket(keepalive);
|
||||
|
||||
// iterate on clients
|
||||
CClients *clients = g_Reflector.GetClients();
|
||||
auto it = clients->begin();
|
||||
std::shared_ptr<CClient>client = nullptr;
|
||||
while ( (client = clients->FindNextClient(EProtocol::m17, it)) != nullptr )
|
||||
{
|
||||
// send keepalive
|
||||
Send(keepalive, client->GetIp());
|
||||
|
||||
// is this client busy ?
|
||||
if ( client->IsAMaster() )
|
||||
{
|
||||
// yes, just tickle it
|
||||
client->Alive();
|
||||
}
|
||||
// check it's still with us
|
||||
else if ( !client->IsAlive() )
|
||||
{
|
||||
// no, disconnect
|
||||
CBuffer disconnect;
|
||||
disconnect.Set("DISC");
|
||||
Send(disconnect, client->GetIp());
|
||||
|
||||
// remove it
|
||||
std::cout << "M17 client " << client->GetCallsign() << " keepalive timeout" << std::endl;
|
||||
clients->RemoveClient(client);
|
||||
}
|
||||
|
||||
}
|
||||
g_Reflector.ReleaseClients();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// packet decoding helpers
|
||||
|
||||
bool CM17Protocol::IsValidConnectPacket(const CBuffer &Buffer, CCallsign &callsign, char &mod)
|
||||
{
|
||||
uint8_t tag[] = { 'C', 'O', 'N', 'N' };
|
||||
bool valid = false;
|
||||
if (11 == Buffer.size() && 0 == Buffer.Compare(tag, 4))
|
||||
{
|
||||
callsign.CodeIn(Buffer.data() + 4);
|
||||
mod = Buffer.data()[10];
|
||||
valid = (callsign.IsValid() && IsLetter(mod));
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
bool CM17Protocol::IsValidDisconnectPacket(const CBuffer &Buffer, CCallsign &callsign)
|
||||
{
|
||||
uint8_t tag[] = { 'D', 'I', 'S', 'C' };
|
||||
bool valid = false;
|
||||
if ((Buffer.size() == 10) && (0 == Buffer.Compare(tag, 4)))
|
||||
{
|
||||
callsign.CodeIn(Buffer.data() + 4);
|
||||
valid = callsign.IsValid();
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
bool CM17Protocol::IsValidKeepAlivePacket(const CBuffer &Buffer, CCallsign &callsign)
|
||||
{
|
||||
uint8_t tag[] = { 'P', 'O', 'N', 'G' };
|
||||
bool valid = false;
|
||||
if ( (Buffer.size() == 10) || (0 == Buffer.Compare(tag, 4)) )
|
||||
{
|
||||
callsign.CodeIn(Buffer.data() + 4);
|
||||
valid = callsign.IsValid();
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
bool CM17Protocol::IsValidDvPacket(const CBuffer &Buffer, std::unique_ptr<CDvHeaderPacket> &header, std::unique_ptr<CDvFramePacket> &frame)
|
||||
{
|
||||
uint8_t tag[] = { 'M', '1', '7', ' ' };
|
||||
|
||||
if ( (Buffer.size() == sizeof(SM17Frame)) && (0 == Buffer.Compare(tag, sizeof(tag))) && (0x4U == (0x1CU & Buffer[13])) )
|
||||
// Buffer[13] is the lsb byte of the frametype. 0x4 means payload contains Codec2 voice data and there is no encryption.
|
||||
// the 0x1CU mask just lets us see the encryptions bytes (must be zero) and the msb of the payload type (must be set)
|
||||
{
|
||||
// Make the M17 header
|
||||
CM17Packet m17(Buffer.data());
|
||||
// get the header
|
||||
header = std::unique_ptr<CDvHeaderPacket>(new CDvHeaderPacket(m17));
|
||||
|
||||
// get the frame
|
||||
if (m17.IsLastPacket())
|
||||
{
|
||||
// it's the last frame
|
||||
frame = std::unique_ptr<CDvLastFramePacket>(new CDvLastFramePacket(m17));
|
||||
}
|
||||
else
|
||||
{
|
||||
// it's a regular DV frame
|
||||
frame = std::unique_ptr<CDvFramePacket>(new CDvFramePacket(m17));
|
||||
}
|
||||
|
||||
// check validity of packets
|
||||
if ( header && header->IsValid() && frame && frame->IsValid() )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// packet encoding helpers
|
||||
|
||||
void CM17Protocol::EncodeKeepAlivePacket(CBuffer &Buffer)
|
||||
{
|
||||
Buffer.resize(10);
|
||||
memcpy(Buffer.data(), "PING", 4);
|
||||
g_Reflector.GetCallsign().CodeOut(Buffer.data() + 4);
|
||||
}
|
||||
|
||||
void CM17Protocol::EncodeDvPacket(SM17Frame &frame, const CDvHeaderPacket &Header, const CDvFramePacket &DvFrame, uint32_t iSeq) const
|
||||
{
|
||||
ECodecType codec_in = Header.GetCodecIn(); // We'll need this
|
||||
|
||||
|
||||
// do the lich structure first
|
||||
// first, the dest and src callsigns
|
||||
Header.GetRpt2Callsign().CodeOut(frame.lich.addr_dst);
|
||||
CCallsign from = g_Reflector.GetCallsign();
|
||||
from.SetModule(Header.GetModule());
|
||||
from.CodeOut(frame.lich.addr_src);
|
||||
// then the frame type, if the incoming frame is NOT an M17 1600, then it will be Voice only
|
||||
frame.lich.frametype = htons((ECodecType::c2_1600==codec_in) ? 0x7U : 0x5U);
|
||||
memcpy(frame.lich.nonce, DvFrame.GetNonce(), 14);
|
||||
|
||||
// now the main part of the packet
|
||||
memcpy(frame.magic, "M17 ", 4);
|
||||
// the frame number comes from the stream sequence counter
|
||||
frame.framenumber = htons(iSeq % 0x8000U);
|
||||
memcpy(frame.payload, DvFrame.GetCodecData(codec_in), 16);
|
||||
frame.streamid = Header.GetStreamId(); // no host<--->network byte swapping since we never do any math on this value
|
||||
// finally, calcualte the m17 CRC value and load it
|
||||
frame.crc = htons(m17crc.CalcCRC(frame.magic, sizeof(SM17Frame)-2));
|
||||
}
|
||||
|
||||
void CM17Protocol::EncodeDvLastPacket(SM17Frame &frame, const CDvHeaderPacket &Header, const CDvFramePacket &DvFrame, uint32_t iSeq) const
|
||||
{
|
||||
EncodeDvPacket(frame, Header, DvFrame, iSeq);
|
||||
frame.framenumber |= 0x8000U;
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
|
||||
// ulxd -- The universal reflector
|
||||
// Copyright © 2021 Thomas A. Early N7TAE
|
||||
//
|
||||
// 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Timer.h"
|
||||
#include "Protocol.h"
|
||||
#include "DVHeaderPacket.h"
|
||||
#include "DVFramePacket.h"
|
||||
#include "DVLastFramePacket.h"
|
||||
#include "M17CRC.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// define
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CM17StreamCacheItem
|
||||
{
|
||||
public:
|
||||
CM17StreamCacheItem() : m_iSeqCounter(0) {}
|
||||
|
||||
CDvHeaderPacket m_dvHeader;
|
||||
uint32_t m_iSeqCounter;
|
||||
};
|
||||
|
||||
class CM17Protocol : public CProtocol
|
||||
{
|
||||
public:
|
||||
// initialization
|
||||
bool Initialize(const char *type, const EProtocol ptype, const uint16_t port, const bool has_ipv4, const bool has_ipv6);
|
||||
|
||||
// task
|
||||
void Task(void);
|
||||
|
||||
protected:
|
||||
// queue helper
|
||||
void HandleQueue(void);
|
||||
|
||||
// keepalive helpers
|
||||
void HandleKeepalives(void);
|
||||
|
||||
// stream helpers
|
||||
void OnDvHeaderPacketIn(std::unique_ptr<CDvHeaderPacket> &, const CIp &);
|
||||
|
||||
// packet decoding helpers
|
||||
bool IsValidConnectPacket(const CBuffer &, CCallsign &, char &);
|
||||
bool IsValidDisconnectPacket(const CBuffer &, CCallsign &);
|
||||
bool IsValidKeepAlivePacket(const CBuffer &, CCallsign &);
|
||||
bool IsValidDvPacket(const CBuffer &, std::unique_ptr<CDvHeaderPacket> &, std::unique_ptr<CDvFramePacket> &);
|
||||
|
||||
// packet encoding helpers
|
||||
void EncodeKeepAlivePacket(CBuffer &);
|
||||
void EncodeDvPacket(SM17Frame &, const CDvHeaderPacket &, const CDvFramePacket &, uint32_t) const;
|
||||
void EncodeDvLastPacket(SM17Frame &, const CDvHeaderPacket &, const CDvFramePacket &, uint32_t) const;
|
||||
|
||||
protected:
|
||||
// for keep alive
|
||||
CTimer m_LastKeepaliveTime;
|
||||
|
||||
// for queue header caches
|
||||
std::unordered_map<char, CM17StreamCacheItem> m_StreamsCache;
|
||||
|
||||
private:
|
||||
CM17CRC m17crc;
|
||||
};
|
||||
+10
-11
@@ -73,9 +73,9 @@
|
||||
// protocols ---------------------------------------------------
|
||||
|
||||
#ifndef NO_G3
|
||||
enum class EProtocol { any, none, dextra, dplus, dcs, ulx, dmrplus, dmrmmdvm, ysf, g3 };
|
||||
enum class EProtocol { any, none, dextra, dplus, dcs, ulx, dmrplus, dmrmmdvm, ysf, m17, g3 };
|
||||
#else
|
||||
enum class EProtocol { any, none, dextra, dplus, dcs, xlx, dmrplus, dmrmmdvm, ysf };
|
||||
enum class EProtocol { any, none, dextra, dplus, dcs, xlx, dmrplus, dmrmmdvm, ysf, m17 };
|
||||
#endif
|
||||
|
||||
// DExtra
|
||||
@@ -124,6 +124,12 @@ enum class EProtocol { any, none, dextra, dplus, dcs, xlx, dmrplus, dmrmmdvm, ys
|
||||
// #define YSF_AUTOLINK_ENABLE 0 // 1 = enable, 0 = disable auto-link
|
||||
// #define YSF_AUTOLINK_MODULE 'B' // module for client to auto-link to
|
||||
|
||||
// M17
|
||||
#define M17_PORT 17000
|
||||
#define M17_KEEPALIVE_PERIOD 3
|
||||
#define M17_KEEPALIVE_TIMEOUT (M17_KEEPALIVE_PERIOD*10)
|
||||
#define M17_RECONNECT_PERIOD 5
|
||||
|
||||
#ifndef NO_G3
|
||||
// G3 Terminal
|
||||
#define G3_PRESENCE_PORT 12346 // UDP port
|
||||
@@ -133,21 +139,14 @@ enum class EProtocol { any, none, dextra, dplus, dcs, xlx, dmrplus, dmrmmdvm, ys
|
||||
#define G3_KEEPALIVE_TIMEOUT 3600 // in seconds, 1 hour
|
||||
#endif
|
||||
|
||||
#ifdef TRANSCODER_IP
|
||||
// Transcoder server --------------------------------------------
|
||||
|
||||
#ifdef TRANSCODER_IP
|
||||
#define TRANSCODER_PORT 10100 // UDP port
|
||||
#endif
|
||||
#define TRANSCODER_KEEPALIVE_PERIOD 5 // in seconds
|
||||
#define TRANSCODER_KEEPALIVE_TIMEOUT 30 // in seconds
|
||||
#define TRANSCODER_AMBEPACKET_TIMEOUT 400 // in ms
|
||||
#endif
|
||||
|
||||
// codec --------------------------------------------------------
|
||||
|
||||
#define CODEC_NONE 0
|
||||
#define CODEC_AMBEPLUS 1 // DStar
|
||||
#define CODEC_AMBE2PLUS 2 // DMR
|
||||
|
||||
|
||||
// DMRid database -----------------------------------------------
|
||||
|
||||
|
||||
+2
-2
@@ -47,8 +47,8 @@ ifeq ($(ysf_db), true)
|
||||
LDFLAGS += `mysql_config --libs`
|
||||
endif
|
||||
|
||||
ifdef tc_ip
|
||||
SRCS += Transcoder.cpp CodecStream.cpp
|
||||
ifdef need_tc
|
||||
SRCS += CodecStream.cpp
|
||||
endif
|
||||
|
||||
ifeq ($(use_g3), true)
|
||||
|
||||
+38
-3
@@ -19,6 +19,11 @@
|
||||
#include "Main.h"
|
||||
#include "Packet.h"
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructor
|
||||
|
||||
CPacket::CPacket()
|
||||
{
|
||||
m_uiStreamId = 0;
|
||||
@@ -28,8 +33,10 @@ CPacket::CPacket()
|
||||
m_uiYsfPacketId = 0;
|
||||
m_uiYsfPacketSubId = 0;
|
||||
m_uiYsfPacketFrameId = 0;
|
||||
m_uiM17FrameNumber = 0;
|
||||
m_cModule = ' ';
|
||||
m_uiOriginId = ORIGIN_LOCAL;
|
||||
m_eCodecIn = ECodecType::none;
|
||||
};
|
||||
|
||||
// dstar contrsuctor
|
||||
@@ -43,8 +50,10 @@ CPacket::CPacket(uint16_t sid, uint8_t dstarpid)
|
||||
m_uiYsfPacketId = 0xFF;
|
||||
m_uiYsfPacketSubId = 0xFF;
|
||||
m_uiYsfPacketFrameId = 0xFF;
|
||||
m_uiM17FrameNumber = 0x8000U;
|
||||
m_cModule = ' ';
|
||||
m_uiOriginId = ORIGIN_LOCAL;
|
||||
m_eCodecIn = ECodecType::dstar;
|
||||
};
|
||||
|
||||
// dmr constructor
|
||||
@@ -58,8 +67,10 @@ CPacket::CPacket(uint16_t sid, uint8_t dmrpid, uint8_t dmrspid)
|
||||
m_uiYsfPacketId = 0xFF;
|
||||
m_uiYsfPacketSubId = 0xFF;
|
||||
m_uiYsfPacketFrameId = 0xFF;
|
||||
m_uiM17FrameNumber = 0x8000U;
|
||||
m_cModule = ' ';
|
||||
m_uiOriginId = ORIGIN_LOCAL;
|
||||
m_eCodecIn = ECodecType::dmr;
|
||||
};
|
||||
|
||||
// ysf constructor
|
||||
@@ -73,13 +84,15 @@ CPacket::CPacket(uint16_t sid, uint8_t ysfpid, uint8_t ysfsubpid, uint8_t ysffri
|
||||
m_uiDstarPacketId = 0xFF;
|
||||
m_uiDmrPacketId = 0xFF;
|
||||
m_uiDmrPacketSubid = 0xFF;
|
||||
m_uiM17FrameNumber = 0x8000U;
|
||||
m_cModule = ' ';
|
||||
m_uiOriginId = ORIGIN_LOCAL;
|
||||
m_eCodecIn = ECodecType::dmr;
|
||||
}
|
||||
|
||||
// xlx constructor
|
||||
|
||||
CPacket::CPacket(uint16_t sid, uint8_t dstarpid, uint8_t dmrpid, uint8_t dmrsubpid, uint8_t ysfpid, uint8_t ysfsubpid, uint8_t ysffrid)
|
||||
CPacket::CPacket(uint16_t sid, uint8_t dstarpid, uint8_t dmrpid, uint8_t dmrsubpid, uint8_t ysfpid, uint8_t ysfsubpid, uint8_t ysffrid, ECodecType codecIn)
|
||||
{
|
||||
m_uiStreamId = sid;
|
||||
m_uiDstarPacketId = dstarpid;
|
||||
@@ -88,8 +101,25 @@ CPacket::CPacket(uint16_t sid, uint8_t dstarpid, uint8_t dmrpid, uint8_t dmrsubp
|
||||
m_uiYsfPacketId = ysfpid;
|
||||
m_uiYsfPacketSubId = ysfsubpid;
|
||||
m_uiYsfPacketFrameId = ysffrid;
|
||||
m_uiM17FrameNumber = 0x8000U;
|
||||
m_cModule = ' ';
|
||||
m_uiOriginId = ORIGIN_LOCAL;
|
||||
m_eCodecIn = codecIn;
|
||||
}
|
||||
|
||||
// m17 constructor
|
||||
|
||||
CPacket::CPacket(const CM17Packet &m17) : CPacket()
|
||||
{
|
||||
m_uiStreamId = m17.GetStreamId();
|
||||
m_uiDstarPacketId = 0xFF;
|
||||
m_uiDmrPacketId = 0xFF;
|
||||
m_uiDmrPacketSubid = 0xFF;
|
||||
m_uiYsfPacketId = 0xFF;
|
||||
m_uiYsfPacketSubId = 0xFF;
|
||||
m_uiYsfPacketFrameId = 0xFF;
|
||||
m_eCodecIn = (0x6U == (0x6U & m17.GetFrameType())) ? ECodecType::c2_1600 : ECodecType::c2_3200;
|
||||
m_uiM17FrameNumber = 0x7FFFU & m17.GetFrameNumber();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -97,9 +127,9 @@ CPacket::CPacket(uint16_t sid, uint8_t dstarpid, uint8_t dmrpid, uint8_t dmrsubp
|
||||
|
||||
void CPacket::UpdatePids(uint32_t pid)
|
||||
{
|
||||
// called while phusing this packet in a stream queue
|
||||
// called while pushing this packet in a stream queue
|
||||
// so now packet sequence number is known and undefined pids can be updated
|
||||
// this is needed as dtsar & dmt pids are different and cannot be
|
||||
// this is needed as dtsar & dmr pids are different and cannot be
|
||||
// derived from each other
|
||||
|
||||
// dstar pid needs update ?
|
||||
@@ -120,4 +150,9 @@ void CPacket::UpdatePids(uint32_t pid)
|
||||
m_uiYsfPacketSubId = pid % 5;
|
||||
m_uiYsfPacketFrameId = ((pid / 5) & 0x7FU) << 1;
|
||||
}
|
||||
// m17 needs update?
|
||||
if (m_uiM17FrameNumber == 0x8000U)
|
||||
{
|
||||
m_uiM17FrameNumber = pid % 0x7FFFU;
|
||||
}
|
||||
}
|
||||
+35
-31
@@ -1,5 +1,7 @@
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
#pragma once
|
||||
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ulxd -- The universal reflector
|
||||
// Copyright © 2021 Thomas A. Early N7TAE
|
||||
//
|
||||
@@ -16,17 +18,14 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Origin Id
|
||||
|
||||
enum class ECodecType { none, dstar, dmr, c2_1600, c2_3200 };
|
||||
|
||||
#define ORIGIN_LOCAL 0
|
||||
#define ORIGIN_PEER 1
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
#include "M17Packet.h"
|
||||
|
||||
class CPacket
|
||||
{
|
||||
@@ -36,7 +35,8 @@ public:
|
||||
CPacket(uint16_t sid, uint8_t dstarpid);
|
||||
CPacket(uint16_t sid, uint8_t dmrpid, uint8_t dmrsubpid);
|
||||
CPacket(uint16_t sid, uint8_t ysfpid, uint8_t ysfsubpid, uint8_t ysfsubpidmax);
|
||||
CPacket(uint16_t sid, uint8_t dstarpid, uint8_t dmrpid, uint8_t dmrsubpid, uint8_t ysfpid, uint8_t ysfsubpid, uint8_t ysfsubpidmax);
|
||||
CPacket(uint16_t sid, uint8_t dstarpid, uint8_t dmrpid, uint8_t dmrsubpid, uint8_t ysfpid, uint8_t ysfsubpid, uint8_t ysfsubpidmax, ECodecType);
|
||||
CPacket(const CM17Packet &);
|
||||
|
||||
// destructor
|
||||
virtual ~CPacket() {}
|
||||
@@ -51,33 +51,37 @@ public:
|
||||
virtual bool HasTranscodableAmbe(void) const { return false; }
|
||||
|
||||
// get
|
||||
virtual bool IsValid(void) const { return true; }
|
||||
uint16_t GetStreamId(void) const { return m_uiStreamId; }
|
||||
uint8_t GetPacketId(void) const { return m_uiDstarPacketId; }
|
||||
uint8_t GetDstarPacketId(void) const { return m_uiDstarPacketId; }
|
||||
uint8_t GetDmrPacketId(void) const { return m_uiDmrPacketId; }
|
||||
uint8_t GetDmrPacketSubid(void) const { return m_uiDmrPacketSubid; }
|
||||
uint8_t GetYsfPacketId(void) const { return m_uiYsfPacketId; }
|
||||
uint8_t GetYsfPacketSubId(void) const { return m_uiYsfPacketSubId; }
|
||||
uint8_t GetYsfPacketFrameId(void) const { return m_uiYsfPacketFrameId; }
|
||||
char GetModule(void) const { return m_cModule; }
|
||||
bool IsLocalOrigin(void) const { return (m_uiOriginId == ORIGIN_LOCAL); }
|
||||
virtual bool IsValid(void) const { return true; }
|
||||
uint16_t GetStreamId(void) const { return m_uiStreamId; }
|
||||
uint16_t M17FrameNumber(void) const { return m_uiM17FrameNumber; }
|
||||
uint8_t GetPacketId(void) const { return m_uiDstarPacketId; }
|
||||
uint8_t GetDstarPacketId(void) const { return m_uiDstarPacketId; }
|
||||
uint8_t GetDmrPacketId(void) const { return m_uiDmrPacketId; }
|
||||
uint8_t GetDmrPacketSubid(void) const { return m_uiDmrPacketSubid; }
|
||||
uint8_t GetYsfPacketId(void) const { return m_uiYsfPacketId; }
|
||||
uint8_t GetYsfPacketSubId(void) const { return m_uiYsfPacketSubId; }
|
||||
uint8_t GetYsfPacketFrameId(void) const { return m_uiYsfPacketFrameId; }
|
||||
char GetModule(void) const { return m_cModule; }
|
||||
bool IsLocalOrigin(void) const { return (m_uiOriginId == ORIGIN_LOCAL); }
|
||||
ECodecType GetCodecIn(void) const { return m_eCodecIn; }
|
||||
|
||||
// set
|
||||
void UpdatePids(uint32_t);
|
||||
void SetModule(char c) { m_cModule = c; }
|
||||
void SetLocalOrigin(void) { m_uiOriginId = ORIGIN_LOCAL; }
|
||||
void SetRemotePeerOrigin(void) { m_uiOriginId = ORIGIN_PEER; }
|
||||
void SetModule(char cMod) { m_cModule = cMod; }
|
||||
void SetLocalOrigin(void) { m_uiOriginId = ORIGIN_LOCAL; }
|
||||
void SetRemotePeerOrigin(void) { m_uiOriginId = ORIGIN_PEER; }
|
||||
|
||||
protected:
|
||||
// data
|
||||
uint16_t m_uiStreamId;
|
||||
uint8_t m_uiDstarPacketId;
|
||||
uint8_t m_uiDmrPacketId;
|
||||
uint8_t m_uiDmrPacketSubid;
|
||||
uint8_t m_uiYsfPacketId;
|
||||
uint8_t m_uiYsfPacketSubId;
|
||||
uint8_t m_uiYsfPacketFrameId;
|
||||
char m_cModule;
|
||||
uint8_t m_uiOriginId;
|
||||
uint16_t m_uiStreamId;
|
||||
uint16_t m_uiM17FrameNumber;
|
||||
uint8_t m_uiDstarPacketId;
|
||||
uint8_t m_uiDmrPacketId;
|
||||
uint8_t m_uiDmrPacketSubid;
|
||||
uint8_t m_uiYsfPacketId;
|
||||
uint8_t m_uiYsfPacketSubId;
|
||||
uint8_t m_uiYsfPacketFrameId;
|
||||
char m_cModule;
|
||||
uint8_t m_uiOriginId;
|
||||
ECodecType m_eCodecIn;
|
||||
};
|
||||
+2
-2
@@ -28,7 +28,7 @@
|
||||
|
||||
CPeer::CPeer()
|
||||
{
|
||||
::memset(m_ReflectorModules, 0, sizeof(m_ReflectorModules));
|
||||
memset(m_ReflectorModules, 0, sizeof(m_ReflectorModules));
|
||||
m_ConnectTime = std::time(nullptr);
|
||||
m_LastHeardTime = std::time(nullptr);
|
||||
}
|
||||
@@ -37,7 +37,7 @@ CPeer::CPeer(const CCallsign &callsign, const CIp &ip, const char *modules, cons
|
||||
{
|
||||
m_Callsign = callsign;
|
||||
m_Ip = ip;
|
||||
::memset(m_ReflectorModules, 0, sizeof(m_ReflectorModules));
|
||||
memset(m_ReflectorModules, 0, sizeof(m_ReflectorModules));
|
||||
::strncpy(m_ReflectorModules, modules, sizeof(m_ReflectorModules)-1);
|
||||
m_Version = version;
|
||||
m_LastKeepaliveTime.start();
|
||||
|
||||
@@ -638,13 +638,13 @@ bool CURFProtocol::EncodeDvFramePacket(const CDvFramePacket &Packet, CBuffer *Bu
|
||||
Buffer->Set(tag, sizeof(tag));
|
||||
Buffer->Append(Packet.GetStreamId());
|
||||
Buffer->Append((uint8_t)(Packet.GetDstarPacketId() % 21));
|
||||
Buffer->Append((uint8_t *)Packet.GetAmbe(), AMBE_SIZE);
|
||||
Buffer->Append((uint8_t *)Packet.GetDvData(), DVDATA_SIZE);
|
||||
Buffer->Append((uint8_t *)Packet.GetAmbe(), 9);
|
||||
Buffer->Append((uint8_t *)Packet.GetDvData(), 3);
|
||||
|
||||
Buffer->Append((uint8_t)Packet.GetDmrPacketId());
|
||||
Buffer->Append((uint8_t)Packet.GetDmrPacketSubid());
|
||||
Buffer->Append((uint8_t *)Packet.GetAmbePlus(), AMBEPLUS_SIZE);
|
||||
Buffer->Append((uint8_t *)Packet.GetDvSync(), DVSYNC_SIZE);
|
||||
Buffer->Append((uint8_t *)Packet.GetAmbePlus(), 9);
|
||||
Buffer->Append((uint8_t *)Packet.GetDvSync(), 7);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -665,8 +665,8 @@ bool CURFProtocol::EncodeDvLastFramePacket(const CDvLastFramePacket &Packet, CBu
|
||||
|
||||
Buffer->Append((uint8_t)Packet.GetDmrPacketId());
|
||||
Buffer->Append((uint8_t)Packet.GetDmrPacketSubid());
|
||||
Buffer->Append((uint8_t *)Packet.GetAmbePlus(), AMBEPLUS_SIZE);
|
||||
Buffer->Append((uint8_t *)Packet.GetDvSync(), DVSYNC_SIZE);
|
||||
Buffer->Append((uint8_t *)Packet.GetAmbePlus(), 9);
|
||||
Buffer->Append((uint8_t *)Packet.GetDvSync(), 7);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright (C) 2020 by Thomas Early N7TAE
|
||||
*
|
||||
* 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 <iostream>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <unistd.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "UnixPacketSock.h"
|
||||
|
||||
CUnixPacket::CUnixPacket() : m_fd(-1), m_host(NULL) {}
|
||||
|
||||
ssize_t CUnixPacket::Read(void *buffer, const ssize_t size)
|
||||
{
|
||||
if (0 > m_fd)
|
||||
return -1;
|
||||
ssize_t len = read(m_fd, buffer, size);
|
||||
if (len < 1)
|
||||
{
|
||||
if (-1 == len)
|
||||
{
|
||||
std::cerr << "Read error on '" << m_name << "': " << strerror(errno) << std::endl;
|
||||
}
|
||||
else if (0 == len)
|
||||
{
|
||||
std::cerr << "Read error on '" << m_name << "': EOF" << std::endl;
|
||||
}
|
||||
if (Restart())
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
bool CUnixPacket::Write(const void *buffer, const ssize_t size)
|
||||
{
|
||||
if (0 > m_fd)
|
||||
return true;
|
||||
ssize_t written = write(m_fd, buffer, size);
|
||||
if (written != size)
|
||||
{
|
||||
if (-1 == written)
|
||||
{
|
||||
std::cerr << "Write error on '" << m_name << "': " << strerror(errno) << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Write error on '" << m_name << "': Only wrote " << written << " of " << size << " bytes" << std::endl;
|
||||
}
|
||||
return Restart();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CUnixPacket::Restart()
|
||||
{
|
||||
if (! m_host->IsRunning())
|
||||
return true;
|
||||
std::cout << "Restarting '" << m_name << "'... " << std::endl;
|
||||
Close();
|
||||
std::string name(m_name);
|
||||
return Open(name.c_str(), m_host);
|
||||
}
|
||||
|
||||
int CUnixPacket::GetFD()
|
||||
{
|
||||
return m_fd;
|
||||
}
|
||||
|
||||
CUnixPacketServer::CUnixPacketServer() : m_server(-1) {}
|
||||
|
||||
CUnixPacketServer::~CUnixPacketServer()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
bool CUnixPacketServer::Open(const char *name, CKRBase *host)
|
||||
{
|
||||
m_server = socket(AF_UNIX, SOCK_SEQPACKET, 0);
|
||||
m_host = host;
|
||||
if (m_server < 0)
|
||||
{
|
||||
std::cerr << "Cannot open '" << name << "' socket: " << strerror(errno) << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
struct sockaddr_un addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
memcpy(addr.sun_path+1, name, strlen(name));
|
||||
if (-1 == bind(m_server, (struct sockaddr *)&addr, sizeof(addr)))
|
||||
{
|
||||
std::cerr << "Cannot bind '" << name << "' socket: " << strerror(errno) << std::endl;
|
||||
Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (-1 == listen(m_server, 1))
|
||||
{
|
||||
std::cerr << "Cannot listen on '" << name << "' socket: " << strerror(errno) << std::endl;
|
||||
Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
m_fd = accept(m_server, nullptr, 0);
|
||||
if (m_fd < 0)
|
||||
{
|
||||
std::cerr << "Cannot accept on '" << name << "' socket: " << strerror(errno) << std::endl;
|
||||
Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
strncpy(m_name, name, 108);
|
||||
return false;
|
||||
}
|
||||
|
||||
void CUnixPacketServer::Close()
|
||||
{
|
||||
if (m_server >= 0)
|
||||
{
|
||||
close(m_server);
|
||||
m_server = -1;
|
||||
}
|
||||
if (m_fd >= 0)
|
||||
{
|
||||
close(m_fd);
|
||||
m_fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
CUnixPacketClient::~CUnixPacketClient()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
bool CUnixPacketClient::Open(const char *name, CKRBase *host)
|
||||
{
|
||||
m_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
|
||||
if (m_fd < 0)
|
||||
{
|
||||
std::cerr << "Cannot open unix client socket " << name << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
struct sockaddr_un addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
memcpy(addr.sun_path+1, name, strlen(name));
|
||||
int rval = -1;
|
||||
int tries = 0;
|
||||
while (rval < 0)
|
||||
{
|
||||
rval = connect(m_fd, (struct sockaddr *)&addr, sizeof(addr));
|
||||
if (rval < 0)
|
||||
{
|
||||
if (ECONNREFUSED == errno)
|
||||
{
|
||||
if (0 == tries++ % 20)
|
||||
std::cout << "Waiting for " << name << " server to start..." << std::endl;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Cannot connect '" << name << "' socket: " << strerror(errno) << std::endl;
|
||||
Close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (! m_host->IsRunning())
|
||||
{
|
||||
Close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
m_host = host;
|
||||
strncpy(m_name, name, 108);
|
||||
return false;
|
||||
}
|
||||
|
||||
void CUnixPacketClient::Close()
|
||||
{
|
||||
if (m_fd >= 0)
|
||||
{
|
||||
close(m_fd);
|
||||
m_fd = -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
* Copyright (C) 2020 by Thomas Early N7TAE
|
||||
*
|
||||
* 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 <sys/types.h>
|
||||
|
||||
#include "KRBase.h"
|
||||
|
||||
class CUnixPacket
|
||||
{
|
||||
public:
|
||||
CUnixPacket();
|
||||
virtual bool Open(const char *name, CKRBase *host) = 0;
|
||||
virtual void Close() = 0;
|
||||
bool Write(const void *buffer, const ssize_t size);
|
||||
ssize_t Read(void *buffer, const ssize_t size);
|
||||
int GetFD();
|
||||
protected:
|
||||
bool Restart();
|
||||
int m_fd;
|
||||
CKRBase *m_host;
|
||||
char m_name[108];
|
||||
};
|
||||
|
||||
class CUnixPacketServer : public CUnixPacket
|
||||
{
|
||||
public:
|
||||
CUnixPacketServer();
|
||||
~CUnixPacketServer();
|
||||
bool Open(const char *name, CKRBase *host);
|
||||
void Close();
|
||||
protected:
|
||||
int m_server;
|
||||
};
|
||||
|
||||
class CUnixPacketClient : public CUnixPacket
|
||||
{
|
||||
public:
|
||||
~CUnixPacketClient();
|
||||
bool Open(const char *name, CKRBase *host);
|
||||
void Close();
|
||||
};
|
||||
@@ -238,16 +238,16 @@ bool CWiresxCmdHandler::ReplyToWiresxDxReqPacket(const CIp &Ip, const CWiresxInf
|
||||
RoomId = (uint8_t)(Module - 'A');
|
||||
|
||||
// fill data buffer
|
||||
::memset(data, 0x00U, 150U);
|
||||
::memset(data, ' ', 128U);
|
||||
memset(data, 0x00U, 150U);
|
||||
memset(data, ' ', 128U);
|
||||
// seq no
|
||||
data[0U] = m_seqNo;
|
||||
// command
|
||||
::memcpy(data + 1U, DX_RESP, 4U);
|
||||
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);
|
||||
memcpy(data + 5U, WiresxInfo.GetId(), 5U);
|
||||
memcpy(data + 10U, WiresxInfo.GetNode(), 10U);
|
||||
memcpy(data + 20U, WiresxInfo.GetName(), 14U);
|
||||
// linked room
|
||||
if (!IsLinked)
|
||||
{
|
||||
@@ -266,19 +266,19 @@ bool CWiresxCmdHandler::ReplyToWiresxDxReqPacket(const CIp &Ip, const CWiresxInf
|
||||
char item[16U];
|
||||
// refl->m_id
|
||||
::sprintf(item, "%05d", 4001U + RoomId);
|
||||
::memcpy(data + 36U, item, 5U);
|
||||
memcpy(data + 36U, item, 5U);
|
||||
// refl->name
|
||||
::memset(item, ' ', 16U);
|
||||
::memcpy(item, "MODULE", 6U); // K2IE fix for U/C only radios
|
||||
memset(item, ' ', 16U);
|
||||
memcpy(item, "MODULE", 6U); // K2IE fix for U/C only radios
|
||||
item[7] = 'A' + RoomId;
|
||||
::memcpy(data + 41U, item, 16U);
|
||||
memcpy(data + 41U, item, 16U);
|
||||
// refl->count
|
||||
::sprintf(item, "%03d", RoomId + 1);
|
||||
::memcpy(data + 57U, item, 3U);
|
||||
memcpy(data + 57U, item, 3U);
|
||||
// other
|
||||
::memset(data + 60U, ' ', 10U);
|
||||
memset(data + 60U, ' ', 10U);
|
||||
// refl->m_desc
|
||||
::memcpy(data + 70U, "Description ", 14U);
|
||||
memcpy(data + 70U, "Description ", 14U);
|
||||
}
|
||||
|
||||
// frequencies
|
||||
@@ -301,7 +301,7 @@ bool CWiresxCmdHandler::ReplyToWiresxDxReqPacket(const CIp &Ip, const CWiresxInf
|
||||
char freq[30U];
|
||||
::sprintf(freq, "%05u.%06u%c%03u.%06u", WiresxInfo.GetTxFrequency() / 1000000U, freqHz, sign, offset / 1000000U, offset % 1000000U);
|
||||
|
||||
::memcpy(data + 84U, freq, 23U);
|
||||
memcpy(data + 84U, freq, 23U);
|
||||
}
|
||||
|
||||
// EOD & CRC
|
||||
@@ -325,16 +325,16 @@ bool CWiresxCmdHandler::ReplyToWiresxAllReqPacket(const CIp &Ip, const CWiresxIn
|
||||
uint8_t data[1100U];
|
||||
|
||||
// fill data buffer
|
||||
::memset(data, 0x00U, 1100U);
|
||||
memset(data, 0x00U, 1100U);
|
||||
// seq no
|
||||
data[0U] = m_seqNo;
|
||||
// command
|
||||
::memcpy(data + 1U, ALL_RESP, 4U);
|
||||
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);
|
||||
memcpy(data + 7U, WiresxInfo.GetId(), 5U);
|
||||
memcpy(data + 12U, WiresxInfo.GetNode(), 10U);
|
||||
|
||||
// number of entries
|
||||
const char *modules = ACTIVE_MODULES;
|
||||
@@ -356,24 +356,24 @@ bool CWiresxCmdHandler::ReplyToWiresxAllReqPacket(const CIp &Ip, const CWiresxIn
|
||||
int RoomId = RoomMod - 'A';
|
||||
|
||||
// prepare
|
||||
::memset(data + offset, ' ', 50U);
|
||||
memset(data + offset, ' ', 50U);
|
||||
data[offset + 0U] = '5';
|
||||
|
||||
// refl->m_id
|
||||
::sprintf(item, "%05d", 4001U + RoomId);
|
||||
::memcpy(data + offset + 1U, item, 5U);
|
||||
memcpy(data + offset + 1U, item, 5U);
|
||||
// refl->name
|
||||
::memset(item, ' ', 16U);
|
||||
::memcpy(item, "MODULE", 6U); // K2IE fix for U/C only radios
|
||||
memset(item, ' ', 16U);
|
||||
memcpy(item, "MODULE", 6U); // K2IE fix for U/C only radios
|
||||
item[7] = RoomMod;
|
||||
::memcpy(data + offset + 6U, item, 16U);
|
||||
memcpy(data + offset + 6U, item, 16U);
|
||||
// refl->count
|
||||
::sprintf(item, "%03d", RoomId + 1);
|
||||
::memcpy(data + offset + 22U, item, 3U);
|
||||
memcpy(data + offset + 22U, item, 3U);
|
||||
// other
|
||||
::memset(data + offset + 25U, ' ', 10U);
|
||||
memset(data + offset + 25U, ' ', 10U);
|
||||
// refl->m_desc
|
||||
::memcpy(data + offset + 35U, "Description ", 14U);
|
||||
memcpy(data + offset + 35U, "Description ", 14U);
|
||||
data[offset + 49U] = 0x0DU;
|
||||
// next
|
||||
offset += 50U;
|
||||
@@ -388,7 +388,7 @@ bool CWiresxCmdHandler::ReplyToWiresxAllReqPacket(const CIp &Ip, const CWiresxIn
|
||||
uint offset2 = offset;
|
||||
// patch the remaining
|
||||
uint k = 1029U - offset2;
|
||||
::memset(data+offset2, ' ', k);
|
||||
memset(data+offset2, ' ', k);
|
||||
offset2 += k;
|
||||
|
||||
// EOD + CRC
|
||||
@@ -412,7 +412,7 @@ bool CWiresxCmdHandler::ReplyToWiresxAllReqPacket(const CIp &Ip, const CWiresxIn
|
||||
|
||||
// patch the remaining
|
||||
//uint k = 1031U - offset;
|
||||
//::memset(data+offset, ' ', k);
|
||||
//memset(data+offset, ' ', k);
|
||||
//offset += k;
|
||||
|
||||
// and encode the reply
|
||||
@@ -439,17 +439,17 @@ bool CWiresxCmdHandler::ReplyToWiresxConnReqPacket(const CIp &Ip, const CWiresxI
|
||||
RoomId = (uint8_t)(Module - 'A');
|
||||
|
||||
// prepare buffer
|
||||
::memset(data, 0x00U, 110U);
|
||||
::memset(data, ' ', 90U);
|
||||
memset(data, 0x00U, 110U);
|
||||
memset(data, ' ', 90U);
|
||||
|
||||
// seq no
|
||||
data[0U] = m_seqNo;
|
||||
// command
|
||||
::memcpy(data + 1U, CONN_RESP, 4U);
|
||||
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);
|
||||
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
|
||||
@@ -458,17 +458,17 @@ bool CWiresxCmdHandler::ReplyToWiresxConnReqPacket(const CIp &Ip, const CWiresxI
|
||||
|
||||
// refl->m_id
|
||||
::sprintf(item, "%05d", 4001U + RoomId);
|
||||
::memcpy(data + 36U, item, 5U);
|
||||
memcpy(data + 36U, item, 5U);
|
||||
// refl->name
|
||||
::memset(item, ' ', 16U);
|
||||
::memcpy(item, "MODULE", 6U); // K2IE fix for U/C only radios
|
||||
memset(item, ' ', 16U);
|
||||
memcpy(item, "MODULE", 6U); // K2IE fix for U/C only radios
|
||||
item[7] = 'A' + RoomId;
|
||||
::memcpy(data + 41U, item, 16U);
|
||||
memcpy(data + 41U, item, 16U);
|
||||
// refl->count
|
||||
::sprintf(item, "%03d", RoomId + 1);
|
||||
::memcpy(data + 57U, item, 3U);
|
||||
memcpy(data + 57U, item, 3U);
|
||||
// refl->m_desc
|
||||
::memcpy(data + 70U, "Description ", 14U);
|
||||
memcpy(data + 70U, "Description ", 14U);
|
||||
}
|
||||
data[84U] = '0';
|
||||
data[85U] = '0';
|
||||
@@ -497,17 +497,17 @@ bool CWiresxCmdHandler::ReplyToWiresxDiscReqPacket(const CIp &Ip, const CWiresxI
|
||||
uint8_t data[110U];
|
||||
|
||||
// prepare buffer
|
||||
::memset(data, 0x00U, 110U);
|
||||
::memset(data, ' ', 90U);
|
||||
memset(data, 0x00U, 110U);
|
||||
memset(data, ' ', 90U);
|
||||
|
||||
// seq no
|
||||
data[0U] = m_seqNo;
|
||||
// command
|
||||
::memcpy(data + 1U, DISC_RESP, 4U);
|
||||
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);
|
||||
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';
|
||||
@@ -580,11 +580,11 @@ bool CWiresxCmdHandler::EncodeAndSendWiresxPacket(const CIp &Ip, const CBuffer &
|
||||
// Write the header
|
||||
{
|
||||
//header
|
||||
::memcpy(buffer, NET_HEADER, 34U);
|
||||
::memcpy(buffer + 4U, WiresxInfo.GetCallsign(), 10U);
|
||||
::memcpy(buffer + 14U, WiresxInfo.GetNode(), 10U);
|
||||
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);
|
||||
memcpy(buffer + 35U, YSF_SYNC_BYTES, YSF_SYNC_LENGTH_BYTES);
|
||||
// Fich
|
||||
fich.load(DEFAULT_FICH);
|
||||
fich.setFI(YSF_FI_HEADER);
|
||||
@@ -637,7 +637,7 @@ bool CWiresxCmdHandler::EncodeAndSendWiresxPacket(const CIp &Ip, const CBuffer &
|
||||
{
|
||||
uint8_t temp[20U];
|
||||
temp[0U] = 0x00U;
|
||||
::memcpy(temp + 1U, Data.data() + offset, 19U);
|
||||
memcpy(temp + 1U, Data.data() + offset, 19U);
|
||||
payload.writeDataFRModeData2(temp, buffer + 35U);
|
||||
offset += 19U;
|
||||
}
|
||||
@@ -734,7 +734,7 @@ bool CWiresxCmdHandler::DebugTestDecodePacket(const CBuffer &Buffer)
|
||||
{
|
||||
case YSF_FI_HEADER:
|
||||
len = 0;
|
||||
::memset(command, 0x00, sizeof(command));
|
||||
memset(command, 0x00, sizeof(command));
|
||||
std::cout << "Header" << std::endl;
|
||||
break;
|
||||
case YSF_FI_TERMINATOR:
|
||||
|
||||
+19
-19
@@ -27,16 +27,16 @@
|
||||
|
||||
CWiresxInfo::CWiresxInfo()
|
||||
{
|
||||
::memset(m_callsign, ' ', YSF_CALLSIGN_LENGTH);
|
||||
::memset(m_node, ' ', YSF_CALLSIGN_LENGTH);
|
||||
::memset(m_name, ' ', 14);
|
||||
::memset(m_id, ' ', 6);
|
||||
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);
|
||||
memset(m_csd1, '*', 20U);
|
||||
memset(m_csd2, ' ', 20U);
|
||||
memset(m_csd3, ' ', 20U);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,22 +45,22 @@ CWiresxInfo::CWiresxInfo()
|
||||
|
||||
void CWiresxInfo::SetCallsign(const CCallsign &callsign)
|
||||
{
|
||||
::memset(m_callsign, ' ', YSF_CALLSIGN_LENGTH);
|
||||
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));
|
||||
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));
|
||||
memset(m_name, ' ', 14);
|
||||
memcpy(m_name, name, MIN(::strlen(name), 14));
|
||||
UpdateId();
|
||||
}
|
||||
|
||||
@@ -75,13 +75,13 @@ void CWiresxInfo::SetFrequencies(uint txFreq, uint rxFreq)
|
||||
|
||||
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);
|
||||
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)
|
||||
|
||||
@@ -59,7 +59,7 @@ const unsigned int INTERLEAVE_TABLE[] =
|
||||
|
||||
CYSFFICH::CYSFFICH()
|
||||
{
|
||||
::memset(m_fich, 0U, 6U);
|
||||
memset(m_fich, 0U, 6U);
|
||||
}
|
||||
|
||||
bool CYSFFICH::decode(const unsigned char* bytes)
|
||||
@@ -300,5 +300,5 @@ void CYSFFICH::load(const unsigned char* fich)
|
||||
{
|
||||
assert(fich != nullptr);
|
||||
|
||||
::memcpy(m_fich, fich, 4U);
|
||||
memcpy(m_fich, fich, 4U);
|
||||
}
|
||||
@@ -32,7 +32,7 @@ CYsfNodeDirFile g_YsfNodeDir;
|
||||
|
||||
CYsfNodeDirFile::CYsfNodeDirFile()
|
||||
{
|
||||
::memset(&m_LastModTime, 0, sizeof(time_t));
|
||||
memset(&m_LastModTime, 0, sizeof(time_t));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -105,11 +105,11 @@ bool CYsfNodeDirHttp::HttpGet(const char *hostname, const char *filename, int po
|
||||
// get hostname address
|
||||
struct sockaddr_in servaddr;
|
||||
struct hostent *hp;
|
||||
::memset(&servaddr,0,sizeof(servaddr));
|
||||
memset(&servaddr,0,sizeof(servaddr));
|
||||
if( (hp = gethostbyname(hostname)) != nullptr )
|
||||
{
|
||||
// dns resolved
|
||||
::memcpy((char *)&servaddr.sin_addr.s_addr, (char *)hp->h_addr, hp->h_length);
|
||||
memcpy((char *)&servaddr.sin_addr.s_addr, (char *)hp->h_addr, hp->h_length);
|
||||
servaddr.sin_port = htons(port);
|
||||
servaddr.sin_family = AF_INET;
|
||||
|
||||
|
||||
+22
-22
@@ -94,7 +94,7 @@ bool CYSFPayload::processHeaderData(unsigned char* data)
|
||||
unsigned char* p2 = dch;
|
||||
for (unsigned int i = 0U; i < 5U; i++)
|
||||
{
|
||||
::memcpy(p2, p1, 9U);
|
||||
memcpy(p2, p1, 9U);
|
||||
p1 += 18U;
|
||||
p2 += 9U;
|
||||
}
|
||||
@@ -125,13 +125,13 @@ bool CYSFPayload::processHeaderData(unsigned char* data)
|
||||
if (m_dest == nullptr)
|
||||
{
|
||||
m_dest = std::unique_ptr<unsigned char[]>(new unsigned char[YSF_CALLSIGN_LENGTH]);
|
||||
::memcpy(m_dest.get(), output, YSF_CALLSIGN_LENGTH);
|
||||
memcpy(m_dest.get(), output, YSF_CALLSIGN_LENGTH);
|
||||
}
|
||||
|
||||
if (m_source == nullptr)
|
||||
{
|
||||
m_source = std::unique_ptr<unsigned char[]>(new unsigned char[YSF_CALLSIGN_LENGTH]);
|
||||
::memcpy(m_source.get(), output + YSF_CALLSIGN_LENGTH, YSF_CALLSIGN_LENGTH);
|
||||
memcpy(m_source.get(), output + YSF_CALLSIGN_LENGTH, YSF_CALLSIGN_LENGTH);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0U; i < 20U; i++)
|
||||
@@ -165,7 +165,7 @@ bool CYSFPayload::processHeaderData(unsigned char* data)
|
||||
p2 = bytes;
|
||||
for (unsigned int i = 0U; i < 5U; i++)
|
||||
{
|
||||
::memcpy(p1, p2, 9U);
|
||||
memcpy(p1, p2, 9U);
|
||||
p1 += 18U;
|
||||
p2 += 9U;
|
||||
}
|
||||
@@ -175,7 +175,7 @@ bool CYSFPayload::processHeaderData(unsigned char* data)
|
||||
p2 = dch;
|
||||
for (unsigned int i = 0U; i < 5U; i++)
|
||||
{
|
||||
::memcpy(p2, p1, 9U);
|
||||
memcpy(p2, p1, 9U);
|
||||
p1 += 18U;
|
||||
p2 += 9U;
|
||||
}
|
||||
@@ -202,10 +202,10 @@ bool CYSFPayload::processHeaderData(unsigned char* data)
|
||||
output[i] ^= WHITENING_DATA[i];
|
||||
|
||||
if (m_downlink)
|
||||
::memcpy(output + 0U, m_downlink.get(), YSF_CALLSIGN_LENGTH);
|
||||
memcpy(output + 0U, m_downlink.get(), YSF_CALLSIGN_LENGTH);
|
||||
|
||||
if (m_uplink)
|
||||
::memcpy(output + YSF_CALLSIGN_LENGTH, m_uplink.get(), YSF_CALLSIGN_LENGTH);
|
||||
memcpy(output + YSF_CALLSIGN_LENGTH, m_uplink.get(), YSF_CALLSIGN_LENGTH);
|
||||
|
||||
for (unsigned int i = 0U; i < 20U; i++)
|
||||
output[i] ^= WHITENING_DATA[i];
|
||||
@@ -238,7 +238,7 @@ bool CYSFPayload::processHeaderData(unsigned char* data)
|
||||
p2 = bytes;
|
||||
for (unsigned int i = 0U; i < 5U; i++)
|
||||
{
|
||||
::memcpy(p1, p2, 9U);
|
||||
memcpy(p1, p2, 9U);
|
||||
p1 += 18U;
|
||||
p2 += 9U;
|
||||
}
|
||||
@@ -252,7 +252,7 @@ bool CYSFPayload::readDataFRModeData1(const unsigned char* data, unsigned char*
|
||||
assert(data != nullptr);
|
||||
assert(dt != nullptr);
|
||||
|
||||
::memset(dt, ' ', 20U);
|
||||
memset(dt, ' ', 20U);
|
||||
|
||||
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||
|
||||
@@ -262,7 +262,7 @@ bool CYSFPayload::readDataFRModeData1(const unsigned char* data, unsigned char*
|
||||
unsigned char* p2 = dch;
|
||||
for (unsigned int i = 0U; i < 5U; i++)
|
||||
{
|
||||
::memcpy(p2, p1, 9U);
|
||||
memcpy(p2, p1, 9U);
|
||||
p1 += 18U;
|
||||
p2 += 9U;
|
||||
}
|
||||
@@ -292,7 +292,7 @@ bool CYSFPayload::readDataFRModeData1(const unsigned char* data, unsigned char*
|
||||
|
||||
// CUtils::dump(1U, "FR Mode Data 1", output, 20U);
|
||||
|
||||
::memcpy(dt, output, 20U);
|
||||
memcpy(dt, output, 20U);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -303,7 +303,7 @@ bool CYSFPayload::readDataFRModeData2(const unsigned char* data, unsigned char*
|
||||
assert(data != nullptr);
|
||||
assert(dt != nullptr);
|
||||
|
||||
::memset(dt, ' ', 20U);
|
||||
memset(dt, ' ', 20U);
|
||||
|
||||
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||
|
||||
@@ -313,7 +313,7 @@ bool CYSFPayload::readDataFRModeData2(const unsigned char* data, unsigned char*
|
||||
unsigned char* p2 = dch;
|
||||
for (unsigned int i = 0U; i < 5U; i++)
|
||||
{
|
||||
::memcpy(p2, p1, 9U);
|
||||
memcpy(p2, p1, 9U);
|
||||
p1 += 18U;
|
||||
p2 += 9U;
|
||||
}
|
||||
@@ -343,7 +343,7 @@ bool CYSFPayload::readDataFRModeData2(const unsigned char* data, unsigned char*
|
||||
|
||||
// CUtils::dump(1U, "FR Mode Data 2", output, 20U);
|
||||
|
||||
::memcpy(dt, output, 20U);
|
||||
memcpy(dt, output, 20U);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -354,7 +354,7 @@ 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);
|
||||
memcpy(dt_tmp, dt, YSF_CALLSIGN_LENGTH);
|
||||
|
||||
for (unsigned int i = 0U; i < 10U; i++)
|
||||
dt_tmp[i] ^= WHITENING_DATA[i];
|
||||
@@ -389,7 +389,7 @@ void CYSFPayload::writeVDMode2Data(unsigned char* data, const unsigned char* dt)
|
||||
unsigned char* p2 = bytes;
|
||||
for (unsigned int i = 0U; i < 5U; i++)
|
||||
{
|
||||
::memcpy(p1, p2, 5U);
|
||||
memcpy(p1, p2, 5U);
|
||||
p1 += 18U;
|
||||
p2 += 5U;
|
||||
}
|
||||
@@ -409,7 +409,7 @@ bool CYSFPayload::readVDMode1Data(const unsigned char* data, unsigned char* dt)
|
||||
unsigned char* p2 = dch;
|
||||
for (unsigned int i = 0U; i < 5U; i++)
|
||||
{
|
||||
::memcpy(p2, p1, 9U);
|
||||
memcpy(p2, p1, 9U);
|
||||
p1 += 18U;
|
||||
p2 += 9U;
|
||||
}
|
||||
@@ -439,7 +439,7 @@ bool CYSFPayload::readVDMode1Data(const unsigned char* data, unsigned char* dt)
|
||||
|
||||
// CUtils::dump(1U, "V/D Mode 1 Data", output, 20U);
|
||||
|
||||
::memcpy(dt, output, 20U);
|
||||
memcpy(dt, output, 20U);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -459,7 +459,7 @@ bool CYSFPayload::readVDMode2Data(const unsigned char* data, unsigned char* dt)
|
||||
unsigned char* p2 = dch;
|
||||
for (unsigned int i = 0U; i < 5U; i++)
|
||||
{
|
||||
::memcpy(p2, p1, 5U);
|
||||
memcpy(p2, p1, 5U);
|
||||
p1 += 18U;
|
||||
p2 += 5U;
|
||||
}
|
||||
@@ -489,7 +489,7 @@ bool CYSFPayload::readVDMode2Data(const unsigned char* data, unsigned char* dt)
|
||||
|
||||
// CUtils::dump(1U, "V/D Mode 2 Data", output, YSF_CALLSIGN_LENGTH);
|
||||
|
||||
::memcpy(dt, output, YSF_CALLSIGN_LENGTH);
|
||||
memcpy(dt, output, YSF_CALLSIGN_LENGTH);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -547,7 +547,7 @@ void CYSFPayload::writeDataFRModeData1(const unsigned char* dt, unsigned char* d
|
||||
unsigned char* p2 = bytes;
|
||||
for (unsigned int i = 0U; i < 5U; i++)
|
||||
{
|
||||
::memcpy(p1, p2, 9U);
|
||||
memcpy(p1, p2, 9U);
|
||||
p1 += 18U;
|
||||
p2 += 9U;
|
||||
}
|
||||
@@ -594,7 +594,7 @@ void CYSFPayload::writeDataFRModeData2(const unsigned char* dt, unsigned char* d
|
||||
unsigned char* p2 = bytes;
|
||||
for (unsigned int i = 0U; i < 5U; i++)
|
||||
{
|
||||
::memcpy(p1, p2, 9U);
|
||||
memcpy(p1, p2, 9U);
|
||||
p1 += 18U;
|
||||
p2 += 9U;
|
||||
}
|
||||
|
||||
+40
-40
@@ -186,11 +186,11 @@ void CYsfProtocol::Task(void)
|
||||
EncodeServerStatusPacket(&Buffer);
|
||||
Send(Buffer, Ip);
|
||||
}
|
||||
else if ( Buffer.size() == 80 && 0 == ::memcmp(Buffer.data(), "YSFI", 4) )
|
||||
else if ( Buffer.size() == 80 && 0 == memcmp(Buffer.data(), "YSFI", 4) )
|
||||
{
|
||||
// do nothing, it's unneeded information from BlueDV
|
||||
}
|
||||
else if ( Buffer.size() == 50 && 0 == ::memcmp(Buffer.data(), "YSFO", 4) )
|
||||
else if ( Buffer.size() == 50 && 0 == memcmp(Buffer.data(), "YSFO", 4) )
|
||||
{
|
||||
// do nothing, it's unneeded options from BlueDV
|
||||
}
|
||||
@@ -425,10 +425,10 @@ bool CYsfProtocol::IsValidDvHeaderPacket(const CIp &Ip, const CYSFFICH &Fich, co
|
||||
{
|
||||
// build DVHeader
|
||||
char sz[YSF_CALLSIGN_LENGTH+1];
|
||||
::memcpy(sz, &(Buffer.data()[14]), YSF_CALLSIGN_LENGTH);
|
||||
memcpy(sz, &(Buffer.data()[14]), YSF_CALLSIGN_LENGTH);
|
||||
sz[YSF_CALLSIGN_LENGTH] = 0;
|
||||
CCallsign csMY = CCallsign((const char *)sz);
|
||||
::memcpy(sz, &(Buffer.data()[4]), YSF_CALLSIGN_LENGTH);
|
||||
memcpy(sz, &(Buffer.data()[4]), YSF_CALLSIGN_LENGTH);
|
||||
sz[YSF_CALLSIGN_LENGTH] = 0;
|
||||
CCallsign rpt1 = CCallsign((const char *)sz);
|
||||
rpt1.SetModule(YSF_MODULE_ID);
|
||||
@@ -443,8 +443,8 @@ bool CYsfProtocol::IsValidDvHeaderPacket(const CIp &Ip, const CYSFFICH &Fich, co
|
||||
}
|
||||
// and 2 DV Frames
|
||||
{
|
||||
uint8_t uiAmbe[AMBE_SIZE];
|
||||
::memset(uiAmbe, 0x00, sizeof(uiAmbe));
|
||||
uint8_t uiAmbe[9];
|
||||
memset(uiAmbe, 0x00, sizeof(uiAmbe));
|
||||
frames[0] = std::unique_ptr<CDvFramePacket>(new CDvFramePacket(uiAmbe, uiStreamId, Fich.getFN(), 0, 0));
|
||||
frames[1] = std::unique_ptr<CDvFramePacket>(new CDvFramePacket(uiAmbe, uiStreamId, Fich.getFN(), 1, 0));
|
||||
}
|
||||
@@ -466,11 +466,11 @@ bool CYsfProtocol::IsValidDvFramePacket(const CIp &Ip, const CYSFFICH &Fich, con
|
||||
uint32_t uiStreamId = IpToStreamId(Ip);
|
||||
|
||||
// get DV frames
|
||||
uint8_t ambe0[AMBEPLUS_SIZE];
|
||||
uint8_t ambe1[AMBEPLUS_SIZE];
|
||||
uint8_t ambe2[AMBEPLUS_SIZE];
|
||||
uint8_t ambe3[AMBEPLUS_SIZE];
|
||||
uint8_t ambe4[AMBEPLUS_SIZE];
|
||||
uint8_t ambe0[9];
|
||||
uint8_t ambe1[9];
|
||||
uint8_t ambe2[9];
|
||||
uint8_t ambe3[9];
|
||||
uint8_t ambe4[9];
|
||||
uint8_t *ambes[5] = { ambe0, ambe1, ambe2, ambe3, ambe4 };
|
||||
CYsfUtils::DecodeVD2Vchs((unsigned char *)&(Buffer.data()[35]), ambes);
|
||||
|
||||
@@ -499,8 +499,8 @@ bool CYsfProtocol::IsValidDvLastFramePacket(const CIp &Ip, const CYSFFICH &Fich,
|
||||
|
||||
// get DV frames
|
||||
{
|
||||
uint8_t uiAmbe[AMBE_SIZE];
|
||||
::memset(uiAmbe, 0x00, sizeof(uiAmbe));
|
||||
uint8_t uiAmbe[9];
|
||||
memset(uiAmbe, 0x00, sizeof(uiAmbe));
|
||||
oneframe = std::unique_ptr<CDvFramePacket>(new CDvFramePacket(uiAmbe, uiStreamId, Fich.getFN(), 0, 0));
|
||||
lastframe = std::unique_ptr<CDvLastFramePacket>(new CDvLastFramePacket(uiAmbe, uiStreamId, Fich.getFN(), 1, 0));
|
||||
}
|
||||
@@ -532,12 +532,12 @@ bool CYsfProtocol::EncodeDvHeaderPacket(const CDvHeaderPacket &Header, CBuffer *
|
||||
// tag
|
||||
Buffer->Set(tag, sizeof(tag));
|
||||
// rpt1
|
||||
::memset(sz, ' ', sizeof(sz));
|
||||
memset(sz, ' ', sizeof(sz));
|
||||
Header.GetRpt1Callsign().GetCallsignString(sz);
|
||||
sz[::strlen(sz)] = ' ';
|
||||
Buffer->Append((uint8_t *)sz, YSF_CALLSIGN_LENGTH);
|
||||
// my
|
||||
::memset(sz, ' ', sizeof(sz));
|
||||
memset(sz, ' ', sizeof(sz));
|
||||
Header.GetMyCallsign().GetCallsignString(sz);
|
||||
sz[::strlen(sz)] = ' ';
|
||||
Buffer->Append((uint8_t *)sz, YSF_CALLSIGN_LENGTH);
|
||||
@@ -563,11 +563,11 @@ bool CYsfProtocol::EncodeDvHeaderPacket(const CDvHeaderPacket &Header, CBuffer *
|
||||
Buffer->Append(fichd, YSF_FICH_LENGTH_BYTES);
|
||||
// payload
|
||||
unsigned char csd1[20U], csd2[20U];
|
||||
::memset(csd1, '*', YSF_CALLSIGN_LENGTH);
|
||||
::memset(csd1 + YSF_CALLSIGN_LENGTH, ' ', YSF_CALLSIGN_LENGTH);
|
||||
memset(csd1, '*', YSF_CALLSIGN_LENGTH);
|
||||
memset(csd1 + YSF_CALLSIGN_LENGTH, ' ', YSF_CALLSIGN_LENGTH);
|
||||
Header.GetMyCallsign().GetCallsignString(sz);
|
||||
::memcpy(csd1 + YSF_CALLSIGN_LENGTH, sz, ::strlen(sz));
|
||||
::memset(csd2, ' ', YSF_CALLSIGN_LENGTH + YSF_CALLSIGN_LENGTH);
|
||||
memcpy(csd1 + YSF_CALLSIGN_LENGTH, sz, ::strlen(sz));
|
||||
memset(csd2, ' ', YSF_CALLSIGN_LENGTH + YSF_CALLSIGN_LENGTH);
|
||||
CYSFPayload payload;
|
||||
uint8_t temp[120];
|
||||
payload.writeHeader(temp, csd1, csd2);
|
||||
@@ -588,12 +588,12 @@ bool CYsfProtocol::EncodeDvPacket(const CDvHeaderPacket &Header, const CDvFrameP
|
||||
// tag
|
||||
Buffer->Set(tag, sizeof(tag));
|
||||
// rpt1
|
||||
::memset(sz, ' ', sizeof(sz));
|
||||
memset(sz, ' ', sizeof(sz));
|
||||
Header.GetRpt1Callsign().GetCallsignString(sz);
|
||||
sz[::strlen(sz)] = ' ';
|
||||
Buffer->Append((uint8_t *)sz, YSF_CALLSIGN_LENGTH);
|
||||
// my
|
||||
::memset(sz, ' ', sizeof(sz));
|
||||
memset(sz, ' ', sizeof(sz));
|
||||
Header.GetMyCallsign().GetCallsignString(sz);
|
||||
sz[::strlen(sz)] = ' ';
|
||||
Buffer->Append((uint8_t *)sz, YSF_CALLSIGN_LENGTH);
|
||||
@@ -619,11 +619,11 @@ bool CYsfProtocol::EncodeDvPacket(const CDvHeaderPacket &Header, const CDvFrameP
|
||||
// payload
|
||||
CYSFPayload payload;
|
||||
uint8_t temp[120];
|
||||
::memset(temp, 0x00, sizeof(temp));
|
||||
memset(temp, 0x00, sizeof(temp));
|
||||
// DV
|
||||
for ( int i = 0; i < 5; i++ )
|
||||
{
|
||||
CYsfUtils::EncodeVD2Vch((unsigned char *)DvFrames[i].GetAmbePlus(), temp+35+(18*i));
|
||||
CYsfUtils::EncodeVD2Vch((unsigned char *)DvFrames[i].GetCodecData(ECodecType::dmr), temp+35+(18*i));
|
||||
}
|
||||
// data
|
||||
switch (DvFrames[0].GetYsfPacketId())
|
||||
@@ -634,14 +634,14 @@ bool CYsfProtocol::EncodeDvPacket(const CDvHeaderPacket &Header, const CDvFrameP
|
||||
break;
|
||||
case 1:
|
||||
// Src
|
||||
::memset(sz, ' ', sizeof(sz));
|
||||
memset(sz, ' ', sizeof(sz));
|
||||
Header.GetMyCallsign().GetCallsignString(sz);
|
||||
sz[::strlen(sz)] = ' ';
|
||||
payload.writeVDMode2Data(temp, (const unsigned char*)sz);
|
||||
break;
|
||||
case 2:
|
||||
// Down
|
||||
::memset(sz, ' ', sizeof(sz));
|
||||
memset(sz, ' ', sizeof(sz));
|
||||
Header.GetRpt1Callsign().GetCallsignString(sz);
|
||||
sz[::strlen(sz)] = ' ';
|
||||
payload.writeVDMode2Data(temp, (const unsigned char*)sz);
|
||||
@@ -679,12 +679,12 @@ bool CYsfProtocol::EncodeDvLastPacket(const CDvHeaderPacket &Header, CBuffer *Bu
|
||||
// tag
|
||||
Buffer->Set(tag, sizeof(tag));
|
||||
// rpt1
|
||||
::memset(sz, ' ', sizeof(sz));
|
||||
memset(sz, ' ', sizeof(sz));
|
||||
Header.GetRpt1Callsign().GetCallsignString(sz);
|
||||
sz[::strlen(sz)] = ' ';
|
||||
Buffer->Append((uint8_t *)sz, YSF_CALLSIGN_LENGTH);
|
||||
// my
|
||||
::memset(sz, ' ', sizeof(sz));
|
||||
memset(sz, ' ', sizeof(sz));
|
||||
Header.GetMyCallsign().GetCallsignString(sz);
|
||||
sz[::strlen(sz)] = ' ';
|
||||
Buffer->Append((uint8_t *)sz, YSF_CALLSIGN_LENGTH);
|
||||
@@ -710,11 +710,11 @@ bool CYsfProtocol::EncodeDvLastPacket(const CDvHeaderPacket &Header, CBuffer *Bu
|
||||
Buffer->Append(fichd, YSF_FICH_LENGTH_BYTES);
|
||||
// payload
|
||||
unsigned char csd1[20U], csd2[20U];
|
||||
::memset(csd1, '*', YSF_CALLSIGN_LENGTH);
|
||||
::memset(csd1 + YSF_CALLSIGN_LENGTH, ' ', YSF_CALLSIGN_LENGTH);
|
||||
memset(csd1, '*', YSF_CALLSIGN_LENGTH);
|
||||
memset(csd1 + YSF_CALLSIGN_LENGTH, ' ', YSF_CALLSIGN_LENGTH);
|
||||
Header.GetMyCallsign().GetCallsignString(sz);
|
||||
::memcpy(csd1 + YSF_CALLSIGN_LENGTH, sz, ::strlen(sz));
|
||||
::memset(csd2, ' ', YSF_CALLSIGN_LENGTH + YSF_CALLSIGN_LENGTH);
|
||||
memcpy(csd1 + YSF_CALLSIGN_LENGTH, sz, ::strlen(sz));
|
||||
memset(csd2, ' ', YSF_CALLSIGN_LENGTH + YSF_CALLSIGN_LENGTH);
|
||||
CYSFPayload payload;
|
||||
uint8_t temp[120];
|
||||
payload.writeHeader(temp, csd1, csd2);
|
||||
@@ -793,35 +793,35 @@ bool CYsfProtocol::IsValidwirexPacket(const CBuffer &Buffer, CYSFFICH *Fich, CCa
|
||||
{
|
||||
// get argument
|
||||
char buffer[4U];
|
||||
::memcpy(buffer, command + 5U + 2U, 3U);
|
||||
memcpy(buffer, command + 5U + 2U, 3U);
|
||||
buffer[3U] = 0x00U;
|
||||
*Arg = ::atoi(buffer);
|
||||
// and decode command
|
||||
if (::memcmp(command + 1U, DX_REQ, 3U) == 0)
|
||||
if (memcmp(command + 1U, DX_REQ, 3U) == 0)
|
||||
{
|
||||
*Cmd = WIRESX_CMD_DX_REQ;
|
||||
*Arg = 0;
|
||||
}
|
||||
else if (::memcmp(command + 1U, ALL_REQ, 3U) == 0)
|
||||
else if (memcmp(command + 1U, ALL_REQ, 3U) == 0)
|
||||
{
|
||||
// argument is start index of list
|
||||
if ( *Arg > 0 )
|
||||
(*Arg)--;
|
||||
// check if all or search
|
||||
if ( ::memcmp(command + 5U, "01", 2) == 0 )
|
||||
if ( memcmp(command + 5U, "01", 2) == 0 )
|
||||
{
|
||||
*Cmd = WIRESX_CMD_ALL_REQ;
|
||||
}
|
||||
else if ( ::memcmp(command + 5U, "11", 2) == 0 )
|
||||
else if ( memcmp(command + 5U, "11", 2) == 0 )
|
||||
{
|
||||
*Cmd = WIRESX_CMD_SEARCH_REQ;
|
||||
}
|
||||
}
|
||||
else if (::memcmp(command + 1U, CONN_REQ, 3U) == 0)
|
||||
else if (memcmp(command + 1U, CONN_REQ, 3U) == 0)
|
||||
{
|
||||
*Cmd = WIRESX_CMD_CONN_REQ;
|
||||
}
|
||||
else if (::memcmp(command + 1U, DISC_REQ, 3U) == 0)
|
||||
else if (memcmp(command + 1U, DISC_REQ, 3U) == 0)
|
||||
{
|
||||
*Cmd = WIRESX_CMD_DISC_REQ;
|
||||
*Arg = 0;
|
||||
@@ -860,7 +860,7 @@ bool CYsfProtocol::EncodeServerStatusPacket(CBuffer *Buffer) const
|
||||
// tag
|
||||
Buffer->Set(tag, sizeof(tag));
|
||||
// hash
|
||||
::memset(callsign, ' ', sizeof(callsign));
|
||||
memset(callsign, ' ', sizeof(callsign));
|
||||
g_Reflector.GetCallsign().GetCallsign(callsign);
|
||||
char sz[16];
|
||||
::sprintf(sz, "%05u", CalcHash(callsign, 16) % 100000U);
|
||||
@@ -938,7 +938,7 @@ bool CYsfProtocol::DebugTestDecodePacket(const CBuffer &Buffer)
|
||||
{
|
||||
case YSF_FI_HEADER:
|
||||
len = 0;
|
||||
::memset(command, 0x00, sizeof(command));
|
||||
memset(command, 0x00, sizeof(command));
|
||||
std::cout << "Header" << std::endl;
|
||||
break;
|
||||
case YSF_FI_TERMINATOR:
|
||||
|
||||
@@ -562,7 +562,7 @@ void CYsfUtils::DecodeVD2Vchs(uint8_t *data, uint8_t **ambe)
|
||||
WRITE_BIT(v_dmr, cPos, dat_c & MASK);
|
||||
}
|
||||
|
||||
::memcpy(ambe[frame++], v_dmr, 9);
|
||||
memcpy(ambe[frame++], v_dmr, 9);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -602,8 +602,8 @@ void CYsfUtils::EncodeVD2Vch(uint8_t *ambe, uint8_t *data)
|
||||
// and to vch
|
||||
unsigned char vch[13U];
|
||||
unsigned char ysfFrame[13U];
|
||||
::memset(vch, 0U, 13U);
|
||||
::memset(ysfFrame, 0, 13U);
|
||||
memset(vch, 0U, 13U);
|
||||
memset(ysfFrame, 0, 13U);
|
||||
|
||||
unsigned int dat_a = a >> 12;
|
||||
|
||||
@@ -656,5 +656,5 @@ void CYsfUtils::EncodeVD2Vch(uint8_t *ambe, uint8_t *data)
|
||||
WRITE_BIT(ysfFrame, n, s);
|
||||
}
|
||||
|
||||
::memcpy(data, ysfFrame, 13U);
|
||||
memcpy(data, ysfFrame, 13U);
|
||||
}
|
||||
Reference in new issue
Block a user