mirror of https://github.com/ShaYmez/xlxd.git
xlxd 2.2.1
* auto-reload of deride DB * interlink protocol v2.0
This commit is contained in:
parent
ed24a5b8cb
commit
32a437c138
|
@ -25,7 +25,8 @@
|
|||
#include "main.h"
|
||||
#include <string.h>
|
||||
#include <cctype>
|
||||
#include "cdmriddir.h"
|
||||
#include "cdmriddirfile.h"
|
||||
#include "cdmriddirhttp.h"
|
||||
#include "ccallsign.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -60,16 +61,24 @@ CCallsign::CCallsign(const char *sz, uint32 dmrid)
|
|||
// dmrid ok ?
|
||||
if ( m_uiDmrid == 0 )
|
||||
{
|
||||
m_uiDmrid = g_DmridDir.FindDmrid(*this);
|
||||
g_DmridDir.Lock();
|
||||
{
|
||||
m_uiDmrid = g_DmridDir.FindDmrid(*this);
|
||||
}
|
||||
g_DmridDir.Unlock();
|
||||
}
|
||||
}
|
||||
else if ( m_uiDmrid != 0 )
|
||||
{
|
||||
const CCallsign *callsign = g_DmridDir.FindCallsign(m_uiDmrid);
|
||||
if ( callsign != NULL )
|
||||
{
|
||||
::memcpy(m_Callsign, callsign->m_Callsign, sizeof(m_Callsign));
|
||||
}
|
||||
g_DmridDir.Lock();
|
||||
{
|
||||
const CCallsign *callsign = g_DmridDir.FindCallsign(m_uiDmrid);
|
||||
if ( callsign != NULL )
|
||||
{
|
||||
::memcpy(m_Callsign, callsign->m_Callsign, sizeof(m_Callsign));
|
||||
}
|
||||
}
|
||||
g_DmridDir.Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -151,7 +160,11 @@ void CCallsign::SetCallsign(const char *sz, bool UpdateDmrid)
|
|||
// and update dmrid
|
||||
if ( UpdateDmrid )
|
||||
{
|
||||
m_uiDmrid = g_DmridDir.FindDmrid(*this);
|
||||
g_DmridDir.Lock();
|
||||
{
|
||||
m_uiDmrid = g_DmridDir.FindDmrid(*this);
|
||||
}
|
||||
g_DmridDir.Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -174,7 +187,11 @@ void CCallsign::SetCallsign(const uint8 *buffer, int len, bool UpdateDmrid)
|
|||
}
|
||||
if ( UpdateDmrid )
|
||||
{
|
||||
m_uiDmrid = g_DmridDir.FindDmrid(*this);
|
||||
g_DmridDir.Lock();
|
||||
{
|
||||
m_uiDmrid = g_DmridDir.FindDmrid(*this);
|
||||
}
|
||||
g_DmridDir.Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,11 +200,15 @@ void CCallsign::SetDmrid(uint32 dmrid, bool UpdateCallsign)
|
|||
m_uiDmrid = dmrid;
|
||||
if ( UpdateCallsign )
|
||||
{
|
||||
const CCallsign *callsign = g_DmridDir.FindCallsign(dmrid);
|
||||
if ( callsign != NULL )
|
||||
{
|
||||
::memcpy(m_Callsign, callsign->m_Callsign, sizeof(m_Callsign));
|
||||
}
|
||||
g_DmridDir.Lock();
|
||||
{
|
||||
const CCallsign *callsign = g_DmridDir.FindCallsign(dmrid);
|
||||
if ( callsign != NULL )
|
||||
{
|
||||
::memcpy(m_Callsign, callsign->m_Callsign, sizeof(m_Callsign));
|
||||
}
|
||||
}
|
||||
g_DmridDir.Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
CCallsignList::CCallsignList()
|
||||
{
|
||||
m_Filename = NULL;
|
||||
::memset(&m_LastModTime, 0, sizeof(CCallsignList));
|
||||
::memset(&m_LastModTime, 0, sizeof(time_t));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -26,9 +26,95 @@
|
|||
#include "main.h"
|
||||
#include "creflector.h"
|
||||
#include "cdmriddir.h"
|
||||
#include "cdmriddirfile.h"
|
||||
#include "cdmriddirhttp.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructor & destructor
|
||||
|
||||
CDmridDir::CDmridDir()
|
||||
{
|
||||
m_bStopThread = false;
|
||||
m_pThread = NULL;
|
||||
}
|
||||
|
||||
CDmridDir::~CDmridDir()
|
||||
{
|
||||
// kill threads
|
||||
m_bStopThread = true;
|
||||
if ( m_pThread != NULL )
|
||||
{
|
||||
m_pThread->join();
|
||||
delete m_pThread;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CDmridDir g_DmridDir;
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// init & close
|
||||
|
||||
bool CDmridDir::Init(void)
|
||||
{
|
||||
// load content
|
||||
Reload();
|
||||
|
||||
// reset stop flag
|
||||
m_bStopThread = false;
|
||||
|
||||
// start thread;
|
||||
m_pThread = new std::thread(CDmridDir::Thread, this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CDmridDir::Close(void)
|
||||
{
|
||||
m_bStopThread = true;
|
||||
if ( m_pThread != NULL )
|
||||
{
|
||||
m_pThread->join();
|
||||
delete m_pThread;
|
||||
m_pThread = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// thread
|
||||
|
||||
void CDmridDir::Thread(CDmridDir *This)
|
||||
{
|
||||
while ( !This->m_bStopThread )
|
||||
{
|
||||
// Wait 30 seconds
|
||||
CTimePoint::TaskSleepFor(DMRIDDB_REFRESH_RATE * 60000);
|
||||
|
||||
// have lists files changed ?
|
||||
if ( This->NeedReload() )
|
||||
{
|
||||
This->Reload();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Reload
|
||||
|
||||
bool CDmridDir::Reload(void)
|
||||
{
|
||||
CBuffer buffer;
|
||||
bool ok = false;
|
||||
|
||||
if ( LoadContent(&buffer) )
|
||||
{
|
||||
Lock();
|
||||
{
|
||||
ok = RefreshContent(buffer);
|
||||
}
|
||||
Unlock();
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// find
|
||||
|
@ -53,218 +139,6 @@ uint32 CDmridDir::FindDmrid(const CCallsign &callsign)
|
|||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// refresh
|
||||
|
||||
#if (DMRIDDB_USE_RLX_SERVER == 1)
|
||||
bool CDmridDir::RefreshContent(void)
|
||||
{
|
||||
bool ok = true;
|
||||
CBuffer buffer;
|
||||
|
||||
// get file from xlxapi server
|
||||
if ( (ok = HttpGet("xlxapi.rlx.lu", "api/exportdmr.php", 80, &buffer)) )
|
||||
{
|
||||
// clear directory
|
||||
m_CallsignMap.clear();
|
||||
m_DmridMap.clear();
|
||||
|
||||
// scan file
|
||||
if ( buffer.size() > 0 )
|
||||
{
|
||||
char *ptr1 = (char *)buffer.data();
|
||||
char *ptr2;
|
||||
// get next line
|
||||
while ( (ptr2 = ::strchr(ptr1, '\n')) != NULL )
|
||||
{
|
||||
*ptr2 = 0;
|
||||
// get items
|
||||
char *dmrid;
|
||||
char *callsign;
|
||||
if ( ((dmrid = ::strtok(ptr1, ";")) != NULL) && IsValidDmrid(dmrid) )
|
||||
{
|
||||
if ( ((callsign = ::strtok(NULL, ";")) != NULL) )
|
||||
{
|
||||
// new entry
|
||||
uint32 ui = atoi(dmrid);
|
||||
CCallsign cs(callsign, ui);
|
||||
if ( cs.IsValid() )
|
||||
{
|
||||
m_CallsignMap.insert(std::pair<uint32,CCallsign>(ui, cs));
|
||||
m_DmridMap.insert(std::pair<CCallsign,uint32>(cs,ui));
|
||||
}
|
||||
}
|
||||
}
|
||||
// next line
|
||||
ptr1 = ptr2+1;
|
||||
}
|
||||
// done
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
// report
|
||||
std::cout << "Read " << m_DmridMap.size() << " DMR id from online database " << std::endl;
|
||||
|
||||
// done
|
||||
return ok;
|
||||
}
|
||||
#else
|
||||
bool CDmridDir::RefreshContent(void)
|
||||
{
|
||||
bool ok = true;
|
||||
CBuffer buffer;
|
||||
std::ifstream file;
|
||||
std::streampos size;
|
||||
|
||||
// open file
|
||||
file.open(DMRIDDB_PATH, std::ios::in | std::ios::binary | std::ios::ate);
|
||||
if ( file.is_open() )
|
||||
{
|
||||
// clear directory
|
||||
m_CallsignMap.clear();
|
||||
m_DmridMap.clear();
|
||||
|
||||
// scan file
|
||||
size = file.tellg();
|
||||
if ( size > 0 )
|
||||
{
|
||||
// read file into buffer
|
||||
buffer.resize((int)size+1);
|
||||
file.seekg (0, std::ios::beg);
|
||||
file.read((char *)buffer.data(), (int)size);
|
||||
|
||||
// close file
|
||||
file.close();
|
||||
|
||||
// crack it
|
||||
char *ptr1 = (char *)buffer.data();
|
||||
char *ptr2;
|
||||
// get next line
|
||||
while ( (ptr2 = ::strchr(ptr1, '\n')) != NULL )
|
||||
{
|
||||
*ptr2 = 0;
|
||||
// get items
|
||||
char *dmrid;
|
||||
char *callsign;
|
||||
if ( ((dmrid = ::strtok(ptr1, ";")) != NULL) && IsValidDmrid(dmrid) )
|
||||
{
|
||||
if ( ((callsign = ::strtok(NULL, ";")) != NULL) )
|
||||
{
|
||||
// new entry
|
||||
uint32 ui = atoi(dmrid);
|
||||
CCallsign cs(callsign, ui);
|
||||
if ( cs.IsValid() )
|
||||
{
|
||||
m_CallsignMap.insert(std::pair<uint32,CCallsign>(ui, cs));
|
||||
m_DmridMap.insert(std::pair<CCallsign,uint32>(cs,ui));
|
||||
}
|
||||
}
|
||||
}
|
||||
// next line
|
||||
ptr1 = ptr2+1;
|
||||
}
|
||||
// done
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
// report
|
||||
std::cout << "Read " << m_DmridMap.size() << " DMR id from online database " << std::endl;
|
||||
|
||||
// done
|
||||
return ok;
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// httpd helpers
|
||||
|
||||
#define DMRID_HTTPGET_SIZEMAX (256)
|
||||
#define DMRID_TEXTFILE_SIZEMAX (10*1024*1024)
|
||||
|
||||
bool CDmridDir::HttpGet(const char *hostname, const char *filename, int port, CBuffer *buffer)
|
||||
{
|
||||
bool ok = false;
|
||||
int sock_id;
|
||||
|
||||
// open socket
|
||||
if ( (sock_id = ::socket(AF_INET, SOCK_STREAM, 0)) >= 0 )
|
||||
{
|
||||
// get hostname address
|
||||
struct sockaddr_in servaddr;
|
||||
struct hostent *hp;
|
||||
::memset(&servaddr,0,sizeof(servaddr));
|
||||
if( (hp = gethostbyname(hostname)) != NULL )
|
||||
{
|
||||
// dns resolved
|
||||
::memcpy((char *)&servaddr.sin_addr.s_addr, (char *)hp->h_addr, hp->h_length);
|
||||
servaddr.sin_port = htons(port);
|
||||
servaddr.sin_family = AF_INET;
|
||||
|
||||
// connect
|
||||
if ( ::connect(sock_id, (struct sockaddr *)&servaddr, sizeof(servaddr)) == 0)
|
||||
{
|
||||
// send the GET request
|
||||
char request[DMRID_HTTPGET_SIZEMAX];
|
||||
::sprintf(request, "GET /%s HTTP/1.0\r\nFrom: %s\r\nUser-Agent: xlxd\r\n\r\n",
|
||||
filename, (const char *)g_Reflector.GetCallsign());
|
||||
::write(sock_id, request, strlen(request));
|
||||
|
||||
// config receive timeouts
|
||||
fd_set read_set;
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = 5;
|
||||
timeout.tv_usec = 0;
|
||||
FD_ZERO(&read_set);
|
||||
FD_SET(sock_id, &read_set);
|
||||
|
||||
// get the reply back
|
||||
buffer->clear();
|
||||
bool done = false;
|
||||
do
|
||||
{
|
||||
char buf[1440];
|
||||
ssize_t len = 0;
|
||||
select(sock_id+1, &read_set, NULL, NULL, &timeout);
|
||||
//if ( (ret > 0) || ((ret < 0) && (errno == EINPROGRESS)) )
|
||||
//if ( ret >= 0 )
|
||||
//{
|
||||
usleep(5000);
|
||||
len = read(sock_id, buf, 1440);
|
||||
if ( len > 0 )
|
||||
{
|
||||
buffer->Append((uint8 *)buf, (int)len);
|
||||
ok = true;
|
||||
}
|
||||
//}
|
||||
done = (len <= 0);
|
||||
|
||||
} while (!done);
|
||||
buffer->Append((uint8)0);
|
||||
|
||||
// and disconnect
|
||||
close(sock_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Cannot establish connection with host " << hostname << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Host " << hostname << " not found" << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Failed to open wget socket" << std::endl;
|
||||
}
|
||||
|
||||
// done
|
||||
return ok;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// syntax helpers
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include "cbuffer.h"
|
||||
#include "ccallsign.h"
|
||||
|
||||
|
||||
// compare function for std::map::find
|
||||
|
||||
struct CallsignCompare
|
||||
|
@ -48,31 +47,49 @@ class CDmridDir
|
|||
{
|
||||
public:
|
||||
// constructor
|
||||
CDmridDir() {}
|
||||
CDmridDir();
|
||||
|
||||
// destructor
|
||||
~CDmridDir() {}
|
||||
~CDmridDir();
|
||||
|
||||
// init & close
|
||||
virtual bool Init(void);
|
||||
virtual void Close(void);
|
||||
|
||||
// locks
|
||||
void Lock(void) { m_Mutex.lock(); }
|
||||
void Unlock(void) { m_Mutex.unlock(); }
|
||||
|
||||
// refresh
|
||||
bool RefreshContent(void);
|
||||
virtual bool LoadContent(CBuffer *) { return false; }
|
||||
virtual bool RefreshContent(const CBuffer &) { return false; }
|
||||
|
||||
// find
|
||||
const CCallsign *FindCallsign(uint32);
|
||||
uint32 FindDmrid(const CCallsign &);
|
||||
|
||||
protected:
|
||||
// httpd helpers
|
||||
bool HttpGet(const char *, const char *, int, CBuffer *);
|
||||
|
||||
// syntax helpers
|
||||
// thread
|
||||
static void Thread(CDmridDir *);
|
||||
|
||||
// reload helpers
|
||||
bool Reload(void);
|
||||
virtual bool NeedReload(void) { return false; }
|
||||
bool IsValidDmrid(const char *);
|
||||
|
||||
protected:
|
||||
// directory
|
||||
// data
|
||||
std::map <uint32, CCallsign> m_CallsignMap;
|
||||
std::map <CCallsign, uint32, CallsignCompare> m_DmridMap;
|
||||
|
||||
// Lock()
|
||||
std::mutex m_Mutex;
|
||||
|
||||
// thread
|
||||
bool m_bStopThread;
|
||||
std::thread *m_pThread;
|
||||
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif /* cdmriddir_h */
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
//
|
||||
// cdmriddirfile.cpp
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 29/12/2017.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include "main.h"
|
||||
#include "cdmriddirfile.h"
|
||||
|
||||
|
||||
#if (DMRIDDB_USE_RLX_SERVER == 0)
|
||||
CDmridDirFile g_DmridDir;
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructor & destructor
|
||||
|
||||
CDmridDirFile::CDmridDirFile()
|
||||
{
|
||||
::memset(&m_LastModTime, 0, sizeof(time_t));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// init & close
|
||||
|
||||
bool CDmridDirFile::Init(void)
|
||||
{
|
||||
return CDmridDir::Init();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// refresh
|
||||
|
||||
bool CDmridDirFile::NeedReload(void)
|
||||
{
|
||||
bool needReload = false;
|
||||
|
||||
time_t time;
|
||||
if ( GetLastModTime(&time) )
|
||||
{
|
||||
needReload = time != m_LastModTime;
|
||||
}
|
||||
return needReload;
|
||||
}
|
||||
|
||||
bool CDmridDirFile::LoadContent(CBuffer *buffer)
|
||||
{
|
||||
bool ok = false;
|
||||
std::ifstream file;
|
||||
std::streampos size;
|
||||
|
||||
// open file
|
||||
file.open(DMRIDDB_PATH, std::ios::in | std::ios::binary | std::ios::ate);
|
||||
if ( file.is_open() )
|
||||
{
|
||||
// read file
|
||||
size = file.tellg();
|
||||
if ( size > 0 )
|
||||
{
|
||||
// read file into buffer
|
||||
buffer->resize((int)size+1);
|
||||
file.seekg (0, std::ios::beg);
|
||||
file.read((char *)buffer->data(), (int)size);
|
||||
|
||||
// close file
|
||||
file.close();
|
||||
|
||||
// update time
|
||||
GetLastModTime(&m_LastModTime);
|
||||
|
||||
// done
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
// done
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool CDmridDirFile::RefreshContent(const CBuffer &buffer)
|
||||
{
|
||||
bool ok = false;
|
||||
|
||||
// clear directory
|
||||
m_CallsignMap.clear();
|
||||
m_DmridMap.clear();
|
||||
|
||||
// scan buffer
|
||||
if ( buffer.size() > 0 )
|
||||
{
|
||||
// crack it
|
||||
char *ptr1 = (char *)buffer.data();
|
||||
char *ptr2;
|
||||
|
||||
// get next line
|
||||
while ( (ptr2 = ::strchr(ptr1, '\n')) != NULL )
|
||||
{
|
||||
*ptr2 = 0;
|
||||
// get items
|
||||
char *dmrid;
|
||||
char *callsign;
|
||||
if ( ((dmrid = ::strtok(ptr1, ";")) != NULL) && IsValidDmrid(dmrid) )
|
||||
{
|
||||
if ( ((callsign = ::strtok(NULL, ";")) != NULL) )
|
||||
{
|
||||
// new entry
|
||||
uint32 ui = atoi(dmrid);
|
||||
CCallsign cs(callsign, ui);
|
||||
if ( cs.IsValid() )
|
||||
{
|
||||
m_CallsignMap.insert(std::pair<uint32,CCallsign>(ui, cs));
|
||||
m_DmridMap.insert(std::pair<CCallsign,uint32>(cs,ui));
|
||||
}
|
||||
}
|
||||
}
|
||||
// next line
|
||||
ptr1 = ptr2+1;
|
||||
}
|
||||
|
||||
// done
|
||||
ok = true;
|
||||
}
|
||||
|
||||
// report
|
||||
std::cout << "Read " << m_DmridMap.size() << " DMR id from file " << DMRIDDB_PATH << std::endl;
|
||||
|
||||
// done
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
bool CDmridDirFile::GetLastModTime(time_t *time)
|
||||
{
|
||||
bool ok = false;
|
||||
|
||||
struct stat fileStat;
|
||||
if( ::stat(DMRIDDB_PATH, &fileStat) != -1 )
|
||||
{
|
||||
*time = fileStat.st_mtime;
|
||||
ok = true;
|
||||
}
|
||||
return ok;
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
//
|
||||
// cdmrididirfile.h
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 29/12/2017.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef cdmrididirfile_h
|
||||
#define cdmrididirfile_h
|
||||
|
||||
#include "cdmriddir.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CDmridDirFile : public CDmridDir
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CDmridDirFile();
|
||||
|
||||
// destructor
|
||||
~CDmridDirFile() {}
|
||||
|
||||
// init & close
|
||||
bool Init(void);
|
||||
|
||||
// refresh
|
||||
bool LoadContent(CBuffer *);
|
||||
bool RefreshContent(const CBuffer &);
|
||||
|
||||
protected:
|
||||
// reload helpers
|
||||
bool NeedReload(void);
|
||||
bool GetLastModTime(time_t *);
|
||||
|
||||
protected:
|
||||
// data
|
||||
time_t m_LastModTime;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#endif /* cdmrididirfile_h */
|
|
@ -0,0 +1,182 @@
|
|||
//
|
||||
// cdmriddirhttp.cpp
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 29/12/2017.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include <string.h>
|
||||
#include "main.h"
|
||||
#include "creflector.h"
|
||||
#include "cdmriddirhttp.h"
|
||||
|
||||
#if (DMRIDDB_USE_RLX_SERVER == 1)
|
||||
CDmridDirHttp g_DmridDir;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// refresh
|
||||
|
||||
bool CDmridDirHttp::LoadContent(CBuffer *buffer)
|
||||
{
|
||||
// get file from xlxapi server
|
||||
return HttpGet("xlxapi.rlx.lu", "api/exportdmr.php", 80, buffer);
|
||||
}
|
||||
|
||||
bool CDmridDirHttp::RefreshContent(const CBuffer &buffer)
|
||||
{
|
||||
bool ok = false;
|
||||
|
||||
// clear directory
|
||||
m_CallsignMap.clear();
|
||||
m_DmridMap.clear();
|
||||
|
||||
// scan file
|
||||
if ( buffer.size() > 0 )
|
||||
{
|
||||
char *ptr1 = (char *)buffer.data();
|
||||
char *ptr2;
|
||||
// get next line
|
||||
while ( (ptr2 = ::strchr(ptr1, '\n')) != NULL )
|
||||
{
|
||||
*ptr2 = 0;
|
||||
// get items
|
||||
char *dmrid;
|
||||
char *callsign;
|
||||
if ( ((dmrid = ::strtok(ptr1, ";")) != NULL) && IsValidDmrid(dmrid) )
|
||||
{
|
||||
if ( ((callsign = ::strtok(NULL, ";")) != NULL) )
|
||||
{
|
||||
// new entry
|
||||
uint32 ui = atoi(dmrid);
|
||||
CCallsign cs(callsign, ui);
|
||||
if ( cs.IsValid() )
|
||||
{
|
||||
m_CallsignMap.insert(std::pair<uint32,CCallsign>(ui, cs));
|
||||
m_DmridMap.insert(std::pair<CCallsign,uint32>(cs,ui));
|
||||
}
|
||||
}
|
||||
}
|
||||
// next line
|
||||
ptr1 = ptr2+1;
|
||||
}
|
||||
// done
|
||||
ok = true;
|
||||
}
|
||||
|
||||
// report
|
||||
std::cout << "Read " << m_DmridMap.size() << " DMR id from xlxapi.rlx.lu database " << std::endl;
|
||||
|
||||
// done
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// httpd helpers
|
||||
|
||||
#define DMRID_HTTPGET_SIZEMAX (256)
|
||||
#define DMRID_TEXTFILE_SIZEMAX (10*1024*1024)
|
||||
|
||||
bool CDmridDirHttp::HttpGet(const char *hostname, const char *filename, int port, CBuffer *buffer)
|
||||
{
|
||||
bool ok = false;
|
||||
int sock_id;
|
||||
|
||||
// open socket
|
||||
if ( (sock_id = ::socket(AF_INET, SOCK_STREAM, 0)) >= 0 )
|
||||
{
|
||||
// get hostname address
|
||||
struct sockaddr_in servaddr;
|
||||
struct hostent *hp;
|
||||
::memset(&servaddr,0,sizeof(servaddr));
|
||||
if( (hp = gethostbyname(hostname)) != NULL )
|
||||
{
|
||||
// dns resolved
|
||||
::memcpy((char *)&servaddr.sin_addr.s_addr, (char *)hp->h_addr, hp->h_length);
|
||||
servaddr.sin_port = htons(port);
|
||||
servaddr.sin_family = AF_INET;
|
||||
|
||||
// connect
|
||||
if ( ::connect(sock_id, (struct sockaddr *)&servaddr, sizeof(servaddr)) == 0)
|
||||
{
|
||||
// send the GET request
|
||||
char request[DMRID_HTTPGET_SIZEMAX];
|
||||
::sprintf(request, "GET /%s HTTP/1.0\r\nFrom: %s\r\nUser-Agent: xlxd\r\n\r\n",
|
||||
filename, (const char *)g_Reflector.GetCallsign());
|
||||
::write(sock_id, request, strlen(request));
|
||||
|
||||
// config receive timeouts
|
||||
fd_set read_set;
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = 5;
|
||||
timeout.tv_usec = 0;
|
||||
FD_ZERO(&read_set);
|
||||
FD_SET(sock_id, &read_set);
|
||||
|
||||
// get the reply back
|
||||
buffer->clear();
|
||||
bool done = false;
|
||||
do
|
||||
{
|
||||
char buf[1440];
|
||||
ssize_t len = 0;
|
||||
select(sock_id+1, &read_set, NULL, NULL, &timeout);
|
||||
//if ( (ret > 0) || ((ret < 0) && (errno == EINPROGRESS)) )
|
||||
//if ( ret >= 0 )
|
||||
//{
|
||||
usleep(5000);
|
||||
len = read(sock_id, buf, 1440);
|
||||
if ( len > 0 )
|
||||
{
|
||||
buffer->Append((uint8 *)buf, (int)len);
|
||||
ok = true;
|
||||
}
|
||||
//}
|
||||
done = (len <= 0);
|
||||
|
||||
} while (!done);
|
||||
buffer->Append((uint8)0);
|
||||
|
||||
// and disconnect
|
||||
close(sock_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Cannot establish connection with host " << hostname << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Host " << hostname << " not found" << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Failed to open wget socket" << std::endl;
|
||||
}
|
||||
|
||||
// done
|
||||
return ok;
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
//
|
||||
// cdmriddirhttp.h
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 29/12/2017.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef cdmriddirhttp_h
|
||||
#define cdmriddirhttp_h
|
||||
|
||||
#include "cdmriddir.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CDmridDirHttp : public CDmridDir
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CDmridDirHttp() {}
|
||||
|
||||
// destructor
|
||||
~CDmridDirHttp() {}
|
||||
|
||||
// refresh
|
||||
bool LoadContent(CBuffer *);
|
||||
bool RefreshContent(const CBuffer &);
|
||||
|
||||
protected:
|
||||
// reload helpers
|
||||
bool NeedReload(void) { return true; }
|
||||
bool HttpGet(const char *, const char *, int, CBuffer *);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#endif /* cdmriddirhttp_h */
|
|
@ -61,6 +61,20 @@ CDvFramePacket::CDvFramePacket(const uint8 *ambe, const uint8 *sync, uint16 sid,
|
|||
::memset(m_uiDvData, 0, sizeof(m_uiDvData));
|
||||
}
|
||||
|
||||
// dstar + dmr constructor
|
||||
|
||||
CDvFramePacket::CDvFramePacket
|
||||
(uint16 sid,
|
||||
uint8 dstarpid, const uint8 *dstarambe, const uint8 *dstardvdata,
|
||||
uint8 dmrpid, uint8 dprspid, const uint8 *dmrambe, const uint8 *dmrsync)
|
||||
: CPacket(sid, dstarpid, dmrpid, dprspid)
|
||||
{
|
||||
::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));
|
||||
}
|
||||
|
||||
// copy constructor
|
||||
|
||||
CDvFramePacket::CDvFramePacket(const CDvFramePacket &DvFrame)
|
||||
|
|
|
@ -55,6 +55,7 @@ public:
|
|||
CDvFramePacket();
|
||||
CDvFramePacket(const struct dstar_dvframe *, uint16, uint8);
|
||||
CDvFramePacket(const uint8 *, const uint8 *, uint16, uint8, uint8);
|
||||
CDvFramePacket(uint16, uint8, const uint8 *, const uint8 *, uint8, uint8, const uint8 *, const uint8 *);
|
||||
CDvFramePacket(const CDvFramePacket &);
|
||||
|
||||
// destructor
|
||||
|
|
|
@ -47,6 +47,16 @@ CDvLastFramePacket::CDvLastFramePacket(const uint8 *ambe, const uint8 *sync, uin
|
|||
{
|
||||
}
|
||||
|
||||
// dstar + dmr constructor
|
||||
|
||||
CDvLastFramePacket::CDvLastFramePacket
|
||||
(uint16 sid,
|
||||
uint8 dstarpid, const uint8 *dstarambe, const uint8 *dstardvdata,
|
||||
uint8 dmrpid, uint8 dprspid, const uint8 *dmrambe, const uint8 *dmrsync)
|
||||
: CDvFramePacket(sid, dstarpid, dstarambe, dstardvdata, dmrpid, dprspid, dmrambe, dmrsync)
|
||||
{
|
||||
}
|
||||
|
||||
// copy constructor
|
||||
|
||||
CDvLastFramePacket::CDvLastFramePacket(const CDvLastFramePacket &DvFrame)
|
||||
|
|
|
@ -42,6 +42,7 @@ public:
|
|||
CDvLastFramePacket();
|
||||
CDvLastFramePacket(const struct dstar_dvframe *, uint16, uint8);
|
||||
CDvLastFramePacket(const uint8 *, const uint8 *, uint16, uint8, uint8);
|
||||
CDvLastFramePacket(uint16, uint8, const uint8 *, const uint8 *, uint8, uint8, const uint8 *, const uint8 *);
|
||||
CDvLastFramePacket(const CDvLastFramePacket &);
|
||||
|
||||
// destructor
|
||||
|
|
|
@ -59,6 +59,16 @@ CPacket::CPacket(uint16 sid, uint8 dmrpid, uint8 dmrspid)
|
|||
m_uiOriginId = ORIGIN_LOCAL;
|
||||
};
|
||||
|
||||
CPacket::CPacket(uint16 sid, uint8 dstarpid, uint8 dmrpid, uint8 dmrsubpid)
|
||||
{
|
||||
m_uiStreamId = sid;
|
||||
m_uiDstarPacketId = dstarpid;
|
||||
m_uiDmrPacketId = dmrpid;
|
||||
m_uiDmrPacketSubid = dmrsubpid;
|
||||
m_uiModuleId = ' ';
|
||||
m_uiOriginId = ORIGIN_LOCAL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// virtual duplication
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ public:
|
|||
CPacket();
|
||||
CPacket(uint16 sid, uint8 dstarpid);
|
||||
CPacket(uint16 sid, uint8 dmrpid, uint8 dmrsubpid);
|
||||
CPacket(uint16 sid, uint8 dstarpid, uint8 dmrpid, uint8 dmrsubpid);
|
||||
|
||||
// destructor
|
||||
virtual ~CPacket() {};
|
||||
|
|
|
@ -40,12 +40,13 @@ CPeer::CPeer()
|
|||
m_LastHeardTime = std::time(NULL);
|
||||
}
|
||||
|
||||
CPeer::CPeer(const CCallsign &callsign, const CIp &ip, char *modules)
|
||||
CPeer::CPeer(const CCallsign &callsign, const CIp &ip, char *modules, const CVersion &version)
|
||||
{
|
||||
m_Callsign = callsign;
|
||||
m_Ip = ip;
|
||||
::memset(m_ReflectorModules, 0, sizeof(m_ReflectorModules));
|
||||
::strncpy(m_ReflectorModules, modules, sizeof(m_ReflectorModules)-1);
|
||||
m_Version = version;
|
||||
m_LastKeepaliveTime.Now();
|
||||
m_ConnectTime = std::time(NULL);
|
||||
m_LastHeardTime = std::time(NULL);
|
||||
|
@ -56,6 +57,7 @@ CPeer::CPeer(const CPeer &peer)
|
|||
m_Callsign = peer.m_Callsign;
|
||||
m_Ip = peer.m_Ip;
|
||||
::memcpy(m_ReflectorModules, peer.m_ReflectorModules, sizeof(m_ReflectorModules));
|
||||
m_Version = peer.m_Version;
|
||||
m_LastKeepaliveTime = peer.m_LastKeepaliveTime;
|
||||
m_ConnectTime = peer.m_ConnectTime;
|
||||
m_LastHeardTime = peer.m_LastHeardTime;
|
||||
|
@ -82,6 +84,7 @@ bool CPeer::operator ==(const CPeer &peer) const
|
|||
|
||||
same &= (peer.m_Callsign == m_Callsign);
|
||||
same &= (peer.m_Ip == m_Ip);
|
||||
same &= (peer.m_Version == m_Version);
|
||||
for ( int i = 0; (i < m_Clients.size()) && same ; i++ )
|
||||
{
|
||||
same &= (peer.m_Clients[i] == m_Clients[i]);
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#ifndef cpeer_h
|
||||
#define cpeer_h
|
||||
|
||||
#include "cversion.h"
|
||||
#include "ctimepoint.h"
|
||||
#include "cip.h"
|
||||
#include "ccallsign.h"
|
||||
|
@ -41,7 +42,7 @@ class CPeer
|
|||
public:
|
||||
// constructors
|
||||
CPeer();
|
||||
CPeer(const CCallsign &, const CIp &, char *);
|
||||
CPeer(const CCallsign &, const CIp &, char *, const CVersion &);
|
||||
CPeer(const CPeer &);
|
||||
|
||||
// destructor
|
||||
|
@ -82,6 +83,7 @@ protected:
|
|||
CCallsign m_Callsign;
|
||||
CIp m_Ip;
|
||||
char m_ReflectorModules[NB_MODULES_MAX+1];
|
||||
CVersion m_Version;
|
||||
std::vector<CClient *> m_Clients;
|
||||
|
||||
// status
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
#include <string.h>
|
||||
#include "creflector.h"
|
||||
#include "cgatekeeper.h"
|
||||
#include "cdmriddir.h"
|
||||
#include "cdmriddirfile.h"
|
||||
#include "cdmriddirhttp.h"
|
||||
#include "ctranscoder.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -102,7 +103,7 @@ bool CReflector::Start(void)
|
|||
ok &= g_GateKeeper.Init();
|
||||
|
||||
// init dmrid directory
|
||||
g_DmridDir.RefreshContent();
|
||||
g_DmridDir.Init();
|
||||
|
||||
// init the transcoder
|
||||
g_Transcoder.Init();
|
||||
|
|
|
@ -188,12 +188,6 @@ void CTranscoder::Task(void)
|
|||
|
||||
}
|
||||
|
||||
// handle end of streaming timeout
|
||||
//CheckStreamsTimeout();
|
||||
|
||||
// handle queue from reflector
|
||||
//HandleQueue();
|
||||
|
||||
// keep client alive
|
||||
if ( m_LastKeepaliveTime.DurationSinceNow() > TRANSCODER_KEEPALIVE_PERIOD )
|
||||
{
|
||||
|
|
|
@ -55,6 +55,9 @@ public:
|
|||
void Lock(void) { m_Mutex.lock(); }
|
||||
void Unlock(void) { m_Mutex.unlock(); }
|
||||
|
||||
// status
|
||||
bool IsConnected(void) const { return m_bConnected; }
|
||||
|
||||
// manage streams
|
||||
CCodecStream *GetStream(CPacketStream *, uint8);
|
||||
void ReleaseStream(CCodecStream *);
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
//
|
||||
// cversion.cpp
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 05/01/2018.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "main.h"
|
||||
#include "cversion.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructor
|
||||
|
||||
CVersion::CVersion()
|
||||
{
|
||||
m_iMajor = 0;
|
||||
m_iMinor = 0;
|
||||
m_iRevision = 0;
|
||||
}
|
||||
|
||||
CVersion::CVersion(int iMajor, int iMinor, int iRevision)
|
||||
{
|
||||
m_iMajor = iMajor;
|
||||
m_iMinor = iMinor;
|
||||
m_iRevision = iRevision;
|
||||
}
|
||||
|
||||
CVersion::CVersion(const CVersion &Version)
|
||||
{
|
||||
m_iMajor = Version.m_iMajor;
|
||||
m_iMinor = Version.m_iMinor;
|
||||
m_iRevision = Version.m_iRevision;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// comparaison
|
||||
|
||||
bool CVersion::IsEqualOrHigherTo(const CVersion &version) const
|
||||
{
|
||||
if ( m_iMajor > version.m_iMajor )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if ( m_iMajor == version.m_iMajor )
|
||||
{
|
||||
if ( m_iMinor > version.m_iMinor )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if ( m_iMinor == version.m_iMinor )
|
||||
{
|
||||
if ( m_iRevision >= version.m_iRevision )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// operator
|
||||
|
||||
bool CVersion::operator ==(const CVersion &Version) const
|
||||
{
|
||||
return ( (Version.m_iMajor == m_iMajor) &&
|
||||
(Version.m_iMinor == m_iMinor) &&
|
||||
(Version.m_iRevision == m_iRevision )) ;
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
//
|
||||
// cversion.h
|
||||
// xlxd
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 05/01/2018.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of xlxd.
|
||||
//
|
||||
// xlxd is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// xlxd is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef cversion_h
|
||||
#define cversion_h
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CVersion
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CVersion();
|
||||
CVersion(int, int, int);
|
||||
CVersion(const CVersion &);
|
||||
|
||||
// destructor
|
||||
virtual ~CVersion() {}
|
||||
|
||||
// get
|
||||
int GetMajor(void) const { return m_iMajor; }
|
||||
int GetMinor(void) const { return m_iMinor; }
|
||||
int GetRevision(void) const { return m_iRevision; }
|
||||
|
||||
// comparaison
|
||||
bool IsEqualOrHigherTo(const CVersion &) const;
|
||||
|
||||
// operator
|
||||
bool operator ==(const CVersion &) const;
|
||||
|
||||
protected:
|
||||
// data
|
||||
int m_iMajor;
|
||||
int m_iMinor;
|
||||
int m_iRevision;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#endif /* cversion_h */
|
|
@ -32,16 +32,40 @@
|
|||
|
||||
CXlxClient::CXlxClient()
|
||||
{
|
||||
m_ProtRev = XLX_PROTOCOL_REVISION_0;
|
||||
}
|
||||
|
||||
CXlxClient::CXlxClient(const CCallsign &callsign, const CIp &ip, char reflectorModule)
|
||||
CXlxClient::CXlxClient(const CCallsign &callsign, const CIp &ip, char reflectorModule, int protRev)
|
||||
: CClient(callsign, ip, reflectorModule)
|
||||
{
|
||||
m_ProtRev = protRev;
|
||||
}
|
||||
|
||||
CXlxClient::CXlxClient(const CXlxClient &client)
|
||||
: CClient(client)
|
||||
{
|
||||
m_ProtRev = client.m_ProtRev;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// identity
|
||||
|
||||
int CXlxClient::GetCodec(void) const
|
||||
{
|
||||
int codec;
|
||||
|
||||
switch ( GetProtocolRevision() )
|
||||
{
|
||||
case XLX_PROTOCOL_REVISION_0:
|
||||
case XLX_PROTOCOL_REVISION_1:
|
||||
default:
|
||||
codec = CODEC_AMBEPLUS;
|
||||
break;
|
||||
case XLX_PROTOCOL_REVISION_2:
|
||||
codec = CODEC_NONE;
|
||||
break;
|
||||
}
|
||||
return codec;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// define
|
||||
|
||||
#define XLX_PROTOCOL_REVISION_0 0 // AMBE only, original connect mechanism
|
||||
#define XLX_PROTOCOL_REVISION_1 1 // AMBE only, revised connect mechanism
|
||||
#define XLX_PROTOCOL_REVISION_2 2 // Transcoded AMBE+AMBE2 interlink
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
@ -40,7 +44,7 @@ class CXlxClient : public CClient
|
|||
public:
|
||||
// constructors
|
||||
CXlxClient();
|
||||
CXlxClient(const CCallsign &, const CIp &, char = ' ');
|
||||
CXlxClient(const CCallsign &, const CIp &, char = ' ', int = XLX_PROTOCOL_REVISION_0);
|
||||
CXlxClient(const CXlxClient &);
|
||||
|
||||
// destructor
|
||||
|
@ -48,7 +52,9 @@ public:
|
|||
|
||||
// identity
|
||||
int GetProtocol(void) const { return PROTOCOL_XLX; }
|
||||
int GetProtocolRevision(void) const { return m_ProtRev; }
|
||||
const char *GetProtocolName(void) const { return "XLX"; }
|
||||
int GetCodec(void) const;
|
||||
bool IsPeer(void) const { return true; }
|
||||
|
||||
// status
|
||||
|
@ -56,6 +62,10 @@ public:
|
|||
|
||||
// reporting
|
||||
void WriteXml(std::ofstream &) {}
|
||||
|
||||
protected:
|
||||
// data
|
||||
int m_ProtRev;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -37,14 +37,18 @@ CXlxPeer::CXlxPeer()
|
|||
{
|
||||
}
|
||||
|
||||
CXlxPeer::CXlxPeer(const CCallsign &callsign, const CIp &ip, char *modules)
|
||||
: CPeer(callsign, ip, modules)
|
||||
CXlxPeer::CXlxPeer(const CCallsign &callsign, const CIp &ip, char *modules, const CVersion &version)
|
||||
: CPeer(callsign, ip, modules, version)
|
||||
{
|
||||
// get protocol revision
|
||||
int protrev = GetProtocolRevision(version);
|
||||
//std::cout << "Adding XLX peer with protocol revision " << protrev << std::endl;
|
||||
|
||||
// and construct all xlx clients
|
||||
for ( int i = 0; i < ::strlen(modules); i++ )
|
||||
{
|
||||
// create
|
||||
CXlxClient *client = new CXlxClient(callsign, ip, modules[i]);
|
||||
CXlxClient *client = new CXlxClient(callsign, ip, modules[i], protrev);
|
||||
// and append to vector
|
||||
m_Clients.push_back(client);
|
||||
}
|
||||
|
@ -82,3 +86,21 @@ bool CXlxPeer::IsAlive(void) const
|
|||
return (m_LastKeepaliveTime.DurationSinceNow() < XLX_KEEPALIVE_TIMEOUT);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// revision helper
|
||||
|
||||
int CXlxPeer::GetProtocolRevision(const CVersion &version)
|
||||
{
|
||||
int protrev = XLX_PROTOCOL_REVISION_0;
|
||||
|
||||
if ( version.IsEqualOrHigherTo(CVersion(2,2,0)) )
|
||||
{
|
||||
protrev = XLX_PROTOCOL_REVISION_2;
|
||||
}
|
||||
else if ( version.IsEqualOrHigherTo(CVersion(1,4,0)) )
|
||||
{
|
||||
protrev = XLX_PROTOCOL_REVISION_1;
|
||||
}
|
||||
return protrev;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,9 +26,11 @@
|
|||
#define cxlxpeer_h
|
||||
|
||||
#include "cpeer.h"
|
||||
#include "cxlxclient.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// define
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
@ -38,7 +40,7 @@ class CXlxPeer : public CPeer
|
|||
public:
|
||||
// constructors
|
||||
CXlxPeer();
|
||||
CXlxPeer(const CCallsign &, const CIp &, char *);
|
||||
CXlxPeer(const CCallsign &, const CIp &, char *, const CVersion &);
|
||||
CXlxPeer(const CXlxPeer &);
|
||||
|
||||
// destructor
|
||||
|
@ -46,9 +48,13 @@ public:
|
|||
|
||||
// status
|
||||
bool IsAlive(void) const;
|
||||
|
||||
// identity
|
||||
int GetProtocol(void) const { return PROTOCOL_XLX; }
|
||||
const char *GetProtocolName(void) const { return "XLX"; }
|
||||
|
||||
// revision helper
|
||||
static int GetProtocolRevision(const CVersion &);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -67,10 +67,10 @@ void CXlxProtocol::Task(void)
|
|||
CIp Ip;
|
||||
CCallsign Callsign;
|
||||
char Modules[NB_MODULES_MAX+1];
|
||||
CVersion Version;
|
||||
CDvHeaderPacket *Header;
|
||||
CDvFramePacket *Frame;
|
||||
CDvLastFramePacket *LastFrame;
|
||||
uint8 Major, Minor, Revision;
|
||||
|
||||
// any incoming packet ?
|
||||
if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 )
|
||||
|
@ -106,34 +106,41 @@ void CXlxProtocol::Task(void)
|
|||
// handle it
|
||||
OnDvLastFramePacketIn(LastFrame, &Ip);
|
||||
}
|
||||
else if ( IsValidConnectPacket(Buffer, &Callsign, Modules, &Major, &Minor, &Revision) )
|
||||
else if ( IsValidConnectPacket(Buffer, &Callsign, Modules, &Version) )
|
||||
{
|
||||
std::cout << "XLX (" << (int)Major << "." << (int)Minor << "." << (int)Revision
|
||||
std::cout << "XLX ("
|
||||
<< Version.GetMajor() << "." << Version.GetMinor() << "." << Version.GetRevision()
|
||||
<< ") connect packet for modules " << Modules
|
||||
<< " from " << Callsign << " at " << Ip << std::endl;
|
||||
|
||||
// callsign authorized?
|
||||
if ( g_GateKeeper.MayLink(Callsign, Ip, PROTOCOL_XLX, Modules) )
|
||||
{
|
||||
// acknowledge connecting request
|
||||
// following is version dependent
|
||||
// for backward compatibility, only send ACK once
|
||||
if ( (Major == 1) && (Minor < 4) )
|
||||
switch ( CXlxPeer::GetProtocolRevision(Version) )
|
||||
{
|
||||
// already connected ?
|
||||
CPeers *peers = g_Reflector.GetPeers();
|
||||
if ( peers->FindPeer(Callsign, Ip, PROTOCOL_XLX) == NULL )
|
||||
{
|
||||
case XLX_PROTOCOL_REVISION_0:
|
||||
{
|
||||
// already connected ?
|
||||
CPeers *peers = g_Reflector.GetPeers();
|
||||
if ( peers->FindPeer(Callsign, Ip, PROTOCOL_XLX) == NULL )
|
||||
{
|
||||
// acknowledge the request
|
||||
EncodeConnectAckPacket(&Buffer, Modules);
|
||||
m_Socket.Send(Buffer, Ip);
|
||||
}
|
||||
g_Reflector.ReleasePeers();
|
||||
|
||||
}
|
||||
break;
|
||||
case XLX_PROTOCOL_REVISION_1:
|
||||
case XLX_PROTOCOL_REVISION_2:
|
||||
default:
|
||||
// acknowledge the request
|
||||
EncodeConnectAckPacket(&Buffer, Modules);
|
||||
m_Socket.Send(Buffer, Ip);
|
||||
}
|
||||
g_Reflector.ReleasePeers();
|
||||
}
|
||||
else
|
||||
{
|
||||
// acknowledge the request
|
||||
EncodeConnectAckPacket(&Buffer, Modules);
|
||||
m_Socket.Send(Buffer, Ip);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -143,7 +150,7 @@ void CXlxProtocol::Task(void)
|
|||
m_Socket.Send(Buffer, Ip);
|
||||
}
|
||||
}
|
||||
else if ( IsValidAckPacket(Buffer, &Callsign, Modules) )
|
||||
else if ( IsValidAckPacket(Buffer, &Callsign, Modules, &Version) )
|
||||
{
|
||||
std::cout << "XLX ack packet for modules " << Modules << " from " << Callsign << " at " << Ip << std::endl;
|
||||
|
||||
|
@ -156,8 +163,8 @@ void CXlxProtocol::Task(void)
|
|||
{
|
||||
// create the new peer
|
||||
// this also create one client per module
|
||||
CXlxPeer *peer = new CXlxPeer(Callsign, Ip, Modules);
|
||||
|
||||
CXlxPeer *peer = new CXlxPeer(Callsign, Ip, Modules, Version);
|
||||
|
||||
// append the peer to reflector peer list
|
||||
// this also add all new clients to reflector client list
|
||||
peers->AddPeer(peer);
|
||||
|
@ -253,6 +260,13 @@ void CXlxProtocol::HandleQueue(void)
|
|||
CBuffer buffer;
|
||||
if ( EncodeDvPacket(*packet, &buffer) )
|
||||
{
|
||||
// encode revision dependent version
|
||||
CBuffer bufferLegacy = buffer;
|
||||
if ( packet->IsDvFrame() && (bufferLegacy.size() == 45) )
|
||||
{
|
||||
bufferLegacy.resize(27);
|
||||
}
|
||||
|
||||
// and push it to all our clients linked to the module and who are not streaming in
|
||||
CClients *clients = g_Reflector.GetClients();
|
||||
int index = -1;
|
||||
|
@ -263,7 +277,25 @@ void CXlxProtocol::HandleQueue(void)
|
|||
if ( !client->IsAMaster() && (client->GetReflectorModule() == packet->GetModuleId()) )
|
||||
{
|
||||
// no, send the packet
|
||||
m_Socket.Send(buffer, client->GetIp());
|
||||
// this is protocol revision dependent
|
||||
switch ( client->GetProtocolRevision() )
|
||||
{
|
||||
case XLX_PROTOCOL_REVISION_0:
|
||||
case XLX_PROTOCOL_REVISION_1:
|
||||
m_Socket.Send(bufferLegacy, client->GetIp());
|
||||
break;
|
||||
case XLX_PROTOCOL_REVISION_2:
|
||||
default:
|
||||
if ( g_Transcoder.IsConnected() )
|
||||
{
|
||||
m_Socket.Send(buffer, client->GetIp());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Socket.Send(bufferLegacy, client->GetIp());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
g_Reflector.ReleaseClients();
|
||||
|
@ -459,7 +491,7 @@ bool CXlxProtocol::IsValidKeepAlivePacket(const CBuffer &Buffer, CCallsign *call
|
|||
}
|
||||
|
||||
|
||||
bool CXlxProtocol::IsValidConnectPacket(const CBuffer &Buffer, CCallsign *callsign, char *modules, uint8 *major, uint8 *minor, uint8 *rev)
|
||||
bool CXlxProtocol::IsValidConnectPacket(const CBuffer &Buffer, CCallsign *callsign, char *modules, CVersion *version)
|
||||
{
|
||||
bool valid = false;
|
||||
if ((Buffer.size() == 39) && (Buffer.data()[0] == 'L') && (Buffer.data()[38] == 0))
|
||||
|
@ -467,9 +499,7 @@ bool CXlxProtocol::IsValidConnectPacket(const CBuffer &Buffer, CCallsign *callsi
|
|||
callsign->SetCallsign((const uint8 *)&(Buffer.data()[1]), 8);
|
||||
::strcpy(modules, (const char *)&(Buffer.data()[12]));
|
||||
valid = callsign->IsValid();
|
||||
*major = Buffer.data()[9];
|
||||
*minor = Buffer.data()[10];
|
||||
*rev = Buffer.data()[11];
|
||||
*version = CVersion(Buffer.data()[9], Buffer.data()[10], Buffer.data()[11]);
|
||||
for ( int i = 0; i < ::strlen(modules); i++ )
|
||||
{
|
||||
valid &= IsLetter(modules[i]);
|
||||
|
@ -489,7 +519,7 @@ bool CXlxProtocol::IsValidDisconnectPacket(const CBuffer &Buffer, CCallsign *cal
|
|||
return valid;
|
||||
}
|
||||
|
||||
bool CXlxProtocol::IsValidAckPacket(const CBuffer &Buffer, CCallsign *callsign, char *modules)
|
||||
bool CXlxProtocol::IsValidAckPacket(const CBuffer &Buffer, CCallsign *callsign, char *modules, CVersion *version)
|
||||
{
|
||||
bool valid = false;
|
||||
if ((Buffer.size() == 39) && (Buffer.data()[0] == 'A') && (Buffer.data()[38] == 0))
|
||||
|
@ -497,6 +527,7 @@ bool CXlxProtocol::IsValidAckPacket(const CBuffer &Buffer, CCallsign *callsign,
|
|||
callsign->SetCallsign((const uint8 *)&(Buffer.data()[1]), 8);
|
||||
::strcpy(modules, (const char *)&(Buffer.data()[12]));
|
||||
valid = callsign->IsValid();
|
||||
*version = CVersion(Buffer.data()[9], Buffer.data()[10], Buffer.data()[11]);
|
||||
for ( int i = 0; i < ::strlen(modules); i++ )
|
||||
{
|
||||
valid &= IsLetter(modules[i]);
|
||||
|
@ -516,6 +547,74 @@ bool CXlxProtocol::IsValidNackPacket(const CBuffer &Buffer, CCallsign *callsign)
|
|||
return valid;
|
||||
}
|
||||
|
||||
CDvFramePacket *CXlxProtocol::IsValidDvFramePacket(const CBuffer &Buffer)
|
||||
{
|
||||
CDvFramePacket *dvframe = NULL;
|
||||
|
||||
// base class first (protocol revision 1 and lower)
|
||||
dvframe = CDextraProtocol::IsValidDvFramePacket(Buffer);
|
||||
|
||||
// otherwise try protocol revision 2
|
||||
if ( (dvframe == NULL) &&
|
||||
(Buffer.size() == 45) && (Buffer.Compare((uint8 *)"DSVT", 4) == 0) &&
|
||||
(Buffer.data()[4] == 0x20) && (Buffer.data()[8] == 0x20) &&
|
||||
((Buffer.data()[14] & 0x40) == 0) )
|
||||
{
|
||||
// create packet
|
||||
dvframe = new CDvFramePacket(
|
||||
// sid
|
||||
*((uint16 *)&(Buffer.data()[12])),
|
||||
// dstar
|
||||
Buffer.data()[14], &(Buffer.data()[15]), &(Buffer.data()[24]),
|
||||
// dmr
|
||||
Buffer.data()[27], Buffer.data()[28], &(Buffer.data()[29]), &(Buffer.data()[38]));
|
||||
|
||||
// check validity of packet
|
||||
if ( !dvframe->IsValid() )
|
||||
{
|
||||
delete dvframe;
|
||||
dvframe = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// done
|
||||
return dvframe;
|
||||
}
|
||||
|
||||
CDvLastFramePacket *CXlxProtocol::IsValidDvLastFramePacket(const CBuffer &Buffer)
|
||||
{
|
||||
CDvLastFramePacket *dvframe = NULL;
|
||||
|
||||
// base class first (protocol revision 1 and lower)
|
||||
dvframe = CDextraProtocol::IsValidDvLastFramePacket(Buffer);
|
||||
|
||||
// otherwise try protocol revision 2
|
||||
if ( (dvframe == NULL) &&
|
||||
(Buffer.size() == 45) && (Buffer.Compare((uint8 *)"DSVT", 4) == 0) &&
|
||||
(Buffer.data()[4] == 0x20) && (Buffer.data()[8] == 0x20) &&
|
||||
((Buffer.data()[14] & 0x40) != 0) )
|
||||
{
|
||||
// create packet
|
||||
dvframe = new CDvLastFramePacket(
|
||||
// sid
|
||||
*((uint16 *)&(Buffer.data()[12])),
|
||||
// dstar
|
||||
Buffer.data()[14], &(Buffer.data()[15]), &(Buffer.data()[24]),
|
||||
// dmr
|
||||
Buffer.data()[27], Buffer.data()[28], &(Buffer.data()[29]), &(Buffer.data()[38]));
|
||||
|
||||
// check validity of packet
|
||||
if ( !dvframe->IsValid() )
|
||||
{
|
||||
delete dvframe;
|
||||
dvframe = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// done
|
||||
return dvframe;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// packet encoding helpers
|
||||
|
||||
|
@ -584,3 +683,42 @@ void CXlxProtocol::EncodeConnectNackPacket(CBuffer *Buffer)
|
|||
Buffer->Append((uint8)0);
|
||||
}
|
||||
|
||||
bool CXlxProtocol::EncodeDvFramePacket(const CDvFramePacket &Packet, CBuffer *Buffer) const
|
||||
{
|
||||
uint8 tag[] = { 'D','S','V','T',0x20,0x00,0x00,0x00,0x20,0x00,0x01,0x02 };
|
||||
|
||||
Buffer->Set(tag, sizeof(tag));
|
||||
Buffer->Append(Packet.GetStreamId());
|
||||
Buffer->Append((uint8)(Packet.GetDstarPacketId() % 21));
|
||||
Buffer->Append((uint8 *)Packet.GetAmbe(), AMBE_SIZE);
|
||||
Buffer->Append((uint8 *)Packet.GetDvData(), DVDATA_SIZE);
|
||||
|
||||
Buffer->Append((uint8)Packet.GetDmrPacketId());
|
||||
Buffer->Append((uint8)Packet.GetDmrPacketSubid());
|
||||
Buffer->Append((uint8 *)Packet.GetAmbePlus(), AMBEPLUS_SIZE);
|
||||
Buffer->Append((uint8 *)Packet.GetDvSync(), DVSYNC_SIZE);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool CXlxProtocol::EncodeDvLastFramePacket(const CDvLastFramePacket &Packet, CBuffer *Buffer) const
|
||||
{
|
||||
uint8 tag[] = { 'D','S','V','T',0x20,0x00,0x00,0x00,0x20,0x00,0x01,0x02 };
|
||||
uint8 dstarambe[] = { 0x55,0xC8,0x7A,0x00,0x00,0x00,0x00,0x00,0x00 };
|
||||
uint8 dstardvdata[] = { 0x25,0x1A,0xC6 };
|
||||
|
||||
Buffer->Set(tag, sizeof(tag));
|
||||
Buffer->Append(Packet.GetStreamId());
|
||||
Buffer->Append((uint8)((Packet.GetPacketId() % 21) | 0x40));
|
||||
Buffer->Append(dstarambe, sizeof(dstarambe));
|
||||
Buffer->Append(dstardvdata, sizeof(dstardvdata));
|
||||
|
||||
|
||||
Buffer->Append((uint8)Packet.GetDmrPacketId());
|
||||
Buffer->Append((uint8)Packet.GetDmrPacketSubid());
|
||||
Buffer->Append((uint8 *)Packet.GetAmbePlus(), AMBEPLUS_SIZE);
|
||||
Buffer->Append((uint8 *)Packet.GetDvSync(), DVSYNC_SIZE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#ifndef cxlxprotocol_h
|
||||
#define cxlxprotocol_h
|
||||
|
||||
|
||||
#include "cversion.h"
|
||||
#include "ctimepoint.h"
|
||||
#include "cdextraprotocol.h"
|
||||
#include "cclients.h"
|
||||
|
@ -65,18 +65,22 @@ protected:
|
|||
void OnDvLastFramePacketIn(CDvLastFramePacket *, const CIp * = NULL);
|
||||
|
||||
// packet decoding helpers
|
||||
bool IsValidKeepAlivePacket(const CBuffer &, CCallsign *);
|
||||
bool IsValidConnectPacket(const CBuffer &, CCallsign *, char *, uint8 *, uint8 *, uint8 *);
|
||||
bool IsValidDisconnectPacket(const CBuffer &, CCallsign *);
|
||||
bool IsValidAckPacket(const CBuffer &, CCallsign *, char *);
|
||||
bool IsValidNackPacket(const CBuffer &, CCallsign *);
|
||||
bool IsValidKeepAlivePacket(const CBuffer &, CCallsign *);
|
||||
bool IsValidConnectPacket(const CBuffer &, CCallsign *, char *, CVersion *);
|
||||
bool IsValidDisconnectPacket(const CBuffer &, CCallsign *);
|
||||
bool IsValidAckPacket(const CBuffer &, CCallsign *, char *, CVersion *);
|
||||
bool IsValidNackPacket(const CBuffer &, CCallsign *);
|
||||
CDvFramePacket *IsValidDvFramePacket(const CBuffer &);
|
||||
CDvLastFramePacket *IsValidDvLastFramePacket(const CBuffer &);
|
||||
|
||||
// packet encoding helpers
|
||||
void EncodeKeepAlivePacket(CBuffer *);
|
||||
void EncodeConnectPacket(CBuffer *, const char *);
|
||||
void EncodeDisconnectPacket(CBuffer *);
|
||||
void EncodeConnectAckPacket(CBuffer *, const char *);
|
||||
void EncodeConnectNackPacket(CBuffer *);
|
||||
void EncodeKeepAlivePacket(CBuffer *);
|
||||
void EncodeConnectPacket(CBuffer *, const char *);
|
||||
void EncodeDisconnectPacket(CBuffer *);
|
||||
void EncodeConnectAckPacket(CBuffer *, const char *);
|
||||
void EncodeConnectNackPacket(CBuffer *);
|
||||
bool EncodeDvFramePacket(const CDvFramePacket &, CBuffer *) const;
|
||||
bool EncodeDvLastFramePacket(const CDvLastFramePacket &, CBuffer *) const;
|
||||
|
||||
protected:
|
||||
// time
|
||||
|
|
|
@ -94,6 +94,9 @@ int main(int argc, const char * argv[])
|
|||
return 1;
|
||||
}
|
||||
|
||||
// splash
|
||||
std::cout << "Starting xlxd " << VERSION_MAJOR << "." << VERSION_MINOR << "." << VERSION_REVISION << std::endl << std::endl;
|
||||
|
||||
// initialize reflector
|
||||
g_Reflector.SetCallsign(argv[1]);
|
||||
g_Reflector.SetListenIp(CIp(argv[2]));
|
||||
|
|
18
src/main.h
18
src/main.h
|
@ -48,8 +48,8 @@
|
|||
// version -----------------------------------------------------
|
||||
|
||||
#define VERSION_MAJOR 2
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_REVISION 0
|
||||
#define VERSION_MINOR 2
|
||||
#define VERSION_REVISION 1
|
||||
|
||||
// global ------------------------------------------------------
|
||||
|
||||
|
@ -127,8 +127,9 @@
|
|||
|
||||
// DMRid database -----------------------------------------------
|
||||
|
||||
#define DMRIDDB_USE_RLX_SERVER 0
|
||||
#define DMRIDDB_PATH "/xlxd/dmrid.dat"
|
||||
#define DMRIDDB_USE_RLX_SERVER 1 // 1 = use http, 0 = use local file
|
||||
#define DMRIDDB_PATH "/xlxd/dmrid.dat" // local file path
|
||||
#define DMRIDDB_REFRESH_RATE 180 // in minutes
|
||||
|
||||
|
||||
// xml & json reporting -----------------------------------------
|
||||
|
@ -180,8 +181,13 @@ extern CReflector g_Reflector;
|
|||
class CGateKeeper;
|
||||
extern CGateKeeper g_GateKeeper;
|
||||
|
||||
class CDmridDir;
|
||||
extern CDmridDir g_DmridDir;
|
||||
#if (DMRIDDB_USE_RLX_SERVER == 1)
|
||||
class CDmridDirHttp;
|
||||
extern CDmridDirHttp g_DmridDir;
|
||||
#else
|
||||
class CDmridDirFile;
|
||||
extern CDmridDirFile g_DmridDir;
|
||||
#endif
|
||||
|
||||
class CTranscoder;
|
||||
extern CTranscoder g_Transcoder;
|
||||
|
|
Loading…
Reference in New Issue