Rewrite the networking for dual IPv4 and IPv6.

This commit is contained in:
Jonathan Naylor 2020-11-04 11:50:57 +00:00
parent ef58905da9
commit bfbdfea30b
12 changed files with 283 additions and 67 deletions

View File

@ -41,6 +41,7 @@ m_file(file),
m_callsign(), m_callsign(),
m_rptAddress(), m_rptAddress(),
m_rptPort(0U), m_rptPort(0U),
m_myAddress(),
m_myPort(0U), m_myPort(0U),
m_debug(false), m_debug(false),
m_daemon(false), m_daemon(false),
@ -142,6 +143,8 @@ bool CConf::read()
m_rptAddress = value; m_rptAddress = value;
else if (::strcmp(key, "RptPort") == 0) else if (::strcmp(key, "RptPort") == 0)
m_rptPort = (unsigned int)::atoi(value); m_rptPort = (unsigned int)::atoi(value);
else if (::strcmp(key, "LocalAddress") == 0)
m_myAddress = value;
else if (::strcmp(key, "LocalPort") == 0) else if (::strcmp(key, "LocalPort") == 0)
m_myPort = (unsigned int)::atoi(value); m_myPort = (unsigned int)::atoi(value);
else if (::strcmp(key, "Debug") == 0) else if (::strcmp(key, "Debug") == 0)
@ -229,6 +232,11 @@ unsigned int CConf::getRptPort() const
return m_rptPort; return m_rptPort;
} }
std::string CConf::getMyAddress() const
{
return m_myAddress;
}
unsigned int CConf::getMyPort() const unsigned int CConf::getMyPort() const
{ {
return m_myPort; return m_myPort;

View File

@ -34,6 +34,7 @@ public:
std::string getCallsign() const; std::string getCallsign() const;
std::string getRptAddress() const; std::string getRptAddress() const;
unsigned int getRptPort() const; unsigned int getRptPort() const;
std::string getMyAddress() const;
unsigned int getMyPort() const; unsigned int getMyPort() const;
bool getDebug() const; bool getDebug() const;
bool getDaemon() const; bool getDaemon() const;
@ -77,6 +78,7 @@ private:
std::string m_callsign; std::string m_callsign;
std::string m_rptAddress; std::string m_rptAddress;
unsigned int m_rptPort; unsigned int m_rptPort;
std::string m_myAddress;
unsigned int m_myPort; unsigned int m_myPort;
bool m_debug; bool m_debug;
bool m_daemon; bool m_daemon;

View File

@ -1,10 +1,10 @@
CC = cc CC = cc
CXX = c++ CXX = c++
CFLAGS = -g -O3 -Wall -DHAVE_LOG_H -std=c++0x -pthread CFLAGS = -g -O3 -Wall -DHAVE_LOG_H -DUDP_SOCKET_MAX=2 -std=c++0x -pthread
LIBS = -lpthread LIBS = -lpthread
LDFLAGS = -g LDFLAGS = -g
OBJECTS = Conf.o DMRLookup.o Log.o Mutex.o Network.o P25Gateway.o Reflectors.o StopWatch.o Thread.o Timer.o UDPSocket.o Utils.o Voice.o OBJECTS = Conf.o DMRLookup.o Log.o Mutex.o P25Gateway.o P25Network.o Reflectors.o RptNetwork.o StopWatch.o Thread.o Timer.o UDPSocket.o Utils.o Voice.o
all: P25Gateway all: P25Gateway

View File

@ -17,10 +17,11 @@
*/ */
#include "P25Gateway.h" #include "P25Gateway.h"
#include "RptNetwork.h"
#include "P25Network.h"
#include "Reflectors.h" #include "Reflectors.h"
#include "StopWatch.h" #include "StopWatch.h"
#include "DMRLookup.h" #include "DMRLookup.h"
#include "Network.h"
#include "Version.h" #include "Version.h"
#include "Thread.h" #include "Thread.h"
#include "Voice.h" #include "Voice.h"
@ -188,14 +189,14 @@ void CP25Gateway::run()
return; return;
} }
CNetwork localNetwork(m_conf.getMyPort(), m_conf.getCallsign(), m_conf.getDebug()); CRptNetwork localNetwork(m_conf.getMyAddress(), m_conf.getMyPort(), rptAddr, rptAddrLen, m_conf.getCallsign(), m_conf.getDebug());
ret = localNetwork.open(); ret = localNetwork.open();
if (!ret) { if (!ret) {
::LogFinalise(); ::LogFinalise();
return; return;
} }
CNetwork remoteNetwork(m_conf.getNetworkPort(), m_conf.getCallsign(), m_conf.getNetworkDebug()); CP25Network remoteNetwork(m_conf.getNetworkPort(), m_conf.getCallsign(), m_conf.getNetworkDebug());
ret = remoteNetwork.open(); ret = remoteNetwork.open();
if (!ret) { if (!ret) {
localNetwork.close(); localNetwork.close();
@ -266,9 +267,9 @@ void CP25Gateway::run()
staticTG.m_addrLen = reflector->m_addrLen; staticTG.m_addrLen = reflector->m_addrLen;
staticTGs.push_back(staticTG); staticTGs.push_back(staticTG);
remoteNetwork.writePoll(staticTG.m_addr, staticTG.m_addrLen); remoteNetwork.poll(staticTG.m_addr, staticTG.m_addrLen);
remoteNetwork.writePoll(staticTG.m_addr, staticTG.m_addrLen); remoteNetwork.poll(staticTG.m_addr, staticTG.m_addrLen);
remoteNetwork.writePoll(staticTG.m_addr, staticTG.m_addrLen); remoteNetwork.poll(staticTG.m_addr, staticTG.m_addrLen);
LogMessage("Statically linked to reflector %u", *it); LogMessage("Statically linked to reflector %u", *it);
} }
@ -280,7 +281,7 @@ void CP25Gateway::run()
unsigned int addrLen; unsigned int addrLen;
// From the reflector to the MMDVM // From the reflector to the MMDVM
unsigned int len = remoteNetwork.readData(buffer, 200U, addr, addrLen); unsigned int len = remoteNetwork.read(buffer, 200U, addr, addrLen);
if (len > 0U) { if (len > 0U) {
// If we're linked and it's from the right place, send it on // If we're linked and it's from the right place, send it on
if (currentAddrLen > 0U && CUDPSocket::match(currentAddr, addr)) { if (currentAddrLen > 0U && CUDPSocket::match(currentAddr, addr)) {
@ -295,7 +296,7 @@ void CP25Gateway::run()
buffer[3U] = (currentTG >> 0) & 0xFFU; buffer[3U] = (currentTG >> 0) & 0xFFU;
} }
localNetwork.writeData(buffer, len, rptAddr, rptAddrLen); localNetwork.write(buffer, len);
hangTimer.start(); hangTimer.start();
} }
@ -324,7 +325,7 @@ void CP25Gateway::run()
buffer[3U] = (currentTG >> 0) & 0xFFU; buffer[3U] = (currentTG >> 0) & 0xFFU;
} }
localNetwork.writeData(buffer, len, rptAddr, rptAddrLen); localNetwork.write(buffer, len);
LogMessage("Switched to reflector %u due to network activity", currentTG); LogMessage("Switched to reflector %u due to network activity", currentTG);
@ -336,7 +337,7 @@ void CP25Gateway::run()
} }
// From the MMDVM to the reflector or control data // From the MMDVM to the reflector or control data
len = localNetwork.readData(buffer, 200U, addr, addrLen); len = localNetwork.read(buffer, 200U);
if (len > 0U) { if (len > 0U) {
if (buffer[0U] == 0x65U) { if (buffer[0U] == 0x65U) {
dstTG = (buffer[1U] << 16) & 0xFF0000U; dstTG = (buffer[1U] << 16) & 0xFF0000U;
@ -353,9 +354,9 @@ void CP25Gateway::run()
LogMessage("Unlinking from reflector %u by %s", currentTG, callsign.c_str()); LogMessage("Unlinking from reflector %u by %s", currentTG, callsign.c_str());
if (!currentIsStatic) { if (!currentIsStatic) {
remoteNetwork.writeUnlink(currentAddr, currentAddrLen); remoteNetwork.unlink(currentAddr, currentAddrLen);
remoteNetwork.writeUnlink(currentAddr, currentAddrLen); remoteNetwork.unlink(currentAddr, currentAddrLen);
remoteNetwork.writeUnlink(currentAddr, currentAddrLen); remoteNetwork.unlink(currentAddr, currentAddrLen);
} }
hangTimer.stop(); hangTimer.stop();
@ -394,9 +395,9 @@ void CP25Gateway::run()
LogMessage("Switched to reflector %u due to RF activity from %s", currentTG, callsign.c_str()); LogMessage("Switched to reflector %u due to RF activity from %s", currentTG, callsign.c_str());
if (!currentIsStatic) { if (!currentIsStatic) {
remoteNetwork.writePoll(currentAddr, currentAddrLen); remoteNetwork.poll(currentAddr, currentAddrLen);
remoteNetwork.writePoll(currentAddr, currentAddrLen); remoteNetwork.poll(currentAddr, currentAddrLen);
remoteNetwork.writePoll(currentAddr, currentAddrLen); remoteNetwork.poll(currentAddr, currentAddrLen);
} }
hangTimer.setTimeout(rfHangTime); hangTimer.setTimeout(rfHangTime);
@ -430,7 +431,7 @@ void CP25Gateway::run()
buffer[3U] = (currentTG >> 0) & 0xFFU; buffer[3U] = (currentTG >> 0) & 0xFFU;
} }
remoteNetwork.writeData(buffer, len, currentAddr, currentAddrLen); remoteNetwork.write(buffer, len, currentAddr, currentAddrLen);
hangTimer.start(); hangTimer.start();
} }
} }
@ -438,7 +439,7 @@ void CP25Gateway::run()
if (voice != NULL) { if (voice != NULL) {
unsigned int length = voice->read(buffer); unsigned int length = voice->read(buffer);
if (length > 0U) if (length > 0U)
localNetwork.writeData(buffer, length, rptAddr, rptAddrLen); localNetwork.write(buffer, length);
} }
if (remoteSocket != NULL) { if (remoteSocket != NULL) {
@ -455,9 +456,9 @@ void CP25Gateway::run()
LogMessage("Unlinked from reflector %u by remote command", currentTG); LogMessage("Unlinked from reflector %u by remote command", currentTG);
if (!currentIsStatic) { if (!currentIsStatic) {
remoteNetwork.writeUnlink(currentAddr, currentAddrLen); remoteNetwork.unlink(currentAddr, currentAddrLen);
remoteNetwork.writeUnlink(currentAddr, currentAddrLen); remoteNetwork.unlink(currentAddr, currentAddrLen);
remoteNetwork.writeUnlink(currentAddr, currentAddrLen); remoteNetwork.unlink(currentAddr, currentAddrLen);
} }
hangTimer.stop(); hangTimer.stop();
@ -495,9 +496,9 @@ void CP25Gateway::run()
LogMessage("Switched to reflector %u by remote command", currentTG); LogMessage("Switched to reflector %u by remote command", currentTG);
if (!currentIsStatic) { if (!currentIsStatic) {
remoteNetwork.writePoll(currentAddr, currentAddrLen); remoteNetwork.poll(currentAddr, currentAddrLen);
remoteNetwork.writePoll(currentAddr, currentAddrLen); remoteNetwork.poll(currentAddr, currentAddrLen);
remoteNetwork.writePoll(currentAddr, currentAddrLen); remoteNetwork.poll(currentAddr, currentAddrLen);
} }
hangTimer.setTimeout(rfHangTime); hangTimer.setTimeout(rfHangTime);
@ -533,9 +534,9 @@ void CP25Gateway::run()
LogMessage("Unlinking from %u due to inactivity", currentTG); LogMessage("Unlinking from %u due to inactivity", currentTG);
if (!currentIsStatic) { if (!currentIsStatic) {
remoteNetwork.writeUnlink(currentAddr, currentAddrLen); remoteNetwork.unlink(currentAddr, currentAddrLen);
remoteNetwork.writeUnlink(currentAddr, currentAddrLen); remoteNetwork.unlink(currentAddr, currentAddrLen);
remoteNetwork.writeUnlink(currentAddr, currentAddrLen); remoteNetwork.unlink(currentAddr, currentAddrLen);
} }
if (voice != NULL) if (voice != NULL)
@ -549,15 +550,17 @@ void CP25Gateway::run()
currentTG = 0U; currentTG = 0U;
} }
localNetwork.clock(ms);
pollTimer.clock(ms); pollTimer.clock(ms);
if (pollTimer.isRunning() && pollTimer.hasExpired()) { if (pollTimer.isRunning() && pollTimer.hasExpired()) {
// Poll the static TGs // Poll the static TGs
for (std::vector<CStaticTG>::const_iterator it = staticTGs.cbegin(); it != staticTGs.cend(); ++it) for (std::vector<CStaticTG>::const_iterator it = staticTGs.cbegin(); it != staticTGs.cend(); ++it)
remoteNetwork.writePoll((*it).m_addr, (*it).m_addrLen); remoteNetwork.poll((*it).m_addr, (*it).m_addrLen);
// Poll the dynamic TG // Poll the dynamic TG
if (!currentIsStatic && currentAddrLen > 0U) if (!currentIsStatic && currentAddrLen > 0U)
remoteNetwork.writePoll(currentAddr, currentAddrLen); remoteNetwork.poll(currentAddr, currentAddrLen);
pollTimer.start(); pollTimer.start();
} }

View File

@ -2,6 +2,7 @@
Callsign=G4KLX Callsign=G4KLX
RptAddress=127.0.0.1 RptAddress=127.0.0.1
RptPort=32010 RptPort=32010
LocalAddress=127.0.0.1
LocalPort=42020 LocalPort=42020
Debug=0 Debug=0
Daemon=1 Daemon=1

View File

@ -87,7 +87,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>HAVE_LOG_H;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>HAVE_LOG_H;UDP_SOCKET_MAX=2;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -101,7 +101,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>HAVE_LOG_H;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>HAVE_LOG_H;UDP_SOCKET_MAX=2;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -117,7 +117,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>HAVE_LOG_H;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>HAVE_LOG_H;UDP_SOCKET_MAX=2;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -135,7 +135,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>HAVE_LOG_H;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>HAVE_LOG_H;UDP_SOCKET_MAX=2;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -150,9 +150,10 @@
<ClInclude Include="DMRLookup.h" /> <ClInclude Include="DMRLookup.h" />
<ClInclude Include="Log.h" /> <ClInclude Include="Log.h" />
<ClInclude Include="Mutex.h" /> <ClInclude Include="Mutex.h" />
<ClInclude Include="Network.h" />
<ClInclude Include="P25Gateway.h" /> <ClInclude Include="P25Gateway.h" />
<ClInclude Include="P25Network.h" />
<ClInclude Include="Reflectors.h" /> <ClInclude Include="Reflectors.h" />
<ClInclude Include="RptNetwork.h" />
<ClInclude Include="StopWatch.h" /> <ClInclude Include="StopWatch.h" />
<ClInclude Include="Thread.h" /> <ClInclude Include="Thread.h" />
<ClInclude Include="Timer.h" /> <ClInclude Include="Timer.h" />
@ -166,9 +167,10 @@
<ClCompile Include="DMRLookup.cpp" /> <ClCompile Include="DMRLookup.cpp" />
<ClCompile Include="Log.cpp" /> <ClCompile Include="Log.cpp" />
<ClCompile Include="Mutex.cpp" /> <ClCompile Include="Mutex.cpp" />
<ClCompile Include="Network.cpp" />
<ClCompile Include="P25Gateway.cpp" /> <ClCompile Include="P25Gateway.cpp" />
<ClCompile Include="P25Network.cpp" />
<ClCompile Include="Reflectors.cpp" /> <ClCompile Include="Reflectors.cpp" />
<ClCompile Include="RptNetwork.cpp" />
<ClCompile Include="StopWatch.cpp" /> <ClCompile Include="StopWatch.cpp" />
<ClCompile Include="Thread.cpp" /> <ClCompile Include="Thread.cpp" />
<ClCompile Include="Timer.cpp" /> <ClCompile Include="Timer.cpp" />

View File

@ -23,9 +23,6 @@
<ClInclude Include="Mutex.h"> <ClInclude Include="Mutex.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Network.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="P25Gateway.h"> <ClInclude Include="P25Gateway.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
@ -53,6 +50,12 @@
<ClInclude Include="Voice.h"> <ClInclude Include="Voice.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="P25Network.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="RptNetwork.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="Conf.cpp"> <ClCompile Include="Conf.cpp">
@ -67,9 +70,6 @@
<ClCompile Include="Mutex.cpp"> <ClCompile Include="Mutex.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Network.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="P25Gateway.cpp"> <ClCompile Include="P25Gateway.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
@ -94,5 +94,11 @@
<ClCompile Include="Voice.cpp"> <ClCompile Include="Voice.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="P25Network.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="RptNetwork.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include "Network.h" #include "P25Network.h"
#include "Utils.h" #include "Utils.h"
#include "Log.h" #include "Log.h"
@ -24,26 +24,33 @@
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
CNetwork::CNetwork(unsigned int port, const std::string& callsign, bool debug) : CP25Network::CP25Network(unsigned int port, const std::string& callsign, bool debug) :
m_callsign(callsign), m_callsign(callsign),
m_socket(port), m_socket(),
m_port(port),
m_debug(debug) m_debug(debug)
{ {
assert(port > 0U);
m_callsign.resize(10U, ' '); m_callsign.resize(10U, ' ');
} }
CNetwork::~CNetwork() CP25Network::~CP25Network()
{ {
} }
bool CNetwork::open() bool CP25Network::open()
{ {
LogInfo("Opening P25 network connection"); LogInfo("Opening P25 network connection");
return m_socket.open(); bool ret = m_socket.open(0, PF_INET, "", m_port);
if (!ret)
return false;
return m_socket.open(1, PF_INET6, "", m_port);
} }
bool CNetwork::writeData(const unsigned char* data, unsigned int length, const sockaddr_storage& addr, unsigned int addrLen) bool CP25Network::write(const unsigned char* data, unsigned int length, const sockaddr_storage& addr, unsigned int addrLen)
{ {
assert(data != NULL); assert(data != NULL);
assert(length > 0U); assert(length > 0U);
@ -54,7 +61,7 @@ bool CNetwork::writeData(const unsigned char* data, unsigned int length, const s
return m_socket.write(data, length, addr, addrLen); return m_socket.write(data, length, addr, addrLen);
} }
bool CNetwork::writePoll(const sockaddr_storage& addr, unsigned int addrLen) bool CP25Network::poll(const sockaddr_storage& addr, unsigned int addrLen)
{ {
unsigned char data[15U]; unsigned char data[15U];
@ -69,7 +76,7 @@ bool CNetwork::writePoll(const sockaddr_storage& addr, unsigned int addrLen)
return m_socket.write(data, 11U, addr, addrLen); return m_socket.write(data, 11U, addr, addrLen);
} }
bool CNetwork::writeUnlink(const sockaddr_storage& addr, unsigned int addrLen) bool CP25Network::unlink(const sockaddr_storage& addr, unsigned int addrLen)
{ {
unsigned char data[15U]; unsigned char data[15U];
@ -84,7 +91,7 @@ bool CNetwork::writeUnlink(const sockaddr_storage& addr, unsigned int addrLen)
return m_socket.write(data, 11U, addr, addrLen); return m_socket.write(data, 11U, addr, addrLen);
} }
unsigned int CNetwork::readData(unsigned char* data, unsigned int length, sockaddr_storage& addr, unsigned int& addrLen) unsigned int CP25Network::read(unsigned char* data, unsigned int length, sockaddr_storage& addr, unsigned int& addrLen)
{ {
assert(data != NULL); assert(data != NULL);
assert(length > 0U); assert(length > 0U);
@ -99,7 +106,7 @@ unsigned int CNetwork::readData(unsigned char* data, unsigned int length, sockad
return len; return len;
} }
void CNetwork::close() void CP25Network::close()
{ {
m_socket.close(); m_socket.close();

View File

@ -16,34 +16,35 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef Network_H #ifndef P25Network_H
#define Network_H #define P25Network_H
#include "UDPSocket.h" #include "UDPSocket.h"
#include <cstdint> #include <cstdint>
#include <string> #include <string>
class CNetwork { class CP25Network {
public: public:
CNetwork(unsigned int port, const std::string& callsign, bool debug); CP25Network(unsigned int port, const std::string& callsign, bool debug);
~CNetwork(); ~CP25Network();
bool open(); bool open();
bool writeData(const unsigned char* data, unsigned int length, const sockaddr_storage& addr, unsigned int addrLen); bool write(const unsigned char* data, unsigned int length, const sockaddr_storage& addr, unsigned int addrLen);
unsigned int readData(unsigned char* data, unsigned int length, sockaddr_storage& addr, unsigned int& addrLen); unsigned int read(unsigned char* data, unsigned int length, sockaddr_storage& addr, unsigned int& addrLen);
bool writePoll(const sockaddr_storage& addr, unsigned int addrLen); bool poll(const sockaddr_storage& addr, unsigned int addrLen);
bool writeUnlink(const sockaddr_storage& addr, unsigned int addrLen); bool unlink(const sockaddr_storage& addr, unsigned int addrLen);
void close(); void close();
private: private:
std::string m_callsign; std::string m_callsign;
CUDPSocket m_socket; CUDPSocket m_socket;
unsigned int m_port;
bool m_debug; bool m_debug;
}; };

130
P25Gateway/RptNetwork.cpp Normal file
View File

@ -0,0 +1,130 @@
/*
* Copyright (C) 2009-2014,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 "RptNetwork.h"
#include "Utils.h"
#include "Log.h"
#include <cstdio>
#include <cassert>
#include <cstring>
CRptNetwork::CRptNetwork(const std::string& myAddr, unsigned int myPort, const sockaddr_storage& rptAddr, unsigned int rptAddrLen, const std::string& callsign, bool debug) :
m_myAddr(),
m_myAddrLen(0U),
m_rptAddr(rptAddr),
m_rptAddrLen(rptAddrLen),
m_callsign(callsign),
m_socket(myAddr, myPort),
m_debug(debug),
m_timer(1000U, 5U)
{
assert(myPort > 0U);
assert(rptAddrLen > 0U);
CUDPSocket::lookup(myAddr, myPort, m_myAddr, m_myAddrLen);
m_callsign.resize(10U, ' ');
}
CRptNetwork::~CRptNetwork()
{
}
bool CRptNetwork::open()
{
if (m_myAddrLen == 0U) {
LogError("Unable to resolve the local address and port");
return false;
}
LogInfo("Opening Rpt network connection");
bool ret = m_socket.open(m_myAddr);
if (ret) {
m_timer.start();
return true;
} else {
return false;
}
}
bool CRptNetwork::write(const unsigned char* data, unsigned int length)
{
assert(data != NULL);
assert(length > 0U);
if (m_debug)
CUtils::dump(1U, "Rpt Network Data Sent", data, length);
return m_socket.write(data, length, m_rptAddr, m_rptAddrLen);
}
bool CRptNetwork::writePoll()
{
unsigned char data[15U];
data[0U] = 0xF0U;
for (unsigned int i = 0U; i < 10U; i++)
data[i + 1U] = m_callsign.at(i);
if (m_debug)
CUtils::dump(1U, "Rpt Network Poll Sent", data, 11U);
return m_socket.write(data, 11U, m_rptAddr, m_rptAddrLen);
}
unsigned int CRptNetwork::read(unsigned char* data, unsigned int length)
{
assert(data != NULL);
assert(length > 0U);
sockaddr_storage addr;
unsigned int addrLen = 0U;
int len = m_socket.read(data, length, addr, addrLen);
if (len <= 0)
return 0U;
if (!CUDPSocket::match(addr, m_rptAddr))
return 0U;
if (m_debug)
CUtils::dump(1U, "Rpt Network Data Received", data, len);
return len;
}
void CRptNetwork::clock(unsigned int ms)
{
m_timer.clock(ms);
if (m_timer.isRunning() && m_timer.hasExpired()) {
writePoll();
m_timer.start();
}
}
void CRptNetwork::close()
{
m_timer.stop();
m_socket.close();
LogInfo("Closing Rpt network connection");
}

56
P25Gateway/RptNetwork.h Normal file
View File

@ -0,0 +1,56 @@
/*
* Copyright (C) 2009-2014,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.
*/
#ifndef RptNetwork_H
#define RptNetwork_H
#include "UDPSocket.h"
#include "Timer.h"
#include <cstdint>
#include <string>
class CRptNetwork {
public:
CRptNetwork(const std::string& myAddr, unsigned int myPort, const sockaddr_storage& rptAddr, unsigned int rptAddrLen, const std::string& callsign, bool debug);
~CRptNetwork();
bool open();
bool write(const unsigned char* data, unsigned int length);
unsigned int read(unsigned char* data, unsigned int length);
void clock(unsigned int ms);
void close();
private:
sockaddr_storage m_myAddr;
unsigned int m_myAddrLen;
sockaddr_storage m_rptAddr;
unsigned int m_rptAddrLen;
std::string m_callsign;
CUDPSocket m_socket;
bool m_debug;
CTimer m_timer;
bool writePoll();
};
#endif

View File

@ -19,6 +19,6 @@
#if !defined(VERSION_H) #if !defined(VERSION_H)
#define VERSION_H #define VERSION_H
const char* VERSION = "20201102"; const char* VERSION = "20201104";
#endif #endif