Beginnings of the DG-ID Gateway
This commit is contained in:
parent
66feacb19f
commit
af2be04fc8
52 changed files with 8642 additions and 1 deletions
381
DGIdGateway/APRSWriter.cpp
Normal file
381
DGIdGateway/APRSWriter.cpp
Normal file
|
@ -0,0 +1,381 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2010-2014,2016,2017,2018,2020 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 "APRSWriter.h"
|
||||||
|
#include "YSFDefines.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
CAPRSWriter::CAPRSWriter(const std::string& callsign, const std::string& rptSuffix, const std::string& address, unsigned int port, const std::string& suffix, bool debug) :
|
||||||
|
m_idTimer(1000U),
|
||||||
|
m_callsign(callsign),
|
||||||
|
m_debug(debug),
|
||||||
|
m_txFrequency(0U),
|
||||||
|
m_rxFrequency(0U),
|
||||||
|
m_latitude(0.0F),
|
||||||
|
m_longitude(0.0F),
|
||||||
|
m_height(0),
|
||||||
|
m_desc(),
|
||||||
|
m_suffix(suffix),
|
||||||
|
m_aprsAddress(),
|
||||||
|
m_aprsPort(port),
|
||||||
|
m_aprsSocket()
|
||||||
|
#if defined(USE_GPSD)
|
||||||
|
,m_gpsdEnabled(false),
|
||||||
|
m_gpsdAddress(),
|
||||||
|
m_gpsdPort(),
|
||||||
|
m_gpsdData()
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
assert(!callsign.empty());
|
||||||
|
assert(!address.empty());
|
||||||
|
assert(port > 0U);
|
||||||
|
|
||||||
|
if (!rptSuffix.empty()) {
|
||||||
|
m_callsign.append("-");
|
||||||
|
m_callsign.append(rptSuffix.substr(0U, 1U));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_aprsAddress = CUDPSocket::lookup(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
CAPRSWriter::~CAPRSWriter()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAPRSWriter::setInfo(unsigned int txFrequency, unsigned int rxFrequency, const std::string& desc)
|
||||||
|
{
|
||||||
|
m_txFrequency = txFrequency;
|
||||||
|
m_rxFrequency = rxFrequency;
|
||||||
|
m_desc = desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAPRSWriter::setStaticLocation(float latitude, float longitude, int height)
|
||||||
|
{
|
||||||
|
m_latitude = latitude;
|
||||||
|
m_longitude = longitude;
|
||||||
|
m_height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAPRSWriter::setGPSDLocation(const std::string& address, const std::string& port)
|
||||||
|
{
|
||||||
|
#if defined(USE_GPSD)
|
||||||
|
assert(!address.empty());
|
||||||
|
assert(!port.empty());
|
||||||
|
|
||||||
|
m_gpsdEnabled = true;
|
||||||
|
m_gpsdAddress = address;
|
||||||
|
m_gpsdPort = port;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CAPRSWriter::open()
|
||||||
|
{
|
||||||
|
#if defined(USE_GPSD)
|
||||||
|
if (m_gpsdEnabled) {
|
||||||
|
int ret = ::gps_open(m_gpsdAddress.c_str(), m_gpsdPort.c_str(), &m_gpsdData);
|
||||||
|
if (ret != 0) {
|
||||||
|
LogError("Error when opening access to gpsd - %d - %s", errno, ::gps_errstr(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
::gps_stream(&m_gpsdData, WATCH_ENABLE | WATCH_JSON, NULL);
|
||||||
|
|
||||||
|
LogMessage("Connected to GPSD");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
bool ret = m_aprsSocket.open();
|
||||||
|
if (!ret)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
LogMessage("Opened connection to the APRS Gateway");
|
||||||
|
|
||||||
|
m_idTimer.setTimeout(60U);
|
||||||
|
m_idTimer.start();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAPRSWriter::write(const unsigned char* source, const char* type, unsigned char radio, float fLatitude, float fLongitude)
|
||||||
|
{
|
||||||
|
assert(source != NULL);
|
||||||
|
assert(type != NULL);
|
||||||
|
|
||||||
|
char callsign[15U];
|
||||||
|
::memcpy(callsign, source, YSF_CALLSIGN_LENGTH);
|
||||||
|
callsign[YSF_CALLSIGN_LENGTH] = 0x00U;
|
||||||
|
|
||||||
|
size_t n = ::strspn(callsign, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
|
||||||
|
callsign[n] = 0x00U;
|
||||||
|
|
||||||
|
if (!m_suffix.empty()) {
|
||||||
|
::strcat(callsign, "-");
|
||||||
|
::strcat(callsign, m_suffix.substr(0U, 1U).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
double tempLat = ::fabs(fLatitude);
|
||||||
|
double tempLong = ::fabs(fLongitude);
|
||||||
|
|
||||||
|
double latitude = ::floor(tempLat);
|
||||||
|
double longitude = ::floor(tempLong);
|
||||||
|
|
||||||
|
latitude = (tempLat - latitude) * 60.0 + latitude * 100.0;
|
||||||
|
longitude = (tempLong - longitude) * 60.0 + longitude * 100.0;
|
||||||
|
|
||||||
|
char lat[20U];
|
||||||
|
::sprintf(lat, "%07.2lf", latitude);
|
||||||
|
|
||||||
|
char lon[20U];
|
||||||
|
::sprintf(lon, "%08.2lf", longitude);
|
||||||
|
|
||||||
|
char symbol;
|
||||||
|
switch (radio) {
|
||||||
|
case 0x24U:
|
||||||
|
case 0x28U:
|
||||||
|
case 0x30U:
|
||||||
|
symbol = '[';
|
||||||
|
break;
|
||||||
|
case 0x25U:
|
||||||
|
case 0x29U:
|
||||||
|
symbol = '>';
|
||||||
|
break;
|
||||||
|
case 0x26U:
|
||||||
|
symbol = 'r';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
symbol = '-';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
char output[300U];
|
||||||
|
::sprintf(output, "%s>APDPRS,C4FM*,qAR,%s:!%s%c/%s%c%c %s via MMDVM\r\n",
|
||||||
|
callsign, m_callsign.c_str(),
|
||||||
|
lat, (fLatitude < 0.0F) ? 'S' : 'N',
|
||||||
|
lon, (fLongitude < 0.0F) ? 'W' : 'E',
|
||||||
|
symbol, type);
|
||||||
|
|
||||||
|
if (m_debug)
|
||||||
|
LogDebug("APRS ==> %s", output);
|
||||||
|
|
||||||
|
m_aprsSocket.write((unsigned char*)output, (unsigned int)::strlen(output), m_aprsAddress, m_aprsPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAPRSWriter::clock(unsigned int ms)
|
||||||
|
{
|
||||||
|
m_idTimer.clock(ms);
|
||||||
|
|
||||||
|
#if defined(USE_GPSD)
|
||||||
|
if (m_gpsdEnabled) {
|
||||||
|
if (m_idTimer.hasExpired()) {
|
||||||
|
sendIdFrameMobile();
|
||||||
|
m_idTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
#endif
|
||||||
|
if (m_idTimer.hasExpired()) {
|
||||||
|
sendIdFrameFixed();
|
||||||
|
m_idTimer.setTimeout(20U * 60U);
|
||||||
|
m_idTimer.start();
|
||||||
|
}
|
||||||
|
#if defined(USE_GPSD)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAPRSWriter::close()
|
||||||
|
{
|
||||||
|
m_aprsSocket.close();
|
||||||
|
|
||||||
|
#if defined(USE_GPSD)
|
||||||
|
if (m_gpsdEnabled) {
|
||||||
|
::gps_stream(&m_gpsdData, WATCH_DISABLE, NULL);
|
||||||
|
::gps_close(&m_gpsdData);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAPRSWriter::sendIdFrameFixed()
|
||||||
|
{
|
||||||
|
// Default values aren't passed on
|
||||||
|
if (m_latitude == 0.0F && m_longitude == 0.0F)
|
||||||
|
return;
|
||||||
|
|
||||||
|
char desc[200U];
|
||||||
|
if (m_txFrequency != 0U) {
|
||||||
|
float offset = float(int(m_rxFrequency) - int(m_txFrequency)) / 1000000.0F;
|
||||||
|
::sprintf(desc, "MMDVM Voice %.5LfMHz %c%.4lfMHz%s%s",
|
||||||
|
(long double)(m_txFrequency) / 1000000.0F,
|
||||||
|
offset < 0.0F ? '-' : '+',
|
||||||
|
::fabs(offset), m_desc.empty() ? "" : ", ", m_desc.c_str());
|
||||||
|
} else {
|
||||||
|
::sprintf(desc, "MMDVM Voice%s%s", m_desc.empty() ? "" : ", ", m_desc.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* band = "4m";
|
||||||
|
if (m_txFrequency >= 1200000000U)
|
||||||
|
band = "1.2";
|
||||||
|
else if (m_txFrequency >= 420000000U)
|
||||||
|
band = "440";
|
||||||
|
else if (m_txFrequency >= 144000000U)
|
||||||
|
band = "2m";
|
||||||
|
else if (m_txFrequency >= 50000000U)
|
||||||
|
band = "6m";
|
||||||
|
else if (m_txFrequency >= 28000000U)
|
||||||
|
band = "10m";
|
||||||
|
|
||||||
|
double tempLat = ::fabs(m_latitude);
|
||||||
|
double tempLong = ::fabs(m_longitude);
|
||||||
|
|
||||||
|
double latitude = ::floor(tempLat);
|
||||||
|
double longitude = ::floor(tempLong);
|
||||||
|
|
||||||
|
latitude = (tempLat - latitude) * 60.0 + latitude * 100.0;
|
||||||
|
longitude = (tempLong - longitude) * 60.0 + longitude * 100.0;
|
||||||
|
|
||||||
|
char lat[20U];
|
||||||
|
::sprintf(lat, "%07.2lf", latitude);
|
||||||
|
|
||||||
|
char lon[20U];
|
||||||
|
::sprintf(lon, "%08.2lf", longitude);
|
||||||
|
|
||||||
|
std::string server = m_callsign;
|
||||||
|
size_t pos = server.find_first_of('-');
|
||||||
|
if (pos == std::string::npos)
|
||||||
|
server.append("-S");
|
||||||
|
else
|
||||||
|
server.append("S");
|
||||||
|
|
||||||
|
char output[500U];
|
||||||
|
::sprintf(output, "%s>APDG03,TCPIP*,qAC,%s:!%s%cD%s%c&/A=%06.0f%s %s\r\n",
|
||||||
|
m_callsign.c_str(), server.c_str(),
|
||||||
|
lat, (m_latitude < 0.0F) ? 'S' : 'N',
|
||||||
|
lon, (m_longitude < 0.0F) ? 'W' : 'E',
|
||||||
|
float(m_height) * 3.28F, band, desc);
|
||||||
|
|
||||||
|
if (m_debug)
|
||||||
|
LogDebug("APRS ==> %s", output);
|
||||||
|
|
||||||
|
m_aprsSocket.write((unsigned char*)output, (unsigned int)::strlen(output), m_aprsAddress, m_aprsPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(USE_GPSD)
|
||||||
|
void CAPRSWriter::sendIdFrameMobile()
|
||||||
|
{
|
||||||
|
if (!::gps_waiting(&m_gpsdData, 0))
|
||||||
|
return;
|
||||||
|
|
||||||
|
#if GPSD_API_MAJOR_VERSION >= 7
|
||||||
|
if (::gps_read(&m_gpsdData, NULL, 0) <= 0)
|
||||||
|
return;
|
||||||
|
#else
|
||||||
|
if (::gps_read(&m_gpsdData) <= 0)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
if (m_gpsdData.status != STATUS_FIX)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool latlonSet = (m_gpsdData.set & LATLON_SET) == LATLON_SET;
|
||||||
|
bool altitudeSet = (m_gpsdData.set & ALTITUDE_SET) == ALTITUDE_SET;
|
||||||
|
bool velocitySet = (m_gpsdData.set & SPEED_SET) == SPEED_SET;
|
||||||
|
bool bearingSet = (m_gpsdData.set & TRACK_SET) == TRACK_SET;
|
||||||
|
|
||||||
|
if (!latlonSet)
|
||||||
|
return;
|
||||||
|
|
||||||
|
float rawLatitude = float(m_gpsdData.fix.latitude);
|
||||||
|
float rawLongitude = float(m_gpsdData.fix.longitude);
|
||||||
|
#if GPSD_API_MAJOR_VERSION >= 9
|
||||||
|
float rawAltitude = float(m_gpsdData.fix.altMSL);
|
||||||
|
#else
|
||||||
|
float rawAltitude = float(m_gpsdData.fix.altitude);
|
||||||
|
#endif
|
||||||
|
float rawVelocity = float(m_gpsdData.fix.speed);
|
||||||
|
float rawBearing = float(m_gpsdData.fix.track);
|
||||||
|
|
||||||
|
char desc[200U];
|
||||||
|
if (m_txFrequency != 0U) {
|
||||||
|
float offset = float(int(m_rxFrequency) - int(m_txFrequency)) / 1000000.0F;
|
||||||
|
::sprintf(desc, "MMDVM Voice %.5LfMHz %c%.4lfMHz%s%s",
|
||||||
|
(long double)(m_txFrequency) / 1000000.0F,
|
||||||
|
offset < 0.0F ? '-' : '+',
|
||||||
|
::fabs(offset), m_desc.empty() ? "" : ", ", m_desc.c_str());
|
||||||
|
} else {
|
||||||
|
::sprintf(desc, "MMDVM Voice%s%s", m_desc.empty() ? "" : ", ", m_desc.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* band = "4m";
|
||||||
|
if (m_txFrequency >= 1200000000U)
|
||||||
|
band = "1.2";
|
||||||
|
else if (m_txFrequency >= 420000000U)
|
||||||
|
band = "440";
|
||||||
|
else if (m_txFrequency >= 144000000U)
|
||||||
|
band = "2m";
|
||||||
|
else if (m_txFrequency >= 50000000U)
|
||||||
|
band = "6m";
|
||||||
|
else if (m_txFrequency >= 28000000U)
|
||||||
|
band = "10m";
|
||||||
|
|
||||||
|
double tempLat = ::fabs(rawLatitude);
|
||||||
|
double tempLong = ::fabs(rawLongitude);
|
||||||
|
|
||||||
|
double latitude = ::floor(tempLat);
|
||||||
|
double longitude = ::floor(tempLong);
|
||||||
|
|
||||||
|
latitude = (tempLat - latitude) * 60.0 + latitude * 100.0;
|
||||||
|
longitude = (tempLong - longitude) * 60.0 + longitude * 100.0;
|
||||||
|
|
||||||
|
char lat[20U];
|
||||||
|
::sprintf(lat, "%07.2lf", latitude);
|
||||||
|
|
||||||
|
char lon[20U];
|
||||||
|
::sprintf(lon, "%08.2lf", longitude);
|
||||||
|
|
||||||
|
std::string server = m_callsign;
|
||||||
|
size_t pos = server.find_first_of('-');
|
||||||
|
if (pos == std::string::npos)
|
||||||
|
server.append("-S");
|
||||||
|
else
|
||||||
|
server.append("S");
|
||||||
|
|
||||||
|
char output[500U];
|
||||||
|
::sprintf(output, "%s>APDG03,TCPIP*,qAC,%s:!%s%cD%s%c&",
|
||||||
|
m_callsign.c_str(), server.c_str(),
|
||||||
|
lat, (rawLatitude < 0.0F) ? 'S' : 'N',
|
||||||
|
lon, (rawLongitude < 0.0F) ? 'W' : 'E');
|
||||||
|
|
||||||
|
if (bearingSet && velocitySet)
|
||||||
|
::sprintf(output + ::strlen(output), "%03.0f/%03.0f", rawBearing, rawVelocity * 0.539957F);
|
||||||
|
|
||||||
|
if (altitudeSet)
|
||||||
|
::sprintf(output + ::strlen(output), "/A=%06.0f", float(rawAltitude) * 3.28F);
|
||||||
|
|
||||||
|
::sprintf(output + ::strlen(output), "%s %s\r\n", band, desc);
|
||||||
|
|
||||||
|
if (m_debug)
|
||||||
|
LogDebug("APRS ==> %s", output);
|
||||||
|
|
||||||
|
m_aprsSocket.write((unsigned char*)output, (unsigned int)::strlen(output), m_aprsAddress, m_aprsPort);
|
||||||
|
}
|
||||||
|
#endif
|
87
DGIdGateway/APRSWriter.h
Normal file
87
DGIdGateway/APRSWriter.h
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2010,2011,2012,2016,2017,2018,2020 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 APRSWriter_H
|
||||||
|
#define APRSWriter_H
|
||||||
|
|
||||||
|
#include "UDPSocket.h"
|
||||||
|
#include "Timer.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>
|
||||||
|
#if defined(USE_GPSD)
|
||||||
|
#include <gps.h>
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#include <winsock.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class CAPRSWriter {
|
||||||
|
public:
|
||||||
|
CAPRSWriter(const std::string& callsign, const std::string& rptSuffix, const std::string& address, unsigned int port, const std::string& suffix, bool debug);
|
||||||
|
~CAPRSWriter();
|
||||||
|
|
||||||
|
bool open();
|
||||||
|
|
||||||
|
void setInfo(unsigned int txFrequency, unsigned int rxFrequency, const std::string& desc);
|
||||||
|
|
||||||
|
void setStaticLocation(float latitude, float longitude, int height);
|
||||||
|
|
||||||
|
void setGPSDLocation(const std::string& address, const std::string& port);
|
||||||
|
|
||||||
|
void write(const unsigned char* source, const char* type, unsigned char radio, float latitude, float longitude);
|
||||||
|
|
||||||
|
void clock(unsigned int ms);
|
||||||
|
|
||||||
|
void close();
|
||||||
|
|
||||||
|
private:
|
||||||
|
CTimer m_idTimer;
|
||||||
|
std::string m_callsign;
|
||||||
|
bool m_debug;
|
||||||
|
unsigned int m_txFrequency;
|
||||||
|
unsigned int m_rxFrequency;
|
||||||
|
float m_latitude;
|
||||||
|
float m_longitude;
|
||||||
|
int m_height;
|
||||||
|
std::string m_desc;
|
||||||
|
std::string m_suffix;
|
||||||
|
in_addr m_aprsAddress;
|
||||||
|
unsigned int m_aprsPort;
|
||||||
|
CUDPSocket m_aprsSocket;
|
||||||
|
#if defined(USE_GPSD)
|
||||||
|
bool m_gpsdEnabled;
|
||||||
|
std::string m_gpsdAddress;
|
||||||
|
std::string m_gpsdPort;
|
||||||
|
struct gps_data_t m_gpsdData;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void sendIdFrameFixed();
|
||||||
|
void sendIdFrameMobile();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
115
DGIdGateway/CRC.cpp
Normal file
115
DGIdGateway/CRC.cpp
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
* 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 "CRC.h"
|
||||||
|
|
||||||
|
#include "Utils.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
const uint16_t CCITT16_TABLE2[] = {
|
||||||
|
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
|
||||||
|
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
|
||||||
|
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
|
||||||
|
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
|
||||||
|
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
|
||||||
|
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
|
||||||
|
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
|
||||||
|
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
|
||||||
|
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
|
||||||
|
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
|
||||||
|
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
|
||||||
|
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
|
||||||
|
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
|
||||||
|
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
|
||||||
|
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
|
||||||
|
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
|
||||||
|
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
|
||||||
|
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||||
|
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
|
||||||
|
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
|
||||||
|
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
|
||||||
|
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
||||||
|
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
|
||||||
|
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||||
|
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
|
||||||
|
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
|
||||||
|
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
|
||||||
|
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
|
||||||
|
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
|
||||||
|
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
|
||||||
|
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
|
||||||
|
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 };
|
||||||
|
|
||||||
|
|
||||||
|
void CCRC::addCCITT16(unsigned char *in, unsigned int length)
|
||||||
|
{
|
||||||
|
assert(in != NULL);
|
||||||
|
assert(length > 2U);
|
||||||
|
|
||||||
|
union {
|
||||||
|
uint16_t crc16;
|
||||||
|
uint8_t crc8[2U];
|
||||||
|
};
|
||||||
|
|
||||||
|
crc16 = 0U;
|
||||||
|
|
||||||
|
for (unsigned i = 0U; i < (length - 2U); i++)
|
||||||
|
crc16 = (uint16_t(crc8[0U]) << 8) ^ CCITT16_TABLE2[crc8[1U] ^ in[i]];
|
||||||
|
|
||||||
|
crc16 = ~crc16;
|
||||||
|
|
||||||
|
in[length - 1U] = crc8[0U];
|
||||||
|
in[length - 2U] = crc8[1U];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CCRC::checkCCITT16(const unsigned char *in, unsigned int length)
|
||||||
|
{
|
||||||
|
assert(in != NULL);
|
||||||
|
assert(length > 2U);
|
||||||
|
|
||||||
|
union {
|
||||||
|
uint16_t crc16;
|
||||||
|
uint8_t crc8[2U];
|
||||||
|
};
|
||||||
|
|
||||||
|
crc16 = 0U;
|
||||||
|
|
||||||
|
for (unsigned i = 0U; i < (length - 2U); i++)
|
||||||
|
crc16 = (uint16_t(crc8[0U]) << 8) ^ CCITT16_TABLE2[crc8[1U] ^ in[i]];
|
||||||
|
|
||||||
|
crc16 = ~crc16;
|
||||||
|
|
||||||
|
return crc8[0U] == in[length - 1U] && crc8[1U] == in[length - 2U];
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CCRC::addCRC(const unsigned char* in, unsigned int length)
|
||||||
|
{
|
||||||
|
assert(in != NULL);
|
||||||
|
|
||||||
|
unsigned char crc = 0U;
|
||||||
|
|
||||||
|
for (unsigned int i = 0U; i < length; i++)
|
||||||
|
crc += in[i];
|
||||||
|
|
||||||
|
return crc;
|
||||||
|
}
|
31
DGIdGateway/CRC.h
Normal file
31
DGIdGateway/CRC.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* 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(CRC_H)
|
||||||
|
#define CRC_H
|
||||||
|
|
||||||
|
class CCRC
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void addCCITT16(unsigned char* in, unsigned int length);
|
||||||
|
static bool checkCCITT16(const unsigned char* in, unsigned int length);
|
||||||
|
|
||||||
|
static unsigned char addCRC(const unsigned char* in, unsigned int length);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
430
DGIdGateway/Conf.cpp
Normal file
430
DGIdGateway/Conf.cpp
Normal file
|
@ -0,0 +1,430 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015-2020 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>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
const int BUFFER_SIZE = 500;
|
||||||
|
|
||||||
|
enum SECTION {
|
||||||
|
SECTION_NONE,
|
||||||
|
SECTION_GENERAL,
|
||||||
|
SECTION_INFO,
|
||||||
|
SECTION_LOG,
|
||||||
|
SECTION_APRS,
|
||||||
|
SECTION_YSF_NETWORK,
|
||||||
|
SECTION_FCS_NETWORK,
|
||||||
|
SECTION_DGID,
|
||||||
|
SECTION_GPSD
|
||||||
|
};
|
||||||
|
|
||||||
|
CConf::CConf(const std::string& file) :
|
||||||
|
m_file(file),
|
||||||
|
m_callsign(),
|
||||||
|
m_suffix(),
|
||||||
|
m_id(0U),
|
||||||
|
m_rptAddress(),
|
||||||
|
m_rptPort(0U),
|
||||||
|
m_myAddress(),
|
||||||
|
m_myPort(0U),
|
||||||
|
m_rfHangTime(60U),
|
||||||
|
m_netHangTime(60U),
|
||||||
|
m_debug(false),
|
||||||
|
m_daemon(false),
|
||||||
|
m_rxFrequency(0U),
|
||||||
|
m_txFrequency(0U),
|
||||||
|
m_power(0U),
|
||||||
|
m_latitude(0.0F),
|
||||||
|
m_longitude(0.0F),
|
||||||
|
m_height(0),
|
||||||
|
m_name(),
|
||||||
|
m_description(),
|
||||||
|
m_logDisplayLevel(0U),
|
||||||
|
m_logFileLevel(0U),
|
||||||
|
m_logFilePath(),
|
||||||
|
m_logFileRoot(),
|
||||||
|
m_aprsEnabled(false),
|
||||||
|
m_aprsAddress(),
|
||||||
|
m_aprsPort(0U),
|
||||||
|
m_aprsSuffix(),
|
||||||
|
m_aprsDescription(),
|
||||||
|
m_ysfNetHosts(),
|
||||||
|
m_ysfRFHangTime(60U),
|
||||||
|
m_ysfNetHangTime(60U),
|
||||||
|
m_ysfNetDebug(false),
|
||||||
|
m_fcsRFHangTime(60U),
|
||||||
|
m_fcsNetHangTime(60U),
|
||||||
|
m_fcsNetDebug(false),
|
||||||
|
m_dgIdData(),
|
||||||
|
m_gpsdEnabled(false),
|
||||||
|
m_gpsdAddress(),
|
||||||
|
m_gpsdPort()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
DGIdData* dgIdData = NULL;
|
||||||
|
|
||||||
|
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, "[Info]", 6U) == 0)
|
||||||
|
section = SECTION_INFO;
|
||||||
|
else if (::strncmp(buffer, "[Log]", 5U) == 0)
|
||||||
|
section = SECTION_LOG;
|
||||||
|
else if (::strncmp(buffer, "[APRS]", 6U) == 0)
|
||||||
|
section = SECTION_APRS;
|
||||||
|
else if (::strncmp(buffer, "[YSF Network]", 13U) == 0)
|
||||||
|
section = SECTION_YSF_NETWORK;
|
||||||
|
else if (::strncmp(buffer, "[FCS Network]", 13U) == 0)
|
||||||
|
section = SECTION_FCS_NETWORK;
|
||||||
|
else if (::strncmp(buffer, "[DGId=", 6U) == 0) {
|
||||||
|
section = SECTION_DGID;
|
||||||
|
dgIdData = new DGIdData;
|
||||||
|
dgIdData->m_dgId = (unsigned int)::atoi(buffer + 6U);
|
||||||
|
m_dgIdData.push_back(dgIdData);
|
||||||
|
} else if (::strncmp(buffer, "[GPSD]", 6U) == 0)
|
||||||
|
section = SECTION_GPSD;
|
||||||
|
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, "Callsign") == 0) {
|
||||||
|
// Convert the callsign to upper case
|
||||||
|
for (unsigned int i = 0U; value[i] != 0; i++)
|
||||||
|
value[i] = ::toupper(value[i]);
|
||||||
|
m_callsign = value;
|
||||||
|
} else if (::strcmp(key, "Suffix") == 0) {
|
||||||
|
// Convert the callsign to upper case
|
||||||
|
for (unsigned int i = 0U; value[i] != 0; i++)
|
||||||
|
value[i] = ::toupper(value[i]);
|
||||||
|
m_suffix = value;
|
||||||
|
} else if (::strcmp(key, "Id") == 0)
|
||||||
|
m_id = (unsigned int)::atoi(value);
|
||||||
|
else if (::strcmp(key, "RptAddress") == 0)
|
||||||
|
m_rptAddress = value;
|
||||||
|
else if (::strcmp(key, "RptPort") == 0)
|
||||||
|
m_rptPort = (unsigned int)::atoi(value);
|
||||||
|
else if (::strcmp(key, "LocalAddress") == 0)
|
||||||
|
m_myAddress = value;
|
||||||
|
else if (::strcmp(key, "LocalPort") == 0)
|
||||||
|
m_myPort = (unsigned int)::atoi(value);
|
||||||
|
else if (::strcmp(key, "RFHangTime") == 0)
|
||||||
|
m_ysfRFHangTime = m_fcsRFHangTime = m_rfHangTime = (unsigned int)::atoi(value);
|
||||||
|
else if (::strcmp(key, "NetHangTime") == 0)
|
||||||
|
m_ysfNetHangTime = m_fcsNetHangTime = m_netHangTime = (unsigned int)::atoi(value);
|
||||||
|
else if (::strcmp(key, "Debug") == 0)
|
||||||
|
m_debug = ::atoi(value) == 1;
|
||||||
|
else if (::strcmp(key, "Daemon") == 0)
|
||||||
|
m_daemon = ::atoi(value) == 1;
|
||||||
|
} else if (section == SECTION_INFO) {
|
||||||
|
if (::strcmp(key, "TXFrequency") == 0)
|
||||||
|
m_txFrequency = (unsigned int)::atoi(value);
|
||||||
|
else if (::strcmp(key, "RXFrequency") == 0)
|
||||||
|
m_rxFrequency = (unsigned int)::atoi(value);
|
||||||
|
else if (::strcmp(key, "Power") == 0)
|
||||||
|
m_power = (unsigned int)::atoi(value);
|
||||||
|
else if (::strcmp(key, "Latitude") == 0)
|
||||||
|
m_latitude = float(::atof(value));
|
||||||
|
else if (::strcmp(key, "Longitude") == 0)
|
||||||
|
m_longitude = float(::atof(value));
|
||||||
|
else if (::strcmp(key, "Height") == 0)
|
||||||
|
m_height = ::atoi(value);
|
||||||
|
else if (::strcmp(key, "Name") == 0)
|
||||||
|
m_name = value;
|
||||||
|
else if (::strcmp(key, "Description") == 0)
|
||||||
|
m_description = 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_APRS) {
|
||||||
|
if (::strcmp(key, "Enable") == 0)
|
||||||
|
m_aprsEnabled = ::atoi(value) == 1;
|
||||||
|
else if (::strcmp(key, "Address") == 0)
|
||||||
|
m_aprsAddress = value;
|
||||||
|
else if (::strcmp(key, "Port") == 0)
|
||||||
|
m_aprsPort = (unsigned int)::atoi(value);
|
||||||
|
else if (::strcmp(key, "Suffix") == 0)
|
||||||
|
m_aprsSuffix = value;
|
||||||
|
else if (::strcmp(key, "Description") == 0)
|
||||||
|
m_aprsDescription = value;
|
||||||
|
} else if (section == SECTION_YSF_NETWORK) {
|
||||||
|
if (::strcmp(key, "Hosts") == 0)
|
||||||
|
m_ysfNetHosts = value;
|
||||||
|
else if (::strcmp(key, "RFHangTime") == 0)
|
||||||
|
m_ysfRFHangTime = (unsigned int)::atoi(value);
|
||||||
|
else if (::strcmp(key, "NetHangTime") == 0)
|
||||||
|
m_ysfNetHangTime = (unsigned int)::atoi(value);
|
||||||
|
else if (::strcmp(key, "Debug") == 0)
|
||||||
|
m_ysfNetDebug = ::atoi(value) == 1;
|
||||||
|
} else if (section == SECTION_FCS_NETWORK) {
|
||||||
|
if (::strcmp(key, "RFHangTime") == 0)
|
||||||
|
m_fcsRFHangTime = (unsigned int)::atoi(value);
|
||||||
|
else if (::strcmp(key, "NetHangTime") == 0)
|
||||||
|
m_fcsNetHangTime = (unsigned int)::atoi(value);
|
||||||
|
else if (::strcmp(key, "Debug") == 0)
|
||||||
|
m_fcsNetDebug = ::atoi(value) == 1;
|
||||||
|
} else if (section == SECTION_DGID) {
|
||||||
|
assert(dgIdData != NULL);
|
||||||
|
if (::strcmp(key, "Type") == 0) {
|
||||||
|
dgIdData->m_type = value;
|
||||||
|
dgIdData->m_static = false;
|
||||||
|
if (::strcmp(value, "YSF") == 0) {
|
||||||
|
dgIdData->m_rfHangTime = m_ysfRFHangTime;
|
||||||
|
dgIdData->m_netHangTime = m_ysfNetHangTime;
|
||||||
|
dgIdData->m_debug = m_ysfNetDebug;
|
||||||
|
} else if (::strcmp(value, "FCS") == 0) {
|
||||||
|
dgIdData->m_rfHangTime = m_fcsRFHangTime;
|
||||||
|
dgIdData->m_netHangTime = m_fcsNetHangTime;
|
||||||
|
dgIdData->m_debug = m_fcsNetDebug;
|
||||||
|
} else {
|
||||||
|
dgIdData->m_rfHangTime = m_rfHangTime;
|
||||||
|
dgIdData->m_netHangTime = m_netHangTime;
|
||||||
|
dgIdData->m_debug = false;
|
||||||
|
}
|
||||||
|
} else if (::strcmp(key, "RFHangTime") == 0)
|
||||||
|
dgIdData->m_rfHangTime = (unsigned int)::atoi(value);
|
||||||
|
else if (::strcmp(key, "NetHangTime") == 0)
|
||||||
|
dgIdData->m_netHangTime = (unsigned int)::atoi(value);
|
||||||
|
else if (::strcmp(key, "Static") == 0)
|
||||||
|
dgIdData->m_static = ::atoi(value) == 1;
|
||||||
|
else if (::strcmp(key, "Address") == 0)
|
||||||
|
dgIdData->m_address = value;
|
||||||
|
else if (::strcmp(key, "Name") == 0)
|
||||||
|
dgIdData->m_name = value;
|
||||||
|
else if (::strcmp(key, "Port") == 0)
|
||||||
|
dgIdData->m_port = (unsigned int)::atoi(value);
|
||||||
|
else if (::strcmp(key, "Local") == 0)
|
||||||
|
dgIdData->m_local = (unsigned int)::atoi(value);
|
||||||
|
else if (::strcmp(key, "Destination") == 0) {
|
||||||
|
char* p1 = ::strtok(value, ",");
|
||||||
|
char* p2 = ::strtok(NULL, "\r\n");
|
||||||
|
IMRSDestination* dest = new IMRSDestination;
|
||||||
|
dest->m_dgId = (unsigned int)::atoi(p1);
|
||||||
|
dest->m_address = p2;
|
||||||
|
dgIdData->m_destinations.push_back(dest);
|
||||||
|
} else if (::strcmp(key, "Debug") == 0)
|
||||||
|
dgIdData->m_debug = ::atoi(value) == 1;
|
||||||
|
} else if (section == SECTION_GPSD) {
|
||||||
|
if (::strcmp(key, "Enable") == 0)
|
||||||
|
m_gpsdEnabled = ::atoi(value) == 1;
|
||||||
|
else if (::strcmp(key, "Address") == 0)
|
||||||
|
m_gpsdAddress = value;
|
||||||
|
else if (::strcmp(key, "Port") == 0)
|
||||||
|
m_gpsdPort = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::fclose(fp);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CConf::getCallsign() const
|
||||||
|
{
|
||||||
|
return m_callsign;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CConf::getSuffix() const
|
||||||
|
{
|
||||||
|
return m_suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int CConf::getId() const
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CConf::getRptAddress() const
|
||||||
|
{
|
||||||
|
return m_rptAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int CConf::getRptPort() const
|
||||||
|
{
|
||||||
|
return m_rptPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CConf::getMyAddress() const
|
||||||
|
{
|
||||||
|
return m_myAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int CConf::getMyPort() const
|
||||||
|
{
|
||||||
|
return m_myPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CConf::getDebug() const
|
||||||
|
{
|
||||||
|
return m_debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CConf::getDaemon() const
|
||||||
|
{
|
||||||
|
return m_daemon;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int CConf::getRxFrequency() const
|
||||||
|
{
|
||||||
|
return m_rxFrequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int CConf::getTxFrequency() const
|
||||||
|
{
|
||||||
|
return m_txFrequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int CConf::getPower() const
|
||||||
|
{
|
||||||
|
return m_power;
|
||||||
|
}
|
||||||
|
|
||||||
|
float CConf::getLatitude() const
|
||||||
|
{
|
||||||
|
return m_latitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
float CConf::getLongitude() const
|
||||||
|
{
|
||||||
|
return m_longitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CConf::getHeight() const
|
||||||
|
{
|
||||||
|
return m_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CConf::getName() const
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CConf::getDescription() const
|
||||||
|
{
|
||||||
|
return m_description;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CConf::getAPRSEnabled() const
|
||||||
|
{
|
||||||
|
return m_aprsEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CConf::getAPRSAddress() const
|
||||||
|
{
|
||||||
|
return m_aprsAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int CConf::getAPRSPort() const
|
||||||
|
{
|
||||||
|
return m_aprsPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CConf::getAPRSSuffix() const
|
||||||
|
{
|
||||||
|
return m_aprsSuffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CConf::getAPRSDescription() const
|
||||||
|
{
|
||||||
|
return m_aprsDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CConf::getYSFNetHosts() const
|
||||||
|
{
|
||||||
|
return m_ysfNetHosts;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<DGIdData*> CConf::getDGIdData() const
|
||||||
|
{
|
||||||
|
return m_dgIdData;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CConf::getGPSDEnabled() const
|
||||||
|
{
|
||||||
|
return m_gpsdEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CConf::getGPSDAddress() const
|
||||||
|
{
|
||||||
|
return m_gpsdAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CConf::getGPSDPort() const
|
||||||
|
{
|
||||||
|
return m_gpsdPort;
|
||||||
|
}
|
||||||
|
|
147
DGIdGateway/Conf.h
Normal file
147
DGIdGateway/Conf.h
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015-2020 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>
|
||||||
|
|
||||||
|
struct IMRSDestination {
|
||||||
|
std::string m_address;
|
||||||
|
unsigned int m_dgId;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DGIdData {
|
||||||
|
unsigned int m_dgId;
|
||||||
|
std::string m_type;
|
||||||
|
bool m_static;
|
||||||
|
std::string m_name;
|
||||||
|
std::string m_address;
|
||||||
|
unsigned int m_port;
|
||||||
|
unsigned int m_local;
|
||||||
|
std::vector<IMRSDestination*> m_destinations;
|
||||||
|
unsigned int m_rfHangTime;
|
||||||
|
unsigned int m_netHangTime;
|
||||||
|
bool m_debug;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CConf
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CConf(const std::string& file);
|
||||||
|
~CConf();
|
||||||
|
|
||||||
|
bool read();
|
||||||
|
|
||||||
|
// The General section
|
||||||
|
std::string getCallsign() const;
|
||||||
|
std::string getSuffix() const;
|
||||||
|
unsigned int getId() const;
|
||||||
|
std::string getRptAddress() const;
|
||||||
|
unsigned int getRptPort() const;
|
||||||
|
std::string getMyAddress() const;
|
||||||
|
unsigned int getMyPort() const;
|
||||||
|
bool getDebug() const;
|
||||||
|
bool getDaemon() const;
|
||||||
|
|
||||||
|
// The Info section
|
||||||
|
unsigned int getRxFrequency() const;
|
||||||
|
unsigned int getTxFrequency() const;
|
||||||
|
unsigned int getPower() const;
|
||||||
|
float getLatitude() const;
|
||||||
|
float getLongitude() const;
|
||||||
|
int getHeight() const;
|
||||||
|
std::string getName() const;
|
||||||
|
std::string getDescription() const;
|
||||||
|
|
||||||
|
// The Log section
|
||||||
|
unsigned int getLogDisplayLevel() const;
|
||||||
|
unsigned int getLogFileLevel() const;
|
||||||
|
std::string getLogFilePath() const;
|
||||||
|
std::string getLogFileRoot() const;
|
||||||
|
|
||||||
|
// The APRS section
|
||||||
|
bool getAPRSEnabled() const;
|
||||||
|
std::string getAPRSAddress() const;
|
||||||
|
unsigned int getAPRSPort() const;
|
||||||
|
std::string getAPRSSuffix() const;
|
||||||
|
std::string getAPRSDescription() const;
|
||||||
|
|
||||||
|
// The YSF Network section
|
||||||
|
std::string getYSFNetHosts() const;
|
||||||
|
|
||||||
|
// The DG-ID Section
|
||||||
|
std::vector<DGIdData*> getDGIdData() const;
|
||||||
|
|
||||||
|
// The GPSD section
|
||||||
|
bool getGPSDEnabled() const;
|
||||||
|
std::string getGPSDAddress() const;
|
||||||
|
std::string getGPSDPort() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_file;
|
||||||
|
std::string m_callsign;
|
||||||
|
std::string m_suffix;
|
||||||
|
unsigned int m_id;
|
||||||
|
std::string m_rptAddress;
|
||||||
|
unsigned int m_rptPort;
|
||||||
|
std::string m_myAddress;
|
||||||
|
unsigned int m_myPort;
|
||||||
|
unsigned int m_rfHangTime;
|
||||||
|
unsigned int m_netHangTime;
|
||||||
|
bool m_debug;
|
||||||
|
bool m_daemon;
|
||||||
|
|
||||||
|
unsigned int m_rxFrequency;
|
||||||
|
unsigned int m_txFrequency;
|
||||||
|
unsigned int m_power;
|
||||||
|
float m_latitude;
|
||||||
|
float m_longitude;
|
||||||
|
int m_height;
|
||||||
|
std::string m_name;
|
||||||
|
std::string m_description;
|
||||||
|
|
||||||
|
unsigned int m_logDisplayLevel;
|
||||||
|
unsigned int m_logFileLevel;
|
||||||
|
std::string m_logFilePath;
|
||||||
|
std::string m_logFileRoot;
|
||||||
|
|
||||||
|
bool m_aprsEnabled;
|
||||||
|
std::string m_aprsAddress;
|
||||||
|
unsigned int m_aprsPort;
|
||||||
|
std::string m_aprsSuffix;
|
||||||
|
std::string m_aprsDescription;
|
||||||
|
|
||||||
|
std::string m_ysfNetHosts;
|
||||||
|
unsigned int m_ysfRFHangTime;
|
||||||
|
unsigned int m_ysfNetHangTime;
|
||||||
|
bool m_ysfNetDebug;
|
||||||
|
|
||||||
|
unsigned int m_fcsRFHangTime;
|
||||||
|
unsigned int m_fcsNetHangTime;
|
||||||
|
bool m_fcsNetDebug;
|
||||||
|
|
||||||
|
std::vector<DGIdData*> m_dgIdData;
|
||||||
|
|
||||||
|
bool m_gpsdEnabled;
|
||||||
|
std::string m_gpsdAddress;
|
||||||
|
std::string m_gpsdPort;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
556
DGIdGateway/DGIdGateway.cpp
Normal file
556
DGIdGateway/DGIdGateway.cpp
Normal file
|
@ -0,0 +1,556 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016-2020 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 "YSFReflectors.h"
|
||||||
|
#include "DGIdGateway.h"
|
||||||
|
#include "DGIdNetwork.h"
|
||||||
|
#include "YSFNetwork.h"
|
||||||
|
#include "FCSNetwork.h"
|
||||||
|
#include "UDPSocket.h"
|
||||||
|
#include "StopWatch.h"
|
||||||
|
#include "Version.h"
|
||||||
|
#include "YSFFICH.h"
|
||||||
|
#include "Thread.h"
|
||||||
|
#include "Timer.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
#include <Windows.h>
|
||||||
|
#else
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
const char* DEFAULT_INI_FILE = "DGIdGateway.ini";
|
||||||
|
#else
|
||||||
|
const char* DEFAULT_INI_FILE = "/etc/DGIdGateway.ini";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <clocale>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
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, "DGIdGateway version %s\n", VERSION);
|
||||||
|
return 0;
|
||||||
|
} else if (arg.substr(0, 1) == "-") {
|
||||||
|
::fprintf(stderr, "Usage: DGIdGateway [-v|--version] [filename]\n");
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
iniFile = argv[currentArg];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CDGIdGateway* gateway = new CDGIdGateway(std::string(iniFile));
|
||||||
|
|
||||||
|
int ret = gateway->run();
|
||||||
|
|
||||||
|
delete gateway;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
CDGIdGateway::CDGIdGateway(const std::string& configFile) :
|
||||||
|
m_callsign(),
|
||||||
|
m_suffix(),
|
||||||
|
m_conf(configFile),
|
||||||
|
m_writer(NULL),
|
||||||
|
m_gps(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CDGIdGateway::~CDGIdGateway()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int CDGIdGateway::run()
|
||||||
|
{
|
||||||
|
bool ret = m_conf.read();
|
||||||
|
if (!ret) {
|
||||||
|
::fprintf(stderr, "DGIdGateway: cannot read the .ini file\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
setlocale(LC_ALL, "C");
|
||||||
|
|
||||||
|
#if !defined(_WIN32) && !defined(_WIN64)
|
||||||
|
bool m_daemon = m_conf.getDaemon();
|
||||||
|
if (m_daemon) {
|
||||||
|
// Create new process
|
||||||
|
pid_t pid = ::fork();
|
||||||
|
if (pid == -1) {
|
||||||
|
::fprintf(stderr, "Couldn't fork() , exiting\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if (pid != 0) {
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new session and process group
|
||||||
|
if (::setsid() == -1) {
|
||||||
|
::fprintf(stderr, "Couldn't setsid(), exiting\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the working directory to the root directory
|
||||||
|
if (::chdir("/") == -1) {
|
||||||
|
::fprintf(stderr, "Couldn't cd /, exiting\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we are currently root...
|
||||||
|
if (getuid() == 0) {
|
||||||
|
struct passwd* user = ::getpwnam("mmdvm");
|
||||||
|
if (user == NULL) {
|
||||||
|
::fprintf(stderr, "Could not get the mmdvm user, exiting\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
::fprintf(stderr, "Could not set mmdvm GID, exiting\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setuid(mmdvm_uid) != 0) {
|
||||||
|
::fprintf(stderr, "Could not set mmdvm UID, exiting\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Double check it worked (AKA Paranoia)
|
||||||
|
if (setuid(0) != -1) {
|
||||||
|
::fprintf(stderr, "It's possible to regain root - something is wrong!, exiting\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ret = ::LogInitialise(m_conf.getLogFilePath(), m_conf.getLogFileRoot(), m_conf.getLogFileLevel(), m_conf.getLogDisplayLevel());
|
||||||
|
if (!ret) {
|
||||||
|
::fprintf(stderr, "DGIdGateway: unable to open the log file\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(_WIN32) && !defined(_WIN64)
|
||||||
|
if (m_daemon) {
|
||||||
|
::close(STDIN_FILENO);
|
||||||
|
::close(STDOUT_FILENO);
|
||||||
|
::close(STDERR_FILENO);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_callsign = m_conf.getCallsign();
|
||||||
|
m_suffix = m_conf.getSuffix();
|
||||||
|
|
||||||
|
bool debug = m_conf.getDebug();
|
||||||
|
in_addr rptAddress = CUDPSocket::lookup(m_conf.getRptAddress());
|
||||||
|
unsigned int rptPort = m_conf.getRptPort();
|
||||||
|
std::string myAddress = m_conf.getMyAddress();
|
||||||
|
unsigned int myPort = m_conf.getMyPort();
|
||||||
|
|
||||||
|
CYSFNetwork rptNetwork(myAddress, myPort, m_callsign, debug);
|
||||||
|
rptNetwork.setDestination("MMDVM", rptAddress, rptPort);
|
||||||
|
|
||||||
|
ret = rptNetwork.open();
|
||||||
|
if (!ret) {
|
||||||
|
::LogError("Cannot open the repeater network port");
|
||||||
|
::LogFinalise();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string fileName = m_conf.getYSFNetHosts();
|
||||||
|
|
||||||
|
CYSFReflectors* reflectors = new CYSFReflectors(fileName);
|
||||||
|
reflectors->load();
|
||||||
|
|
||||||
|
unsigned int currentDGId = 0U;
|
||||||
|
|
||||||
|
CDGIdNetwork* dgIdNetwork[100U];
|
||||||
|
for (unsigned int i = 0U; i < 100U; i++)
|
||||||
|
dgIdNetwork[i] = NULL;
|
||||||
|
|
||||||
|
std::vector<DGIdData*> dgIdData = m_conf.getDGIdData();
|
||||||
|
for (std::vector<DGIdData*>::const_iterator it = dgIdData.begin(); it != dgIdData.end(); ++it) {
|
||||||
|
unsigned int dgid = (*it)->m_dgId;
|
||||||
|
std::string type = (*it)->m_type;
|
||||||
|
bool statc = (*it)->m_static;
|
||||||
|
unsigned int rfHangTime = (*it)->m_rfHangTime;
|
||||||
|
unsigned int netHangTime = (*it)->m_netHangTime;
|
||||||
|
bool debug = (*it)->m_debug;
|
||||||
|
|
||||||
|
if (type == "FCS") {
|
||||||
|
std::string name = (*it)->m_name;
|
||||||
|
unsigned int local = (*it)->m_local;
|
||||||
|
unsigned int txFrequency = m_conf.getTxFrequency();
|
||||||
|
unsigned int rxFrequency = m_conf.getRxFrequency();
|
||||||
|
std::string locator = calculateLocator();
|
||||||
|
unsigned int id = m_conf.getId();
|
||||||
|
|
||||||
|
dgIdNetwork[dgid] = new CFCSNetwork(name, local, m_callsign, rxFrequency, txFrequency, locator, id, debug);
|
||||||
|
dgIdNetwork[dgid]->m_modes = YSF_DT_VD_MODE1 | YSF_DT_VD_MODE2 | YSF_DT_VOICE_FR_MODE | YSF_DT_DATA_FR_MODE;
|
||||||
|
dgIdNetwork[dgid]->m_static = statc;
|
||||||
|
dgIdNetwork[dgid]->m_rfHangTime = rfHangTime;
|
||||||
|
dgIdNetwork[dgid]->m_netHangTime = netHangTime;
|
||||||
|
} else if (type == "YSF") {
|
||||||
|
std::string name = (*it)->m_name;
|
||||||
|
unsigned int local = (*it)->m_local;
|
||||||
|
|
||||||
|
CYSFReflector* reflector = reflectors->findByName(name);
|
||||||
|
if (reflector != NULL) {
|
||||||
|
CYSFNetwork* ysf = new CYSFNetwork(local, m_callsign, debug);
|
||||||
|
ysf->setDestination(reflector->m_name, reflector->m_address, reflector->m_port);
|
||||||
|
|
||||||
|
dgIdNetwork[dgid] = ysf;
|
||||||
|
dgIdNetwork[dgid]->m_modes = YSF_DT_VD_MODE1 | YSF_DT_VD_MODE2 | YSF_DT_VOICE_FR_MODE | YSF_DT_DATA_FR_MODE;
|
||||||
|
dgIdNetwork[dgid]->m_static = statc;
|
||||||
|
dgIdNetwork[dgid]->m_rfHangTime = rfHangTime;
|
||||||
|
dgIdNetwork[dgid]->m_netHangTime = netHangTime;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
} else if (type == "IMRS") {
|
||||||
|
dgIdNetwork[dgid] = new CIMRSNetwork;
|
||||||
|
dgIdNetwork[dgid]->m_modes = YSF_DT_VD_MODE1 | YSF_DT_VD_MODE2 | YSF_DT_VOICE_FR_MODE | YSF_DT_DATA_FR_MODE;
|
||||||
|
dgIdNetwork[dgid]->m_static = statc;
|
||||||
|
dgIdNetwork[dgid]->m_rfHangTime = rfHangTime;
|
||||||
|
dgIdNetwork[dgid]->m_netHangTime = netHangTime;
|
||||||
|
*/
|
||||||
|
} else if (type == "Parrot") {
|
||||||
|
in_addr address = CUDPSocket::lookup((*it)->m_address);
|
||||||
|
unsigned int port = (*it)->m_port;
|
||||||
|
unsigned int local = (*it)->m_local;
|
||||||
|
|
||||||
|
if (address.s_addr != INADDR_NONE) {
|
||||||
|
CYSFNetwork* ysf = new CYSFNetwork(local, m_callsign, debug);
|
||||||
|
ysf->setDestination("PARROT", address, port);
|
||||||
|
|
||||||
|
dgIdNetwork[dgid] = ysf;
|
||||||
|
dgIdNetwork[dgid]->m_modes = YSF_DT_VD_MODE1 | YSF_DT_VD_MODE2 | YSF_DT_VOICE_FR_MODE | YSF_DT_DATA_FR_MODE;
|
||||||
|
dgIdNetwork[dgid]->m_static = statc;
|
||||||
|
dgIdNetwork[dgid]->m_rfHangTime = rfHangTime;
|
||||||
|
dgIdNetwork[dgid]->m_netHangTime = netHangTime;
|
||||||
|
}
|
||||||
|
} else if (type == "YSF2DMR") {
|
||||||
|
in_addr address = CUDPSocket::lookup((*it)->m_address);
|
||||||
|
unsigned int port = (*it)->m_port;
|
||||||
|
unsigned int local = (*it)->m_local;
|
||||||
|
|
||||||
|
if (address.s_addr != INADDR_NONE) {
|
||||||
|
CYSFNetwork* ysf = new CYSFNetwork(local, m_callsign, debug);
|
||||||
|
ysf->setDestination("YSF2DMR", address, port);
|
||||||
|
|
||||||
|
dgIdNetwork[dgid] = ysf;
|
||||||
|
dgIdNetwork[dgid]->m_modes = YSF_DT_VD_MODE1 | YSF_DT_VD_MODE2;
|
||||||
|
dgIdNetwork[dgid]->m_static = statc;
|
||||||
|
dgIdNetwork[dgid]->m_rfHangTime = rfHangTime;
|
||||||
|
dgIdNetwork[dgid]->m_netHangTime = netHangTime;
|
||||||
|
}
|
||||||
|
} else if (type == "YSF2NXDN") {
|
||||||
|
in_addr address = CUDPSocket::lookup((*it)->m_address);
|
||||||
|
unsigned int port = (*it)->m_port;
|
||||||
|
unsigned int local = (*it)->m_local;
|
||||||
|
|
||||||
|
if (address.s_addr != INADDR_NONE) {
|
||||||
|
CYSFNetwork* ysf = new CYSFNetwork(local, m_callsign, debug);
|
||||||
|
ysf->setDestination("YSF2NXDN", address, port);
|
||||||
|
|
||||||
|
dgIdNetwork[dgid] = ysf;
|
||||||
|
dgIdNetwork[dgid]->m_modes = YSF_DT_VD_MODE1 | YSF_DT_VD_MODE2;
|
||||||
|
dgIdNetwork[dgid]->m_static = statc;
|
||||||
|
dgIdNetwork[dgid]->m_rfHangTime = rfHangTime;
|
||||||
|
dgIdNetwork[dgid]->m_netHangTime = netHangTime;
|
||||||
|
}
|
||||||
|
} else if (type == "YSF2P25") {
|
||||||
|
in_addr address = CUDPSocket::lookup((*it)->m_address);
|
||||||
|
unsigned int port = (*it)->m_port;
|
||||||
|
unsigned int local = (*it)->m_local;
|
||||||
|
|
||||||
|
if (address.s_addr != INADDR_NONE) {
|
||||||
|
CYSFNetwork* ysf = new CYSFNetwork(local, m_callsign, debug);
|
||||||
|
ysf->setDestination("YSF2P25", address, port);
|
||||||
|
|
||||||
|
dgIdNetwork[dgid] = ysf;
|
||||||
|
dgIdNetwork[dgid]->m_modes = YSF_DT_VOICE_FR_MODE;
|
||||||
|
dgIdNetwork[dgid]->m_static = statc;
|
||||||
|
dgIdNetwork[dgid]->m_rfHangTime = rfHangTime;
|
||||||
|
dgIdNetwork[dgid]->m_netHangTime = netHangTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dgIdNetwork[dgid] != NULL) {
|
||||||
|
LogDebug("Loaded DG-ID %u", dgid);
|
||||||
|
bool ret = dgIdNetwork[dgid]->open();
|
||||||
|
if (!ret) {
|
||||||
|
delete dgIdNetwork[dgid];
|
||||||
|
dgIdNetwork[dgid] = NULL;
|
||||||
|
}
|
||||||
|
if (dgIdNetwork[dgid] != NULL && dgIdNetwork[dgid]->m_static) {
|
||||||
|
dgIdNetwork[dgid]->link();
|
||||||
|
dgIdNetwork[dgid]->link();
|
||||||
|
dgIdNetwork[dgid]->link();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createGPS();
|
||||||
|
|
||||||
|
CTimer inactivityTimer(1000U);
|
||||||
|
|
||||||
|
CStopWatch stopWatch;
|
||||||
|
stopWatch.start();
|
||||||
|
|
||||||
|
LogMessage("Starting DGIdGateway-%s", VERSION);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
unsigned char buffer[200U];
|
||||||
|
memset(buffer, 0U, 200U);
|
||||||
|
|
||||||
|
if (rptNetwork.read(0U, buffer) > 0U) {
|
||||||
|
if (::memcmp(buffer + 0U, "YSFD", 4U) == 0) {
|
||||||
|
CYSFFICH fich;
|
||||||
|
bool valid = fich.decode(buffer + 35U);
|
||||||
|
if (valid) {
|
||||||
|
unsigned char fi = fich.getFI();
|
||||||
|
unsigned char dt = fich.getDT();
|
||||||
|
unsigned char fn = fich.getFN();
|
||||||
|
unsigned char ft = fich.getFT();
|
||||||
|
unsigned char dgId = fich.getDGId();
|
||||||
|
|
||||||
|
if (dgId != 0U && dgId != currentDGId) {
|
||||||
|
if (dgIdNetwork[currentDGId] != NULL && !dgIdNetwork[currentDGId]->m_static) {
|
||||||
|
dgIdNetwork[currentDGId]->unlink();
|
||||||
|
dgIdNetwork[currentDGId]->unlink();
|
||||||
|
dgIdNetwork[currentDGId]->unlink();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dgIdNetwork[dgId] != NULL && !dgIdNetwork[dgId]->m_static) {
|
||||||
|
dgIdNetwork[dgId]->link();
|
||||||
|
dgIdNetwork[dgId]->link();
|
||||||
|
dgIdNetwork[dgId]->link();
|
||||||
|
}
|
||||||
|
|
||||||
|
LogDebug("DG-ID set to %u via RF", dgId);
|
||||||
|
currentDGId = dgId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_gps != NULL)
|
||||||
|
m_gps->data(buffer + 14U, buffer + 35U, fi, dt, fn, ft);
|
||||||
|
|
||||||
|
if (currentDGId != 0U && dgIdNetwork[currentDGId] != NULL) {
|
||||||
|
// Only allow the wanted modes through
|
||||||
|
if ((dgIdNetwork[currentDGId]->m_modes & dt) != 0U) {
|
||||||
|
dgIdNetwork[currentDGId]->write(currentDGId, buffer);
|
||||||
|
inactivityTimer.setTimeout(dgIdNetwork[currentDGId]->m_rfHangTime);
|
||||||
|
inactivityTimer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((buffer[34U] & 0x01U) == 0x01U) {
|
||||||
|
if (m_gps != NULL)
|
||||||
|
m_gps->reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 1U; i < 100U; i++) {
|
||||||
|
if (dgIdNetwork[i] != NULL) {
|
||||||
|
unsigned int len = dgIdNetwork[i]->read(i, buffer);
|
||||||
|
if (len > 0U && (i == currentDGId || currentDGId == 0U)) {
|
||||||
|
if (::memcmp(buffer + 0U, "YSFD", 4U) == 0) {
|
||||||
|
CYSFFICH fich;
|
||||||
|
bool valid = fich.decode(buffer + 35U);
|
||||||
|
if (valid) {
|
||||||
|
fich.setDGId(i);
|
||||||
|
fich.encode(buffer + 35U);
|
||||||
|
|
||||||
|
rptNetwork.write(0U, buffer);
|
||||||
|
inactivityTimer.setTimeout(dgIdNetwork[i]->m_netHangTime);
|
||||||
|
inactivityTimer.start();
|
||||||
|
|
||||||
|
if (currentDGId == 0U) {
|
||||||
|
LogDebug("DG-ID set to %u via Network", i);
|
||||||
|
currentDGId = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int ms = stopWatch.elapsed();
|
||||||
|
stopWatch.start();
|
||||||
|
|
||||||
|
rptNetwork.clock(ms);
|
||||||
|
for (unsigned int i = 0U; i < 100U; i++) {
|
||||||
|
if (dgIdNetwork[i] != NULL)
|
||||||
|
dgIdNetwork[i]->clock(ms);
|
||||||
|
}
|
||||||
|
if (m_writer != NULL)
|
||||||
|
m_writer->clock(ms);
|
||||||
|
|
||||||
|
inactivityTimer.clock(ms);
|
||||||
|
if (inactivityTimer.isRunning() && inactivityTimer.hasExpired()) {
|
||||||
|
if (dgIdNetwork[currentDGId] != NULL && !dgIdNetwork[currentDGId]->m_static) {
|
||||||
|
dgIdNetwork[currentDGId]->unlink();
|
||||||
|
dgIdNetwork[currentDGId]->unlink();
|
||||||
|
dgIdNetwork[currentDGId]->unlink();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LogDebug("DG-ID set to 0 via timeout");
|
||||||
|
|
||||||
|
currentDGId = 0U;
|
||||||
|
inactivityTimer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ms < 5U)
|
||||||
|
CThread::sleep(5U);
|
||||||
|
}
|
||||||
|
|
||||||
|
rptNetwork.close();
|
||||||
|
|
||||||
|
if (m_gps != NULL) {
|
||||||
|
m_writer->close();
|
||||||
|
delete m_writer;
|
||||||
|
delete m_gps;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 1U; i < 100U; i++) {
|
||||||
|
if (dgIdNetwork[i] != NULL) {
|
||||||
|
dgIdNetwork[i]->unlink();
|
||||||
|
dgIdNetwork[i]->unlink();
|
||||||
|
dgIdNetwork[i]->unlink();
|
||||||
|
dgIdNetwork[i]->close();
|
||||||
|
delete dgIdNetwork[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::LogFinalise();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDGIdGateway::createGPS()
|
||||||
|
{
|
||||||
|
if (!m_conf.getAPRSEnabled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::string address = m_conf.getAPRSAddress();
|
||||||
|
unsigned int port = m_conf.getAPRSPort();
|
||||||
|
std::string suffix = m_conf.getAPRSSuffix();
|
||||||
|
bool debug = m_conf.getDebug();
|
||||||
|
|
||||||
|
m_writer = new CAPRSWriter(m_callsign, m_suffix, address, port, suffix, debug);
|
||||||
|
|
||||||
|
unsigned int txFrequency = m_conf.getTxFrequency();
|
||||||
|
unsigned int rxFrequency = m_conf.getRxFrequency();
|
||||||
|
std::string desc = m_conf.getAPRSDescription();
|
||||||
|
|
||||||
|
m_writer->setInfo(txFrequency, rxFrequency, desc);
|
||||||
|
|
||||||
|
bool enabled = m_conf.getGPSDEnabled();
|
||||||
|
if (enabled) {
|
||||||
|
std::string address = m_conf.getGPSDAddress();
|
||||||
|
std::string port = m_conf.getGPSDPort();
|
||||||
|
|
||||||
|
m_writer->setGPSDLocation(address, port);
|
||||||
|
} else {
|
||||||
|
float latitude = m_conf.getLatitude();
|
||||||
|
float longitude = m_conf.getLongitude();
|
||||||
|
int height = m_conf.getHeight();
|
||||||
|
|
||||||
|
m_writer->setStaticLocation(latitude, longitude, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ret = m_writer->open();
|
||||||
|
if (!ret) {
|
||||||
|
delete m_writer;
|
||||||
|
m_writer = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_gps = new CGPS(m_writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CDGIdGateway::calculateLocator()
|
||||||
|
{
|
||||||
|
std::string locator;
|
||||||
|
|
||||||
|
float latitude = m_conf.getLatitude();
|
||||||
|
float longitude = m_conf.getLongitude();
|
||||||
|
|
||||||
|
if (latitude < -90.0F || latitude > 90.0F)
|
||||||
|
return "AA00AA";
|
||||||
|
|
||||||
|
if (longitude < -360.0F || longitude > 360.0F)
|
||||||
|
return "AA00AA";
|
||||||
|
|
||||||
|
latitude += 90.0F;
|
||||||
|
|
||||||
|
if (longitude > 180.0F)
|
||||||
|
longitude -= 360.0F;
|
||||||
|
|
||||||
|
if (longitude < -180.0F)
|
||||||
|
longitude += 360.0F;
|
||||||
|
|
||||||
|
longitude += 180.0F;
|
||||||
|
|
||||||
|
float lon = ::floor(longitude / 20.0F);
|
||||||
|
float lat = ::floor(latitude / 10.0F);
|
||||||
|
|
||||||
|
locator += 'A' + (unsigned int)lon;
|
||||||
|
locator += 'A' + (unsigned int)lat;
|
||||||
|
|
||||||
|
longitude -= lon * 20.0F;
|
||||||
|
latitude -= lat * 10.0F;
|
||||||
|
|
||||||
|
lon = ::floor(longitude / 2.0F);
|
||||||
|
lat = ::floor(latitude / 1.0F);
|
||||||
|
|
||||||
|
locator += '0' + (unsigned int)lon;
|
||||||
|
locator += '0' + (unsigned int)lat;
|
||||||
|
|
||||||
|
longitude -= lon * 2.0F;
|
||||||
|
latitude -= lat * 1.0F;
|
||||||
|
|
||||||
|
lon = ::floor(longitude / (2.0F / 24.0F));
|
||||||
|
lat = ::floor(latitude / (1.0F / 24.0F));
|
||||||
|
|
||||||
|
locator += 'A' + (unsigned int)lon;
|
||||||
|
locator += 'A' + (unsigned int)lat;
|
||||||
|
|
||||||
|
return locator;
|
||||||
|
}
|
||||||
|
|
152
DGIdGateway/DGIdGateway.filters
Normal file
152
DGIdGateway/DGIdGateway.filters
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
<?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="RingBuffer.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="StopWatch.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="Version.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="YSFDefines.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Log.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="YSFGateway.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Conf.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="YSFFICH.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="CRC.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Golay24128.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="YSFConvolution.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="GPS.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="YSFPayload.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="WiresX.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Thread.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Sync.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Utils.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="APRSWriter.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="DTMF.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="YSFNetwork.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="YSFReflectors.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="FCSNetwork.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="StopWatch.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="Log.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="YSFGateway.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Conf.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="YSFFICH.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="CRC.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Golay24128.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="YSFConvolution.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="GPS.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="YSFPayload.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="WiresX.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Thread.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Sync.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Utils.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="APRSWriter.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="DTMF.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="YSFNetwork.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="YSFReflectors.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="FCSNetwork.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
47
DGIdGateway/DGIdGateway.h
Normal file
47
DGIdGateway/DGIdGateway.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016,2017,2018,2020 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(DGIdGateway_H)
|
||||||
|
#define DGIdGateway_H
|
||||||
|
|
||||||
|
#include "APRSWriter.h"
|
||||||
|
#include "Conf.h"
|
||||||
|
#include "GPS.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class CDGIdGateway
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CDGIdGateway(const std::string& configFile);
|
||||||
|
~CDGIdGateway();
|
||||||
|
|
||||||
|
int run();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_callsign;
|
||||||
|
std::string m_suffix;
|
||||||
|
CConf m_conf;
|
||||||
|
CAPRSWriter* m_writer;
|
||||||
|
CGPS* m_gps;
|
||||||
|
|
||||||
|
std::string calculateLocator();
|
||||||
|
void createGPS();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
138
DGIdGateway/DGIdGateway.ini
Normal file
138
DGIdGateway/DGIdGateway.ini
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
[General]
|
||||||
|
Callsign=G9BF
|
||||||
|
Suffix=RPT
|
||||||
|
# Suffix=ND
|
||||||
|
Id=1234567
|
||||||
|
RptAddress=127.0.0.1
|
||||||
|
RptPort=3200
|
||||||
|
LocalAddress=127.0.0.1
|
||||||
|
LocalPort=4200
|
||||||
|
RFHangTime=120
|
||||||
|
NetHangTime=120
|
||||||
|
Debug=0
|
||||||
|
Daemon=0
|
||||||
|
|
||||||
|
[Info]
|
||||||
|
RXFrequency=430475000
|
||||||
|
TXFrequency=439475000
|
||||||
|
Power=1
|
||||||
|
Latitude=0.0
|
||||||
|
Longitude=0.0
|
||||||
|
Height=0
|
||||||
|
Name=Nowhere
|
||||||
|
Description=Multi-Mode Repeater
|
||||||
|
|
||||||
|
[Log]
|
||||||
|
# Logging levels, 0=No logging
|
||||||
|
DisplayLevel=1
|
||||||
|
FileLevel=1
|
||||||
|
FilePath=.
|
||||||
|
FileRoot=DGIdGateway
|
||||||
|
|
||||||
|
[APRS]
|
||||||
|
Enable=0
|
||||||
|
Address=127.0.0.1
|
||||||
|
Port=8673
|
||||||
|
Description=APRS Description
|
||||||
|
Suffix=Y
|
||||||
|
|
||||||
|
[YSF Network]
|
||||||
|
Hosts=./YSFHosts.txt
|
||||||
|
RFHangTime=120
|
||||||
|
NetHangTime=60
|
||||||
|
Debug=0
|
||||||
|
|
||||||
|
[FCS Network]
|
||||||
|
RFHangTime=120
|
||||||
|
NetHangTime=60
|
||||||
|
Debug=0
|
||||||
|
|
||||||
|
[DGId=1]
|
||||||
|
# YSF Local Parrot
|
||||||
|
Type=Parrot
|
||||||
|
Static=1
|
||||||
|
Address=127.0.0.1
|
||||||
|
Port=42012
|
||||||
|
Local=42013
|
||||||
|
RFHangTime=30
|
||||||
|
NetHangTime=30
|
||||||
|
Debug=0
|
||||||
|
|
||||||
|
[DGId=10]
|
||||||
|
# Local YSF2DMR TG23590
|
||||||
|
Type=YSF2DMR
|
||||||
|
Static=1
|
||||||
|
Address=127.0.0.1
|
||||||
|
Port=42014
|
||||||
|
Local=42015
|
||||||
|
#RFHangTime=120
|
||||||
|
#NetHangTime=60
|
||||||
|
Debug=0
|
||||||
|
|
||||||
|
[DGId=11]
|
||||||
|
# Local YSF2DMR TG23510
|
||||||
|
Type=YSF2DMR
|
||||||
|
Static=1
|
||||||
|
Address=127.0.0.1
|
||||||
|
Port=42016
|
||||||
|
Local=42017
|
||||||
|
#RFHangTime=120
|
||||||
|
#NetHangTime=60
|
||||||
|
Debug=0
|
||||||
|
|
||||||
|
[DGId=20]
|
||||||
|
# Local YSF2NXDN TG65000
|
||||||
|
Type=YSF2NXDN
|
||||||
|
Static=1
|
||||||
|
Address=127.0.0.1
|
||||||
|
Port=42018
|
||||||
|
Local=42019
|
||||||
|
#RFHangTime=120
|
||||||
|
#NetHangTime=60
|
||||||
|
Debug=0
|
||||||
|
|
||||||
|
[DGId=30]
|
||||||
|
# Local YSF2P25 TG10200
|
||||||
|
Type=YSF2P25
|
||||||
|
Static=1
|
||||||
|
Address=127.0.0.1
|
||||||
|
Port=42020
|
||||||
|
Local=42021
|
||||||
|
#RFHangTime=120
|
||||||
|
#NetHangTime=60
|
||||||
|
Debug=0
|
||||||
|
|
||||||
|
[DGId=40]
|
||||||
|
# YSF Reflector CQ-UK
|
||||||
|
Type=YSF
|
||||||
|
Static=0
|
||||||
|
Name=0-0-CQ-UK-ROOM
|
||||||
|
Local=42023
|
||||||
|
#RFHangTime=120
|
||||||
|
#NetHangTime=60
|
||||||
|
Debug=0
|
||||||
|
|
||||||
|
[DGId=50]
|
||||||
|
# FCS Reflector FCS001-01
|
||||||
|
Type=FCS
|
||||||
|
Static=0
|
||||||
|
Name=FCS00101
|
||||||
|
Local=42025
|
||||||
|
#RFHangTime=120
|
||||||
|
#NetHangTime=60
|
||||||
|
Debug=0
|
||||||
|
|
||||||
|
[DGId=100]
|
||||||
|
# Local IMRS System Fusion Network
|
||||||
|
Type=IMRS
|
||||||
|
Destination=100,44.131.4.1
|
||||||
|
Destination=75,44.131.4.2
|
||||||
|
#RFHangTime=120
|
||||||
|
#NetHangTime=60
|
||||||
|
Debug=1
|
||||||
|
|
||||||
|
[GPSD]
|
||||||
|
Enable=0
|
||||||
|
Address=127.0.0.1
|
||||||
|
Port=2947
|
||||||
|
|
200
DGIdGateway/DGIdGateway.vcxproj
Normal file
200
DGIdGateway/DGIdGateway.vcxproj
Normal file
|
@ -0,0 +1,200 @@
|
||||||
|
<?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>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{4F82857B-D2CC-48DC-91A8-6275BDD3081B}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>YSFGateway</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.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>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</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>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</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>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="APRSWriter.h" />
|
||||||
|
<ClInclude Include="Conf.h" />
|
||||||
|
<ClInclude Include="CRC.h" />
|
||||||
|
<ClInclude Include="DTMF.h" />
|
||||||
|
<ClInclude Include="FCSNetwork.h" />
|
||||||
|
<ClInclude Include="Golay24128.h" />
|
||||||
|
<ClInclude Include="GPS.h" />
|
||||||
|
<ClInclude Include="Log.h" />
|
||||||
|
<ClInclude Include="RingBuffer.h" />
|
||||||
|
<ClInclude Include="StopWatch.h" />
|
||||||
|
<ClInclude Include="Sync.h" />
|
||||||
|
<ClInclude Include="Thread.h" />
|
||||||
|
<ClInclude Include="Timer.h" />
|
||||||
|
<ClInclude Include="UDPSocket.h" />
|
||||||
|
<ClInclude Include="Utils.h" />
|
||||||
|
<ClInclude Include="Version.h" />
|
||||||
|
<ClInclude Include="WiresX.h" />
|
||||||
|
<ClInclude Include="YSFConvolution.h" />
|
||||||
|
<ClInclude Include="YSFDefines.h" />
|
||||||
|
<ClInclude Include="YSFFICH.h" />
|
||||||
|
<ClInclude Include="YSFGateway.h" />
|
||||||
|
<ClInclude Include="YSFNetwork.h" />
|
||||||
|
<ClInclude Include="YSFPayload.h" />
|
||||||
|
<ClInclude Include="YSFReflectors.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="APRSWriter.cpp" />
|
||||||
|
<ClCompile Include="Conf.cpp" />
|
||||||
|
<ClCompile Include="CRC.cpp" />
|
||||||
|
<ClCompile Include="DTMF.cpp" />
|
||||||
|
<ClCompile Include="FCSNetwork.cpp" />
|
||||||
|
<ClCompile Include="Golay24128.cpp" />
|
||||||
|
<ClCompile Include="GPS.cpp" />
|
||||||
|
<ClCompile Include="Log.cpp" />
|
||||||
|
<ClCompile Include="StopWatch.cpp" />
|
||||||
|
<ClCompile Include="Sync.cpp" />
|
||||||
|
<ClCompile Include="Thread.cpp" />
|
||||||
|
<ClCompile Include="Timer.cpp" />
|
||||||
|
<ClCompile Include="UDPSocket.cpp" />
|
||||||
|
<ClCompile Include="Utils.cpp" />
|
||||||
|
<ClCompile Include="WiresX.cpp" />
|
||||||
|
<ClCompile Include="YSFConvolution.cpp" />
|
||||||
|
<ClCompile Include="YSFFICH.cpp" />
|
||||||
|
<ClCompile Include="YSFGateway.cpp" />
|
||||||
|
<ClCompile Include="YSFNetwork.cpp" />
|
||||||
|
<ClCompile Include="YSFPayload.cpp" />
|
||||||
|
<ClCompile Include="YSFReflectors.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
25
DGIdGateway/DGIdNetwork.cpp
Normal file
25
DGIdGateway/DGIdNetwork.cpp
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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 "DGIdNetwork.h"
|
||||||
|
|
||||||
|
|
||||||
|
CDGIdNetwork::~CDGIdNetwork()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
52
DGIdGateway/DGIdNetwork.h
Normal file
52
DGIdGateway/DGIdNetwork.h
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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 DGIdNetwork_H
|
||||||
|
#define DGIdNetwork_H
|
||||||
|
|
||||||
|
|
||||||
|
class CDGIdNetwork {
|
||||||
|
public:
|
||||||
|
virtual ~CDGIdNetwork() = 0;
|
||||||
|
|
||||||
|
virtual bool open() = 0;
|
||||||
|
|
||||||
|
virtual void link() = 0;
|
||||||
|
|
||||||
|
virtual void write(unsigned int dgId, const unsigned char* data) = 0;
|
||||||
|
|
||||||
|
virtual unsigned int read(unsigned int dgid, unsigned char* data) = 0;
|
||||||
|
|
||||||
|
virtual void clock(unsigned int ms) = 0;
|
||||||
|
|
||||||
|
virtual void unlink() = 0;
|
||||||
|
|
||||||
|
virtual void close() = 0;
|
||||||
|
|
||||||
|
// Allowed modes
|
||||||
|
unsigned char m_modes;
|
||||||
|
|
||||||
|
bool m_static;
|
||||||
|
|
||||||
|
unsigned int m_rfHangTime;
|
||||||
|
unsigned int m_netHangTime;
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
252
DGIdGateway/FCSNetwork.cpp
Normal file
252
DGIdGateway/FCSNetwork.cpp
Normal file
|
@ -0,0 +1,252 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009-2014,2016,2017,2018,2020 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 "YSFDefines.h"
|
||||||
|
#include "FCSNetwork.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
const char* FCS_VERSION = "MMDVM";
|
||||||
|
|
||||||
|
const unsigned int BUFFER_LENGTH = 200U;
|
||||||
|
|
||||||
|
CFCSNetwork::CFCSNetwork(const std::string& reflector, unsigned int port, const std::string& callsign, unsigned int rxFrequency, unsigned int txFrequency, const std::string& locator, unsigned int id, bool debug) :
|
||||||
|
m_socket(port),
|
||||||
|
m_debug(debug),
|
||||||
|
m_address(),
|
||||||
|
m_ping(NULL),
|
||||||
|
m_info(NULL),
|
||||||
|
m_reflector(reflector),
|
||||||
|
m_print(),
|
||||||
|
m_buffer(1000U, "FCS Network Buffer"),
|
||||||
|
m_n(0U),
|
||||||
|
m_pingTimer(1000U, 0U, 800U),
|
||||||
|
m_resetTimer(1000U, 1U),
|
||||||
|
m_state(FCS_UNLINKED)
|
||||||
|
{
|
||||||
|
m_info = new unsigned char[100U];
|
||||||
|
::sprintf((char*)m_info, "%9u%9u%-6.6s%-12.12s%7u", rxFrequency, txFrequency, locator.c_str(), FCS_VERSION, id);
|
||||||
|
::memset(m_info + 43U, ' ', 57U);
|
||||||
|
|
||||||
|
m_ping = new unsigned char[25U];
|
||||||
|
::memcpy(m_ping + 0U, "PING", 4U);
|
||||||
|
::memset(m_ping + 4U, ' ', 6U);
|
||||||
|
::memcpy(m_ping + 4U, callsign.c_str(), callsign.size());
|
||||||
|
::memset(m_ping + 10U, 0x00U, 15U);
|
||||||
|
::memcpy(m_ping + 10U, reflector.c_str(), 8U);
|
||||||
|
}
|
||||||
|
|
||||||
|
CFCSNetwork::~CFCSNetwork()
|
||||||
|
{
|
||||||
|
delete[] m_info;
|
||||||
|
delete[] m_ping;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CFCSNetwork::open()
|
||||||
|
{
|
||||||
|
LogMessage("Resolving FCS00x addresses");
|
||||||
|
|
||||||
|
m_addresses["FCS001"] = CUDPSocket::lookup("fcs001.xreflector.net");
|
||||||
|
m_addresses["FCS002"] = CUDPSocket::lookup("fcs002.xreflector.net");
|
||||||
|
m_addresses["FCS003"] = CUDPSocket::lookup("fcs003.xreflector.net");
|
||||||
|
m_addresses["FCS004"] = CUDPSocket::lookup("fcs004.xreflector.net");
|
||||||
|
m_addresses["FCS005"] = CUDPSocket::lookup("fcs005.xreflector.net");
|
||||||
|
m_addresses["FCS222"] = CUDPSocket::lookup("fcs222.xreflector.net");
|
||||||
|
m_addresses["FCS224"] = CUDPSocket::lookup("fcs224.xreflector.net");
|
||||||
|
m_addresses["FCS232"] = CUDPSocket::lookup("fcs232.xreflector.net");
|
||||||
|
|
||||||
|
LogMessage("Opening FCS network connection");
|
||||||
|
|
||||||
|
return m_socket.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFCSNetwork::write(const unsigned char* data)
|
||||||
|
{
|
||||||
|
assert(data != NULL);
|
||||||
|
|
||||||
|
if (m_state != FCS_LINKED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
unsigned char buffer[130U];
|
||||||
|
::memset(buffer + 0U, ' ', 130U);
|
||||||
|
::memcpy(buffer + 0U, data + 35U, 120U);
|
||||||
|
::memcpy(buffer + 121U, m_reflector.c_str(), 8U);
|
||||||
|
|
||||||
|
if (m_debug)
|
||||||
|
CUtils::dump(1U, "FCS Network Data Sent", buffer, 130U);
|
||||||
|
|
||||||
|
m_socket.write(buffer, 130U, m_address, FCS_PORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFCSNetwork::link()
|
||||||
|
{
|
||||||
|
if (m_state != FCS_LINKED) {
|
||||||
|
std::string name = m_reflector.substr(0U, 6U);
|
||||||
|
if (m_addresses.count(name) == 0U) {
|
||||||
|
LogError("Unknown FCS reflector - %s", name.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_address = m_addresses[name];
|
||||||
|
if (m_address.s_addr == INADDR_NONE) {
|
||||||
|
LogError("FCS reflector %s has no address", name.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_print = m_reflector.substr(0U, 6U) + "-" + m_reflector.substr(6U);
|
||||||
|
|
||||||
|
m_state = FCS_LINKING;
|
||||||
|
|
||||||
|
m_pingTimer.start();
|
||||||
|
|
||||||
|
writePing();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFCSNetwork::unlink()
|
||||||
|
{
|
||||||
|
if (m_state != FCS_LINKED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_socket.write((unsigned char*)"CLOSE ", 11U, m_address, FCS_PORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFCSNetwork::clock(unsigned int ms)
|
||||||
|
{
|
||||||
|
m_pingTimer.clock(ms);
|
||||||
|
if (m_pingTimer.isRunning() && m_pingTimer.hasExpired()) {
|
||||||
|
writePing();
|
||||||
|
m_pingTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_resetTimer.clock(ms);
|
||||||
|
if (m_resetTimer.isRunning() && m_resetTimer.hasExpired()) {
|
||||||
|
m_n = 0U;
|
||||||
|
m_resetTimer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (m_state == FCS_UNLINKED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (address.s_addr != m_address.s_addr || port != FCS_PORT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_debug)
|
||||||
|
CUtils::dump(1U, "FCS Network Data Received", buffer, length);
|
||||||
|
|
||||||
|
if (length == 7) {
|
||||||
|
if (m_state == FCS_LINKING)
|
||||||
|
LogMessage("Linked to %s", m_print.c_str());
|
||||||
|
m_state = FCS_LINKED;
|
||||||
|
writeInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length == 10 && m_state == FCS_LINKING) {
|
||||||
|
LogMessage("Linked to %s", m_print.c_str());
|
||||||
|
m_state = FCS_LINKED;
|
||||||
|
writeInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length == 7 || length == 10 || length == 130) {
|
||||||
|
unsigned char len = length;
|
||||||
|
m_buffer.addData(&len, 1U);
|
||||||
|
m_buffer.addData(buffer, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int CFCSNetwork::read(unsigned char* data)
|
||||||
|
{
|
||||||
|
assert(data != NULL);
|
||||||
|
|
||||||
|
if (m_buffer.isEmpty())
|
||||||
|
return 0U;
|
||||||
|
|
||||||
|
unsigned char len = 0U;
|
||||||
|
m_buffer.getData(&len, 1U);
|
||||||
|
|
||||||
|
// Pass pings up to the gateway to reset the lost timer.
|
||||||
|
if (len != 130U) {
|
||||||
|
m_buffer.getData(data, len);
|
||||||
|
|
||||||
|
::memset(data + 0U, ' ', 14U);
|
||||||
|
::memcpy(data + 0U, "YSFP", 4U);
|
||||||
|
::memcpy(data + 4U, m_print.c_str(), 8U);
|
||||||
|
|
||||||
|
return 14U;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_resetTimer.start();
|
||||||
|
|
||||||
|
unsigned char buffer[130U];
|
||||||
|
m_buffer.getData(buffer, len);
|
||||||
|
|
||||||
|
::memset(data + 0U, ' ', 35U);
|
||||||
|
::memcpy(data + 0U, "YSFD", 4U);
|
||||||
|
::memcpy(data + 35U, buffer, 120U);
|
||||||
|
|
||||||
|
// Put the reflector name as the via callsign.
|
||||||
|
::memcpy(data + 4U, m_print.c_str(), 9U);
|
||||||
|
|
||||||
|
data[34U] = m_n;
|
||||||
|
m_n += 2U;
|
||||||
|
|
||||||
|
return 155U;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFCSNetwork::close()
|
||||||
|
{
|
||||||
|
m_socket.close();
|
||||||
|
|
||||||
|
LogMessage("Closing FCS network connection");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFCSNetwork::writeInfo()
|
||||||
|
{
|
||||||
|
if (m_state != FCS_LINKED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_debug)
|
||||||
|
CUtils::dump(1U, "FCS Network Data Sent", m_info, 100U);
|
||||||
|
|
||||||
|
m_socket.write(m_info, 100U, m_address, FCS_PORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFCSNetwork::writePing()
|
||||||
|
{
|
||||||
|
if (m_state == FCS_UNLINKED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_debug)
|
||||||
|
CUtils::dump(1U, "FCS Network Data Sent", m_ping, 25U);
|
||||||
|
|
||||||
|
m_socket.write(m_ping, 25U, m_address, FCS_PORT);
|
||||||
|
}
|
76
DGIdGateway/FCSNetwork.h
Normal file
76
DGIdGateway/FCSNetwork.h
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009-2014,2016,2017,2018,2020 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 FCSNetwork_H
|
||||||
|
#define FCSNetwork_H
|
||||||
|
|
||||||
|
#include "DGIdNetwork.h"
|
||||||
|
#include "YSFDefines.h"
|
||||||
|
#include "UDPSocket.h"
|
||||||
|
#include "RingBuffer.h"
|
||||||
|
#include "Timer.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
enum FCS_STATE {
|
||||||
|
FCS_UNLINKED,
|
||||||
|
FCS_LINKING,
|
||||||
|
FCS_LINKED
|
||||||
|
};
|
||||||
|
|
||||||
|
class CFCSNetwork : public CDGIdNetwork {
|
||||||
|
public:
|
||||||
|
CFCSNetwork(const std::string& reflector, unsigned int port, const std::string& callsign, unsigned int rxFrequency, unsigned int txFrequency, const std::string& locator, unsigned int id, bool debug);
|
||||||
|
virtual ~CFCSNetwork();
|
||||||
|
|
||||||
|
virtual bool open();
|
||||||
|
|
||||||
|
virtual void link();
|
||||||
|
|
||||||
|
virtual void write(unsigned int dgId, const unsigned char* data);
|
||||||
|
|
||||||
|
virtual unsigned int read(unsigned int dgId, unsigned char* data);
|
||||||
|
|
||||||
|
virtual void clock(unsigned int ms);
|
||||||
|
|
||||||
|
virtual void unlink();
|
||||||
|
|
||||||
|
virtual void close();
|
||||||
|
|
||||||
|
private:
|
||||||
|
CUDPSocket m_socket;
|
||||||
|
bool m_debug;
|
||||||
|
in_addr m_address;
|
||||||
|
unsigned char* m_ping;
|
||||||
|
unsigned char* m_info;
|
||||||
|
std::string m_reflector;
|
||||||
|
std::string m_print;
|
||||||
|
CRingBuffer<unsigned char> m_buffer;
|
||||||
|
std::map<std::string, in_addr> m_addresses;
|
||||||
|
unsigned char m_n;
|
||||||
|
CTimer m_pingTimer;
|
||||||
|
CTimer m_resetTimer;
|
||||||
|
FCS_STATE m_state;
|
||||||
|
|
||||||
|
void writeInfo();
|
||||||
|
void writePing();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
678
DGIdGateway/FCSRooms.txt
Normal file
678
DGIdGateway/FCSRooms.txt
Normal file
|
@ -0,0 +1,678 @@
|
||||||
|
# FCS_Hosts.txt downloaded from http://www.pistar.uk/downloads/FCS_Hosts.txt
|
||||||
|
# Sourced from PiStar.UK Update Server
|
||||||
|
# File created at Tuesday 8th of May 2018 01:20:49 AM BST
|
||||||
|
FCS00100;Repeater;FCS001 - Repeater;;;
|
||||||
|
FCS00101;Deutschland;FCS001 - Deutschland;;;
|
||||||
|
FCS00102;World Wide ;FCS001 - World Wide ;;;
|
||||||
|
FCS00103;Switzerland;FCS001 - Switzerland;;;
|
||||||
|
FCS00104;Denmark;FCS001 - Denmark;;;
|
||||||
|
FCS00105;Great Britain;FCS001 - Great Britain;;;
|
||||||
|
FCS00106;United States of America;FCS001 - United States of America;;;
|
||||||
|
FCS00107;Netherlands;FCS001 - Netherlands;;;
|
||||||
|
FCS00108;South korea;FCS001 - South korea;;;
|
||||||
|
FCS00109;Austria;FCS001 - Austria;;;
|
||||||
|
FCS00110;Sweden;FCS001 - Sweden;;;
|
||||||
|
FCS00111;Belgium;FCS001 - Belgium;;;
|
||||||
|
FCS00112;Portugal;FCS001 - Portugal;;;
|
||||||
|
FCS00113;Norway;FCS001 - Norway;;;
|
||||||
|
FCS00114;Australia;FCS001 - Australia;;;
|
||||||
|
FCS00115;Test System;FCS001 - Test System;;;
|
||||||
|
FCS00116;Brazil;FCS001 - Brazil;;;
|
||||||
|
FCS00117;Canada;FCS001 - Canada;;;
|
||||||
|
FCS00118;Spain;FCS001 - Spain;;;
|
||||||
|
FCS00119;Czech;FCS001 - Czech;;;
|
||||||
|
FCS00120;Slovakia;FCS001 - Slovakia;;;
|
||||||
|
FCS00121;Japan;FCS001 - Japan;;;
|
||||||
|
FCS00122;THAILAND;FCS001 - THAILAND;;;
|
||||||
|
FCS00123;Bulgaria;FCS001 - Bulgaria;;;
|
||||||
|
FCS00124; United States of America2;FCS001 - United States of America2;;;
|
||||||
|
FCS00125;Hungary;FCS001 - Hungary;;;
|
||||||
|
FCS00126;Polen;FCS001 - Polen;;;
|
||||||
|
FCS00127;Italy2;FCS001 - Italy2;;;
|
||||||
|
FCS00128;Australia;FCS001 - Australia;;;
|
||||||
|
FCS00129;Canada;FCS001 - Canada;;;
|
||||||
|
FCS00130;Iwate001jp-net;FCS001 - Iwate001jp-net;;;
|
||||||
|
FCS00131;Hessen;FCS001 - Hessen;;;
|
||||||
|
FCS00132;Luxembourg;FCS001 - Luxembourg;;;
|
||||||
|
FCS00133;Franc;FCS001 - Franc;;;
|
||||||
|
FCS00134;Greece;FCS001 - Greece;;;
|
||||||
|
FCS00135;Mecklenburg-Vorpommern;FCS001 - Mecklenburg-Vorpommern;;;
|
||||||
|
FCS00136;Sendai;FCS001 - Sendai;;;
|
||||||
|
FCS00139;China;FCS001 - China;;;
|
||||||
|
FCS00140;Spain2;FCS001 - Spain2;;;
|
||||||
|
FCS00141;HB9DR;FCS001 - HB9DR;;;
|
||||||
|
FCS00142;Repeater Schweiz;FCS001 - Repeater Schweiz;;;
|
||||||
|
FCS00143;GL/GR Room Schweiz;FCS001 - GL/GR Room Schweiz;;;
|
||||||
|
FCS00144;Zuerich/Schweiz;FCS001 - Zuerich/Schweiz;;;
|
||||||
|
FCS00146;DL-NORDWEST;FCS001 - DL-NORDWEST;;;
|
||||||
|
FCS00147;Kurpfalz;FCS001 - Kurpfalz;;;
|
||||||
|
FCS00150;Canada;FCS001 - Canada;;;
|
||||||
|
FCS00156;Elbe-Weser;FCS001 - Elbe-Weser;;;
|
||||||
|
FCS00160;CATALUNYA;FCS001 - CATALUNYA;;;
|
||||||
|
FCS00166;Nord-Ostsee-Link;FCS001 - Nord-Ostsee-Link;;;
|
||||||
|
FCS00167;Baden-Pfalz;FCS001 - Baden-Pfalz;;;
|
||||||
|
FCS00169;Italy;FCS001 - Italy;;;
|
||||||
|
FCS00170;SoCal Link Society;FCS001 - SoCal Link Society;;;
|
||||||
|
FCS00171;ARGENTINA LINK;FCS001 - ARGENTINA LINK;;;
|
||||||
|
FCS00173;phillipines;FCS001 - phillipines;;;
|
||||||
|
FCS00180;Schleswig-Holstein;FCS001 - Schleswig-Holstein;;;
|
||||||
|
FCS00186;GAUCHOS DEL SUR;FCS001 - GAUCHOS DEL SUR;;;
|
||||||
|
FCS00187;Rhein-Main / Wetterau;FCS001 - Rhein-Main / Wetterau;;;
|
||||||
|
FCS00188;TIROLER OBERLAND;FCS001 - TIROLER OBERLAND;;;
|
||||||
|
FCS00189;OE9/Vorarlberg;FCS001 - OE9/Vorarlberg;;;
|
||||||
|
FCS00192;Dongle User OE;FCS001 - Dongle User OE;;;
|
||||||
|
FCS00198;C4FM OE8;FCS001 - C4FM OE8;;;
|
||||||
|
FCS00199;ECHO;FCS001 - ECHO;;;
|
||||||
|
FCS00200;TALK USA1;FCS002 - TALK USA1;;;
|
||||||
|
FCS00201;TALK USA2;FCS002 - TALK USA2;;;
|
||||||
|
FCS00202;Alabama;FCS002 - Alabama;;;
|
||||||
|
FCS00203;Alaska;FCS002 - Alaska;;;
|
||||||
|
FCS00204;Arizona;FCS002 - Arizona;;;
|
||||||
|
FCS00205;Arkansas;FCS002 - Arkansas;;;
|
||||||
|
FCS00206;California;FCS002 - California;;;
|
||||||
|
FCS00207;Colorado;FCS002 - Colorado;;;
|
||||||
|
FCS00208;Connecticut;FCS002 - Connecticut;;;
|
||||||
|
FCS00209;Delaware;FCS002 - Delaware;;;
|
||||||
|
FCS00210;Florida;FCS002 - Florida;;;
|
||||||
|
FCS00211;Georgia;FCS002 - Georgia;;;
|
||||||
|
FCS00212;Hawaii;FCS002 - Hawaii;;;
|
||||||
|
FCS00213;Idaho;FCS002 - Idaho;;;
|
||||||
|
FCS00214;Illinois;FCS002 - Illinois;;;
|
||||||
|
FCS00215;Indiana;FCS002 - Indiana;;;
|
||||||
|
FCS00216;Iowa;FCS002 - Iowa;;;
|
||||||
|
FCS00217;Kansas;FCS002 - Kansas;;;
|
||||||
|
FCS00218;Louisiana;FCS002 - Louisiana;;;
|
||||||
|
FCS00219;Maine;FCS002 - Maine;;;
|
||||||
|
FCS00220;Maryland;FCS002 - Maryland;;;
|
||||||
|
FCS00221;Massachusetts;FCS002 - Massachusetts;;;
|
||||||
|
FCS00222;Michigan;FCS002 - Michigan;;;
|
||||||
|
FCS00223;Minnesota;FCS002 - Minnesota;;;
|
||||||
|
FCS00224;Mississippi;FCS002 - Mississippi;;;
|
||||||
|
FCS00225;Missouri;FCS002 - Missouri;;;
|
||||||
|
FCS00226;Montana;FCS002 - Montana;;;
|
||||||
|
FCS00227;Nebraska;FCS002 - Nebraska;;;
|
||||||
|
FCS00228;Nevada;FCS002 - Nevada;;;
|
||||||
|
FCS00229;New Hampshire;FCS002 - New Hampshire;;;
|
||||||
|
FCS00230;New Jersey;FCS002 - New Jersey;;;
|
||||||
|
FCS00231;New Mexico;FCS002 - New Mexico;;;
|
||||||
|
FCS00232;New York;FCS002 - New York;;;
|
||||||
|
FCS00233;North Carolina;FCS002 - North Carolina;;;
|
||||||
|
FCS00234;North Dakota;FCS002 - North Dakota;;;
|
||||||
|
FCS00235;Ohio;FCS002 - Ohio;;;
|
||||||
|
FCS00236;Oklahoma;FCS002 - Oklahoma;;;
|
||||||
|
FCS00237;Oregon;FCS002 - Oregon;;;
|
||||||
|
FCS00238;Pennsylvania;FCS002 - Pennsylvania;;;
|
||||||
|
FCS00239;Rhode Island;FCS002 - Rhode Island;;;
|
||||||
|
FCS00240;South Carolina;FCS002 - South Carolina;;;
|
||||||
|
FCS00241;South Dakota;FCS002 - South Dakota;;;
|
||||||
|
FCS00242;Tennessee;FCS002 - Tennessee;;;
|
||||||
|
FCS00243;Texas;FCS002 - Texas;;;
|
||||||
|
FCS00244;Utah;FCS002 - Utah;;;
|
||||||
|
FCS00245;Vermont;FCS002 - Vermont;;;
|
||||||
|
FCS00246;Virginia;FCS002 - Virginia;;;
|
||||||
|
FCS00247;Washington;FCS002 - Washington;;;
|
||||||
|
FCS00248;West Virginia;FCS002 - West Virginia;;;
|
||||||
|
FCS00249;Wisconsin;FCS002 - Wisconsin;;;
|
||||||
|
FCS00250;Wyoming;FCS002 - Wyoming;;;
|
||||||
|
FCS00251;AREC;FCS002 - AREC;;;
|
||||||
|
FCS00253;Puerto Rico;FCS002 - Puerto Rico;;;
|
||||||
|
FCS00255;Central Alabama;FCS002 - Central Alabama;;;
|
||||||
|
FCS00256;Northeast Florida;FCS002 - Northeast Florida;;;
|
||||||
|
FCS00259;Public Safety ARG;FCS002 - Public Safety ARG;;;
|
||||||
|
FCS00260;AB2BH-AZ;FCS002 - AB2BH-AZ;;;
|
||||||
|
FCS00261;Belfast;FCS002 - Belfast;;;
|
||||||
|
FCS00269;Illinois Link;FCS002 - Illinois Link;;;
|
||||||
|
FCS00270;SoCal Link Society;FCS002 - SoCal Link Society;;;
|
||||||
|
FCS00271;SoCal Link Society;FCS002 - SoCal Link Society;;;
|
||||||
|
FCS00275;Wires-X Spain;FCS002 - Wires-X Spain;;;
|
||||||
|
FCS00280;Canada english;FCS002 - Canada english;;;
|
||||||
|
FCS00281;Canada francais;FCS002 - Canada francais;;;
|
||||||
|
FCS00284;NJ-NY RGNL;FCS002 - NJ-NY RGNL;;;
|
||||||
|
FCS00285;America-Ragchew (Wires-X);FCS002 - America-Ragchew (Wires-X);;;
|
||||||
|
FCS00288;KK4GAF;FCS002 - KK4GAF;;;
|
||||||
|
FCS00290;America Link WIRES-X;FCS002 - America Link WIRES-X;;;
|
||||||
|
FCS00291;CQ-UK WIRES-X;FCS002 - CQ-UK WIRES-X;;;
|
||||||
|
FCS00298;Software Test;FCS002 - Software Test;;;
|
||||||
|
FCS00299;ECHO;FCS002 - ECHO;;;
|
||||||
|
FCS00300;Group SYSOP chat ROOM;FCS003 - Group SYSOP chat ROOM;;;
|
||||||
|
FCS00301;FUSION-CANADA-FR;FCS003 - FUSION-CANADA-FR;;;
|
||||||
|
FCS00302;FUSION-QUEBEC-EN;FCS003 - FUSION-QUEBEC-EN;;;
|
||||||
|
FCS00303;Newfoundland and Labrador;FCS003 - Newfoundland and Labrador;;;
|
||||||
|
FCS00304;PEI;FCS003 - PEI;;;
|
||||||
|
FCS00305;New Brunswick;FCS003 - New Brunswick;;;
|
||||||
|
FCS00306;Ontario;FCS003 - Ontario;;;
|
||||||
|
FCS00307;Manitoba;FCS003 - Manitoba;;;
|
||||||
|
FCS00308;Saskatchewan;FCS003 - Saskatchewan;;;
|
||||||
|
FCS00309;Alberta;FCS003 - Alberta;;;
|
||||||
|
FCS00310;British Columbia;FCS003 - British Columbia;;;
|
||||||
|
FCS00311;Yukon / NWT / Nunavut;FCS003 - Yukon / NWT / Nunavut;;;
|
||||||
|
FCS00312;New England USA-East;FCS003 - New England USA-East;;;
|
||||||
|
FCS00314;NILECOMM;FCS003 - NILECOMM;;;
|
||||||
|
FCS00315;PA-Fl Link Society;FCS003 - PA-Fl Link Society;;;
|
||||||
|
FCS00316;San Diego;FCS003 - San Diego;;;
|
||||||
|
FCS00317;VA7GH Test Room;FCS003 - VA7GH Test Room;;;
|
||||||
|
FCS00318;ALOHA-HAWAII Wires-X;FCS003 - ALOHA-HAWAII Wires-X;;;
|
||||||
|
FCS00320;Irish Group;FCS003 - Irish Group;;;
|
||||||
|
FCS00321;CARS Nevada;FCS003 - CARS Nevada;;;
|
||||||
|
FCS00325;D.A.R.N.;FCS003 - D.A.R.N.;;;
|
||||||
|
FCS00328;SouthEast Mississippi;FCS003 - SouthEast Mississippi;;;
|
||||||
|
FCS00330;TeXaS-I35;FCS003 - TeXaS-I35;;;
|
||||||
|
FCS00333;Carolina Link;FCS003 - Carolina Link;;;
|
||||||
|
FCS00334;TEXAS - NEXUS;FCS003 - TEXAS - NEXUS;;;
|
||||||
|
FCS00335;Ohio NET;FCS003 - Ohio NET;;;
|
||||||
|
FCS00346;SAT-DRC;FCS003 - SAT-DRC;;;
|
||||||
|
FCS00350;LEO-ARC;FCS003 - LEO-ARC;;;
|
||||||
|
FCS00355;WINSCONSIN LINK;FCS003 - WINSCONSIN LINK;;;
|
||||||
|
FCS00358;Alabama Link;FCS003 - Alabama Link;;;
|
||||||
|
FCS00369;Midwest Hub;FCS003 - Midwest Hub;;;
|
||||||
|
FCS00370;SoCal Link Network;FCS003 - SoCal Link Network;;;
|
||||||
|
FCS00371;SoCal Link Society Café;FCS003 - SoCal Link Society Café;;;
|
||||||
|
FCS00372;ND6C-OpenSPOT Network;FCS003 - ND6C-OpenSPOT Network;;;
|
||||||
|
FCS00373;PINOYHAMS;FCS003 - PINOYHAMS;;;
|
||||||
|
FCS00376;Montivilliers C4FM / F4ETA;FCS003 - Montivilliers C4FM / F4ETA;;;
|
||||||
|
FCS00377;WXCTAC;FCS003 - WXCTAC;;;
|
||||||
|
FCS00385;Haïti System Fusion - HH2MJF;FCS003 - Haïti System Fusion - HH2MJF;;;
|
||||||
|
FCS00390;America Link Wires-X;FCS003 - America Link Wires-X;;;
|
||||||
|
FCS00397;DV4Home Test ROOM;FCS003 - DV4Home Test ROOM;;;
|
||||||
|
FCS00398;DV4mini Test ROOM;FCS003 - DV4mini Test ROOM;;;
|
||||||
|
FCS00399;ECHO;FCS003 - ECHO;;;
|
||||||
|
FCS00400;La-Espanola;FCS004 - La-Espanola;;;
|
||||||
|
FCS00401;EA-DISTRITO-1;FCS004 - EA-DISTRITO-1;;;
|
||||||
|
FCS00402;EA-DISTRITO-2;FCS004 - EA-DISTRITO-2;;;
|
||||||
|
FCS00403;EA-DISTRITO-3;FCS004 - EA-DISTRITO-3;;;
|
||||||
|
FCS00404;EA-DISTRITO-4;FCS004 - EA-DISTRITO-4;;;
|
||||||
|
FCS00405;EA-DISTRITO-5;FCS004 - EA-DISTRITO-5;;;
|
||||||
|
FCS00406;EA-DISTRITO-6;FCS004 - EA-DISTRITO-6;;;
|
||||||
|
FCS00407;EA-DISTRITO-7;FCS004 - EA-DISTRITO-7;;;
|
||||||
|
FCS00408;EA-DISTRITO-8;FCS004 - EA-DISTRITO-8;;;
|
||||||
|
FCS00409;EA-DISTRITO-9;FCS004 - EA-DISTRITO-9;;;
|
||||||
|
FCS00410;Republica Dominicana;FCS004 - Republica Dominicana;;;
|
||||||
|
FCS00411;DMR-TG314233-WiresX;FCS004 - DMR-TG314233-WiresX;;;
|
||||||
|
FCS00412;DVMEGA-WiresX-UK;FCS004 - DVMEGA-WiresX-UK;;;
|
||||||
|
FCS00413;HP-Panama-HUB;FCS004 - HP-Panama-HUB;;;
|
||||||
|
FCS00414;Guatemala;FCS004 - Guatemala;;;
|
||||||
|
FCS00415;Great-Britain;FCS004 - Great-Britain;;;
|
||||||
|
FCS00416;Miami-Latino;FCS004 - Miami-Latino;;;
|
||||||
|
FCS00417;Southern-Germany;FCS004 - Southern-Germany;;;
|
||||||
|
FCS00418;DCS018-Test;FCS004 - DCS018-Test;;;
|
||||||
|
FCS00419;Middle-Germany;FCS004 - Middle-Germany;;;
|
||||||
|
FCS00420;CQ-UK-WiresX-Room;FCS004 - CQ-UK-WiresX-Room;;;
|
||||||
|
FCS00421;Campania;FCS004 - Campania;;;
|
||||||
|
FCS00422;America-Ragchew-WiresX;FCS004 - America-Ragchew-WiresX;;;
|
||||||
|
FCS00423;Hertfordshire-RAYNET;FCS004 - Hertfordshire-RAYNET;;;
|
||||||
|
FCS00424;Fusion-Latina-WiresX-41067;FCS004 - Fusion-Latina-WiresX-41067;;;
|
||||||
|
FCS00425;Scotland;FCS004 - Scotland;;;
|
||||||
|
FCS00426;Oost-Nederland-Room;FCS004 - Oost-Nederland-Room;;;
|
||||||
|
FCS00427;Scout&Guide-JOTA;FCS004 - Scout&Guide-JOTA;;;
|
||||||
|
FCS00428;NWFG;FCS004 - NWFG;;;
|
||||||
|
FCS00429;D.A.R.C-USA;FCS004 - D.A.R.C-USA;;;
|
||||||
|
FCS00430;Irish-Scottish-Link;FCS004 - Irish-Scottish-Link;;;
|
||||||
|
FCS00431;UKHUB;FCS004 - UKHUB;;;
|
||||||
|
FCS00432;LincsLink;FCS004 - LincsLink;;;
|
||||||
|
FCS00433;Stockport-Room;FCS004 - Stockport-Room;;;
|
||||||
|
FCS00434;N8UKF-Repeater-Group;FCS004 - N8UKF-Repeater-Group;;;
|
||||||
|
FCS00435;WW-DX-Link-System;FCS004 - WW-DX-Link-System;;;
|
||||||
|
FCS00436;Essex-UK;FCS004 - Essex-UK;;;
|
||||||
|
FCS00437;Palmac;FCS004 - Palmac;;;
|
||||||
|
FCS00438;CQ-South-Wales;FCS004 - CQ-South-Wales;;;
|
||||||
|
FCS00439;Indiana-Link-SO;FCS004 - Indiana-Link-SO;;;
|
||||||
|
FCS00440;USA;FCS004 - USA;;;
|
||||||
|
FCS00441;Sevilla-TG21441;FCS004 - Sevilla-TG21441;;;
|
||||||
|
FCS00442;Eglisau-Amateur-Radio-Group;FCS004 - Eglisau-Amateur-Radio-Group;;;
|
||||||
|
FCS00443;Greenwich-Link-London;FCS004 - Greenwich-Link-London;;;
|
||||||
|
FCS00444;DMR-CHIRIQUi-TG7144;FCS004 - DMR-CHIRIQUi-TG7144;;;
|
||||||
|
FCS00445;NORTHSTAR;FCS004 - NORTHSTAR;;;
|
||||||
|
FCS00446;Kuwait-R;FCS004 - Kuwait-R;;;
|
||||||
|
FCS00447;Digital-Radio-Group-NZ;FCS004 - Digital-Radio-Group-NZ;;;
|
||||||
|
FCS00448;New-Zealand;FCS004 - New-Zealand;;;
|
||||||
|
FCS00449;MI5DAW;FCS004 - MI5DAW;;;
|
||||||
|
FCS00450;LEO-ARC;FCS004 - LEO-ARC;;;
|
||||||
|
FCS00451;RFIT;FCS004 - RFIT;;;
|
||||||
|
FCS00452;Seccion-Local-URE-Caceres;FCS004 - Seccion-Local-URE-Caceres;;;
|
||||||
|
FCS00453;Alaska-Last-Frontier;FCS004 - Alaska-Last-Frontier;;;
|
||||||
|
FCS00454;QSO-America;FCS004 - QSO-America;;;
|
||||||
|
FCS00455;Oldham-Radio-Club-Fusion-Group;FCS004 - Oldham-Radio-Club-Fusion-Group;;;
|
||||||
|
FCS00456;Nashville-HUB;FCS004 - Nashville-HUB;;;
|
||||||
|
FCS00457;Kapihan;FCS004 - Kapihan;;;
|
||||||
|
FCS00458;Catalina-Amateur-Repeater-Ass;FCS004 - Catalina-Amateur-Repeater-Ass;;;
|
||||||
|
FCS00459;Rhode-Island-Digital-Link;FCS004 - Rhode-Island-Digital-Link;;;
|
||||||
|
FCS00460;United-Kingdom-NET-WiresX;FCS004 - United-Kingdom-NET-WiresX;;;
|
||||||
|
FCS00461;21461BM-XLX051F-DSTAR-10302-NXDN-YSF-EA-SPAIN;FCS004 - 21461BM-XLX051F-DSTAR-10302-NXDN-YSF-EA-SPAIN;;;
|
||||||
|
FCS00462;Mabuhay-Canada-Link;FCS004 - Mabuhay-Canada-Link;;;
|
||||||
|
FCS00463;Uruguay-Link;FCS004 - Uruguay-Link;;;
|
||||||
|
FCS00464;WiresX 27464;FCS004 - WiresX 27464;;;
|
||||||
|
FCS00465;ADER;FCS004 - ADER;;;
|
||||||
|
FCS00466;nn;FCS004 - nn;;;
|
||||||
|
FCS00467;Minnesota-Nice;FCS004 - Minnesota-Nice;;;
|
||||||
|
FCS00468;GoldRunCa-Fusion-Group;FCS004 - GoldRunCa-Fusion-Group;;;
|
||||||
|
FCS00469;SE-Mississippi;FCS004 - SE-Mississippi;;;
|
||||||
|
FCS00470;DMR+-4370-Test;FCS004 - DMR+-4370-Test;;;
|
||||||
|
FCS00471;nn;FCS004 - nn;;;
|
||||||
|
FCS00472;nn;FCS004 - nn;;;
|
||||||
|
FCS00473;SOTA;FCS004 - SOTA;;;
|
||||||
|
FCS00474;DMR+-4374-Test;FCS004 - DMR+-4374-Test;;;
|
||||||
|
FCS00475;21369-KJ4VO-WORK-RM;FCS004 - 21369-KJ4VO-WORK-RM;;;
|
||||||
|
FCS00476;nn;FCS004 - nn;;;
|
||||||
|
FCS00477;HUBNet;FCS004 - HUBNet;;;
|
||||||
|
FCS00478;nn;FCS004 - nn;;;
|
||||||
|
FCS00479;CQ-California-Reflector;FCS004 - CQ-California-Reflector;;;
|
||||||
|
FCS00480;XLX925F;FCS004 - XLX925F;;;
|
||||||
|
FCS00481;nn;FCS004 - nn;;;
|
||||||
|
FCS00482;Netherlands;FCS004 - Netherlands;;;
|
||||||
|
FCS00483;CW-Ops;FCS004 - CW-Ops;;;
|
||||||
|
FCS00484;OMISS;FCS004 - OMISS;;;
|
||||||
|
FCS00485;XLX925E;FCS004 - XLX925E;;;
|
||||||
|
FCS00486;Argentina-Link;FCS004 - Argentina-Link;;;
|
||||||
|
FCS00487;URE-Salamanca;FCS004 - URE-Salamanca;;;
|
||||||
|
FCS00488;Philippine-Link;FCS004 - Philippine-Link;;;
|
||||||
|
FCS00489;Pinoy-Tambayan;FCS004 - Pinoy-Tambayan;;;
|
||||||
|
FCS00490;JOTA-SPAIN-2018;FCS004 - JOTA-SPAIN-2018;;;
|
||||||
|
FCS00491;SierraNorCal;FCS004 - SierraNorCal;;;
|
||||||
|
FCS00492;nn;FCS004 - nn;;;
|
||||||
|
FCS00493;nn;FCS004 - nn;;;
|
||||||
|
FCS00494;Almeria;FCS004 - Almeria;;;
|
||||||
|
FCS00495;Entrelaces-Latinos;FCS004 - Entrelaces-Latinos;;;
|
||||||
|
FCS00496;RC-Veleta;FCS004 - RC-Veleta;;;
|
||||||
|
FCS00497;APRS-Room;FCS004 - APRS-Room;;;
|
||||||
|
FCS00498;Hotspot-Test;FCS004 - Hotspot-Test;;;
|
||||||
|
FCS00499;ECHO;FCS004 - ECHO;;;
|
||||||
|
FCS00500;nn;FCS005 - nn;;;
|
||||||
|
FCS00501;nn;FCS005 - nn;;;
|
||||||
|
FCS00502;nn;FCS005 - nn;;;
|
||||||
|
FCS00503;nn;FCS005 - nn;;;
|
||||||
|
FCS00504;nn;FCS005 - nn;;;
|
||||||
|
FCS00505;nn;FCS005 - nn;;;
|
||||||
|
FCS00506;nn;FCS005 - nn;;;
|
||||||
|
FCS00507;nn;FCS005 - nn;;;
|
||||||
|
FCS00508;nn;FCS005 - nn;;;
|
||||||
|
FCS00509;nn;FCS005 - nn;;;
|
||||||
|
FCS00510;nn;FCS005 - nn;;;
|
||||||
|
FCS00511;nn;FCS005 - nn;;;
|
||||||
|
FCS00512;nn;FCS005 - nn;;;
|
||||||
|
FCS00513;nn;FCS005 - nn;;;
|
||||||
|
FCS00514;nn;FCS005 - nn;;;
|
||||||
|
FCS00515;DL-MultiNet-Bridge;FCS005 - DL-MultiNet-Bridge;;;
|
||||||
|
FCS00516;nn;FCS005 - nn;;;
|
||||||
|
FCS00517;nn;FCS005 - nn;;;
|
||||||
|
FCS00518;nn;FCS005 - nn;;;
|
||||||
|
FCS00519;nn;FCS005 - nn;;;
|
||||||
|
FCS00520;nn;FCS005 - nn;;;
|
||||||
|
FCS00521;nn;FCS005 - nn;;;
|
||||||
|
FCS00522;nn;FCS005 - nn;;;
|
||||||
|
FCS00523;nn;FCS005 - nn;;;
|
||||||
|
FCS00524;nn;FCS005 - nn;;;
|
||||||
|
FCS00525;nn;FCS005 - nn;;;
|
||||||
|
FCS00526;nn;FCS005 - nn;;;
|
||||||
|
FCS00527;nn;FCS005 - nn;;;
|
||||||
|
FCS00528;nn;FCS005 - nn;;;
|
||||||
|
FCS00529;nn;FCS005 - nn;;;
|
||||||
|
FCS00530;nn;FCS005 - nn;;;
|
||||||
|
FCS00531;nn;FCS005 - nn;;;
|
||||||
|
FCS00532;nn;FCS005 - nn;;;
|
||||||
|
FCS00533;nn;FCS005 - nn;;;
|
||||||
|
FCS00534;nn;FCS005 - nn;;;
|
||||||
|
FCS00535;nn;FCS005 - nn;;;
|
||||||
|
FCS00536;nn;FCS005 - nn;;;
|
||||||
|
FCS00537;nn;FCS005 - nn;;;
|
||||||
|
FCS00538;Niedersachsen;FCS005 - Niedersachsen;;;
|
||||||
|
FCS00539;nn;FCS005 - nn;;;
|
||||||
|
FCS00540;nn;FCS005 - nn;;;
|
||||||
|
FCS00541;nn;FCS005 - nn;;;
|
||||||
|
FCS00542;nn;FCS005 - nn;;;
|
||||||
|
FCS00543;nn;FCS005 - nn;;;
|
||||||
|
FCS00544;Pacific-Intertie-Net;FCS005 - Pacific-Intertie-Net;;;
|
||||||
|
FCS00545;nn;FCS005 - nn;;;
|
||||||
|
FCS00546;nn;FCS005 - nn;;;
|
||||||
|
FCS00547;nn;FCS005 - nn;;;
|
||||||
|
FCS00548;nn;FCS005 - nn;;;
|
||||||
|
FCS00549;nn;FCS005 - nn;;;
|
||||||
|
FCS00550;nn;FCS005 - nn;;;
|
||||||
|
FCS00551;nn;FCS005 - nn;;;
|
||||||
|
FCS00552;nn;FCS005 - nn;;;
|
||||||
|
FCS00553;nn;FCS005 - nn;;;
|
||||||
|
FCS00554;nn;FCS005 - nn;;;
|
||||||
|
FCS00555;nn;FCS005 - nn;;;
|
||||||
|
FCS00556;nn;FCS005 - nn;;;
|
||||||
|
FCS00557;nn;FCS005 - nn;;;
|
||||||
|
FCS00558;nn;FCS005 - nn;;;
|
||||||
|
FCS00559;nn;FCS005 - nn;;;
|
||||||
|
FCS00560;nn;FCS005 - nn;;;
|
||||||
|
FCS00561;nn;FCS005 - nn;;;
|
||||||
|
FCS00562;nn;FCS005 - nn;;;
|
||||||
|
FCS00563;nn;FCS005 - nn;;;
|
||||||
|
FCS00564;nn;FCS005 - nn;;;
|
||||||
|
FCS00565;nn;FCS005 - nn;;;
|
||||||
|
FCS00566;nn;FCS005 - nn;;;
|
||||||
|
FCS00567;nn;FCS005 - nn;;;
|
||||||
|
FCS00568;nn;FCS005 - nn;;;
|
||||||
|
FCS00569;nn;FCS005 - nn;;;
|
||||||
|
FCS00570;nn;FCS005 - nn;;;
|
||||||
|
FCS00571;nn;FCS005 - nn;;;
|
||||||
|
FCS00572;nn;FCS005 - nn;;;
|
||||||
|
FCS00573;nn;FCS005 - nn;;;
|
||||||
|
FCS00574;nn;FCS005 - nn;;;
|
||||||
|
FCS00575;nn;FCS005 - nn;;;
|
||||||
|
FCS00576;nn;FCS005 - nn;;;
|
||||||
|
FCS00577;nn;FCS005 - nn;;;
|
||||||
|
FCS00578;nn;FCS005 - nn;;;
|
||||||
|
FCS00579;nn;FCS005 - nn;;;
|
||||||
|
FCS00580;nn;FCS005 - nn;;;
|
||||||
|
FCS00581;nn;FCS005 - nn;;;
|
||||||
|
FCS00582;nn;FCS005 - nn;;;
|
||||||
|
FCS00583;nn;FCS005 - nn;;;
|
||||||
|
FCS00584;nn;FCS005 - nn;;;
|
||||||
|
FCS00585;nn;FCS005 - nn;;;
|
||||||
|
FCS00586;nn;FCS005 - nn;;;
|
||||||
|
FCS00587;nn;FCS005 - nn;;;
|
||||||
|
FCS00588;nn;FCS005 - nn;;;
|
||||||
|
FCS00589;nn;FCS005 - nn;;;
|
||||||
|
FCS00590;DMRplus-Chat;FCS005 - DMRplus-Chat;;;
|
||||||
|
FCS00591;nn;FCS005 - nn;;;
|
||||||
|
FCS00592;nn;FCS005 - nn;;;
|
||||||
|
FCS00593;nn;FCS005 - nn;;;
|
||||||
|
FCS00594;nn;FCS005 - nn;;;
|
||||||
|
FCS00595;nn;FCS005 - nn;;;
|
||||||
|
FCS00596;nn;FCS005 - nn;;;
|
||||||
|
FCS00597;nn;FCS005 - nn;;;
|
||||||
|
FCS00598;nn;FCS005 - nn;;;
|
||||||
|
FCS00599;ECHO;FCS005 - ECHO;;;
|
||||||
|
FCS22200;nn;FCS222 - nn;;;
|
||||||
|
FCS22201;nn;FCS222 - nn;;;
|
||||||
|
FCS22202;nn;FCS222 - nn;;;
|
||||||
|
FCS22203;nn;FCS222 - nn;;;
|
||||||
|
FCS22204;nn;FCS222 - nn;;;
|
||||||
|
FCS22205;nn;FCS222 - nn;;;
|
||||||
|
FCS22206;nn;FCS222 - nn;;;
|
||||||
|
FCS22207;nn;FCS222 - nn;;;
|
||||||
|
FCS22208;nn;FCS222 - nn;;;
|
||||||
|
FCS22209;nn;FCS222 - nn;;;
|
||||||
|
FCS22210;nn;FCS222 - nn;;;
|
||||||
|
FCS22211;nn;FCS222 - nn;;;
|
||||||
|
FCS22212;nn;FCS222 - nn;;;
|
||||||
|
FCS22213;nn;FCS222 - nn;;;
|
||||||
|
FCS22214;nn;FCS222 - nn;;;
|
||||||
|
FCS22215;nn;FCS222 - nn;;;
|
||||||
|
FCS22216;nn;FCS222 - nn;;;
|
||||||
|
FCS22217;Netherlands;FCS222 - Netherlands;;;
|
||||||
|
FCS22218;nn;FCS222 - nn;;;
|
||||||
|
FCS22219;nn;FCS222 - nn;;;
|
||||||
|
FCS22220;D-A-CH;FCS222 - D-A-CH;;;
|
||||||
|
FCS22221;nn;FCS222 - nn;;;
|
||||||
|
FCS22222;Italy;FCS222 - Italy;;;
|
||||||
|
FCS22223;nn;FCS222 - nn;;;
|
||||||
|
FCS22224;Spain;FCS222 - Spain;;;
|
||||||
|
FCS22225;nn;FCS222 - nn;;;
|
||||||
|
FCS22226;Poland;FCS222 - Poland;;;
|
||||||
|
FCS22227;nn;FCS222 - nn;;;
|
||||||
|
FCS22228;Switzerland;FCS222 - Switzerland;;;
|
||||||
|
FCS22229;nn;FCS222 - nn;;;
|
||||||
|
FCS22230;nn;FCS222 - nn;;;
|
||||||
|
FCS22231;nn;FCS222 - nn;;;
|
||||||
|
FCS22232;Austria;FCS222 - Austria;;;
|
||||||
|
FCS22233;nn;FCS222 - nn;;;
|
||||||
|
FCS22234;nn;FCS222 - nn;;;
|
||||||
|
FCS22235;nn;FCS222 - nn;;;
|
||||||
|
FCS22236;nn;FCS222 - nn;;;
|
||||||
|
FCS22237;nn;FCS222 - nn;;;
|
||||||
|
FCS22238;nn;FCS222 - nn;;;
|
||||||
|
FCS22239;nn;FCS222 - nn;;;
|
||||||
|
FCS22240;nn;FCS222 - nn;;;
|
||||||
|
FCS22241;nn;FCS222 - nn;;;
|
||||||
|
FCS22242;nn;FCS222 - nn;;;
|
||||||
|
FCS22243;nn;FCS222 - nn;;;
|
||||||
|
FCS22244;nn;FCS222 - nn;;;
|
||||||
|
FCS22245;nn;FCS222 - nn;;;
|
||||||
|
FCS22246;nn;FCS222 - nn;;;
|
||||||
|
FCS22247;nn;FCS222 - nn;;;
|
||||||
|
FCS22248;nn;FCS222 - nn;;;
|
||||||
|
FCS22249;nn;FCS222 - nn;;;
|
||||||
|
FCS22250;nn;FCS222 - nn;;;
|
||||||
|
FCS22251;nn;FCS222 - nn;;;
|
||||||
|
FCS22252;nn;FCS222 - nn;;;
|
||||||
|
FCS22253;nn;FCS222 - nn;;;
|
||||||
|
FCS22254;nn;FCS222 - nn;;;
|
||||||
|
FCS22255;nn;FCS222 - nn;;;
|
||||||
|
FCS22256;nn;FCS222 - nn;;;
|
||||||
|
FCS22257;nn;FCS222 - nn;;;
|
||||||
|
FCS22258;nn;FCS222 - nn;;;
|
||||||
|
FCS22259;nn;FCS222 - nn;;;
|
||||||
|
FCS22260;nn;FCS222 - nn;;;
|
||||||
|
FCS22261;nn;FCS222 - nn;;;
|
||||||
|
FCS22262;Germany;FCS222 - Germany;;;
|
||||||
|
FCS22263;nn;FCS222 - nn;;;
|
||||||
|
FCS22264;nn;FCS222 - nn;;;
|
||||||
|
FCS22265;nn;FCS222 - nn;;;
|
||||||
|
FCS22266;nn;FCS222 - nn;;;
|
||||||
|
FCS22267;nn;FCS222 - nn;;;
|
||||||
|
FCS22268;nn;FCS222 - nn;;;
|
||||||
|
FCS22269;nn;FCS222 - nn;;;
|
||||||
|
FCS22270;nn;FCS222 - nn;;;
|
||||||
|
FCS22271;nn;FCS222 - nn;;;
|
||||||
|
FCS22272;nn;FCS222 - nn;;;
|
||||||
|
FCS22273;nn;FCS222 - nn;;;
|
||||||
|
FCS22274;nn;FCS222 - nn;;;
|
||||||
|
FCS22275;nn;FCS222 - nn;;;
|
||||||
|
FCS22276;nn;FCS222 - nn;;;
|
||||||
|
FCS22277;nn;FCS222 - nn;;;
|
||||||
|
FCS22278;nn;FCS222 - nn;;;
|
||||||
|
FCS22279;nn;FCS222 - nn;;;
|
||||||
|
FCS22280;nn;FCS222 - nn;;;
|
||||||
|
FCS22281;nn;FCS222 - nn;;;
|
||||||
|
FCS22282;nn;FCS222 - nn;;;
|
||||||
|
FCS22283;nn;FCS222 - nn;;;
|
||||||
|
FCS22284;nn;FCS222 - nn;;;
|
||||||
|
FCS22285;nn;FCS222 - nn;;;
|
||||||
|
FCS22286;nn;FCS222 - nn;;;
|
||||||
|
FCS22287;nn;FCS222 - nn;;;
|
||||||
|
FCS22288;nn;FCS222 - nn;;;
|
||||||
|
FCS22289;nn;FCS222 - nn;;;
|
||||||
|
FCS22290;nn;FCS222 - nn;;;
|
||||||
|
FCS22291;nn;FCS222 - nn;;;
|
||||||
|
FCS22292;nn;FCS222 - nn;;;
|
||||||
|
FCS22293;nn;FCS222 - nn;;;
|
||||||
|
FCS22294;nn;FCS222 - nn;;;
|
||||||
|
FCS22295;nn;FCS222 - nn;;;
|
||||||
|
FCS22296;nn;FCS222 - nn;;;
|
||||||
|
FCS22297;nn;FCS222 - nn;;;
|
||||||
|
FCS22298;nn;FCS222 - nn;;;
|
||||||
|
FCS22299;ECHO;FCS222 - ECHO;;;
|
||||||
|
FCS22400;nn;FCS224 - nn;;;
|
||||||
|
FCS22401;nn;FCS224 - nn;;;
|
||||||
|
FCS22402;nn;FCS224 - nn;;;
|
||||||
|
FCS22403;nn;FCS224 - nn;;;
|
||||||
|
FCS22404;nn;FCS224 - nn;;;
|
||||||
|
FCS22405;nn;FCS224 - nn;;;
|
||||||
|
FCS22406;nn;FCS224 - nn;;;
|
||||||
|
FCS22407;nn;FCS224 - nn;;;
|
||||||
|
FCS22408;nn;FCS224 - nn;;;
|
||||||
|
FCS22409;nn;FCS224 - nn;;;
|
||||||
|
FCS22410;nn;FCS224 - nn;;;
|
||||||
|
FCS22411;nn;FCS224 - nn;;;
|
||||||
|
FCS22412;nn;FCS224 - nn;;;
|
||||||
|
FCS22413;nn;FCS224 - nn;;;
|
||||||
|
FCS22414;2X;FCS224 - 2X;;;
|
||||||
|
FCS22415;nn;FCS224 - nn;;;
|
||||||
|
FCS22416;nn;FCS224 - nn;;;
|
||||||
|
FCS22417;Netherlands;FCS224 - Netherlands;;;
|
||||||
|
FCS22418;nn;FCS224 - nn;;;
|
||||||
|
FCS22419;nn;FCS224 - nn;;;
|
||||||
|
FCS22420;D-A-CH;FCS224 - D-A-CH;;;
|
||||||
|
FCS22421;nn;FCS224 - nn;;;
|
||||||
|
FCS22422;Italy;FCS224 - Italy;;;
|
||||||
|
FCS22423;nn;FCS224 - nn;;;
|
||||||
|
FCS22424;Spain;FCS224 - Spain;;;
|
||||||
|
FCS22425;nn;FCS224 - nn;;;
|
||||||
|
FCS22426;Poland;FCS224 - Poland;;;
|
||||||
|
FCS22427;nn;FCS224 - nn;;;
|
||||||
|
FCS22428;Switzerland;FCS224 - Switzerland;;;
|
||||||
|
FCS22429;nn;FCS224 - nn;;;
|
||||||
|
FCS22430;nn;FCS224 - nn;;;
|
||||||
|
FCS22431;nn;FCS224 - nn;;;
|
||||||
|
FCS22432;Austria;FCS224 - Austria;;;
|
||||||
|
FCS22433;nn;FCS224 - nn;;;
|
||||||
|
FCS22434;nn;FCS224 - nn;;;
|
||||||
|
FCS22435;nn;FCS224 - nn;;;
|
||||||
|
FCS22436;nn;FCS224 - nn;;;
|
||||||
|
FCS22437;nn;FCS224 - nn;;;
|
||||||
|
FCS22438;nn;FCS224 - nn;;;
|
||||||
|
FCS22439;nn;FCS224 - nn;;;
|
||||||
|
FCS22440;nn;FCS224 - nn;;;
|
||||||
|
FCS22441;nn;FCS224 - nn;;;
|
||||||
|
FCS22442;nn;FCS224 - nn;;;
|
||||||
|
FCS22443;nn;FCS224 - nn;;;
|
||||||
|
FCS22444;nn;FCS224 - nn;;;
|
||||||
|
FCS22445;nn;FCS224 - nn;;;
|
||||||
|
FCS22446;nn;FCS224 - nn;;;
|
||||||
|
FCS22447;nn;FCS224 - nn;;;
|
||||||
|
FCS22448;nn;FCS224 - nn;;;
|
||||||
|
FCS22449;nn;FCS224 - nn;;;
|
||||||
|
FCS22450;nn;FCS224 - nn;;;
|
||||||
|
FCS22451;nn;FCS224 - nn;;;
|
||||||
|
FCS22452;nn;FCS224 - nn;;;
|
||||||
|
FCS22453;nn;FCS224 - nn;;;
|
||||||
|
FCS22454;nn;FCS224 - nn;;;
|
||||||
|
FCS22455;nn;FCS224 - nn;;;
|
||||||
|
FCS22456;nn;FCS224 - nn;;;
|
||||||
|
FCS22457;nn;FCS224 - nn;;;
|
||||||
|
FCS22458;nn;FCS224 - nn;;;
|
||||||
|
FCS22459;nn;FCS224 - nn;;;
|
||||||
|
FCS22460;nn;FCS224 - nn;;;
|
||||||
|
FCS22461;nn;FCS224 - nn;;;
|
||||||
|
FCS22462;Germany;FCS224 - Germany;;;
|
||||||
|
FCS22463;nn;FCS224 - nn;;;
|
||||||
|
FCS22464;nn;FCS224 - nn;;;
|
||||||
|
FCS22465;nn;FCS224 - nn;;;
|
||||||
|
FCS22466;nn;FCS224 - nn;;;
|
||||||
|
FCS22467;nn;FCS224 - nn;;;
|
||||||
|
FCS22468;nn;FCS224 - nn;;;
|
||||||
|
FCS22469;nn;FCS224 - nn;;;
|
||||||
|
FCS22470;nn;FCS224 - nn;;;
|
||||||
|
FCS22471;nn;FCS224 - nn;;;
|
||||||
|
FCS22472;nn;FCS224 - nn;;;
|
||||||
|
FCS22473;nn;FCS224 - nn;;;
|
||||||
|
FCS22474;nn;FCS224 - nn;;;
|
||||||
|
FCS22475;nn;FCS224 - nn;;;
|
||||||
|
FCS22476;nn;FCS224 - nn;;;
|
||||||
|
FCS22477;nn;FCS224 - nn;;;
|
||||||
|
FCS22478;2X;FCS224 - 2X;;;
|
||||||
|
FCS22479;nn;FCS224 - nn;;;
|
||||||
|
FCS22480;TST;FCS224 - TST;;;
|
||||||
|
FCS22481;nn;FCS224 - nn;;;
|
||||||
|
FCS22482;nn;FCS224 - nn;;;
|
||||||
|
FCS22483;nn;FCS224 - nn;;;
|
||||||
|
FCS22484;nn;FCS224 - nn;;;
|
||||||
|
FCS22485;nn;FCS224 - nn;;;
|
||||||
|
FCS22486;nn;FCS224 - nn;;;
|
||||||
|
FCS22487;nn;FCS224 - nn;;;
|
||||||
|
FCS22488;nn;FCS224 - nn;;;
|
||||||
|
FCS22489;nn;FCS224 - nn;;;
|
||||||
|
FCS22490;nn;FCS224 - nn;;;
|
||||||
|
FCS22491;nn;FCS224 - nn;;;
|
||||||
|
FCS22492;nn;FCS224 - nn;;;
|
||||||
|
FCS22493;nn;FCS224 - nn;;;
|
||||||
|
FCS22494;nn;FCS224 - nn;;;
|
||||||
|
FCS22495;nn;FCS224 - nn;;;
|
||||||
|
FCS22496;nn;FCS224 - nn;;;
|
||||||
|
FCS22497;nn;FCS224 - nn;;;
|
||||||
|
FCS22498;nn;FCS224 - nn;;;
|
||||||
|
FCS22499;ECHO;FCS224 - ECHO;;;
|
||||||
|
FCS23200;nn;FCS232 - nn;;;
|
||||||
|
FCS23201;2X;FCS232 - 2X;;;
|
||||||
|
FCS23202;nn;FCS232 - nn;;;
|
||||||
|
FCS23203;nn;FCS232 - nn;;;
|
||||||
|
FCS23204;2X;FCS232 - 2X;;;
|
||||||
|
FCS23205;2X;FCS232 - 2X;;;
|
||||||
|
FCS23206;2X;FCS232 - 2X;;;
|
||||||
|
FCS23207;2X;FCS232 - 2X;;;
|
||||||
|
FCS23208;2X;FCS232 - 2X;;;
|
||||||
|
FCS23209;nn;FCS232 - nn;;;
|
||||||
|
FCS23210;2X;FCS232 - 2X;;;
|
||||||
|
FCS23211;2X;FCS232 - 2X;;;
|
||||||
|
FCS23212;2X;FCS232 - 2X;;;
|
||||||
|
FCS23213;2X;FCS232 - 2X;;;
|
||||||
|
FCS23214;nn;FCS232 - nn;;;
|
||||||
|
FCS23215;nn;FCS232 - nn;;;
|
||||||
|
FCS23216;nn;FCS232 - nn;;;
|
||||||
|
FCS23217;Netherlands;FCS232 - Netherlands;;;
|
||||||
|
FCS23218;nn;FCS232 - nn;;;
|
||||||
|
FCS23219;nn;FCS232 - nn;;;
|
||||||
|
FCS23220;D-A-CH;FCS232 - D-A-CH;;;
|
||||||
|
FCS23221;nn;FCS232 - nn;;;
|
||||||
|
FCS23222;Italy;FCS232 - Italy;;;
|
||||||
|
FCS23223;nn;FCS232 - nn;;;
|
||||||
|
FCS23224;nn;FCS232 - nn;;;
|
||||||
|
FCS23225;nn;FCS232 - nn;;;
|
||||||
|
FCS23226;Poland;FCS232 - Poland;;;
|
||||||
|
FCS23227;nn;FCS232 - nn;;;
|
||||||
|
FCS23228;Switzerland;FCS232 - Switzerland;;;
|
||||||
|
FCS23229;nn;FCS232 - nn;;;
|
||||||
|
FCS23230;nn;FCS232 - nn;;;
|
||||||
|
FCS23231;nn;FCS232 - nn;;;
|
||||||
|
FCS23232;Austria;FCS232 - Austria;;;
|
||||||
|
FCS23233;nn;FCS232 - nn;;;
|
||||||
|
FCS23234;nn;FCS232 - nn;;;
|
||||||
|
FCS23235;nn;FCS232 - nn;;;
|
||||||
|
FCS23236;nn;FCS232 - nn;;;
|
||||||
|
FCS23237;nn;FCS232 - nn;;;
|
||||||
|
FCS23238;nn;FCS232 - nn;;;
|
||||||
|
FCS23239;nn;FCS232 - nn;;;
|
||||||
|
FCS23240;nn;FCS232 - nn;;;
|
||||||
|
FCS23241;nn;FCS232 - nn;;;
|
||||||
|
FCS23242;nn;FCS232 - nn;;;
|
||||||
|
FCS23243;nn;FCS232 - nn;;;
|
||||||
|
FCS23244;nn;FCS232 - nn;;;
|
||||||
|
FCS23245;nn;FCS232 - nn;;;
|
||||||
|
FCS23246;nn;FCS232 - nn;;;
|
||||||
|
FCS23247;nn;FCS232 - nn;;;
|
||||||
|
FCS23248;nn;FCS232 - nn;;;
|
||||||
|
FCS23249;nn;FCS232 - nn;;;
|
||||||
|
FCS23250;nn;FCS232 - nn;;;
|
||||||
|
FCS23251;nn;FCS232 - nn;;;
|
||||||
|
FCS23252;nn;FCS232 - nn;;;
|
||||||
|
FCS23253;nn;FCS232 - nn;;;
|
||||||
|
FCS23254;nn;FCS232 - nn;;;
|
||||||
|
FCS23255;nn;FCS232 - nn;;;
|
||||||
|
FCS23256;nn;FCS232 - nn;;;
|
||||||
|
FCS23257;nn;FCS232 - nn;;;
|
||||||
|
FCS23258;nn;FCS232 - nn;;;
|
||||||
|
FCS23259;nn;FCS232 - nn;;;
|
||||||
|
FCS23260;nn;FCS232 - nn;;;
|
||||||
|
FCS23261;nn;FCS232 - nn;;;
|
||||||
|
FCS23262;Germany;FCS232 - Germany;;;
|
||||||
|
FCS23263;nn;FCS232 - nn;;;
|
||||||
|
FCS23264;nn;FCS232 - nn;;;
|
||||||
|
FCS23265;nn;FCS232 - nn;;;
|
||||||
|
FCS23266;nn;FCS232 - nn;;;
|
||||||
|
FCS23267;nn;FCS232 - nn;;;
|
||||||
|
FCS23268;nn;FCS232 - nn;;;
|
||||||
|
FCS23269;nn;FCS232 - nn;;;
|
||||||
|
FCS23270;nn;FCS232 - nn;;;
|
||||||
|
FCS23271;2X;FCS232 - 2X;;;
|
||||||
|
FCS23272;nn;FCS232 - nn;;;
|
||||||
|
FCS23273;2X;FCS232 - 2X;;;
|
||||||
|
FCS23274;nn;FCS232 - nn;;;
|
||||||
|
FCS23275;nn;FCS232 - nn;;;
|
||||||
|
FCS23276;2X;FCS232 - 2X;;;
|
||||||
|
FCS23277;2X;FCS232 - 2X;;;
|
||||||
|
FCS23278;nn;FCS232 - nn;;;
|
||||||
|
FCS23279;nn;FCS232 - nn;;;
|
||||||
|
FCS23280;TST;FCS232 - TST;;;
|
||||||
|
FCS23281;OE-TEST;FCS232 - OE-TEST;;;
|
||||||
|
FCS23282;T2;FCS232 - T2;;;
|
||||||
|
FCS23283;T3;FCS232 - T3;;;
|
||||||
|
FCS23284;nn;FCS232 - nn;;;
|
||||||
|
FCS23285;nn;FCS232 - nn;;;
|
||||||
|
FCS23286;nn;FCS232 - nn;;;
|
||||||
|
FCS23287;nn;FCS232 - nn;;;
|
||||||
|
FCS23288;nn;FCS232 - nn;;;
|
||||||
|
FCS23289;nn;FCS232 - nn;;;
|
||||||
|
FCS23290;nn;FCS232 - nn;;;
|
||||||
|
FCS23291;OE-1;FCS232 - OE-1;;;
|
||||||
|
FCS23292;nn;FCS232 - nn;;;
|
||||||
|
FCS23293;OE-3;FCS232 - OE-3;;;
|
||||||
|
FCS23294;nn;FCS232 - nn;;;
|
||||||
|
FCS23295;nn;FCS232 - nn;;;
|
||||||
|
FCS23296;nn;FCS232 - nn;;;
|
||||||
|
FCS23297;nn;FCS232 - nn;;;
|
||||||
|
FCS23298;OE-8;FCS232 - OE-8;;;
|
||||||
|
FCS23299;ECHO;FCS232 - ECHO;;;
|
272
DGIdGateway/GPS.cpp
Normal file
272
DGIdGateway/GPS.cpp
Normal file
|
@ -0,0 +1,272 @@
|
||||||
|
/*
|
||||||
|
* 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 "GPS.h"
|
||||||
|
#include "YSFPayload.h"
|
||||||
|
#include "YSFDefines.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
#include "CRC.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
const unsigned char SHRT_GPS[] = {0x22U, 0x62U};
|
||||||
|
const unsigned char LONG_GPS[] = {0x47U, 0x64U};
|
||||||
|
|
||||||
|
CGPS::CGPS(CAPRSWriter* writer) :
|
||||||
|
m_writer(writer),
|
||||||
|
m_buffer(NULL),
|
||||||
|
m_sent(false)
|
||||||
|
{
|
||||||
|
assert(writer != NULL);
|
||||||
|
|
||||||
|
m_buffer = new unsigned char[300U];
|
||||||
|
}
|
||||||
|
|
||||||
|
CGPS::~CGPS()
|
||||||
|
{
|
||||||
|
delete[] m_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGPS::data(const unsigned char* source, const unsigned char* data, unsigned char fi, unsigned char dt, unsigned char fn, unsigned char ft)
|
||||||
|
{
|
||||||
|
if (m_sent)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fi != YSF_FI_COMMUNICATIONS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CYSFPayload payload;
|
||||||
|
|
||||||
|
if (dt == YSF_DT_VD_MODE1) {
|
||||||
|
if (fn == 0U || fn == 1U || fn == 2U)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool valid = payload.readVDMode1Data(data, m_buffer + (fn - 3U) * 20U);
|
||||||
|
if (!valid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fn == ft) {
|
||||||
|
bool valid = false;
|
||||||
|
|
||||||
|
// Find the end marker
|
||||||
|
for (unsigned int i = (fn - 2U) * 20U; i > 0U; i--) {
|
||||||
|
if (m_buffer[i] == 0x03U) {
|
||||||
|
unsigned char crc = CCRC::addCRC(m_buffer, i + 1U);
|
||||||
|
if (crc == m_buffer[i + 1U])
|
||||||
|
valid = true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid) {
|
||||||
|
if (::memcmp(m_buffer + 1U, SHRT_GPS, 2U) == 0) {
|
||||||
|
CUtils::dump("Short GPS data received", m_buffer, (fn - 2U) * 20U);
|
||||||
|
transmitGPS(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (::memcmp(m_buffer + 1U, LONG_GPS, 2U) == 0) {
|
||||||
|
CUtils::dump("Long GPS data received", m_buffer, (fn - 2U) * 20U);
|
||||||
|
transmitGPS(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_sent = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (dt == YSF_DT_VD_MODE2) {
|
||||||
|
if (fn != 6U && fn != 7U)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool valid = payload.readVDMode2Data(data, m_buffer + (fn - 6U) * 10U);
|
||||||
|
if (!valid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fn == ft) {
|
||||||
|
bool valid = false;
|
||||||
|
|
||||||
|
// Find the end marker
|
||||||
|
for (unsigned int i = (fn - 5U) * 10U; i > 0U; i--) {
|
||||||
|
if (m_buffer[i] == 0x03U) {
|
||||||
|
unsigned char crc = CCRC::addCRC(m_buffer, i + 1U);
|
||||||
|
if (crc == m_buffer[i + 1U])
|
||||||
|
valid = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid) {
|
||||||
|
if (::memcmp(m_buffer + 1U, SHRT_GPS, 2U) == 0) {
|
||||||
|
CUtils::dump("Short GPS data received", m_buffer, (fn - 5U) * 10U);
|
||||||
|
transmitGPS(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (::memcmp(m_buffer + 1U, LONG_GPS, 2U) == 0) {
|
||||||
|
CUtils::dump("Long GPS data received", m_buffer, (fn - 5U) * 10U);
|
||||||
|
transmitGPS(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_sent = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGPS::reset()
|
||||||
|
{
|
||||||
|
m_sent = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGPS::transmitGPS(const unsigned char* source)
|
||||||
|
{
|
||||||
|
assert(m_writer != NULL);
|
||||||
|
|
||||||
|
// We don't know who its from!
|
||||||
|
if (::memcmp(source, " ", YSF_CALLSIGN_LENGTH) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (unsigned int i = 5U; i < 11U; i++) {
|
||||||
|
unsigned char b = m_buffer[i] & 0xF0U;
|
||||||
|
if (b != 0x50U && b != 0x30U)
|
||||||
|
return; // error/unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int tens = m_buffer[5U] & 0x0FU;
|
||||||
|
unsigned int units = m_buffer[6U] & 0x0FU;
|
||||||
|
unsigned int lat_deg = (tens * 10U) + units;
|
||||||
|
if (tens > 9U || units > 9U || lat_deg > 89U)
|
||||||
|
return; // error/unknown
|
||||||
|
|
||||||
|
tens = m_buffer[7U] & 0x0FU;
|
||||||
|
units = m_buffer[8U] & 0x0FU;
|
||||||
|
unsigned int lat_min = (tens * 10U) + units;
|
||||||
|
if (tens > 9U || units > 9U || lat_min > 59U)
|
||||||
|
return; // error/unknown
|
||||||
|
|
||||||
|
tens = m_buffer[9U] & 0x0FU;
|
||||||
|
units = m_buffer[10U] & 0x0FU;
|
||||||
|
unsigned int lat_min_frac = (tens * 10U) + units;
|
||||||
|
if (tens > 9U || units > 10U || lat_min_frac > 99U) // units > 10 ??? .. more buggy Yaesu firmware ?
|
||||||
|
return; // error/unknown
|
||||||
|
|
||||||
|
int lat_dir;
|
||||||
|
unsigned char b = m_buffer[8U] & 0xF0U; // currently a guess
|
||||||
|
if (b == 0x50U)
|
||||||
|
lat_dir = 1; // N
|
||||||
|
else if (b == 0x30U)
|
||||||
|
lat_dir = -1; // S
|
||||||
|
else
|
||||||
|
return; // error/unknown
|
||||||
|
|
||||||
|
unsigned int lon_deg;
|
||||||
|
b = m_buffer[9U] & 0xF0U;
|
||||||
|
if (b == 0x50U) {
|
||||||
|
// lon deg 0 to 9, and 100 to 179
|
||||||
|
b = m_buffer[11U];
|
||||||
|
if (b >= 0x76U && b <= 0x7FU)
|
||||||
|
lon_deg = b - 0x76U; // 0 to 9
|
||||||
|
else if (b >= 0x6CU && b <= 0x75U)
|
||||||
|
lon_deg = 100U + (b - 0x6CU); // 100 to 109
|
||||||
|
else if (b >= 0x26U && b <= 0x6BU)
|
||||||
|
lon_deg = 110U + (b - 0x26U); // 110 to 179
|
||||||
|
else
|
||||||
|
return; // error/unknown
|
||||||
|
} else if (b == 0x30U) {
|
||||||
|
// lon deg 10 to 99
|
||||||
|
b = m_buffer[11U];
|
||||||
|
if (b >= 0x26U && b <= 0x7FU)
|
||||||
|
lon_deg = 10U + (b - 0x26U); // 10 to 99
|
||||||
|
else
|
||||||
|
return; // error/unknown
|
||||||
|
} else {
|
||||||
|
return; // error/unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int lon_min;
|
||||||
|
b = m_buffer[12U];
|
||||||
|
if (b >= 0x58U && b <= 0x61U)
|
||||||
|
lon_min = b - 0x58U; // 0 to 9
|
||||||
|
else if (b >= 0x26U && b <= 0x57U)
|
||||||
|
lon_min = 10U + (b - 0x26U); // 10 to 59
|
||||||
|
else
|
||||||
|
return; // error/unknown
|
||||||
|
|
||||||
|
unsigned int lon_min_frac;
|
||||||
|
b = m_buffer[13U];
|
||||||
|
if (b >= 0x1CU && b <= 0x7FU)
|
||||||
|
lon_min_frac = b - 0x1CU;
|
||||||
|
else
|
||||||
|
return; // error/unknown
|
||||||
|
|
||||||
|
int lon_dir;
|
||||||
|
b = m_buffer[10U] & 0xF0U;
|
||||||
|
if (b == 0x30U)
|
||||||
|
lon_dir = 1; // E
|
||||||
|
else if (b == 0x50U)
|
||||||
|
lon_dir = -1; // W
|
||||||
|
else
|
||||||
|
return; // error/unknown
|
||||||
|
|
||||||
|
unsigned int lat_sec = lat_min_frac * 60U;
|
||||||
|
lat_sec = (lat_sec + (lat_sec % 100U)) / 100U; // with rounding
|
||||||
|
|
||||||
|
unsigned int lon_sec = lon_min_frac * 60U;
|
||||||
|
lon_sec = (lon_sec + (lon_sec % 100U)) / 100U; // with rounding
|
||||||
|
|
||||||
|
// >= 0 is north, < 0 is south
|
||||||
|
float latitude = lat_deg + ((lat_min + ((float)lat_min_frac * 0.01F)) * (1.0F / 60.0F));
|
||||||
|
latitude *= lat_dir;
|
||||||
|
|
||||||
|
// >= 0 is east, < 0 is west
|
||||||
|
float longitude = lon_deg + ((lon_min + ((float)lon_min_frac * 0.01F)) * (1.0F / 60.0F));
|
||||||
|
longitude *= lon_dir;
|
||||||
|
|
||||||
|
char radio[10U];
|
||||||
|
|
||||||
|
switch (m_buffer[4U]) {
|
||||||
|
case 0x24U:
|
||||||
|
::strcpy(radio, "FT-1D");
|
||||||
|
break;
|
||||||
|
case 0x25U:
|
||||||
|
::strcpy(radio, "FTM-400D");
|
||||||
|
break;
|
||||||
|
case 0x26U:
|
||||||
|
::strcpy(radio, "DR-1X");
|
||||||
|
break;
|
||||||
|
case 0x28U:
|
||||||
|
::strcpy(radio, "FT-2D");
|
||||||
|
break;
|
||||||
|
case 0x29U:
|
||||||
|
::strcpy(radio, "FTM-100D");
|
||||||
|
break;
|
||||||
|
case 0x30U:
|
||||||
|
::strcpy(radio, "FT-3D");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
::sprintf(radio, "0x%02X", m_buffer[4U]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogMessage("GPS Position from %10.10s of radio=%s lat=%f long=%f", source, radio, latitude, longitude);
|
||||||
|
|
||||||
|
m_writer->write(source, radio, m_buffer[4U], latitude, longitude);
|
||||||
|
|
||||||
|
m_sent = true;
|
||||||
|
}
|
43
DGIdGateway/GPS.h
Normal file
43
DGIdGateway/GPS.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(GPS_H)
|
||||||
|
#define GPS_H
|
||||||
|
|
||||||
|
#include "APRSWriter.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class CGPS {
|
||||||
|
public:
|
||||||
|
CGPS(CAPRSWriter* writer);
|
||||||
|
~CGPS();
|
||||||
|
|
||||||
|
void data(const unsigned char* source, const unsigned char* data, unsigned char fi, unsigned char dt, unsigned char fn, unsigned char ft);
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
private:
|
||||||
|
CAPRSWriter* m_writer;
|
||||||
|
unsigned char* m_buffer;
|
||||||
|
bool m_sent;
|
||||||
|
|
||||||
|
void transmitGPS(const unsigned char* source);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
1108
DGIdGateway/Golay24128.cpp
Normal file
1108
DGIdGateway/Golay24128.cpp
Normal file
File diff suppressed because it is too large
Load diff
32
DGIdGateway/Golay24128.h
Normal file
32
DGIdGateway/Golay24128.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2010,2016 by Jonathan Naylor G4KLX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef Golay24128_H
|
||||||
|
#define Golay24128_H
|
||||||
|
|
||||||
|
class CGolay24128 {
|
||||||
|
public:
|
||||||
|
static unsigned int encode23127(unsigned int data);
|
||||||
|
static unsigned int encode24128(unsigned int data);
|
||||||
|
|
||||||
|
static unsigned int decode23127(unsigned int code);
|
||||||
|
static unsigned int decode24128(unsigned int code);
|
||||||
|
static unsigned int decode24128(unsigned char* bytes);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
136
DGIdGateway/Log.cpp
Normal file
136
DGIdGateway/Log.cpp
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
36
DGIdGateway/Log.h
Normal file
36
DGIdGateway/Log.h
Normal file
|
@ -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
|
30
DGIdGateway/Makefile
Normal file
30
DGIdGateway/Makefile
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
CC = gcc
|
||||||
|
CXX = g++
|
||||||
|
|
||||||
|
# Use the following CFLAGS and LIBS if you don't want to use gpsd.
|
||||||
|
CFLAGS = -g -O3 -Wall -std=c++0x -pthread
|
||||||
|
LIBS = -lm -lpthread
|
||||||
|
|
||||||
|
# Use the following CFLAGS and LIBS if you do want to use gpsd.
|
||||||
|
#CFLAGS = -g -O3 -Wall -DUSE_GPSD -std=c++0x -pthread
|
||||||
|
#LIBS = -lm -lpthread -lgps
|
||||||
|
|
||||||
|
LDFLAGS = -g
|
||||||
|
|
||||||
|
OBJECTS = APRSWriter.o Conf.o CRC.o DGIdGateway.o DGIdNetwork.o FCSNetwork.o Golay24128.o GPS.o Log.o StopWatch.o Sync.o Thread.o Timer.o \
|
||||||
|
UDPSocket.o Utils.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o YSFReflectors.o
|
||||||
|
|
||||||
|
all: DGIdGateway
|
||||||
|
|
||||||
|
DGIdGateway: $(OBJECTS)
|
||||||
|
$(CXX) $(OBJECTS) $(CFLAGS) $(LIBS) -o DGIdGateway
|
||||||
|
|
||||||
|
%.o: %.cpp
|
||||||
|
$(CXX) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
install:
|
||||||
|
install -m 755 DGIdGateway /usr/local/bin/
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) DGIdGateway *.o *.d *.bak *~
|
||||||
|
|
12
DGIdGateway/README.md
Normal file
12
DGIdGateway/README.md
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
The YSF Gateway interfaces the MMDVM Host to the open source YSF Reflector system using the standard Wires-X commands from the radio. It also gateways position information to aprs.fi if sent.
|
||||||
|
|
||||||
|
The file YSFHosts.txt holds information about the reflectors available, and the gateway has the ability to reload this file at intervals to ensure that it is always up to date.
|
||||||
|
|
||||||
|
It is expected that a call to retrieve this file is done via some mechanism such as cron on Linux. The URLs to retrieve the latest file are [http://register.ysfreflector.de/export_csv.php](http://register.ysfreflector.de/export_csv.php), or [https://register.ysfreflector.de/export_csv.php](https://register.ysfreflector.de/export_csv.php).
|
||||||
|
|
||||||
|
An example would be following line in root's crontab, that fetches the reflector-list each 5 minutes:
|
||||||
|
> sudo crontab -e
|
||||||
|
|
||||||
|
add following line:
|
||||||
|
|
||||||
|
> */5 * * * * wget -O /var/YSFGateway/YSFHosts.txt http://register.ysfreflector.de/export_csv.php
|
149
DGIdGateway/RingBuffer.h
Normal file
149
DGIdGateway/RingBuffer.h
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
/*
|
||||||
|
* 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 "Log.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()) {
|
||||||
|
LogError("**** Overflow in %s ring buffer, %u >= %u", 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) {
|
||||||
|
LogError("**** Underflow in %s ring buffer, %u < %u", 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) {
|
||||||
|
LogError("**** Underflow peek in %s ring buffer, %u < %u", 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
|
105
DGIdGateway/StopWatch.cpp
Normal file
105
DGIdGateway/StopWatch.cpp
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
/*
|
||||||
|
* 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 "StopWatch.h"
|
||||||
|
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
|
||||||
|
CStopWatch::CStopWatch() :
|
||||||
|
m_frequencyS(),
|
||||||
|
m_frequencyMS(),
|
||||||
|
m_start()
|
||||||
|
{
|
||||||
|
::QueryPerformanceFrequency(&m_frequencyS);
|
||||||
|
|
||||||
|
m_frequencyMS.QuadPart = m_frequencyS.QuadPart / 1000ULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CStopWatch::~CStopWatch()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long long CStopWatch::time() const
|
||||||
|
{
|
||||||
|
LARGE_INTEGER now;
|
||||||
|
::QueryPerformanceCounter(&now);
|
||||||
|
|
||||||
|
return (unsigned long long)(now.QuadPart / m_frequencyMS.QuadPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long long CStopWatch::start()
|
||||||
|
{
|
||||||
|
::QueryPerformanceCounter(&m_start);
|
||||||
|
|
||||||
|
return (unsigned long long)(m_start.QuadPart / m_frequencyS.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_frequencyS.QuadPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
CStopWatch::CStopWatch() :
|
||||||
|
m_startMS(0ULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CStopWatch::~CStopWatch()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long long CStopWatch::time() const
|
||||||
|
{
|
||||||
|
struct timeval now;
|
||||||
|
::gettimeofday(&now, NULL);
|
||||||
|
|
||||||
|
return now.tv_sec * 1000ULL + now.tv_usec / 1000ULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long long CStopWatch::start()
|
||||||
|
{
|
||||||
|
struct timespec now;
|
||||||
|
::clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
|
|
||||||
|
m_startMS = now.tv_sec * 1000ULL + now.tv_nsec / 1000000ULL;
|
||||||
|
|
||||||
|
return m_startMS;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int CStopWatch::elapsed()
|
||||||
|
{
|
||||||
|
struct timespec now;
|
||||||
|
::clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
|
|
||||||
|
unsigned long long nowMS = now.tv_sec * 1000ULL + now.tv_nsec / 1000000ULL;
|
||||||
|
|
||||||
|
return nowMS - m_startMS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
49
DGIdGateway/StopWatch.h
Normal file
49
DGIdGateway/StopWatch.h
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* 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(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 long time() const;
|
||||||
|
|
||||||
|
unsigned long long start();
|
||||||
|
unsigned int elapsed();
|
||||||
|
|
||||||
|
private:
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
LARGE_INTEGER m_frequencyS;
|
||||||
|
LARGE_INTEGER m_frequencyMS;
|
||||||
|
LARGE_INTEGER m_start;
|
||||||
|
#else
|
||||||
|
unsigned long long m_startMS;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
32
DGIdGateway/Sync.cpp
Normal file
32
DGIdGateway/Sync.cpp
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* 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 "Sync.h"
|
||||||
|
|
||||||
|
#include "YSFDefines.h"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
void CSync::add(unsigned char* data)
|
||||||
|
{
|
||||||
|
assert(data != NULL);
|
||||||
|
|
||||||
|
::memcpy(data, YSF_SYNC_BYTES, YSF_SYNC_LENGTH_BYTES);
|
||||||
|
}
|
30
DGIdGateway/Sync.h
Normal file
30
DGIdGateway/Sync.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* 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(SYNC_H)
|
||||||
|
#define SYNC_H
|
||||||
|
|
||||||
|
class CSync
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void add(unsigned char* data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
101
DGIdGateway/Thread.cpp
Normal file
101
DGIdGateway/Thread.cpp
Normal file
|
@ -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
|
56
DGIdGateway/Thread.h
Normal file
56
DGIdGateway/Thread.h
Normal file
|
@ -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
|
68
DGIdGateway/Timer.cpp
Normal file
68
DGIdGateway/Timer.cpp
Normal file
|
@ -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;
|
||||||
|
}
|
89
DGIdGateway/Timer.h
Normal file
89
DGIdGateway/Timer.h
Normal file
|
@ -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
|
264
DGIdGateway/UDPSocket.cpp
Normal file
264
DGIdGateway/UDPSocket.cpp
Normal file
|
@ -0,0 +1,264 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogInfo("Opening UDP port on %u", m_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
58
DGIdGateway/UDPSocket.h
Normal file
58
DGIdGateway/UDPSocket.h
Normal file
|
@ -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
|
146
DGIdGateway/Utils.cpp
Normal file
146
DGIdGateway/Utils.cpp
Normal file
|
@ -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;
|
||||||
|
}
|
36
DGIdGateway/Utils.h
Normal file
36
DGIdGateway/Utils.h
Normal file
|
@ -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
|
24
DGIdGateway/Version.h
Normal file
24
DGIdGateway/Version.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015-2020 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 = "20200803";
|
||||||
|
|
||||||
|
#endif
|
141
DGIdGateway/YSFConvolution.cpp
Normal file
141
DGIdGateway/YSFConvolution.cpp
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009-2016 by Jonathan Naylor G4KLX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "YSFConvolution.h"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
||||||
|
|
||||||
|
#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
|
||||||
|
#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
|
||||||
|
|
||||||
|
const uint8_t BRANCH_TABLE1[] = {0U, 0U, 0U, 0U, 1U, 1U, 1U, 1U};
|
||||||
|
const uint8_t BRANCH_TABLE2[] = {0U, 1U, 1U, 0U, 0U, 1U, 1U, 0U};
|
||||||
|
|
||||||
|
const unsigned int NUM_OF_STATES_D2 = 8U;
|
||||||
|
const unsigned int NUM_OF_STATES = 16U;
|
||||||
|
const uint32_t M = 2U;
|
||||||
|
const unsigned int K = 5U;
|
||||||
|
|
||||||
|
CYSFConvolution::CYSFConvolution() :
|
||||||
|
m_metrics1(NULL),
|
||||||
|
m_metrics2(NULL),
|
||||||
|
m_oldMetrics(NULL),
|
||||||
|
m_newMetrics(NULL),
|
||||||
|
m_decisions(NULL),
|
||||||
|
m_dp(NULL)
|
||||||
|
{
|
||||||
|
m_metrics1 = new uint16_t[16U];
|
||||||
|
m_metrics2 = new uint16_t[16U];
|
||||||
|
m_decisions = new uint64_t[180U];
|
||||||
|
}
|
||||||
|
|
||||||
|
CYSFConvolution::~CYSFConvolution()
|
||||||
|
{
|
||||||
|
delete[] m_metrics1;
|
||||||
|
delete[] m_metrics2;
|
||||||
|
delete[] m_decisions;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CYSFConvolution::start()
|
||||||
|
{
|
||||||
|
::memset(m_metrics1, 0x00U, NUM_OF_STATES * sizeof(uint16_t));
|
||||||
|
::memset(m_metrics2, 0x00U, NUM_OF_STATES * sizeof(uint16_t));
|
||||||
|
|
||||||
|
m_oldMetrics = m_metrics1;
|
||||||
|
m_newMetrics = m_metrics2;
|
||||||
|
m_dp = m_decisions;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CYSFConvolution::decode(uint8_t s0, uint8_t s1)
|
||||||
|
{
|
||||||
|
*m_dp = 0U;
|
||||||
|
|
||||||
|
for (uint8_t i = 0U; i < NUM_OF_STATES_D2; i++) {
|
||||||
|
uint8_t j = i * 2U;
|
||||||
|
|
||||||
|
uint16_t metric = (BRANCH_TABLE1[i] ^ s0) + (BRANCH_TABLE2[i] ^ s1);
|
||||||
|
|
||||||
|
uint16_t m0 = m_oldMetrics[i] + metric;
|
||||||
|
uint16_t m1 = m_oldMetrics[i + NUM_OF_STATES_D2] + (M - metric);
|
||||||
|
uint8_t decision0 = (m0 >= m1) ? 1U : 0U;
|
||||||
|
m_newMetrics[j + 0U] = decision0 != 0U ? m1 : m0;
|
||||||
|
|
||||||
|
m0 = m_oldMetrics[i] + (M - metric);
|
||||||
|
m1 = m_oldMetrics[i + NUM_OF_STATES_D2] + metric;
|
||||||
|
uint8_t decision1 = (m0 >= m1) ? 1U : 0U;
|
||||||
|
m_newMetrics[j + 1U] = decision1 != 0U ? m1 : m0;
|
||||||
|
|
||||||
|
*m_dp |= (uint64_t(decision1) << (j + 1U)) | (uint64_t(decision0) << (j + 0U));
|
||||||
|
}
|
||||||
|
|
||||||
|
++m_dp;
|
||||||
|
|
||||||
|
assert((m_dp - m_decisions) <= 180);
|
||||||
|
|
||||||
|
uint16_t* tmp = m_oldMetrics;
|
||||||
|
m_oldMetrics = m_newMetrics;
|
||||||
|
m_newMetrics = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CYSFConvolution::chainback(unsigned char* out, unsigned int nBits)
|
||||||
|
{
|
||||||
|
assert(out != NULL);
|
||||||
|
|
||||||
|
uint32_t state = 0U;
|
||||||
|
|
||||||
|
while (nBits-- > 0) {
|
||||||
|
--m_dp;
|
||||||
|
|
||||||
|
uint32_t i = state >> (9 - K);
|
||||||
|
uint8_t bit = uint8_t(*m_dp >> i) & 1;
|
||||||
|
state = (bit << 7) | (state >> 1);
|
||||||
|
|
||||||
|
WRITE_BIT1(out, nBits, bit != 0U);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CYSFConvolution::encode(const unsigned char* in, unsigned char* out, unsigned int nBits) const
|
||||||
|
{
|
||||||
|
assert(in != NULL);
|
||||||
|
assert(out != NULL);
|
||||||
|
assert(nBits > 0U);
|
||||||
|
|
||||||
|
uint8_t d1 = 0U, d2 = 0U, d3 = 0U, d4 = 0U;
|
||||||
|
uint32_t k = 0U;
|
||||||
|
for (unsigned int i = 0U; i < nBits; i++) {
|
||||||
|
uint8_t d = READ_BIT1(in, i) ? 1U : 0U;
|
||||||
|
|
||||||
|
uint8_t g1 = (d + d3 + d4) & 1;
|
||||||
|
uint8_t g2 = (d + d1 + d2 + d4) & 1;
|
||||||
|
|
||||||
|
d4 = d3;
|
||||||
|
d3 = d2;
|
||||||
|
d2 = d1;
|
||||||
|
d1 = d;
|
||||||
|
|
||||||
|
WRITE_BIT1(out, k, g1 != 0U);
|
||||||
|
k++;
|
||||||
|
|
||||||
|
WRITE_BIT1(out, k, g2 != 0U);
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
}
|
47
DGIdGateway/YSFConvolution.h
Normal file
47
DGIdGateway/YSFConvolution.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(YSFConvolution_H)
|
||||||
|
#define YSFConvolution_H
|
||||||
|
|
||||||
|
#include "YSFConvolution.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
class CYSFConvolution {
|
||||||
|
public:
|
||||||
|
CYSFConvolution();
|
||||||
|
~CYSFConvolution();
|
||||||
|
|
||||||
|
void start();
|
||||||
|
void decode(uint8_t s0, uint8_t s1);
|
||||||
|
void chainback(unsigned char* out, unsigned int nBits);
|
||||||
|
|
||||||
|
void encode(const unsigned char* in, unsigned char* out, unsigned int nBits) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint16_t* m_metrics1;
|
||||||
|
uint16_t* m_metrics2;
|
||||||
|
uint16_t* m_oldMetrics;
|
||||||
|
uint16_t* m_newMetrics;
|
||||||
|
uint64_t* m_decisions;
|
||||||
|
uint64_t* m_dp;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
52
DGIdGateway/YSFDefines.h
Normal file
52
DGIdGateway/YSFDefines.h
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015,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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(YSFDefines_H)
|
||||||
|
#define YSFDefines_H
|
||||||
|
|
||||||
|
const unsigned int YSF_FRAME_LENGTH_BYTES = 120U;
|
||||||
|
|
||||||
|
const unsigned char YSF_SYNC_BYTES[] = {0xD4U, 0x71U, 0xC9U, 0x63U, 0x4DU};
|
||||||
|
const unsigned int YSF_SYNC_LENGTH_BYTES = 5U;
|
||||||
|
|
||||||
|
const unsigned int YSF_FICH_LENGTH_BYTES = 25U;
|
||||||
|
|
||||||
|
const unsigned char YSF_SYNC_OK = 0x01U;
|
||||||
|
|
||||||
|
const unsigned int YSF_CALLSIGN_LENGTH = 10U;
|
||||||
|
|
||||||
|
const unsigned char YSF_FI_HEADER = 0x00U;
|
||||||
|
const unsigned char YSF_FI_COMMUNICATIONS = 0x01U;
|
||||||
|
const unsigned char YSF_FI_TERMINATOR = 0x02U;
|
||||||
|
const unsigned char YSF_FI_TEST = 0x03U;
|
||||||
|
|
||||||
|
const unsigned char YSF_DT_VD_MODE1 = 0x00U;
|
||||||
|
const unsigned char YSF_DT_DATA_FR_MODE = 0x01U;
|
||||||
|
const unsigned char YSF_DT_VD_MODE2 = 0x02U;
|
||||||
|
const unsigned char YSF_DT_VOICE_FR_MODE = 0x03U;
|
||||||
|
|
||||||
|
const unsigned char YSF_CM_GROUP1 = 0x00U;
|
||||||
|
const unsigned char YSF_CM_GROUP2 = 0x01U;
|
||||||
|
const unsigned char YSF_CM_INDIVIDUAL = 0x03U;
|
||||||
|
|
||||||
|
const unsigned char YSF_MR_NOT_BUSY = 0x01U;
|
||||||
|
const unsigned char YSF_MR_BUSY = 0x02U;
|
||||||
|
|
||||||
|
const unsigned int FCS_PORT = 62500U;
|
||||||
|
|
||||||
|
#endif
|
274
DGIdGateway/YSFFICH.cpp
Normal file
274
DGIdGateway/YSFFICH.cpp
Normal file
|
@ -0,0 +1,274 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016,2017,2019 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 "YSFConvolution.h"
|
||||||
|
#include "YSFDefines.h"
|
||||||
|
#include "Golay24128.h"
|
||||||
|
#include "YSFFICH.h"
|
||||||
|
#include "CRC.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
||||||
|
|
||||||
|
#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
|
||||||
|
#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
|
||||||
|
|
||||||
|
const unsigned int INTERLEAVE_TABLE[] = {
|
||||||
|
0U, 40U, 80U, 120U, 160U,
|
||||||
|
2U, 42U, 82U, 122U, 162U,
|
||||||
|
4U, 44U, 84U, 124U, 164U,
|
||||||
|
6U, 46U, 86U, 126U, 166U,
|
||||||
|
8U, 48U, 88U, 128U, 168U,
|
||||||
|
10U, 50U, 90U, 130U, 170U,
|
||||||
|
12U, 52U, 92U, 132U, 172U,
|
||||||
|
14U, 54U, 94U, 134U, 174U,
|
||||||
|
16U, 56U, 96U, 136U, 176U,
|
||||||
|
18U, 58U, 98U, 138U, 178U,
|
||||||
|
20U, 60U, 100U, 140U, 180U,
|
||||||
|
22U, 62U, 102U, 142U, 182U,
|
||||||
|
24U, 64U, 104U, 144U, 184U,
|
||||||
|
26U, 66U, 106U, 146U, 186U,
|
||||||
|
28U, 68U, 108U, 148U, 188U,
|
||||||
|
30U, 70U, 110U, 150U, 190U,
|
||||||
|
32U, 72U, 112U, 152U, 192U,
|
||||||
|
34U, 74U, 114U, 154U, 194U,
|
||||||
|
36U, 76U, 116U, 156U, 196U,
|
||||||
|
38U, 78U, 118U, 158U, 198U};
|
||||||
|
|
||||||
|
CYSFFICH::CYSFFICH(const CYSFFICH& fich) :
|
||||||
|
m_fich(NULL)
|
||||||
|
{
|
||||||
|
m_fich = new unsigned char[6U];
|
||||||
|
|
||||||
|
::memcpy(m_fich, fich.m_fich, 6U);
|
||||||
|
}
|
||||||
|
|
||||||
|
CYSFFICH::CYSFFICH() :
|
||||||
|
m_fich(NULL)
|
||||||
|
{
|
||||||
|
m_fich = new unsigned char[6U];
|
||||||
|
|
||||||
|
memset(m_fich, 0x00U, 6U);
|
||||||
|
}
|
||||||
|
|
||||||
|
CYSFFICH::~CYSFFICH()
|
||||||
|
{
|
||||||
|
delete[] m_fich;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CYSFFICH::decode(const unsigned char* bytes)
|
||||||
|
{
|
||||||
|
assert(bytes != NULL);
|
||||||
|
|
||||||
|
// Skip the sync bytes
|
||||||
|
bytes += YSF_SYNC_LENGTH_BYTES;
|
||||||
|
|
||||||
|
CYSFConvolution viterbi;
|
||||||
|
viterbi.start();
|
||||||
|
|
||||||
|
// Deinterleave the FICH and send bits to the Viterbi decoder
|
||||||
|
for (unsigned int i = 0U; i < 100U; i++) {
|
||||||
|
unsigned int n = INTERLEAVE_TABLE[i];
|
||||||
|
uint8_t s0 = READ_BIT1(bytes, n) ? 1U : 0U;
|
||||||
|
|
||||||
|
n++;
|
||||||
|
uint8_t s1 = READ_BIT1(bytes, n) ? 1U : 0U;
|
||||||
|
|
||||||
|
viterbi.decode(s0, s1);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char output[13U];
|
||||||
|
viterbi.chainback(output, 96U);
|
||||||
|
|
||||||
|
unsigned int b0 = CGolay24128::decode24128(output + 0U);
|
||||||
|
unsigned int b1 = CGolay24128::decode24128(output + 3U);
|
||||||
|
unsigned int b2 = CGolay24128::decode24128(output + 6U);
|
||||||
|
unsigned int b3 = CGolay24128::decode24128(output + 9U);
|
||||||
|
|
||||||
|
m_fich[0U] = (b0 >> 4) & 0xFFU;
|
||||||
|
m_fich[1U] = ((b0 << 4) & 0xF0U) | ((b1 >> 8) & 0x0FU);
|
||||||
|
m_fich[2U] = (b1 >> 0) & 0xFFU;
|
||||||
|
m_fich[3U] = (b2 >> 4) & 0xFFU;
|
||||||
|
m_fich[4U] = ((b2 << 4) & 0xF0U) | ((b3 >> 8) & 0x0FU);
|
||||||
|
m_fich[5U] = (b3 >> 0) & 0xFFU;
|
||||||
|
|
||||||
|
return CCRC::checkCCITT162(m_fich, 6U);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CYSFFICH::encode(unsigned char* bytes)
|
||||||
|
{
|
||||||
|
assert(bytes != NULL);
|
||||||
|
|
||||||
|
// Skip the sync bytes
|
||||||
|
bytes += YSF_SYNC_LENGTH_BYTES;
|
||||||
|
|
||||||
|
CCRC::addCCITT162(m_fich, 6U);
|
||||||
|
|
||||||
|
unsigned int b0 = ((m_fich[0U] << 4) & 0xFF0U) | ((m_fich[1U] >> 4) & 0x00FU);
|
||||||
|
unsigned int b1 = ((m_fich[1U] << 8) & 0xF00U) | ((m_fich[2U] >> 0) & 0x0FFU);
|
||||||
|
unsigned int b2 = ((m_fich[3U] << 4) & 0xFF0U) | ((m_fich[4U] >> 4) & 0x00FU);
|
||||||
|
unsigned int b3 = ((m_fich[4U] << 8) & 0xF00U) | ((m_fich[5U] >> 0) & 0x0FFU);
|
||||||
|
|
||||||
|
unsigned int c0 = CGolay24128::encode24128(b0);
|
||||||
|
unsigned int c1 = CGolay24128::encode24128(b1);
|
||||||
|
unsigned int c2 = CGolay24128::encode24128(b2);
|
||||||
|
unsigned int c3 = CGolay24128::encode24128(b3);
|
||||||
|
|
||||||
|
unsigned char conv[13U];
|
||||||
|
conv[0U] = (c0 >> 16) & 0xFFU;
|
||||||
|
conv[1U] = (c0 >> 8) & 0xFFU;
|
||||||
|
conv[2U] = (c0 >> 0) & 0xFFU;
|
||||||
|
conv[3U] = (c1 >> 16) & 0xFFU;
|
||||||
|
conv[4U] = (c1 >> 8) & 0xFFU;
|
||||||
|
conv[5U] = (c1 >> 0) & 0xFFU;
|
||||||
|
conv[6U] = (c2 >> 16) & 0xFFU;
|
||||||
|
conv[7U] = (c2 >> 8) & 0xFFU;
|
||||||
|
conv[8U] = (c2 >> 0) & 0xFFU;
|
||||||
|
conv[9U] = (c3 >> 16) & 0xFFU;
|
||||||
|
conv[10U] = (c3 >> 8) & 0xFFU;
|
||||||
|
conv[11U] = (c3 >> 0) & 0xFFU;
|
||||||
|
conv[12U] = 0x00U;
|
||||||
|
|
||||||
|
CYSFConvolution convolution;
|
||||||
|
unsigned char convolved[25U];
|
||||||
|
convolution.encode(conv, convolved, 100U);
|
||||||
|
|
||||||
|
unsigned int j = 0U;
|
||||||
|
for (unsigned int i = 0U; i < 100U; i++) {
|
||||||
|
unsigned int n = INTERLEAVE_TABLE[i];
|
||||||
|
|
||||||
|
bool s0 = READ_BIT1(convolved, j) != 0U;
|
||||||
|
j++;
|
||||||
|
|
||||||
|
bool s1 = READ_BIT1(convolved, j) != 0U;
|
||||||
|
j++;
|
||||||
|
|
||||||
|
WRITE_BIT1(bytes, n, s0);
|
||||||
|
|
||||||
|
n++;
|
||||||
|
WRITE_BIT1(bytes, n, s1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CYSFFICH::getFI() const
|
||||||
|
{
|
||||||
|
return (m_fich[0U] >> 6) & 0x03U;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CYSFFICH::getCM() const
|
||||||
|
{
|
||||||
|
return (m_fich[0U] >> 2) & 0x03U;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CYSFFICH::getBN() const
|
||||||
|
{
|
||||||
|
return m_fich[0U] & 0x03U;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CYSFFICH::getBT() const
|
||||||
|
{
|
||||||
|
return (m_fich[1U] >> 6) & 0x03U;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CYSFFICH::getFN() const
|
||||||
|
{
|
||||||
|
return (m_fich[1U] >> 3) & 0x07U;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CYSFFICH::getFT() const
|
||||||
|
{
|
||||||
|
return m_fich[1U] & 0x07U;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CYSFFICH::getDT() const
|
||||||
|
{
|
||||||
|
return m_fich[2U] & 0x03U;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CYSFFICH::getMR() const
|
||||||
|
{
|
||||||
|
return (m_fich[2U] >> 3) & 0x03U;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CYSFFICH::getDev() const
|
||||||
|
{
|
||||||
|
return (m_fich[2U] & 0x40U) == 0x40U;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char CYSFFICH::getDGId() const
|
||||||
|
{
|
||||||
|
return m_fich[3U] & 0x7FU;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CYSFFICH::setFI(unsigned char fi)
|
||||||
|
{
|
||||||
|
m_fich[0U] &= 0x3FU;
|
||||||
|
m_fich[0U] |= (fi << 6) & 0xC0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CYSFFICH::setFN(unsigned char fn)
|
||||||
|
{
|
||||||
|
m_fich[1U] &= 0xC7U;
|
||||||
|
m_fich[1U] |= (fn << 3) & 0x38U;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CYSFFICH::setFT(unsigned char ft)
|
||||||
|
{
|
||||||
|
m_fich[1U] &= 0xF8U;
|
||||||
|
m_fich[1U] |= ft & 0x07U;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CYSFFICH::setMR(unsigned char mr)
|
||||||
|
{
|
||||||
|
m_fich[2U] &= 0xC7U;
|
||||||
|
m_fich[2U] |= (mr << 3) & 0x38U;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CYSFFICH::setVoIP(bool on)
|
||||||
|
{
|
||||||
|
if (on)
|
||||||
|
m_fich[2U] |= 0x04U;
|
||||||
|
else
|
||||||
|
m_fich[2U] &= 0xFBU;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CYSFFICH::setDev(bool on)
|
||||||
|
{
|
||||||
|
if (on)
|
||||||
|
m_fich[2U] |= 0x40U;
|
||||||
|
else
|
||||||
|
m_fich[2U] &= 0xBFU;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CYSFFICH::setDGId(unsigned char id)
|
||||||
|
{
|
||||||
|
m_fich[3U] &= 0x80U;
|
||||||
|
m_fich[3U] |= id & 0x7FU;
|
||||||
|
}
|
||||||
|
|
||||||
|
CYSFFICH& CYSFFICH::operator=(const CYSFFICH& fich)
|
||||||
|
{
|
||||||
|
if (&fich != this)
|
||||||
|
::memcpy(m_fich, fich.m_fich, 6U);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
57
DGIdGateway/YSFFICH.h
Normal file
57
DGIdGateway/YSFFICH.h
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016,2017,2019 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(YSFFICH_H)
|
||||||
|
#define YSFFICH_H
|
||||||
|
|
||||||
|
class CYSFFICH {
|
||||||
|
public:
|
||||||
|
CYSFFICH(const CYSFFICH& fich);
|
||||||
|
CYSFFICH();
|
||||||
|
~CYSFFICH();
|
||||||
|
|
||||||
|
bool decode(const unsigned char* bytes);
|
||||||
|
|
||||||
|
void encode(unsigned char* bytes);
|
||||||
|
|
||||||
|
unsigned char getFI() const;
|
||||||
|
unsigned char getCM() const;
|
||||||
|
unsigned char getBN() const;
|
||||||
|
unsigned char getBT() const;
|
||||||
|
unsigned char getFN() const;
|
||||||
|
unsigned char getFT() const;
|
||||||
|
unsigned char getDT() const;
|
||||||
|
unsigned char getMR() const;
|
||||||
|
bool getDev() const;
|
||||||
|
unsigned char getDGId() const;
|
||||||
|
|
||||||
|
void setFI(unsigned char fi);
|
||||||
|
void setFN(unsigned char fn);
|
||||||
|
void setFT(unsigned char ft);
|
||||||
|
void setMR(unsigned char mr);
|
||||||
|
void setVoIP(bool set);
|
||||||
|
void setDev(bool set);
|
||||||
|
void setDGId(unsigned char id);
|
||||||
|
|
||||||
|
CYSFFICH& operator=(const CYSFFICH& fich);
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned char* m_fich;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
899
DGIdGateway/YSFHosts.txt
Normal file
899
DGIdGateway/YSFHosts.txt
Normal file
|
@ -0,0 +1,899 @@
|
||||||
|
90681;0-0-AMERICA;CQ USA! USA!;130.211.170.41;42001;010;http://
|
||||||
|
03729;0-0-CHINAVIRUS;COVID CHAT;130.211.170.41;42002;001;http://
|
||||||
|
27793;0-0-CQ-UK-ROOM;cq-uk.co.uk;81.150.10.62;42200;073;http://www.mb6er.com/ysf/
|
||||||
|
24160;0-CQ-UK-AUSSIE;Reflector 2;81.150.10.63;42100;009;https://www.cq-uk.co.uk
|
||||||
|
02203;0-HUBNet;Link to HUBNet;81.105.24.211;42000;005;https://hubnetwork.uk/
|
||||||
|
84922;0-KP3AV-Systems;Puerto Rico HU;70.45.32.69;41000;004;https://www.kp3av.net/
|
||||||
|
92150;0-MAGA;MAGA AMERICA;130.211.170.41;42000;001;http://no.not.yet/
|
||||||
|
65702;0-OE-Austria;Official;94.199.173.123;42200;001;http://oe9xvi.dyndns.org:46193
|
||||||
|
24117;00-AACQ-VK;VK WiRES-X;110.232.113.108;42002;014;http://110.232.113.108/vw
|
||||||
|
38900;00-AAYSF001;YSF001;110.232.113.108;42000;005;http://ysf001.duckdns.org
|
||||||
|
38089;0077;IRLP/ DMR/ D-S;23.94.25.146;42002;006;http://xe1dvi.crabdance.com/html/index.php
|
||||||
|
32642;021YSF;KR 021YSF;27.100.207.79;42000;006;http://ysf021.dvham.com
|
||||||
|
33280;0303_YSFColo;0303_YSFColo;3.22.106.87;42000;002;http://
|
||||||
|
40608;069-Er-Super-Fre;BM-YSF-P25-NXD;13.57.29.35;42000;004;http://
|
||||||
|
84905;096ysf-Busan-KR;Link TG450391;125.135.231.82;42000;000;http://096ysf.duckdns.org
|
||||||
|
11506;0970_YSFColo;0970_YSFColo;75.71.97.203;42000;004;http://
|
||||||
|
11500;0E7XTR;Tirol Oberland;185.199.82.169;42000;002;https://inet01.synology.me:46193
|
||||||
|
02573;1004DMR;DRM C4FM CROSS;218.144.164.10;42000;004;http://1004dmr.dvham.com/indexysf.php
|
||||||
|
74652;119-YSF;KR 119YSF;61.42.88.20;42000;030;http://ysf119.dvham.com/index.php
|
||||||
|
68800;2007-DXGROUP;Web Server;89.46.75.115;42000;005;http://89.46.75.115/index
|
||||||
|
37865;450IPSC2;C4FM TO DMR;220.71.19.222;42000;005;http://450ipsc2.dvham.com/indexysf.php
|
||||||
|
21796;4X-Israel;Israel Digital;109.226.48.53;42000;001;http://ysf972.ddns.net
|
||||||
|
06015;50525;Bridge-NXDN-P2;103.1.187.140;42000;003;http://50525.ysfreflector.net
|
||||||
|
97629;79435;IT S.M.A.M Pis;185.177.59.32;42000;005;http://185.177.59.32
|
||||||
|
65947;843IPSC2;IPSC2-DMR(TG84;218.144.164.13;42000;001;http://ipsc2843.dvham.com/indexysf.php
|
||||||
|
60227;911-Cop-Talk;911 Cop Talk;34.238.149.231;42000;002;http://ysf.k2cop.com
|
||||||
|
83018;95ANorth;Fernley,NV USA;216.128.134.46;42000;001;http://ysf.k7wby.com
|
||||||
|
44734;AARC-Fusion;AARC Fusion;64.179.223.222;42000;001;https://ysf.spdns.org
|
||||||
|
17950;AH-HUH.NET;YSF;52.192.129.174;42000;012;http://ah-huh.net/ysf/
|
||||||
|
02034;Alabama-Link;Alabama-Link;96.47.95.121;42000;048;http://ysf.alabamalink.info/
|
||||||
|
64230;America-RC;YSF-TO-WIRES-X;65.101.7.50;42001;015;http://arcysf.duckdns.org
|
||||||
|
21080;AmericaLink;AmericaLink;209.126.110.236;42000;443;http://hamfm.com/ysf/
|
||||||
|
30458;AnHui-HeFei01;YSF/BM460601;47.116.60.36;42000;003;http://eei-edu.f3322.net
|
||||||
|
31897;AR-AR-CIRCULO;ROSARIO;181.165.15.51;42000;007;http://circulorosario.linkpc.net
|
||||||
|
10111;AR-ARG;*ARG* Argentin;149.28.100.251;42000;001;http://ysfarg.ddns.net
|
||||||
|
73599;AR-TG722-LINK;YSF to TG722;80.211.1.59;42000;000;http://722ysfargentina.dnsalias.com
|
||||||
|
60842;ARG-FUSION;C4FM;200.81.152.112;42000;000;http://rotativos.dyndns.org:42002
|
||||||
|
31302;ARG-ROOM;Argentina-ROOM;190.194.12.53;42000;008;http://xlx.argentina-room.dns-cloud.net
|
||||||
|
66099;ARGENTINA-LINK;Link to TG7227;80.211.7.43;42000;014;http://7221ysfargentina.dnsalias.com
|
||||||
|
61159;ArkLaTex;ArkLaTex;104.198.203.19;42000;002;http://104.198.203.19
|
||||||
|
24490;ASL48270;AllStar;104.143.94.48;42042;001;http://104.143.94.48/YSFReflector/index.php
|
||||||
|
25223;AT-Austria-OE1;OE1XFV;213.47.71.17;42000;003;http://oe1xfv.ddns.net/YSFReflector-Dashboard/
|
||||||
|
00396;AT-Austria-OE3;OE3AAS;77.116.18.249;42100;001;http://oe3aas.ddns.net/YSFReflector-Dashboard/
|
||||||
|
71095;AT-Austria-OE5;OE5XOL;185.16.114.90;42000;001;http://oe5xol.ham-radio-op.net/YSFReflector-Dashboard/
|
||||||
|
59911;AT-Austria-OE8;OE8VIK;178.199.109.52;42000;000;http://oe8vik.internet-box.ch/YSFReflector-Dashboard
|
||||||
|
23201;AT-C4FM-Austria;(YCS001);89.185.97.38;42000;073;http://c4fm.oevsv.at/ycs/
|
||||||
|
73082;AU-Albury-Chat;Albury Chat;52.63.126.187;42000;009;http://52.63.126.187/
|
||||||
|
43110;AU-NSW;AU NSW;123.243.237.216;42000;000;http://ysfnsw.gustotech.net/
|
||||||
|
05057;AU_TAS;VK7 Tasmania;45.248.50.37;42001;001;http://vk7hse.duckdns.org/ysf
|
||||||
|
74037;BARC-ONT-CA;Burlington ARC;69.158.63.158;42000;000;http://barcysfreflector.ddns.net
|
||||||
|
00043;BAYAREA-YSF;Silicon Valley;45.32.129.65;42000;010;http://ysf.bsdworld.org/ysf/
|
||||||
|
44992;BE-YSF-Liege;Wires-X<>YSF;51.75.249.214;42002;000;http://51.75.249.214/ysf/
|
||||||
|
64364;BE-YSF-Vl;C4FMVlaanderen;81.95.126.168;42001;009;http://ysf.on4top.be/ysf/
|
||||||
|
79520;BE-YSF-Wallonie;C4FM Wallon;51.255.193.63;42000;003;http://www.ysfwallonie.net/
|
||||||
|
46197;BE-YSFEUREGIO;LNK_BE_EUREGIO;213.49.173.226;43000;003;http://rmx.noip.me:6380
|
||||||
|
00076;Berks-County;Pennsylvania;24.115.37.118;42020;000;http://
|
||||||
|
69733;BM2410/XLX010D;SSA Bulletin;95.216.197.75;42001;001;http://ysf2.brandmeister.se
|
||||||
|
56800;Boar's-Nest;Good Ol' Boys;67.140.163.107;42002;000;http://
|
||||||
|
90558;BR-PU2LRZ;TG268916 WIRES;186.228.91.9;42000;010;http://ysf-brasil.com.br
|
||||||
|
08059;Brasil-AMRASE;Brasil-Link;201.62.48.60;42000;003;http://ysf.amrase.org.br/ysf
|
||||||
|
72526;BRAZIL-724;DV Brazil;191.252.203.6;42000;004;https://ysf.dvbrazil.com.br/
|
||||||
|
85044;C4FM-SEOUL;TG45050 TO C4F;222.110.59.176;42000;004;http://ysfso.dvham.com/indexysf.php
|
||||||
|
36037;CA-420-Network;RAGCHEW;142.93.158.165;42000;003;https://ysf.420hamradio.network
|
||||||
|
77353;CA-Canada;C4FM Ontario;144.217.241.23;42100;007;http://c4fmontario.hopto.org
|
||||||
|
71083;CA-Canada-FR;Fusion Canada;38.110.97.161;42000;015;http://38.110.97.161
|
||||||
|
29579;CA-CQ-Canada;DMR TGIF 3022;142.93.158.165;42002;003;https://cqcanada.420hamradio.network/
|
||||||
|
71305;CA-DMRQ-3022;DMRQ TG3022;38.110.97.161;42554;003;http://dmrq.ca/
|
||||||
|
53710;CA-Maritimes;Can Maritimes;178.128.231.202;42000;007;http://ysf.nbdmr.net
|
||||||
|
19952;CA-Nanikana;Nanikana;142.217.113.98;42000;000;http://142.217.113.98
|
||||||
|
36010;CA-ON-ProCom;ON Prov Comms;70.50.41.195;42000;003;http://freestar.homelinux.net/ysf
|
||||||
|
23829;CA-Upper-Can;Upper Can QRP;64.118.21.239;42100;005;http://ve3ucc.ddns.net/
|
||||||
|
13339;CA-WEST-CAN;Western Canada;172.105.26.148;42001;000;http://ysf.ve6meo.ca
|
||||||
|
13124;CA-YSF-CHARC;SW QUEBEC,CA;207.35.36.179;42000;002;https://207.35.36.179
|
||||||
|
72576;CA-YSF-TO-WIRESX;REF-BRIDGE-LAB;192.222.226.35;42002;000;http://dashboard.va2ss.com:8080/
|
||||||
|
48095;CAMCAST;YSF REFLECTOR;80.211.12.209;42000;000;http://80.211.12.209/index.php
|
||||||
|
01177;CARG;CURACAO YSF;138.219.142.144;42000;001;http://138.219.142.144
|
||||||
|
79602;Carolina-Link;79602;208.104.55.181;42001;012;http://208.104.55.181/index.php
|
||||||
|
77785;CDARIN;CDARIN-XLX420;149.28.54.17;42002;000;https://xlx.cdarin.net/ysf
|
||||||
|
30998;CH-228-Swiss;YCS Group 28 S;195.225.116.245;42000;005;http://ysf.hb-connect.ch/
|
||||||
|
63347;CH-228-Swiss2;HB-CONNECT;176.10.105.210;42002;000;http://
|
||||||
|
15280;CH-HB9VD;Radioamateurs;217.182.128.3;42000;002;http://reflector.hb9vd.ch/ysf
|
||||||
|
37664;CH-IT-SWISS;C4FM OM;94.177.215.206;42000;000;http://94.177.215.206
|
||||||
|
66049;ChinaLink;China YSF Refl;60.219.211.9;42000;000;http://ysf.tocall.fun:8081
|
||||||
|
22638;CH_JOTA;Jamboree on th;157.161.57.65;42001;000;http://pi2.woody.ch:8080/YSFReflector-Dashboard/ (ipv6 only)
|
||||||
|
72350;CL-CHILE;YSF to TG730;186.64.123.59;42000;002;http://sdradio.cl/ysf
|
||||||
|
34287;CL-CL-CHILE;YSF HOTSPOT'S;186.103.150.254;42000;000;https://www.radioaficion.pro/ysf
|
||||||
|
19525;CL-EMCOMM;TG 730911;186.64.123.59;42001;000;http://sdradio.cl/ysf2
|
||||||
|
09627;CL-YSF;CHILE YSF ROOM;186.64.123.59;42002;002;http://sdradio.cl/ysf3
|
||||||
|
18829;CN-CC#1;TG 460501;47.104.177.248;42000;001;https://mmdvm.cc/ysf/
|
||||||
|
86319;CN-China-#3;C4FM;123.58.6.137;42000;003;http://123.58.6.137:8088/
|
||||||
|
46055;CN-China-#4;TG460531;112.229.25.110;42003;000;http://pi.jwebid.com:81
|
||||||
|
49766;CN-China-#7;YSFn/DMR/P25;47.100.76.205;42002;000;http://
|
||||||
|
50565;CN-CN-BJS-YSF;CN BJS C4FM;49.233.142.122;42250;002;https://ysf.bh1ofp.com/
|
||||||
|
08408;CN-CN-China-4;P25;47.105.33.47;42003;002;http://www.bg3hbr.cn/ysfp25/
|
||||||
|
25574;CN-CN-SH;YSF/TG46068;116.235.186.62;42000;002;http://chinafex.tpddns.cn:82
|
||||||
|
99996;CN-CN-SH-BR4AC;TG46021;118.89.184.51;42000;001;http://
|
||||||
|
41095;CN-CN-SH-JIUTING;TG4601319;140.143.12.207;42000;001;http://
|
||||||
|
99117;CN-LiaoNing;YSF by BH2UOL;47.95.194.251;42000;000;http://47.95.194.251
|
||||||
|
36400;CN-NMG-1#;C4FM China;39.64.187.131;42000;001;http://jw.jwebid.com:88
|
||||||
|
01347;CN-Shanghai;YSF by BH4EZG;124.78.51.205;42000;000;http://
|
||||||
|
45441;CN-Shenyang-2;YSF by BH2UOL;139.226.2.194;42000;000;http://angel66.f3322.net:2122/
|
||||||
|
87327;CN-SHLK;C4FM;218.79.217.10;42000;002;http://
|
||||||
|
19610;CN-SXXY-YSF;TG46091;123.139.189.182;42000;001;http://ysf.jzsqx.com:3578/ysf/
|
||||||
|
10552;CN-SZ-YSF;BM TG46073;14.116.159.221;42000;005;http://
|
||||||
|
78497;CN-TIANJIN;C4FM/TG460022;47.104.79.192;42000;002;http://
|
||||||
|
57490;CN-Wuhan;CNWUH YSFRef;118.89.199.238;42000;004;http://
|
||||||
|
84099;CN-XUZHOU;TG460516;119.45.191.42;42000;003;http://www.bd4two.cn
|
||||||
|
69058;CNARN;CNARN;45.76.175.5;42000;014;http://cnarn.hopto.org
|
||||||
|
20059;CN_China_#1;W24166/TG46001;58.250.171.29;42000;056;http://ysf.sz790.com:8081/
|
||||||
|
72001;CO-HK_NAL_LCRA;BM TG732;186.29.69.76;42000;007;http://ysfnal.lcra.org.co
|
||||||
|
11115;CQ-MICHIGAN;MICHIGAN USA;107.141.52.226;42002;000;http://
|
||||||
|
27715;CQ-OHIO;Ohio, USA;24.192.74.248;42002;001;http://
|
||||||
|
18480;CT-BMCAT;C4FM Catalunya;94.177.237.192;42000;010;http://ysf900.dyndns.org/ysf
|
||||||
|
04523;CT-CATALANA;C4FM CATALUNYA;213.195.111.148;42000;004;http://catalana.ea3hkb.cat
|
||||||
|
68592;CT-GARRAF;C4FM CATALUNYA;213.195.111.148;42001;005;http://garraf.ea3hkb.cat
|
||||||
|
99797;CT-RI-ROOM;C4FM LINKED;45.58.45.126;42000;008;http://
|
||||||
|
12096;CW-ToyTronNet;Sunny Curacao;186.159.96.100;42001;000;http://ysf.toytron.com
|
||||||
|
14353;CY-YSF-Cyprus;YSF Cyprus Ref;213.7.197.202;42000;001;http://xlx146.ddns.net:81/ysf/
|
||||||
|
26541;CZ-Czech;TG2300 DCS19V;80.250.3.114;42000;011;http://80.250.3.114/index.php
|
||||||
|
26541;CZ-Czech;TG2300 DCS19V;80.250.3.114;42000;011;http://xlx230.ok2it.com
|
||||||
|
52690;CZ-YSF-Klatovy;CZ;46.23.62.124;42200;000;http://46.23.62.124:42080
|
||||||
|
77329;CZ-YSF-Praha;CZ YSF Praha;185.32.183.148;42000;004;http://185.32.183.148/ysf/
|
||||||
|
21972;DE-Berlin;Spandau;81.169.245.52;42000;004;http://www.comvision.de/ysf/
|
||||||
|
42539;DE-Bremen;Bremen-Nord;82.207.204.207;42002;000;http://do0bre.ddns.net/
|
||||||
|
14187;DE-DL-DL1BH;Bremerhaven;87.245.30.60;42000;003;http://
|
||||||
|
90730;DE-DL-Elbe-Weser;DL-Elbe-Weser;91.58.164.76;42000;002;http://dl-elbe-weser.spdns.de
|
||||||
|
07588;DE-DL-Hamburg;Hamburg City;95.116.202.35;42000;006;http://db0fs-router.hamnet.hamburg:22225/index.php
|
||||||
|
54919;DE-DL-NORDWEST;DL-Nordwest;93.240.48.68;42000;034;http://dl-nordwest.spdns.de
|
||||||
|
68399;DE-DL-Oberberg;Bergisches Kr.;82.165.136.160;42000;001;http://ysf.shakerware.de
|
||||||
|
47791;DE-DL-Saar;Saarland;167.86.110.62;42002;001;https://c4fm.ysfreflector.de/DL-Saar/
|
||||||
|
07794;DE-DL5OCD;Hildesheim;46.41.2.20;42000;004;http://dl5ocd.selfhost.eu
|
||||||
|
21584;DE-Fusion-MUC;Fusion-MUC;93.240.113.55;42004;002;http://
|
||||||
|
62829;DE-Germany;YSF262 BM263;167.86.110.62;42000;010;https://c4fm.ysfreflector.de/Germany
|
||||||
|
22675;DE-Germany02;MultiNet-Bridg;185.228.139.209;42000;009;http://ysf-germany02.xreflector.net/ysf/
|
||||||
|
92161;DE-GOETTINGEN;Raum Gö;51.15.40.103;42001;005;http://goettingen-ysf.tk
|
||||||
|
02883;DE-Hannover-XLnk;Hannover und U;81.14.225.84;42000;002;http://ysf.hannover-x.link
|
||||||
|
44305;DE-Heidekreis;Niedersachsen;91.64.24.111;41000;002;http://do3bsl.ddns.net
|
||||||
|
19138;DE-HESSEN-F17;F17 Reflector;80.69.46.184;42000;002;http://
|
||||||
|
55160;DE-Huelzweiler;DL4WM-Reflecto;213.135.12.4;42000;000;http://
|
||||||
|
93571;DE-Inselfreunde;BM-TG26444;88.198.94.77;42444;002;http://
|
||||||
|
68030;DE-Laatzen;Hannover;159.69.64.204;42000;001;https://blackdan.de/ysf
|
||||||
|
90448;DE-Neumarkt;YSF Neumarkt;213.202.228.66;42000;004;http://213.202.228.66/neumarkt/YSFReflector-Dashboard/index.php
|
||||||
|
87939;DE-Notfunk;NotfunkGruppe;78.47.182.224;42001;000;https://notfunk.ysf.vfdb.org/
|
||||||
|
61156;DE-Oberbayern;BM-TG26285;88.198.94.77;42285;003;http://
|
||||||
|
13100;DE-OBERLAUSITZ;YSF Ostsachsen;85.214.61.75;42000;002;https://ysf02.bzsax.de/ysf-ol/
|
||||||
|
09319;DE-Oberpfalz;Region Opf.;78.47.182.224;42009;007;https://oberpfalz.vfdb.org/
|
||||||
|
13111;DE-OBL-RAUM-1;YSF;85.214.61.75;42001;000;http://
|
||||||
|
64445;DE-OWL;XLX508G OWL;185.188.4.15;42001;006;http://ysf.hb9gfx.ch
|
||||||
|
74154;DE-PEGASUS;Multi-Bridge;78.46.11.65;42000;077;https://status.projekt-pegasus.net/
|
||||||
|
20548;DE-PEGASUS2;Test System;78.46.11.65;42001;001;https://status.projekt-pegasus.net/
|
||||||
|
63421;DE-Ruhrgebiet;Ruhrgebiet;144.76.12.90;42000;006;http://dg3yjb.beba.re/YSFReflector
|
||||||
|
10977;DE-Sachsen;BM TG2629;109.104.48.10;42001;001;http://
|
||||||
|
68240;DE-Schwarzwald;#68240 Schwarz;185.75.164.30;42000;008;https://db0vs.de/YSFReflector-Dashboard/index.php
|
||||||
|
55966;DE-Thueringen;Thüringen Ref;195.145.3.97;42000;005;http://44.225.117.67/YSFReflector-Dashboard/
|
||||||
|
95352;DE-Twitterrunde;GW BM TG263333;167.86.110.62;42001;001;https://c4fm.ysfreflector.de/Twitterrunde
|
||||||
|
53414;DE-VFDB;Telekom&Post;78.47.182.224;42000;001;https://vfdb.ysf.vfdb.org/
|
||||||
|
33465;DE_DL-Baltic;Greifswald;81.169.128.244;42001;003;http://ysf.digitalfunk-nordost.de
|
||||||
|
46981;DL1SGP-YSF;Testing;51.75.79.91;42000;000;http://
|
||||||
|
58967;DMRPlus-IT;DMRPlus Italia;185.82.114.247;42000;002;http://ysf.aotnet.it/
|
||||||
|
01579;DO-DOMREP;YSF DRP;172.105.158.111;42000;001;http://hi8k.xreflector.es/
|
||||||
|
30406;DO-YSF-Dom.-Rep.;YSF for HI;190.166.132.207;42000;002;http://arcrica.dyndns.org:8088
|
||||||
|
43499;DPRNS;TH DPRNS;203.150.19.24;42000;005;http://c4fm.dprns.com
|
||||||
|
38035;DRIVETIME;FW Drivetime;71.81.181.30;42061;001;http://ysf.ki5cey.com:45000/
|
||||||
|
53636;DV-Caribbean;DV Multimode;190.213.20.171;42100;001;http://dvcar.9y4c.tk:8080
|
||||||
|
31769;DV-Modems;DV_Modems_YSF_;51.91.78.118;42000;001;http://
|
||||||
|
78427;DX1ARM;DX1ARM-RPT;104.168.176.33;42000;006;http://
|
||||||
|
11096;DX1O-Amsat-PH;DX1O Amsat PH;206.189.146.41;42000;001;http://206.189.146.41
|
||||||
|
06989;DXhunter-SM2;DXhunter SM2;95.217.7.128;42000;001;http://95.217.7.128
|
||||||
|
18196;EA-ARSA;EA2RKS;104.148.41.57;42003;002;http://arsa.xreflector.es/
|
||||||
|
22401;EA-C4FM-Spain;(YCS224);212.237.3.141;42000;060;http://ycs.xreflector.es/
|
||||||
|
73531;EA-CANARIAS;CANARIAS;164.132.96.157;42005;000;http://ysfcanarias.c4fm.es/
|
||||||
|
94533;EA-Distrito-1;Wires X Spain;80.211.102.100;42000;001;http://80.211.102.100
|
||||||
|
62980;EA-Distrito-4;REM Spain YSF;212.237.0.67;42000;015;http://ysfdistrito4.xreflector.es/
|
||||||
|
90182;EA-Distrito-7;RC Veleta;212.237.11.53;42000;001;http://212.237.11.53/html/ysf/
|
||||||
|
18470;EA-EXTREMADURA;EXTREMADURA;51.75.140.10;42002;002;http://ysfextemadura.c4fm.es/ysf2
|
||||||
|
42670;EA-HAMNET;C4FM Spain;80.211.105.70;42000;001;http://80.211.105.70/
|
||||||
|
42670;EA-HAMNET;C4FM Spain;80.211.105.70;42000;001;http://80.211.105.70/
|
||||||
|
55815;EA-SPAIN-21461;MULTIPROTOCOLO;85.255.8.71;42105;002;http://hblinkspain.duckdns.org/YSFReflector
|
||||||
|
17535;EA-TG21468;CANARIAS;164.132.96.157;42003;004;http://ysfhispano.c4fm.es/
|
||||||
|
31977;ECOAMERICA;AB6MM;104.194.206.233;42000;002;http://104.194.206.233/index.php
|
||||||
|
74161;ES-112;EMERGENCIAS;51.77.213.200;42004;000;http://51.77.213.200/ysf4
|
||||||
|
32027;ES-ADER;ASSOCIACIO ADE;62.171.178.202;42000;004;http://digitalader.ddns.net/ysf
|
||||||
|
90884;ES-ADR;Radio Club ADR;51.254.128.134;42003;000;http://51.254.128.134/ysf3
|
||||||
|
66492;ES-AMIRED;YAESU AMIRED;89.38.150.252;42010;000;http://
|
||||||
|
64324;ES-BM-Sevilla;BM21441;104.148.41.57;42002;001;http://fnssevilla.c4fm.es/ysf2
|
||||||
|
96308;ES-CACERES;SEC.LOC.URE CC;51.75.140.10;42000;001;http://ysfcaceres.c4fm.es
|
||||||
|
09059;ES-CANARIAS;Canarias C4FM;185.166.212.132;42000;000;http://185.166.212.132/ysf/
|
||||||
|
32474;ES-CQ-DX;CQ WORLD WIDE;51.77.213.200;42003;001;http://51.77.213.200/ysf3
|
||||||
|
41674;ES-EA-SPAIN;Red WiresX ES;212.237.11.53;42002;001;http://ysfspain.c4fm.es/html/ysf2
|
||||||
|
34018;ES-EA4GAX-YSF;YSF EA4GAX;51.83.78.210;42002;000;http://51.83.78.210/YSF/
|
||||||
|
16172;ES-EA7URC-Link;EA7URC Oficial;193.30.100.102;42000;001;http://
|
||||||
|
99760;ES-EALINK;YSF EALINK;194.182.66.76;42000;000;http://www.fusion.ealink.es/ysf/
|
||||||
|
11650;ES-EL-EJIDO;EL EJIDO SPAIN;80.88.90.73;42000;000;http://80.88.90.73/
|
||||||
|
41996;ES-ELITE;C4FM;51.77.213.200;42002;019;http://51.77.213.200/ysf2
|
||||||
|
96124;ES-ES-ALMERIA;YSF ALMERIA;80.211.1.143;42000;002;http://80.211.1.143/ysf/
|
||||||
|
60725;ES-GOMERA;R5 GOMERA VHF;185.166.212.132;42003;000;http://185.166.212.132/ysf4
|
||||||
|
10069;ES-IBERIA;C4FM;51.77.213.200;42001;001;http://51.77.213.200/ysf
|
||||||
|
14275;ES-MADRID;YSF de Madrid;51.254.128.134;42002;001;http://51.254.128.134/ysf2
|
||||||
|
65531;ES-MARCA;YSF MARCA;80.211.41.147;42000;001;http://80.211.41.147/ysf/
|
||||||
|
49810;ES-PEANUT-YSF;YSF PEANUT;164.132.96.157;42000;007;http://ysfpeanut.c4fm.es
|
||||||
|
15642;ES-REM-SPAIN;YSF Reflector;80.211.163.139;42000;005;http://ysfreflector-rem.spdns.org
|
||||||
|
18044;ES-TECNICO-Y-MAS;URE CT TENERIF;185.166.212.132;42002;000;http://185.166.212.132/ysf3/
|
||||||
|
45904;ES-TENERIFE;YSF<>TG21438;185.166.212.132;42001;001;http://185.166.212.132/ysf2/
|
||||||
|
50246;ES-Zulu-Radio;YSF Zulu Radio;51.254.128.134;42000;003;https://zuluradio.es/ysf/
|
||||||
|
50135;EST-Ref;YSF reflector;95.216.163.65;42000;001;http://ysf.2ip.ee/dashboard
|
||||||
|
06975;Europe-YSF;Europe-YSF;93.240.48.68;42100;004;http://Europe-YSF.spdns.org:81
|
||||||
|
00007;EUROPELINK;Europe link;161.97.73.43;42000;142;http://europelink.pa7lim.nl
|
||||||
|
13029;FI-MIKKELI;Mikkeli YSF;139.162.159.150;42000;003;http://139.162.159.150/ysf/
|
||||||
|
96442;Foxhole;RagChew;52.176.105.136;42000;000;http://ysf.kz4fox.com
|
||||||
|
95198;FR-Centre-France;Centre-France;185.4.78.122;42002;009;http://ysf-centre-france.f1tzo.com:81
|
||||||
|
00645;FR-FON-Gateway;Salon FON GW;185.4.78.122;42000;001;http://ysf-fon-gateway.f1tzo.com:81
|
||||||
|
71173;FR-Franche-Comte;Franche-Comte;51.75.252.197;42000;000;http://
|
||||||
|
30262;FR-International;Salon Interna.;185.4.78.122;42005;002;http://ysf-international-rrf.f1tzo.com:81
|
||||||
|
72173;FR-RIDF;FR Reseau IDF;185.4.78.122;42001;001;http://
|
||||||
|
86886;FR-Room-ZIT;Room F1ZIT;151.80.143.185;42002;035;http://151.80.143.185/zit/YSFReflector-Dashboard/
|
||||||
|
39510;FR-wiresxfrance;Wires-X-France;151.80.143.185;42001;000;http://151.80.143.185/WXF/YSFReflector-Dashboard/index.php
|
||||||
|
83665;FR-YSF-Alpes;Rhone-Alpes;217.182.66.229;42000;000;http://ysf-alpes.f4gve.net
|
||||||
|
13844;FR-YSF-Cappelle;YSF Room F1ZKY;2.59.239.114;42000;000;http://ysf.a3rn.org:2626
|
||||||
|
77805;FR-YSF-Dijon;FR YSF Dijon;185.216.25.140;42000;001;http://
|
||||||
|
58617;FR-YSF-France;Fusion France;87.98.132.205;42000;037;http://ysf-france.fr/
|
||||||
|
64879;FR-YSF-FraWide;France-Wide;5.135.190.184;42010;005;http://ns3294400.ovh.net/YSFDashboard/
|
||||||
|
44708;FR-YSF-HBLink;C4FM HBLink TG;82.64.55.217;42000;000;http://ysf-hblink.dyndns.org:8778/
|
||||||
|
16762;FR-YSF-HDF;Region Nord;51.15.172.24;42001;000;https://srv.hambox.fr/hdf-dashboard/
|
||||||
|
91713;FR-YSF-Limouzi;C4FM Limousin;82.64.55.4;42000;002;http://ysf-limousin.dyndns.org:8787
|
||||||
|
34722;FR-YSF-Linux-fr;Linux French;213.32.19.95;42000;000;http://vps.hambox.fr/ysf-linux-fr/
|
||||||
|
41576;FR-YSF-Nantes;YSF Room F5ZLK;92.222.75.165;42000;003;http://www.f5ore.dyndns.org
|
||||||
|
46353;FR-YSF-Nord;Nord;178.32.163.106;42000;002;http://
|
||||||
|
24703;FR-YSF-NordOuest;XLX933-E;78.206.208.208;42000;001;http://78.206.208.208:8081/YSFReflector-Dashboard/index.php
|
||||||
|
59495;FR-YSF-St-Amand;St Amand (59);51.15.172.24;42000;000;http://
|
||||||
|
04170;FR-YSF-TEST;France-Tests;51.75.133.61;42000;000;http://vps731279.ovh.net/
|
||||||
|
39300;FR-YSF-URGENCE;FR-emcom;78.206.208.208;42021;003;https://fr-emcom.com/
|
||||||
|
87357;GB-2E0ENN-DIRECT;Direct Server;86.181.36.50;42003;000;http://
|
||||||
|
46504;GB-400-Club;400 Club;157.245.45.67;42008;001;https://400club.446em.uk
|
||||||
|
91153;GB-4SQITYSF;4SquareIT YSF;34.89.92.173;42000;000;http://ysf.eilec.com
|
||||||
|
01918;GB-Allstars;Fusion Allstrs;81.133.73.69;42002;005;http://
|
||||||
|
88473;GB-BARC-CLUB;Burnham On Sea;88.97.60.42;42002;003;http://88.97.60.42:8080/
|
||||||
|
42233;GB-BLIND-VETS;Blind Veterans;159.65.16.93;42000;005;http://
|
||||||
|
70507;GB-CelticCluster;YSF-Reflector;85.159.210.162;42000;000;https://ysfref.celticcluster.org
|
||||||
|
88972;GB-CovARS;Coventry ARS;18.130.199.150;42001;001;http://ysf2.g1iul.org.uk
|
||||||
|
23952;GB-CQ-Sussex;All Welcome;84.9.168.216;42002;001;http://
|
||||||
|
19889;GB-Dartmoor-Room;Dartmoor Area;80.229.144.250;42002;001;http://
|
||||||
|
64259;GB-Durham;YSFReflector;34.89.108.212;42000;000;http://
|
||||||
|
91767;GB-Fusion-Kernow;Fusion SW UK;87.117.229.165;43000;001;http://ysf.mb6cc.co.uk
|
||||||
|
08248;GB-GX4MWS-Club;Macc A.R. Club;188.165.209.35;42000;000;http://
|
||||||
|
16437;GB-hideout;xlx201;157.245.45.67;42003;001;https://ukhide.446em.uk
|
||||||
|
57727;GB-HUBNet;Link to HUBNet;5.57.94.92;42000;013;https://hubnetwork.uk/
|
||||||
|
84338;GB-M0OUK-Link;www.OARC.uk;165.22.121.251;42002;003;http://ysf.oarc.uk/
|
||||||
|
54916;GB-MB6RI;YSFR mb6ri.co.;86.132.7.82;42200;001;http://wires-xuk.sytes.net/
|
||||||
|
97576;GB-N.Ireland;YSF N.Ireland;87.117.229.165;42500;002;http://
|
||||||
|
13344;GB-North-West-UK;NWRG;209.250.255.162;42000;006;http://209.250.255.162/
|
||||||
|
58362;GB-NorthWestLink;TG23520;217.46.179.246;42004;001;http://
|
||||||
|
26368;GB-qso365;qso365.co.uk;212.159.79.56;42002;002;http://g6nhu.getmyip.com:8900
|
||||||
|
41012;GB-Sandbox;Testing;88.97.60.42;42003;000;http://88.97.60.42:8090
|
||||||
|
23551;GB-SCOT-MULTI;SCOTLAND MULTI;92.3.117.38;42000;001;http://
|
||||||
|
67256;GB-Smoggie-UK;SMOGGIE LINK;108.61.172.174;42000;004;http://
|
||||||
|
62400;GB-W.Mids;IO82UI;86.148.110.250;42021;001;http://wfrg.ddns.net/
|
||||||
|
06284;GB-WARC;Warrington ARC;109.148.101.52;42000;004;http://
|
||||||
|
93529;GB-WestBerkshire;West Berks UK;62.232.43.186;42000;003;http://m0cuk.uk:8080
|
||||||
|
13322;GB-xlx201b;MultiMode;157.245.45.67;42001;001;https://xlx201b.446em.uk
|
||||||
|
41142;GB-XLX969;Relfector for;142.93.46.36;42000;000;http://xlx969.nwfg.online
|
||||||
|
27617;GB-YORKSHIRE-YSF;YSF Leeds UK;45.58.139.108;42000;001;http://45.58.139.108/
|
||||||
|
23945;GB3TH;Tamworth UK;5.2.112.26;42000;004;http://5.2.112.26
|
||||||
|
77817;GB7SJ;Repeater link;217.46.179.246;42000;006;http://
|
||||||
|
83260;GR-HellasFame;Greek YSF Test;95.179.190.33;42000;002;http://stargate-dmr.net:8080
|
||||||
|
96370;Gr8ter-Detroit;Great Lakes MI;107.141.52.226;42006;001;http://
|
||||||
|
89995;Great-Lakes;Great Lakes Ar;107.141.52.226;42003;001;http://
|
||||||
|
60237;GT-ASL-48455;AllStar Audio;190.148.222.28;42101;001;http://190.148.222.28:8502/index.php
|
||||||
|
36606;GT-Guatemala;Enlace DMR+;104.143.94.48;42142;003;http://104.143.94.48/YSFReflector/YSFHBLink/index.php
|
||||||
|
25419;Guatemala;Link Regional;ysf.tg9aor.net;42000;002;http://
|
||||||
|
47247;HB-C4FM-Basel;Gruppo HB9CSR;212.237.33.114;43000;003;http://212.237.33.114/c4fm/index.php
|
||||||
|
87252;HBLINK-SPAIN;HBLINK SPAIN;85.255.8.71;42000;002;http://hblinkspain.duckdns.org/YSF
|
||||||
|
73821;HCRA-YSF;HCRA Refl;168.235.80.185;42001;001;http://ysf.nt1k.com
|
||||||
|
23667;HELLAS-Zone;YSF Reflector;85.93.91.80;42000;016;http://www.hellaszone.com/index.php/ysf-hellas-zone
|
||||||
|
36039;HK-HAM;YSF<=>454;119.237.142.173;42002;002;http://ysf.852ham.org/
|
||||||
|
56322;HN-HONDURAS;YSF Honduras;104.223.170.236;42000;002;http://ysfhonduras.xreflector.es/
|
||||||
|
01689;HP-PANAMA-HUB;C4FM DMR;179.63.194.94;42000;013;http://hp-panama-hub.c4fmpanama.org/
|
||||||
|
14248;HR-9A-C4FM;9A C4FM HR;35.175.149.169;42000;004;http://35.175.149.169
|
||||||
|
18164;HU-Balaton;YSF Siofok;5.189.162.5;42200;002;http://5.189.162.5
|
||||||
|
49993;HU-HU-TG2162;BM TG2162;185.187.75.192;42300;003;http://brandmeister.hu/ysfref2162/
|
||||||
|
41120;HU-Hungary;BM TG216;185.187.75.192;42100;003;http://brandmeister.hu/ysfref/
|
||||||
|
26973;Hudson-City-NJ;YSF Reflector;192.223.27.159;42000;003;http://ysf.dmrnet.net/ysf
|
||||||
|
52077;IE_YSF_Ireland;Fusion <> DMR;44.155.254.23;42000;004;https://ysf-2724.ei3rcw.ampr.org/index.php
|
||||||
|
14689;Indiana-Link-So;Bridge:IRLP_00;107.155.116.148;42000;008;http://107.155.116.148/ysf
|
||||||
|
96014;IRLP_0070;Bridge to 0070;75.127.13.79;42000;003;http://k5nx.com/YSFdashboard
|
||||||
|
60905;IRLP_0087;Bridge to 0087;192.210.239.5;42000;001;http://k8lrc.crabdance.com/index.php
|
||||||
|
75373;IT-773Cluster;TG222773 - BM;89.46.75.166;42000;003;http://xlx773.iz0rin.it/ysf/
|
||||||
|
92157;IT-APRS-PUGLIA;www.aprspuglia;185.216.27.214;42000;000;http://185.216.27.214/
|
||||||
|
54102;IT-ARI-VINCI;C4FM;80.211.99.134;42000;001;http://80.211.99.134
|
||||||
|
46773;IT-C4FM-ABRUZZO;IT-DMR 22261;5.88.241.47;42001;003;http://ysf-abruzzo.ariroseto.it/ysf
|
||||||
|
17120;IT-C4FM-HBLink-D;Zona1 Piemonte;94.177.173.53;42000;001;http://94.177.173.53/ysf/index.php
|
||||||
|
22201;IT-C4FM-Italy;(YCS222);94.177.187.31;42000;023;http://ycs.grupporadiofirenze.net/ycs/
|
||||||
|
16547;IT-C4FM-LECCE;YSFReflector;80.211.133.104;42000;004;http://c4fm-lecce.ddns.net/index.php
|
||||||
|
16547;IT-C4FM-LECCE;YSFReflector;80.211.133.104;42000;004;http://c4fm-lecce.ddns.net/index.php
|
||||||
|
30483;IT-C4FM-Lodi;Lombardia;94.177.187.40;42000;004;http://ysflodi.iw2gob.it/c4fm/index.php
|
||||||
|
14115;IT-C4FM-PUGLIA;DMR TG PUGLIA;95.248.215.75;42000;002;http://ysfpuglia.iz7gll.it:8888
|
||||||
|
26765;IT-C4FM-ROSETO;IT-DMR 222035;109.239.250.3;42000;002;http://ysf-roseto.ariroseto.it/ysf
|
||||||
|
06901;IT-C4FM-TERAMO;C4FM TERAMO;195.32.87.220;42000;000;http://ysf-teramo.ns0.it/
|
||||||
|
94514;IT-CALABRIA;MP CALABRIA;185.250.144.228;42000;001;http://185.250.144.228/
|
||||||
|
27746;IT-CATANIA;TG22491-BM;91.92.136.252;42000;001;http://91.92.136.252/YSFdash
|
||||||
|
23740;IT-DGT-Zona-0;Rete DGT zona0;185.177.59.221;42000;001;http://185.177.59.221/YSF/
|
||||||
|
47946;IT-Digiland;Italia;82.223.18.138;42000;002;http://82.223.18.138/ysf/index.php
|
||||||
|
58288;IT-GDO-FUSION;C4FM OSSOLA;88.149.167.221;42000;000;http://iz1zpj.duckdns.org
|
||||||
|
76421;IT-GIOIATAURO;#76421;80.211.74.187;42000;005;http://ysf.rcdigital.it
|
||||||
|
26045;IT-GRF-YSF;TUSCANY MULTIP;31.14.142.119;42005;008;http://ysf.grupporadiofirenze.net/ysf_5
|
||||||
|
03832;IT-I0-LAZIO;773RadioGroup;93.186.255.126;42000;005;http://ysf.iz0rin.it/ysf
|
||||||
|
45679;IT-I6-ABRUZZO;IT-I6-ABRUZZO;95.246.180.57;42000;001;http://iz6ouf77.ddns.net/ysf/
|
||||||
|
64599;IT-IQ3CR;ARI Belluno;95.233.192.20;42000;000;http://iq3cr.ddns.net/index.php
|
||||||
|
92365;IT-IS0-Sardegna;Multiprotocoll;51.254.206.201;42000;002;https://ysf.is0.org
|
||||||
|
18255;IT-ITALIA;YSF Italia CIS;185.177.59.166;42000;002;http://
|
||||||
|
18316;IT-ITALY-I2-MI;ITALY-I2-MI;94.33.52.82;42001;002;http://www.iw2hgl.it
|
||||||
|
82021;IT-IU3GMR-YSF;IU3GMR ROOM;95.233.192.20;43000;000;http://iu3gmr.ddns.net/index.php
|
||||||
|
05579;IT-PERAZZA;YSF Reflector;195.128.234.114;42001;000;http://ysf.iz6rnd.it
|
||||||
|
73436;IT-RedNet;Svxlink-net;80.211.239.167;42010;001;http://rednet.iu0krr.it/YSF_2/
|
||||||
|
01444;IT-RNG-NET;GRF CLUSTER;164.68.100.69;42444;001;http://XLX038.grupporadiofirenze.net
|
||||||
|
10885;IT-RNRE-YSF;CROSSLINK;31.14.135.7;42000;001;http://ysf-10885.duckdns.org/ysf/
|
||||||
|
34697;IT-SICILIA;#34697;80.211.84.249;42001;004;http://ysf.digitalsicilia.it
|
||||||
|
12385;IT-TERNI;TERNI TG88;80.211.239.167;42020;001;http://itterni.iu0krr.it/YSF_1/
|
||||||
|
79445;IT-TUSCANY;C4FM-DMR-NXDN;80.211.99.134;42001;001;http://80.211.99.134/YSFTuscany/
|
||||||
|
71249;IT-UMBRIA;YSF UMBRIA;80.211.239.167;42000;001;http://itumbria.iu0krr.it/YSF_3/
|
||||||
|
72983;IT-VENETO;VENETO MULTIP;81.174.3.170;42010;000;http://ysfr.dyndns.org
|
||||||
|
93884;IT-YSF-BRESCIA;CLUSTER BS;212.237.56.10;42000;001;http://ysf.dmrbrescia.it
|
||||||
|
28345;IT-YSF-CUNEO;C4FM ROOM CUNE;82.56.147.96;42000;000;http://
|
||||||
|
43102;IT-YSF-HBLINK;TG 22200;80.211.64.211;42005;001;https://ysf.hblink.it
|
||||||
|
65716;IT-YSF-LUCANIA;YSF LUCANIA;51.255.172.249;42001;000;http://ysf.iz8gur.it/
|
||||||
|
31585;IT-YSF-NORD;ITALY NORD;212.237.9.215;42000;007;http://ysfitalynord.dyndns.biz/ysf/
|
||||||
|
82044;IT-YSFROOM-ITALY;WIRES-X ITALY;80.211.96.39;42000;029;http://ysfroomitaly.iw2gob.it/c4fm/index.php
|
||||||
|
67411;IT-Zona-4;EmiliaRomagna;212.84.32.29;42000;000;http://
|
||||||
|
11881;IT-Zona-9;Sicilia;80.211.62.178;42001;004;http://80.211.62.178/YSF/index.php
|
||||||
|
22211;IT_C4FM-LIGURIA;Reg. Liguria;212.237.8.77;42004;001;http://
|
||||||
|
22236;IT_C4FM-TIGULLIO;Tigullio;188.213.173.69;42000;001;http://c4fm.selfip.com/
|
||||||
|
00012;JAPANLINK;Japan link;207.244.224.170;42000;053;http://japanlink.xreflector-jp.org
|
||||||
|
90219;Jason's-Bar;C4FM Saloon;67.205.134.229;42000;001;http://ysf.w4jmf.com
|
||||||
|
25383;JP-JAPAN;Fusion Japan;122.222.1.50;42000;017;http://c4fm.owari.biz/ysfref/
|
||||||
|
88748;JP-SAKURA-Net;SNWLab Fusion;153.126.179.214;42000;000;http://ysfref.snwlab.net/
|
||||||
|
15742;JP-YSF-NAGOYA;YSF;221.170.106.177;42000;013;http://xrf098.mydns.jp:8030
|
||||||
|
79605;JP-YSF-ONOGORO;YSF;157.65.31.91;42001;000;http://xlx970.onogoro.net/
|
||||||
|
30051;JP-YSFDMR-Net;YSF;211.131.179.106;42000;003;http://ysfreflector.pgw.jp
|
||||||
|
80960;JP_XRF499;YSF;203.137.76.22;42000;001;http://xrf499.xreflector-jp.org/ysf/
|
||||||
|
31983;K8JTK-Hub;DVMIS;149.28.114.219;42001;002;http://YSFReflector31983.K8JTK.org
|
||||||
|
10482;KAPIHAN;kapihan.net;45.77.186.5;42001;007;http://ysf.kapihan.net
|
||||||
|
22856;KAPIHAN2;kapihan.net;144.202.99.113;42001;001;http://ysf2.kapihan.net
|
||||||
|
89902;KB1NE-GROUP;NE Wireless;104.236.92.130;42000;001;http://
|
||||||
|
36745;KN6CLM;Elevated RF;107.172.156.110;42000;001;http://107.172.156.110/
|
||||||
|
92708;konabarbarian;SF Bay Area;54.197.204.105;42000;002;http://
|
||||||
|
48316;KP4GA;Puerto Rico;66.50.96.7;42000;001;http://kp4ga.selfip.com/
|
||||||
|
44444;KR1P;YSF to AllStar;166.70.154.77;42225;003;http://ysf.kr1p.org
|
||||||
|
17077;LaGrandeDigital;www.lagrandefl;99.145.170.193;42000;002;http://digital.lagrandefl.com
|
||||||
|
33461;LATINOS-UNIDO;HISPANIC TG;174.138.36.176;42000;002;http://
|
||||||
|
59933;LibertyNet;W8RFA Free4all;68.60.143.37;42000;000;http://
|
||||||
|
15425;LincsLink;14 characters;86.181.36.50;42002;003;http://
|
||||||
|
07188;LZ0IOS;Repeater Sofia;46.233.56.166;42005;002;http://
|
||||||
|
24597;M1AXM-CQUK;Devon UK;fusion2.m1axm.co.uk;42001;000;http://fusion.m1axm.co.uk
|
||||||
|
53278;MALLORCA;ZONA EA;82.223.122.28;42000;001;http://
|
||||||
|
13827;ME-YSFMontenegro;TG29792;89.188.45.102;43007;004;http://13827ysf.ddns.net
|
||||||
|
74718;MID-MICHIGAN;GREAT LAKES;107.141.52.226;42005;000;http://
|
||||||
|
21505;MIL+VET;Mil and Vets;5.81.41.50;42000;001;http://gb7rn.ddns.net/9111
|
||||||
|
23944;MX-Fusion-Mexico;Fusion Mexico;200.57.9.10;42000;004;http://ysf.ared.org.mx
|
||||||
|
67915;MX-Normex;YSF;208.82.116.113;42000;000;http://208.82.116.113/index.php
|
||||||
|
11714;MY-Malaysia-Net;Malaysia Net;150.129.184.54;42000;002;http://ysf.dmrnet.org/ysf/index.php
|
||||||
|
35767;N1AJW-Test-2;Potpourri;104.153.109.57;42005;003;https:// 104.153.109.57
|
||||||
|
88843;NA9PL_PAAROS;PAAROS.com;159.203.73.99;42000;004;http://NA9PL.com/YSF/
|
||||||
|
77518;NEARC;BM TG 31257;172.245.110.121;42000;001;http://ysf.w0jay.com/YSFReflector-Dashboard/index.php
|
||||||
|
62121;NEMARC-Fusion;NEMARC;3.225.138.100;42003;005;http://k2ej-ysf.ddns.net/
|
||||||
|
45734;NETSWATbg;YSF SWATbg NET;94.26.58.60;42005;000;https://ysf.swat.bg
|
||||||
|
32772;NL-C4FM-Dutch;NL C4FM Dutch;81.169.224.52;42000;002;http://nlc4fmdutch.pa7lim.nl
|
||||||
|
96455;NL-Central;Centraal NL;90.145.156.242;42000;079;http://c4fm.digitalevoice.nl
|
||||||
|
31911;NL-DARES;EMCOMM NL;80.115.153.238;42000;000;http://dares.ham-radio-op.net:8080
|
||||||
|
20070;NL-Hobbyscoop;hobbyscoop.nl;44.137.42.25;42000;004;http://fusion.pi9noz.ampr.org
|
||||||
|
20431;NL-Limburg;Goojundaag LB;37.97.194.88;42002;001;http://limburg.is-very-nice.org
|
||||||
|
73238;NL-Noord;test reflector;44.137.87.82;42000;002;http://44.137.87.82/index.php
|
||||||
|
63539;NL-Oost;test reflector;44.137.87.83;42000;002;http://44.137.87.83/index.php
|
||||||
|
59819;NL-PA0ROB;test nlx204;82.171.119.45;42004;000;http://nlpa0rob.ddns.net/
|
||||||
|
01966;NL-PD4MM;Marcel QPO;80.115.153.238;42004;001;http://pd4mm.nl
|
||||||
|
73443;NL-PI1DAF;Multi Repeater;86.80.221.107;42000;002;http:/pd0poh.ddns.net
|
||||||
|
91665;NL-RNLMC;Marine Corps;95.111.246.149;42001;001;http://Marines.Ham-Radio-OP.net
|
||||||
|
63234;NL-TechTalk;204_Z - TG2045;82.171.119.45;42002;002;http://nltechtalk.ddns.net
|
||||||
|
71117;NL-TEST;Dutch test;173.249.54.49;42000;002;http://ysftest.pa7lim.nl
|
||||||
|
76591;NL-XLX204X;Multi Mode [X];82.171.119.45;42003;002;http://nlxlx204x.ddns.net/
|
||||||
|
44919;NO-General;Norwegian chat;80.89.46.242;42000;002;http://ysf.hamlabs.no/ysf/index.php
|
||||||
|
21302;North-Mich;W1WRS repeater;47.224.93.95;42002;002;http://192.168.1.12
|
||||||
|
67703;Northern-NH-ASL;US NNHASL;72.73.78.92;42000;001;https://nhhub.wordpress.com/
|
||||||
|
33156;NV-Bridge;Fernley, NV;71.89.225.19;42000;000;http://
|
||||||
|
51561;NZ-Ashburton;Repeater;114.23.212.119;42000;008;http://zl4rx.co.nz:89
|
||||||
|
59115;NZ-Canterbury-NZ;Wires-X <<>> B;124.197.62.162;42050;002;http://canterburydigitalreflectors.hopto.org
|
||||||
|
62078;NZ-Christchurch;South Island -;124.197.62.162;42000;001;http://xlx530.hopto.org/YSF
|
||||||
|
75161;NZ-ROAR-NZ;Rotarians ARNZ;203.86.194.92;42000;001;http://www.xlx299.nz/ysf/
|
||||||
|
52755;NZ-Talk;Kiwi Link;123.255.62.27;42000;001;http://nz-talk.ddns.net:89
|
||||||
|
29073;NZ-Whangarei;ZL1AMK YSF;218.101.105.192;42000;001;http://zl1amk.ddns.net:85
|
||||||
|
33191;NZ-YSF-Reflector;NZ Reflector;114.23.212.119;43000;001;http://zl4rx.co.nz:88
|
||||||
|
89797;NZ-YSF-XLX287;ysf.zl2wl.nz;45.32.90.50;42000;001;http://ysf.zl2wl.nz
|
||||||
|
07338;NZ-YSF-XLX750;http://www.xlx;203.86.206.49;42001;002;http://ysf.xlx750.nz
|
||||||
|
72753;Oakland;W6OAK;45.77.188.74;42000;001;http://ysf.w6oak.org/
|
||||||
|
40557;Ohio-Link---LGLG;OHIO-LINK;209.190.4.10;42000;047;http://ysf.glorb.com
|
||||||
|
72170;openGD77;openGD77;128.199.76.58;42000;001;http://128.199.76.58/
|
||||||
|
52792;Orobie-Reflector;EchoLink Refle;80.211.131.80;42000;002;http://ysf-dagobah.hblink.it/
|
||||||
|
15639;Ostsee;Backup DL5CG;91.66.81.13;42001;001;http://dl5cg.ddns.net/ysf
|
||||||
|
23020;Ottawa-Ont;Canada Link;184.175.49.98;42000;003;http://ysf-ottawa.ddns.net
|
||||||
|
08344;PA-ysf-hp3icc;Ysf Chiriqui;190.141.113.82;42000;007;http://ysf-hp3icc.ddns.net/
|
||||||
|
99999;Parrot;Parrot;137.226.79.115;42020;000;http://
|
||||||
|
79383;PH-BISDAK;Bisayang Dako;45.79.92.86;42002;001;http://xlx.dmrphilippines.network/ysfbisdak
|
||||||
|
59008;PH-DX1AFP;PHILCCOM;167.99.190.123;42100;002;http://167.99.190.123/dx1afp/index.php
|
||||||
|
78258;PH-DX1PAR;DX1PAR;178.128.216.38;42100;012;http://
|
||||||
|
19751;PH-DX1WPI;DX1WPI;167.99.190.123;42000;001;http://167.99.190.123/index.php
|
||||||
|
18808;PH-DX2ACV;MAHARLIKA;108.61.216.100;42030;005;http://ph-dx2acv.ddns.net
|
||||||
|
71972;PH-DX7NRD;NORAD7;140.82.14.24;42002;001;http://
|
||||||
|
10707;PH-DX9RAG-FDCCU;PH Davao-Cotab;149.28.76.10;42000;001;http://dx9rag-n0mis.ddns.net
|
||||||
|
09543;PH-MAHARLIKA;MAHARLIKA;149.28.94.53;42100;001;http://149.28.94.53/index.php
|
||||||
|
43437;PH-WMG-ZAM;WMG;67.205.154.243;42000;004;http://
|
||||||
|
08318;PH-YSF-DX3NE;YSF-DX3NE;8.3.29.153;42000;002;http://dx3ne.ddns.net
|
||||||
|
35328;PIJALNIA-PIWA;OPIS PIJANY;64.53.214.179;42005;000;http://64.53.214.179
|
||||||
|
25393;PL-4280;YSF/DMR/DCS132;155.133.14.66;42031;001;https://brandmeister.network/?page=lh&DestinationID=260080
|
||||||
|
61266;PL-BRIDGE;Poland BRIDGE;91.197.227.13;42026;000;http://ysfbridge.pzk.pl/
|
||||||
|
68368;PL-HBLink;HBLink Polska;80.211.208.227;42080;001;https://ysf.hblink.pl
|
||||||
|
22538;PL-Kutno;Kutno;77.55.209.188;42078;001;https://ysf.hblink.kutno.pl/
|
||||||
|
74359;PL-Local;Local;91.201.88.18;42234;000;http://
|
||||||
|
29114;PL-POLAND;YSF PL POLAND;80.211.251.171;42025;016;http://
|
||||||
|
15495;PL-POLSKA;POLSKA WIRESX;155.133.14.66;42026;008;http://
|
||||||
|
55546;PL-Silesia;Poland Silesia;91.197.227.13;42003;000;http://ysfsilesia.pzk.pl/
|
||||||
|
82068;PL-SLASK;Regionalna;91.201.88.18;42237;001;http://
|
||||||
|
53245;PL-SP1;YSF SP1;155.133.14.66;42041;000;http://ysf016.wiresx.pl:8081/sp1/
|
||||||
|
12508;PL-SP2;YSF SP2;155.133.14.66;42042;000;http://ysf016.wiresx.pl:8081/sp2/
|
||||||
|
02328;PL-SP3;YSF SP3;155.133.14.66;42043;000;http://ysf016.wiresx.pl:8081/sp3/
|
||||||
|
48598;PL-SP4;YSF SP4;155.133.14.66;42044;000;http://ysf016.wiresx.pl:8081/sp4/
|
||||||
|
45300;PL-SP5;YSF SP5;155.133.14.66;42045;000;http://ysf016.wiresx.pl:8081/sp5/
|
||||||
|
92967;PL-SP6;YSF SP6;155.133.14.66;42046;000;http://ysf016.wiresx.pl:8081/sp6/
|
||||||
|
92078;PL-SP7;YSF SP7;155.133.14.66;42047;000;http://ysf016.wiresx.pl:8081/sp7/
|
||||||
|
71372;PL-SP8;YSF SP8;155.133.14.66;42048;000;http://ysf016.wiresx.pl:8081/sp8/
|
||||||
|
78984;PL-SP9;YSF SP9;155.133.14.66;42049;000;http://ysf016.wiresx.pl:8081/sp9/
|
||||||
|
38691;PL-SR4H;SR4H-ROOM;91.244.185.128;42000;001;http://
|
||||||
|
40464;PL-SR7MK;Swiety Krzyz W;155.133.14.66;42024;001;http://ysf016.wiresx.pl:8081/sr7mk/
|
||||||
|
40594;PL-SR8DEF;Debica;155.133.14.66;42033;001;http://
|
||||||
|
78099;PL-SR8FWD;Wlodawa WiresX;155.133.14.66;42030;001;http://sr8fwd.wiresx.pl
|
||||||
|
79009;PL-SR8K;Dubiecko;155.133.14.66;42032;002;http://ysf016.wiresx.pl:8081/sr8k/
|
||||||
|
91407;PL-SR8LUF;Lublin;155.133.14.66;42028;001;http://ysf016.wiresx.pl:8081/sr8luf/
|
||||||
|
87318;PL-SR8UVC;Chotylow;155.133.14.66;42034;001;http://
|
||||||
|
54644;PL-SR8UWD;Wlodawa YSF;155.133.14.66;42027;001;http://sr8uwd.wiresx.pl
|
||||||
|
64506;PL-SR8WD;Wlodawa;155.133.14.66;42029;001;http://ysf016.wiresx.pl:8081/sr8dmr/
|
||||||
|
83600;PL-SR9DBN;Myslowice;91.201.88.18;42235;001;http://
|
||||||
|
39816;PL-SR9DX;Bytom;85.11.120.150;42223;001;http://www.dx.katowice.pl
|
||||||
|
52742;PL-WARMIA-MAZURY;Elblag;109.241.51.213;42055;003;http://sp2wlf.tplinkdns.com/
|
||||||
|
09815;PL-XLX132;D-Star Gateway;91.203.55.87;42001;002;http://xlx132.dstar.radom.pl/ysf/
|
||||||
|
80986;PL-YSF260;BM TG260;155.133.14.66;42035;003;http://ysf016.wiresx.pl:8081/260/
|
||||||
|
37358;PLUG;The Philly LUG;173.12.0.169;42000;003;http://ham.daotechnologies.com/ysf-dashboard
|
||||||
|
92044;PR-KP4CA;Boriken DMR Ne;64.154.38.101;42000;003;http://boriken-ysf.ddns.net/
|
||||||
|
02986;PT-YSF009;C4FM-Portugal;109.71.44.237;42000;002;http://c4fm.from-ct.com/
|
||||||
|
45742;PT-YSF012;BM2682-Link;194.38.140.204;42100;002;http://ysf012.from-ct.com
|
||||||
|
52639;PT-YSF268;BM2682-Link;194.38.140.204;42125;001;http://ysf268.from-ct.com
|
||||||
|
15461;PT-YSF903;BM2682-Link;194.38.140.204;42150;001;http://ysf903.from-ct.com
|
||||||
|
09658;PT-YSF915;BM2682-Link;164.68.117.231;42000;001;http://ysf915.from-ct.com
|
||||||
|
30270;PUERTO-RICO;ENLACE BORICUA;162.243.169.90;42000;004;http://kp4msr.praredn.org
|
||||||
|
45591;QUAHOG-NETWORK;BM-TG-31445;45.77.213.187;42000;002;http://ysf.ridigitallink.net
|
||||||
|
95623;R.C.-AMIRED---C4;WiresX CATALUN;89.36.215.181;42000;016;http://89.36.215.181
|
||||||
|
64150;Radio-Oasis;ham radio;50.82.207.97;42000;000;http://50.82.207.97/dashboard
|
||||||
|
66265;Randin;RCRG (Ki4eki);75.145.198.42;42000;001;http://
|
||||||
|
23531;RAYNET-UK;RAYNET-UK_YSF_;51.91.78.118;42001;007;http://23531.raynet-uk.net/
|
||||||
|
31444;RI-DIGITAL-LINK;BM-TG-31444;155.138.201.254;42000;002;http://c4fm.ridigitallink.net/
|
||||||
|
43537;RO-YO-EmCom;EmCom Romania;89.33.44.100;42112;003;http://yo2loj.ro/emcom
|
||||||
|
03435;RO-YSF-BM-226;YSF BM TG226;89.33.44.100;42002;003;http://ysf2bm.hamnet.ro
|
||||||
|
95093;RO-YSF-DMR-YO-W;YSF DMR+ Link;89.33.44.100;42007;005;http://ysf2dmr.hamnet.ro
|
||||||
|
75904;RRARE-OKTX;Red RiverOK/TX;18.218.160.231;42000;002;http://18.218.160.231/index.php
|
||||||
|
40387;RU-DMR;TG2503;188.42.30.175;42000;004;https://ysf.dstar.su/dash/
|
||||||
|
39544;RU-KAVKAZ;North Caucasus;37.18.35.2;42000;003;http://kavkaz.qrz.ru/YSF/
|
||||||
|
09020;RU-KRSNDR;Krasnodar;176.192.125.46;42002;001;http://c4fm.tk/YSF3/index.php
|
||||||
|
67143;RU-MAYKOP;Maykop;176.192.125.46;42005;001;http://176.192.125.46/YSF5/
|
||||||
|
27797;RU-MOSCOW;MOSKWA;128.0.132.69;42000;003;http://128.0.132.69
|
||||||
|
31022;RU-POCTOB;Rostov-Don;83.69.77.96;42000;001;http://c4fm.xyz/our-c4fm-wires-x-room.php
|
||||||
|
11193;RU-RADIOCULT;YSF;91.247.248.67;42000;001;http://ysf.radiocult.su:8083
|
||||||
|
17383;RU-SCANNER;Russia;176.192.125.46;42000;004;http://176.192.125.46/YSF/
|
||||||
|
58312;RU-SHAKHTY;Shakhty;176.192.125.46;42004;001;http://c4fm.tk/YSF4/
|
||||||
|
16530;RU-VLGDNK;Volgodonsk;176.192.125.46;42001;002;http://176.192.125.46/YSF2/
|
||||||
|
25641;RUDIVO;YSF;194.182.85.217;42000;008;http://194.182.85.217/
|
||||||
|
75294;RV-rpt-group;Rogue Valley;71.94.243.50;42001;001;http://
|
||||||
|
23611;SAT-TRAC;TG 31683;192.99.245.120;42001;003;http://192.99.245.120
|
||||||
|
40208;SC-Scotland;Scottish YSF;13.69.14.204;42000;018;http://c4fm.dvscotland.net
|
||||||
|
02868;SCAN-i-546;SCAN-i 546;149.28.202.133;42001;006;http://scanintl.spdns.org
|
||||||
|
82040;SD_HUB;DMR-ALLSTAR;155.138.225.161;42000;003;http://ysfreflector.sddstar.com
|
||||||
|
93753;SE-SE0O_CROSS;YSF>DMR TG2400;31.211.216.13;42000;002;http://
|
||||||
|
06000;SE-SM4-SE-01302;Fusion to SM4;94.234.176.231;42000;002;http://94.234.176.231:3180
|
||||||
|
80858;SE-SWEDEN-HUB;Wires-X, DMR;95.216.151.253;42000;007;http://ysf.forthmeijer.com
|
||||||
|
69673;SE-TG240240-Link;TG240240 Link;95.216.197.75;42000;003;http://ysf.brandmeister.se
|
||||||
|
65461;SE-Virginia;Tidewater;71.120.150.136;41500;001;http://71.120.150.136
|
||||||
|
30217;SEOH-YSFLINK;SEOH YSFLINK;44.70.25.177;42002;002;http://k8khw.dyndns-remote.com
|
||||||
|
43075;SE_SwedenLink_28;SE_SwedenLink_;94.254.105.236;42000;002;http://ysfsl.c4fm.se
|
||||||
|
16390;SG-YSF-V2;SINGAPORE-YSF;14.102.146.160;42002;001;https://ysf.lucifernet.com/
|
||||||
|
48857;SI-Slovenia;YSF>DMR TG293;188.230.203.194;42000;004;http://xlx511.ddns.net:46193/index.php
|
||||||
|
62716;SI-Slovenia2;YSF Slovenia;109.182.208.84;42000;002;http://router.dyn.ts.si:38401/
|
||||||
|
98269;SK-B.Bystrica;YFS Slovak;178.143.62.29;42000;002;http://ysfreflektor.koren.network:8080
|
||||||
|
83776;SKYNET-YSF;SKYNET/C4FM;167.172.17.107;42000;001;http://c4fm37040.ddns.net/
|
||||||
|
28735;SMS1;SMS backup;167.99.135.20;42000;000;http://
|
||||||
|
29961;SNARS;SNARS TG31328;162.248.93.209;42000;001;http://ysf.snars.net
|
||||||
|
27688;SO-Oregon-rc;SO RC;71.94.243.50;42000;002;http://blahdiadem.hopto.org
|
||||||
|
80956;SuperARC;Phoenix, AZ;69.71.61.230;42000;002;http://
|
||||||
|
77982;SZ790;TG46073;58.250.171.29;50790;001;http://
|
||||||
|
08580;tgwells-ysf;tgwells-ysf;18.191.186.57;42000;000;http://tgwells.com
|
||||||
|
40538;The-Missing-Link;Inland Empire;76.174.207.37;42003;001;http://ysfkc6gwf.ddns.net
|
||||||
|
45800;TheHideoutCrew;Yeet;69.164.222.140;42002;004;http://69.164.222.140/
|
||||||
|
31110;Tipton-ARS;Tipton Co, TN;207.65.47.88;42000;000;http://
|
||||||
|
22539;TN-NETDA;TN-NETDA;155.138.237.140;42040;006;http://
|
||||||
|
44212;TNARES-EAST;TNARES-EAST;155.138.237.140;42110;001;http://
|
||||||
|
07683;TNARES-MID;TNARES-MID;155.138.237.140;42120;000;http://
|
||||||
|
76787;TNARES-STWIDE;TNARES-STWIDE;155.138.237.140;42100;004;http://
|
||||||
|
76805;TNARES-TAC-E;TNARES-TAC-E;155.138.237.140;42140;000;http://
|
||||||
|
67313;TNARES-TAC-M;TNARES-TAC-M;155.138.237.140;42150;000;http://
|
||||||
|
47567;TNARES-TAC-W;TNARES-TAC-W;155.138.237.140;42160;000;http://
|
||||||
|
48064;TNARES-WEST;TNARES-WEST;155.138.237.140;42130;000;http://
|
||||||
|
43513;TROJMIASTO;Poland Tricity;195.140.190.58;42000;000;http://ysftricity.ham-dmr.pl/
|
||||||
|
30743;TW-HAMTALK;C4FM @HAMTALK;118.150.164.96;42000;004;http://www.hamtalk.net/ysfr
|
||||||
|
26112;TW-YSF338;YSF@TYARC;114.32.215.38;42000;002;http://ysftw338.ddns.net
|
||||||
|
39369;UA-Azimuth;Azimuth-club;193.27.208.38;42000;001;http://193.27.208.38
|
||||||
|
55467;UA-Dnipro;DMR TG25504;5.255.33.253;42004;001;http://
|
||||||
|
57835;UA-Emergency;DMR TG2559;5.255.33.253;42003;001;http://
|
||||||
|
46588;UA-Exolink;DMR/C4FM;5.255.33.253;42000;001;http://
|
||||||
|
37683;UA-Kyiv-city;DMR TG25501;5.255.33.253;42001;001;http://
|
||||||
|
82255;UA-LVOV-YSF;DMR TG25514;134.249.141.148;42002;001;http://ysf82255.uw0wu.ml
|
||||||
|
50847;UA-Mykolayiv;DMR TG25515;5.255.33.253;42005;001;http://
|
||||||
|
85106;UA-Odesa;DMR TG25516;5.255.33.253;42002;001;http://
|
||||||
|
88338;UA-UA-Ref;YSF UA reflect;95.216.163.65;42100;001;http://ysf.2ip.ee/dashboard2
|
||||||
|
66216;UA-Zakarpatia;DMR TG25507;142.91.158.199;42002;001;http://xrf255.reflector.up4dar.de/ysf/index.php
|
||||||
|
13201;UK-DVMEGA;DVMEGA CHAT;212.237.34.32;42000;002;http://c4fm.dvmega.co.uk
|
||||||
|
83087;UK_YSF_BM_UK;UK_Ref_DN_ONLY;87.117.229.171;42000;012;http://
|
||||||
|
20087;UNIVERSAL-TWR;SE MI DIGITAL;107.141.52.226;42001;000;http://
|
||||||
|
74940;Unix;Unix system ad;185.244.130.88;42002;000;http://ysf.sysprotect.eu
|
||||||
|
74940;Unix;Unix system ad;185.244.130.88;42002;000;http://ysf.sysprotect.eu
|
||||||
|
65416;URSALAMANCA;URE SALAMANCA;31.14.139.112;42000;000;http://31.14.139.112
|
||||||
|
51380;Uruguay-YSF;UY YSF;201.217.131.107;42000;006;http://cx4ae.no-ip.org
|
||||||
|
29727;Uruguay-YSF-Char;Uruguay C4FM;201.217.131.106;42000;001;http://ysfuruguay.ddns.net
|
||||||
|
59210;US-1st-Resp;TGIF TG 450;157.245.247.7;42000;003;http://
|
||||||
|
51123;US-31150;Hawaii;149.28.82.52;42000;005;http://149.28.82.52/YSF
|
||||||
|
44693;US-42001hamshack;paducah;142.93.53.85;42000;000;http://
|
||||||
|
09344;US-AC1KV;AC1KV Rptr;140.82.14.24;42000;001;http://
|
||||||
|
75056;US-AF4Y;AF4Y Refelctor;107.191.51.252;42000;006;http://
|
||||||
|
61482;US-AfterNetK4DJL;AfterNet K4DJL;96.47.95.121;42003;001;http://afternet.alabamalink.info
|
||||||
|
21988;US-AggielandLink;Aggieland Link;71.252.210.227;42000;000;https://www.aggielandlink.com/Dashboard
|
||||||
|
57882;US-AK4LT;The Fire Ants;51.79.69.216;42000;002;http://
|
||||||
|
75021;US-AMLEG-NCKYP42;KB4KY Repeater;67.215.222.30;42000;000;https://tinyurl.com/y5tlg93t
|
||||||
|
11689;US-Amsat;Satellite Ops;149.28.241.59;42000;017;http://149.28.241.59
|
||||||
|
55223;US-AZ-SEOC;Oro Valley ARC;69.244.58.8;42001;001;http://
|
||||||
|
36252;US-AZ-TUCSON;Oro Valley ARC;69.244.58.8;42000;003;http://
|
||||||
|
79496;US-Beards-Den;Open Room;68.4.184.234;42200;003;http://k6tvb.isa-geek.com:8888/index.php
|
||||||
|
00081;US-Berks-County;Pennsylvania;24.152.248.205;42042;000;http://
|
||||||
|
85490;US-BM-TG-31083;CO Severe WX;54.191.50.212;42050;001;http://54.191.50.212/ysf2
|
||||||
|
99256;US-BM-TG-31088;Colorado HD;54.191.50.212;42005;005;http://54.191.50.212
|
||||||
|
97501;US-BRRO;688;54.89.57.238;42000;001;http://xlx688.ab8m.com/
|
||||||
|
44742;US-CARA;CARA Group;45.79.93.167;43000;003;http://xlx.cara.nu/ysf
|
||||||
|
25662;US-Carlisle,PA;N3JUO;174.49.161.236;42002;000;http://ysfcvpa.hopto.org
|
||||||
|
94390;US-Central-AL;WiresX 21713;99.46.36.113;8001;006;http://
|
||||||
|
49235;US-CKRG;Central Kansas;100.25.76.93;42000;004;http://
|
||||||
|
44977;US-CNJHAM;Link to XLX020;52.23.107.220;42000;004;http://ysfreflector.kb2ear.net
|
||||||
|
99032;US-CO-KF0ABA;NOCO Ragchew;73.34.87.216;42000;000;http://ysfnode.jmrust.com/
|
||||||
|
53927;US-CO-WE0FUN;Fun Machine Co;199.59.31.9;42000;003;http://c4fm.we0fun.com
|
||||||
|
23160;US-ColoradoMega;CO Transcode;74.91.118.134;42000;011;http://ysf.parkerradio.org/ysf
|
||||||
|
71941;US-Connecticut;N1AJW-Test;192.223.31.208;42000;000;https://192.223.31.208
|
||||||
|
62608;US-Connecticut-1;CT Chat;192.223.31.208;42010;001;http://192.223.31.208
|
||||||
|
91800;US-CQ-California;CAL-YSFtoWires;104.218.36.162;42001;004;http://ysfxlx.dyndns.org
|
||||||
|
62208;US-CQ-NODAK-A-ZX;CQ NorthDakota;18.217.188.43;42000;006;http://ysf.cqnodak.com
|
||||||
|
73884;US-craftwerx;team-craftwerx;67.160.251.224;42511;002;http://
|
||||||
|
46301;US-CW-Ops;CW Academy/CW;107.182.34.107;42002;002;http://cwopsysf.dyndns.org
|
||||||
|
50279;US-DUDE-Link;DUDE XLX106;69.163.163.88;42000;008;http://xlx106.dudetronics.com
|
||||||
|
38542;US-DX-HUB;US DX-HUB;45.32.193.214;42000;000;http://45.32.193.214/YSF
|
||||||
|
40422;US-DX3CA-OMG;OLD MAN GROUP;149.248.6.211;42000;007;http://dx3caomg.tqhhc.com
|
||||||
|
23957;US-DX3L-YSF;RIZAL-LATITUDE;140.186.202.60;42000;004;http://latitudeysf.ddns.net
|
||||||
|
11102;US-DXLINKSYSTEM;DX-LINK SYSTEM;155.138.236.26;42000;003;http://xlx749ysf.drgnz.com
|
||||||
|
43953;US-East-Pipeline;Link;75.68.143.156;42007;009;http://
|
||||||
|
88084;US-EcosDelCoqui;Conociendo Ami;66.223.212.215;42002;003;http://ecosdelcoqui.kl4ne.net
|
||||||
|
88023;US-EOH-GWY-HUB;X Hub/Bridge;64.154.38.103;42000;001;http://29999.link/YSF
|
||||||
|
12567;US-ERDN;ERDN YSF Ref;173.208.200.179;42000;001;https://ysf.kc1awv.net/index.php
|
||||||
|
12567;US-ERDN;ERDN YSF Ref;173.208.200.179;42000;000;https://xlx337.kc1awv.net
|
||||||
|
13458;US-FACSchool-ARC;New Iberia, LA;98.191.70.50;42000;002;http://longwire.net:8088
|
||||||
|
11665;US-Farmers;Farm Talk;67.140.163.107;42010;001;http://
|
||||||
|
37921;US-FLORIDA;FL REFLECTOR;76.109.114.132;42000;002;http://
|
||||||
|
04154;US-Georgia;Georgia USA;45.32.223.140;42000;000;http://ysf-ga.ka7utd.com/
|
||||||
|
99602;US-GulfBeach-FL;Gulfcoastradio;50.116.24.240;42000;006;http://50.116.24.240
|
||||||
|
36271;US-GulfCoast-FL;Gulfcoastradio;18.205.34.190;42000;000;http://ysf36271.ddns.net
|
||||||
|
01896;US-HarleyHangout;DMR_AllStar;38.133.241.80;42000;002;http://
|
||||||
|
93877;US-Houston-Texas;Houston Texas;23.30.91.29;42000;002;http://ysf.cognetic.com
|
||||||
|
01037;US-HRCC-LINK;HRCC LINK;209.182.218.92;42001;007;http://ysf.hrcc.link
|
||||||
|
02931;US-Hudson-NY;Upstate NY;24.105.206.243;42002;006;http://keetz.mynetgear.com
|
||||||
|
04400;US-HXO;HXO 31325;162.248.93.209;42005;001;http://ysf.hxo.radio
|
||||||
|
83132;US-Illinois-Link;Illinois Link;74.208.235.115;42000;016;http://74.208.235.115/YSFReflector-Dashboard/
|
||||||
|
02500;US-IL_NGRMARC;NG Radio Club;73.74.148.160;42000;001;http://
|
||||||
|
80060;US-JAXBCH-Link;JAX BCH Link;66.177.51.38;42000;000;http://
|
||||||
|
68798;US-JerryNet;YSF Reflector;18.216.66.72;42000;002;https://ysf.ad6dm.net
|
||||||
|
01295;US-JOTA-1;9071;104.200.25.53;42001;001;http://
|
||||||
|
27662;US-JOTA-2;9072;104.200.25.53;42002;000;http://
|
||||||
|
02177;US-K3IHI-RPT;YSF TG;131.106.30.132;42000;003;http://
|
||||||
|
05944;US-K4LPD-YSF;YSFReflector;134.209.44.53;42000;001;http://k4lpd.luisra369.com
|
||||||
|
32343;US-K4NWS;ALERT-K4NWS;34.219.110.119;42000;001;http://ysf.alert-alabama.org/YSFReflector-Dashboard/
|
||||||
|
37581;US-K7SFQ-YSF;K7SFQ YSF Ref;50.39.137.114;42000;000;http://
|
||||||
|
12345;US-K9EQ-----DYEF;Development;167.99.150.253;42004;000;http://
|
||||||
|
81734;US-K9POL;US K9POL;104.238.162.162;42000;000;http://
|
||||||
|
12479;US-Kansas-City;WIRES-X MOKAN;99.169.52.241;42000;006;http://www.salaman.org/ysf
|
||||||
|
08398;US-Kansas3120;ks-dmr.net;129.130.229.11;42030;004;http://129.130.229.11:15426/3120/
|
||||||
|
77661;US-KB1NYT-YSF;Swansea, MA;24.218.238.119;42000;002;http://kb1nyt.hopto.org:8091/ysf
|
||||||
|
57046;US-KB4OVL;Indian Rvr FL;69.137.164.8;42000;001;http://
|
||||||
|
04438;US-KC2RC;KC2RC W-X room;3.82.236.213;42000;004;http://3.82.236.213/
|
||||||
|
69140;US-KE4SCS;KE4SCS Rptr;155.138.222.156;42000;000;http://155.138.222.156
|
||||||
|
92516;US-Kentucky-LARC;Local Rag Chew;161.35.141.182;42000;001;http://
|
||||||
|
43114;US-KENTUCKY-OWWZ;W4IOD Test Ref;76.244.26.57;42000;002;http://
|
||||||
|
40806;US-KENTUCKY-WXGC;W4IOD Repeater;167.99.150.253;42002;008;http://mnwis-ysf.ddns.net/W4IOD.php
|
||||||
|
02824;US-KI5HXE;KI5HXE;157.245.138.123;42000;000;http://
|
||||||
|
03772;US-KitsapLink;Kitsap Talk;98.125.77.141;42810;000;http://
|
||||||
|
40438;US-KK4OVW-TN-YTR;White House T;104.56.140.47;42000;001;http://
|
||||||
|
25956;US-KM4EDS;Blount County;96.47.95.121;42002;003;http://danny.alabamalink.info
|
||||||
|
93262;US-KO4AXW-7;Richmond, Virg;142.93.202.44;42000;000;http://ko4axw-ysf.ddns.net/index.php
|
||||||
|
29162;US-Ktown;Los Angeles Kt;104.174.35.78;42002;000;https://192.168.0.40
|
||||||
|
43310;US-KU0S;Test Bridged Y;76.196.111.153;42000;002;http://ysf.ku0s.com/dashboard/
|
||||||
|
21511;US-KV4S;KV4S;96.47.95.121;42004;002;http://kv4s.alabamalink.info
|
||||||
|
44967;US-Ky-Hood-Rats;Hood Rats Club;67.140.163.107;42020;001;http://kyhoodrats.ddns.net
|
||||||
|
97215;US-LEO-ARC;LEO ARC;74.91.116.36;42000;006;http://74.91.116.36
|
||||||
|
65982;US-LHSREF;LHS Podcast;67.224.119.40;42000;001;http://reflector.k5tux.us/Dashboard
|
||||||
|
01240;US-LosAngeles;SocalPinoy;47.180.104.101;42003;002;http://socalpinoy.ddns.net
|
||||||
|
44428;US-Magnolia-Link;Magnolia Wires;76.107.175.206;42042;001;http://
|
||||||
|
87168;US-Marana-AZ;Oro Valley ARC;69.244.58.8;42002;001;http://
|
||||||
|
68928;US-MID-TN-RM;Middle Tenn;104.56.140.47;42001;000;http://
|
||||||
|
42592;US-MissingLynk;MissingLynk;104.248.12.84;42000;001;http://104.248.12.84
|
||||||
|
21493;US-MNWIS----RDNT;21493;167.99.150.253;42000;018;http://mnwis-ysf.ddns.net
|
||||||
|
77445;US-Muletown-TN;Maury County;104.237.132.247;42000;002;http://104.237.132.247
|
||||||
|
43210;US-MVARC----KBNA;MVARC Idaho;167.99.150.253;42003;004;http://
|
||||||
|
92059;US-N1TVI;Dew-Cave;159.65.189.183;42001;000;http://n1tvi.net:8081
|
||||||
|
93958;US-N4KWT-ALPHA;Louisville, KY;23.126.8.172;42002;000;http://23.126.8.172/index.php
|
||||||
|
08035;US-N4KWT-BRAVO;Louisville, KY;23.126.8.173;42000;000;http://23.126.8.173/index.php
|
||||||
|
59680;US-N8RQJ-RPT;WiresX 49602;157.245.93.169;42000;001;http://157.245.93.169
|
||||||
|
90882;US-NACS;C4FM;68.232.234.210;42000;001;http://
|
||||||
|
54635;US-Nashville-HUB;Nashville-HUB;34.235.143.37;42000;002;http://
|
||||||
|
06177;US-NC-440-Link;NC 440 Link;172.104.214.72;42000;001;http://ysf.msmts.com
|
||||||
|
32398;US-NE-Oregon;Oregon Room;73.25.190.37;42000;002;http://
|
||||||
|
56521;US-Nebraska_Hub;D-Star DMR YSF;71.8.194.163;42000;003;http://ysf.ham-radio-op.net
|
||||||
|
77204;US-Nevada;Nevada TG3132;162.248.93.209;42001;002;http://ysf.snars.net/nevada
|
||||||
|
93319;US-NgakNgak;Ngakngakan YSF;45.79.92.86;42000;004;http://xlx.dmrphilippines.network/ysf
|
||||||
|
58333;US-NOMBRA;nombra.tech;172.90.53.5;42001;000;http://
|
||||||
|
00561;US-North-America;DVSwitch.org;44.103.34.4;42000;000;http://dvswitch.org/YSF_NA/
|
||||||
|
27402;US-Northstar;Northstar Link;149.28.113.51;42000;001;http://149.28.113.51
|
||||||
|
83242;US-NW-Ohio;YSF-NW-Ohio;18.188.19.87;42000;001;http://ec2-18-188-19-87.us-east-2.compute.amazonaws.com/
|
||||||
|
13070;US-NWMO;NW Missouri;199.188.121.118;42000;001;http://nwmoroom.duckdns.org
|
||||||
|
53594;US-Ohio;Ohio;192.241.240.7;42000;005;http://ysf.n8qq.com
|
||||||
|
19053;US-OklahomaLink;RCWA.org;3.208.70.29;42000;013;http://3.208.70.29
|
||||||
|
72321;US-OMG-LA-LV;OLD MAN GROUP;149.248.21.148;42002;002;http://omglalv.tqhhc.com
|
||||||
|
14927;US-OMISS---YSF;YSF Multimode;104.49.29.243;42001;002;http://
|
||||||
|
74158;US-Oro-Valley-AZ;Oro Valley ARC;75.146.134.22;42000;023;http://
|
||||||
|
59281;US-OVARC-Test;Oro Valley ARC;69.244.58.8;42003;000;http://
|
||||||
|
06864;US-Penn-Link_1;XLX045A YSF;54.85.206.3;42000;004;http://xlx045.pennlinkgroup.com/ysfA
|
||||||
|
20223;US-Penn-Link_2;XLX045D YSF;54.85.206.3;42006;000;http://xlx045.Pennlinkgroup.com/ysfD/
|
||||||
|
69186;US-Penn-Link_3;XLX545B YSF;3.215.215.169;42001;001;http://xlx545.pennlinkgroup.com/ysfA
|
||||||
|
35119;US-Penn-Link_4;XLX045E YSF;54.85.206.3;42001;002;http://xlx045.pennlinkgroup.com/ysfE
|
||||||
|
92207;US-Penn-Link_5;XLX545E YSF;3.215.215.169;42000;002;http://xlx545.pennlinkgroup.com/ysfE
|
||||||
|
17947;US-Penn-Link_7;XLX045C YSF;54.85.206.3;42002;001;http://xlx045.Pennlinkgroup.com/ysfC/
|
||||||
|
19669;US-Penn-Link_8;XLX545A;3.215.215.169;42002;001;http://xlx545.pennlinkgroup.com/ysfA
|
||||||
|
69614;US-Phoenix-AZ;Phoenix AZ;68.14.214.57;42500;003;http://68.14.214.57:8080
|
||||||
|
30887;US-Phoenix-AZ-2;Phoenix AZ 2;72.194.183.82;42501;001;http://72.194.183.82:8081
|
||||||
|
31672;US-Pi-Star-Multi;Pi-Star Multi;142.44.240.244;42000;002;https://multi-reflector.pistar.uk
|
||||||
|
03169;US-PINOY-5155;PEANUT-PINOY;107.172.83.104;45000;002;http://ysf-p555.ddns.net
|
||||||
|
00094;US-Pottstown-Pa;Pennsylvania;69.249.242.117;42000;000;http://
|
||||||
|
63222;US-QCWA;Chapter 147;94.177.189.17;42000;003;http://94.177.189.17/ysf
|
||||||
|
63222;US-QCWA;Chapter 147;94.177.189.17;42000;003;http://ysfqcwa.xreflector.es
|
||||||
|
61324;US-Radio-Kollel;Torah Kollel;54.83.61.74;42000;000;http://
|
||||||
|
35010;US-Reddit;DMR TG 98003;74.214.25.135;42000;007;http://xlx216.km8v.com/
|
||||||
|
40874;US-REF020A;REF020A Link;52.23.107.220;42100;002;http://ysf020.kb2ear.net
|
||||||
|
33703;US-RKT-CTY-HSV;RKT.CTY.HSV.AL;136.53.51.207;42000;000;http://136.53.51.207
|
||||||
|
84105;US-RMM-YSF;RMM YSF;96.244.208.211;55555;000;http://ysf.robmon.com
|
||||||
|
92805;US-RocketCity-AL;Huntsville, AL;155.138.207.101;42000;002;http://155.138.207.101
|
||||||
|
38469;US-RuralMN-707;Rural MN;24.230.163.50;42000;002;https://707ysf.kd0ioe.com
|
||||||
|
84398;US-SADRC;SanAntonioDRC;173.226.176.18;42000;017;http://
|
||||||
|
52470;US-SARA-QRX-FCMG;Stillwater MN;69.147.211.168;42000;001;http://
|
||||||
|
39642;US-Secret-TG;Secret;75.118.136.88;42002;000;http://
|
||||||
|
92722;US-Skyhub-Link;Denver SkyHub;65.114.195.171;42000;010;http://kg0sky.duckdns.org/YSFReflector-Dashboard
|
||||||
|
40861;US-SOMN-----FAPG;SO MN;64.254.189.194;42000;003;http://
|
||||||
|
12461;US-South-MS-Net;South MS Net;50.246.136.107;42000;000;http://50.246.136.107:42001
|
||||||
|
29364;US-South-Texas;South Texas;76.183.98.122;42011;002;http://ae5jo.bounceme.net
|
||||||
|
96447;US-SOUTHEASTLINK;Provided by: L;45.32.214.224;42000;009;http://selink.lmarc.net/YSFDash/index.php
|
||||||
|
73102;US-Southwest-USA;Southwest USA;24.121.90.225;42000;011;http://24.121.90.225:8888/index.php
|
||||||
|
18503;US-SpaceCityChat;SpaceCityChat;108.209.70.215;42000;001;http://kk4lpo.ddnsgeek.com
|
||||||
|
95375;US-Steel-City;Pittsburgh, PA;71.60.185.34;42000;000;http://steelcityusa.ddns.net/
|
||||||
|
53632;US-TGIF;TGIF 31665;74.91.125.81;42000;003;http://tgif.network/ysf
|
||||||
|
81342;US-THINKNET;TEXAS US;104.239.146.135;42000;001;http://thinknet.mostlychris.com
|
||||||
|
23964;US-TREKFAN;TrekFan;138.68.11.56;42000;000;http://skylab.trekfan.org
|
||||||
|
08106;US-Triangle-Net;Triangle Net;74.91.121.182;42000;001;http://
|
||||||
|
15783;US-Truck-Travel;Truck Travel;74.91.121.182;42002;004;http://travel.atruckerslife.com
|
||||||
|
00546;US-Tucson-AZ;Oro Valley ARC;69.244.58.8;42004;004;http://
|
||||||
|
55817;US-Uni-Link;UniversityLink;128.83.129.92;42000;002;http://repeaters.as.utexas.edu/ysf/
|
||||||
|
55326;US-US-JOTA;DMR 907;104.200.25.53;42000;001;http://
|
||||||
|
03732;US-US-WNY-XRX;XRX Club;98.3.111.214;42000;001;http://
|
||||||
|
99539;US-VaDigital;YSF Reflector;3.19.122.217;42000;004;http://ysf.vadigital.network
|
||||||
|
13120;US-W2MMD-Sknkwks;W2MMD Sknkwks;72.82.133.138;42000;004;http://
|
||||||
|
39114;US-W6AUSBeeville;YSF Beeville;151.80.166.60;42000;000;http://
|
||||||
|
02512;US-WA-PNW;PNW Rag chew;144.202.95.90;42000;000;http://ysf.kc9gwk.com
|
||||||
|
07923;US-WA3PNY-GW;Input 1 to Net;3.215.215.169;42003;006;http://xlx545.pennlinkgroup.com/ysfG
|
||||||
|
64020;US-WA3PNY-GW2;Input 2 to Net;54.85.206.3;42004;002;http://xlx245.pennlinkgroup.com/ysfG2/
|
||||||
|
24157;US-Western-NC;WNC and nearby;199.168.200.18;42000;002;http://
|
||||||
|
37733;US-WestSide;Waukesha, WI;54.70.201.171;42000;010;http://www.reflectorusa.com
|
||||||
|
97689;US-Wi-Fi-Talk;Wireless Pros;173.162.46.202;42000;001;http://ysf.n4taj.com:8989
|
||||||
|
40396;US-WKENTUCKYDXEB;K4KMW RF Link;68.57.59.67;42000;001;http://
|
||||||
|
21335;US-WM-CONNECT;Wires-X 21335;199.85.255.10;42000;009;http://ysfdash.wmtg.me
|
||||||
|
98899;US-WolfDen;Massachusetts;100.0.63.70;42000;014;http://wolfden.ddnsgeek.com:42080
|
||||||
|
31357;US-WU3K;US WU3K;96.255.162.150;42000;000;http://
|
||||||
|
19941;US-WV-LINK;WV DIGI LINK;142.93.246.87;42000;002;http://
|
||||||
|
73602;US-XLX625;WA8BRO;68.55.76.168;42000;001;http://xlx625.wa8bro.com
|
||||||
|
55812;US-YSF-FDCCU;US San Diego;104.207.152.88;42000;004;http://ysf-n0mis.ddns.net
|
||||||
|
98060;US-YSF-Miami;YSF Miami;104.148.41.76;42000;002;http://104.148.41.76
|
||||||
|
12224;US-YSF-NE;NEW-ENGLAND;18.204.209.243;42000;002;http://
|
||||||
|
41373;US-YSF295;OMIK RADIO;64.137.187.75;42000;002;http://ysf295.dyndns.org
|
||||||
|
97912;US_SIN_Southern;Indiana_Link;142.93.181.147;42000;019;http://w9windigital.org/ysf
|
||||||
|
67356;US_SKYNET;SKYNET;104.130.158.171;42000;003;http://ysfdash.mostlychris.com:9000
|
||||||
|
82699;VCDRC;VCDRC TG31070;162.248.93.209;42003;001;http://ysf.snars.net/vcdrc/
|
||||||
|
20818;VE2YXY-TEST;VE2YXY-TEST;138.197.143.53;42000;001;http://
|
||||||
|
21468;WIRES-X;Room 21468;190.148.222.28;42103;000;http://
|
||||||
|
38635;Wires-X-YO-W;WiresX Romania;89.33.44.100;42003;001;http://wiresx.hamnet.ro
|
||||||
|
00008;WORLDLINK;World link;209.126.0.55;42000;017;http://worldlink.pa7lim.nl
|
||||||
|
27142;W_Tennessee;YSF Reflector;3.15.171.29;42000;001;http://
|
||||||
|
18145;XLX000;XLX reflector;45.56.118.86;42000;009;http://xlx000.xlxreflector.org
|
||||||
|
71981;XLX004;XLX reflector;44.103.34.3;42001;011;http://xlx004.kb8zgl.net
|
||||||
|
65978;XLX010;XLX reflector;85.197.129.86;42000;105;http://xlx.brandmeister.se
|
||||||
|
66396;XLX020;XLX reflector;66.175.215.217;42000;019;http://xlx020.k2ie.net
|
||||||
|
53148;XLX022;XLX reflector;83.137.45.98;42000;081;http://xlx022.tms-it.net
|
||||||
|
41945;XLX023;XLX reflector;77.85.192.94;42000;015;http://xlx023.ddns.net
|
||||||
|
86381;XLX026;XLX reflector;209.42.149.140;42000;014;http://xlx026.cnharc.org
|
||||||
|
29295;XLX029;XLX reflector;45.62.239.138;42000;000;http://029.r2i.net
|
||||||
|
44644;XLX032;XLX reflector;158.64.26.140;42000;015;http://xlx032.epf.lu
|
||||||
|
67001;XLX033;XLX reflector;46.226.178.81;42000;009;http://xrf033.dyndns.org
|
||||||
|
13908;XLX037;XLX reflector;198.100.154.155;42000;002;http://xlx037.ddns.net
|
||||||
|
82176;XLX038;XLX reflector;164.68.100.69;42000;000;http://xlx038.grupporadiofirenze.net/db/dashboard/
|
||||||
|
72207;XLX040;XLX reflector;109.71.45.29;42000;016;http://xrf040.dyndns.org
|
||||||
|
15976;XLX043;XLX reflector;206.189.239.225;42000;005;http://xlx043.pauldingares.com
|
||||||
|
80207;XLX046;XLX reflector;98.128.173.195;42000;000;https://xlx.c4fm.se
|
||||||
|
16909;XLX048;XLX reflector;45.62.213.248;42000;000;http://xlx048.ds6.com
|
||||||
|
13440;XLX051;XLX reflector;93.186.254.219;42001;037;http://xlx051-ea5spain.duckdns.org
|
||||||
|
90443;XLX056;XLX reflector;155.138.237.66;42000;008;http://scmidlands.network
|
||||||
|
89670;XLX062;XLX reflector;52.139.47.149;42000;001;http://xlx.baddogmedia.ca
|
||||||
|
64547;XLX069;XLX reflector;51.77.213.200;42000;003;http://51.77.213.200/db
|
||||||
|
42356;XLX070;COVENTRY ARS;18.130.199.150;42000;001;http://xlx070.g1iul.org.uk
|
||||||
|
67018;XLX077;XLX reflector;23.94.25.146;42000;005;http://xe1dvi.crabdance.com/db/index.php
|
||||||
|
75749;XLX094;XLX reflector;96.126.124.4;42000;000;http://xlx.txi35hams.com
|
||||||
|
59637;XLX098;XLX reflector;221.170.106.177;42001;154;http://xrf098.mydns.jp
|
||||||
|
74096;XLX100;XLX reflector;45.62.241.133;42000;000;http://xlx100.xlxreflector.org
|
||||||
|
39444;XLX101;XLX reflector;45.62.245.46;42000;000;http://xlx101.xlxreflector.org
|
||||||
|
57188;XLX102;XLX reflector;45.79.220.142;42000;027;http://xlx102.xlxreflector.org
|
||||||
|
37102;XLX104;XLX reflector;50.116.38.232;42000;007;http://xlx104.xlxreflector.org
|
||||||
|
58717;XLX105;XLX reflector;51.254.99.78;42000;003;http://ysf.xrf105.fr
|
||||||
|
92626;XLX109;XLX reflector;218.221.179.75;42000;001;http://109.bayfm78.tokyo/
|
||||||
|
20012;XLX124;XLX reflector;211.14.169.234;42000;140;http://xrf124.xreflector-jp.org
|
||||||
|
35367;XLX126;XLX reflector;217.173.179.95;42000;002;http://xlx126.noip.pl:8080
|
||||||
|
39815;XLX129;XLX reflector;220.145.77.199;42000;190;http://guwgw.cir-ins.com/
|
||||||
|
88621;XLX131;XLX reflector;80.127.118.226;42000;004;https://xlx131.pe1er.nl
|
||||||
|
77462;XLX132;XLX reflector;91.203.55.87;42000;038;http://xlx132.dstar.radom.pl/index.php?show=repeaters
|
||||||
|
48375;XLX140;WORLDWIDE;95.211.211.145;42000;000;http://xlx140.nix.pt
|
||||||
|
93407;XLX143;XLX reflector;161.35.235.224;42100;001;http://
|
||||||
|
59323;XLX174;XLX reflector;81.169.128.244;42000;007;http://xlx.digitalfunk-nordost.de
|
||||||
|
07483;XLX175;XLX Reflector;162.248.92.25;38000;000;http://ysf.ke8khn.com
|
||||||
|
95272;XLX185;XLX reflector;89.215.13.208;42000;011;http://xlx185.lz2kac.org:8680
|
||||||
|
86930;XLX200;XLX reflector;62.171.191.147;42000;001;http://xlxzone.net/index.php
|
||||||
|
62200;XLX201;XLX reflector;157.245.45.67;42000;013;https://xlx201.446em.uk
|
||||||
|
62862;XLX204;room Z Wires-X;82.171.119.45;42001;023;http://xlx204.ddns.net/
|
||||||
|
70248;XLX207;XLX reflector;150.129.138.49;42000;004;http://xlx.br2sy.net
|
||||||
|
20236;XLX208;XLX reflector;51.178.80.187;42000;016;https://xlx208.f5kav.fr/index.php
|
||||||
|
60106;XLX220;XLX reflector;124.41.83.11;42000;176;http://xlx220.sapotech.com
|
||||||
|
79890;XLX227;XLX reflector;89.33.44.100;42000;026;http://xlx227.hamnet.ro
|
||||||
|
34300;XLX229;XLX reflector;194.191.4.54;42000;047;http://dstar.hamnet.xyz
|
||||||
|
03349;XLX232;XLX reflector;89.185.97.35;42000;132;http://dstar.oevsv.at/db/index.php?show=modules
|
||||||
|
66065;XLX240;ZOMBIE-ALERT;107.141.52.226;42000;037;http://
|
||||||
|
31725;XLX250;XLX reflector;44.159.15.2;42000;011;https://xlx.ham.in.th
|
||||||
|
31855;XLX255;UA XLXd255 REF;142.91.158.199;42000;029;http://xrf255.reflector.up4dar.de/db/index.php
|
||||||
|
10347;XLX256;XLX reflector;162.238.214.18;42000;008;http://162.238.214.18
|
||||||
|
24862;XLX257;UA XLXd257 REF;134.249.141.148;42000;003;http://xlxd257.uw0wu.ml
|
||||||
|
14019;XLX260;XLX reflector;80.211.208.227;42000;008;https://xlx260.hblink.pl
|
||||||
|
83294;XLX267;XLX reflector;185.244.130.88;42000;000;http://ysf.sysprotect.eu
|
||||||
|
42725;XLX268;XLX reflector;194.38.140.204;42000;058;https://xlx268.from-ct.com
|
||||||
|
64702;XLX270;XLX reflector;158.64.26.132;42000;046;https://xlx270.epf.lu/
|
||||||
|
44047;XLX290;XLX reflector;44.182.7.20;42000;005;http://xlx.digitalsicilia.it
|
||||||
|
81632;XLX295;XLX reflector;64.137.161.161;42000;021;http://xlx295.dyndns.org
|
||||||
|
95424;XLX298;XLX reflector;219.107.78.72;42001;015;http://xrf298.mydns.jp
|
||||||
|
23565;XLX301;Canberra Link;124.187.44.129;42000;002;http://xlx301.duckdns.org
|
||||||
|
67862;XLX302;XLX reflector;144.217.241.23;42000;027;http://xlx302.hopto.org/db/
|
||||||
|
30362;XLX305;XLX reflector;178.250.54.203;42000;001;http://xlx.m5adi.com/
|
||||||
|
35947;XLX307;XLX reflector;72.21.76.154;42000;035;https://xlx307.openquad.net
|
||||||
|
92688;XLX311;XLX reflector;91.204.44.37;42000;000;https://xlx311.db0he.de
|
||||||
|
08623;XLX312;TriStateDMR;192.241.160.183;42000;008;http://xlx.dmr-marc.net
|
||||||
|
29178;XLX314;XLX reflector;186.19.139.15;42000;000;http://xlx314.ddns.net
|
||||||
|
38481;XLX328;XLX reflector;212.237.33.114;42000;022;http://212.237.33.114/index.php
|
||||||
|
83603;XLX330;"Megalink 330";44.70.49.128;42000;003;http://xlx.megalink.network
|
||||||
|
66149;XLX334;XLX reflector;96.47.95.121;42001;058;http://xlx.alabamalink.info
|
||||||
|
26906;XLX339;Hannover-XLink;nc.hannover-x.link;0;005;https://xlx.hannover-x.link
|
||||||
|
51599;XLX345;XLX reflector;73.253.128.47;42000;003;http://xlx345.dyndns.org:82
|
||||||
|
96507;XLX358;XLX reflector;93.152.167.4;42000;000;http://xlx358.ddns.net/
|
||||||
|
22852;XLX359;XLX reflector;94.156.172.213;42000;048;http://xlx359.ddns.net/
|
||||||
|
04965;XLX362;XLX reflector;198.166.220.68;42000;002;http://xlx362.gcdtech.ca/index.php
|
||||||
|
74839;XLX369;XLX reflector;72.89.122.8;42000;005;http://xlx369.w4eae.net
|
||||||
|
40341;XLX375;XLX reflector;12.221.169.50;42000;001;http://
|
||||||
|
88395;XLX377;XLX reflector;186.159.96.100;42000;003;http://xlx.toytron.com
|
||||||
|
45641;XLX381;TRIANGLE NC;74.91.114.100;42000;006;http://ysf.trianglenc.net
|
||||||
|
84823;XLX383;Kingsland GA;74.91.121.41;42000;003;http://74.91.121.41
|
||||||
|
00389;XLX389;XLX reflector;49.176.201.188;42000;051;http://xlxdmr.duckdns.org/db/
|
||||||
|
48042;XLX395;XLX reflector;95.255.196.50;42444;011;http://xlx395.grupporadiofirenze.net
|
||||||
|
66392;XLX398;XLX reflector;139.64.246.155;42000;000;http://xlx398.dyndns.org
|
||||||
|
64192;XLX410;XLX-REFLECTOR;166.78.145.146;42000;014;https://xlx.n5amd.com
|
||||||
|
29299;XLX420;XLX reflector;149.28.54.17;42000;000;https://xlx.cdarin.net
|
||||||
|
58291;XLX421;XLX reflector;118.189.181.236;42000;041;http://9v1lh.spdns.org:8086/
|
||||||
|
45165;XLX422;XLX reflector;93.240.48.68;42200;003;http://dl-nordwest.spdns.de:82/
|
||||||
|
26451;XLX425;XLX reflector;77.203.220.188;42000;004;http://srv-xlx.ddns.net
|
||||||
|
92585;XLX431;XLX reflector;61.195.98.225;42000;240;http://xrf431.xreflector-jp.org/
|
||||||
|
62243;XLX434;XLX reflector;51.254.128.134;42001;004;http://51.254.128.134/db
|
||||||
|
66583;XLX444;XLX reflector;46.38.241.228;42000;057;http://ysf444.pa3dfn.nl
|
||||||
|
68810;XLX449;XLX reflector;75.68.26.134;42000;000;http://hub.ollieted.com/db/
|
||||||
|
90015;XLX450;XLX reflector;45.62.241.140;42000;001;http://xlx450.xlxreflector.org
|
||||||
|
71743;XLX451;XLX reflector;45.62.239.185;42000;000;http://451.ds6.com
|
||||||
|
26845;XLX452;XLX reflector;45.62.210.37;42000;000;http://xlx452.ds6.com
|
||||||
|
26845;XLX452;XLX reflector;206.208.56.14;42000;000;http://xlx451.xreflector.org
|
||||||
|
97273;XLX453;HKHAM node -1-;61.239.171.240;42000;032;http://xlx453.hkham.org:8087/db
|
||||||
|
73993;XLX454;HKHAM node -2-;218.103.102.5;42000;059;http://xlx454.hkham.net/ysf
|
||||||
|
43173;XLX455;XLX reflector;208.71.169.83;42000;002;http://
|
||||||
|
93342;XLX456;XLX reflector;54.37.205.183;42000;046;https://xlx456.de
|
||||||
|
92227;XLX469;XLX reflector;104.207.138.156;42000;001;http://xlx469.kb0isw.com/index.php
|
||||||
|
98796;XLX479;XLX reflector;198.58.106.10;42000;007;http://zenas.n9ink.net
|
||||||
|
78936;XLX480;XLX reflector;95.179.145.178;42000;000;http://95.179.145.178
|
||||||
|
49716;XLX500;XLX reflector;58.96.21.253;42000;006;http://xlx500.org
|
||||||
|
51594;XLX502;XLX reflector;190.148.222.28;42102;017;http://190.148.222.28:8503/dashboard/index.php
|
||||||
|
07490;XLX503;XLX reflector;179.51.0.153;42000;008;http://179.51.0.153:8503/dashboard
|
||||||
|
71247;XLX504;XLX reflector;200.52.151.155;42000;002;http://200.52.151.155:8504/index.php
|
||||||
|
85857;XLX505;XLX reflector;45.248.50.37;42000;014;http://vk7hse.duckdns.org/xlx
|
||||||
|
88194;XLX507;XLX reflector;201.224.1.251;42000;005;http://xlx507.c4fmpanama.org/
|
||||||
|
64446;XLX508;XLX508 OWL;185.188.4.15;42000;052;http://xlx508.hb9gfx.ch
|
||||||
|
12230;XLX514;XLX reflector;203.137.118.143;42000;234;http://xrf514.xreflector-jp.org/
|
||||||
|
07475;XLX520;XLX reflector;44.159.15.1;42000;071;http://ysf.dtdxa.com
|
||||||
|
18807;XLX522;XLX reflector;14.102.146.160;42000;035;https://xlx.lucifernet.com/dashboard/index.php
|
||||||
|
59245;XLX530;XLX reflector;124.197.62.162;42025;031;http://xlx530.hopto.org
|
||||||
|
40946;XLX531;XLX reflector;149.28.170.145;42000;035;http://xlx531.drgnz.com
|
||||||
|
19577;XLX538;XLX reflector;183.76.38.69;42000;139;http://xrf538.mydns.jp
|
||||||
|
52074;XLX546;XLX reflector;149.28.202.133;42000;001;http://xlxscanintl.spdns.org
|
||||||
|
52074;XLX546;XLX reflector;149.28.202.133;42000;001;http://scani546.mooo.com
|
||||||
|
93887;XLX547;XLX reflector;45.77.186.5;42000;005;http://xlx.kapihan.net
|
||||||
|
83362;XLX548;XLX reflector;144.202.99.113;42000;000;http://xlx2.kapihan.net
|
||||||
|
28340;XLX560;XLX reflector;150.66.42.72;42000;229;http://xrf560.xreflector-jp.org/
|
||||||
|
08806;XLX595;XLX reflector;124.26.61.245;42000;014;http://hamradio.dip.jp
|
||||||
|
00412;XLX600;XLX reflector;13.69.14.204;42001;045;http://xlx600.dvscotland.net
|
||||||
|
91682;XLX621;HRCCLINK XLX;209.182.218.92;42000;006;http://xlxd.hrcc.link
|
||||||
|
36240;XLX634;XLX reflector;150.66.9.57;42000;016;http://xrf634.xreflector-jp.org/
|
||||||
|
13946;XLX651;XLX reflector;104.143.94.48;42200;004;http://104.143.94.48/XLX/dashboard/index.php
|
||||||
|
52732;XLX654;XLX reflector;94.33.52.82;42002;002;http://www.iw2hgl.it:81
|
||||||
|
84093;XLX669;XLX reflector;144.202.115.103;42000;003;http://xlx669-maharlika.ddns.net
|
||||||
|
76138;XLX679;XLX reflector;45.79.180.62;42000;005;http://xlx.borris.me
|
||||||
|
03560;XLX698;XLX reflector;203.137.123.89;42000;231;http://xrf698.xreflector-jp.org/
|
||||||
|
86410;XLX710;XLX reflector;209.126.0.55;42001;000;http://xlx710.pa7lim.nl
|
||||||
|
51642;XLX711;XLX reflector;192.243.108.150;42000;000;http://xlx711-ni.ddns.net
|
||||||
|
51265;XLX714;XLX reflector;213.195.111.148;44000;012;http://xlx714.ea3hkb.cat
|
||||||
|
78911;XLX716;XLX reflector;190.232.249.27;42000;005;http://xlx716.ddns.net/
|
||||||
|
88921;XLX725;XLX reflector;172.245.9.180;42000;000;http://xrf725.nq4t.com
|
||||||
|
84891;XLX741;XLX reflector;203.137.78.41;42000;220;http://xrf741.xreflector-jp.org
|
||||||
|
59607;XLX748;XLX reflector;64.137.174.49;42000;000;http://xlx748.dyndns.org
|
||||||
|
89323;XLX749;XLX reflector;45.76.252.9;42000;004;http://xlx749.drgnz.com/
|
||||||
|
32748;XLX750;XLX reflector;203.86.206.49;42000;103;http://www.xlx750.nz
|
||||||
|
41007;XLX751;XLX-REFLECTOR;149.28.71.1;42000;027;https://xlx751.drgnz.com/
|
||||||
|
62994;XLX758;XLX reflector;93.240.113.55;42000;001;http://
|
||||||
|
73934;XLX760;XLX reflector;172.245.71.164;42000;002;http://
|
||||||
|
67173;XLX776;XLX reflector;118.27.26.18;42000;172;http://776.bayfm78.tokyo/
|
||||||
|
01906;XLX778;XLX reflector;77.237.7.125;42000;018;https://xlx.hblink.kutno.pl/
|
||||||
|
38363;XLX781;XLX reflector;101.143.242.199;42000;240;http://xrf781.xreflector-jp.org/
|
||||||
|
45047;XLX799;XLX reflector;37.143.205.157;42000;006;http://xlxsof.ddns.net
|
||||||
|
53055;XLX800;XLX reflector;87.252.188.119;42000;015;http://xlx800.ddns.net
|
||||||
|
16226;XLX807;XLX reflector;116.91.197.3;42000;109;http://xrf807.owari.biz
|
||||||
|
55102;XLX810;XLX reflector;71.41.121.228;42000;003;http://xlx810.xlxreflector.org
|
||||||
|
48348;XLX812;XLX reflector;203.145.233.141;42000;138;http://xrf812.xreflector-jp.org/
|
||||||
|
70562;XLX837;XLX reflector;204.16.243.183;42000;000;http://xlx837.ai3i.net
|
||||||
|
54890;XLX840;XLX reflector;3.22.173.251;42000;001;http://ysf.lyrg.co.uk/
|
||||||
|
51106;XLX847;XLX reflector;204.16.243.184;42000;000;http://xlx847.ai3i.net
|
||||||
|
23661;XLX857;XLX reflector;204.16.243.185;42000;003;http://xlx857.ai3i.net
|
||||||
|
39930;XLX860;Allgaeu;24.134.86.93;42000;002;http://db0ess.de
|
||||||
|
08422;XLX888;XLX reflector;212.237.11.233;42000;019;http://xlx888.duckdns.org/db/index.php
|
||||||
|
48010;XLX891;XLX reflector;209.251.60.221;42000;007;http://xlx891.cidcomm.com
|
||||||
|
44904;XLX899;XLX reflector;45.14.224.180;42000;002;http://xlx899.mywire.org/
|
||||||
|
71144;XLX905;XLX reflector;94.199.173.123;42000;052;http://xlx905.oe9.at
|
||||||
|
82567;XLX922;XLX reflector;81.150.10.62;42000;016;https://www.cq-uk.co.uk
|
||||||
|
52616;XLX934;XLX reflector;79.6.136.177;42000;011;http://xlx934.arifvg.it
|
||||||
|
70191;XLX945;XLX reflector;213.202.229.40;42000;051;http://dcs945.xreflector.net
|
||||||
|
94341;XLX950;XLX reflector;158.64.26.134;42000;080;http://xlx950.epf.lu
|
||||||
|
43446;XLX957;XLX reflector;89.46.67.252;42000;004;http://xlx.dmrbrescia.it/xlxd/
|
||||||
|
15401;XLX960;XLX reflector;184.23.183.98;42000;006;http://xlxlist.dyndns.org
|
||||||
|
13897;XLX965;XLX reflector;80.211.190.216;42000;012;http://xlx965.hblink.it
|
||||||
|
45678;XLX970;XLX reflector;157.65.31.91;42000;204;http://ysf.onogoro.net/
|
||||||
|
96771;XLX973;XLX reflector;211.14.169.43;42000;015;http://xrf973.xreflector-jp.org/
|
||||||
|
85560;XLX978;XLX reflector;3.96.147.240;42000;004;http://xlx978.dyndns.org
|
||||||
|
37815;XLX994;XLX reflector;95.179.231.28;42000;008;https://xlx994.onlineradioclub.org
|
||||||
|
30906;XLXARG;XLX reflector;45.62.247.43;42000;009;http://xlxarg.no9s.org
|
||||||
|
91940;XLXCFR;XLX reflector;104.167.102.44;42000;009;http://xlxcfr.no9s.org
|
||||||
|
50281;XLXGUS;XLX reflector;104.167.112.102;42000;009;http://xlxgus.xlxreflector.org
|
||||||
|
17004;YO-Wires-X-E;WiresX Romania;85.122.16.152;42000;000;http://85.122.16.152
|
||||||
|
48709;YSF-24566;IT RADIOSCOUT;217.182.156.147;42000;000;http://ysf.radioscout.it/YSFReflector-Dashboard/
|
||||||
|
75917;YSF-768;Portugal 768;80.211.15.21;42000;002;http://ysf.voxpopuli.pt
|
||||||
|
54357;YSF-HBL-GDA;HBLink Polska;77.55.212.58;42000;000;http://77.55.212.58:8888
|
||||||
|
23053;YSF-IQ2AQ-L;YSF-SVXLINK;80.211.32.170;42000;003;http://80.211.32.170/ysf
|
||||||
|
06595;YSF-OMEGA;TAMBAYAN C4FM;107.175.49.145;42000;004;http://omegacomm.ddns.net
|
||||||
|
64915;YSF-PINOY;SPECTRUM;144.202.115.103;42030;006;http://ysf-pinoyspectrum.ddns.net
|
||||||
|
98022;YSF-PUSA;YSF-PUSA;149.248.7.112;42000;000;http://ab6bp.ddns.net
|
||||||
|
01183;YSF-TAMBAYAN;TAMBAYAN;47.157.208.97;42050;000;http://ysf-pinoytambayan.ddns.net
|
||||||
|
26626;YSF-TI;YSF Tango Indi;165.227.115.205;42000;002;http://xrf.ossdr.com/ysf
|
||||||
|
77299;YSF-TSIONG;Tambayan;107.175.215.106;42050;000;http://tsiong.ddns.net
|
||||||
|
41577;YSF-YO-W;Fusion Romania;89.33.44.100;42001;004;http://ysf.hamnet.ro
|
||||||
|
94614;YSF004;US Michigan Ro;44.103.34.3;42000;001;http://ysf004.kb8zgl.net/YSFReflector
|
||||||
|
43223;YSF2WIRESX;WIRESX 43223;104.143.94.48;42424;004;http://
|
||||||
|
49868;YSF345;USA CTDGroup;73.253.128.47;42002;001;http://ysf345.dyndns.org:82/YSF/
|
||||||
|
86137;ysf4aws;ysf4aws;18.210.76.48;42000;000;http://
|
||||||
|
88240;ZOMBIE-ALERT;WiresX #28298;107.141.52.226;42009;016;http://zombiealert.ddns.net
|
91
DGIdGateway/YSFHostsupdate.sh
Executable file
91
DGIdGateway/YSFHostsupdate.sh
Executable file
|
@ -0,0 +1,91 @@
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
#
|
||||||
|
# YSFHostsupdate.sh
|
||||||
|
#
|
||||||
|
# Copyright (C) 2016 by Tony Corbett G0WFV
|
||||||
|
# Adapted to YSFHosts by Paul Nannery KC2VRJ on 6/28/2016 with all crdeit
|
||||||
|
# to G0WFV for the orignal script.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
###############################################################################
|
||||||
|
#
|
||||||
|
# On a Linux based system, such as a Raspberry Pi, this script will perform all
|
||||||
|
# the steps required to maintain the YSFHosts.txt (or similar) file for you.
|
||||||
|
#
|
||||||
|
# It is designed to run from crontab and will download the YSFHosts from the
|
||||||
|
# master ysfreflector.de database and optionally keep a backup of previously
|
||||||
|
# created files for you.
|
||||||
|
#
|
||||||
|
# It will also prune the number of backup files according to a value specified
|
||||||
|
# by you in the configuration below.
|
||||||
|
#
|
||||||
|
# To install in root's crontab use the command ...
|
||||||
|
#
|
||||||
|
# sudo crontab -e
|
||||||
|
#
|
||||||
|
# ... and add the following line to the bottom of the file ...
|
||||||
|
#
|
||||||
|
# 0 0 * * * /path/to/script/YSFHostsupdate.sh 1>/dev/null 2>&1
|
||||||
|
#
|
||||||
|
# ... where /path/to/script/ should be replaced by the path to this script.
|
||||||
|
#
|
||||||
|
###############################################################################
|
||||||
|
#
|
||||||
|
# CONFIGURATION
|
||||||
|
#
|
||||||
|
# Full path to YSFHosts
|
||||||
|
YSFHOSTS=/path/to/YSFHosts.txt
|
||||||
|
|
||||||
|
# How many YSFHosts files do you want backed up (0 = do not keep backups)
|
||||||
|
YSFHOSTSFILEBACKUP=1
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
#
|
||||||
|
# Do not edit below here
|
||||||
|
#
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
# Check we are root
|
||||||
|
if [ "$(id -u)" != "0" ]
|
||||||
|
then
|
||||||
|
echo "This script must be run as root" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create backup of old file
|
||||||
|
if [ ${YSFHOSTSFILEBACKUP} -ne 0 ]
|
||||||
|
then
|
||||||
|
cp ${YSFHOSTS} ${YSFHOSTS}.$(date +%d%m%y)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Prune backups
|
||||||
|
BACKUPCOUNT=$(ls ${YSFHOSTS}.* | wc -l)
|
||||||
|
BACKUPSTODELETE=$(expr ${BACKUPCOUNT} - ${YSFHOSTSFILEBACKUP})
|
||||||
|
|
||||||
|
if [ ${BACKUPCOUNT} -gt ${YSFHOSTSFILEBACKUP} ]
|
||||||
|
then
|
||||||
|
for f in $(ls -tr ${YSFHOSTS}.* | head -${BACKUPSTODELETE})
|
||||||
|
do
|
||||||
|
rm -f $f
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Generate YSFHosts.txt file
|
||||||
|
curl https://register.ysfreflector.de/export_csv.php > ${YSFHOSTS}
|
||||||
|
|
||||||
|
exit 0
|
206
DGIdGateway/YSFNetwork.cpp
Normal file
206
DGIdGateway/YSFNetwork.cpp
Normal file
|
@ -0,0 +1,206 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009-2014,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 "YSFDefines.h"
|
||||||
|
#include "YSFNetwork.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
const unsigned int BUFFER_LENGTH = 200U;
|
||||||
|
|
||||||
|
CYSFNetwork::CYSFNetwork(const std::string& address, unsigned int port, const std::string& callsign, bool debug) :
|
||||||
|
m_socket(address, port),
|
||||||
|
m_debug(debug),
|
||||||
|
m_address(),
|
||||||
|
m_port(0U),
|
||||||
|
m_poll(NULL),
|
||||||
|
m_unlink(NULL),
|
||||||
|
m_buffer(1000U, "YSF Network Buffer"),
|
||||||
|
m_pollTimer(1000U, 5U),
|
||||||
|
m_name(),
|
||||||
|
m_linked(false)
|
||||||
|
{
|
||||||
|
m_poll = new unsigned char[14U];
|
||||||
|
::memcpy(m_poll + 0U, "YSFP", 4U);
|
||||||
|
|
||||||
|
m_unlink = new unsigned char[14U];
|
||||||
|
::memcpy(m_unlink + 0U, "YSFU", 4U);
|
||||||
|
|
||||||
|
std::string node = callsign;
|
||||||
|
node.resize(YSF_CALLSIGN_LENGTH, ' ');
|
||||||
|
|
||||||
|
for (unsigned int i = 0U; i < YSF_CALLSIGN_LENGTH; i++) {
|
||||||
|
m_poll[i + 4U] = node.at(i);
|
||||||
|
m_unlink[i + 4U] = node.at(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CYSFNetwork::CYSFNetwork(unsigned int port, const std::string& callsign, bool debug) :
|
||||||
|
m_socket(port),
|
||||||
|
m_debug(debug),
|
||||||
|
m_address(),
|
||||||
|
m_port(0U),
|
||||||
|
m_poll(NULL),
|
||||||
|
m_unlink(NULL),
|
||||||
|
m_buffer(1000U, "YSF Network Buffer"),
|
||||||
|
m_pollTimer(1000U, 5U)
|
||||||
|
{
|
||||||
|
m_poll = new unsigned char[14U];
|
||||||
|
::memcpy(m_poll + 0U, "YSFP", 4U);
|
||||||
|
|
||||||
|
m_unlink = new unsigned char[14U];
|
||||||
|
::memcpy(m_unlink + 0U, "YSFU", 4U);
|
||||||
|
|
||||||
|
std::string node = callsign;
|
||||||
|
node.resize(YSF_CALLSIGN_LENGTH, ' ');
|
||||||
|
|
||||||
|
for (unsigned int i = 0U; i < YSF_CALLSIGN_LENGTH; i++) {
|
||||||
|
m_poll[i + 4U] = node.at(i);
|
||||||
|
m_unlink[i + 4U] = node.at(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CYSFNetwork::~CYSFNetwork()
|
||||||
|
{
|
||||||
|
delete[] m_poll;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CYSFNetwork::open()
|
||||||
|
{
|
||||||
|
LogMessage("Opening YSF network connection");
|
||||||
|
|
||||||
|
return m_socket.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CYSFNetwork::setDestination(const std::string& name, const in_addr& address, unsigned int port)
|
||||||
|
{
|
||||||
|
m_name = name;
|
||||||
|
m_address = address;
|
||||||
|
m_port = port;
|
||||||
|
m_linked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CYSFNetwork::clearDestination()
|
||||||
|
{
|
||||||
|
m_address.s_addr = INADDR_NONE;
|
||||||
|
m_port = 0U;
|
||||||
|
m_linked = false;
|
||||||
|
|
||||||
|
m_pollTimer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CYSFNetwork::write(const unsigned char* data)
|
||||||
|
{
|
||||||
|
assert(data != NULL);
|
||||||
|
|
||||||
|
if (m_port == 0U)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_debug)
|
||||||
|
CUtils::dump(1U, "YSF Network Data Sent", data, 155U);
|
||||||
|
|
||||||
|
m_socket.write(data, 155U, m_address, m_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CYSFNetwork::writePoll(unsigned int count)
|
||||||
|
{
|
||||||
|
if (m_port == 0U)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_pollTimer.start();
|
||||||
|
|
||||||
|
for (unsigned int i = 0U; i < count; i++)
|
||||||
|
m_socket.write(m_poll, 14U, m_address, m_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CYSFNetwork::writeUnlink(unsigned int count)
|
||||||
|
{
|
||||||
|
m_pollTimer.stop();
|
||||||
|
|
||||||
|
if (m_port == 0U)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (unsigned int i = 0U; i < count; i++)
|
||||||
|
m_socket.write(m_unlink, 14U, m_address, m_port);
|
||||||
|
|
||||||
|
m_linked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CYSFNetwork::clock(unsigned int ms)
|
||||||
|
{
|
||||||
|
unsigned char buffer[BUFFER_LENGTH];
|
||||||
|
in_addr address;
|
||||||
|
unsigned int port;
|
||||||
|
|
||||||
|
m_pollTimer.clock(ms);
|
||||||
|
if (m_pollTimer.isRunning() && m_pollTimer.hasExpired())
|
||||||
|
writePoll();
|
||||||
|
|
||||||
|
int length = m_socket.read(buffer, BUFFER_LENGTH, address, port);
|
||||||
|
if (length <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_port == 0U)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (address.s_addr != m_address.s_addr || port != m_port)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (::memcmp(buffer, "YSFP", 4U) == 0 && !m_linked) {
|
||||||
|
if (strcmp(m_name.c_str(),"MMDVM")== 0)
|
||||||
|
LogMessage("Link successful to %s", m_name.c_str());
|
||||||
|
else
|
||||||
|
LogMessage("Linked to %s", m_name.c_str());
|
||||||
|
|
||||||
|
m_linked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_debug)
|
||||||
|
CUtils::dump(1U, "YSF Network Data Received", buffer, length);
|
||||||
|
|
||||||
|
unsigned char len = length;
|
||||||
|
m_buffer.addData(&len, 1U);
|
||||||
|
|
||||||
|
m_buffer.addData(buffer, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int CYSFNetwork::read(unsigned char* data)
|
||||||
|
{
|
||||||
|
assert(data != NULL);
|
||||||
|
|
||||||
|
if (m_buffer.isEmpty())
|
||||||
|
return 0U;
|
||||||
|
|
||||||
|
unsigned char len = 0U;
|
||||||
|
m_buffer.getData(&len, 1U);
|
||||||
|
|
||||||
|
m_buffer.getData(data, len);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CYSFNetwork::close()
|
||||||
|
{
|
||||||
|
m_socket.close();
|
||||||
|
|
||||||
|
LogMessage("Closing YSF network connection");
|
||||||
|
}
|
67
DGIdGateway/YSFNetwork.h
Normal file
67
DGIdGateway/YSFNetwork.h
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009-2014,2016,2017,2018,2020 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 YSFNetwork_H
|
||||||
|
#define YSFNetwork_H
|
||||||
|
|
||||||
|
#include "DGIdNetwork.h"
|
||||||
|
#include "YSFDefines.h"
|
||||||
|
#include "UDPSocket.h"
|
||||||
|
#include "RingBuffer.h"
|
||||||
|
#include "Timer.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class CYSFNetwork : public CDGIdNetwork {
|
||||||
|
public:
|
||||||
|
CYSFNetwork(const std::string& address, unsigned int port, const std::string& callsign, bool debug);
|
||||||
|
CYSFNetwork(unsigned int port, const std::string& callsign, bool debug);
|
||||||
|
virtual ~CYSFNetwork();
|
||||||
|
|
||||||
|
virtual bool open();
|
||||||
|
|
||||||
|
virtual void link();
|
||||||
|
|
||||||
|
void setDestination(const std::string& name, const in_addr& address, unsigned int port);
|
||||||
|
|
||||||
|
virtual void write(unsigned int dgId, const unsigned char* data);
|
||||||
|
|
||||||
|
void writePoll(unsigned int count = 1U);
|
||||||
|
virtual void unlink();
|
||||||
|
|
||||||
|
virtual unsigned int read(unsigned int dgId, unsigned char* data);
|
||||||
|
|
||||||
|
virtual void clock(unsigned int ms);
|
||||||
|
|
||||||
|
virtual void close();
|
||||||
|
|
||||||
|
private:
|
||||||
|
CUDPSocket m_socket;
|
||||||
|
bool m_debug;
|
||||||
|
in_addr m_address;
|
||||||
|
unsigned int m_port;
|
||||||
|
unsigned char* m_poll;
|
||||||
|
unsigned char* m_unlink;
|
||||||
|
CRingBuffer<unsigned char> m_buffer;
|
||||||
|
CTimer m_pollTimer;
|
||||||
|
std::string m_name;
|
||||||
|
bool m_linked;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
357
DGIdGateway/YSFPayload.cpp
Normal file
357
DGIdGateway/YSFPayload.cpp
Normal file
|
@ -0,0 +1,357 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 Jonathan Naylor, G4KLX
|
||||||
|
* Copyright (C) 2016 Mathias Weyland, HB9FRV
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; version 2 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "YSFConvolution.h"
|
||||||
|
#include "YSFPayload.h"
|
||||||
|
#include "YSFDefines.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
#include "CRC.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
const unsigned int INTERLEAVE_TABLE_9_20[] = {
|
||||||
|
0U, 40U, 80U, 120U, 160U, 200U, 240U, 280U, 320U,
|
||||||
|
2U, 42U, 82U, 122U, 162U, 202U, 242U, 282U, 322U,
|
||||||
|
4U, 44U, 84U, 124U, 164U, 204U, 244U, 284U, 324U,
|
||||||
|
6U, 46U, 86U, 126U, 166U, 206U, 246U, 286U, 326U,
|
||||||
|
8U, 48U, 88U, 128U, 168U, 208U, 248U, 288U, 328U,
|
||||||
|
10U, 50U, 90U, 130U, 170U, 210U, 250U, 290U, 330U,
|
||||||
|
12U, 52U, 92U, 132U, 172U, 212U, 252U, 292U, 332U,
|
||||||
|
14U, 54U, 94U, 134U, 174U, 214U, 254U, 294U, 334U,
|
||||||
|
16U, 56U, 96U, 136U, 176U, 216U, 256U, 296U, 336U,
|
||||||
|
18U, 58U, 98U, 138U, 178U, 218U, 258U, 298U, 338U,
|
||||||
|
20U, 60U, 100U, 140U, 180U, 220U, 260U, 300U, 340U,
|
||||||
|
22U, 62U, 102U, 142U, 182U, 222U, 262U, 302U, 342U,
|
||||||
|
24U, 64U, 104U, 144U, 184U, 224U, 264U, 304U, 344U,
|
||||||
|
26U, 66U, 106U, 146U, 186U, 226U, 266U, 306U, 346U,
|
||||||
|
28U, 68U, 108U, 148U, 188U, 228U, 268U, 308U, 348U,
|
||||||
|
30U, 70U, 110U, 150U, 190U, 230U, 270U, 310U, 350U,
|
||||||
|
32U, 72U, 112U, 152U, 192U, 232U, 272U, 312U, 352U,
|
||||||
|
34U, 74U, 114U, 154U, 194U, 234U, 274U, 314U, 354U,
|
||||||
|
36U, 76U, 116U, 156U, 196U, 236U, 276U, 316U, 356U,
|
||||||
|
38U, 78U, 118U, 158U, 198U, 238U, 278U, 318U, 358U};
|
||||||
|
|
||||||
|
const unsigned int INTERLEAVE_TABLE_5_20[] = {
|
||||||
|
0U, 40U, 80U, 120U, 160U,
|
||||||
|
2U, 42U, 82U, 122U, 162U,
|
||||||
|
4U, 44U, 84U, 124U, 164U,
|
||||||
|
6U, 46U, 86U, 126U, 166U,
|
||||||
|
8U, 48U, 88U, 128U, 168U,
|
||||||
|
10U, 50U, 90U, 130U, 170U,
|
||||||
|
12U, 52U, 92U, 132U, 172U,
|
||||||
|
14U, 54U, 94U, 134U, 174U,
|
||||||
|
16U, 56U, 96U, 136U, 176U,
|
||||||
|
18U, 58U, 98U, 138U, 178U,
|
||||||
|
20U, 60U, 100U, 140U, 180U,
|
||||||
|
22U, 62U, 102U, 142U, 182U,
|
||||||
|
24U, 64U, 104U, 144U, 184U,
|
||||||
|
26U, 66U, 106U, 146U, 186U,
|
||||||
|
28U, 68U, 108U, 148U, 188U,
|
||||||
|
30U, 70U, 110U, 150U, 190U,
|
||||||
|
32U, 72U, 112U, 152U, 192U,
|
||||||
|
34U, 74U, 114U, 154U, 194U,
|
||||||
|
36U, 76U, 116U, 156U, 196U,
|
||||||
|
38U, 78U, 118U, 158U, 198U};
|
||||||
|
|
||||||
|
const unsigned char WHITENING_DATA[] = {0x93U, 0xD7U, 0x51U, 0x21U, 0x9CU, 0x2FU, 0x6CU, 0xD0U, 0xEFU, 0x0FU,
|
||||||
|
0xF8U, 0x3DU, 0xF1U, 0x73U, 0x20U, 0x94U, 0xEDU, 0x1EU, 0x7CU, 0xD8U};
|
||||||
|
|
||||||
|
const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
||||||
|
|
||||||
|
#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
|
||||||
|
#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
|
||||||
|
|
||||||
|
CYSFPayload::CYSFPayload()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CYSFPayload::~CYSFPayload()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CYSFPayload::readVDMode1Data(const unsigned char* data, unsigned char* dt)
|
||||||
|
{
|
||||||
|
assert(data != NULL);
|
||||||
|
assert(dt != NULL);
|
||||||
|
|
||||||
|
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||||
|
|
||||||
|
unsigned char dch[45U];
|
||||||
|
|
||||||
|
const unsigned char* p1 = data;
|
||||||
|
unsigned char* p2 = dch;
|
||||||
|
for (unsigned int i = 0U; i < 5U; i++) {
|
||||||
|
::memcpy(p2, p1, 9U);
|
||||||
|
p1 += 18U; p2 += 9U;
|
||||||
|
}
|
||||||
|
|
||||||
|
CYSFConvolution conv;
|
||||||
|
conv.start();
|
||||||
|
|
||||||
|
for (unsigned int i = 0U; i < 180U; i++) {
|
||||||
|
unsigned int n = INTERLEAVE_TABLE_9_20[i];
|
||||||
|
uint8_t s0 = READ_BIT1(dch, n) ? 1U : 0U;
|
||||||
|
|
||||||
|
n++;
|
||||||
|
uint8_t s1 = READ_BIT1(dch, n) ? 1U : 0U;
|
||||||
|
|
||||||
|
conv.decode(s0, s1);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char output[23U];
|
||||||
|
conv.chainback(output, 176U);
|
||||||
|
|
||||||
|
bool ret = CCRC::checkCCITT16(output, 22U);
|
||||||
|
if (ret) {
|
||||||
|
for (unsigned int i = 0U; i < 20U; i++)
|
||||||
|
output[i] ^= WHITENING_DATA[i];
|
||||||
|
|
||||||
|
CUtils::dump(1U, "V/D Mode 1 Data", output, 20U);
|
||||||
|
|
||||||
|
::memcpy(dt, output, 20U);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CYSFPayload::readVDMode2Data(const unsigned char* data, unsigned char* dt)
|
||||||
|
{
|
||||||
|
assert(data != NULL);
|
||||||
|
assert(dt != NULL);
|
||||||
|
|
||||||
|
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||||
|
|
||||||
|
unsigned char dch[25U];
|
||||||
|
|
||||||
|
const unsigned char* p1 = data;
|
||||||
|
unsigned char* p2 = dch;
|
||||||
|
for (unsigned int i = 0U; i < 5U; i++) {
|
||||||
|
::memcpy(p2, p1, 5U);
|
||||||
|
p1 += 18U; p2 += 5U;
|
||||||
|
}
|
||||||
|
|
||||||
|
CYSFConvolution conv;
|
||||||
|
conv.start();
|
||||||
|
|
||||||
|
for (unsigned int i = 0U; i < 100U; i++) {
|
||||||
|
unsigned int n = INTERLEAVE_TABLE_5_20[i];
|
||||||
|
uint8_t s0 = READ_BIT1(dch, n) ? 1U : 0U;
|
||||||
|
|
||||||
|
n++;
|
||||||
|
uint8_t s1 = READ_BIT1(dch, n) ? 1U : 0U;
|
||||||
|
|
||||||
|
conv.decode(s0, s1);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char output[13U];
|
||||||
|
conv.chainback(output, 96U);
|
||||||
|
|
||||||
|
bool ret = CCRC::checkCCITT16(output, 12U);
|
||||||
|
if (ret) {
|
||||||
|
for (unsigned int i = 0U; i < 10U; i++)
|
||||||
|
output[i] ^= WHITENING_DATA[i];
|
||||||
|
|
||||||
|
CUtils::dump(1U, "V/D Mode 2 Data", output, YSF_CALLSIGN_LENGTH);
|
||||||
|
|
||||||
|
::memcpy(dt, output, YSF_CALLSIGN_LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CYSFPayload::readDataFRModeData1(const unsigned char* data, unsigned char* dt)
|
||||||
|
{
|
||||||
|
assert(data != NULL);
|
||||||
|
assert(dt != NULL);
|
||||||
|
|
||||||
|
::memset(dt, ' ', 20U);
|
||||||
|
|
||||||
|
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||||
|
|
||||||
|
unsigned char dch[45U];
|
||||||
|
|
||||||
|
const unsigned char* p1 = data;
|
||||||
|
unsigned char* p2 = dch;
|
||||||
|
for (unsigned int i = 0U; i < 5U; i++) {
|
||||||
|
::memcpy(p2, p1, 9U);
|
||||||
|
p1 += 18U; p2 += 9U;
|
||||||
|
}
|
||||||
|
|
||||||
|
CYSFConvolution conv;
|
||||||
|
conv.start();
|
||||||
|
|
||||||
|
for (unsigned int i = 0U; i < 180U; i++) {
|
||||||
|
unsigned int n = INTERLEAVE_TABLE_9_20[i];
|
||||||
|
uint8_t s0 = READ_BIT1(dch, n) ? 1U : 0U;
|
||||||
|
|
||||||
|
n++;
|
||||||
|
uint8_t s1 = READ_BIT1(dch, n) ? 1U : 0U;
|
||||||
|
|
||||||
|
conv.decode(s0, s1);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char output[23U];
|
||||||
|
conv.chainback(output, 176U);
|
||||||
|
|
||||||
|
bool ret = CCRC::checkCCITT16(output, 22U);
|
||||||
|
if (ret) {
|
||||||
|
for (unsigned int i = 0U; i < 20U; i++)
|
||||||
|
output[i] ^= WHITENING_DATA[i];
|
||||||
|
|
||||||
|
CUtils::dump(1U, "FR Mode Data 1", output, 20U);
|
||||||
|
|
||||||
|
::memcpy(dt, output, 20U);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CYSFPayload::readDataFRModeData2(const unsigned char* data, unsigned char* dt)
|
||||||
|
{
|
||||||
|
assert(data != NULL);
|
||||||
|
assert(dt != NULL);
|
||||||
|
|
||||||
|
::memset(dt, ' ', 20U);
|
||||||
|
|
||||||
|
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||||
|
|
||||||
|
unsigned char dch[45U];
|
||||||
|
|
||||||
|
const unsigned char* p1 = data + 9U;
|
||||||
|
unsigned char* p2 = dch;
|
||||||
|
for (unsigned int i = 0U; i < 5U; i++) {
|
||||||
|
::memcpy(p2, p1, 9U);
|
||||||
|
p1 += 18U; p2 += 9U;
|
||||||
|
}
|
||||||
|
|
||||||
|
CYSFConvolution conv;
|
||||||
|
conv.start();
|
||||||
|
|
||||||
|
for (unsigned int i = 0U; i < 180U; i++) {
|
||||||
|
unsigned int n = INTERLEAVE_TABLE_9_20[i];
|
||||||
|
uint8_t s0 = READ_BIT1(dch, n) ? 1U : 0U;
|
||||||
|
|
||||||
|
n++;
|
||||||
|
uint8_t s1 = READ_BIT1(dch, n) ? 1U : 0U;
|
||||||
|
|
||||||
|
conv.decode(s0, s1);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char output[23U];
|
||||||
|
conv.chainback(output, 176U);
|
||||||
|
|
||||||
|
bool ret = CCRC::checkCCITT16(output, 22U);
|
||||||
|
if (ret) {
|
||||||
|
for (unsigned int i = 0U; i < 20U; i++)
|
||||||
|
output[i] ^= WHITENING_DATA[i];
|
||||||
|
|
||||||
|
CUtils::dump(1U, "FR Mode Data 2", output, 20U);
|
||||||
|
|
||||||
|
::memcpy(dt, output, 20U);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CYSFPayload::writeDataFRModeData1(const unsigned char* dt, unsigned char* data)
|
||||||
|
{
|
||||||
|
assert(dt != NULL);
|
||||||
|
assert(data != NULL);
|
||||||
|
|
||||||
|
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||||
|
|
||||||
|
unsigned char output[25U];
|
||||||
|
for (unsigned int i = 0U; i < 20U; i++)
|
||||||
|
output[i] = dt[i] ^ WHITENING_DATA[i];
|
||||||
|
|
||||||
|
CCRC::addCCITT16(output, 22U);
|
||||||
|
output[22U] = 0x00U;
|
||||||
|
|
||||||
|
unsigned char convolved[45U];
|
||||||
|
|
||||||
|
CYSFConvolution conv;
|
||||||
|
conv.encode(output, convolved, 180U);
|
||||||
|
|
||||||
|
unsigned char bytes[45U];
|
||||||
|
unsigned int j = 0U;
|
||||||
|
for (unsigned int i = 0U; i < 180U; i++) {
|
||||||
|
unsigned int n = INTERLEAVE_TABLE_9_20[i];
|
||||||
|
|
||||||
|
bool s0 = READ_BIT1(convolved, j) != 0U;
|
||||||
|
j++;
|
||||||
|
|
||||||
|
bool s1 = READ_BIT1(convolved, j) != 0U;
|
||||||
|
j++;
|
||||||
|
|
||||||
|
WRITE_BIT1(bytes, n, s0);
|
||||||
|
|
||||||
|
n++;
|
||||||
|
WRITE_BIT1(bytes, n, s1);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char* p1 = data;
|
||||||
|
unsigned char* p2 = bytes;
|
||||||
|
for (unsigned int i = 0U; i < 5U; i++) {
|
||||||
|
::memcpy(p1, p2, 9U);
|
||||||
|
p1 += 18U; p2 += 9U;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CYSFPayload::writeDataFRModeData2(const unsigned char* dt, unsigned char* data)
|
||||||
|
{
|
||||||
|
assert(dt != NULL);
|
||||||
|
assert(data != NULL);
|
||||||
|
|
||||||
|
data += YSF_SYNC_LENGTH_BYTES + YSF_FICH_LENGTH_BYTES;
|
||||||
|
|
||||||
|
unsigned char output[25U];
|
||||||
|
for (unsigned int i = 0U; i < 20U; i++)
|
||||||
|
output[i] = dt[i] ^ WHITENING_DATA[i];
|
||||||
|
|
||||||
|
CCRC::addCCITT16(output, 22U);
|
||||||
|
output[22U] = 0x00U;
|
||||||
|
|
||||||
|
unsigned char convolved[45U];
|
||||||
|
|
||||||
|
CYSFConvolution conv;
|
||||||
|
conv.encode(output, convolved, 180U);
|
||||||
|
|
||||||
|
unsigned char bytes[45U];
|
||||||
|
unsigned int j = 0U;
|
||||||
|
for (unsigned int i = 0U; i < 180U; i++) {
|
||||||
|
unsigned int n = INTERLEAVE_TABLE_9_20[i];
|
||||||
|
|
||||||
|
bool s0 = READ_BIT1(convolved, j) != 0U;
|
||||||
|
j++;
|
||||||
|
|
||||||
|
bool s1 = READ_BIT1(convolved, j) != 0U;
|
||||||
|
j++;
|
||||||
|
|
||||||
|
WRITE_BIT1(bytes, n, s0);
|
||||||
|
|
||||||
|
n++;
|
||||||
|
WRITE_BIT1(bytes, n, s1);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char* p1 = data + 9U;
|
||||||
|
unsigned char* p2 = bytes;
|
||||||
|
for (unsigned int i = 0U; i < 5U; i++) {
|
||||||
|
::memcpy(p1, p2, 9U);
|
||||||
|
p1 += 18U; p2 += 9U;
|
||||||
|
}
|
||||||
|
}
|
42
DGIdGateway/YSFPayload.h
Normal file
42
DGIdGateway/YSFPayload.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 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(YSFPayload_H)
|
||||||
|
#define YSFPayload_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class CYSFPayload {
|
||||||
|
public:
|
||||||
|
CYSFPayload();
|
||||||
|
~CYSFPayload();
|
||||||
|
|
||||||
|
bool readVDMode1Data(const unsigned char* data, unsigned char* dt);
|
||||||
|
|
||||||
|
bool readVDMode2Data(const unsigned char* data, unsigned char* dt);
|
||||||
|
|
||||||
|
bool readDataFRModeData1(const unsigned char* data, unsigned char* dt);
|
||||||
|
bool readDataFRModeData2(const unsigned char* data, unsigned char* dt);
|
||||||
|
|
||||||
|
void writeDataFRModeData1(const unsigned char* dt, unsigned char* data);
|
||||||
|
void writeDataFRModeData2(const unsigned char* dt, unsigned char* data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
107
DGIdGateway/YSFReflectors.cpp
Normal file
107
DGIdGateway/YSFReflectors.cpp
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016-2020 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 "YSFReflectors.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
|
CYSFReflectors::CYSFReflectors(const std::string& hostsFile) :
|
||||||
|
m_hostsFile(hostsFile),
|
||||||
|
m_reflectors()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CYSFReflectors::~CYSFReflectors()
|
||||||
|
{
|
||||||
|
for (std::vector<CYSFReflector*>::iterator it = m_reflectors.begin(); it != m_reflectors.end(); ++it)
|
||||||
|
delete *it;
|
||||||
|
|
||||||
|
m_reflectors.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CYSFReflectors::load()
|
||||||
|
{
|
||||||
|
FILE* fp = ::fopen(m_hostsFile.c_str(), "rt");
|
||||||
|
if (fp != NULL) {
|
||||||
|
char buffer[100U];
|
||||||
|
while (::fgets(buffer, 100U, fp) != NULL) {
|
||||||
|
if (buffer[0U] == '#')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
char* p1 = ::strtok(buffer, ";\r\n");
|
||||||
|
char* p2 = ::strtok(NULL, ";\r\n");
|
||||||
|
char* p3 = ::strtok(NULL, ";\r\n");
|
||||||
|
char* p4 = ::strtok(NULL, ";\r\n");
|
||||||
|
char* p5 = ::strtok(NULL, ";\r\n");
|
||||||
|
char* p6 = ::strtok(NULL, "\r\n");
|
||||||
|
|
||||||
|
if (p1 != NULL && p2 != NULL && p3 != NULL && p4 != NULL && p5 != NULL && p6 != NULL) {
|
||||||
|
std::string host = std::string(p4);
|
||||||
|
|
||||||
|
in_addr address = CUDPSocket::lookup(host);
|
||||||
|
if (address.s_addr != INADDR_NONE) {
|
||||||
|
CYSFReflector* refl = new CYSFReflector;
|
||||||
|
refl->m_id = std::string(p1);
|
||||||
|
refl->m_name = std::string(p2);
|
||||||
|
refl->m_address = address;
|
||||||
|
refl->m_port = (unsigned int)::atoi(p5);
|
||||||
|
|
||||||
|
m_reflectors.push_back(refl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size = m_reflectors.size();
|
||||||
|
LogInfo("Loaded %u YSF reflectors", size);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CYSFReflector* CYSFReflectors::findById(const std::string& id)
|
||||||
|
{
|
||||||
|
for (std::vector<CYSFReflector*>::const_iterator it = m_reflectors.cbegin(); it != m_reflectors.cend(); ++it) {
|
||||||
|
if (id == (*it)->m_id)
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogMessage("Trying to find non existent YSF reflector with an id of %s", id.c_str());
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CYSFReflector* CYSFReflectors::findByName(const std::string& name)
|
||||||
|
{
|
||||||
|
for (std::vector<CYSFReflector*>::const_iterator it = m_reflectors.cbegin(); it != m_reflectors.cend(); ++it) {
|
||||||
|
if (name == (*it)->m_name)
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogMessage("Trying to find non existent YSF reflector with a name of %s", name.c_str());
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
58
DGIdGateway/YSFReflectors.h
Normal file
58
DGIdGateway/YSFReflectors.h
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016-2020 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(YSFReflectors_H)
|
||||||
|
#define YSFReflectors_H
|
||||||
|
|
||||||
|
#include "UDPSocket.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class CYSFReflector {
|
||||||
|
public:
|
||||||
|
CYSFReflector() :
|
||||||
|
m_id(),
|
||||||
|
m_name(),
|
||||||
|
m_address(),
|
||||||
|
m_port(0U)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string m_id;
|
||||||
|
std::string m_name;
|
||||||
|
in_addr m_address;
|
||||||
|
unsigned int m_port;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CYSFReflectors {
|
||||||
|
public:
|
||||||
|
CYSFReflectors(const std::string& hostsFile);
|
||||||
|
~CYSFReflectors();
|
||||||
|
|
||||||
|
bool load();
|
||||||
|
|
||||||
|
CYSFReflector* findById(const std::string& id);
|
||||||
|
CYSFReflector* findByName(const std::string& name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_hostsFile;
|
||||||
|
std::vector<CYSFReflector*> m_reflectors;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
2
Makefile
2
Makefile
|
@ -1,4 +1,4 @@
|
||||||
SUBDIRS = YSFGateway YSFParrot YSFReflector
|
SUBDIRS = DGIdGateway YSFGateway YSFParrot YSFReflector
|
||||||
CLEANDIRS = $(SUBDIRS:%=clean-%)
|
CLEANDIRS = $(SUBDIRS:%=clean-%)
|
||||||
INSTALLDIRS = $(SUBDIRS:%=install-%)
|
INSTALLDIRS = $(SUBDIRS:%=install-%)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue