mirror of
https://github.com/ShaYmez/NXDNClients.git
synced 2026-08-14 07:23:29 -04:00
Initial commit.
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016,2018 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "Conf.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cctype>
|
||||
|
||||
const int BUFFER_SIZE = 500;
|
||||
|
||||
enum SECTION {
|
||||
SECTION_NONE,
|
||||
SECTION_GENERAL,
|
||||
SECTION_ID_LOOKUP,
|
||||
SECTION_LOG,
|
||||
SECTION_NETWORK,
|
||||
SECTION_NXCORE
|
||||
};
|
||||
|
||||
CConf::CConf(const std::string& file) :
|
||||
m_file(file),
|
||||
m_daemon(false),
|
||||
m_lookupName(),
|
||||
m_lookupTime(0U),
|
||||
m_logDisplayLevel(0U),
|
||||
m_logFileLevel(0U),
|
||||
m_logFilePath(),
|
||||
m_logFileRoot(),
|
||||
m_networkPort(0U),
|
||||
m_networkDebug(false),
|
||||
m_nxCoreEnabled(false),
|
||||
m_nxCoreAddress(),
|
||||
m_nxCoreDebug(false)
|
||||
{
|
||||
}
|
||||
|
||||
CConf::~CConf()
|
||||
{
|
||||
}
|
||||
|
||||
bool CConf::read()
|
||||
{
|
||||
FILE* fp = ::fopen(m_file.c_str(), "rt");
|
||||
if (fp == NULL) {
|
||||
::fprintf(stderr, "Couldn't open the .ini file - %s\n", m_file.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
SECTION section = SECTION_NONE;
|
||||
|
||||
char buffer[BUFFER_SIZE];
|
||||
while (::fgets(buffer, BUFFER_SIZE, fp) != NULL) {
|
||||
if (buffer[0U] == '#')
|
||||
continue;
|
||||
|
||||
if (buffer[0U] == '[') {
|
||||
if (::strncmp(buffer, "[General]", 9U) == 0)
|
||||
section = SECTION_GENERAL;
|
||||
else if (::strncmp(buffer, "[Id Lookup]", 11U) == 0)
|
||||
section = SECTION_ID_LOOKUP;
|
||||
else if (::strncmp(buffer, "[Log]", 5U) == 0)
|
||||
section = SECTION_LOG;
|
||||
else if (::strncmp(buffer, "[Network]", 9U) == 0)
|
||||
section = SECTION_NETWORK;
|
||||
else if (::strncmp(buffer, "[NXCore]", 8U) == 0)
|
||||
section = SECTION_NXCORE;
|
||||
else
|
||||
section = SECTION_NONE;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
char* key = ::strtok(buffer, " \t=\r\n");
|
||||
if (key == NULL)
|
||||
continue;
|
||||
|
||||
char* value = ::strtok(NULL, "\r\n");
|
||||
if (section == SECTION_GENERAL) {
|
||||
if (::strcmp(key, "Daemon") == 0)
|
||||
m_daemon = ::atoi(value) == 1;
|
||||
} else if (section == SECTION_ID_LOOKUP) {
|
||||
if (::strcmp(key, "Name") == 0)
|
||||
m_lookupName = value;
|
||||
else if (::strcmp(key, "Time") == 0)
|
||||
m_lookupTime = (unsigned int)::atoi(value);
|
||||
} else if (section == SECTION_LOG) {
|
||||
if (::strcmp(key, "FilePath") == 0)
|
||||
m_logFilePath = value;
|
||||
else if (::strcmp(key, "FileRoot") == 0)
|
||||
m_logFileRoot = value;
|
||||
else if (::strcmp(key, "FileLevel") == 0)
|
||||
m_logFileLevel = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "DisplayLevel") == 0)
|
||||
m_logDisplayLevel = (unsigned int)::atoi(value);
|
||||
} else if (section == SECTION_NETWORK) {
|
||||
if (::strcmp(key, "Port") == 0)
|
||||
m_networkPort = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "Debug") == 0)
|
||||
m_networkDebug = ::atoi(value) == 1;
|
||||
} else if (section == SECTION_NXCORE) {
|
||||
if (::strcmp(key, "Enabled") == 0)
|
||||
m_nxCoreEnabled = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "Address") == 0)
|
||||
m_nxCoreAddress = value;
|
||||
else if (::strcmp(key, "Debug") == 0)
|
||||
m_nxCoreDebug = ::atoi(value) == 1;
|
||||
}
|
||||
}
|
||||
|
||||
::fclose(fp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CConf::getDaemon() const
|
||||
{
|
||||
return m_daemon;
|
||||
}
|
||||
|
||||
std::string CConf::getLookupName() const
|
||||
{
|
||||
return m_lookupName;
|
||||
}
|
||||
|
||||
unsigned int CConf::getLookupTime() const
|
||||
{
|
||||
return m_lookupTime;
|
||||
}
|
||||
|
||||
unsigned int CConf::getLogDisplayLevel() const
|
||||
{
|
||||
return m_logDisplayLevel;
|
||||
}
|
||||
|
||||
unsigned int CConf::getLogFileLevel() const
|
||||
{
|
||||
return m_logFileLevel;
|
||||
}
|
||||
|
||||
std::string CConf::getLogFilePath() const
|
||||
{
|
||||
return m_logFilePath;
|
||||
}
|
||||
|
||||
std::string CConf::getLogFileRoot() const
|
||||
{
|
||||
return m_logFileRoot;
|
||||
}
|
||||
|
||||
unsigned int CConf::getNetworkPort() const
|
||||
{
|
||||
return m_networkPort;
|
||||
}
|
||||
|
||||
bool CConf::getNetworkDebug() const
|
||||
{
|
||||
return m_networkDebug;
|
||||
}
|
||||
|
||||
bool CConf::getNXCoreEnabled() const
|
||||
{
|
||||
return m_nxCoreEnabled;
|
||||
}
|
||||
|
||||
std::string CConf::getNXCoreAddress() const
|
||||
{
|
||||
return m_nxCoreAddress;
|
||||
}
|
||||
|
||||
bool CConf::getNXCoreDebug() const
|
||||
{
|
||||
return m_nxCoreDebug;
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016,2018 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#if !defined(CONF_H)
|
||||
#define CONF_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class CConf
|
||||
{
|
||||
public:
|
||||
CConf(const std::string& file);
|
||||
~CConf();
|
||||
|
||||
bool read();
|
||||
|
||||
// The General section
|
||||
bool getDaemon() const;
|
||||
|
||||
// The Id Lookup section
|
||||
std::string getLookupName() const;
|
||||
unsigned int getLookupTime() const;
|
||||
|
||||
// The Log section
|
||||
unsigned int getLogDisplayLevel() const;
|
||||
unsigned int getLogFileLevel() const;
|
||||
std::string getLogFilePath() const;
|
||||
std::string getLogFileRoot() const;
|
||||
|
||||
// The Network section
|
||||
unsigned int getNetworkPort() const;
|
||||
bool getNetworkDebug() const;
|
||||
|
||||
// The NXCore section
|
||||
bool getNXCoreEnabled() const;
|
||||
std::string getNXCoreAddress() const;
|
||||
bool getNXCoreDebug() const;
|
||||
|
||||
private:
|
||||
std::string m_file;
|
||||
bool m_daemon;
|
||||
|
||||
std::string m_lookupName;
|
||||
unsigned int m_lookupTime;
|
||||
|
||||
unsigned int m_logDisplayLevel;
|
||||
unsigned int m_logFileLevel;
|
||||
std::string m_logFilePath;
|
||||
std::string m_logFileRoot;
|
||||
|
||||
unsigned int m_networkPort;
|
||||
bool m_networkDebug;
|
||||
|
||||
bool m_nxCoreEnabled;
|
||||
std::string m_nxCoreAddress;
|
||||
bool m_nxCoreDebug;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "Log.h"
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstdarg>
|
||||
#include <ctime>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
static unsigned int m_fileLevel = 2U;
|
||||
static std::string m_filePath;
|
||||
static std::string m_fileRoot;
|
||||
|
||||
static FILE* m_fpLog = NULL;
|
||||
|
||||
static unsigned int m_displayLevel = 2U;
|
||||
|
||||
static struct tm m_tm;
|
||||
|
||||
static char LEVELS[] = " DMIWEF";
|
||||
|
||||
static bool LogOpen()
|
||||
{
|
||||
if (m_fileLevel == 0U)
|
||||
return true;
|
||||
|
||||
time_t now;
|
||||
::time(&now);
|
||||
|
||||
struct tm* tm = ::gmtime(&now);
|
||||
|
||||
if (tm->tm_mday == m_tm.tm_mday && tm->tm_mon == m_tm.tm_mon && tm->tm_year == m_tm.tm_year) {
|
||||
if (m_fpLog != NULL)
|
||||
return true;
|
||||
} else {
|
||||
if (m_fpLog != NULL)
|
||||
::fclose(m_fpLog);
|
||||
}
|
||||
|
||||
char filename[100U];
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
::sprintf(filename, "%s\\%s-%04d-%02d-%02d.log", m_filePath.c_str(), m_fileRoot.c_str(), tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday);
|
||||
#else
|
||||
::sprintf(filename, "%s/%s-%04d-%02d-%02d.log", m_filePath.c_str(), m_fileRoot.c_str(), tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday);
|
||||
#endif
|
||||
|
||||
m_fpLog = ::fopen(filename, "a+t");
|
||||
m_tm = *tm;
|
||||
|
||||
return m_fpLog != NULL;
|
||||
}
|
||||
|
||||
bool LogInitialise(const std::string& filePath, const std::string& fileRoot, unsigned int fileLevel, unsigned int displayLevel)
|
||||
{
|
||||
m_filePath = filePath;
|
||||
m_fileRoot = fileRoot;
|
||||
m_fileLevel = fileLevel;
|
||||
m_displayLevel = displayLevel;
|
||||
return ::LogOpen();
|
||||
}
|
||||
|
||||
void LogFinalise()
|
||||
{
|
||||
if (m_fpLog != NULL)
|
||||
::fclose(m_fpLog);
|
||||
}
|
||||
|
||||
void Log(unsigned int level, const char* fmt, ...)
|
||||
{
|
||||
assert(fmt != NULL);
|
||||
|
||||
char buffer[300U];
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
SYSTEMTIME st;
|
||||
::GetSystemTime(&st);
|
||||
|
||||
::sprintf(buffer, "%c: %04u-%02u-%02u %02u:%02u:%02u.%03u ", LEVELS[level], st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
|
||||
#else
|
||||
struct timeval now;
|
||||
::gettimeofday(&now, NULL);
|
||||
|
||||
struct tm* tm = ::gmtime(&now.tv_sec);
|
||||
|
||||
::sprintf(buffer, "%c: %04d-%02d-%02d %02d:%02d:%02d.%03lu ", LEVELS[level], tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, now.tv_usec / 1000U);
|
||||
#endif
|
||||
|
||||
va_list vl;
|
||||
va_start(vl, fmt);
|
||||
|
||||
::vsprintf(buffer + ::strlen(buffer), fmt, vl);
|
||||
|
||||
va_end(vl);
|
||||
|
||||
if (level >= m_fileLevel && m_fileLevel != 0U) {
|
||||
bool ret = ::LogOpen();
|
||||
if (!ret)
|
||||
return;
|
||||
|
||||
::fprintf(m_fpLog, "%s\n", buffer);
|
||||
::fflush(m_fpLog);
|
||||
}
|
||||
|
||||
if (level >= m_displayLevel && m_displayLevel != 0U) {
|
||||
::fprintf(stdout, "%s\n", buffer);
|
||||
::fflush(stdout);
|
||||
}
|
||||
|
||||
if (level == 6U) { // Fatal
|
||||
::fclose(m_fpLog);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#if !defined(LOG_H)
|
||||
#define LOG_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#define LogDebug(fmt, ...) Log(1U, fmt, ##__VA_ARGS__)
|
||||
#define LogMessage(fmt, ...) Log(2U, fmt, ##__VA_ARGS__)
|
||||
#define LogInfo(fmt, ...) Log(3U, fmt, ##__VA_ARGS__)
|
||||
#define LogWarning(fmt, ...) Log(4U, fmt, ##__VA_ARGS__)
|
||||
#define LogError(fmt, ...) Log(5U, fmt, ##__VA_ARGS__)
|
||||
#define LogFatal(fmt, ...) Log(6U, fmt, ##__VA_ARGS__)
|
||||
|
||||
extern void Log(unsigned int level, const char* fmt, ...);
|
||||
|
||||
extern bool LogInitialise(const std::string& filePath, const std::string& fileRoot, unsigned int fileLevel, unsigned int displayLevel);
|
||||
extern void LogFinalise();
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,19 @@
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
CFLAGS = -g -O3 -Wall -std=c++0x -pthread
|
||||
LIBS = -lpthread
|
||||
LDFLAGS = -g
|
||||
|
||||
OBJECTS = Conf.o Log.o Mutex.o NXCoreNetwork.o NXDNLookup.o NXDNNetwork.o NXDNReflector.o StopWatch.o Thread.o Timer.o UDPSocket.o Utils.o
|
||||
|
||||
all: NXDNReflector
|
||||
|
||||
NXDNReflector: $(OBJECTS)
|
||||
$(CXX) $(OBJECTS) $(CFLAGS) $(LIBS) -o NXDNReflector
|
||||
|
||||
%.o: %.cpp
|
||||
$(CXX) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
$(RM) NXDNReflector *.o *.d *.bak *~
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "Mutex.h"
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
||||
CMutex::CMutex() :
|
||||
m_handle()
|
||||
{
|
||||
m_handle = ::CreateMutex(NULL, FALSE, NULL);
|
||||
}
|
||||
|
||||
CMutex::~CMutex()
|
||||
{
|
||||
::CloseHandle(m_handle);
|
||||
}
|
||||
|
||||
void CMutex::lock()
|
||||
{
|
||||
::WaitForSingleObject(m_handle, INFINITE);
|
||||
}
|
||||
|
||||
void CMutex::unlock()
|
||||
{
|
||||
::ReleaseMutex(m_handle);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
CMutex::CMutex() :
|
||||
m_mutex(PTHREAD_MUTEX_INITIALIZER)
|
||||
{
|
||||
}
|
||||
|
||||
CMutex::~CMutex()
|
||||
{
|
||||
}
|
||||
|
||||
void CMutex::lock()
|
||||
{
|
||||
::pthread_mutex_lock(&m_mutex);
|
||||
}
|
||||
|
||||
void CMutex::unlock()
|
||||
{
|
||||
::pthread_mutex_unlock(&m_mutex);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#if !defined(MUTEX_H)
|
||||
#define MUTEX_H
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
class CMutex
|
||||
{
|
||||
public:
|
||||
CMutex();
|
||||
~CMutex();
|
||||
|
||||
void lock();
|
||||
void unlock();
|
||||
|
||||
private:
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
HANDLE m_handle;
|
||||
#else
|
||||
pthread_mutex_t m_mutex;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2014,2016,2018 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "NXCoreNetwork.h"
|
||||
#include "Utils.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
const unsigned int BUFFER_LENGTH = 200U;
|
||||
|
||||
const unsigned int NXCORE_PORT = 41300U;
|
||||
|
||||
CNXCoreNetwork::CNXCoreNetwork(const std::string& address, bool debug) :
|
||||
m_socket("", NXCORE_PORT),
|
||||
m_address(),
|
||||
m_debug(debug),
|
||||
m_buffer(1000U, "NXCore Network")
|
||||
{
|
||||
assert(!address.empty());
|
||||
|
||||
m_address = CUDPSocket::lookup(address);
|
||||
}
|
||||
|
||||
CNXCoreNetwork::~CNXCoreNetwork()
|
||||
{
|
||||
}
|
||||
|
||||
bool CNXCoreNetwork::open()
|
||||
{
|
||||
LogMessage("Opening NXCore network connection");
|
||||
|
||||
if (m_address.s_addr == INADDR_NONE)
|
||||
return false;
|
||||
|
||||
return m_socket.open();
|
||||
}
|
||||
|
||||
bool CNXCoreNetwork::write(const unsigned char* data, unsigned int len)
|
||||
{
|
||||
assert(data != NULL);
|
||||
|
||||
unsigned char buffer[110U];
|
||||
::memset(buffer, 0x00U, 110U);
|
||||
|
||||
buffer[0U] = 'I';
|
||||
buffer[1U] = 'C';
|
||||
buffer[2U] = 'O';
|
||||
buffer[3U] = 'M';
|
||||
buffer[4U] = 0x01U;
|
||||
buffer[5U] = 0x01U;
|
||||
buffer[6U] = 0x08U;
|
||||
buffer[7U] = 0xE0U;
|
||||
|
||||
buffer[37U] = 0x23U;
|
||||
buffer[38U] = (data[9U] & 0x0CU) != 0x00U ? 0x1CU : 0x10U;
|
||||
buffer[39U] = 0x21U;
|
||||
|
||||
::memcpy(buffer + 40U, data + 10U, 33U);
|
||||
|
||||
if (m_debug)
|
||||
CUtils::dump(1U, "NXCore Network Data Sent", buffer, 102U);
|
||||
|
||||
return m_socket.write(buffer, 102U, m_address, NXCORE_PORT);
|
||||
}
|
||||
|
||||
void CNXCoreNetwork::clock(unsigned int ms)
|
||||
{
|
||||
unsigned char buffer[BUFFER_LENGTH];
|
||||
|
||||
in_addr address;
|
||||
unsigned int port;
|
||||
int length = m_socket.read(buffer, BUFFER_LENGTH, address, port);
|
||||
if (length <= 0)
|
||||
return;
|
||||
|
||||
// Check if the data is for us
|
||||
if (m_address.s_addr != address.s_addr || port != NXCORE_PORT) {
|
||||
LogMessage("NXCore packet received from an invalid source, %08X != %08X and/or %u != %u", m_address.s_addr, address.s_addr, NXCORE_PORT, port);
|
||||
return;
|
||||
}
|
||||
|
||||
// Invalid packet type?
|
||||
if (::memcmp(buffer, "ICOM", 4U) != 0)
|
||||
return;
|
||||
|
||||
if (length != 102)
|
||||
return;
|
||||
|
||||
if (m_debug)
|
||||
CUtils::dump(1U, "NXCore Network Data Received", buffer, length);
|
||||
|
||||
m_buffer.addData(buffer + 40U, 33U);
|
||||
}
|
||||
|
||||
bool CNXCoreNetwork::read(unsigned char* data, unsigned int len)
|
||||
{
|
||||
assert(data != NULL);
|
||||
|
||||
if (m_buffer.isEmpty())
|
||||
return false;
|
||||
|
||||
m_buffer.getData(data, 33U);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CNXCoreNetwork::close()
|
||||
{
|
||||
m_socket.close();
|
||||
|
||||
LogMessage("Closing NXCore network connection");
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2014,2016,2018 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef NXCoreNetwork_H
|
||||
#define NXCoreNetwork_H
|
||||
|
||||
#include "RingBuffer.h"
|
||||
#include "UDPSocket.h"
|
||||
#include "Timer.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
class CNXCoreNetwork {
|
||||
public:
|
||||
CNXCoreNetwork(const std::string& address, bool debug);
|
||||
~CNXCoreNetwork();
|
||||
|
||||
bool open();
|
||||
|
||||
bool write(const unsigned char* data, unsigned int len);
|
||||
|
||||
bool read(unsigned char* data, unsigned int len);
|
||||
|
||||
void close();
|
||||
|
||||
void clock(unsigned int ms);
|
||||
|
||||
private:
|
||||
CUDPSocket m_socket;
|
||||
in_addr m_address;
|
||||
bool m_debug;
|
||||
CRingBuffer<unsigned char> m_buffer;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,405 @@
|
||||
UID,Call,Name,Location,Notes
|
||||
2,W2FLY/M,Harry,Southern NJ,UHF NX-800 mobile
|
||||
3,WB2OOM/M,Tina,Southern NJ,UHF NX-800 Mobile
|
||||
4,W2FLY/M,Harry,Southern NJ,UHF NX-800 Van
|
||||
7,F1PRY,Emmanuel,BEAUVAIS FR,
|
||||
8,W2FLY/P,Harry,Southern NJ,UHF NX-820 Port 2
|
||||
9,KE8BGA,Lowell Katz,"Cleveland, Ohio","on the north shore, NX-800"
|
||||
17,KC2SNI,Jim Hannon,"West Berlin, New Jersey",My Radio is an Icom IC-3161DT
|
||||
25,WB2RUH/P,Bruce,Southern NJ,UHF NX-320
|
||||
26,WB2RUH/M,Bruce,Southern NJ,UHF NX-800 mobile
|
||||
30,KD4MOJ,Doug,,Doug
|
||||
74,N2IXC,Ed,Chatsworth NJ,
|
||||
76,W2FLY/P,Harry,Southern NJ,UFH NX5300 Port 1
|
||||
77,W2FLY/P,Harry,"Somers Point, NJ",UHF NX-800 Shore Base
|
||||
78,W2FLY,Harry,"Mullica Hill, NJ",UHF NX-800
|
||||
79,W2FLY/M,Harry,Southern NJ,UHF NX-5800
|
||||
80,W2FLY/M,Harry,Southern NJ,VHF NX-5700 mobile
|
||||
82,W2FLY/P,Harry,"Somers Point, NJ",VHF NX-700 Shore Base
|
||||
85,W2FLY/M,Harry,Southern NJ,VHF NX_700 van
|
||||
86,W2FLY,Harry,"Mullica Hill, NJ",VHF NX-700 base
|
||||
87,W2FLY/M,Harry,Southern NJ,VHF NX-700 mobile
|
||||
88,W2FLY/P,Harry,Southern NJ,VHF NX-220 portable
|
||||
89,WB2RUH,Bruce,Vineland NJ,VHF NX-700 base
|
||||
99,K1ZSG,Don,,Mobile
|
||||
134,N2SRO,Mike,Pitman,Mobile Radio
|
||||
134,N2SRO,Mike,NJ,
|
||||
141,KF2M,Greg Popovich,"Mt Laurel, NJ",IC-F4161DT
|
||||
401,W1KFR,Bill,,Bill
|
||||
901,K1IFF,Cliff,CT,Cliff NX320
|
||||
902,K1IFF,Cliff,CT,Cliff NX320 - demo
|
||||
903,K1IFF,Cliff,CT,Cliff NX800H
|
||||
905,WA1LMV,Rick,,Rick NX320
|
||||
906,K1IFF,Cliff,CT,Cliff NX200
|
||||
907,K1IFF,Cliff,CT,Future
|
||||
908,W4CLL,Chuck,,CHUCK
|
||||
909,AB1UB V,Woody,"Bristol, CT",
|
||||
909,AB1UB,Woody,"Bristol, CT",
|
||||
909,AB1UB,Woody,,Woody NX300
|
||||
909,W4CCL,Chuck,,CHUCK
|
||||
910,W4CLL,Chuck,,CHUCK
|
||||
911,W4CLL,Chuck,,CHUCK
|
||||
912,W4CCL,Chuck,,CHUCK
|
||||
920,N1XDN,Bob,CT,Bob P1 UHF NX300
|
||||
921,N1XDN,Bob,CT,Bob P1 VHF NX220
|
||||
922,N1XDN,Bob,CT,Bob P2 UHF NX300
|
||||
923,N1XDN,Bob,CT,Bob M1 VHF NX700
|
||||
924,N1XDN,Bob,CT,Bob P3 UHF NX-5300
|
||||
925,N1XDN,Bob,CT,Bob P2 VHF NX-5200
|
||||
926,N1XDN,Bob,CT,Bob M1 UHF NX-5800
|
||||
928,N1XDN,Bob,CT,Icom portable
|
||||
930,K1IFF,Cliff,CT,NX300
|
||||
931,K1IFF,Cliff,CT,NX300
|
||||
936,W1GPO,John,,NX300
|
||||
951,K1KGQ,Joel,,Joel NX800H
|
||||
952,K1KGQ,Joel,CT,Truck radio
|
||||
952,K1GML,Gail,,Gail NX800H
|
||||
953,K1KGQ,Joel,,Joel NX320-1
|
||||
954,K1KGQ,Joel,,
|
||||
955,K1KGQ,Joel,,
|
||||
956,K1KGQ,Joel,,
|
||||
957,K1KGQ,Joel,,
|
||||
958,K1KGQ,Joel,,Joel F4161
|
||||
959,K1KGQ,Joel,,Future
|
||||
960,K1ZXX,Gary,,Gary - Icom All radios
|
||||
961,WA1SSB,Joe,,Joe NX800H
|
||||
962,N1MAT,Dennis,,Dennis F4161
|
||||
963,N1MAT,Dennis,,Dennis F4161
|
||||
970,KB1VRI,Nick,CT,
|
||||
970,KB1VRI,Nick,,Nick
|
||||
971,N1ELE,Paul,CT,
|
||||
972,N1ODJ,Kenny Schmitz,Middletown,
|
||||
973,W1VLF,Paul,CT,
|
||||
980,W1RHS,Rick,Connecticut,
|
||||
995,K1IFF/Base,Cliff,"Brsitol, CT",NXR710 link radio
|
||||
1001,KE4GWW,James,AL,NX200 Portable #1
|
||||
1002,KE4GWW,James,AL,NX200 Portable #2
|
||||
1003,KE4GWW,James,AL,NX300 Portable #1
|
||||
1004,KE4GWW,James,AL,NX300 Portable #2
|
||||
1005,KE4GWW,James,AL,NX700 Base
|
||||
1006,KE4GWW,James,AL,NX800 Base
|
||||
1007,KE4GWW,James M. Nelson,"Dothan, AL",NX700 Mobile#1
|
||||
1008,DK6PX,Stefan,Germany nr Bad Toelz,Coming up FR6000
|
||||
1008,KE4GWW,James,AL,NX700 Mobile#2
|
||||
1009,KE4GWW,James,AL,NX800 Mobile#1
|
||||
1010,KE4GWW,James,AL,NX800 Mobile#2
|
||||
1066,KM4JXP,Peter Tasker,Longboat Key,NX5300
|
||||
1954,W4BPT,BILLY TAYLOR,"RINGGOLD,GA.",
|
||||
1956,KC7SDD,Dana Hanford,"Bainbridge Island, WA","Member BARC, W7NPC.org"
|
||||
1963,N5JRN,David Barts,"Bainbridge Island, WA","Handheld, Icom 4161"
|
||||
1966,ZS6IIX,Henry,Petit South Africa,
|
||||
1997,KC1AJR,Giovanni,East Hampton CT,kenwood NX800 K2
|
||||
3070,W4ORL,Ralph,,Ralph - Mobile
|
||||
3071,W4LOV,Mike,,Mike - NX800
|
||||
3072,N4JTK,John,,John - NX800
|
||||
3074,W4MCA,Michael,,Michael - NX300
|
||||
3075,W4LOV,Mike,,Mike - NX800
|
||||
3079,NN4TT,Dave,Orlando,NX300
|
||||
3079,W4ORL,Ralph,,Ralph - Portable
|
||||
3081,W4MCA,Michael,,Michael - NX800
|
||||
3082,W4LOV,Mike,,Mike - Portable
|
||||
3083,KD4TWJ,Dean,,Dean - Mobile NX800
|
||||
3271,N4KEG,Richard,,RICHARD - Mobile and or ht's N4KEG (UHF)
|
||||
3274,KD4EFM,Evans,FL,
|
||||
3275,KD4EFM,Evans,FL,
|
||||
3278,KD4EFM,Evans,FL,
|
||||
3279,N4KEG,Richard,,
|
||||
3280,KD4EFM,Evans,"Lakeland, Florida",work radio
|
||||
3280,KD4EFM,Evans,FL,Evans Mobile(s)
|
||||
3280,KD4EFM,Evans,FL,
|
||||
3281,N4KEG,Richard,,
|
||||
3450,K0KAD,CHAD TAYLOR,"SPOKANE VALLEY, WA",My Portable
|
||||
3451,K0KAD,CHAD TAYLOR,"SPOKANE VALLEY, WA",My Base Station
|
||||
3452,K0KAD,CHAD TAYLOR,"SPOKANE VALLEY, WA",Mobile Radio
|
||||
4020,K4XXX,Ed,"London, KY",NX820 Base
|
||||
4802,hb3yrb,Alex,Verbier,nx5300
|
||||
4804,hb9fmf,Didier,Rougemont,NX5300
|
||||
5001,N5QZ,Ryan,AR,"N5QZ, Ryan McAfee, Searcy, AR - Kenwood NX-820"
|
||||
5002,N5QZ,Ryan,AR,"N5QZ, Ryan McAfee, Searcy, AR - Kenwood NX-720"
|
||||
5003,N5QS,Roger,AR,"N5QS, Roger Gray, Searcy, AR - Kenwood NX-820"
|
||||
5004,N5QS,Roger,AR,"N5QS, Roger Gray, Searcy, AR - Kenwood NX-720"
|
||||
5005,AC5AV,Larry,AR,"AC5AV, Larry Sicks, Searcy, AR"
|
||||
5006,AC5AV,Larry,AR,"AC5AV, Larry Sicks, Searcy, AR"
|
||||
5007,N5LKE,James,AR,"N5LKE, James Ferguson, Searcy, AR - Kenwood NX-800"
|
||||
5008,AF5WN,Mason,AR,"AF5WN, Mason Creager, Cabot, AR - Kenwood NX-700H"
|
||||
5009,KJ5SF,Stan,AR,"KJ5SF, Stan Rongey, Searcy, AR - Kenwood NX-800"
|
||||
5100,K5SRS,Michael Smith,"Fayetteville, AR",NX-5800 Mobile
|
||||
5101,KC5YQB,Paul Blair,"Fayetteville, AR",
|
||||
5125,AE5OQ,Armstead,"Higden, AR",
|
||||
5125,AE5OQ,Armstead,AR,entered by k1iff
|
||||
5134,AE5OQ,Armstead,AR,"AE5OQ, Armstead M Feland, IV, Higdon, AR - Kenwood NX-200"
|
||||
5150,WY6NN,Doug,"Los Angeles, CA",NX-300/5300
|
||||
5151,KC6HFJ,Tamara,"Los Angeles, CA",NX-300
|
||||
5170,K5WMZ,Gary,AR,"K5WMZ, Gary D Partlow, Ward, AR - Kenwood NX-700"
|
||||
5599,W1ZM,Ryan,,"W1ZM, Ryan Nelson, NX-5300"
|
||||
5987,W5ZN,Joel,AR,"W5ZN, Joel Harrison, Judsonia, AR - Kenwood NX-800"
|
||||
6430,K4GFD,Norm,FL,Norm Greensboro Fla
|
||||
6431,K4GFD,Norm,,
|
||||
6432,K4GFD,Norm,,
|
||||
6439,N4NKV,George,,George
|
||||
6801,hb9vsd,relais de verbier,verbier,
|
||||
6802,HB9YRB,Alex,Verbier,
|
||||
6804,HB9FMF,Didier,Rougemont,
|
||||
7737,N4NKV,George,,George
|
||||
9834,VA7NY,PJ,,PJ
|
||||
12002,W4KJP,Kevin,,KEVIN
|
||||
12005,KD4TWJ,Dean,,Dean - Portable IC-F4161
|
||||
12006,W4MO,Stewart,,STEWART NX300 / 320
|
||||
12007,W4MO,Stewart,,STEWART NX800
|
||||
12010,kd4dwp,Ben,Orlando,
|
||||
12013,K4NBC,Miguel Orama,"Palm Bay, Florida",Icom F4146DS UHF Portable
|
||||
12014,K4NBC,Miguel Orama,"Palm Bay, Florida",Kenwood NX200 VHF HT
|
||||
12015,K4NBC,K4NBC-Miguel UHF Mobile,"Palm Bay, Florida",Future UHF Mobile
|
||||
12016,K4NBC,Miguel,"Palm Bay, Florida",M2 Icom F6061D
|
||||
12017,N4JFZ,,,
|
||||
12021,W4PJT,Paul,,Paul
|
||||
12023,KD4NWL,John,,JOHN
|
||||
12127,W4KDM,Rick,,Rick - Portable NX300
|
||||
12136,WA4KWK,John,,John F6121
|
||||
12200,NB9X,Paul,FL,
|
||||
12201,NB9X,Paul,FL,PAUL
|
||||
12202,NB9X,Paul,FL,
|
||||
12203,NB9X,Paul,FL,
|
||||
12204,WX3C,Juan Arias,Florida,Orlando metro
|
||||
12204,NB9X,Paul,FL,
|
||||
12210,N4APG,Bill,,Bill Pfost
|
||||
12211,N4APG,Bill,,Bill Pfost
|
||||
12212,N4APG,Bill,,Bill Pfost
|
||||
12213,N4APG,Bill,,Bill Pfost
|
||||
12214,N4APG,Bill,,Bill Pfost
|
||||
12215,WA4ISB,Ed,,ED Mobile
|
||||
12216,WA4ISB,Ed,,
|
||||
12220,N4PK,Paul,,PAUK K.
|
||||
12221,N4PK,Paul,,
|
||||
12222,W4PJT,Paul,,
|
||||
12223,W4PJT,Paul,,
|
||||
12226,KI4SWY,William,,
|
||||
12230,KQ4KX,Richard,,Richard Sharp
|
||||
12231,KQ4KX,Richard,,
|
||||
12234,KD4TWJ,Dean,EL98,
|
||||
12235,N1IC,Nick,,Nic
|
||||
12236,N1IC,Nick,,
|
||||
12240,KR4X,Larry,,
|
||||
12241,KR4X,Larry,,
|
||||
12245,KD4ACG,Jason,"Hudson, FL",Icom Mobile
|
||||
12245,KD4ACG,Jason,,JASON
|
||||
12246,KD4ACG,Jason,"Hudson, FL",Icom Portable
|
||||
12246,KD4ACG,Jason,,JASON
|
||||
12247,K2MCI,,,
|
||||
12250,KE4GYX,,,
|
||||
12272,KE4OSL,,,
|
||||
12273,KE4OSL,,,
|
||||
12374,KF4I,Thom,,Thom Base
|
||||
12375,KF4I,Thom,,Thom Mobile
|
||||
12523,KM4JVE,Ana,,Ana - IC-F4161
|
||||
12577,N2DLX,Richard,,Rich Dunajewski NX-5800
|
||||
12604,K4CBN,Greg,,GREG
|
||||
12605,K4CBN,Greg,,
|
||||
12606,K4CBN,Greg,,
|
||||
12607,K4CBN,Greg,,
|
||||
12608,K4CBN,Greg,,
|
||||
12666,KI4SWY,William,,William Stillwel ( All Radios )
|
||||
12691,KE3WDW,Sam,,Sam
|
||||
12780,KC4YUA,Brett,,BRETT
|
||||
13105,W7QO,Alan,,
|
||||
13106,W7QO,Alan,,
|
||||
13107,W7QO,Alan,,
|
||||
13121,W4CML,Chuck,,
|
||||
13122,W4CML,Chuck,,
|
||||
13125,KD4APP,Don,,Don - NX300
|
||||
13126,KD4APP,Don,,Don - F6061D
|
||||
13127,KD4APP,Don,,Don - NX200
|
||||
13131,W5JR,Mike,,
|
||||
13132,W5JR,Mike,,
|
||||
13401,W1KFR,Bill,,Bill
|
||||
13815,KG4BKO,Bill,GA,nx320
|
||||
14020,K4XXX,Ed,"London, KY",NX5300
|
||||
14021,K4XXX,Ed,"London, KY",NX5200
|
||||
15001,N5QZ,Ryan,AR,"N5QZ, Ryan McAfee, Searcy, AR - Kenwood NX-800H (Vehicle 1)"
|
||||
15002,N5QZ,Ryan,AR,"N5QZ, Ryan McAfee, Searcy, AR - Kenwood NX-700 (Vehicle 1)"
|
||||
15003,N5QZ,Ryan,AR,"N5QZ, Ryan McAfee, Searcy, AR - Kenwood NX-800 (Vehicle 2)"
|
||||
15004,N5QZ,Ryan,AR,"N5QZ, Ryan McAfee, Searcy, AR - Kenwood NX-700 (Vehicle 2)"
|
||||
15005,N5QS,Roger,AR,"N5QS, Roger Gray, Searcy, AR - Kenwood NX-800 (Vehicle 1)"
|
||||
15006,N5QS,Roger,AR,"N5QS, Roger Gray, Searcy, AR - Kenwood NX-700 (Vehicle 1)"
|
||||
15007,N5QS,Roger,AR,"N5QS, Roger Gray, Searcy, AR - Kenwood NX-800 (Vehicle 2)"
|
||||
15008,N5QS,Roger,AR,"N5QS, Roger Gray, Searcy, AR - Kenwood NX-700 (Vehicle 2)"
|
||||
15009,N5QS,Roger,AR,"N5QS, Roger Gray, Searcy, AR - Kenwood NX-800 (Vehicle 3)"
|
||||
15010,N5QS,Roger,AR,"N5QS, Roger Gray, Searcy, AR - Kenwood NX-700 (Vehicle 3)"
|
||||
15011,N5QT,Dawn,AR,"N5QT, Dawn Gray, Searcy, AR - Kenwood NX-800"
|
||||
15012,AC5AV,Larry,AR,"AC5AV, Larry Sicks, Searcy, AR - Kenwood NX-800"
|
||||
15013,AC5AV,Larry,AR,"AC5AV, Larry Sicks, Searcy, AR - Kenwood NX-700"
|
||||
15014,N5QT,Dawn,AR,"N5QT, Dawn Gray, Searcy, AR - Kenwood NX-700"
|
||||
15015,N5QS,Roger,AR,"N5QS, Roger Gray, Searcy, AR Motorcycle Mobile"
|
||||
15016,KG5KS,Kenny,,"KG5KS, Kenny Thompson - Kenwood NX-700HK"
|
||||
15017,KG5KS,Kenny,,"KG5KS, Kenny Thompson - Kenwood NX-800HK"
|
||||
15018,N5QS,Roger,AR,"N5QS, Roger Gray, Searcy, AR ATV Mobile"
|
||||
15019,N5QS,Roger,AR,"N5QS, Roger Gray, Searcy, AR ATV Mobile"
|
||||
15020,WA8UBL,Allen,AR,"WA8UBL, Allen Herrick, Beebe, AR, Kenwood NX-700"
|
||||
15021,KD5HRT,Heath,AR,"KD5HRT, Heath Taylor, McRae, AR, Kenwood NX-800"
|
||||
15022,WA8UBL,Allen,AR,"WA8UBL, Allen Herrick, Beebe, AR - Kenwood NX-800"
|
||||
15023,N5ZA,Joel,AR,"N5ZA, Joe Belew, Beebe, AR - Kenwood NX-700"
|
||||
15024,KF5TPF,Ryan,AR,"KF5TPF, Ryan Nelson, Edgemont, AR NX-700"
|
||||
15025,KE5YZP,Ryan,AR,"KE5YZP, Ryan Schwarck, Batesville, AR NX-700"
|
||||
15026,AF5OD,Landon,AR,"AF5OD, Landon McCord, Searcy, AR"
|
||||
15027,KB5RFF,Scott,AR,"KB5RFF, Scott Gray, Searcy, AR - Kenwood NX-800"
|
||||
17002,KC9GMX,Stephen,,Stephen - Base F6121D
|
||||
17004,KC9GMX,Stephen,,Stephen - F6061D
|
||||
17005,KC9NPJ,Jarrett,,Jarrett F6121D
|
||||
17006,KC9GMX,Stephen,,Stephen - F4161DS
|
||||
17007,KC9NPJ,Jarrett,,Jarrett F4231DS
|
||||
17008,KC9RHH,Jesse,,F4101D
|
||||
17009,KC9PHK,Michael,,F4061DS
|
||||
17011,N9BRG,Dan,,Dan kenwood nx800k2
|
||||
17855,AG6RN,Demian,CA,NX-210
|
||||
21007,WA1LMV,Rick,,Rick
|
||||
21014,K2BUI,Eric,,Eric
|
||||
24020,K4XXX,Ed,"London, KY",NX5800
|
||||
24021,K4XXX,Ed,"London, KY",NX5700
|
||||
25001,N5QZ,Ryan,AR,"N5QZ, Ryan McAfee, Searcy, AR - Kenwood NX-300"
|
||||
25002,N5QZ,Ryan,AR,"N5QZ, Ryan McAfee, Searcy, AR - Kenwood NX-200"
|
||||
25003,N5QS,Roger,AR,"N5QS, Roger Gray, Searcy, AR - Kenwood NX-300"
|
||||
25004,N5QS,Roger,AR,"N5QS, Roger Gray, Searcy, AR - Kenwood NX-200"
|
||||
25005,N5QS,Roger,AR,"N5QS, Roger Gray, Searcy, AR - Kenwood NX-320"
|
||||
25006,N5QS,Roger,AR,"N5QS, Roger Gray, Searcy, AR - Kenwood NX-340U"
|
||||
25007,N5QT,Dawn,AR,"N5QT, Dawn Gray, Searcy, AR - Kenwood NX-300"
|
||||
25008,N5QT,Dawn,AR,"N5QT, Dawn Gray, Searcy, AR - Kenwood NX-200"
|
||||
25009,AC5AV,Larry,AR,"AC5AV, Larry Sicks, Searcy, AR - Kenwood NX-300"
|
||||
25010,KD5OOW,Tom,AR,"KD5OOW, Tom McGee, Searcy, AR - Kenwood NX-300"
|
||||
25011,W5ZN,Joel,AR,"W5ZN, Joel Harrison, Judsonia, AR - Kenwood NX-300"
|
||||
25012,KD5HRT,Heath,AR,"KD5HRT, Heath Taylor, McRae, AR - Kenwood NX-300"
|
||||
25013,KK5WA,Darin,AR,"KK5WA, Darin Dykes, Beebe, AR - Kenwood NX-320"
|
||||
25014,N5LKE,James,AR,"N5LKE, James Ferguson, Searcy, AR - Kenwood NX-5300"
|
||||
25015,KJ5ORD,John,AR,"KJ5ORD, John Ord, Searcy, AR - Kenwood NX-300"
|
||||
25016,KB5RFF,Scott,AR,"KB5RFF, Scott Gray, Searcy, AR - Kenwood NX-300"
|
||||
25017,KB5ZUH,Todd,AR,"KB5ZUH, Todd Williams, Searcy, AR - Kenwood NX-320"
|
||||
25018,KB5ZUH,Todd,AR,"KB5ZUH, Todd Williams, Searcy, AR - Kenwood NX-340"
|
||||
25019,KB5ZUH,Todd,AR,"KB5ZUH, Todd Williams, Searcy, AR - Kenwood NX-340"
|
||||
25020,KB5ZUH,Todd,AR,"KB5ZUH, Todd Williams, Searcy, AR - Kenwood NX-320"
|
||||
25021,KE5UZU,Raymond Prince,"England, AR",Kenwood Handheld
|
||||
25021,AF5OD,Landon,AR,"AF5OD, Landon McCord, Searcy, AR"
|
||||
25022,KE5UZU,Raymond Prince,"England, AR",Icom Handheld
|
||||
25022,KE5YZP,Ryan,AR,"KE5YZP, Ryan A Schwarck, Batesville, AR - Icom"
|
||||
25023,KE5YZP,Ryan,AR,"KE5YZP, Ryan A Schwarck, Batesville, AR - Icom"
|
||||
25024,KG5CHM,Colt,AR,"KG5CHM, Colt Boyd, Searcy, AR - Kenwood NX-300"
|
||||
25025,KJ5ORD,John,AR,"KJ5ORD, John Ord, Searcy, AR - Kenwood NX-xxx VHF"
|
||||
25026,WA8UBL,Allen,AR,"WA8UBL, Allen Herrick, Beebe, AR - Kenwood NX-320"
|
||||
25027,KF5TPF,Ryan,AR,"KF5TPF, Ryan Nelson, Edgemont, AR - Kenwood NX-200"
|
||||
25028,WA8UBL,Allen,AR,"WA8UBL, Allen Herrick, Beebe, AR - Kenwood NX-220"
|
||||
25029,KF5WHX,Trey,AR,"KF5WHX, Trey Ferguson, Searcy, AR - Kenwood NX-320"
|
||||
25030,AC5AV,Larry,AR,"AC5AV, Larry Sicks, Searcy, AR"
|
||||
25031,KJ5SF,Stan,AR,"KJ5SF, Stan Rongey, Searcy, AR - Kenwood NX-340"
|
||||
25032,KC5DFH,Kirk,AR,"KC5DFH, Kirk Williams, Searcy, AR - Kenwood NX-340"
|
||||
25033,AF5OD,Landon,AR,"AF5OD, Landon McCord, Searcy, AR, Icom F4161DS"
|
||||
25034,KF5TPF,Ryan,AR,"KF5TPF, Ryan Nelson, Edgemont, AR - ICOM 4161"
|
||||
25035,KG5BMB,Glenda,AR,"KG5BMB, Glenda McCord, Searcy, AR, Icom F4161DS"
|
||||
25039,KC1JET,Jim,,JIM (BASE)
|
||||
25068,N1QD,Joe,,
|
||||
25069,N1COP,Bob,,Bob
|
||||
25070,WD1L,John,,John
|
||||
25125,N1TI,Tim,"Mattapoisett, MA",
|
||||
25125,N1TI,Tim,"Mattapoisett, MA",
|
||||
25144,W1WCF,Walter,,Walter
|
||||
25221,N0XIA,James,,James - Kenwood Mobile and Portable
|
||||
25222,KE4SDC,Ron,,Ron - Portable NX300
|
||||
25246,WG1U,Ken,"Assonet, MA",
|
||||
25333,W1AKN,Jack,,Jack Mobile
|
||||
25390,KC1JET,Jim,,JIM (MOBILE)
|
||||
25390,KC1JET,Jim,,JIM
|
||||
25444,W1TAV,Steve,,Steve
|
||||
25555,WA1MNQ,Mike,,Mike
|
||||
25582,N1KXJ,Ray,"E. Bridgewater, MA.",Port.
|
||||
25582,N1KXJ,Ray Wall,East Bridgewater,
|
||||
25585,N1AVA,Ken Howland,"DARTMOUTH,MA",
|
||||
25700,NN1D,Tony Souza,"Swansea, MA",
|
||||
25740,WG1U,Kenny,,KEN
|
||||
25743,WG1U,Kenny,,KEN
|
||||
25746,N1OTY,John,,JOHN
|
||||
25777,W1BON,Bump,,Bump
|
||||
25830,KB1CHU,Steve,MA,
|
||||
25863,N1ZZN,Jeff,,JEFF
|
||||
25874,KB1KVD,Jason,,Jason - Icom Mob & Port
|
||||
25888,K1WGU,Bob,,Bob
|
||||
25889,AB1CQ,Gary,,Gary
|
||||
25900,N1ZZR,Matt,,Matt - mobile
|
||||
25901,N1MRC,Matt,"Bridgewater, MA",N1MRC P-1
|
||||
25901,N1ZZR,Matt,,Matt
|
||||
25957,KC1HO,Steve,,STEVE
|
||||
27101,KI4SWB,Mark,"Melbourne Beach, FL",Icom Portable
|
||||
27102,KP4OO,Carlos,"Palm Bay, FL",Icom Portable
|
||||
27201,KI4SWB,Mark,"Melbourne Beach, FL",Icom Mobile
|
||||
27202,KP4OO,Carlos,"Palm Bay, FL",Icom Mobile
|
||||
28001,K3KRS,rYAN,CLEVLAND,OHIO
|
||||
30505,KG6MQE,Jim,MT,
|
||||
30571,WX4RCF,Ryan F.,"Tampa, FL",
|
||||
31117,K4QHR,Pete,,Pete
|
||||
31124,KM4JXP,Peter,,NX5300
|
||||
31146,KD2KWD,Michael Santamaria,"Brandon, FL",Kenwood
|
||||
33000,N1PA-R,Paul,NH,PAUL - NEW HAMPSHIRE REPEATER
|
||||
33001,N1PA,Paul,NH,PAUL - NEW HAMPSHIRE
|
||||
33002,N1PA,Paul,NH,PAUL - NEW HAMPSHIRE
|
||||
34001,N2WNS,Bill,NJ,N2WNS Portable
|
||||
34002,N2WNS,Bill,NJ,N2WNS Base
|
||||
36001,W2CCR,Chris,NY,"Chris, Galway, NY NX300"
|
||||
36002,KC2VOB,Asad,NY,"Asad, NYC, NX-5800"
|
||||
36003,KC2VOB,Asad,NY,"Asad, NYC, NX-300GK"
|
||||
36134,N2SRO,Mike,"Pitman, NJ",Portable
|
||||
37001,KA4YMY,Steve,NC,"Steve, Charlotte, NC NX320"
|
||||
37009,KA4YMY,Steve,"Charlotte, NC",
|
||||
37010,KA4YMY,Steve,"Charlotte, NC",
|
||||
37010,KA4YMY,Steve,"Charlotte, NC",
|
||||
40024,N5YEI,Jeff Dalrymple,"Jay, Oklahoma",NX-5800 Mobile
|
||||
40124,N5YEI,Jeff Dalrymple,"Jay, Oklahoma",NX-5300 Portable
|
||||
43751,N4IRS,Steve,,Steve
|
||||
44001,K2BUI,Eric,RI,
|
||||
44002,K2BUI,Eric,"Providence, RI",
|
||||
44007,W2DAN,Dave,,Dave - NX700
|
||||
44298,N1JBC,Jed,,JED
|
||||
49101,WX7Y-1,Bret Mills,Castle Dale Utah,WX7y-1 Hand Held 1
|
||||
49102,WX7Y-2,Bret Mills,"Caslte Dale, Utah",WX7Y-2 Hand held
|
||||
49104,WX7Y-4,Bret Mills,"Castle Dale, Utah",WX7Y-4 Mobile
|
||||
49106,WX7Y-6,Bret Mills,Castle Dale,WX7Y-6 Mobile
|
||||
55700,WB9HKE,Rick,WI,
|
||||
55704,WB9HKE,Rick,WI,
|
||||
57000,VE3SP,Andre,"Toronto, ON",mobile
|
||||
57001,VE3SP,Andre,"Toronto, ON",handheld
|
||||
57001,VE3EI,Eric,,Eric - Portable
|
||||
57002,VE3OKZ,Janusz,"Toronto, ON",mobile
|
||||
57002,VE3EI,Eric,,Eric - Dongle
|
||||
57003,VE3OKZ,Janusz,"Toronto, ON",handheld
|
||||
57004,VE3CCD,Curtis,"Scarborough, ON",handheld
|
||||
57005,VE3NBI,Anoop,"Scarborough, ON",handheld
|
||||
57006,VE3JLU,Sherwin,"Scarborough, ON",handheld
|
||||
57007,va3rq,Jon,"Oakville, ON",handheld
|
||||
57008,ve3ogb,Randy,"Toronto, ON",handheld
|
||||
57009,va3mk,Mark,"Oakville, ON",handheld
|
||||
57010,va3mk,Mark,"Oakville, ON",mobile
|
||||
57011,VA3WZW,Andre,"Durham, ON",mobile
|
||||
57012,VA3WZW,Andre,"Durham, ON",mobile
|
||||
57013,VA3AGV,cottage,"Toronto, ON",mobile
|
||||
57014,VE3BWP,Brian,"Caledon, ON",handheld
|
||||
57015,VE3HY,Frank,"Caledon, ON",handheld
|
||||
57016,VE3UBI,Paul,"Scarborough, ON",mobile
|
||||
57017,VE3UBI,Paul,"Scarborough, ON",handheld
|
||||
57018,VE3RZR,Richard,"Toronto, ON",handheld
|
||||
57019,VE3AEP,Dom,"Toronto, ON",mobile
|
||||
57020,VA3PEO,Adrian,"Toronto, ON",handheld
|
||||
57021,va3wjo,Walter,"Toronto, ON",handheld
|
||||
57022,ve3fkn,Tom,"Stoney Creek, ON",handheld
|
||||
57023,ve3ips,John,"Toronto, ON",handheld
|
||||
57024,VA3CQA,Brian,"Scarborough, ON",handheld
|
||||
57025,VA3PAD,Andrew,"Scarborough, ON",mobile
|
||||
57026,VA3PAD,Andrew,"Scarborough, ON",handheld
|
||||
57027,VA3VAD,Arpad,"Hamilton, ON",handheld
|
||||
57028,VA3KY,Shelly,"Thornhill, ON",mobile
|
||||
57029,VA3KY,Shelly,"Thornhill, ON",handheld
|
||||
57030,VE3KFQ,Doug,"Toronto, ON",mobile
|
||||
57031,VE3KFQ,Doug,"Toronto, ON",handheld
|
||||
57032,VE3AEP,Dom 2,"Toronto, ON",handheld
|
||||
57033,VE3DJZ,Huey,"Hamilton, ON",mobile
|
||||
57034,VE3DJZ,Huey,"Hamilton, ON",handheld
|
||||
57035,VA3RQ,Jon,Oakville ON,Mobile
|
||||
3106418,N5ICK,Nicholas Nixon,"Rialto, Ca",
|
||||
3112205,N2HUC,Phil Roberts,"Port St. Lucie, FL",DV4MINI AMBE voice
|
||||
3118365,NA9VY,Chris Gilbert,"New Palestine, IN",
|
||||
3118366,N9UMJ,Rick Nicholson,Buddha Indiana,
|
||||
3142058,N3BAH,L. Abraham Smith,Southwestern Pennsylvania,
|
||||
|
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (C) 2016,2017,2018 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "NXDNLookup.h"
|
||||
#include "Timer.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cctype>
|
||||
|
||||
CNXDNLookup::CNXDNLookup(const std::string& filename, unsigned int reloadTime) :
|
||||
CThread(),
|
||||
m_filename(filename),
|
||||
m_reloadTime(reloadTime),
|
||||
m_table(),
|
||||
m_mutex(),
|
||||
m_stop(false)
|
||||
{
|
||||
}
|
||||
|
||||
CNXDNLookup::~CNXDNLookup()
|
||||
{
|
||||
}
|
||||
|
||||
bool CNXDNLookup::read()
|
||||
{
|
||||
bool ret = load();
|
||||
|
||||
if (m_reloadTime > 0U)
|
||||
run();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CNXDNLookup::entry()
|
||||
{
|
||||
LogInfo("Started the NXDN Id lookup reload thread");
|
||||
|
||||
CTimer timer(1U, 3600U * m_reloadTime);
|
||||
timer.start();
|
||||
|
||||
while (!m_stop) {
|
||||
sleep(1000U);
|
||||
|
||||
timer.clock();
|
||||
if (timer.hasExpired()) {
|
||||
load();
|
||||
timer.start();
|
||||
}
|
||||
}
|
||||
|
||||
LogInfo("Stopped the NXDN Id lookup reload thread");
|
||||
}
|
||||
|
||||
void CNXDNLookup::stop()
|
||||
{
|
||||
if (m_reloadTime == 0U) {
|
||||
delete this;
|
||||
return;
|
||||
}
|
||||
|
||||
m_stop = true;
|
||||
|
||||
wait();
|
||||
}
|
||||
|
||||
std::string CNXDNLookup::find(unsigned int id)
|
||||
{
|
||||
std::string callsign;
|
||||
|
||||
if (id == 0xFFFFU)
|
||||
return std::string("ALL");
|
||||
|
||||
m_mutex.lock();
|
||||
|
||||
try {
|
||||
callsign = m_table.at(id);
|
||||
} catch (...) {
|
||||
char text[10U];
|
||||
::sprintf(text, "%u", id);
|
||||
callsign = std::string(text);
|
||||
}
|
||||
|
||||
m_mutex.unlock();
|
||||
|
||||
return callsign;
|
||||
}
|
||||
|
||||
bool CNXDNLookup::exists(unsigned int id)
|
||||
{
|
||||
m_mutex.lock();
|
||||
|
||||
bool found = m_table.count(id) == 1U;
|
||||
|
||||
m_mutex.unlock();
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
bool CNXDNLookup::load()
|
||||
{
|
||||
FILE* fp = ::fopen(m_filename.c_str(), "rt");
|
||||
if (fp == NULL) {
|
||||
LogWarning("Cannot open the NXDN Id lookup file - %s", m_filename.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
m_mutex.lock();
|
||||
|
||||
// Remove the old entries
|
||||
m_table.clear();
|
||||
|
||||
char buffer[100U];
|
||||
while (::fgets(buffer, 100U, fp) != NULL) {
|
||||
if (buffer[0U] == '#')
|
||||
continue;
|
||||
|
||||
char* p1 = ::strtok(buffer, ",\t\r\n");
|
||||
char* p2 = ::strtok(NULL, ",\t\r\n");
|
||||
|
||||
if (p1 != NULL && p2 != NULL) {
|
||||
unsigned int id = (unsigned int)::atoi(p1);
|
||||
if (id > 0U) {
|
||||
for (char* p = p2; *p != 0x00U; p++)
|
||||
*p = ::toupper(*p);
|
||||
|
||||
m_table[id] = std::string(p2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_mutex.unlock();
|
||||
|
||||
::fclose(fp);
|
||||
|
||||
size_t size = m_table.size();
|
||||
if (size == 0U)
|
||||
return false;
|
||||
|
||||
LogInfo("Loaded %u Ids to the NXDN callsign lookup table", size);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2016,2017,2018 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef NXDNLookup_H
|
||||
#define NXDNLookup_H
|
||||
|
||||
#include "Thread.h"
|
||||
#include "Mutex.h"
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
class CNXDNLookup : public CThread {
|
||||
public:
|
||||
CNXDNLookup(const std::string& filename, unsigned int reloadTime);
|
||||
virtual ~CNXDNLookup();
|
||||
|
||||
bool read();
|
||||
|
||||
virtual void entry();
|
||||
|
||||
std::string find(unsigned int id);
|
||||
|
||||
bool exists(unsigned int id);
|
||||
|
||||
void stop();
|
||||
|
||||
private:
|
||||
std::string m_filename;
|
||||
unsigned int m_reloadTime;
|
||||
std::unordered_map<unsigned int, std::string> m_table;
|
||||
CMutex m_mutex;
|
||||
bool m_stop;
|
||||
|
||||
bool load();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2014,2016,2018 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "NXDNNetwork.h"
|
||||
#include "Utils.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
CNXDNNetwork::CNXDNNetwork(unsigned int port, bool debug) :
|
||||
m_socket(port),
|
||||
m_debug(debug)
|
||||
{
|
||||
}
|
||||
|
||||
CNXDNNetwork::~CNXDNNetwork()
|
||||
{
|
||||
}
|
||||
|
||||
bool CNXDNNetwork::open()
|
||||
{
|
||||
LogInfo("Opening NXDN network connection");
|
||||
|
||||
return m_socket.open();
|
||||
}
|
||||
|
||||
bool CNXDNNetwork::write(const unsigned char* data, unsigned int length, const in_addr& address, unsigned int port)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(length > 0U);
|
||||
assert(port > 0U);
|
||||
|
||||
if (m_debug)
|
||||
CUtils::dump(1U, "NXDN Network Data Sent", data, length);
|
||||
|
||||
return m_socket.write(data, length, address, port);
|
||||
}
|
||||
|
||||
unsigned int CNXDNNetwork::read(unsigned char* data, unsigned int length, in_addr& address, unsigned int& port)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(length > 0U);
|
||||
|
||||
int len = m_socket.read(data, length, address, port);
|
||||
if (len <= 0)
|
||||
return 0U;
|
||||
|
||||
if (m_debug)
|
||||
CUtils::dump(1U, "NXDN Network Data Received", data, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void CNXDNNetwork::close()
|
||||
{
|
||||
m_socket.close();
|
||||
|
||||
LogInfo("Closing NXDN network connection");
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2014,2016,2018 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef NXDNNetwork_H
|
||||
#define NXDNNetwork_H
|
||||
|
||||
#include "UDPSocket.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
class CNXDNNetwork {
|
||||
public:
|
||||
CNXDNNetwork(unsigned int port, bool debug);
|
||||
~CNXDNNetwork();
|
||||
|
||||
bool open();
|
||||
|
||||
bool write(const unsigned char* data, unsigned int length, const in_addr& address, unsigned int port);
|
||||
|
||||
unsigned int read(unsigned char* data, unsigned int length, in_addr& address, unsigned int& port);
|
||||
|
||||
void close();
|
||||
|
||||
private:
|
||||
CUDPSocket m_socket;
|
||||
bool m_debug;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,396 @@
|
||||
/*
|
||||
* Copyright (C) 2016,2018 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "NXCoreNetwork.h"
|
||||
#include "NXDNReflector.h"
|
||||
#include "NXDNNetwork.h"
|
||||
#include "NXDNLookup.h"
|
||||
#include "StopWatch.h"
|
||||
#include "Version.h"
|
||||
#include "Thread.h"
|
||||
#include "Utils.h"
|
||||
#include "Log.h"
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
const char* DEFAULT_INI_FILE = "NXDNReflector.ini";
|
||||
#else
|
||||
const char* DEFAULT_INI_FILE = "/etc/NXDNReflector.ini";
|
||||
#endif
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstdarg>
|
||||
#include <ctime>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
const char* iniFile = DEFAULT_INI_FILE;
|
||||
if (argc > 1) {
|
||||
for (int currentArg = 1; currentArg < argc; ++currentArg) {
|
||||
std::string arg = argv[currentArg];
|
||||
if ((arg == "-v") || (arg == "--version")) {
|
||||
::fprintf(stdout, "NXDNReflector version %s\n", VERSION);
|
||||
return 0;
|
||||
} else if (arg.substr(0, 1) == "-") {
|
||||
::fprintf(stderr, "Usage: NXDNReflector [-v|--version] [filename]\n");
|
||||
return 1;
|
||||
} else {
|
||||
iniFile = argv[currentArg];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CNXDNReflector* reflector = new CNXDNReflector(std::string(iniFile));
|
||||
reflector->run();
|
||||
delete reflector;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
CNXDNReflector::CNXDNReflector(const std::string& file) :
|
||||
m_conf(file),
|
||||
m_repeaters()
|
||||
{
|
||||
}
|
||||
|
||||
CNXDNReflector::~CNXDNReflector()
|
||||
{
|
||||
}
|
||||
|
||||
void CNXDNReflector::run()
|
||||
{
|
||||
bool ret = m_conf.read();
|
||||
if (!ret) {
|
||||
::fprintf(stderr, "NXDNReflector: cannot read the .ini file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = ::LogInitialise(m_conf.getLogFilePath(), m_conf.getLogFileRoot(), m_conf.getLogFileLevel(), m_conf.getLogDisplayLevel());
|
||||
if (!ret) {
|
||||
::fprintf(stderr, "NXDNReflector: unable to open the log file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
bool m_daemon = m_conf.getDaemon();
|
||||
if (m_daemon) {
|
||||
// Create new process
|
||||
pid_t pid = ::fork();
|
||||
if (pid == -1) {
|
||||
::LogWarning("Couldn't fork() , exiting");
|
||||
return;
|
||||
}
|
||||
else if (pid != 0)
|
||||
exit(EXIT_SUCCESS);
|
||||
|
||||
// Create new session and process group
|
||||
if (::setsid() == -1) {
|
||||
::LogWarning("Couldn't setsid(), exiting");
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the working directory to the root directory
|
||||
if (::chdir("/") == -1) {
|
||||
::LogWarning("Couldn't cd /, exiting");
|
||||
return;
|
||||
}
|
||||
|
||||
::close(STDIN_FILENO);
|
||||
::close(STDOUT_FILENO);
|
||||
::close(STDERR_FILENO);
|
||||
|
||||
//If we are currently root...
|
||||
if (getuid() == 0) {
|
||||
struct passwd* user = ::getpwnam("mmdvm");
|
||||
if (user == NULL) {
|
||||
::LogError("Could not get the mmdvm user, exiting");
|
||||
return;
|
||||
}
|
||||
|
||||
uid_t mmdvm_uid = user->pw_uid;
|
||||
gid_t mmdvm_gid = user->pw_gid;
|
||||
|
||||
//Set user and group ID's to mmdvm:mmdvm
|
||||
if (setgid(mmdvm_gid) != 0) {
|
||||
::LogWarning("Could not set mmdvm GID, exiting");
|
||||
return;
|
||||
}
|
||||
|
||||
if (setuid(mmdvm_uid) != 0) {
|
||||
::LogWarning("Could not set mmdvm UID, exiting");
|
||||
return;
|
||||
}
|
||||
|
||||
//Double check it worked (AKA Paranoia)
|
||||
if (setuid(0) != -1) {
|
||||
::LogWarning("It's possible to regain root - something is wrong!, exiting");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
CNXDNNetwork nxdnNetwork(m_conf.getNetworkPort(), m_conf.getNetworkDebug());
|
||||
ret = nxdnNetwork.open();
|
||||
if (!ret) {
|
||||
::LogFinalise();
|
||||
return;
|
||||
}
|
||||
|
||||
CNXCoreNetwork* nxCoreNetwork = NULL;
|
||||
if (m_conf.getNXCoreEnabled()) {
|
||||
nxCoreNetwork = new CNXCoreNetwork(m_conf.getNXCoreAddress(), m_conf.getNXCoreDebug());
|
||||
ret = nxCoreNetwork->open();
|
||||
if (!ret) {
|
||||
nxdnNetwork.close();
|
||||
delete nxCoreNetwork;
|
||||
::LogFinalise();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CNXDNLookup* lookup = new CNXDNLookup(m_conf.getLookupName(), m_conf.getLookupTime());
|
||||
lookup->read();
|
||||
|
||||
CStopWatch stopWatch;
|
||||
stopWatch.start();
|
||||
|
||||
CTimer dumpTimer(1000U, 120U);
|
||||
dumpTimer.start();
|
||||
|
||||
LogMessage("Starting NXDNReflector-%s", VERSION);
|
||||
|
||||
CNXDNRepeater* current = NULL;
|
||||
bool nxCore = false;
|
||||
|
||||
CTimer watchdogTimer(1000U, 0U, 1500U);
|
||||
|
||||
for (;;) {
|
||||
unsigned char buffer[200U];
|
||||
in_addr address;
|
||||
unsigned int port;
|
||||
|
||||
unsigned int len = nxdnNetwork.read(buffer, 200U, address, port);
|
||||
if (len > 0U) {
|
||||
CNXDNRepeater* rpt = findRepeater(address, port);
|
||||
|
||||
if (::memcmp(buffer, "NXDNP", 5U) == 0) {
|
||||
if (rpt == NULL) {
|
||||
rpt = new CNXDNRepeater;
|
||||
rpt->m_timer.start();
|
||||
rpt->m_address = address;
|
||||
rpt->m_port = port;
|
||||
rpt->m_callsign = std::string((char*)(buffer + 5U), 10U);
|
||||
m_repeaters.push_back(rpt);
|
||||
|
||||
LogMessage("Adding %s (%s:%u)", rpt->m_callsign.c_str(), ::inet_ntoa(address), port);
|
||||
}
|
||||
else {
|
||||
rpt->m_timer.start();
|
||||
}
|
||||
|
||||
// Return the poll
|
||||
nxdnNetwork.write(buffer, len, address, port);
|
||||
} else if (::memcmp(buffer, "NXDNU", 5U) == 0) {
|
||||
if (rpt != NULL) {
|
||||
std::string callsign = std::string((char*)(buffer + 5U), 10U);
|
||||
LogMessage("Removing %s (%s:%u)", callsign.c_str(), ::inet_ntoa(address), port);
|
||||
|
||||
for (std::vector<CNXDNRepeater*>::iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it) {
|
||||
if (*it == rpt) {
|
||||
m_repeaters.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delete rpt;
|
||||
}
|
||||
} else if (::memcmp(buffer, "NXDND", 5U) == 0) {
|
||||
if (rpt != NULL) {
|
||||
rpt->m_timer.start();
|
||||
|
||||
if (current == NULL && !nxCore) {
|
||||
current = rpt;
|
||||
|
||||
unsigned short srcId = (buffer[5U] << 8) | buffer[6U];
|
||||
unsigned short dstId = (buffer[7U] << 8) | buffer[8U];
|
||||
bool grp = (buffer[9U] & 0x01U) == 0x01U;
|
||||
|
||||
std::string callsign = lookup->find(srcId);
|
||||
LogMessage("Transmission from %s at %s to %s%u", callsign.c_str(), current->m_callsign.c_str(), grp ? "TG " : "", dstId);
|
||||
}
|
||||
|
||||
if (current == rpt) {
|
||||
watchdogTimer.start();
|
||||
|
||||
for (std::vector<CNXDNRepeater*>::const_iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it) {
|
||||
in_addr addr = (*it)->m_address;
|
||||
unsigned int prt = (*it)->m_port;
|
||||
if (addr.s_addr != address.s_addr || prt != port)
|
||||
nxdnNetwork.write(buffer, len, addr, prt);
|
||||
|
||||
if (nxCoreNetwork != NULL)
|
||||
nxCoreNetwork->write(buffer, len);
|
||||
}
|
||||
|
||||
if ((buffer[9U] & 0x04U) == 0x04U) {
|
||||
LogMessage("Received end of transmission");
|
||||
watchdogTimer.stop();
|
||||
current = NULL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LogMessage("Data received from an unknown source - %s:%u", ::inet_ntoa(address), port);
|
||||
CUtils::dump(2U, "Data", buffer, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nxCoreNetwork != NULL) {
|
||||
len = nxCoreNetwork->read(buffer, 200U);
|
||||
if (len > 0U) {
|
||||
if (current == NULL) {
|
||||
if (!nxCore) {
|
||||
if ((buffer[0U] == 0x81U || buffer[0U] == 0x83U) && buffer[5U] == 0x01U) {
|
||||
bool grp = (buffer[7U] & 0x20U) == 0x20U;
|
||||
unsigned short srcId = (buffer[8U] << 8) | buffer[9U];
|
||||
unsigned short dstId = (buffer[10U] << 8) | buffer[11U];
|
||||
|
||||
std::string callsign = lookup->find(srcId);
|
||||
LogMessage("Transmission from %s at NXCore to %s%u", callsign.c_str(), grp ? "TG " : "", dstId);
|
||||
|
||||
nxCore = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (nxCore) {
|
||||
watchdogTimer.start();
|
||||
|
||||
for (std::vector<CNXDNRepeater*>::const_iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it) {
|
||||
in_addr addr = (*it)->m_address;
|
||||
unsigned int prt = (*it)->m_port;
|
||||
nxdnNetwork.write(buffer, len, addr, prt);
|
||||
}
|
||||
|
||||
if ((buffer[0U] == 0x81U || buffer[0U] == 0x83U) && buffer[5U] == 0x08U) {
|
||||
LogMessage("Received end of transmission");
|
||||
nxCore = false;
|
||||
watchdogTimer.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int ms = stopWatch.elapsed();
|
||||
stopWatch.start();
|
||||
|
||||
// Remove any repeaters that haven't reported for a while
|
||||
for (std::vector<CNXDNRepeater*>::iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it)
|
||||
(*it)->m_timer.clock(ms);
|
||||
|
||||
for (std::vector<CNXDNRepeater*>::iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it) {
|
||||
CNXDNRepeater* itRpt = *it;
|
||||
if (itRpt->m_timer.hasExpired()) {
|
||||
in_addr address = itRpt->m_address;
|
||||
unsigned int port = itRpt->m_port;
|
||||
std::string callsign = itRpt->m_callsign;
|
||||
LogMessage("Removing %s (%s:%u) disappeared", callsign.c_str(), ::inet_ntoa(address), port);
|
||||
m_repeaters.erase(it);
|
||||
delete itRpt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
watchdogTimer.clock(ms);
|
||||
if (watchdogTimer.isRunning() && watchdogTimer.hasExpired()) {
|
||||
LogMessage("Network watchdog has expired");
|
||||
watchdogTimer.stop();
|
||||
current = NULL;
|
||||
nxCore = false;
|
||||
}
|
||||
|
||||
dumpTimer.clock(ms);
|
||||
if (dumpTimer.hasExpired()) {
|
||||
dumpRepeaters();
|
||||
dumpTimer.start();
|
||||
}
|
||||
|
||||
if (nxCoreNetwork != NULL)
|
||||
nxCoreNetwork->clock(ms);
|
||||
|
||||
if (ms < 5U)
|
||||
CThread::sleep(5U);
|
||||
}
|
||||
|
||||
nxdnNetwork.close();
|
||||
|
||||
if (nxCoreNetwork != NULL) {
|
||||
nxCoreNetwork->close();
|
||||
delete nxCoreNetwork;
|
||||
}
|
||||
|
||||
lookup->stop();
|
||||
|
||||
::LogFinalise();
|
||||
}
|
||||
|
||||
CNXDNRepeater* CNXDNReflector::findRepeater(const in_addr& address, unsigned int port) const
|
||||
{
|
||||
for (std::vector<CNXDNRepeater*>::const_iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it) {
|
||||
if (address.s_addr == (*it)->m_address.s_addr && (*it)->m_port == port)
|
||||
return *it;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CNXDNReflector::dumpRepeaters() const
|
||||
{
|
||||
if (m_repeaters.size() == 0U) {
|
||||
LogMessage("No repeaters linked");
|
||||
return;
|
||||
}
|
||||
|
||||
LogMessage("Currently linked repeaters:");
|
||||
|
||||
for (std::vector<CNXDNRepeater*>::const_iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it) {
|
||||
in_addr address = (*it)->m_address;
|
||||
unsigned int port = (*it)->m_port;
|
||||
std::string callsign = (*it)->m_callsign;
|
||||
unsigned int timer = (*it)->m_timer.getTimer();
|
||||
unsigned int timeout = (*it)->m_timer.getTimeout();
|
||||
LogMessage(" %s (%s:%u) %u/%u", callsign.c_str(), ::inet_ntoa(address), port, timer, timeout);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) 2016,2018 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#if !defined(NXDNReflector_H)
|
||||
#define NXDNReflector_H
|
||||
|
||||
#include "Timer.h"
|
||||
#include "Conf.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
#include <netdb.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#else
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
|
||||
class CNXDNRepeater {
|
||||
public:
|
||||
CNXDNRepeater() :
|
||||
m_address(),
|
||||
m_port(0U),
|
||||
m_callsign(),
|
||||
m_timer(1000U, 120U)
|
||||
{
|
||||
}
|
||||
|
||||
in_addr m_address;
|
||||
unsigned int m_port;
|
||||
std::string m_callsign;
|
||||
CTimer m_timer;
|
||||
};
|
||||
|
||||
class CNXDNReflector
|
||||
{
|
||||
public:
|
||||
CNXDNReflector(const std::string& file);
|
||||
~CNXDNReflector();
|
||||
|
||||
void run();
|
||||
|
||||
private:
|
||||
CConf m_conf;
|
||||
std::vector<CNXDNRepeater*> m_repeaters;
|
||||
|
||||
CNXDNRepeater* findRepeater(const in_addr& address, unsigned int port) const;
|
||||
void dumpRepeaters() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,22 @@
|
||||
[General]
|
||||
Daemon=1
|
||||
|
||||
[Id Lookup]
|
||||
Name=NXDN.csv
|
||||
Time=24
|
||||
|
||||
[Log]
|
||||
# Logging levels, 0=No logging
|
||||
DisplayLevel=1
|
||||
FileLevel=1
|
||||
FilePath=.
|
||||
FileRoot=NXDNReflector
|
||||
|
||||
[Network]
|
||||
Port=41007
|
||||
Debug=0
|
||||
|
||||
[NXCore]
|
||||
Enabled=0
|
||||
Address=127.0.0.1
|
||||
Debug=0
|
||||
@@ -0,0 +1,76 @@
|
||||
#!/bin/bash
|
||||
### BEGIN INIT INFO
|
||||
#
|
||||
# Provides: NXDNReflector
|
||||
# Required-Start: $all
|
||||
# Required-Stop:
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: Example startscript NXDNReflector
|
||||
|
||||
#
|
||||
### END INIT INFO
|
||||
## Fill in name of program here.
|
||||
PROG="NXDNReflector"
|
||||
PROG_PATH="/usr/local/bin/"
|
||||
PROG_ARGS="/etc/NXDNReflector.ini"
|
||||
PIDFILE="/var/run/NXDNReflector.pid"
|
||||
USER="root"
|
||||
|
||||
start() {
|
||||
if [ -e $PIDFILE ]; then
|
||||
## Program is running, exit with error.
|
||||
echo "Error! $PROG is currently running!" 1>&2
|
||||
exit 1
|
||||
else
|
||||
cd $PROG_PATH
|
||||
./$PROG $PROG_ARGS
|
||||
echo "$PROG started"
|
||||
touch $PIDFILE
|
||||
fi
|
||||
}
|
||||
|
||||
stop() {
|
||||
if [ -e $PIDFILE ]; then
|
||||
## Program is running, so stop it
|
||||
echo "$PROG is running"
|
||||
rm -f $PIDFILE
|
||||
killall $PROG
|
||||
echo "$PROG stopped"
|
||||
else
|
||||
## Program is not running, exit with error.
|
||||
echo "Error! $PROG not started!" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
## Check to see if we are running as root first.
|
||||
## Found at
|
||||
## http://www.cyberciti.biz/tips/shell-root-user-check-script.html
|
||||
if [ "$(id -u)" != "0" ]; then
|
||||
echo "This script must be run as root" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
start
|
||||
exit 0
|
||||
;;
|
||||
stop)
|
||||
stop
|
||||
exit 0
|
||||
;;
|
||||
reload|restart|force-reload)
|
||||
stop
|
||||
sleep 5
|
||||
start
|
||||
exit 0
|
||||
;;
|
||||
**)
|
||||
echo "Usage: $0 {start|stop|reload}" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
exit 0
|
||||
### END
|
||||
@@ -0,0 +1,31 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27130.2026
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NXDNReflector", "NXDNReflector.vcxproj", "{C68ABEB3-5CDD-4B26-8D66-77FE81EC6BB5}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{C68ABEB3-5CDD-4B26-8D66-77FE81EC6BB5}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{C68ABEB3-5CDD-4B26-8D66-77FE81EC6BB5}.Debug|x64.Build.0 = Debug|x64
|
||||
{C68ABEB3-5CDD-4B26-8D66-77FE81EC6BB5}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{C68ABEB3-5CDD-4B26-8D66-77FE81EC6BB5}.Debug|x86.Build.0 = Debug|Win32
|
||||
{C68ABEB3-5CDD-4B26-8D66-77FE81EC6BB5}.Release|x64.ActiveCfg = Release|x64
|
||||
{C68ABEB3-5CDD-4B26-8D66-77FE81EC6BB5}.Release|x64.Build.0 = Release|x64
|
||||
{C68ABEB3-5CDD-4B26-8D66-77FE81EC6BB5}.Release|x86.ActiveCfg = Release|Win32
|
||||
{C68ABEB3-5CDD-4B26-8D66-77FE81EC6BB5}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {32F19C39-C6E7-44AB-BE4C-EA8DD3C57231}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,186 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Conf.h" />
|
||||
<ClInclude Include="NXCoreNetwork.h" />
|
||||
<ClInclude Include="NXDNLookup.h" />
|
||||
<ClInclude Include="Log.h" />
|
||||
<ClInclude Include="Mutex.h" />
|
||||
<ClInclude Include="NXDNNetwork.h" />
|
||||
<ClInclude Include="NXDNReflector.h" />
|
||||
<ClInclude Include="RingBuffer.h" />
|
||||
<ClInclude Include="StopWatch.h" />
|
||||
<ClInclude Include="Thread.h" />
|
||||
<ClInclude Include="Timer.h" />
|
||||
<ClInclude Include="UDPSocket.h" />
|
||||
<ClInclude Include="Utils.h" />
|
||||
<ClInclude Include="Version.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Conf.cpp" />
|
||||
<ClCompile Include="NXCoreNetwork.cpp" />
|
||||
<ClCompile Include="NXDNLookup.cpp" />
|
||||
<ClCompile Include="Log.cpp" />
|
||||
<ClCompile Include="Mutex.cpp" />
|
||||
<ClCompile Include="NXDNNetwork.cpp" />
|
||||
<ClCompile Include="NXDNReflector.cpp" />
|
||||
<ClCompile Include="StopWatch.cpp" />
|
||||
<ClCompile Include="Thread.cpp" />
|
||||
<ClCompile Include="Timer.cpp" />
|
||||
<ClCompile Include="UDPSocket.cpp" />
|
||||
<ClCompile Include="Utils.cpp" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{C68ABEB3-5CDD-4B26-8D66-77FE81EC6BB5}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>NXDNReflector</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,95 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Conf.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="NXDNLookup.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Log.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Mutex.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="NXDNReflector.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RingBuffer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="StopWatch.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Thread.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Timer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="UDPSocket.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Utils.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Version.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="NXDNNetwork.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="NXCoreNetwork.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Conf.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="NXDNLookup.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Log.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Mutex.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="NXDNReflector.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="StopWatch.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Thread.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Timer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UDPSocket.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Utils.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="NXDNNetwork.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="NXCoreNetwork.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (C) 2006-2009,2012,2013,2015,2016 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef RingBuffer_H
|
||||
#define RingBuffer_H
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
template<class T> class CRingBuffer {
|
||||
public:
|
||||
CRingBuffer(unsigned int length, const char* name) :
|
||||
m_length(length),
|
||||
m_name(name),
|
||||
m_buffer(NULL),
|
||||
m_iPtr(0U),
|
||||
m_oPtr(0U)
|
||||
{
|
||||
assert(length > 0U);
|
||||
assert(name != NULL);
|
||||
|
||||
m_buffer = new T[length];
|
||||
|
||||
::memset(m_buffer, 0x00, m_length * sizeof(T));
|
||||
}
|
||||
|
||||
~CRingBuffer()
|
||||
{
|
||||
delete[] m_buffer;
|
||||
}
|
||||
|
||||
bool addData(const T* buffer, unsigned int nSamples)
|
||||
{
|
||||
if (nSamples >= freeSpace()) {
|
||||
::fprintf(stderr, "**** Overflow in %s ring buffer, %u >= %u\n", m_name, nSamples, freeSpace());
|
||||
return false;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0U; i < nSamples; i++) {
|
||||
m_buffer[m_iPtr++] = buffer[i];
|
||||
|
||||
if (m_iPtr == m_length)
|
||||
m_iPtr = 0U;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool getData(T* buffer, unsigned int nSamples)
|
||||
{
|
||||
if (dataSize() < nSamples) {
|
||||
::fprintf(stderr, "**** Underflow in %s ring buffer, %u < %u\n", m_name, dataSize(), nSamples);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0U; i < nSamples; i++) {
|
||||
buffer[i] = m_buffer[m_oPtr++];
|
||||
|
||||
if (m_oPtr == m_length)
|
||||
m_oPtr = 0U;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool peek(T* buffer, unsigned int nSamples)
|
||||
{
|
||||
if (dataSize() < nSamples) {
|
||||
::fprintf(stderr, "**** Underflow peek in %s ring buffer, %u < %u\n", m_name, dataSize(), nSamples);
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int ptr = m_oPtr;
|
||||
for (unsigned int i = 0U; i < nSamples; i++) {
|
||||
buffer[i] = m_buffer[ptr++];
|
||||
|
||||
if (ptr == m_length)
|
||||
ptr = 0U;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_iPtr = 0U;
|
||||
m_oPtr = 0U;
|
||||
|
||||
::memset(m_buffer, 0x00, m_length * sizeof(T));
|
||||
}
|
||||
|
||||
unsigned int freeSpace() const
|
||||
{
|
||||
if (m_oPtr == m_iPtr)
|
||||
return m_length;
|
||||
|
||||
if (m_oPtr > m_iPtr)
|
||||
return m_oPtr - m_iPtr;
|
||||
|
||||
return (m_length + m_oPtr) - m_iPtr;
|
||||
}
|
||||
|
||||
unsigned int dataSize() const
|
||||
{
|
||||
return m_length - freeSpace();
|
||||
}
|
||||
|
||||
bool hasSpace(unsigned int length) const
|
||||
{
|
||||
return freeSpace() > length;
|
||||
}
|
||||
|
||||
bool hasData() const
|
||||
{
|
||||
return m_oPtr != m_iPtr;
|
||||
}
|
||||
|
||||
bool isEmpty() const
|
||||
{
|
||||
return m_oPtr == m_iPtr;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int m_length;
|
||||
const char* m_name;
|
||||
T* m_buffer;
|
||||
unsigned int m_iPtr;
|
||||
unsigned int m_oPtr;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "StopWatch.h"
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
||||
CStopWatch::CStopWatch() :
|
||||
m_frequency(),
|
||||
m_start()
|
||||
{
|
||||
::QueryPerformanceFrequency(&m_frequency);
|
||||
}
|
||||
|
||||
CStopWatch::~CStopWatch()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned long CStopWatch::start()
|
||||
{
|
||||
::QueryPerformanceCounter(&m_start);
|
||||
|
||||
return (unsigned long)(m_start.QuadPart / m_frequency.QuadPart);
|
||||
}
|
||||
|
||||
unsigned int CStopWatch::elapsed()
|
||||
{
|
||||
LARGE_INTEGER now;
|
||||
::QueryPerformanceCounter(&now);
|
||||
|
||||
LARGE_INTEGER temp;
|
||||
temp.QuadPart = (now.QuadPart - m_start.QuadPart) * 1000;
|
||||
|
||||
return (unsigned int)(temp.QuadPart / m_frequency.QuadPart);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
CStopWatch::CStopWatch() :
|
||||
m_start()
|
||||
{
|
||||
}
|
||||
|
||||
CStopWatch::~CStopWatch()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned long CStopWatch::start()
|
||||
{
|
||||
::gettimeofday(&m_start, NULL);
|
||||
|
||||
return m_start.tv_usec;
|
||||
}
|
||||
|
||||
unsigned int CStopWatch::elapsed()
|
||||
{
|
||||
struct timeval now;
|
||||
::gettimeofday(&now, NULL);
|
||||
|
||||
unsigned int elapsed = (now.tv_sec - m_start.tv_sec) * 1000U;
|
||||
elapsed += now.tv_usec / 1000U;
|
||||
elapsed -= m_start.tv_usec / 1000U;
|
||||
|
||||
return elapsed;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#if !defined(STOPWATCH_H)
|
||||
#define STOPWATCH_H
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
class CStopWatch
|
||||
{
|
||||
public:
|
||||
CStopWatch();
|
||||
~CStopWatch();
|
||||
|
||||
unsigned long start();
|
||||
unsigned int elapsed();
|
||||
|
||||
private:
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
LARGE_INTEGER m_frequency;
|
||||
LARGE_INTEGER m_start;
|
||||
#else
|
||||
struct timeval m_start;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "Thread.h"
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
||||
CThread::CThread() :
|
||||
m_handle()
|
||||
{
|
||||
}
|
||||
|
||||
CThread::~CThread()
|
||||
{
|
||||
}
|
||||
|
||||
bool CThread::run()
|
||||
{
|
||||
m_handle = ::CreateThread(NULL, 0, &helper, this, 0, NULL);
|
||||
|
||||
return m_handle != NULL;
|
||||
}
|
||||
|
||||
|
||||
void CThread::wait()
|
||||
{
|
||||
::WaitForSingleObject(m_handle, INFINITE);
|
||||
|
||||
::CloseHandle(m_handle);
|
||||
}
|
||||
|
||||
|
||||
DWORD CThread::helper(LPVOID arg)
|
||||
{
|
||||
CThread* p = (CThread*)arg;
|
||||
|
||||
p->entry();
|
||||
|
||||
return 0UL;
|
||||
}
|
||||
|
||||
void CThread::sleep(unsigned int ms)
|
||||
{
|
||||
::Sleep(ms);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
CThread::CThread() :
|
||||
m_thread()
|
||||
{
|
||||
}
|
||||
|
||||
CThread::~CThread()
|
||||
{
|
||||
}
|
||||
|
||||
bool CThread::run()
|
||||
{
|
||||
return ::pthread_create(&m_thread, NULL, helper, this) == 0;
|
||||
}
|
||||
|
||||
|
||||
void CThread::wait()
|
||||
{
|
||||
::pthread_join(m_thread, NULL);
|
||||
}
|
||||
|
||||
|
||||
void* CThread::helper(void* arg)
|
||||
{
|
||||
CThread* p = (CThread*)arg;
|
||||
|
||||
p->entry();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CThread::sleep(unsigned int ms)
|
||||
{
|
||||
::usleep(ms * 1000);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#if !defined(THREAD_H)
|
||||
#define THREAD_H
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
class CThread
|
||||
{
|
||||
public:
|
||||
CThread();
|
||||
virtual ~CThread();
|
||||
|
||||
virtual bool run();
|
||||
|
||||
virtual void entry() = 0;
|
||||
|
||||
virtual void wait();
|
||||
|
||||
static void sleep(unsigned int ms);
|
||||
|
||||
private:
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
HANDLE m_handle;
|
||||
#else
|
||||
pthread_t m_thread;
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
static DWORD __stdcall helper(LPVOID arg);
|
||||
#else
|
||||
static void* helper(void* arg);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2009,2010,2015 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "Timer.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
|
||||
CTimer::CTimer(unsigned int ticksPerSec, unsigned int secs, unsigned int msecs) :
|
||||
m_ticksPerSec(ticksPerSec),
|
||||
m_timeout(0U),
|
||||
m_timer(0U)
|
||||
{
|
||||
assert(ticksPerSec > 0U);
|
||||
|
||||
if (secs > 0U || msecs > 0U) {
|
||||
// m_timeout = ((secs * 1000U + msecs) * m_ticksPerSec) / 1000U + 1U;
|
||||
unsigned long long temp = (secs * 1000ULL + msecs) * m_ticksPerSec;
|
||||
m_timeout = (unsigned int)(temp / 1000ULL + 1ULL);
|
||||
}
|
||||
}
|
||||
|
||||
CTimer::~CTimer()
|
||||
{
|
||||
}
|
||||
|
||||
void CTimer::setTimeout(unsigned int secs, unsigned int msecs)
|
||||
{
|
||||
if (secs > 0U || msecs > 0U) {
|
||||
// m_timeout = ((secs * 1000U + msecs) * m_ticksPerSec) / 1000U + 1U;
|
||||
unsigned long long temp = (secs * 1000ULL + msecs) * m_ticksPerSec;
|
||||
m_timeout = (unsigned int)(temp / 1000ULL + 1ULL);
|
||||
} else {
|
||||
m_timeout = 0U;
|
||||
m_timer = 0U;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int CTimer::getTimeout() const
|
||||
{
|
||||
if (m_timeout == 0U)
|
||||
return 0U;
|
||||
|
||||
return (m_timeout - 1U) / m_ticksPerSec;
|
||||
}
|
||||
|
||||
unsigned int CTimer::getTimer() const
|
||||
{
|
||||
if (m_timer == 0U)
|
||||
return 0U;
|
||||
|
||||
return (m_timer - 1U) / m_ticksPerSec;
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) 2009,2010,2011,2014 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef Timer_H
|
||||
#define Timer_H
|
||||
|
||||
class CTimer {
|
||||
public:
|
||||
CTimer(unsigned int ticksPerSec, unsigned int secs = 0U, unsigned int msecs = 0U);
|
||||
~CTimer();
|
||||
|
||||
void setTimeout(unsigned int secs, unsigned int msecs = 0U);
|
||||
|
||||
unsigned int getTimeout() const;
|
||||
unsigned int getTimer() const;
|
||||
|
||||
unsigned int getRemaining()
|
||||
{
|
||||
if (m_timeout == 0U || m_timer == 0U)
|
||||
return 0U;
|
||||
|
||||
if (m_timer >= m_timeout)
|
||||
return 0U;
|
||||
|
||||
return (m_timeout - m_timer) / m_ticksPerSec;
|
||||
}
|
||||
|
||||
bool isRunning()
|
||||
{
|
||||
return m_timer > 0U;
|
||||
}
|
||||
|
||||
void start(unsigned int secs, unsigned int msecs = 0U)
|
||||
{
|
||||
setTimeout(secs, msecs);
|
||||
|
||||
start();
|
||||
}
|
||||
|
||||
void start()
|
||||
{
|
||||
if (m_timeout > 0U)
|
||||
m_timer = 1U;
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
m_timer = 0U;
|
||||
}
|
||||
|
||||
bool hasExpired()
|
||||
{
|
||||
if (m_timeout == 0U || m_timer == 0U)
|
||||
return false;
|
||||
|
||||
if (m_timer >= m_timeout)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void clock(unsigned int ticks = 1U)
|
||||
{
|
||||
if (m_timer > 0U && m_timeout > 0U)
|
||||
m_timer += ticks;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int m_ticksPerSec;
|
||||
unsigned int m_timeout;
|
||||
unsigned int m_timer;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
* Copyright (C) 2006-2016 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "UDPSocket.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
#include <cerrno>
|
||||
#include <cstring>
|
||||
#endif
|
||||
|
||||
|
||||
CUDPSocket::CUDPSocket(const std::string& address, unsigned int port) :
|
||||
m_address(address),
|
||||
m_port(port),
|
||||
m_fd(-1)
|
||||
{
|
||||
assert(!address.empty());
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
WSAData data;
|
||||
int wsaRet = ::WSAStartup(MAKEWORD(2, 2), &data);
|
||||
if (wsaRet != 0)
|
||||
LogError("Error from WSAStartup");
|
||||
#endif
|
||||
}
|
||||
|
||||
CUDPSocket::CUDPSocket(unsigned int port) :
|
||||
m_address(),
|
||||
m_port(port),
|
||||
m_fd(-1)
|
||||
{
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
WSAData data;
|
||||
int wsaRet = ::WSAStartup(MAKEWORD(2, 2), &data);
|
||||
if (wsaRet != 0)
|
||||
LogError("Error from WSAStartup");
|
||||
#endif
|
||||
}
|
||||
|
||||
CUDPSocket::~CUDPSocket()
|
||||
{
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
::WSACleanup();
|
||||
#endif
|
||||
}
|
||||
|
||||
in_addr CUDPSocket::lookup(const std::string& hostname)
|
||||
{
|
||||
in_addr addr;
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
unsigned long address = ::inet_addr(hostname.c_str());
|
||||
if (address != INADDR_NONE && address != INADDR_ANY) {
|
||||
addr.s_addr = address;
|
||||
return addr;
|
||||
}
|
||||
|
||||
struct hostent* hp = ::gethostbyname(hostname.c_str());
|
||||
if (hp != NULL) {
|
||||
::memcpy(&addr, hp->h_addr_list[0], sizeof(struct in_addr));
|
||||
return addr;
|
||||
}
|
||||
|
||||
LogError("Cannot find address for host %s", hostname.c_str());
|
||||
|
||||
addr.s_addr = INADDR_NONE;
|
||||
return addr;
|
||||
#else
|
||||
in_addr_t address = ::inet_addr(hostname.c_str());
|
||||
if (address != in_addr_t(-1)) {
|
||||
addr.s_addr = address;
|
||||
return addr;
|
||||
}
|
||||
|
||||
struct hostent* hp = ::gethostbyname(hostname.c_str());
|
||||
if (hp != NULL) {
|
||||
::memcpy(&addr, hp->h_addr_list[0], sizeof(struct in_addr));
|
||||
return addr;
|
||||
}
|
||||
|
||||
LogError("Cannot find address for host %s", hostname.c_str());
|
||||
|
||||
addr.s_addr = INADDR_NONE;
|
||||
return addr;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CUDPSocket::open()
|
||||
{
|
||||
m_fd = ::socket(PF_INET, SOCK_DGRAM, 0);
|
||||
if (m_fd < 0) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
LogError("Cannot create the UDP socket, err: %lu", ::GetLastError());
|
||||
#else
|
||||
LogError("Cannot create the UDP socket, err: %d", errno);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_port > 0U) {
|
||||
sockaddr_in addr;
|
||||
::memset(&addr, 0x00, sizeof(sockaddr_in));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(m_port);
|
||||
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
if (!m_address.empty()) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
addr.sin_addr.s_addr = ::inet_addr(m_address.c_str());
|
||||
#else
|
||||
addr.sin_addr.s_addr = ::inet_addr(m_address.c_str());
|
||||
#endif
|
||||
if (addr.sin_addr.s_addr == INADDR_NONE) {
|
||||
LogError("The local address is invalid - %s", m_address.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int reuse = 1;
|
||||
if (::setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) == -1) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
LogError("Cannot set the UDP socket option, err: %lu", ::GetLastError());
|
||||
#else
|
||||
LogError("Cannot set the UDP socket option, err: %d", errno);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if (::bind(m_fd, (sockaddr*)&addr, sizeof(sockaddr_in)) == -1) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
LogError("Cannot bind the UDP address, err: %lu", ::GetLastError());
|
||||
#else
|
||||
LogError("Cannot bind the UDP address, err: %d", errno);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CUDPSocket::read(unsigned char* buffer, unsigned int length, in_addr& address, unsigned int& port)
|
||||
{
|
||||
assert(buffer != NULL);
|
||||
assert(length > 0U);
|
||||
|
||||
// Check that the readfrom() won't block
|
||||
fd_set readFds;
|
||||
FD_ZERO(&readFds);
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
FD_SET((unsigned int)m_fd, &readFds);
|
||||
#else
|
||||
FD_SET(m_fd, &readFds);
|
||||
#endif
|
||||
|
||||
// Return immediately
|
||||
timeval tv;
|
||||
tv.tv_sec = 0L;
|
||||
tv.tv_usec = 0L;
|
||||
|
||||
int ret = ::select(m_fd + 1, &readFds, NULL, NULL, &tv);
|
||||
if (ret < 0) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
LogError("Error returned from UDP select, err: %lu", ::GetLastError());
|
||||
#else
|
||||
LogError("Error returned from UDP select, err: %d", errno);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
return 0;
|
||||
|
||||
sockaddr_in addr;
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
int size = sizeof(sockaddr_in);
|
||||
#else
|
||||
socklen_t size = sizeof(sockaddr_in);
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
int len = ::recvfrom(m_fd, (char*)buffer, length, 0, (sockaddr *)&addr, &size);
|
||||
#else
|
||||
ssize_t len = ::recvfrom(m_fd, (char*)buffer, length, 0, (sockaddr *)&addr, &size);
|
||||
#endif
|
||||
if (len <= 0) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
LogError("Error returned from recvfrom, err: %lu", ::GetLastError());
|
||||
#else
|
||||
LogError("Error returned from recvfrom, err: %d", errno);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
address = addr.sin_addr;
|
||||
port = ntohs(addr.sin_port);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
bool CUDPSocket::write(const unsigned char* buffer, unsigned int length, const in_addr& address, unsigned int port)
|
||||
{
|
||||
assert(buffer != NULL);
|
||||
assert(length > 0U);
|
||||
|
||||
sockaddr_in addr;
|
||||
::memset(&addr, 0x00, sizeof(sockaddr_in));
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr = address;
|
||||
addr.sin_port = htons(port);
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
int ret = ::sendto(m_fd, (char *)buffer, length, 0, (sockaddr *)&addr, sizeof(sockaddr_in));
|
||||
#else
|
||||
ssize_t ret = ::sendto(m_fd, (char *)buffer, length, 0, (sockaddr *)&addr, sizeof(sockaddr_in));
|
||||
#endif
|
||||
if (ret < 0) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
LogError("Error returned from sendto, err: %lu", ::GetLastError());
|
||||
#else
|
||||
LogError("Error returned from sendto, err: %d", errno);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
if (ret != int(length))
|
||||
return false;
|
||||
#else
|
||||
if (ret != ssize_t(length))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CUDPSocket::close()
|
||||
{
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
::closesocket(m_fd);
|
||||
#else
|
||||
::close(m_fd);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2011,2013,2015,2016 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef UDPSocket_H
|
||||
#define UDPSocket_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
#include <netdb.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#else
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
|
||||
class CUDPSocket {
|
||||
public:
|
||||
CUDPSocket(const std::string& address, unsigned int port = 0U);
|
||||
CUDPSocket(unsigned int port = 0U);
|
||||
~CUDPSocket();
|
||||
|
||||
bool open();
|
||||
|
||||
int read(unsigned char* buffer, unsigned int length, in_addr& address, unsigned int& port);
|
||||
bool write(const unsigned char* buffer, unsigned int length, const in_addr& address, unsigned int port);
|
||||
|
||||
void close();
|
||||
|
||||
static in_addr lookup(const std::string& hostName);
|
||||
|
||||
private:
|
||||
std::string m_address;
|
||||
unsigned short m_port;
|
||||
int m_fd;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (C) 2009,2014,2015,2016 Jonathan Naylor, G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "Utils.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
|
||||
void CUtils::dump(const std::string& title, const unsigned char* data, unsigned int length)
|
||||
{
|
||||
assert(data != NULL);
|
||||
|
||||
dump(2U, title, data, length);
|
||||
}
|
||||
|
||||
void CUtils::dump(int level, const std::string& title, const unsigned char* data, unsigned int length)
|
||||
{
|
||||
assert(data != NULL);
|
||||
|
||||
::Log(level, "%s", title.c_str());
|
||||
|
||||
unsigned int offset = 0U;
|
||||
|
||||
while (length > 0U) {
|
||||
std::string output;
|
||||
|
||||
unsigned int bytes = (length > 16U) ? 16U : length;
|
||||
|
||||
for (unsigned i = 0U; i < bytes; i++) {
|
||||
char temp[10U];
|
||||
::sprintf(temp, "%02X ", data[offset + i]);
|
||||
output += temp;
|
||||
}
|
||||
|
||||
for (unsigned int i = bytes; i < 16U; i++)
|
||||
output += " ";
|
||||
|
||||
output += " *";
|
||||
|
||||
for (unsigned i = 0U; i < bytes; i++) {
|
||||
unsigned char c = data[offset + i];
|
||||
|
||||
if (::isprint(c))
|
||||
output += c;
|
||||
else
|
||||
output += '.';
|
||||
}
|
||||
|
||||
output += '*';
|
||||
|
||||
::Log(level, "%04X: %s", offset, output.c_str());
|
||||
|
||||
offset += 16U;
|
||||
|
||||
if (length >= 16U)
|
||||
length -= 16U;
|
||||
else
|
||||
length = 0U;
|
||||
}
|
||||
}
|
||||
|
||||
void CUtils::dump(const std::string& title, const bool* bits, unsigned int length)
|
||||
{
|
||||
assert(bits != NULL);
|
||||
|
||||
dump(2U, title, bits, length);
|
||||
}
|
||||
|
||||
void CUtils::dump(int level, const std::string& title, const bool* bits, unsigned int length)
|
||||
{
|
||||
assert(bits != NULL);
|
||||
|
||||
unsigned char bytes[100U];
|
||||
unsigned int nBytes = 0U;
|
||||
for (unsigned int n = 0U; n < length; n += 8U, nBytes++)
|
||||
bitsToByteBE(bits + n, bytes[nBytes]);
|
||||
|
||||
dump(level, title, bytes, nBytes);
|
||||
}
|
||||
|
||||
void CUtils::byteToBitsBE(unsigned char byte, bool* bits)
|
||||
{
|
||||
assert(bits != NULL);
|
||||
|
||||
bits[0U] = (byte & 0x80U) == 0x80U;
|
||||
bits[1U] = (byte & 0x40U) == 0x40U;
|
||||
bits[2U] = (byte & 0x20U) == 0x20U;
|
||||
bits[3U] = (byte & 0x10U) == 0x10U;
|
||||
bits[4U] = (byte & 0x08U) == 0x08U;
|
||||
bits[5U] = (byte & 0x04U) == 0x04U;
|
||||
bits[6U] = (byte & 0x02U) == 0x02U;
|
||||
bits[7U] = (byte & 0x01U) == 0x01U;
|
||||
}
|
||||
|
||||
void CUtils::byteToBitsLE(unsigned char byte, bool* bits)
|
||||
{
|
||||
assert(bits != NULL);
|
||||
|
||||
bits[0U] = (byte & 0x01U) == 0x01U;
|
||||
bits[1U] = (byte & 0x02U) == 0x02U;
|
||||
bits[2U] = (byte & 0x04U) == 0x04U;
|
||||
bits[3U] = (byte & 0x08U) == 0x08U;
|
||||
bits[4U] = (byte & 0x10U) == 0x10U;
|
||||
bits[5U] = (byte & 0x20U) == 0x20U;
|
||||
bits[6U] = (byte & 0x40U) == 0x40U;
|
||||
bits[7U] = (byte & 0x80U) == 0x80U;
|
||||
}
|
||||
|
||||
void CUtils::bitsToByteBE(const bool* bits, unsigned char& byte)
|
||||
{
|
||||
assert(bits != NULL);
|
||||
|
||||
byte = bits[0U] ? 0x80U : 0x00U;
|
||||
byte |= bits[1U] ? 0x40U : 0x00U;
|
||||
byte |= bits[2U] ? 0x20U : 0x00U;
|
||||
byte |= bits[3U] ? 0x10U : 0x00U;
|
||||
byte |= bits[4U] ? 0x08U : 0x00U;
|
||||
byte |= bits[5U] ? 0x04U : 0x00U;
|
||||
byte |= bits[6U] ? 0x02U : 0x00U;
|
||||
byte |= bits[7U] ? 0x01U : 0x00U;
|
||||
}
|
||||
|
||||
void CUtils::bitsToByteLE(const bool* bits, unsigned char& byte)
|
||||
{
|
||||
assert(bits != NULL);
|
||||
|
||||
byte = bits[0U] ? 0x01U : 0x00U;
|
||||
byte |= bits[1U] ? 0x02U : 0x00U;
|
||||
byte |= bits[2U] ? 0x04U : 0x00U;
|
||||
byte |= bits[3U] ? 0x08U : 0x00U;
|
||||
byte |= bits[4U] ? 0x10U : 0x00U;
|
||||
byte |= bits[5U] ? 0x20U : 0x00U;
|
||||
byte |= bits[6U] ? 0x40U : 0x00U;
|
||||
byte |= bits[7U] ? 0x80U : 0x00U;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2009,2014,2015 by Jonathan Naylor, G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef Utils_H
|
||||
#define Utils_H
|
||||
|
||||
#include <string>
|
||||
|
||||
class CUtils {
|
||||
public:
|
||||
static void dump(const std::string& title, const unsigned char* data, unsigned int length);
|
||||
static void dump(int level, const std::string& title, const unsigned char* data, unsigned int length);
|
||||
|
||||
static void dump(const std::string& title, const bool* bits, unsigned int length);
|
||||
static void dump(int level, const std::string& title, const bool* bits, unsigned int length);
|
||||
|
||||
static void byteToBitsBE(unsigned char byte, bool* bits);
|
||||
static void byteToBitsLE(unsigned char byte, bool* bits);
|
||||
|
||||
static void bitsToByteBE(const bool* bits, unsigned char& byte);
|
||||
static void bitsToByteLE(const bool* bits, unsigned char& byte);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016,2018 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#if !defined(VERSION_H)
|
||||
#define VERSION_H
|
||||
|
||||
const char* VERSION = "20180206";
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user