From fc08cf95f360b3a6000e503a7f66e93ff02f6164 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Wed, 27 May 2020 13:49:55 +0100 Subject: [PATCH 01/27] Update to the latest Kenwood protocol handler. --- NXDNReflector/KenwoodNetwork.cpp | 472 ++++++++++++++++++++++++------- NXDNReflector/KenwoodNetwork.h | 31 +- NXDNReflector/UDPSocket.cpp | 30 +- NXDNReflector/UDPSocket.h | 6 +- NXDNReflector/Version.h | 2 +- 5 files changed, 432 insertions(+), 109 deletions(-) diff --git a/NXDNReflector/KenwoodNetwork.cpp b/NXDNReflector/KenwoodNetwork.cpp index 979c021..8a872c0 100644 --- a/NXDNReflector/KenwoodNetwork.cpp +++ b/NXDNReflector/KenwoodNetwork.cpp @@ -24,6 +24,7 @@ #include #include #include +#include const unsigned char BIT_MASK_TABLE[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U }; @@ -36,25 +37,37 @@ const unsigned int RTP_PORT = 64000U; const unsigned int RTCP_PORT = 64001U; CKenwoodNetwork::CKenwoodNetwork(const std::string& address, bool debug) : -m_rtcpSocket(RTCP_PORT), m_rtpSocket(RTP_PORT), -m_stopWatch(), +m_rtcpSocket(RTCP_PORT), m_address(), +m_headerSeen(false), +m_seen1(false), +m_seen2(false), +m_seen3(false), +m_seen4(false), +m_sacch(NULL), +m_sessionId(1U), m_seqNo(0U), -m_timeStamp(0U), m_ssrc(0U), m_debug(debug), -m_timer(1000U, 0U, 200U) +m_startSecs(0U), +m_startUSecs(0U), +m_rtcpTimer(1000U, 0U, 200U), +m_hangTimer(1000U, 5U), +m_hangType(0U), +m_hangSrc(0U), +m_hangDst(0U) { assert(!address.empty()); - m_address = CUDPSocket::lookup(address); + m_sacch = new unsigned char[10U]; - ::srand((unsigned int)m_stopWatch.time()); + m_address = CUDPSocket::lookup(address); } CKenwoodNetwork::~CKenwoodNetwork() { + delete[] m_sacch; } bool CKenwoodNetwork::open() @@ -72,7 +85,7 @@ bool CKenwoodNetwork::open() return false; } - m_ssrc = ::rand(); + m_ssrc = m_rtpSocket.getLocalAddress(); return true; } @@ -107,12 +120,12 @@ bool CKenwoodNetwork::processIcomVoiceHeader(const unsigned char* inData) outData[3U] = inData[3U]; // FACCH 1+2 - outData[4U] = outData[14U] = inData[6U]; - outData[5U] = outData[15U] = inData[5U]; - outData[6U] = outData[16U] = inData[8U]; - outData[7U] = outData[17U] = inData[7U]; - outData[8U] = outData[18U] = inData[10U]; - outData[9U] = outData[19U] = inData[9U]; + outData[4U] = outData[14U] = inData[6U]; + outData[5U] = outData[15U] = inData[5U]; + outData[6U] = outData[16U] = inData[8U]; + outData[7U] = outData[17U] = inData[7U]; + outData[8U] = outData[18U] = inData[10U]; + outData[9U] = outData[19U] = inData[9U]; outData[10U] = outData[20U] = inData[12U]; outData[11U] = outData[21U] = inData[11U]; @@ -122,13 +135,16 @@ bool CKenwoodNetwork::processIcomVoiceHeader(const unsigned char* inData) switch (inData[5U] & 0x3FU) { case 0x01U: - m_timer.start(); - writeRTCPData(type, src, dst); + m_hangTimer.stop(); + m_rtcpTimer.start(); + writeRTCPStart(); return writeRTPVoiceHeader(outData); - case 0x08U: - m_timer.stop(); - writeRTCPData(type, src, dst); - return writeRTPVoiceTrailer(outData); + case 0x08U: { + m_hangTimer.start(); + bool ret = writeRTPVoiceTrailer(outData); + writeRTCPHang(type, src, dst); + return ret; + } default: return false; } @@ -224,23 +240,27 @@ bool CKenwoodNetwork::writeRTPVoiceHeader(const unsigned char* data) buffer[0U] = 0x80U; buffer[1U] = 0x66U; + m_seqNo++; buffer[2U] = (m_seqNo >> 8) & 0xFFU; buffer[3U] = (m_seqNo >> 0) & 0xFFU; - m_seqNo++; - m_timeStamp = (unsigned long)m_stopWatch.time(); - - buffer[4U] = (m_timeStamp >> 24) & 0xFFU; - buffer[5U] = (m_timeStamp >> 16) & 0xFFU; - buffer[6U] = (m_timeStamp >> 8) & 0xFFU; - buffer[7U] = (m_timeStamp >> 0) & 0xFFU; - m_timeStamp += 640U; + unsigned long timeStamp = getTimeStamp(); + buffer[4U] = (timeStamp >> 24) & 0xFFU; + buffer[5U] = (timeStamp >> 16) & 0xFFU; + buffer[6U] = (timeStamp >> 8) & 0xFFU; + buffer[7U] = (timeStamp >> 0) & 0xFFU; buffer[8U] = (m_ssrc >> 24) & 0xFFU; buffer[9U] = (m_ssrc >> 16) & 0xFFU; buffer[10U] = (m_ssrc >> 8) & 0xFFU; buffer[11U] = (m_ssrc >> 0) & 0xFFU; + m_sessionId++; + buffer[12U] = m_sessionId; + + buffer[13U] = 0x00U; + buffer[14U] = 0x00U; + buffer[15U] = 0x00U; buffer[16U] = 0x03U; buffer[17U] = 0x03U; buffer[18U] = 0x04U; @@ -267,19 +287,26 @@ bool CKenwoodNetwork::writeRTPVoiceTrailer(const unsigned char* data) buffer[0U] = 0x80U; buffer[1U] = 0x66U; + m_seqNo++; buffer[2U] = (m_seqNo >> 8) & 0xFFU; buffer[3U] = (m_seqNo >> 0) & 0xFFU; - buffer[4U] = (m_timeStamp >> 24) & 0xFFU; - buffer[5U] = (m_timeStamp >> 16) & 0xFFU; - buffer[6U] = (m_timeStamp >> 8) & 0xFFU; - buffer[7U] = (m_timeStamp >> 0) & 0xFFU; + unsigned long timeStamp = getTimeStamp(); + buffer[4U] = (timeStamp >> 24) & 0xFFU; + buffer[5U] = (timeStamp >> 16) & 0xFFU; + buffer[6U] = (timeStamp >> 8) & 0xFFU; + buffer[7U] = (timeStamp >> 0) & 0xFFU; buffer[8U] = (m_ssrc >> 24) & 0xFFU; buffer[9U] = (m_ssrc >> 16) & 0xFFU; buffer[10U] = (m_ssrc >> 8) & 0xFFU; buffer[11U] = (m_ssrc >> 0) & 0xFFU; + buffer[12U] = m_sessionId; + + buffer[13U] = 0x00U; + buffer[14U] = 0x00U; + buffer[15U] = 0x00U; buffer[16U] = 0x03U; buffer[17U] = 0x03U; buffer[18U] = 0x04U; @@ -306,21 +333,26 @@ bool CKenwoodNetwork::writeRTPVoiceData(const unsigned char* data) buffer[0U] = 0x80U; buffer[1U] = 0x66U; + m_seqNo++; buffer[2U] = (m_seqNo >> 8) & 0xFFU; buffer[3U] = (m_seqNo >> 0) & 0xFFU; - m_seqNo++; - buffer[4U] = (m_timeStamp >> 24) & 0xFFU; - buffer[5U] = (m_timeStamp >> 16) & 0xFFU; - buffer[6U] = (m_timeStamp >> 8) & 0xFFU; - buffer[7U] = (m_timeStamp >> 0) & 0xFFU; - m_timeStamp += 640U; + unsigned long timeStamp = getTimeStamp(); + buffer[4U] = (timeStamp >> 24) & 0xFFU; + buffer[5U] = (timeStamp >> 16) & 0xFFU; + buffer[6U] = (timeStamp >> 8) & 0xFFU; + buffer[7U] = (timeStamp >> 0) & 0xFFU; buffer[8U] = (m_ssrc >> 24) & 0xFFU; buffer[9U] = (m_ssrc >> 16) & 0xFFU; - buffer[10U] = (m_ssrc >> 8) & 0xFFU; - buffer[11U] = (m_ssrc >> 0) & 0xFFU; + buffer[10U] = (m_ssrc >> 8) & 0xFFU; + buffer[11U] = (m_ssrc >> 0) & 0xFFU; + buffer[12U] = m_sessionId; + + buffer[13U] = 0x00U; + buffer[14U] = 0x00U; + buffer[15U] = 0x00U; buffer[16U] = 0x03U; buffer[17U] = 0x02U; buffer[18U] = 0x04U; @@ -337,30 +369,59 @@ bool CKenwoodNetwork::writeRTPVoiceData(const unsigned char* data) return m_rtpSocket.write(buffer, 59U, m_address, RTP_PORT); } -bool CKenwoodNetwork::writeRTCPPing() +bool CKenwoodNetwork::writeRTCPStart() { +#if defined(_WIN32) || defined(_WIN64) + time_t now; + ::time(&now); + + m_startSecs = uint32_t(now); + + SYSTEMTIME st; + ::GetSystemTime(&st); + + m_startUSecs = st.wMilliseconds * 1000U; +#else + struct timeval tod; + ::gettimeofday(&tod, NULL); + + m_startSecs = tod.tv_sec; + m_startUSecs = tod.tv_usec; +#endif + unsigned char buffer[30U]; ::memset(buffer, 0x00U, 30U); buffer[0U] = 0x8AU; buffer[1U] = 0xCCU; - + buffer[2U] = 0x00U; buffer[3U] = 0x06U; buffer[4U] = (m_ssrc >> 24) & 0xFFU; buffer[5U] = (m_ssrc >> 16) & 0xFFU; - buffer[6U] = (m_ssrc >> 8) & 0xFFU; - buffer[7U] = (m_ssrc >> 0) & 0xFFU; + buffer[6U] = (m_ssrc >> 8) & 0xFFU; + buffer[7U] = (m_ssrc >> 0) & 0xFFU; buffer[8U] = 'K'; buffer[9U] = 'W'; buffer[10U] = 'N'; buffer[11U] = 'E'; + buffer[12U] = (m_startSecs >> 24) & 0xFFU; + buffer[13U] = (m_startSecs >> 16) & 0xFFU; + buffer[14U] = (m_startSecs >> 8) & 0xFFU; + buffer[15U] = (m_startSecs >> 0) & 0xFFU; + + buffer[16U] = (m_startUSecs >> 24) & 0xFFU; + buffer[17U] = (m_startUSecs >> 16) & 0xFFU; + buffer[18U] = (m_startUSecs >> 8) & 0xFFU; + buffer[19U] = (m_startUSecs >> 0) & 0xFFU; + buffer[22U] = 0x02U; buffer[24U] = 0x01U; - buffer[25U] = 0x01U; + + buffer[27U] = 0x0AU; if (m_debug) CUtils::dump(1U, "Kenwood Network RTCP Data Sent", buffer, 28U); @@ -368,33 +429,84 @@ bool CKenwoodNetwork::writeRTCPPing() return m_rtcpSocket.write(buffer, 28U, m_address, RTCP_PORT); } -bool CKenwoodNetwork::writeRTCPData(unsigned char type, unsigned short src, unsigned short dst) +bool CKenwoodNetwork::writeRTCPPing() { - unsigned char buffer[20U]; - ::memset(buffer, 0x00U, 20U); + unsigned char buffer[30U]; + ::memset(buffer, 0x00U, 30U); - buffer[0U] = 0x8BU; + buffer[0U] = 0x8AU; buffer[1U] = 0xCCU; - - buffer[3U] = 0x04U; + buffer[2U] = 0x00U; + buffer[3U] = 0x06U; buffer[4U] = (m_ssrc >> 24) & 0xFFU; buffer[5U] = (m_ssrc >> 16) & 0xFFU; - buffer[6U] = (m_ssrc >> 8) & 0xFFU; - buffer[7U] = (m_ssrc >> 0) & 0xFFU; + buffer[6U] = (m_ssrc >> 8) & 0xFFU; + buffer[7U] = (m_ssrc >> 0) & 0xFFU; buffer[8U] = 'K'; buffer[9U] = 'W'; buffer[10U] = 'N'; buffer[11U] = 'E'; - buffer[12U] = (src >> 8) & 0xFFU; - buffer[13U] = (src >> 0) & 0xFFU; + buffer[12U] = (m_startSecs >> 24) & 0xFFU; + buffer[13U] = (m_startSecs >> 16) & 0xFFU; + buffer[14U] = (m_startSecs >> 8) & 0xFFU; + buffer[15U] = (m_startSecs >> 0) & 0xFFU; - buffer[14U] = (dst >> 8) & 0xFFU; - buffer[15U] = (dst >> 0) & 0xFFU; + buffer[16U] = (m_startUSecs >> 24) & 0xFFU; + buffer[17U] = (m_startUSecs >> 16) & 0xFFU; + buffer[18U] = (m_startUSecs >> 8) & 0xFFU; + buffer[19U] = (m_startUSecs >> 0) & 0xFFU; - buffer[16U] = type; + buffer[22U] = 0x02U; + + buffer[24U] = 0x01U; + + buffer[27U] = 0x7BU; + + if (m_debug) + CUtils::dump(1U, "Kenwood Network RTCP Data Sent", buffer, 28U); + + return m_rtcpSocket.write(buffer, 28U, m_address, RTCP_PORT); +} + +bool CKenwoodNetwork::writeRTCPHang(unsigned char type, unsigned short src, unsigned short dst) +{ + m_hangType = type; + m_hangSrc = src; + m_hangDst = dst; + + return writeRTCPHang(); +} + +bool CKenwoodNetwork::writeRTCPHang() +{ + unsigned char buffer[30U]; + ::memset(buffer, 0x00U, 30U); + + buffer[0U] = 0x8BU; + buffer[1U] = 0xCCU; + buffer[2U] = 0x00U; + buffer[3U] = 0x04U; + + buffer[4U] = (m_ssrc >> 24) & 0xFFU; + buffer[5U] = (m_ssrc >> 16) & 0xFFU; + buffer[6U] = (m_ssrc >> 8) & 0xFFU; + buffer[7U] = (m_ssrc >> 0) & 0xFFU; + + buffer[8U] = 'K'; + buffer[9U] = 'W'; + buffer[10U] = 'N'; + buffer[11U] = 'E'; + + buffer[12U] = (m_hangSrc >> 8) & 0xFFU; + buffer[13U] = (m_hangSrc >> 0) & 0xFFU; + + buffer[14U] = (m_hangDst >> 8) & 0xFFU; + buffer[15U] = (m_hangDst >> 0) & 0xFFU; + + buffer[16U] = m_hangType; if (m_debug) CUtils::dump(1U, "Kenwood Network RTCP Data Sent", buffer, 20U); @@ -409,26 +521,23 @@ unsigned int CKenwoodNetwork::read(unsigned char* data) unsigned char dummy[BUFFER_LENGTH]; readRTCP(dummy); - bool ret; - unsigned int len = readRTP(data); - if (len > 0U) { - switch (data[9U]) { - case 0x05U: // Voice header or trailer - ret = processKenwoodVoiceHeader(data); - if (!ret) - return 0U; - return 33U; - case 0x08U: // Voice data - processKenwoodVoiceData(data); - return 33U; - default: - break; - } + switch (len) { + case 0U: // Nothing received + return 0U; + case 35U: // Voice header or trailer + return processKenwoodVoiceHeader(data); + case 47U: // Voice data + if (m_headerSeen) + return processKenwoodVoiceData(data); + else + return processKenwoodVoiceLateEntry(data); + case 31U: // Data + return processKenwoodData(data); + default: + CUtils::dump(5U, "Unknown data received from the Kenwood network", data, len); + return 0U; } - - CUtils::dump(5U, "Unknown data received from the Kenwood network", data, len); - return 0U; } unsigned int CKenwoodNetwork::readRTP(unsigned char* data) @@ -444,19 +553,14 @@ unsigned int CKenwoodNetwork::readRTP(unsigned char* data) return 0U; // Check if the data is for us - if (m_address.s_addr != address.s_addr || port != RTP_PORT) { - LogMessage("Kenwood RTP packet received from an invalid source, %08X != %08X and/or %u != %u", m_address.s_addr, address.s_addr, RTP_PORT, port); + if (m_address.s_addr != address.s_addr) { + LogMessage("Kenwood RTP packet received from an invalid source, %08X != %08X", m_address.s_addr, address.s_addr); return 0U; } if (m_debug) CUtils::dump(1U, "Kenwood Network RTP Data Received", buffer, length); - if (length != 47 && length != 59) { - LogError("Invalid RTP length of %d", length); - return 0U; - } - ::memcpy(data, buffer + 12U, length - 12U); return length - 12U; @@ -475,19 +579,14 @@ unsigned int CKenwoodNetwork::readRTCP(unsigned char* data) return 0U; // Check if the data is for us - if (m_address.s_addr != address.s_addr || port != RTCP_PORT) { - LogMessage("Kenwood RTCP packet received from an invalid source, %08X != %08X and/or %u != %u", m_address.s_addr, address.s_addr, RTCP_PORT, port); + if (m_address.s_addr != address.s_addr) { + LogMessage("Kenwood RTCP packet received from an invalid source, %08X != %08X", m_address.s_addr, address.s_addr); return 0U; } if (m_debug) CUtils::dump(1U, "Kenwood Network RTCP Data Received", buffer, length); - if (length != 20 && length != 28) { - LogError("Invalid RTCP length of %d", length); - return 0U; - } - if (::memcmp(buffer + 8U, "KWNE", 4U) != 0) { LogError("Missing RTCP KWNE signature"); return 0U; @@ -508,14 +607,23 @@ void CKenwoodNetwork::close() void CKenwoodNetwork::clock(unsigned int ms) { - m_timer.clock(ms); - if (m_timer.isRunning() && m_timer.hasExpired()) { - writeRTCPPing(); - m_timer.start(); + m_rtcpTimer.clock(ms); + if (m_rtcpTimer.isRunning() && m_rtcpTimer.hasExpired()) { + if (m_hangTimer.isRunning()) + writeRTCPHang(); + else + writeRTCPPing(); + m_rtcpTimer.start(); + } + + m_hangTimer.clock(ms); + if (m_hangTimer.isRunning() && m_hangTimer.hasExpired()) { + m_rtcpTimer.stop(); + m_hangTimer.stop(); } } -bool CKenwoodNetwork::processKenwoodVoiceHeader(unsigned char* inData) +unsigned int CKenwoodNetwork::processKenwoodVoiceHeader(unsigned char* inData) { assert(inData != NULL); @@ -552,15 +660,27 @@ bool CKenwoodNetwork::processKenwoodVoiceHeader(unsigned char* inData) switch (outData[5U] & 0x3FU) { case 0x01U: + ::memcpy(inData, outData, 33U); + m_headerSeen = true; + m_seen1 = false; + m_seen2 = false; + m_seen3 = false; + m_seen4 = false; + return 33U; case 0x08U: ::memcpy(inData, outData, 33U); - return true; + m_headerSeen = false; + m_seen1 = false; + m_seen2 = false; + m_seen3 = false; + m_seen4 = false; + return 33U; default: - return false; + return 0U; } } -void CKenwoodNetwork::processKenwoodVoiceData(unsigned char* inData) +unsigned int CKenwoodNetwork::processKenwoodVoiceData(unsigned char* inData) { assert(inData != NULL); @@ -642,4 +762,162 @@ void CKenwoodNetwork::processKenwoodVoiceData(unsigned char* inData) } ::memcpy(inData, outData, 33U); + + return 33U; +} + +unsigned int CKenwoodNetwork::processKenwoodData(unsigned char* inData) +{ + if (inData[7U] != 0x09U && inData[7U] != 0x0BU && inData[7U] != 0x08U) + return 0U; + + unsigned char outData[50U]; + + if (inData[7U] == 0x09U || inData[7U] == 0x08U) { + outData[0U] = 0x90U; + outData[1U] = inData[8U]; + outData[2U] = inData[7U]; + outData[3U] = inData[10U]; + outData[4U] = inData[9U]; + outData[5U] = inData[12U]; + outData[6U] = inData[11U]; + ::memcpy(inData, outData, 7U); + return 7U; + } else { + outData[0U] = 0x90U; + outData[1U] = inData[8U]; + outData[2U] = inData[7U]; + outData[3U] = inData[10U]; + outData[4U] = inData[9U]; + outData[5U] = inData[12U]; + outData[6U] = inData[11U]; + outData[7U] = inData[14U]; + outData[8U] = inData[13U]; + outData[9U] = inData[16U]; + outData[10U] = inData[15U]; + outData[11U] = inData[18U]; + outData[12U] = inData[17U]; + outData[13U] = inData[20U]; + outData[14U] = inData[19U]; + outData[15U] = inData[22U]; + outData[16U] = inData[21U]; + outData[17U] = inData[24U]; + outData[18U] = inData[23U]; + outData[19U] = inData[26U]; + outData[20U] = inData[25U]; + outData[21U] = inData[28U]; + outData[22U] = inData[27U]; + outData[23U] = inData[29U]; + ::memcpy(inData, outData, 24U); + return 24U; + } +} + +unsigned long CKenwoodNetwork::getTimeStamp() const +{ + unsigned long timeStamp = 0UL; + +#if defined(_WIN32) || defined(_WIN64) + SYSTEMTIME st; + ::GetSystemTime(&st); + + unsigned int hh = st.wHour; + unsigned int mm = st.wMinute; + unsigned int ss = st.wSecond; + unsigned int ms = st.wMilliseconds; + + timeStamp += hh * 3600U * 1000U * 80U; + timeStamp += mm * 60U * 1000U * 80U; + timeStamp += ss * 1000U * 80U; + timeStamp += ms * 80U; +#else + struct timeval tod; + ::gettimeofday(&tod, NULL); + + unsigned int ss = tod.tv_sec; + unsigned int ms = tod.tv_usec / 1000U; + + timeStamp += ss * 1000U * 80U; + timeStamp += ms * 80U; +#endif + + return timeStamp; +} + +unsigned int CKenwoodNetwork::processKenwoodVoiceLateEntry(unsigned char* inData) +{ + assert(inData != NULL); + + unsigned char sacch[4U]; + sacch[0U] = inData[12U]; + sacch[1U] = inData[11U]; + sacch[2U] = inData[14U]; + sacch[3U] = inData[13U]; + + switch (sacch[0U] & 0xC0U) { + case 0xC0U: + if (!m_seen1) { + unsigned int offset = 0U; + for (unsigned int i = 8U; i < 26U; i++, offset++) { + bool b = READ_BIT(sacch, i) != 0U; + WRITE_BIT(m_sacch, offset, b); + } + m_seen1 = true; + } + break; + case 0x80U: + if (!m_seen2) { + unsigned int offset = 18U; + for (unsigned int i = 8U; i < 26U; i++, offset++) { + bool b = READ_BIT(sacch, i) != 0U; + WRITE_BIT(m_sacch, offset, b); + } + m_seen2 = true; + } + break; + case 0x40U: + if (!m_seen3) { + unsigned int offset = 36U; + for (unsigned int i = 8U; i < 26U; i++, offset++) { + bool b = READ_BIT(sacch, i) != 0U; + WRITE_BIT(m_sacch, offset, b); + } + m_seen3 = true; + } + break; + case 0x00U: + if (!m_seen4) { + unsigned int offset = 54U; + for (unsigned int i = 8U; i < 26U; i++, offset++) { + bool b = READ_BIT(sacch, i) != 0U; + WRITE_BIT(m_sacch, offset, b); + } + m_seen4 = true; + } + break; + } + + if (!m_seen1 || !m_seen2 || !m_seen3 || !m_seen4) + return 0U; + + // Create a dummy header + // Header SACCH + inData[11U] = 0x10U; + inData[12U] = 0x01U; + inData[13U] = 0x00U; + inData[14U] = 0x00U; + + // Header FACCH + inData[15U] = m_sacch[1U]; + inData[16U] = m_sacch[0U]; + inData[17U] = m_sacch[3U]; + inData[18U] = m_sacch[2U]; + inData[19U] = m_sacch[5U]; + inData[20U] = m_sacch[4U]; + inData[21U] = m_sacch[7U]; + inData[22U] = m_sacch[6U]; + inData[23U] = 0x00U; + inData[24U] = m_sacch[8U]; + + return processKenwoodVoiceHeader(inData); } diff --git a/NXDNReflector/KenwoodNetwork.h b/NXDNReflector/KenwoodNetwork.h index 4c0ded9..0543efe 100644 --- a/NXDNReflector/KenwoodNetwork.h +++ b/NXDNReflector/KenwoodNetwork.h @@ -20,7 +20,6 @@ #define KenwoodNetwork_H #include "CoreNetwork.h" -#include "StopWatch.h" #include "UDPSocket.h" #include "Timer.h" @@ -45,25 +44,41 @@ public: private: CUDPSocket m_rtpSocket; CUDPSocket m_rtcpSocket; - CStopWatch m_stopWatch; in_addr m_address; - unsigned short m_seqNo; - unsigned long m_timeStamp; + bool m_headerSeen; + bool m_seen1; + bool m_seen2; + bool m_seen3; + bool m_seen4; + unsigned char* m_sacch; + uint8_t m_sessionId; + uint16_t m_seqNo; unsigned int m_ssrc; bool m_debug; - CTimer m_timer; + uint32_t m_startSecs; + uint32_t m_startUSecs; + CTimer m_rtcpTimer; + CTimer m_hangTimer; + unsigned char m_hangType; + unsigned short m_hangSrc; + unsigned short m_hangDst; bool processIcomVoiceHeader(const unsigned char* data); bool processIcomVoiceData(const unsigned char* data); - bool processKenwoodVoiceHeader(unsigned char* data); - void processKenwoodVoiceData(unsigned char* data); + unsigned int processKenwoodVoiceHeader(unsigned char* data); + unsigned int processKenwoodVoiceData(unsigned char* data); + unsigned int processKenwoodVoiceLateEntry(unsigned char* data); + unsigned int processKenwoodData(unsigned char* data); bool writeRTPVoiceHeader(const unsigned char* data); bool writeRTPVoiceData(const unsigned char* data); bool writeRTPVoiceTrailer(const unsigned char* data); + bool writeRTCPStart(); bool writeRTCPPing(); - bool writeRTCPData(unsigned char type, unsigned short src, unsigned short dst); + bool writeRTCPHang(unsigned char type, unsigned short src, unsigned short dst); + bool writeRTCPHang(); unsigned int readRTP(unsigned char* data); unsigned int readRTCP(unsigned char* data); + unsigned long getTimeStamp() const; }; #endif diff --git a/NXDNReflector/UDPSocket.cpp b/NXDNReflector/UDPSocket.cpp index 396f1f7..d651ab8 100644 --- a/NXDNReflector/UDPSocket.cpp +++ b/NXDNReflector/UDPSocket.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2016 by Jonathan Naylor G4KLX + * Copyright (C) 2006-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 @@ -260,3 +260,31 @@ void CUDPSocket::close() ::close(m_fd); #endif } + +unsigned long CUDPSocket::getLocalAddress() const +{ + unsigned long address = 0UL; + + char hostname[80U]; + int ret = ::gethostname(hostname, 80); + if (ret == -1) + return 0UL; + + struct hostent* phe = ::gethostbyname(hostname); + if (phe == NULL) + return 0UL; + + if (phe->h_addrtype != AF_INET) + return 0UL; + + for (unsigned int i = 0U; phe->h_addr_list[i] != NULL; i++) { + struct in_addr addr; + ::memcpy(&addr, phe->h_addr_list[i], sizeof(struct in_addr)); + if (addr.s_addr != INADDR_LOOPBACK) { + address = addr.s_addr; + break; + } + } + + return address; +} diff --git a/NXDNReflector/UDPSocket.h b/NXDNReflector/UDPSocket.h index e0af272..4c21a43 100644 --- a/NXDNReflector/UDPSocket.h +++ b/NXDNReflector/UDPSocket.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2011,2013,2015,2016 by Jonathan Naylor G4KLX + * Copyright (C) 2009-2011,2013,2015,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 @@ -47,7 +47,9 @@ public: void close(); - static in_addr lookup(const std::string& hostName); + unsigned long getLocalAddress() const; + + static in_addr lookup(const std::string& hostName); private: std::string m_address; diff --git a/NXDNReflector/Version.h b/NXDNReflector/Version.h index 301ae35..0a67dd6 100644 --- a/NXDNReflector/Version.h +++ b/NXDNReflector/Version.h @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -const char* VERSION = "20200420"; +const char* VERSION = "20200427"; #endif From 166f40b0789128ae9949d915942849770a3fb1d5 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Mon, 1 Jun 2020 11:35:02 +0100 Subject: [PATCH 02/27] Use APRS Gateway for APRS-IS access. --- NXDNGateway/APRSWriter.cpp | 60 +++-- NXDNGateway/APRSWriter.h | 33 +-- NXDNGateway/APRSWriterThread.cpp | 279 ------------------------ NXDNGateway/APRSWriterThread.h | 68 ------ NXDNGateway/Conf.cpp | 28 +-- NXDNGateway/Conf.h | 8 +- NXDNGateway/GPSHandler.cpp | 8 +- NXDNGateway/Makefile | 6 +- NXDNGateway/NXDNGateway.cpp | 5 +- NXDNGateway/NXDNGateway.ini | 12 +- NXDNGateway/NXDNGateway.vcxproj | 4 - NXDNGateway/NXDNGateway.vcxproj.filters | 12 - NXDNGateway/TCPSocket.cpp | 232 -------------------- NXDNGateway/TCPSocket.h | 58 ----- NXDNGateway/Version.h | 2 +- 15 files changed, 71 insertions(+), 744 deletions(-) delete mode 100644 NXDNGateway/APRSWriterThread.cpp delete mode 100644 NXDNGateway/APRSWriterThread.h delete mode 100644 NXDNGateway/TCPSocket.cpp delete mode 100644 NXDNGateway/TCPSocket.h diff --git a/NXDNGateway/APRSWriter.cpp b/NXDNGateway/APRSWriter.cpp index e5eb58e..0dc0177 100644 --- a/NXDNGateway/APRSWriter.cpp +++ b/NXDNGateway/APRSWriter.cpp @@ -23,8 +23,7 @@ #include #include -CAPRSWriter::CAPRSWriter(const std::string& callsign, const std::string& suffix, const std::string& password, const std::string& address, unsigned int port) : -m_thread(NULL), +CAPRSWriter::CAPRSWriter(const std::string& callsign, const std::string& suffix, const std::string& address, unsigned int port) : m_enabled(false), m_idTimer(1000U), m_callsign(callsign), @@ -34,12 +33,14 @@ m_latitude(0.0F), m_longitude(0.0F), m_height(0), m_desc(), +m_aprsAddress(), +m_aprsPort(port), +m_aprsSocket(), m_mobileGPSAddress(), m_mobileGPSPort(0U), -m_socket(NULL) +m_mobileSocket(NULL) { assert(!callsign.empty()); - assert(!password.empty()); assert(!address.empty()); assert(port > 0U); @@ -48,7 +49,7 @@ m_socket(NULL) m_callsign.append(suffix.substr(0U, 1U)); } - m_thread = new CAPRSWriterThread(m_callsign, password, address, port); + m_aprsAddress = CUDPSocket::lookup(address); } CAPRSWriter::~CAPRSWriter() @@ -77,16 +78,16 @@ void CAPRSWriter::setMobileLocation(const std::string& address, unsigned int por m_mobileGPSAddress = CUDPSocket::lookup(address); m_mobileGPSPort = port; - m_socket = new CUDPSocket; + m_mobileSocket = new CUDPSocket; } bool CAPRSWriter::open() { - if (m_socket != NULL) { - bool ret = m_socket->open(); + if (m_mobileSocket != NULL) { + bool ret = m_mobileSocket->open(); if (!ret) { - delete m_socket; - m_socket = NULL; + delete m_mobileSocket; + m_mobileSocket = NULL; return false; } @@ -98,23 +99,21 @@ bool CAPRSWriter::open() m_idTimer.start(); - return m_thread->start(); + return m_aprsSocket.open(); } void CAPRSWriter::write(const char* data) { assert(data != NULL); - m_thread->write(data); + m_aprsSocket.write((unsigned char*)data, (unsigned int)::strlen(data), m_aprsAddress, m_aprsPort); } void CAPRSWriter::clock(unsigned int ms) { m_idTimer.clock(ms); - m_thread->clock(ms); - - if (m_socket != NULL) { + if (m_mobileSocket != NULL) { if (m_idTimer.hasExpired()) { pollGPS(); m_idTimer.start(); @@ -131,26 +130,23 @@ void CAPRSWriter::clock(unsigned int ms) void CAPRSWriter::close() { - if (m_socket != NULL) { - m_socket->close(); - delete m_socket; - } + m_aprsSocket.close(); - m_thread->stop(); + if (m_mobileSocket != NULL) { + m_mobileSocket->close(); + delete m_mobileSocket; + } } bool CAPRSWriter::pollGPS() { - assert(m_socket != NULL); + assert(m_mobileSocket != NULL); - return m_socket->write((unsigned char*)"NXDNGateway", 11U, m_mobileGPSAddress, m_mobileGPSPort); + return m_mobileSocket->write((unsigned char*)"NXDNGateway", 11U, m_mobileGPSAddress, m_mobileGPSPort); } void CAPRSWriter::sendIdFrameFixed() { - if (!m_thread->isConnected()) - return; - // Default values aren't passed on if (m_latitude == 0.0F && m_longitude == 0.0F) return; @@ -201,13 +197,13 @@ void CAPRSWriter::sendIdFrameFixed() server.append("S"); char output[500U]; - ::sprintf(output, "%s>APDG04,TCPIP*,qAC,%s:!%s%cD%s%c&/A=%06.0f%s %s", + ::sprintf(output, "%s>APDG04,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); - m_thread->write(output); + write(output); } void CAPRSWriter::sendIdFrameMobile() @@ -216,13 +212,10 @@ void CAPRSWriter::sendIdFrameMobile() unsigned char buffer[200U]; in_addr address; unsigned int port; - int ret = m_socket->read(buffer, 200U, address, port); + int ret = m_mobileSocket->read(buffer, 200U, address, port); if (ret <= 0) return; - if (!m_thread->isConnected()) - return; - buffer[ret] = '\0'; // Parse the GPS data @@ -297,8 +290,7 @@ void CAPRSWriter::sendIdFrameMobile() ::sprintf(output + ::strlen(output), "%03.0f/%03.0f", rawBearing, rawVelocity * 0.539957F); } - ::sprintf(output + ::strlen(output), "/A=%06.0f%s %s", float(rawAltitude) * 3.28F, band, desc); + ::sprintf(output + ::strlen(output), "/A=%06.0f%s %s\r\n", float(rawAltitude) * 3.28F, band, desc); - m_thread->write(output); + write(output); } - diff --git a/NXDNGateway/APRSWriter.h b/NXDNGateway/APRSWriter.h index 0ea1ad6..d486319 100644 --- a/NXDNGateway/APRSWriter.h +++ b/NXDNGateway/APRSWriter.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010,2011,2012,2016,2017,2018 by Jonathan Naylor G4KLX + * 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 @@ -19,7 +19,6 @@ #ifndef APRSWriter_H #define APRSWriter_H -#include "APRSWriterThread.h" #include "UDPSocket.h" #include "Timer.h" @@ -40,7 +39,7 @@ class CAPRSWriter { public: - CAPRSWriter(const std::string& callsign, const std::string& suffix, const std::string& password, const std::string& address, unsigned int port); + CAPRSWriter(const std::string& callsign, const std::string& suffix, const std::string& address, unsigned int port); ~CAPRSWriter(); bool open(); @@ -58,19 +57,21 @@ public: void close(); private: - CAPRSWriterThread* m_thread; - bool m_enabled; - CTimer m_idTimer; - std::string m_callsign; - unsigned int m_txFrequency; - unsigned int m_rxFrequency; - float m_latitude; - float m_longitude; - int m_height; - std::string m_desc; - in_addr m_mobileGPSAddress; - unsigned int m_mobileGPSPort; - CUDPSocket* m_socket; + bool m_enabled; + CTimer m_idTimer; + std::string m_callsign; + unsigned int m_txFrequency; + unsigned int m_rxFrequency; + float m_latitude; + float m_longitude; + int m_height; + std::string m_desc; + in_addr m_aprsAddress; + unsigned int m_aprsPort; + CUDPSocket m_aprsSocket; + in_addr m_mobileGPSAddress; + unsigned int m_mobileGPSPort; + CUDPSocket* m_mobileSocket; bool pollGPS(); void sendIdFrameFixed(); diff --git a/NXDNGateway/APRSWriterThread.cpp b/NXDNGateway/APRSWriterThread.cpp deleted file mode 100644 index c388609..0000000 --- a/NXDNGateway/APRSWriterThread.cpp +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright (C) 2010-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 "APRSWriterThread.h" -#include "Utils.h" -#include "Log.h" - -#include -#include -#include -#include -#include -#include - -// #define DUMP_TX - -const unsigned int CALLSIGN_LENGTH = 8U; - -const unsigned int APRS_TIMEOUT = 10U; - -CAPRSWriterThread::CAPRSWriterThread(const std::string& callsign, const std::string& password, const std::string& address, unsigned int port) : -CThread(), -m_username(callsign), -m_password(password), -m_socket(address, port), -m_queue(20U, "APRS Queue"), -m_exit(false), -m_connected(false), -m_reconnectTimer(1000U), -m_tries(1U), -m_APRSReadCallback(NULL), -m_filter(), -m_clientName("YSFGateway") -{ - assert(!callsign.empty()); - assert(!password.empty()); - assert(!address.empty()); - assert(port > 0U); - - m_username.resize(CALLSIGN_LENGTH, ' '); - m_username.erase(std::find_if(m_username.rbegin(), m_username.rend(), std::not1(std::ptr_fun(std::isspace))).base(), m_username.end()); - std::transform(m_username.begin(), m_username.end(), m_username.begin(), ::toupper); -} - -CAPRSWriterThread::CAPRSWriterThread(const std::string& callsign, const std::string& password, const std::string& address, unsigned int port, const std::string& filter, const std::string& clientName) : -CThread(), -m_username(callsign), -m_password(password), -m_socket(address, port), -m_queue(20U, "APRS Queue"), -m_exit(false), -m_connected(false), -m_reconnectTimer(1000U), -m_tries(1U), -m_APRSReadCallback(NULL), -m_filter(filter), -m_clientName(clientName) -{ - assert(!callsign.empty()); - assert(!password.empty()); - assert(!address.empty()); - assert(port > 0U); - - m_username.resize(CALLSIGN_LENGTH, ' '); - m_username.erase(std::find_if(m_username.rbegin(), m_username.rend(), std::not1(std::ptr_fun(std::isspace))).base(), m_username.end()); - std::transform(m_username.begin(), m_username.end(), m_username.begin(), ::toupper); -} - -CAPRSWriterThread::~CAPRSWriterThread() -{ - m_username.clear(); -} - -bool CAPRSWriterThread::start() -{ - run(); - - return true; -} - -void CAPRSWriterThread::entry() -{ - LogMessage("Starting the APRS Writer thread"); - - m_connected = connect(); - if (!m_connected) { - LogError("Connect attempt to the APRS server has failed"); - startReconnectionTimer(); - } - - try { - while (!m_exit) { - if (!m_connected) { - if (m_reconnectTimer.isRunning() && m_reconnectTimer.hasExpired()) { - m_reconnectTimer.stop(); - - m_connected = connect(); - if (!m_connected) { - LogError("Reconnect attempt to the APRS server has failed"); - startReconnectionTimer(); - } - } - } - - if (m_connected) { - m_tries = 0U; - - if (!m_queue.isEmpty()){ - char* p = NULL; - m_queue.getData(&p, 1U); - - LogMessage("APRS ==> %s", p); - - ::strcat(p, "\r\n"); - - bool ret = m_socket.write((unsigned char*)p, (unsigned int)::strlen(p)); - if (!ret) { - m_connected = false; - m_socket.close(); - LogError("Connection to the APRS thread has failed"); - startReconnectionTimer(); - } - - delete[] p; - } - { - std::string line; - int length = m_socket.readLine(line, APRS_TIMEOUT); - - if (length < 0) { - m_connected = false; - m_socket.close(); - LogError("Error when reading from the APRS server"); - startReconnectionTimer(); - } - - if(length > 0 && line.at(0U) != '#'//check if we have something and if that something is an APRS frame - && m_APRSReadCallback != NULL)//do we have someone wanting an APRS Frame? - { - //wxLogMessage(wxT("Received APRS Frame : ") + line); - m_APRSReadCallback(std::string(line)); - } - } - - } - } - - if (m_connected) - m_socket.close(); - - while (!m_queue.isEmpty()) { - char* p = NULL; - m_queue.getData(&p, 1U); - delete[] p; - } - } - catch (std::exception& e) { - LogError("Exception raised in the APRS Writer thread - \"%s\"", e.what()); - } - catch (...) { - LogError("Unknown exception raised in the APRS Writer thread"); - } - - LogMessage("Stopping the APRS Writer thread"); -} - -void CAPRSWriterThread::setReadAPRSCallback(ReadAPRSFrameCallback cb) -{ - m_APRSReadCallback = cb; -} - -void CAPRSWriterThread::write(const char* data) -{ - assert(data != NULL); - - if (!m_connected) - return; - - unsigned int len = (unsigned int)::strlen(data); - - char* p = new char[len + 5U]; - ::strcpy(p, data); - - m_queue.addData(&p, 1U); -} - -bool CAPRSWriterThread::isConnected() const -{ - return m_connected; -} - -void CAPRSWriterThread::stop() -{ - m_exit = true; - - wait(); -} - -void CAPRSWriterThread::clock(unsigned int ms) -{ - m_reconnectTimer.clock(ms); -} - -bool CAPRSWriterThread::connect() -{ - bool ret = m_socket.open(); - if (!ret) - return false; - - //wait for lgin banner - int length; - std::string serverResponse; - length = m_socket.readLine(serverResponse, APRS_TIMEOUT); - if (length == 0) { - LogError("No reply from the APRS server after %u seconds", APRS_TIMEOUT); - m_socket.close(); - return false; - } - - LogMessage("Received login banner : %s", serverResponse.c_str()); - - std::string filter(m_filter); - if (filter.length() > 0) - filter.insert(0U, " filter "); - - char connectString[200U]; - ::sprintf(connectString, "user %s pass %s vers %s%s\n", m_username.c_str(), m_password.c_str(), (m_clientName.length() ? m_clientName : "YSFGateway").c_str(), filter.c_str()); - - ret = m_socket.writeLine(std::string(connectString)); - if (!ret) { - m_socket.close(); - return false; - } - - length = m_socket.readLine(serverResponse, APRS_TIMEOUT); - if (length == 0) { - LogError("No reply from the APRS server after %u seconds", APRS_TIMEOUT); - m_socket.close(); - return false; - } - - if (length < 0) { - LogError("Error when reading from the APRS server"); - m_socket.close(); - return false; - } - - LogMessage("Response from APRS server: %s", serverResponse.c_str()); - - LogMessage("Connected to the APRS server"); - - return true; -} - -void CAPRSWriterThread::startReconnectionTimer() -{ - // Clamp at a ten minutes reconnect time - m_tries++; - if (m_tries > 10U) - m_tries = 10U; - - m_reconnectTimer.setTimeout(m_tries * 60U); - m_reconnectTimer.start(); -} diff --git a/NXDNGateway/APRSWriterThread.h b/NXDNGateway/APRSWriterThread.h deleted file mode 100644 index c86c23a..0000000 --- a/NXDNGateway/APRSWriterThread.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2010,2011,2012,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 APRSWriterThread_H -#define APRSWriterThread_H - -#include "TCPSocket.h" -#include "RingBuffer.h" -#include "Timer.h" -#include "Thread.h" - -#include - -typedef void (*ReadAPRSFrameCallback)(const std::string&); - -class CAPRSWriterThread : public CThread { -public: - CAPRSWriterThread(const std::string& callsign, const std::string& password, const std::string& address, unsigned int port); - CAPRSWriterThread(const std::string& callsign, const std::string& password, const std::string& address, unsigned int port, const std::string& filter, const std::string& clientName); - virtual ~CAPRSWriterThread(); - - virtual bool start(); - - virtual bool isConnected() const; - - virtual void write(const char* data); - - virtual void entry(); - - virtual void stop(); - - void setReadAPRSCallback(ReadAPRSFrameCallback cb); - - void clock(unsigned int ms); - -private: - std::string m_username; - std::string m_password; - CTCPSocket m_socket; - CRingBuffer m_queue; - bool m_exit; - bool m_connected; - CTimer m_reconnectTimer; - unsigned int m_tries; - ReadAPRSFrameCallback m_APRSReadCallback; - std::string m_filter; - std::string m_clientName; - - bool connect(); - void startReconnectionTimer(); -}; - -#endif diff --git a/NXDNGateway/Conf.cpp b/NXDNGateway/Conf.cpp index 446be3d..81e1af3 100644 --- a/NXDNGateway/Conf.cpp +++ b/NXDNGateway/Conf.cpp @@ -33,7 +33,7 @@ enum SECTION { SECTION_ID_LOOKUP, SECTION_VOICE, SECTION_LOG, - SECTION_APRS_FI, + SECTION_APRS, SECTION_NETWORK, SECTION_MOBILE_GPS, SECTION_REMOTE_COMMANDS @@ -65,9 +65,8 @@ m_voiceDirectory(), m_logFilePath(), m_logFileRoot(), m_aprsEnabled(false), -m_aprsServer(), -m_aprsPort(0U), -m_aprsPassword(), +m_aprsAddress("127.0.0.1"), +m_aprsPort(8673U), m_aprsSuffix(), m_aprsDescription(), m_networkPort(0U), @@ -119,8 +118,8 @@ bool CConf::read() section = SECTION_VOICE; else if (::strncmp(buffer, "[Log]", 5U) == 0) section = SECTION_LOG; - else if (::strncmp(buffer, "[aprs.fi]", 9U) == 0) - section = SECTION_APRS_FI; + else if (::strncmp(buffer, "[APRS]", 6U) == 0) + section = SECTION_APRS; else if (::strncmp(buffer, "[Network]", 9U) == 0) section = SECTION_NETWORK; else if (::strncmp(buffer, "[Mobile GPS]", 12U) == 0) @@ -195,15 +194,13 @@ bool CConf::read() m_logFilePath = value; else if (::strcmp(key, "FileRoot") == 0) m_logFileRoot = value; - } else if (section == SECTION_APRS_FI) { + } else if (section == SECTION_APRS) { if (::strcmp(key, "Enable") == 0) m_aprsEnabled = ::atoi(value) == 1; - else if (::strcmp(key, "Server") == 0) - m_aprsServer = value; + 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, "Password") == 0) - m_aprsPassword = value; else if (::strcmp(key, "Suffix") == 0) m_aprsSuffix = value; else if (::strcmp(key, "Description") == 0) @@ -366,9 +363,9 @@ bool CConf::getAPRSEnabled() const return m_aprsEnabled; } -std::string CConf::getAPRSServer() const +std::string CConf::getAPRSAddress() const { - return m_aprsServer; + return m_aprsAddress; } unsigned int CConf::getAPRSPort() const @@ -376,11 +373,6 @@ unsigned int CConf::getAPRSPort() const return m_aprsPort; } -std::string CConf::getAPRSPassword() const -{ - return m_aprsPassword; -} - std::string CConf::getAPRSSuffix() const { return m_aprsSuffix; diff --git a/NXDNGateway/Conf.h b/NXDNGateway/Conf.h index 439727e..5b3496c 100644 --- a/NXDNGateway/Conf.h +++ b/NXDNGateway/Conf.h @@ -59,11 +59,10 @@ public: std::string getVoiceLanguage() const; std::string getVoiceDirectory() const; - // The aprs.fi section + // The APRS section bool getAPRSEnabled() const; - std::string getAPRSServer() const; + std::string getAPRSAddress() const; unsigned int getAPRSPort() const; - std::string getAPRSPassword() const; std::string getAPRSSuffix() const; std::string getAPRSDescription() const; @@ -124,9 +123,8 @@ private: std::string m_logFileRoot; bool m_aprsEnabled; - std::string m_aprsServer; + std::string m_aprsAddress; unsigned int m_aprsPort; - std::string m_aprsPassword; std::string m_aprsSuffix; std::string m_aprsDescription; diff --git a/NXDNGateway/GPSHandler.cpp b/NXDNGateway/GPSHandler.cpp index e0a511f..4a81e7c 100644 --- a/NXDNGateway/GPSHandler.cpp +++ b/NXDNGateway/GPSHandler.cpp @@ -140,10 +140,10 @@ bool CGPSHandler::processIcom() int bearing = ::atoi(pRMC[8U]); int speed = ::atoi(pRMC[7U]); - ::sprintf(output, "%s>APDPRS,NXDN*,qAR,%s:!%07.2lf%s/%08.2lf%sr%03d/%03d Icom IDAS via MMDVM", + ::sprintf(output, "%s>APDPRS,NXDN*,qAR,%s:!%07.2lf%s/%08.2lf%sr%03d/%03d Icom IDAS via MMDVM\r\n", source.c_str(), m_callsign.c_str(), latitude, pRMC[4U], longitude, pRMC[6U], bearing, speed); } else { - ::sprintf(output, "%s>APDPRS,NXDN*,qAR,%s:!%07.2lf%s/%08.2lf%sr Icom IDAS via MMDVM", + ::sprintf(output, "%s>APDPRS,NXDN*,qAR,%s:!%07.2lf%s/%08.2lf%sr Icom IDAS via MMDVM\r\n", source.c_str(), m_callsign.c_str(), latitude, pRMC[4U], longitude, pRMC[6U]); } @@ -239,10 +239,10 @@ bool CGPSHandler::processKenwood() char output[300U]; if (course != 0xFFFFU && speedBefore != 0x3FFU && speedAfter != 0x0FU) { - ::sprintf(output, "%s>APDPRS,NXDN*,qAR,%s:!%04u.%02u%c/%05u.%02u%cr%03d/%03d Kenwood NEXEDGE via MMDVM", + ::sprintf(output, "%s>APDPRS,NXDN*,qAR,%s:!%04u.%02u%c/%05u.%02u%cr%03d/%03d Kenwood NEXEDGE via MMDVM\r\n", source.c_str(), m_callsign.c_str(), latBefore, latAfter / 100U, north, lonBefore, lonAfter / 100U, east, course / 10U, speedBefore); } else { - ::sprintf(output, "%s>APDPRS,NXDN*,qAR,%s:!%04u.%02u%c/%05u.%02u%cr Kenwood NEXEDGE via MMDVM", + ::sprintf(output, "%s>APDPRS,NXDN*,qAR,%s:!%04u.%02u%c/%05u.%02u%cr Kenwood NEXEDGE via MMDVM\r\n", source.c_str(), m_callsign.c_str(), latBefore, latAfter / 100U, north, lonBefore, lonAfter / 100U, east); } diff --git a/NXDNGateway/Makefile b/NXDNGateway/Makefile index 4ec984b..20032a2 100644 --- a/NXDNGateway/Makefile +++ b/NXDNGateway/Makefile @@ -4,8 +4,8 @@ CFLAGS = -g -O3 -Wall -std=c++0x -pthread LIBS = -lpthread LDFLAGS = -g -OBJECTS = APRSWriter.o APRSWriterThread.o Conf.o GPSHandler.o IcomNetwork.o KenwoodNetwork.o Log.o Mutex.o NXDNCRC.o NXDNGateway.o NXDNLookup.o NXDNNetwork.o \ - Reflectors.o RptNetwork.o StopWatch.o TCPSocket.o Thread.o Timer.o UDPSocket.o Utils.o Voice.o +OBJECTS = APRSWriter.o Conf.o GPSHandler.o IcomNetwork.o KenwoodNetwork.o Log.o Mutex.o NXDNCRC.o NXDNGateway.o NXDNLookup.o NXDNNetwork.o \ + Reflectors.o RptNetwork.o StopWatch.o Thread.o Timer.o UDPSocket.o Utils.o Voice.o all: NXDNGateway @@ -17,4 +17,4 @@ NXDNGateway: $(OBJECTS) clean: $(RM) NXDNGateway *.o *.d *.bak *~ - \ No newline at end of file + diff --git a/NXDNGateway/NXDNGateway.cpp b/NXDNGateway/NXDNGateway.cpp index e614f9a..ae8a008 100644 --- a/NXDNGateway/NXDNGateway.cpp +++ b/NXDNGateway/NXDNGateway.cpp @@ -591,12 +591,11 @@ void CNXDNGateway::createGPS() std::string callsign = m_conf.getCallsign(); std::string rptSuffix = m_conf.getSuffix(); - std::string hostname = m_conf.getAPRSServer(); + std::string address = m_conf.getAPRSAddress(); unsigned int port = m_conf.getAPRSPort(); - std::string password = m_conf.getAPRSPassword(); std::string suffix = m_conf.getAPRSSuffix(); - m_writer = new CAPRSWriter(callsign, rptSuffix, password, hostname, port); + m_writer = new CAPRSWriter(callsign, rptSuffix, address, port); unsigned int txFrequency = m_conf.getTxFrequency(); unsigned int rxFrequency = m_conf.getRxFrequency(); diff --git a/NXDNGateway/NXDNGateway.ini b/NXDNGateway/NXDNGateway.ini index 205857c..d15e4da 100644 --- a/NXDNGateway/NXDNGateway.ini +++ b/NXDNGateway/NXDNGateway.ini @@ -16,7 +16,7 @@ RptProtocol=Icom RptAddress=127.0.0.1 RptPort=14021 LocalPort=14020 -Debug=0 +Debug=1 Daemon=1 [Info] @@ -34,14 +34,12 @@ Enabled=1 Language=en_GB Directory=./Audio -[aprs.fi] +[APRS] Enable=0 -# Server=noam.aprs2.net -Server=euro.aprs2.net -Port=14580 -Password=9999 -Description=APRS Description +Address=127.0.0.1 +Port=8673 Suffix=N +Description=APRS Description [Id Lookup] Name=NXDN.csv diff --git a/NXDNGateway/NXDNGateway.vcxproj b/NXDNGateway/NXDNGateway.vcxproj index e955110..fae0cf4 100644 --- a/NXDNGateway/NXDNGateway.vcxproj +++ b/NXDNGateway/NXDNGateway.vcxproj @@ -147,7 +147,6 @@ - @@ -162,7 +161,6 @@ - @@ -172,7 +170,6 @@ - @@ -186,7 +183,6 @@ - diff --git a/NXDNGateway/NXDNGateway.vcxproj.filters b/NXDNGateway/NXDNGateway.vcxproj.filters index 4215f7e..e34f2d5 100644 --- a/NXDNGateway/NXDNGateway.vcxproj.filters +++ b/NXDNGateway/NXDNGateway.vcxproj.filters @@ -62,12 +62,6 @@ Header Files - - Header Files - - - Header Files - Header Files @@ -130,12 +124,6 @@ Source Files - - Source Files - - - Source Files - Source Files diff --git a/NXDNGateway/TCPSocket.cpp b/NXDNGateway/TCPSocket.cpp deleted file mode 100644 index 9bfc3c0..0000000 --- a/NXDNGateway/TCPSocket.cpp +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (C) 2010-2013,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 "TCPSocket.h" -#include "UDPSocket.h" -#include "Log.h" - -#include -#include -#include - -#if defined(_WIN32) || defined(_WIN64) -typedef int ssize_t; -#else -#include -#endif - -CTCPSocket::CTCPSocket(const std::string& address, unsigned int port) : -m_address(address), -m_port(port), -m_fd(-1) -{ - assert(!address.empty()); - assert(port > 0U); - -#if defined(_WIN32) || defined(_WIN64) - WSAData data; - int wsaRet = ::WSAStartup(MAKEWORD(2, 2), &data); - if (wsaRet != 0) - LogError("Error from WSAStartup"); -#endif -} - -CTCPSocket::~CTCPSocket() -{ -#if defined(_WIN32) || defined(_WIN64) - ::WSACleanup(); -#endif -} - -bool CTCPSocket::open() -{ - if (m_fd != -1) - return true; - - if (m_address.empty() || m_port == 0U) - return false; - - m_fd = ::socket(PF_INET, SOCK_STREAM, 0); - if (m_fd < 0) { -#if defined(_WIN32) || defined(_WIN64) - LogError("Cannot create the TCP client socket, err=%d", ::GetLastError()); -#else - LogError("Cannot create the TCP client socket, err=%d", errno); -#endif - return false; - } - - struct sockaddr_in addr; - ::memset(&addr, 0x00, sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; - addr.sin_port = htons(m_port); - addr.sin_addr = CUDPSocket::lookup(m_address); - - if (addr.sin_addr.s_addr == INADDR_NONE) { - close(); - return false; - } - - if (::connect(m_fd, (sockaddr*)&addr, sizeof(struct sockaddr_in)) == -1) { -#if defined(_WIN32) || defined(_WIN64) - LogError("Cannot connect the TCP client socket, err=%d", ::GetLastError()); -#else - LogError("Cannot connect the TCP client socket, err=%d", errno); -#endif - close(); - return false; - } - - int noDelay = 1; - if (::setsockopt(m_fd, IPPROTO_TCP, TCP_NODELAY, (char *)&noDelay, sizeof(noDelay)) == -1) { -#if defined(_WIN32) || defined(_WIN64) - LogError("Cannot set the TCP client socket option, err=%d", ::GetLastError()); -#else - LogError("Cannot set the TCP client socket option, err=%d", errno); -#endif - close(); - return false; - } - - return true; -} - -int CTCPSocket::read(unsigned char* buffer, unsigned int length, unsigned int secs, unsigned int msecs) -{ - assert(buffer != NULL); - assert(length > 0U); - assert(m_fd != -1); - - // Check that the recv() 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 after timeout - timeval tv; - tv.tv_sec = secs; - tv.tv_usec = msecs * 1000; - - int ret = ::select(m_fd + 1, &readFds, NULL, NULL, &tv); - if (ret < 0) { -#if defined(_WIN32) || defined(_WIN64) - LogError("Error returned from TCP client select, err=%d", ::GetLastError()); -#else - LogError("Error returned from TCP client select, err=%d", errno); -#endif - return -1; - } - -#if defined(_WIN32) || defined(_WIN64) - if (!FD_ISSET((unsigned int)m_fd, &readFds)) - return 0; -#else - if (!FD_ISSET(m_fd, &readFds)) - return 0; -#endif - - ssize_t len = ::recv(m_fd, (char*)buffer, length, 0); - if (len == 0) { - return -2; - } else if (len < 0) { -#if defined(_WIN32) || defined(_WIN64) - LogError("Error returned from recv, err=%d", ::GetLastError()); -#else - LogError("Error returned from recv, err=%d", errno); -#endif - return -1; - } - - return len; -} - -int CTCPSocket::readLine(std::string& line, unsigned int secs) -{ - // Maybe there is a better way to do this like reading blocks, pushing them for later calls - // Nevermind, we'll read one char at a time for the time being. - int resultCode; - int len = 0; - - line.clear(); - - char c[2U]; - c[1U] = 0x00U; - - do - { - resultCode = read((unsigned char*)c, 1U, secs); - if (resultCode == 1){ - line.append(c); - len++; - } - } while (c[0U] != '\n' && resultCode == 1); - - return resultCode <= 0 ? resultCode : len; -} - -bool CTCPSocket::write(const unsigned char* buffer, unsigned int length) -{ - assert(buffer != NULL); - assert(length > 0U); - assert(m_fd != -1); - - ssize_t ret = ::send(m_fd, (char *)buffer, length, 0); - if (ret != ssize_t(length)) { -#if defined(_WIN32) || defined(_WIN64) - LogError("Error returned from send, err=%d", ::GetLastError()); -#else - LogError("Error returned from send, err=%d", errno); -#endif - return false; - } - - return true; -} - -bool CTCPSocket::writeLine(const std::string& line) -{ - std::string lineCopy(line); - if (lineCopy.length() > 0 && lineCopy.at(lineCopy.length() - 1) != '\n') - lineCopy.append("\n"); - - //stupidly write one char after the other - size_t len = lineCopy.length(); - bool result = true; - for (size_t i = 0U; i < len && result; i++){ - unsigned char c = lineCopy.at(i); - result = write(&c , 1); - } - - return result; -} - -void CTCPSocket::close() -{ - if (m_fd != -1) { -#if defined(_WIN32) || defined(_WIN64) - ::closesocket(m_fd); -#else - ::close(m_fd); -#endif - m_fd = -1; - } -} diff --git a/NXDNGateway/TCPSocket.h b/NXDNGateway/TCPSocket.h deleted file mode 100644 index f3321ed..0000000 --- a/NXDNGateway/TCPSocket.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2010,2011,2012,2013,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 TCPSocket_H -#define TCPSocket_H - -#if !defined(_WIN32) && !defined(_WIN64) -#include -#include -#include -#include -#include -#include -#include -#include -#include -#else -#include -#endif - -#include - -class CTCPSocket { -public: - CTCPSocket(const std::string& address, unsigned int port); - ~CTCPSocket(); - - bool open(); - - int read(unsigned char* buffer, unsigned int length, unsigned int secs, unsigned int msecs = 0U); - int readLine(std::string& line, unsigned int secs); - bool write(const unsigned char* buffer, unsigned int length); - bool writeLine(const std::string& line); - - void close(); - -private: - std::string m_address; - unsigned short m_port; - int m_fd; -}; - -#endif diff --git a/NXDNGateway/Version.h b/NXDNGateway/Version.h index 1c4898c..b8cc636 100644 --- a/NXDNGateway/Version.h +++ b/NXDNGateway/Version.h @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -const char* VERSION = "20200519"; +const char* VERSION = "20200601"; #endif From 95f5d1761d287295705d4ed0a44728194b1b5948 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Mon, 1 Jun 2020 11:37:46 +0100 Subject: [PATCH 03/27] Revert ini file change. --- NXDNGateway/NXDNGateway.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NXDNGateway/NXDNGateway.ini b/NXDNGateway/NXDNGateway.ini index d15e4da..d0fba44 100644 --- a/NXDNGateway/NXDNGateway.ini +++ b/NXDNGateway/NXDNGateway.ini @@ -16,7 +16,7 @@ RptProtocol=Icom RptAddress=127.0.0.1 RptPort=14021 LocalPort=14020 -Debug=1 +Debug=0 Daemon=1 [Info] From 51b2158736192fcac7e0ab975f15e832e71357d3 Mon Sep 17 00:00:00 2001 From: sp4feu <56378304+sp4feu@users.noreply.github.com> Date: Tue, 2 Jun 2020 10:24:24 +0200 Subject: [PATCH 04/27] Update NXDNHosts.txt --- NXDNGateway/NXDNHosts.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NXDNGateway/NXDNHosts.txt b/NXDNGateway/NXDNHosts.txt index 06208ca..887bbf1 100644 --- a/NXDNGateway/NXDNHosts.txt +++ b/NXDNGateway/NXDNHosts.txt @@ -8,6 +8,9 @@ # RED NXDN SPAIN 214 nxdn214.xreflector.es 41400 +# HBLink Poland ,TG260 +260 nxdn.hblink.pl 41400 + # 302, P25 Canada 302 p25canada.hopto.org 41400 From 61479b55dc1dbe57a8b32bbb6d507c22badcc87a Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Wed, 3 Jun 2020 12:24:29 +0100 Subject: [PATCH 05/27] Use gpsd instead of MobileGPS. --- NXDNGateway/APRSWriter.cpp | 108 ++++++++++++++++++------------------ NXDNGateway/APRSWriter.h | 37 ++++++------ NXDNGateway/Conf.cpp | 32 +++++------ NXDNGateway/Conf.h | 14 ++--- NXDNGateway/Makefile | 4 +- NXDNGateway/NXDNGateway.cpp | 8 +-- NXDNGateway/NXDNGateway.ini | 4 +- NXDNGateway/Version.h | 2 +- 8 files changed, 107 insertions(+), 102 deletions(-) diff --git a/NXDNGateway/APRSWriter.cpp b/NXDNGateway/APRSWriter.cpp index 0dc0177..a301eba 100644 --- a/NXDNGateway/APRSWriter.cpp +++ b/NXDNGateway/APRSWriter.cpp @@ -17,6 +17,7 @@ */ #include "APRSWriter.h" +#include "Log.h" #include #include @@ -35,10 +36,13 @@ m_height(0), m_desc(), m_aprsAddress(), m_aprsPort(port), -m_aprsSocket(), -m_mobileGPSAddress(), -m_mobileGPSPort(0U), -m_mobileSocket(NULL) +m_aprsSocket() +#if !defined(_WIN32) && !defined(_WIN64) +,m_gpsdEnabled(false), +m_gpsdAddress(), +m_gpsdPort(0U), +m_gpsdData() +#endif { assert(!callsign.empty()); assert(!address.empty()); @@ -70,32 +74,36 @@ void CAPRSWriter::setStaticLocation(float latitude, float longitude, int height) m_height = height; } -void CAPRSWriter::setMobileLocation(const std::string& address, unsigned int port) +void CAPRSWriter::setGPSDLocation(const std::string& address, const std::string& port) { +#if !defined(_WIN32) && !defined(_WIN64) assert(!address.empty()); - assert(port > 0U); + assert(!port.empty()); - m_mobileGPSAddress = CUDPSocket::lookup(address); - m_mobileGPSPort = port; - - m_mobileSocket = new CUDPSocket; + m_gpsdEnabled = true; + m_gpsdAddress = address; + m_gpsdPort = port; +#endif } bool CAPRSWriter::open() { - if (m_mobileSocket != NULL) { - bool ret = m_mobileSocket->open(); - if (!ret) { - delete m_mobileSocket; - m_mobileSocket = NULL; +#if !defined(_WIN32) && !defined(_WIN64) + 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); + // Poll the GPS every minute m_idTimer.setTimeout(60U); } else { m_idTimer.setTimeout(20U * 60U); } +#endif m_idTimer.start(); @@ -113,36 +121,34 @@ void CAPRSWriter::clock(unsigned int ms) { m_idTimer.clock(ms); - if (m_mobileSocket != NULL) { +#if !defined(_WIN32) && !defined(_WIN64) + if (m_gpsdEnabled) { if (m_idTimer.hasExpired()) { - pollGPS(); + sendIdFrameMobile(); m_idTimer.start(); } - sendIdFrameMobile(); } else { +#endif if (m_idTimer.hasExpired()) { sendIdFrameFixed(); m_idTimer.start(); } +#if !defined(_WIN32) && !defined(_WIN64) } +#endif } void CAPRSWriter::close() { m_aprsSocket.close(); - if (m_mobileSocket != NULL) { - m_mobileSocket->close(); - delete m_mobileSocket; +#if !defined(_WIN32) && !defined(_WIN64) + if (m_gpsdEnabled) { + ::gps_stream(&m_gpsdData, WATCH_DISABLE, NULL); + ::gps_close(&m_gpsdData); } -} - -bool CAPRSWriter::pollGPS() -{ - assert(m_mobileSocket != NULL); - - return m_mobileSocket->write((unsigned char*)"NXDNGateway", 11U, m_mobileGPSAddress, m_mobileGPSPort); +#endif } void CAPRSWriter::sendIdFrameFixed() @@ -208,29 +214,25 @@ void CAPRSWriter::sendIdFrameFixed() void CAPRSWriter::sendIdFrameMobile() { - // Grab GPS data if it's available - unsigned char buffer[200U]; - in_addr address; - unsigned int port; - int ret = m_mobileSocket->read(buffer, 200U, address, port); - if (ret <= 0) + if (!m_gpsdEnabled) return; - buffer[ret] = '\0'; - - // Parse the GPS data - char* pLatitude = ::strtok((char*)buffer, ",\n"); // Latitude - char* pLongitude = ::strtok(NULL, ",\n"); // Longitude - char* pAltitude = ::strtok(NULL, ",\n"); // Altitude (m) - char* pVelocity = ::strtok(NULL, ",\n"); // Velocity (kms/h) - char* pBearing = ::strtok(NULL, "\n"); // Bearing - - if (pLatitude == NULL || pLongitude == NULL || pAltitude == NULL) + if (!::gps_waiting(&m_gpsdData, 0)) return; - float rawLatitude = float(::atof(pLatitude)); - float rawLongitude = float(::atof(pLongitude)); - float rawAltitude = float(::atof(pAltitude)); + 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); + float rawAltitude = float(m_gpsdData.fix.altMSL); + float rawVelocity = float(m_gpsdData.fix.speed); + float rawBearing = float(m_gpsdData.fix.track); char desc[200U]; if (m_txFrequency != 0U) { @@ -283,14 +285,14 @@ void CAPRSWriter::sendIdFrameMobile() lat, (rawLatitude < 0.0F) ? 'S' : 'N', lon, (rawLongitude < 0.0F) ? 'W' : 'E'); - if (pBearing != NULL && pVelocity != NULL) { - float rawBearing = float(::atof(pBearing)); - float rawVelocity = float(::atof(pVelocity)); - + if (bearingSet && velocitySet) ::sprintf(output + ::strlen(output), "%03.0f/%03.0f", rawBearing, rawVelocity * 0.539957F); - } - ::sprintf(output + ::strlen(output), "/A=%06.0f%s %s\r\n", float(rawAltitude) * 3.28F, band, desc); + if (altitudeSet) + ::sprintf(output + ::strlen(output), "/A=%06.0f", float(rawAltitude) * 3.28F); + + ::sprintf(output + ::strlen(output), "%s %s\r\n", band, desc); write(output); } + diff --git a/NXDNGateway/APRSWriter.h b/NXDNGateway/APRSWriter.h index d486319..21f322f 100644 --- a/NXDNGateway/APRSWriter.h +++ b/NXDNGateway/APRSWriter.h @@ -33,6 +33,7 @@ #include #include #include +#include #else #include #endif @@ -48,7 +49,7 @@ public: void setStaticLocation(float latitude, float longitude, int height); - void setMobileLocation(const std::string& address, unsigned int port); + void setGPSDLocation(const std::string& address, const std::string& port); void write(const char* data); @@ -57,23 +58,25 @@ public: void close(); private: - bool m_enabled; - CTimer m_idTimer; - std::string m_callsign; - unsigned int m_txFrequency; - unsigned int m_rxFrequency; - float m_latitude; - float m_longitude; - int m_height; - std::string m_desc; - in_addr m_aprsAddress; - unsigned int m_aprsPort; - CUDPSocket m_aprsSocket; - in_addr m_mobileGPSAddress; - unsigned int m_mobileGPSPort; - CUDPSocket* m_mobileSocket; + bool m_enabled; + CTimer m_idTimer; + std::string m_callsign; + unsigned int m_txFrequency; + unsigned int m_rxFrequency; + float m_latitude; + float m_longitude; + int m_height; + std::string m_desc; + in_addr m_aprsAddress; + unsigned int m_aprsPort; + CUDPSocket m_aprsSocket; +#if !defined(_WIN32) && !defined(_WIN64) + bool m_gpsdEnabled; + std::string m_gpsdAddress; + std::string m_gpsdPort; + struct gps_data_t m_gpsdData; +#endif - bool pollGPS(); void sendIdFrameFixed(); void sendIdFrameMobile(); }; diff --git a/NXDNGateway/Conf.cpp b/NXDNGateway/Conf.cpp index 81e1af3..d1969b0 100644 --- a/NXDNGateway/Conf.cpp +++ b/NXDNGateway/Conf.cpp @@ -35,7 +35,7 @@ enum SECTION { SECTION_LOG, SECTION_APRS, SECTION_NETWORK, - SECTION_MOBILE_GPS, + SECTION_GPSD, SECTION_REMOTE_COMMANDS }; @@ -80,9 +80,9 @@ m_networkNXDN2DMRPort(0U), m_networkStartup(9999U), m_networkInactivityTimeout(0U), m_networkDebug(false), -m_mobileGPSEnabled(false), -m_mobileGPSAddress(), -m_mobileGPSPort(0U), +m_gpsdEnabled(false), +m_gpsdAddress(), +m_gpsdPort(), m_remoteCommandsEnabled(false), m_remoteCommandsPort(6075U) { @@ -122,8 +122,8 @@ bool CConf::read() section = SECTION_APRS; else if (::strncmp(buffer, "[Network]", 9U) == 0) section = SECTION_NETWORK; - else if (::strncmp(buffer, "[Mobile GPS]", 12U) == 0) - section = SECTION_MOBILE_GPS; + else if (::strncmp(buffer, "[GPSD]", 6U) == 0) + section = SECTION_GPSD; else if (::strncmp(buffer, "[Remote Commands]", 17U) == 0) section = SECTION_REMOTE_COMMANDS; else @@ -228,13 +228,13 @@ bool CConf::read() m_networkInactivityTimeout = (unsigned int)::atoi(value); else if (::strcmp(key, "Debug") == 0) m_networkDebug = ::atoi(value) == 1; - } else if (section == SECTION_MOBILE_GPS) { + } else if (section == SECTION_GPSD) { if (::strcmp(key, "Enable") == 0) - m_mobileGPSEnabled = ::atoi(value) == 1; + m_gpsdEnabled = ::atoi(value) == 1; else if (::strcmp(key, "Address") == 0) - m_mobileGPSAddress = value; + m_gpsdAddress = value; else if (::strcmp(key, "Port") == 0) - m_mobileGPSPort = (unsigned int)::atoi(value); + m_gpsdPort = value; } else if (section == SECTION_REMOTE_COMMANDS) { if (::strcmp(key, "Enable") == 0) m_remoteCommandsEnabled = ::atoi(value) == 1; @@ -443,19 +443,19 @@ bool CConf::getNetworkDebug() const return m_networkDebug; } -bool CConf::getMobileGPSEnabled() const +bool CConf::getGPSDEnabled() const { - return m_mobileGPSEnabled; + return m_gpsdEnabled; } -std::string CConf::getMobileGPSAddress() const +std::string CConf::getGPSDAddress() const { - return m_mobileGPSAddress; + return m_gpsdAddress; } -unsigned int CConf::getMobileGPSPort() const +std::string CConf::getGPSDPort() const { - return m_mobileGPSPort; + return m_gpsdPort; } bool CConf::getRemoteCommandsEnabled() const diff --git a/NXDNGateway/Conf.h b/NXDNGateway/Conf.h index 5b3496c..32794cf 100644 --- a/NXDNGateway/Conf.h +++ b/NXDNGateway/Conf.h @@ -83,10 +83,10 @@ public: unsigned int getNetworkInactivityTimeout() const; bool getNetworkDebug() const; - // The Mobile GPS section - bool getMobileGPSEnabled() const; - std::string getMobileGPSAddress() const; - unsigned int getMobileGPSPort() const; + // The GPSD section + bool getGPSDEnabled() const; + std::string getGPSDAddress() const; + std::string getGPSDPort() const; // The Remote Commands section bool getRemoteCommandsEnabled() const; @@ -140,9 +140,9 @@ private: unsigned int m_networkInactivityTimeout; bool m_networkDebug; - bool m_mobileGPSEnabled; - std::string m_mobileGPSAddress; - unsigned int m_mobileGPSPort; + bool m_gpsdEnabled; + std::string m_gpsdAddress; + std::string m_gpsdPort; bool m_remoteCommandsEnabled; unsigned int m_remoteCommandsPort; diff --git a/NXDNGateway/Makefile b/NXDNGateway/Makefile index 20032a2..d9bc000 100644 --- a/NXDNGateway/Makefile +++ b/NXDNGateway/Makefile @@ -1,11 +1,11 @@ CC = gcc CXX = g++ CFLAGS = -g -O3 -Wall -std=c++0x -pthread -LIBS = -lpthread +LIBS = -lpthread -lgps LDFLAGS = -g OBJECTS = APRSWriter.o Conf.o GPSHandler.o IcomNetwork.o KenwoodNetwork.o Log.o Mutex.o NXDNCRC.o NXDNGateway.o NXDNLookup.o NXDNNetwork.o \ - Reflectors.o RptNetwork.o StopWatch.o Thread.o Timer.o UDPSocket.o Utils.o Voice.o + Reflectors.o RptNetwork.o StopWatch.o Thread.o Timer.o UDPSocket.o Utils.o Voice.o all: NXDNGateway diff --git a/NXDNGateway/NXDNGateway.cpp b/NXDNGateway/NXDNGateway.cpp index ae8a008..8f4df31 100644 --- a/NXDNGateway/NXDNGateway.cpp +++ b/NXDNGateway/NXDNGateway.cpp @@ -603,12 +603,12 @@ void CNXDNGateway::createGPS() m_writer->setInfo(txFrequency, rxFrequency, desc); - bool enabled = m_conf.getMobileGPSEnabled(); + bool enabled = m_conf.getGPSDEnabled(); if (enabled) { - std::string address = m_conf.getMobileGPSAddress(); - unsigned int port = m_conf.getMobileGPSPort(); + std::string address = m_conf.getGPSDAddress(); + std::string port = m_conf.getGPSDPort(); - m_writer->setMobileLocation(address, port); + m_writer->setGPSDLocation(address, port); } else { float latitude = m_conf.getLatitude(); float longitude = m_conf.getLongitude(); diff --git a/NXDNGateway/NXDNGateway.ini b/NXDNGateway/NXDNGateway.ini index d0fba44..d0aba7b 100644 --- a/NXDNGateway/NXDNGateway.ini +++ b/NXDNGateway/NXDNGateway.ini @@ -62,10 +62,10 @@ Startup=10200 InactivityTimeout=10 Debug=0 -[Mobile GPS] +[GPSD] Enable=0 Address=127.0.0.1 -Port=7834 +Port=2947 [Remote Commands] Enable=0 diff --git a/NXDNGateway/Version.h b/NXDNGateway/Version.h index b8cc636..64b1742 100644 --- a/NXDNGateway/Version.h +++ b/NXDNGateway/Version.h @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -const char* VERSION = "20200601"; +const char* VERSION = "20200603"; #endif From 71b26b10d16feb9f6e92729eaf37d08a8a193caf Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Wed, 3 Jun 2020 12:42:07 +0100 Subject: [PATCH 06/27] Missed non-Linux timer start. --- NXDNGateway/APRSWriter.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NXDNGateway/APRSWriter.cpp b/NXDNGateway/APRSWriter.cpp index a301eba..9a16c5c 100644 --- a/NXDNGateway/APRSWriter.cpp +++ b/NXDNGateway/APRSWriter.cpp @@ -103,8 +103,9 @@ bool CAPRSWriter::open() } else { m_idTimer.setTimeout(20U * 60U); } +#else + m_idTimer.setTimeout(20U * 60U); #endif - m_idTimer.start(); return m_aprsSocket.open(); From 019835fed74a701d75ce0373a9ca4ce870403df4 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Wed, 3 Jun 2020 12:50:03 +0100 Subject: [PATCH 07/27] Add the missing gps_read. --- NXDNGateway/APRSWriter.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NXDNGateway/APRSWriter.cpp b/NXDNGateway/APRSWriter.cpp index 9a16c5c..43518d5 100644 --- a/NXDNGateway/APRSWriter.cpp +++ b/NXDNGateway/APRSWriter.cpp @@ -221,6 +221,9 @@ void CAPRSWriter::sendIdFrameMobile() if (!::gps_waiting(&m_gpsdData, 0)) return; + if (::gps_read(&m_gpsdData, NULL, 0) <= 0) + 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; From c416e55ceef1e0150fe086183b28b7fa690817b9 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Thu, 4 Jun 2020 08:54:12 +0100 Subject: [PATCH 08/27] Add more gpsd sanity checking. --- NXDNGateway/APRSWriter.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NXDNGateway/APRSWriter.cpp b/NXDNGateway/APRSWriter.cpp index 43518d5..b6c9dd0 100644 --- a/NXDNGateway/APRSWriter.cpp +++ b/NXDNGateway/APRSWriter.cpp @@ -224,6 +224,9 @@ void CAPRSWriter::sendIdFrameMobile() if (::gps_read(&m_gpsdData, NULL, 0) <= 0) return; + 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; From 332ca17f269499e6e15a7de842bbad6deb06cd42 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Thu, 4 Jun 2020 12:23:24 +0100 Subject: [PATCH 09/27] Fixed startup bug. --- NXDNGateway/APRSWriter.cpp | 12 ++++++++++-- NXDNGateway/Version.h | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/NXDNGateway/APRSWriter.cpp b/NXDNGateway/APRSWriter.cpp index b6c9dd0..4af0f7d 100644 --- a/NXDNGateway/APRSWriter.cpp +++ b/NXDNGateway/APRSWriter.cpp @@ -40,7 +40,7 @@ m_aprsSocket() #if !defined(_WIN32) && !defined(_WIN64) ,m_gpsdEnabled(false), m_gpsdAddress(), -m_gpsdPort(0U), +m_gpsdPort(), m_gpsdData() #endif { @@ -98,6 +98,8 @@ bool CAPRSWriter::open() ::gps_stream(&m_gpsdData, WATCH_ENABLE | WATCH_JSON, NULL); + LogMessage("Connected to GPSD"); + // Poll the GPS every minute m_idTimer.setTimeout(60U); } else { @@ -108,7 +110,13 @@ bool CAPRSWriter::open() #endif m_idTimer.start(); - return m_aprsSocket.open(); + bool ret = m_aprsSocket.open(); + if (!ret) + return false; + + LogMessage("Opened connection to the APRS Gateway"); + + return true; } void CAPRSWriter::write(const char* data) diff --git a/NXDNGateway/Version.h b/NXDNGateway/Version.h index 64b1742..a17701b 100644 --- a/NXDNGateway/Version.h +++ b/NXDNGateway/Version.h @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -const char* VERSION = "20200603"; +const char* VERSION = "20200604"; #endif From bd431e614958bd1b377aaa4e8843add3c008dd62 Mon Sep 17 00:00:00 2001 From: Jeffrey <2723529+JeffreyKopcak@users.noreply.github.com> Date: Thu, 4 Jun 2020 23:02:58 -0400 Subject: [PATCH 10/27] Added TG31983 - K8JTK Hub --- NXDNGateway/NXDNHosts.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NXDNGateway/NXDNHosts.txt b/NXDNGateway/NXDNHosts.txt index 887bbf1..cb16ad1 100644 --- a/NXDNGateway/NXDNHosts.txt +++ b/NXDNGateway/NXDNHosts.txt @@ -175,6 +175,9 @@ # DX-LINK SYSTEM, 31777 31777 8.9.4.102 41400 +# K8JTK Hub Multimode ILS/DVMIS (K8JTK.org), 31983 +31983 NXDNReflector31983.K8JTK.org 41400 + # CW-Ops Academy, NXDN Reflector 32103 32103 cwops.dyndns.org 41400 From c186d356952ad28bb964dcca5440ec9226a01b06 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Fri, 5 Jun 2020 09:24:42 +0100 Subject: [PATCH 11/27] Add debugging to the APRS section. --- NXDNGateway/APRSWriter.cpp | 16 +++++++++++----- NXDNGateway/APRSWriter.h | 4 ++-- NXDNGateway/Conf.cpp | 8 ++++---- NXDNGateway/Conf.h | 4 ++-- NXDNGateway/NXDNGateway.cpp | 7 ++++--- NXDNGateway/Version.h | 2 +- 6 files changed, 24 insertions(+), 17 deletions(-) diff --git a/NXDNGateway/APRSWriter.cpp b/NXDNGateway/APRSWriter.cpp index 4af0f7d..231b594 100644 --- a/NXDNGateway/APRSWriter.cpp +++ b/NXDNGateway/APRSWriter.cpp @@ -24,10 +24,10 @@ #include #include -CAPRSWriter::CAPRSWriter(const std::string& callsign, const std::string& suffix, const std::string& address, unsigned int port) : -m_enabled(false), +CAPRSWriter::CAPRSWriter(const std::string& callsign, const std::string& suffix, const std::string& address, unsigned int port, bool debug) : m_idTimer(1000U), m_callsign(callsign), +m_debug(debug), m_txFrequency(0U), m_rxFrequency(0U), m_latitude(0.0F), @@ -123,6 +123,9 @@ void CAPRSWriter::write(const char* data) { assert(data != NULL); + if (m_debug) + LogDebug("APRS ==> %s", data); + m_aprsSocket.write((unsigned char*)data, (unsigned int)::strlen(data), m_aprsAddress, m_aprsPort); } @@ -218,14 +221,14 @@ void CAPRSWriter::sendIdFrameFixed() lon, (m_longitude < 0.0F) ? 'W' : 'E', float(m_height) * 3.28F, band, desc); + if (m_debug) + LogDebug("APRS ==> %s", output); + write(output); } void CAPRSWriter::sendIdFrameMobile() { - if (!m_gpsdEnabled) - return; - if (!::gps_waiting(&m_gpsdData, 0)) return; @@ -308,6 +311,9 @@ void CAPRSWriter::sendIdFrameMobile() ::sprintf(output + ::strlen(output), "%s %s\r\n", band, desc); + if (m_debug) + LogDebug("APRS ==> %s", output); + write(output); } diff --git a/NXDNGateway/APRSWriter.h b/NXDNGateway/APRSWriter.h index 21f322f..461d945 100644 --- a/NXDNGateway/APRSWriter.h +++ b/NXDNGateway/APRSWriter.h @@ -40,7 +40,7 @@ class CAPRSWriter { public: - CAPRSWriter(const std::string& callsign, const std::string& suffix, const std::string& address, unsigned int port); + CAPRSWriter(const std::string& callsign, const std::string& suffix, const std::string& address, unsigned int port, bool debug); ~CAPRSWriter(); bool open(); @@ -58,9 +58,9 @@ public: void close(); private: - bool m_enabled; CTimer m_idTimer; std::string m_callsign; + bool m_debug; unsigned int m_txFrequency; unsigned int m_rxFrequency; float m_latitude; diff --git a/NXDNGateway/Conf.cpp b/NXDNGateway/Conf.cpp index d1969b0..df80dd1 100644 --- a/NXDNGateway/Conf.cpp +++ b/NXDNGateway/Conf.cpp @@ -47,7 +47,7 @@ m_rptProtocol("Icom"), m_rptAddress(), m_rptPort(0U), m_myPort(0U), -m_rptDebug(false), +m_debug(false), m_daemon(false), m_rxFrequency(0U), m_txFrequency(0U), @@ -157,7 +157,7 @@ bool CConf::read() else if (::strcmp(key, "LocalPort") == 0) m_myPort = (unsigned int)::atoi(value); else if (::strcmp(key, "Debug") == 0) - m_rptDebug = ::atoi(value) == 1; + m_debug = ::atoi(value) == 1; else if (::strcmp(key, "Daemon") == 0) m_daemon = ::atoi(value) == 1; } else if (section == SECTION_INFO) { @@ -278,9 +278,9 @@ unsigned int CConf::getMyPort() const return m_myPort; } -bool CConf::getRptDebug() const +bool CConf::getDebug() const { - return m_rptDebug; + return m_debug; } bool CConf::getDaemon() const diff --git a/NXDNGateway/Conf.h b/NXDNGateway/Conf.h index 32794cf..5700b40 100644 --- a/NXDNGateway/Conf.h +++ b/NXDNGateway/Conf.h @@ -37,7 +37,7 @@ public: std::string getRptAddress() const; unsigned int getRptPort() const; unsigned int getMyPort() const; - bool getRptDebug() const; + bool getDebug() const; bool getDaemon() const; // The Info section @@ -100,7 +100,7 @@ private: std::string m_rptAddress; unsigned int m_rptPort; unsigned int m_myPort; - bool m_rptDebug; + bool m_debug; bool m_daemon; unsigned int m_rxFrequency; diff --git a/NXDNGateway/NXDNGateway.cpp b/NXDNGateway/NXDNGateway.cpp index 8f4df31..5277b07 100644 --- a/NXDNGateway/NXDNGateway.cpp +++ b/NXDNGateway/NXDNGateway.cpp @@ -184,9 +184,9 @@ void CNXDNGateway::run() std::string protocol = m_conf.getRptProtocol(); if (protocol == "Kenwood") - localNetwork = new CKenwoodNetwork(m_conf.getMyPort(), m_conf.getRptAddress(), m_conf.getRptPort(), m_conf.getRptDebug()); + localNetwork = new CKenwoodNetwork(m_conf.getMyPort(), m_conf.getRptAddress(), m_conf.getRptPort(), m_conf.getDebug()); else - localNetwork = new CIcomNetwork(m_conf.getMyPort(), m_conf.getRptAddress(), m_conf.getRptPort(), m_conf.getRptDebug()); + localNetwork = new CIcomNetwork(m_conf.getMyPort(), m_conf.getRptAddress(), m_conf.getRptPort(), m_conf.getDebug()); ret = localNetwork->open(); if (!ret) { @@ -594,8 +594,9 @@ void CNXDNGateway::createGPS() 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(callsign, rptSuffix, address, port); + m_writer = new CAPRSWriter(callsign, rptSuffix, address, port, debug); unsigned int txFrequency = m_conf.getTxFrequency(); unsigned int rxFrequency = m_conf.getRxFrequency(); diff --git a/NXDNGateway/Version.h b/NXDNGateway/Version.h index a17701b..b2493a9 100644 --- a/NXDNGateway/Version.h +++ b/NXDNGateway/Version.h @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -const char* VERSION = "20200604"; +const char* VERSION = "20200605"; #endif From 0e4e612d35eb0aed576d4ead2870dfb06d944a3d Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Fri, 5 Jun 2020 11:16:52 +0100 Subject: [PATCH 12/27] Change timings for fixed location startup. --- NXDNGateway/APRSWriter.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/NXDNGateway/APRSWriter.cpp b/NXDNGateway/APRSWriter.cpp index 231b594..fc1fc2c 100644 --- a/NXDNGateway/APRSWriter.cpp +++ b/NXDNGateway/APRSWriter.cpp @@ -99,23 +99,17 @@ bool CAPRSWriter::open() ::gps_stream(&m_gpsdData, WATCH_ENABLE | WATCH_JSON, NULL); LogMessage("Connected to GPSD"); - - // Poll the GPS every minute - m_idTimer.setTimeout(60U); - } else { - m_idTimer.setTimeout(20U * 60U); } -#else - m_idTimer.setTimeout(20U * 60U); #endif - m_idTimer.start(); - 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; } @@ -144,6 +138,7 @@ void CAPRSWriter::clock(unsigned int ms) #endif if (m_idTimer.hasExpired()) { sendIdFrameFixed(); + m_idTimer.setTimeout(20U * 60U); m_idTimer.start(); } #if !defined(_WIN32) && !defined(_WIN64) From 156c5feb36c6d3f7a0803240f2c884fc724e3e22 Mon Sep 17 00:00:00 2001 From: ku-mi Date: Thu, 11 Jun 2020 21:40:32 +0200 Subject: [PATCH 13/27] Changed IP address of Polish NXDN Reflector TG 26200 (new VPS server) --- NXDNGateway/NXDNHosts.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NXDNGateway/NXDNHosts.txt b/NXDNGateway/NXDNHosts.txt index cb16ad1..de8a3f1 100644 --- a/NXDNGateway/NXDNHosts.txt +++ b/NXDNGateway/NXDNHosts.txt @@ -113,7 +113,7 @@ 25641 194.182.85.217 41400 # Poland, 26000 -26000 31.0.161.238 41400 +26000 80.211.249.221 41400 # Deutschland, 26200 26200 26200.ham-nxdn.de 41400 From 37d27130267e00b4249bf49e5cc60217d81c9108 Mon Sep 17 00:00:00 2001 From: ku-mi Date: Thu, 11 Jun 2020 21:40:32 +0200 Subject: [PATCH 14/27] Changed IP address of Polish NXDN Reflector TG 26000 (new VPS server) --- NXDNGateway/NXDNHosts.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NXDNGateway/NXDNHosts.txt b/NXDNGateway/NXDNHosts.txt index cb16ad1..de8a3f1 100644 --- a/NXDNGateway/NXDNHosts.txt +++ b/NXDNGateway/NXDNHosts.txt @@ -113,7 +113,7 @@ 25641 194.182.85.217 41400 # Poland, 26000 -26000 31.0.161.238 41400 +26000 80.211.249.221 41400 # Deutschland, 26200 26200 26200.ham-nxdn.de 41400 From ccc88bec61b53967008a39ebab6f80c5df99ca33 Mon Sep 17 00:00:00 2001 From: Roby Date: Sat, 13 Jun 2020 13:41:02 +0200 Subject: [PATCH 15/27] Update NXDNHosts.txt Change TG Destination --- NXDNGateway/NXDNHosts.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/NXDNGateway/NXDNHosts.txt b/NXDNGateway/NXDNHosts.txt index de8a3f1..186d650 100644 --- a/NXDNGateway/NXDNHosts.txt +++ b/NXDNGateway/NXDNHosts.txt @@ -95,8 +95,9 @@ # 22202 IT NXDN Sardegna 22202 nxdn.is0hha.hblink.it 41400 -# 22220 IT ECHOLINK ITALY -22220 dagobah.hblink.it 41400 +# 22221 HBLINK IT-DMR REGIONALE LOMBARDIA +22221 dagobah.hblink.it 41400 + # 22245 IT PIEDMONT GDO 22245 nxdngdo.duckdns.org 41400 From e41762c0a2529c234d68a4a257773ad248fc71bc Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Sun, 21 Jun 2020 17:43:31 +0100 Subject: [PATCH 16/27] Make the use of gpsd optional. --- NXDNGateway/APRSWriter.cpp | 15 ++++++++------- NXDNGateway/APRSWriter.h | 2 +- NXDNGateway/Makefile | 6 ++++++ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/NXDNGateway/APRSWriter.cpp b/NXDNGateway/APRSWriter.cpp index fc1fc2c..cb67049 100644 --- a/NXDNGateway/APRSWriter.cpp +++ b/NXDNGateway/APRSWriter.cpp @@ -37,7 +37,7 @@ m_desc(), m_aprsAddress(), m_aprsPort(port), m_aprsSocket() -#if !defined(_WIN32) && !defined(_WIN64) +#if defined(USE_GPSD) ,m_gpsdEnabled(false), m_gpsdAddress(), m_gpsdPort(), @@ -76,7 +76,7 @@ void CAPRSWriter::setStaticLocation(float latitude, float longitude, int height) void CAPRSWriter::setGPSDLocation(const std::string& address, const std::string& port) { -#if !defined(_WIN32) && !defined(_WIN64) +#if defined(USE_GPSD) assert(!address.empty()); assert(!port.empty()); @@ -88,7 +88,7 @@ void CAPRSWriter::setGPSDLocation(const std::string& address, const std::string& bool CAPRSWriter::open() { -#if !defined(_WIN32) && !defined(_WIN64) +#if defined(USE_GPSD) if (m_gpsdEnabled) { int ret = ::gps_open(m_gpsdAddress.c_str(), m_gpsdPort.c_str(), &m_gpsdData); if (ret != 0) { @@ -127,7 +127,7 @@ void CAPRSWriter::clock(unsigned int ms) { m_idTimer.clock(ms); -#if !defined(_WIN32) && !defined(_WIN64) +#if defined(USE_GPSD) if (m_gpsdEnabled) { if (m_idTimer.hasExpired()) { sendIdFrameMobile(); @@ -141,7 +141,7 @@ void CAPRSWriter::clock(unsigned int ms) m_idTimer.setTimeout(20U * 60U); m_idTimer.start(); } -#if !defined(_WIN32) && !defined(_WIN64) +#if defined(USE_GPSD) } #endif } @@ -150,7 +150,7 @@ void CAPRSWriter::close() { m_aprsSocket.close(); -#if !defined(_WIN32) && !defined(_WIN64) +#if defined(USE_GPSD) if (m_gpsdEnabled) { ::gps_stream(&m_gpsdData, WATCH_DISABLE, NULL); ::gps_close(&m_gpsdData); @@ -222,6 +222,7 @@ void CAPRSWriter::sendIdFrameFixed() write(output); } +#if defined(USE_GPSD) void CAPRSWriter::sendIdFrameMobile() { if (!::gps_waiting(&m_gpsdData, 0)) @@ -311,4 +312,4 @@ void CAPRSWriter::sendIdFrameMobile() write(output); } - +#endif diff --git a/NXDNGateway/APRSWriter.h b/NXDNGateway/APRSWriter.h index 461d945..df51adc 100644 --- a/NXDNGateway/APRSWriter.h +++ b/NXDNGateway/APRSWriter.h @@ -70,7 +70,7 @@ private: in_addr m_aprsAddress; unsigned int m_aprsPort; CUDPSocket m_aprsSocket; -#if !defined(_WIN32) && !defined(_WIN64) +#if defined(USE_GPSD) bool m_gpsdEnabled; std::string m_gpsdAddress; std::string m_gpsdPort; diff --git a/NXDNGateway/Makefile b/NXDNGateway/Makefile index d9bc000..24cba48 100644 --- a/NXDNGateway/Makefile +++ b/NXDNGateway/Makefile @@ -1,6 +1,12 @@ CC = gcc CXX = g++ + +# Use the following CFLAGS if you don't want to use gpsd. CFLAGS = -g -O3 -Wall -std=c++0x -pthread + +# Use the following CFLAGS if you do want to use gpsd. +CFLAGS = -g -O3 -Wall -DUSE_GPSD -std=c++0x -pthread + LIBS = -lpthread -lgps LDFLAGS = -g From 40d20e0920fe0511ca015df2f2ef61826b064e4a Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Sun, 21 Jun 2020 17:45:02 +0100 Subject: [PATCH 17/27] Fix the LIBS for gpsd. --- NXDNGateway/Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/NXDNGateway/Makefile b/NXDNGateway/Makefile index 24cba48..c3ff0fd 100644 --- a/NXDNGateway/Makefile +++ b/NXDNGateway/Makefile @@ -1,13 +1,14 @@ CC = gcc CXX = g++ -# Use the following CFLAGS if you don't want to use gpsd. +# Use the following CFLAGS and LIBS if you don't want to use gpsd. CFLAGS = -g -O3 -Wall -std=c++0x -pthread +LIBS = -lpthread -# Use the following CFLAGS if you do want to use gpsd. +# Use the following CFLAGS and LIBS if you do want to use gpsd. CFLAGS = -g -O3 -Wall -DUSE_GPSD -std=c++0x -pthread - LIBS = -lpthread -lgps + LDFLAGS = -g OBJECTS = APRSWriter.o Conf.o GPSHandler.o IcomNetwork.o KenwoodNetwork.o Log.o Mutex.o NXDNCRC.o NXDNGateway.o NXDNLookup.o NXDNNetwork.o \ From 003833b85fee023122ade772cecb316d5afc973b Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Sun, 21 Jun 2020 17:46:55 +0100 Subject: [PATCH 18/27] Bump the version date. --- NXDNGateway/Version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NXDNGateway/Version.h b/NXDNGateway/Version.h index b2493a9..6d4de6d 100644 --- a/NXDNGateway/Version.h +++ b/NXDNGateway/Version.h @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -const char* VERSION = "20200605"; +const char* VERSION = "20200621"; #endif From ff544141c63721c1ae4bcbd7c169cac4cdf3c2b1 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Sun, 21 Jun 2020 17:52:16 +0100 Subject: [PATCH 19/27] Test the makefile under Linux. --- NXDNGateway/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NXDNGateway/Makefile b/NXDNGateway/Makefile index c3ff0fd..08a1943 100644 --- a/NXDNGateway/Makefile +++ b/NXDNGateway/Makefile @@ -6,8 +6,8 @@ CFLAGS = -g -O3 -Wall -std=c++0x -pthread LIBS = -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 = -lpthread -lgps +#CFLAGS = -g -O3 -Wall -DUSE_GPSD -std=c++0x -pthread +#LIBS = -lpthread -lgps LDFLAGS = -g From bbf9b2002132214145a484b8dc1327f98ca1fcbc Mon Sep 17 00:00:00 2001 From: Daniel Caujolle-Bert Date: Wed, 24 Jun 2020 11:42:53 +0200 Subject: [PATCH 20/27] Take care if the gpsd API version with gps_read() as function prototype as changed in version 7. --- NXDNGateway/APRSWriter.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/NXDNGateway/APRSWriter.cpp b/NXDNGateway/APRSWriter.cpp index cb67049..df2e347 100644 --- a/NXDNGateway/APRSWriter.cpp +++ b/NXDNGateway/APRSWriter.cpp @@ -228,8 +228,13 @@ 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; From 905469207af693944fc5e24c68709fbe4999073c Mon Sep 17 00:00:00 2001 From: Daniel Caujolle-Bert Date: Wed, 24 Jun 2020 12:04:51 +0200 Subject: [PATCH 21/27] altMSL appeared in API 9. --- NXDNGateway/APRSWriter.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NXDNGateway/APRSWriter.cpp b/NXDNGateway/APRSWriter.cpp index df2e347..248364b 100644 --- a/NXDNGateway/APRSWriter.cpp +++ b/NXDNGateway/APRSWriter.cpp @@ -249,7 +249,11 @@ void CAPRSWriter::sendIdFrameMobile() 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); From bf419db46c585b3e4a4c87eed3a67105aa477371 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Thu, 25 Jun 2020 10:05:38 +0100 Subject: [PATCH 22/27] Add the install target. --- NXDNGateway/Makefile | 3 +++ NXDNParrot/Makefile | 3 +++ NXDNReflector/Makefile | 3 +++ 3 files changed, 9 insertions(+) diff --git a/NXDNGateway/Makefile b/NXDNGateway/Makefile index 08a1943..df938eb 100644 --- a/NXDNGateway/Makefile +++ b/NXDNGateway/Makefile @@ -22,6 +22,9 @@ NXDNGateway: $(OBJECTS) %.o: %.cpp $(CXX) $(CFLAGS) -c -o $@ $< +install: + install -m 755 NXDNGateway /usr/local/bin/ + clean: $(RM) NXDNGateway *.o *.d *.bak *~ diff --git a/NXDNParrot/Makefile b/NXDNParrot/Makefile index 9a4b426..4a03a5f 100644 --- a/NXDNParrot/Makefile +++ b/NXDNParrot/Makefile @@ -14,5 +14,8 @@ NXDNParrot: $(OBJECTS) %.o: %.cpp $(CXX) $(CFLAGS) -c -o $@ $< +install: + install -m 755 NXDNParrot /usr/local/bin/ + clean: $(RM) NXDNParrot *.o *.d *.bak *~ diff --git a/NXDNReflector/Makefile b/NXDNReflector/Makefile index 43c534b..21567be 100644 --- a/NXDNReflector/Makefile +++ b/NXDNReflector/Makefile @@ -14,6 +14,9 @@ NXDNReflector: $(OBJECTS) %.o: %.cpp $(CXX) $(CFLAGS) -c -o $@ $< +install: + install -m 755 NXDNReflector /usr/local/bin/ + clean: $(RM) NXDNReflector *.o *.d *.bak *~ \ No newline at end of file From 2ffe2ff10e353b652cdfc0694850be348632457c Mon Sep 17 00:00:00 2001 From: sardylan Date: Sun, 28 Jun 2020 13:03:43 +0200 Subject: [PATCH 23/27] Adds TG 2231 --- NXDNGateway/NXDNHosts.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NXDNGateway/NXDNHosts.txt b/NXDNGateway/NXDNHosts.txt index cb16ad1..8551b3a 100644 --- a/NXDNGateway/NXDNHosts.txt +++ b/NXDNGateway/NXDNHosts.txt @@ -44,6 +44,9 @@ # 2225 IT Tuscany 2225 80.211.99.134 41400 +# 2231 IT Multiprotocollo Sardegna +2231 nxdn.is0.org 41400 + # 2249 IT SICILIA 2249 nxdn.digitalsicilia.it 41400 From 6e0b6d20c150d8ef1171eb8883a8f925c67b764f Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Mon, 29 Jun 2020 17:23:18 +0100 Subject: [PATCH 24/27] Make use of gps.h optional. --- NXDNGateway/APRSWriter.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NXDNGateway/APRSWriter.h b/NXDNGateway/APRSWriter.h index df51adc..f29d9a5 100644 --- a/NXDNGateway/APRSWriter.h +++ b/NXDNGateway/APRSWriter.h @@ -33,7 +33,9 @@ #include #include #include +#if defined(USE_GPSD) #include +#endif #else #include #endif From f16a7be674bd7066d68fa58ac3a34622a3f96c24 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Tue, 30 Jun 2020 13:01:20 +0100 Subject: [PATCH 25/27] Add RayNet UK. --- NXDNGateway/NXDNHosts.txt | 114 ++++++++++++++++++++------------------ 1 file changed, 59 insertions(+), 55 deletions(-) diff --git a/NXDNGateway/NXDNHosts.txt b/NXDNGateway/NXDNHosts.txt index 45337ed..c8f3d54 100644 --- a/NXDNGateway/NXDNHosts.txt +++ b/NXDNGateway/NXDNHosts.txt @@ -2,31 +2,32 @@ # # The format of this file is the number of the Talk Group followed by the host name or address and port # -# HELLAS Zone TG202 + +# 202 HELLAS Zone 202 hellaszone.com 41400 -# RED NXDN SPAIN +# 214 RED SPAIN 214 nxdn214.xreflector.es 41400 -# HBLink Poland ,TG260 +# 260 HBLink Poland 260 nxdn.hblink.pl 41400 -# 302, P25 Canada +# 302 P25 Canada 302 p25canada.hopto.org 41400 -# Super Freq 420 +# 420 Super Freq 420 hb.superfreqdigital.com 41400 -# VKCore, 505 +# 505 VKCore 505 43.229.63.42 41450 -# New Zealand, 530 +# 530 New Zealand 530 zldigitalreflectors.hopto.org 41400 -# XLX545E PA NXDN +# XLX545E PA 545 70.44.20.24 41401 -# RuralMN Reflector 707 +# 707 RuralMN Reflector 707 707nxdn.kd0ioe.com 41400 # 911 Cop Talk, Multimode TG for Police and First Responders @@ -35,7 +36,10 @@ # 914 Latin America 914 164.132.96.157 41400 -# Florida, 1200 +# 1080 RayNet UK +1080 51.91.78.118 41400 + +# 1200 Florida 1200 florida.nxref.org 41400 # 2140 DMRplus BM Multi @@ -50,7 +54,7 @@ # 2249 IT SICILIA 2249 nxdn.digitalsicilia.it 41400 -# RU DMR TG2503 +# 2503 RU DMR 2503 nxdn.r1ik.ru 41400 # 3023 Ontario Crosslink @@ -59,31 +63,31 @@ # 3142 Pennsylvania 3142 3.215.215.169 41402 -# VK7 TAS, 5057 +# 5057 VK7 TAS 5057 45.248.50.37 41400 -# Multiprotocolo Argentina +# 7225 Multiprotocolo Argentina 7225 ysfarg.ddns.net 41400 -# North America, 10200 +# 10200 North America 10200 dvswitch.org 42400 -# HBLINK Espana, 10301 +# 10301 HBLINK Espana 10301 ea5gvk.duckdns.org 41400 -# NXDN 10302 Multimode BM 21461 EA Spain +# 10302 Multimode BM 21461 EA Spain 10302 93.186.254.219 41400 -# Italian speaking, 10303 +# 10303 Italian speaking 10303 185.203.118.8 41400 -# REM-ADER Spain Group, 10304 +# 10304 REM-ADER Spain Group 10304 176.31.161.9 41400 # Pacific, 10400 10400 pacific.nxref.org 41400 -# Europe, German speaking, 20000 +# 20000 Europe, German speaking 20000 89.185.97.38 41400 # 20945 Deutschland DL1BH @@ -107,113 +111,113 @@ # 22825 Swiss NXDN Reflerctor 22825 212.237.33.114 41400 -# NXDN Scotland, 23551 +# 23551 NXDN Scotland 23551 nxdnscotland.ddns.net 41400 -# NX Core, 25000 +# 25000 NX Core 25000 173.166.94.77 41400 -# Russia NXDN Net, 25641 +# 25641 Russia NXDN Net 25641 194.182.85.217 41400 -# Poland, 26000 +# 26000 Poland 26000 80.211.249.221 41400 -# Deutschland, 26200 +# 26200 Deutschland 26200 26200.ham-nxdn.de 41400 -# Portuguese speaking test, 10268 +# 26810 Portuguese speaking test 26810 84.90.7.110 41400 -# America-Ragchew, 28299 +# 28299 America-Ragchew 28299 65.101.7.52 41400 -# NorCal-Bridge / Multimode-NXDN, 30639 +# 30639 NorCal-Bridge / Multimode-NXDN 30639 wiresxdigi.dyndns.org 41400 -# Alabama-Link, 31010 +# 31010 Alabama-Link 31010 nxdn.alabamalink.info 41400 -# Colorado Fun Machine WE0FUN Bridge to C4FM, DMR, DStar, P25 and AllStarLink (Analog) http://www.we0fun.com +# 31081 Colorado Fun Machine WE0FUN Bridge to C4FM, DMR, DStar, P25 and AllStarLink (Analog) http://www.we0fun.com 31081 nxdn.we0fun.com 41400 -# Colorado HD, 31088 +# 31088 Colorado HD 31088 54.191.50.212 41400 -# Connecticut Chat, 31092 +# 31092 Connecticut Chat 31092 nxdn.alecwasserman.com 41400 -# Kingsland Digital Link +# 31137 Kingsland Digital Link 31137 74.91.119.94 41400 -# Illinois, 31171 +# 31171 Illinois 31171 74.208.235.115 41400 -# Southern Indiana, 31188 +# 31188 Southern Indiana 31188 w9windigital.org 41400 # 31264 XLX625 The BROniverse www.wa8bro.com 31264 nxdn.dudetronics.com 41400 -# Central New Jersey, 31340 +# 31340 Central New Jersey 31340 cnjham.msmts.com 41400 -# Oklahoma Link, 31403 +# 31403 Oklahoma Link 31403 3.208.70.29 41400 -# XLX545A Pennsylvania Cross Mode, 31425 +# 31425 XLX545A Pennsylvania Cross Mode 31425 70.44.20.24 41400 -# XLX545A Pennsylvania Cross Mode (alt), 31426 +# 31426 XLX545A Pennsylvania Cross Mode (alt) 31426 3.215.215.169 41400 -# Rhode Island Digital Link, 31444 +# 31444 Rhode Island Digital Link 31444 18.219.32.21 41400 -# TGIF Network, 31665 +# 31665 TGIF Network 31665 tgif.network 41400 -# Pi-Star NXDN Reflector, 31672 +# 31672 Pi-Star 31672 nxdn-31672.pistar.uk 41400 -# DX-LINK SYSTEM, 31777 +# 31777 DX-LINK SYSTEM, 31777 8.9.4.102 41400 -# K8JTK Hub Multimode ILS/DVMIS (K8JTK.org), 31983 +# 31983 K8JTK Hub Multimode ILS/DVMIS (K8JTK.org) 31983 NXDNReflector31983.K8JTK.org 41400 -# CW-Ops Academy, NXDN Reflector 32103 +# 32103 CW-Ops Academy 32103 cwops.dyndns.org 41400 -# OMISS Group, NXDN Reflector 33581 +# 33581 OMISS Group 33581 omiss.dyndns.org 41400 -# Fusion Canada Fr /Wires-x /Ysf /Nxdn Network +# 40721 Fusion Canada Fr /Wires-x /Ysf /Nxdn Network 40721 38.110.97.161 41400 -# China, 46000 +# 46000 China 46000 120.234.41.144 41400 -# DMR TG50525 bridge, 50525 +# 50525 DMR TG50525 bridge 50525 50525.nxref.org 41400 -# BM NXCore bridge, 50599 +# 50599 BM NXCore bridge 50599 nxdn.duckdns.org 41490 -# Thailand DTDXA XLX520N, 52000 +# 52000 Thailand DTDXA XLX520N 52000 nxdn.dtdxa.com 41400 -# New Zealand, 53099 linked to BM TG 53099 +# 53099 New Zealand, 53099 linked to BM TG 53099 53099 203.86.206.49 41400 -# World Wide, 65000 +# 65000 World Wide 65000 176.9.1.168 41400 -# French-Test, 65208 +# 65208 French-Test 65208 m55.evxonline.net 41400 -# NXDN - 2007DXGROUP +# 65100 NXDN - 2007DXGROUP 65100 89.46.75.115 41400 -# NXDN SPAIN 21410 +# 21410 NXDN SPAIN 21410 nxdn21410.nxdn.es 41400 From c41f9bb5fe581f0ba98363ce36fcef582763f75a Mon Sep 17 00:00:00 2001 From: M0GLJ <32222213+m0glj@users.noreply.github.com> Date: Tue, 30 Jun 2020 16:35:49 +0100 Subject: [PATCH 26/27] Modify TG to unify RayNet UK Talk Groups to same number Oppologies Jonathan G4KLX Regards Adrian M0GLJ --- NXDNGateway/NXDNHosts.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/NXDNGateway/NXDNHosts.txt b/NXDNGateway/NXDNHosts.txt index c8f3d54..32b2a19 100644 --- a/NXDNGateway/NXDNHosts.txt +++ b/NXDNGateway/NXDNHosts.txt @@ -36,9 +36,6 @@ # 914 Latin America 914 164.132.96.157 41400 -# 1080 RayNet UK -1080 51.91.78.118 41400 - # 1200 Florida 1200 florida.nxref.org 41400 @@ -111,6 +108,9 @@ # 22825 Swiss NXDN Reflerctor 22825 212.237.33.114 41400 +# 23531 RayNet UK +23531 51.91.78.118 41400 + # 23551 NXDN Scotland 23551 nxdnscotland.ddns.net 41400 From 822883f40f706cd19a92febb70f7f1a92479406d Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Wed, 1 Jul 2020 13:31:11 +0100 Subject: [PATCH 27/27] Use proper random numbers for the SSRC in the Kenwood network protocol. --- NXDNGateway/KenwoodNetwork.cpp | 10 ++++++++-- NXDNGateway/KenwoodNetwork.h | 2 ++ NXDNGateway/UDPSocket.cpp | 30 +----------------------------- NXDNGateway/UDPSocket.h | 4 +--- NXDNGateway/Version.h | 2 +- NXDNReflector/KenwoodNetwork.cpp | 10 ++++++++-- NXDNReflector/KenwoodNetwork.h | 2 ++ NXDNReflector/UDPSocket.cpp | 28 ---------------------------- NXDNReflector/UDPSocket.h | 4 +--- NXDNReflector/Version.h | 2 +- 10 files changed, 25 insertions(+), 69 deletions(-) diff --git a/NXDNGateway/KenwoodNetwork.cpp b/NXDNGateway/KenwoodNetwork.cpp index c5a4a20..28ab2e2 100644 --- a/NXDNGateway/KenwoodNetwork.cpp +++ b/NXDNGateway/KenwoodNetwork.cpp @@ -55,7 +55,8 @@ m_rtcpTimer(1000U, 0U, 200U), m_hangTimer(1000U, 5U), m_hangType(0U), m_hangSrc(0U), -m_hangDst(0U) +m_hangDst(0U), +m_random() { assert(localPort > 0U); assert(!rptAddress.empty()); @@ -64,6 +65,10 @@ m_hangDst(0U) m_sacch = new unsigned char[10U]; m_address = CUDPSocket::lookup(rptAddress); + + std::random_device rd; + std::mt19937 mt(rd()); + m_random = mt; } CKenwoodNetwork::~CKenwoodNetwork() @@ -86,7 +91,8 @@ bool CKenwoodNetwork::open() return false; } - m_ssrc = m_rtpSocket.getLocalAddress(); + std::uniform_int_distribution dist(0x00000001, 0xfffffffe); + m_ssrc = dist(m_random); return true; } diff --git a/NXDNGateway/KenwoodNetwork.h b/NXDNGateway/KenwoodNetwork.h index aa52d64..b0e1183 100644 --- a/NXDNGateway/KenwoodNetwork.h +++ b/NXDNGateway/KenwoodNetwork.h @@ -25,6 +25,7 @@ #include #include +#include class CKenwoodNetwork : public IRptNetwork { public: @@ -64,6 +65,7 @@ private: unsigned char m_hangType; unsigned short m_hangSrc; unsigned short m_hangDst; + std::mt19937 m_random; bool processIcomVoiceHeader(const unsigned char* data); bool processIcomVoiceData(const unsigned char* data); diff --git a/NXDNGateway/UDPSocket.cpp b/NXDNGateway/UDPSocket.cpp index c105b0b..3c1451b 100644 --- a/NXDNGateway/UDPSocket.cpp +++ b/NXDNGateway/UDPSocket.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2016,2020 by Jonathan Naylor G4KLX + * 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 @@ -261,31 +261,3 @@ void CUDPSocket::close() ::close(m_fd); #endif } - -unsigned long CUDPSocket::getLocalAddress() const -{ - unsigned long address = 0UL; - - char hostname[80U]; - int ret = ::gethostname(hostname, 80); - if (ret == -1) - return 0UL; - - struct hostent* phe = ::gethostbyname(hostname); - if (phe == NULL) - return 0UL; - - if (phe->h_addrtype != AF_INET) - return 0UL; - - for (unsigned int i = 0U; phe->h_addr_list[i] != NULL; i++) { - struct in_addr addr; - ::memcpy(&addr, phe->h_addr_list[i], sizeof(struct in_addr)); - if (addr.s_addr != INADDR_LOOPBACK) { - address = addr.s_addr; - break; - } - } - - return address; -} diff --git a/NXDNGateway/UDPSocket.h b/NXDNGateway/UDPSocket.h index ffc3b92..e0af272 100644 --- a/NXDNGateway/UDPSocket.h +++ b/NXDNGateway/UDPSocket.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2011,2013,2015,2016,2020 by Jonathan Naylor G4KLX + * 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 @@ -47,8 +47,6 @@ public: void close(); - unsigned long getLocalAddress() const; - static in_addr lookup(const std::string& hostName); private: diff --git a/NXDNGateway/Version.h b/NXDNGateway/Version.h index 6d4de6d..dc7a96b 100644 --- a/NXDNGateway/Version.h +++ b/NXDNGateway/Version.h @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -const char* VERSION = "20200621"; +const char* VERSION = "20200701"; #endif diff --git a/NXDNReflector/KenwoodNetwork.cpp b/NXDNReflector/KenwoodNetwork.cpp index 8a872c0..134ea55 100644 --- a/NXDNReflector/KenwoodNetwork.cpp +++ b/NXDNReflector/KenwoodNetwork.cpp @@ -56,13 +56,18 @@ m_rtcpTimer(1000U, 0U, 200U), m_hangTimer(1000U, 5U), m_hangType(0U), m_hangSrc(0U), -m_hangDst(0U) +m_hangDst(0U), +m_random() { assert(!address.empty()); m_sacch = new unsigned char[10U]; m_address = CUDPSocket::lookup(address); + + std::random_device rd; + std::mt19937 mt(rd()); + m_random = mt; } CKenwoodNetwork::~CKenwoodNetwork() @@ -85,7 +90,8 @@ bool CKenwoodNetwork::open() return false; } - m_ssrc = m_rtpSocket.getLocalAddress(); + std::uniform_int_distribution dist(0x00000001, 0xfffffffe); + m_ssrc = dist(m_random); return true; } diff --git a/NXDNReflector/KenwoodNetwork.h b/NXDNReflector/KenwoodNetwork.h index 0543efe..e597802 100644 --- a/NXDNReflector/KenwoodNetwork.h +++ b/NXDNReflector/KenwoodNetwork.h @@ -25,6 +25,7 @@ #include #include +#include class CKenwoodNetwork : public ICoreNetwork { public: @@ -62,6 +63,7 @@ private: unsigned char m_hangType; unsigned short m_hangSrc; unsigned short m_hangDst; + std::mt19937 m_random; bool processIcomVoiceHeader(const unsigned char* data); bool processIcomVoiceData(const unsigned char* data); diff --git a/NXDNReflector/UDPSocket.cpp b/NXDNReflector/UDPSocket.cpp index d651ab8..eaa2e2f 100644 --- a/NXDNReflector/UDPSocket.cpp +++ b/NXDNReflector/UDPSocket.cpp @@ -260,31 +260,3 @@ void CUDPSocket::close() ::close(m_fd); #endif } - -unsigned long CUDPSocket::getLocalAddress() const -{ - unsigned long address = 0UL; - - char hostname[80U]; - int ret = ::gethostname(hostname, 80); - if (ret == -1) - return 0UL; - - struct hostent* phe = ::gethostbyname(hostname); - if (phe == NULL) - return 0UL; - - if (phe->h_addrtype != AF_INET) - return 0UL; - - for (unsigned int i = 0U; phe->h_addr_list[i] != NULL; i++) { - struct in_addr addr; - ::memcpy(&addr, phe->h_addr_list[i], sizeof(struct in_addr)); - if (addr.s_addr != INADDR_LOOPBACK) { - address = addr.s_addr; - break; - } - } - - return address; -} diff --git a/NXDNReflector/UDPSocket.h b/NXDNReflector/UDPSocket.h index 4c21a43..3437b53 100644 --- a/NXDNReflector/UDPSocket.h +++ b/NXDNReflector/UDPSocket.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2011,2013,2015,2016,2020 by Jonathan Naylor G4KLX + * 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 @@ -47,8 +47,6 @@ public: void close(); - unsigned long getLocalAddress() const; - static in_addr lookup(const std::string& hostName); private: diff --git a/NXDNReflector/Version.h b/NXDNReflector/Version.h index 0a67dd6..2cda46b 100644 --- a/NXDNReflector/Version.h +++ b/NXDNReflector/Version.h @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -const char* VERSION = "20200427"; +const char* VERSION = "20200701"; #endif