diff --git a/DMRControl.cpp b/DMRControl.cpp index d13b43f..2e2ce71 100644 --- a/DMRControl.cpp +++ b/DMRControl.cpp @@ -20,7 +20,7 @@ #include #include -CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& blackList, const std::vector& DstIdBlacklistSlot1RF, const std::vector& DstIdWhitelistSlot1RF, const std::vector& DstIdBlacklistSlot2RF, const std::vector& DstIdWhitelistSlot2RF, const std::vector& DstIdBlacklistSlot1NET, const std::vector& DstIdWhitelistSlot1NET, const std::vector& DstIdBlacklistSlot2NET, const std::vector& DstIdWhitelistSlot2NET, unsigned int timeout, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter) : +CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& blackList, const std::vector& DstIdBlacklistSlot1RF, const std::vector& DstIdWhitelistSlot1RF, const std::vector& DstIdBlacklistSlot2RF, const std::vector& DstIdWhitelistSlot2RF, const std::vector& DstIdBlacklistSlot1NET, const std::vector& DstIdWhitelistSlot1NET, const std::vector& DstIdBlacklistSlot2NET, const std::vector& DstIdWhitelistSlot2NET, unsigned int timeout, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter) : m_id(id), m_colorCode(colorCode), m_selfOnly(selfOnly), diff --git a/DMRControl.h b/DMRControl.h index 09ed3be..870271d 100644 --- a/DMRControl.h +++ b/DMRControl.h @@ -19,8 +19,8 @@ #if !defined(DMRControl_H) #define DMRControl_H +#include "DMRNetwork.h" #include "DMRLookup.h" -#include "DMRIPSC.h" #include "Display.h" #include "DMRSlot.h" #include "DMRData.h" @@ -30,7 +30,7 @@ class CDMRControl { public: - CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& blackList, const std::vector& DstIdBlacklistSlot1RF, const std::vector& DstIdWhitelistSlot1RF, const std::vector& DstIdBlacklistSlot2RF, const std::vector& DstIdWhitelistSlot2RF,const std::vector& DstIdBlacklistSlot1NET, const std::vector& DstIdWhitelistSlot1NET, const std::vector& DstIdBlacklistSlot2NET, const std::vector& DstIdWhitelistSlot2NET, unsigned int timeout, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter); + CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& blackList, const std::vector& DstIdBlacklistSlot1RF, const std::vector& DstIdWhitelistSlot1RF, const std::vector& DstIdBlacklistSlot2RF, const std::vector& DstIdWhitelistSlot2RF,const std::vector& DstIdBlacklistSlot1NET, const std::vector& DstIdWhitelistSlot1NET, const std::vector& DstIdBlacklistSlot2NET, const std::vector& DstIdWhitelistSlot2NET, unsigned int timeout, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter); ~CDMRControl(); bool processWakeup(const unsigned char* data); @@ -50,7 +50,7 @@ private: std::vector m_prefixes; std::vector m_blackList; CModem* m_modem; - CDMRIPSC* m_network; + CDMRNetwork* m_network; CDMRSlot m_slot1; CDMRSlot m_slot2; CDMRLookup* m_lookup; diff --git a/DMRIPSC.cpp b/DMRNetwork.cpp similarity index 88% rename from DMRIPSC.cpp rename to DMRNetwork.cpp index 0849734..94fe8a8 100644 --- a/DMRIPSC.cpp +++ b/DMRNetwork.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "DMRIPSC.h" +#include "DMRNetwork.h" #include "StopWatch.h" #include "SHA256.h" @@ -31,7 +31,7 @@ const unsigned int BUFFER_LENGTH = 500U; const unsigned int HOMEBREW_DATA_PACKET_LENGTH = 55U; -CDMRIPSC::CDMRIPSC(const std::string& address, unsigned int port, unsigned int local, unsigned int id, const std::string& password, bool duplex, const char* version, bool debug, bool slot1, bool slot2, bool rssi, HW_TYPE hwType) : +CDMRNetwork::CDMRNetwork(const std::string& address, unsigned int port, unsigned int local, unsigned int id, const std::string& password, bool duplex, const char* version, bool debug, bool slot1, bool slot2, bool rssi, HW_TYPE hwType) : m_address(), m_port(port), m_id(NULL), @@ -51,7 +51,7 @@ m_timeoutTimer(1000U, 60U), m_buffer(NULL), m_salt(NULL), m_streamId(NULL), -m_rxData(1000U, "DMR IPSC"), +m_rxData(1000U, "DMR Network"), m_callsign(), m_rxFrequency(0U), m_txFrequency(0U), @@ -89,7 +89,7 @@ m_beacon(false) ::srand(stopWatch.start()); } -CDMRIPSC::~CDMRIPSC() +CDMRNetwork::~CDMRNetwork() { delete[] m_buffer; delete[] m_salt; @@ -97,7 +97,7 @@ CDMRIPSC::~CDMRIPSC() delete[] m_id; } -void CDMRIPSC::setConfig(const std::string& callsign, unsigned int rxFrequency, unsigned int txFrequency, unsigned int power, unsigned int colorCode, float latitude, float longitude, int height, const std::string& location, const std::string& description, const std::string& url) +void CDMRNetwork::setConfig(const std::string& callsign, unsigned int rxFrequency, unsigned int txFrequency, unsigned int power, unsigned int colorCode, float latitude, float longitude, int height, const std::string& location, const std::string& description, const std::string& url) { m_callsign = callsign; m_rxFrequency = rxFrequency; @@ -112,9 +112,9 @@ void CDMRIPSC::setConfig(const std::string& callsign, unsigned int rxFrequency, m_url = url; } -bool CDMRIPSC::open() +bool CDMRNetwork::open() { - LogMessage("Opening DMR IPSC"); + LogMessage("Opening DMR Network"); bool ret = m_socket.open(); if (!ret) @@ -127,12 +127,12 @@ bool CDMRIPSC::open() return true; } -void CDMRIPSC::enable(bool enabled) +void CDMRNetwork::enable(bool enabled) { m_enabled = enabled; } -bool CDMRIPSC::read(CDMRData& data) +bool CDMRNetwork::read(CDMRData& data) { if (m_status != RUNNING) return false; @@ -197,7 +197,7 @@ bool CDMRIPSC::read(CDMRData& data) return true; } -bool CDMRIPSC::write(const CDMRData& data) +bool CDMRNetwork::write(const CDMRData& data) { if (m_status != RUNNING) return false; @@ -272,7 +272,7 @@ bool CDMRIPSC::write(const CDMRData& data) buffer[54U] = 0x00U; if (m_debug) - CUtils::dump(1U, "IPSC Transmitted", buffer, HOMEBREW_DATA_PACKET_LENGTH); + CUtils::dump(1U, "Network Transmitted", buffer, HOMEBREW_DATA_PACKET_LENGTH); for (unsigned int i = 0U; i < count; i++) write(buffer, HOMEBREW_DATA_PACKET_LENGTH); @@ -280,9 +280,9 @@ bool CDMRIPSC::write(const CDMRData& data) return true; } -void CDMRIPSC::close() +void CDMRNetwork::close() { - LogMessage("Closing DMR IPSC"); + LogMessage("Closing DMR Network"); if (m_status == RUNNING) { unsigned char buffer[9U]; @@ -297,7 +297,7 @@ void CDMRIPSC::close() m_timeoutTimer.stop(); } -void CDMRIPSC::clock(unsigned int ms) +void CDMRNetwork::clock(unsigned int ms) { if (m_status == WAITING_CONNECT) { m_retryTimer.clock(ms); @@ -322,13 +322,13 @@ void CDMRIPSC::clock(unsigned int ms) } // if (m_debug && length > 0) - // CUtils::dump(1U, "IPSC Received", m_buffer, length); + // CUtils::dump(1U, "Network Received", m_buffer, length); if (length > 0 && m_address.s_addr == address.s_addr && m_port == port) { if (::memcmp(m_buffer, "DMRD", 4U) == 0) { if (m_enabled) { if (m_debug) - CUtils::dump(1U, "IPSC Received", m_buffer, length); + CUtils::dump(1U, "Network Received", m_buffer, length); unsigned char len = length; m_rxData.addData(&len, 1U); @@ -342,7 +342,7 @@ void CDMRIPSC::clock(unsigned int ms) m_retryTimer.start(); } else { /* Once the modem death spiral has been prevented in Modem.cpp - the IPSC sometimes times out and reaches here. + the Network sometimes times out and reaches here. We want it to reconnect so... */ LogError("Login to the master has failed, retrying ..."); close(); @@ -419,7 +419,7 @@ void CDMRIPSC::clock(unsigned int ms) } } -bool CDMRIPSC::writeLogin() +bool CDMRNetwork::writeLogin() { unsigned char buffer[8U]; @@ -429,7 +429,7 @@ bool CDMRIPSC::writeLogin() return write(buffer, 8U); } -bool CDMRIPSC::writeAuthorisation() +bool CDMRNetwork::writeAuthorisation() { unsigned int size = m_password.size(); @@ -450,7 +450,7 @@ bool CDMRIPSC::writeAuthorisation() return write(out, 40U); } -bool CDMRIPSC::writeConfig() +bool CDMRNetwork::writeConfig() { const char* software = "MMDVM"; char slots = '0'; @@ -489,7 +489,7 @@ bool CDMRIPSC::writeConfig() return write((unsigned char*)buffer, 302U); } -bool CDMRIPSC::writePing() +bool CDMRNetwork::writePing() { unsigned char buffer[11U]; @@ -499,7 +499,7 @@ bool CDMRIPSC::writePing() return write(buffer, 11U); } -bool CDMRIPSC::wantsBeacon() +bool CDMRNetwork::wantsBeacon() { bool beacon = m_beacon; @@ -508,13 +508,13 @@ bool CDMRIPSC::wantsBeacon() return beacon; } -bool CDMRIPSC::write(const unsigned char* data, unsigned int length) +bool CDMRNetwork::write(const unsigned char* data, unsigned int length) { assert(data != NULL); assert(length > 0U); // if (m_debug) - // CUtils::dump(1U, "IPSC Transmitted", data, length); + // CUtils::dump(1U, "Network Transmitted", data, length); bool ret = m_socket.write(data, length, m_address, m_port); if (!ret) { diff --git a/DMRIPSC.h b/DMRNetwork.h similarity index 89% rename from DMRIPSC.h rename to DMRNetwork.h index 5e630a8..a005613 100644 --- a/DMRIPSC.h +++ b/DMRNetwork.h @@ -16,8 +16,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#if !defined(DMRIPSC_H) -#define DMRIPSC_H +#if !defined(DMRNetwork_H) +#define DMRNetwork_H #include "UDPSocket.h" #include "Timer.h" @@ -28,11 +28,11 @@ #include #include -class CDMRIPSC +class CDMRNetwork { public: - CDMRIPSC(const std::string& address, unsigned int port, unsigned int local, unsigned int id, const std::string& password, bool duplex, const char* version, bool debug, bool slot1, bool slot2, bool rssi, HW_TYPE hwType); - ~CDMRIPSC(); + CDMRNetwork(const std::string& address, unsigned int port, unsigned int local, unsigned int id, const std::string& password, bool duplex, const char* version, bool debug, bool slot1, bool slot2, bool rssi, HW_TYPE hwType); + ~CDMRNetwork(); void setConfig(const std::string& callsign, unsigned int rxFrequency, unsigned int txFrequency, unsigned int power, unsigned int colorCode, float latitude, float longitude, int height, const std::string& location, const std::string& description, const std::string& url); diff --git a/DMRSlot.cpp b/DMRSlot.cpp index 9cea73a..19160e8 100644 --- a/DMRSlot.cpp +++ b/DMRSlot.cpp @@ -35,7 +35,7 @@ std::vector CDMRSlot::m_prefixes; std::vector CDMRSlot::m_blackList; CModem* CDMRSlot::m_modem = NULL; -CDMRIPSC* CDMRSlot::m_network = NULL; +CDMRNetwork* CDMRSlot::m_network = NULL; CDisplay* CDMRSlot::m_display = NULL; bool CDMRSlot::m_duplex = true; CDMRLookup* CDMRSlot::m_lookup = NULL; @@ -1333,7 +1333,7 @@ void CDMRSlot::writeQueueNet(const unsigned char *data) m_queue.addData(data, len); } -void CDMRSlot::init(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& SrcIdBlacklist, const std::vector& DstIdBlacklistSlot1RF, const std::vector& DstIdWhitelistSlot1RF, const std::vector& DstIdBlacklistSlot2RF, const std::vector& DstIdWhitelistSlot2RF, const std::vector& DstIdBlacklistSlot1NET, const std::vector& DstIdWhitelistSlot1NET, const std::vector& DstIdBlacklistSlot2NET, const std::vector& DstIdWhitelistSlot2NET, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter) +void CDMRSlot::init(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& SrcIdBlacklist, const std::vector& DstIdBlacklistSlot1RF, const std::vector& DstIdWhitelistSlot1RF, const std::vector& DstIdBlacklistSlot2RF, const std::vector& DstIdWhitelistSlot2RF, const std::vector& DstIdBlacklistSlot1NET, const std::vector& DstIdWhitelistSlot1NET, const std::vector& DstIdBlacklistSlot2NET, const std::vector& DstIdWhitelistSlot2NET, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter) { assert(id != 0U); assert(modem != NULL); diff --git a/DMRSlot.h b/DMRSlot.h index d678a42..2b48db2 100644 --- a/DMRSlot.h +++ b/DMRSlot.h @@ -21,6 +21,7 @@ #include "DMREmbeddedLC.h" #include "DMRDataHeader.h" +#include "DMRNetwork.h" #include "RingBuffer.h" #include "StopWatch.h" #include "DMRLookup.h" @@ -29,7 +30,6 @@ #include "DMRData.h" #include "Display.h" #include "Defines.h" -#include "DMRIPSC.h" #include "DMREMB.h" #include "Timer.h" #include "Modem.h" @@ -50,7 +50,7 @@ public: void clock(); - static void init(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& SrcIdBlackList, const std::vector& DstIdBlacklistSlot1RF, const std::vector& DstIdWhitelistSlot1RF, const std::vector& DstIdBlacklistSlot2RF, const std::vector& DstIdWhitelistSlot2RF, const std::vector& DstIdBlacklistSlot1NET, const std::vector& DstIdWhitelistSlot1NET, const std::vector& DstIdBlacklistSlot2NET, const std::vector& DstIdWhitelistSlot2NET, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter); + static void init(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& SrcIdBlackList, const std::vector& DstIdBlacklistSlot1RF, const std::vector& DstIdWhitelistSlot1RF, const std::vector& DstIdBlacklistSlot2RF, const std::vector& DstIdWhitelistSlot2RF, const std::vector& DstIdBlacklistSlot1NET, const std::vector& DstIdWhitelistSlot1NET, const std::vector& DstIdBlacklistSlot2NET, const std::vector& DstIdWhitelistSlot2NET, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter); private: unsigned int m_slotNo; @@ -94,7 +94,7 @@ private: static std::vector m_blackList; static CModem* m_modem; - static CDMRIPSC* m_network; + static CDMRNetwork* m_network; static CDisplay* m_display; static bool m_duplex; static CDMRLookup* m_lookup; @@ -134,7 +134,6 @@ private: void insertSilence(unsigned int count); static void setShortLC(unsigned int slotNo, unsigned int id, FLCO flco = FLCO_GROUP, bool voice = true); - static bool validateId(unsigned int id); }; #endif diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index 84d2ea6..47db022 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -123,6 +123,7 @@ m_modem(NULL), m_dstarNetwork(NULL), m_dmrNetwork(NULL), m_ysfNetwork(NULL), +m_p25Network(NULL), m_display(NULL), m_mode(MODE_IDLE), m_rfModeHang(10U), @@ -255,6 +256,12 @@ int CMMDVMHost::run() return 1; } + if (m_p25Enabled && m_conf.getP25NetworkEnabled()) { + ret = createP25Network(); + if (!ret) + return 1; + } + if (m_conf.getCWIdEnabled()) { unsigned int time = m_conf.getCWIdTime(); @@ -366,7 +373,7 @@ int CMMDVMHost::run() LogInfo(" RSSI Offset: %d", rssiOffset); } - dmr = new CDMRControl(id, colorCode, callHang, selfOnly, prefixes, blackList,dstIDBlackListSlot1RF,dstIDWhiteListSlot1RF, dstIDBlackListSlot2RF, dstIDWhiteListSlot2RF, dstIDBlackListSlot1NET,dstIDWhiteListSlot1NET, dstIDBlackListSlot2NET, dstIDWhiteListSlot2NET, m_timeout, m_modem, m_dmrNetwork, m_display, m_duplex, lookup, rssiMultiplier, rssiOffset, jitter); + dmr = new CDMRControl(id, colorCode, callHang, selfOnly, prefixes, blackList, dstIDBlackListSlot1RF, dstIDWhiteListSlot1RF, dstIDBlackListSlot2RF, dstIDWhiteListSlot2RF, dstIDBlackListSlot1NET,dstIDWhiteListSlot1NET, dstIDBlackListSlot2NET, dstIDWhiteListSlot2NET, m_timeout, m_modem, m_dmrNetwork, m_display, m_duplex, lookup, rssiMultiplier, rssiOffset, jitter); m_dmrTXTimer.setTimeout(txHang); } @@ -400,7 +407,7 @@ int CMMDVMHost::run() LogInfo(" RSSI Offset: %d", rssiOffset); } - p25 = new CP25Control(nac, m_display, m_timeout, m_duplex, lookup, rssiMultiplier, rssiOffset); + p25 = new CP25Control(nac, m_p25Network, m_display, m_timeout, m_duplex, lookup, rssiMultiplier, rssiOffset); } setMode(MODE_IDLE); @@ -680,6 +687,8 @@ int CMMDVMHost::run() m_dmrNetwork->clock(ms); if (m_ysfNetwork != NULL) m_ysfNetwork->clock(ms); + if (m_p25Network != NULL) + m_p25Network->clock(ms); m_cwIdTimer.clock(ms); if (m_cwIdTimer.isRunning() && m_cwIdTimer.hasExpired()) { @@ -732,6 +741,11 @@ int CMMDVMHost::run() delete m_ysfNetwork; } + if (m_p25Network != NULL) { + m_p25Network->close(); + delete m_p25Network; + } + delete dstar; delete dmr; delete ysf; @@ -844,7 +858,7 @@ bool CMMDVMHost::createDMRNetwork() LogInfo(" Slot 2: %s", slot2 ? "enabled" : "disabled"); LogInfo(" RSSI: %s", rssi ? "enabled" : "disabled"); - m_dmrNetwork = new CDMRIPSC(address, port, local, id, password, m_duplex, VERSION, debug, slot1, slot2, rssi, hwType); + m_dmrNetwork = new CDMRNetwork(address, port, local, id, password, m_duplex, VERSION, debug, slot1, slot2, rssi, hwType); unsigned int rxFrequency = m_conf.getRxFrequency(); unsigned int txFrequency = m_conf.getTxFrequency(); @@ -911,6 +925,32 @@ bool CMMDVMHost::createYSFNetwork() return true; } +bool CMMDVMHost::createP25Network() +{ + std::string gatewayAddress = m_conf.getP25GatewayAddress(); + unsigned int gatewayPort = m_conf.getP25GatewayPort(); + unsigned int localPort = m_conf.getP25LocalPort(); + bool debug = m_conf.getP25NetworkDebug(); + + LogInfo("P25 Network Parameters"); + LogInfo(" Gateway Address: %s", gatewayAddress.c_str()); + LogInfo(" Gateway Port: %u", gatewayPort); + LogInfo(" Local Port: %u", localPort); + + m_p25Network = new CP25Network(gatewayAddress, gatewayPort, localPort, debug); + + bool ret = m_p25Network->open(); + if (!ret) { + delete m_p25Network; + m_p25Network = NULL; + return false; + } + + m_p25Network->enable(true); + + return true; +} + void CMMDVMHost::readParams() { m_dstarEnabled = m_conf.getDStarEnabled(); @@ -1034,6 +1074,8 @@ void CMMDVMHost::setMode(unsigned char mode) m_dmrNetwork->enable(false); if (m_ysfNetwork != NULL) m_ysfNetwork->enable(false); + if (m_p25Network != NULL) + m_p25Network->enable(false); m_modem->setMode(MODE_DSTAR); m_mode = MODE_DSTAR; m_modeTimer.start(); @@ -1044,6 +1086,8 @@ void CMMDVMHost::setMode(unsigned char mode) m_dstarNetwork->enable(false); if (m_ysfNetwork != NULL) m_ysfNetwork->enable(false); + if (m_p25Network != NULL) + m_p25Network->enable(false); m_modem->setMode(MODE_DMR); if (m_duplex) { m_modem->writeDMRStart(true); @@ -1058,6 +1102,8 @@ void CMMDVMHost::setMode(unsigned char mode) m_dstarNetwork->enable(false); if (m_dmrNetwork != NULL) m_dmrNetwork->enable(false); + if (m_p25Network != NULL) + m_p25Network->enable(false); m_modem->setMode(MODE_YSF); m_mode = MODE_YSF; m_modeTimer.start(); @@ -1083,6 +1129,8 @@ void CMMDVMHost::setMode(unsigned char mode) m_dmrNetwork->enable(false); if (m_ysfNetwork != NULL) m_ysfNetwork->enable(false); + if (m_p25Network != NULL) + m_p25Network->enable(false); if (m_mode == MODE_DMR && m_duplex && m_modem->hasTX()) { m_modem->writeDMRStart(false); m_dmrTXTimer.stop(); @@ -1102,6 +1150,8 @@ void CMMDVMHost::setMode(unsigned char mode) m_dmrNetwork->enable(false); if (m_ysfNetwork != NULL) m_ysfNetwork->enable(false); + if (m_p25Network != NULL) + m_p25Network->enable(false); if (m_mode == MODE_DMR && m_duplex && m_modem->hasTX()) { m_modem->writeDMRStart(false); m_dmrTXTimer.stop(); @@ -1119,6 +1169,8 @@ void CMMDVMHost::setMode(unsigned char mode) m_dmrNetwork->enable(true); if (m_ysfNetwork != NULL) m_ysfNetwork->enable(true); + if (m_p25Network != NULL) + m_p25Network->enable(true); if (m_mode == MODE_DMR && m_duplex && m_modem->hasTX()) { m_modem->writeDMRStart(false); m_dmrTXTimer.stop(); diff --git a/MMDVMHost.h b/MMDVMHost.h index fbdb180..db92394 100644 --- a/MMDVMHost.h +++ b/MMDVMHost.h @@ -21,7 +21,8 @@ #include "DStarNetwork.h" #include "YSFNetwork.h" -#include "DMRIPSC.h" +#include "P25Network.h" +#include "DMRNetwork.h" #include "Display.h" #include "Timer.h" #include "Modem.h" @@ -41,8 +42,9 @@ private: CConf m_conf; CModem* m_modem; CDStarNetwork* m_dstarNetwork; - CDMRIPSC* m_dmrNetwork; + CDMRNetwork* m_dmrNetwork; CYSFNetwork* m_ysfNetwork; + CP25Network* m_p25Network; CDisplay* m_display; unsigned char m_mode; unsigned int m_rfModeHang; @@ -63,6 +65,7 @@ private: bool createDStarNetwork(); bool createDMRNetwork(); bool createYSFNetwork(); + bool createP25Network(); void createDisplay(); void setMode(unsigned char mode); diff --git a/MMDVMHost.vcxproj b/MMDVMHost.vcxproj index 339b7b6..e87912f 100644 --- a/MMDVMHost.vcxproj +++ b/MMDVMHost.vcxproj @@ -161,8 +161,8 @@ - + @@ -186,6 +186,7 @@ + @@ -222,9 +223,9 @@ - + @@ -245,6 +246,7 @@ + diff --git a/MMDVMHost.vcxproj.filters b/MMDVMHost.vcxproj.filters index 3182fcc..2e05124 100644 --- a/MMDVMHost.vcxproj.filters +++ b/MMDVMHost.vcxproj.filters @@ -137,9 +137,6 @@ Header Files - - Header Files - Header Files @@ -194,6 +191,12 @@ Header Files + + Header Files + + + Header Files + @@ -304,9 +307,6 @@ Source Files - - Source Files - Source Files @@ -358,5 +358,11 @@ Source Files + + Source Files + + + Source Files + \ No newline at end of file diff --git a/Makefile b/Makefile index e61f092..f0c581e 100644 --- a/Makefile +++ b/Makefile @@ -7,10 +7,11 @@ LIBS = -lpthread LDFLAGS = -g OBJECTS = \ - AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRIPSC.o DMRLookup.o DMRLC.o \ - DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o Log.o MMDVMHost.o \ - Modem.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25NID.o P25Utils.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o \ - Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRLookup.o DMRLC.o \ + DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ + Golay24128.o Hamming.o Log.o MMDVMHost.o Modem.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Utils.o \ + QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o \ + YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi.Adafruit b/Makefile.Pi.Adafruit index f5b71bb..e108428 100644 --- a/Makefile.Pi.Adafruit +++ b/Makefile.Pi.Adafruit @@ -7,10 +7,11 @@ LIBS = -lwiringPi -lwiringPiDev -lpthread LDFLAGS = -g -L/usr/local/lib OBJECTS = \ - AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRIPSC.o DMRLookup.o DMRLC.o \ - DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o HD44780.o Log.o \ - MMDVMHost.o Modem.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25NID.o P25Utils.o QR1676.o RS129.o SerialController.o SHA256.o \ - StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRLookup.o DMRLC.o \ + DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ + Golay24128.o Hamming.o HD44780.o Log.o MMDVMHost.o Modem.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o \ + P25Utils.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o \ + YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi.HD44780 b/Makefile.Pi.HD44780 index 252af92..9c12ba4 100644 --- a/Makefile.Pi.HD44780 +++ b/Makefile.Pi.HD44780 @@ -7,10 +7,11 @@ LIBS = -lwiringPi -lwiringPiDev -lpthread LDFLAGS = -g -L/usr/local/lib OBJECTS = \ - AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRIPSC.o DMRLookup.o DMRLC.o \ - DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o HD44780.o Log.o \ - MMDVMHost.o Modem.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25NID.o P25Utils.o QR1676.o RS129.o SerialController.o SHA256.o \ - StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRLookup.o DMRLC.o \ + DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ + Golay24128.o Hamming.o HD44780.o Log.o MMDVMHost.o Modem.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o \ + P25Utils.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o \ + YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi.OLED b/Makefile.Pi.OLED index 7b74f6b..b9a4dae 100644 --- a/Makefile.Pi.OLED +++ b/Makefile.Pi.OLED @@ -7,10 +7,11 @@ LIBS = -lArduiPi_OLED -lpthread LDFLAGS = -g -L/usr/local/lib OBJECTS = \ - AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRIPSC.o DMRLookup.o DMRLC.o \ - DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o OLED.o Log.o \ - MMDVMHost.o Modem.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25NID.o P25Utils.o QR1676.o RS129.o SerialController.o SHA256.o \ - StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRLookup.o DMRLC.o \ + DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ + Golay24128.o Hamming.o OLED.o Log.o MMDVMHost.o Modem.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o \ + P25Utils.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o \ + YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi.PCF8574 b/Makefile.Pi.PCF8574 index c5458eb..332489a 100644 --- a/Makefile.Pi.PCF8574 +++ b/Makefile.Pi.PCF8574 @@ -7,10 +7,11 @@ LIBS = -lwiringPi -lwiringPiDev -lpthread LDFLAGS = -g -L/usr/local/lib OBJECTS = \ - AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRIPSC.o DMRLookup.o DMRLC.o \ - DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o HD44780.o Log.o \ - MMDVMHost.o Modem.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25NID.o P25Utils.o QR1676.o RS129.o SerialController.o SHA256.o \ - StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRLookup.o DMRLC.o \ + DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ + Golay24128.o Hamming.o HD44780.o Log.o MMDVMHost.o Modem.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o \ + P25Utils.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o \ + YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Solaris b/Makefile.Solaris index 5cdffb6..52c6358 100644 --- a/Makefile.Solaris +++ b/Makefile.Solaris @@ -7,10 +7,11 @@ LIBS = -lpthread -lsocket LDFLAGS = -g OBJECTS = \ - AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRIPSC.o DMRLookup.o DMRLC.o \ - DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o Log.o MMDVMHost.o \ - Modem.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25NID.o P25Utils.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o \ - Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRLookup.o DMRLC.o \ + DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ + Golay24128.o Hamming.o Log.o MMDVMHost.o Modem.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Utils.o \ + QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o \ + YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/P25Control.cpp b/P25Control.cpp index 9504046..a44d8cc 100644 --- a/P25Control.cpp +++ b/P25Control.cpp @@ -31,8 +31,9 @@ const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U #define WRITE_BIT(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_BIT(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7]) -CP25Control::CP25Control(unsigned int nac, CDisplay* display, unsigned int timeout, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset) : +CP25Control::CP25Control(unsigned int nac, CP25Network* network, CDisplay* display, unsigned int timeout, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset) : m_nac(nac), +m_network(network), m_display(display), m_duplex(duplex), m_lookup(lookup), diff --git a/P25Control.h b/P25Control.h index 508520b..56f3825 100644 --- a/P25Control.h +++ b/P25Control.h @@ -20,6 +20,7 @@ #define P25Control_H #include "RingBuffer.h" +#include "P25Network.h" #include "DMRLookup.h" #include "P25Audio.h" #include "Defines.h" @@ -31,7 +32,7 @@ class CP25Control { public: - CP25Control(unsigned int nac, CDisplay* display, unsigned int timeout, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset); + CP25Control(unsigned int nac, CP25Network* network, CDisplay* display, unsigned int timeout, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset); ~CP25Control(); bool writeModem(unsigned char* data, unsigned int len); @@ -42,6 +43,7 @@ public: private: unsigned int m_nac; + CP25Network* m_network; CDisplay* m_display; bool m_duplex; CDMRLookup* m_lookup; diff --git a/P25Defines.h b/P25Defines.h index 39f1b2e..fd51bfd 100644 --- a/P25Defines.h +++ b/P25Defines.h @@ -32,7 +32,9 @@ const unsigned int P25_TERMLC_FRAME_LENGTH_BYTES = 54U; const unsigned int P25_TERMLC_FRAME_LENGTH_BITS = P25_TERMLC_FRAME_LENGTH_BYTES * 8U; const unsigned int P25_SYNC_LENGTH_BYTES = 6U; + const unsigned int P25_NID_LENGTH_BYTES = 8U; +const unsigned int P25_NID_LENGTH_BITS = P25_NID_LENGTH_BYTES * 8U; const unsigned char P25_SYNC_BYTES[] = {0x55U, 0x75U, 0xF5U, 0xFFU, 0x77U, 0xFFU}; const unsigned char P25_SYNC_BYTES_LENGTH = 6U; diff --git a/P25Network.cpp b/P25Network.cpp new file mode 100644 index 0000000..10fadeb --- /dev/null +++ b/P25Network.cpp @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2009-2014,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 "P25Network.h" +#include "StopWatch.h" +#include "Defines.h" +#include "Utils.h" +#include "Log.h" + +#include +#include +#include + +const unsigned int BUFFER_LENGTH = 100U; + +CP25Network::CP25Network(const std::string& gatewayAddress, unsigned int gatewayPort, unsigned int localPort, bool debug) : +m_socket(localPort), +m_address(), +m_port(gatewayPort), +m_debug(debug), +m_enabled(false), +m_buffer(1000U, "P25 Network"), +m_pollTimer(1000U, 60U) +{ + m_address = CUDPSocket::lookup(gatewayAddress); + + CStopWatch stopWatch; + ::srand(stopWatch.start()); +} + +CP25Network::~CP25Network() +{ +} + +bool CP25Network::open() +{ + LogMessage("Opening P25 network connection"); + + if (m_address.s_addr == INADDR_NONE) + return false; + + m_pollTimer.start(); + + return m_socket.open(); +} + +bool CP25Network::writeHeader(const unsigned char* header, unsigned int length) +{ + assert(header != NULL); +#ifdef notdef + if (m_debug) + CUtils::dump(1U, "P25 Network Header Sent", buffer, 49U); + + for (unsigned int i = 0U; i < 2U; i++) { + bool ret = m_socket.write(buffer, 49U, m_address, m_port); + if (!ret) + return false; + } +#endif + return true; +} + +bool CP25Network::writeData(const unsigned char* data, unsigned int length) +{ + assert(data != NULL); +#ifdef notdef + unsigned char buffer[30U]; + + if (m_debug) + CUtils::dump(1U, "P25 Network Data Sent", buffer, length + 9U); + + return m_socket.write(buffer, length + 9U, m_address, m_port); +#endif + return true; +} + +bool CP25Network::writePoll() +{ +#ifdef notdef + // if (m_debug) + // CUtils::dump(1U, "P25 Network Poll Sent", buffer, 6U + length); + + return m_socket.write(buffer, 6U + length, m_address, m_port); +#endif + return true; +} + +void CP25Network::clock(unsigned int ms) +{ + m_pollTimer.clock(ms); + if (m_pollTimer.hasExpired()) { + writePoll(); + m_pollTimer.start(); + } + + unsigned char buffer[BUFFER_LENGTH]; + + in_addr address; + unsigned int port; + int length = m_socket.read(buffer, BUFFER_LENGTH, address, port); + if (length <= 0) + return; + + // Check if the data is for us + if (m_address.s_addr != address.s_addr || m_port != port) { + LogMessage("P25 packet received from an invalid source, %08X != %08X and/or %u != %u", m_address.s_addr, address.s_addr, m_port, port); + return; + } + + if (!m_enabled) + return; + + // Invalid packet type? + if (::memcmp(buffer, "DSRP", 4U) != 0) + return; +} + +unsigned int CP25Network::read(unsigned char* data, unsigned int length) +{ + assert(data != NULL); + + if (m_buffer.isEmpty()) + return 0U; + + unsigned char c = 0U; + m_buffer.getData(&c, 1U); + + assert(c <= 100U); + assert(c <= length); + + unsigned char buffer[100U]; + m_buffer.getData(buffer, c); + + switch (buffer[0U]) { + case TAG_HEADER: + case TAG_DATA: + case TAG_EOT: + ::memcpy(data, buffer, c); + return c; + + default: + return 0U; + } +} + +void CP25Network::reset() +{ +} + +void CP25Network::close() +{ + m_socket.close(); + + LogMessage("Closing P25 network connection"); +} + +void CP25Network::enable(bool enabled) +{ + if (enabled && !m_enabled) + reset(); + + m_enabled = enabled; +} diff --git a/P25Network.h b/P25Network.h new file mode 100644 index 0000000..cd23818 --- /dev/null +++ b/P25Network.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2009-2014,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 P25Network_H +#define P25Network_H + +#include "RingBuffer.h" +#include "UDPSocket.h" +#include "Timer.h" + +#include +#include + +class CP25Network { +public: + CP25Network(const std::string& gatewayAddress, unsigned int gatewayPort, unsigned int localPort, bool debug); + ~CP25Network(); + + bool open(); + + void enable(bool enabled); + + bool writeHeader(const unsigned char* header, unsigned int length); + bool writeData(const unsigned char* data, unsigned int length); + + unsigned int read(unsigned char* data, unsigned int length); + + void reset(); + + void close(); + + void clock(unsigned int ms); + +private: + CUDPSocket m_socket; + in_addr m_address; + unsigned int m_port; + bool m_debug; + bool m_enabled; + CRingBuffer m_buffer; + CTimer m_pollTimer; + + bool writePoll(); +}; + +#endif