From bfa111872668b38d19e867e3c50cb3ccd9dd89db Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Sat, 9 May 2020 15:08:24 +0100 Subject: [PATCH] Latest changes for Kenwood repeater support. --- NXDNGateway/KenwoodNetwork.cpp | 81 +++++++++++++++++++++++++++------- NXDNGateway/KenwoodNetwork.h | 7 ++- NXDNGateway/UDPSocket.cpp | 31 ++++++++++++- NXDNGateway/UDPSocket.h | 4 +- NXDNGateway/Version.h | 2 +- 5 files changed, 105 insertions(+), 20 deletions(-) diff --git a/NXDNGateway/KenwoodNetwork.cpp b/NXDNGateway/KenwoodNetwork.cpp index d0c31fc..40822c3 100644 --- a/NXDNGateway/KenwoodNetwork.cpp +++ b/NXDNGateway/KenwoodNetwork.cpp @@ -45,17 +45,19 @@ m_seqNo(0U), m_timeStamp(0U), m_ssrc(0U), m_debug(debug), -m_timer(1000U, 0U, 200U), m_startSecs(0U), -m_startMSecs(0U) +m_startMSecs(0U), +m_rtcpTimer(1000U, 0U, 200U), +m_hangTimer(1000U, 5U), +m_hangType(0U), +m_hangSrc(0U), +m_hangDst(0U) { assert(localPort > 0U); assert(!rptAddress.empty()); assert(rptPort > 0U); m_address = CUDPSocket::lookup(rptAddress); - - ::srand((unsigned int)m_stopWatch.time()); } CKenwoodNetwork::~CKenwoodNetwork() @@ -77,7 +79,7 @@ bool CKenwoodNetwork::open() return false; } - m_ssrc = ::rand(); + m_ssrc = m_rtpSocket.getLocalAddress(); return true; } @@ -127,11 +129,12 @@ bool CKenwoodNetwork::processIcomVoiceHeader(const unsigned char* inData) switch (inData[5U] & 0x3FU) { case 0x01U: - m_timer.start(); + m_hangTimer.stop(); + m_rtcpTimer.start(); writeRTCPStart(); return writeRTPVoiceHeader(outData); case 0x08U: - m_timer.stop(); + m_hangTimer.start(); writeRTCPHang(type, src, dst); return writeRTPVoiceTrailer(outData); default: @@ -152,6 +155,10 @@ bool CKenwoodNetwork::processIcomVoiceData(const unsigned char* inData) outData[2U] = inData[4U] & 0xC0U; outData[3U] = inData[3U]; + CUtils::dump(4U, "Icom Audio 1 + 2 + 3 + 4", inData + 5U, 28U); + + CUtils::dump(4U, "Icom Audio 1 + 2", inData + 5U, 14U); + // Audio 1 ::memset(temp, 0x00U, 10U); for (unsigned int i = 0U; i < 49U; i++) { @@ -168,6 +175,8 @@ bool CKenwoodNetwork::processIcomVoiceData(const unsigned char* inData) outData[10U] = temp[7U]; outData[11U] = temp[6U]; + CUtils::dump(4U, "Kenwood unswapped Audio 1", temp, 8U); + // Audio 2 ::memset(temp, 0x00U, 10U); for (unsigned int i = 0U; i < 49U; i++) { @@ -184,6 +193,10 @@ bool CKenwoodNetwork::processIcomVoiceData(const unsigned char* inData) outData[18U] = temp[7U]; outData[19U] = temp[6U]; + CUtils::dump(4U, "Kenwood unswapped Audio 2", temp, 8U); + + CUtils::dump(4U, "Icom Audio 3 + 4", inData + 19U, 14U); + // Audio 3 ::memset(temp, 0x00U, 10U); for (unsigned int i = 0U; i < 49U; i++) { @@ -200,6 +213,8 @@ bool CKenwoodNetwork::processIcomVoiceData(const unsigned char* inData) outData[26U] = temp[7U]; outData[27U] = temp[6U]; + CUtils::dump(4U, "Kenwood unswapped Audio 3", temp, 8U); + // Audio 4 ::memset(temp, 0x00U, 10U); for (unsigned int i = 0U; i < 49U; i++) { @@ -216,6 +231,8 @@ bool CKenwoodNetwork::processIcomVoiceData(const unsigned char* inData) outData[34U] = temp[7U]; outData[35U] = temp[6U]; + CUtils::dump(4U, "Kenwood unswapped Audio 4", temp, 8U); + return writeRTPVoiceData(outData); } @@ -461,6 +478,15 @@ bool CKenwoodNetwork::writeRTCPPing() } 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); @@ -480,13 +506,13 @@ bool CKenwoodNetwork::writeRTCPHang(unsigned char type, unsigned short src, unsi buffer[10U] = 'N'; buffer[11U] = 'E'; - buffer[12U] = (src >> 8) & 0xFFU; - buffer[13U] = (src >> 0) & 0xFFU; + buffer[12U] = (m_hangSrc >> 8) & 0xFFU; + buffer[13U] = (m_hangSrc >> 0) & 0xFFU; - buffer[14U] = (dst >> 8) & 0xFFU; - buffer[15U] = (dst >> 0) & 0xFFU; + buffer[14U] = (m_hangDst >> 8) & 0xFFU; + buffer[15U] = (m_hangDst >> 0) & 0xFFU; - buffer[16U] = type; + buffer[16U] = m_hangType; buffer[17U] = 0x00U; buffer[18U] = 0x00U; @@ -590,10 +616,19 @@ 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(); } } @@ -675,6 +710,8 @@ void CKenwoodNetwork::processKenwoodVoiceData(unsigned char* inData) temp[6U] = inData[22U]; temp[7U] = inData[21U]; + CUtils::dump(4U, "Kenwood unswapped Audio 1", temp, 8U); + for (unsigned int i = 0U; i < 49U; i++, n++) { bool b = READ_BIT(temp, i); WRITE_BIT(outData, n, b); @@ -689,11 +726,15 @@ void CKenwoodNetwork::processKenwoodVoiceData(unsigned char* inData) temp[6U] = inData[30U]; temp[7U] = inData[29U]; + CUtils::dump(4U, "Kenwood unswapped Audio 2", temp, 8U); + for (unsigned int i = 0U; i < 49U; i++, n++) { bool b = READ_BIT(temp, i); WRITE_BIT(outData, n, b); } + CUtils::dump(4U, "Icom Audio 1 + 2", outData + 5U, 14U); + // AMBE 3+4 n = 19U * 8U; @@ -706,6 +747,8 @@ void CKenwoodNetwork::processKenwoodVoiceData(unsigned char* inData) temp[6U] = inData[38U]; temp[7U] = inData[37U]; + CUtils::dump(4U, "Kenwood unswapped Audio 3", temp, 8U); + for (unsigned int i = 0U; i < 49U; i++, n++) { bool b = READ_BIT(temp, i); WRITE_BIT(outData, n, b); @@ -720,11 +763,17 @@ void CKenwoodNetwork::processKenwoodVoiceData(unsigned char* inData) temp[6U] = inData[46U]; temp[7U] = inData[45U]; + CUtils::dump(4U, "Kenwood unswapped Audio 4", temp, 8U); + for (unsigned int i = 0U; i < 49U; i++, n++) { bool b = READ_BIT(temp, i); WRITE_BIT(outData, n, b); } + CUtils::dump(4U, "Icom Audio 3 + 4", outData + 19U, 14U); + + CUtils::dump(4U, "Icom Audio 1 + 2 + 3 + 4", outData + 5U, 28U); + ::memcpy(inData, outData, 33U); } diff --git a/NXDNGateway/KenwoodNetwork.h b/NXDNGateway/KenwoodNetwork.h index b30f5de..bf59c2f 100644 --- a/NXDNGateway/KenwoodNetwork.h +++ b/NXDNGateway/KenwoodNetwork.h @@ -54,9 +54,13 @@ private: unsigned long m_timeStamp; unsigned int m_ssrc; bool m_debug; - CTimer m_timer; uint32_t m_startSecs; uint32_t m_startMSecs; + 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); @@ -69,6 +73,7 @@ private: bool writeRTCPStart(); bool writeRTCPPing(); 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); }; diff --git a/NXDNGateway/UDPSocket.cpp b/NXDNGateway/UDPSocket.cpp index 396f1f7..c105b0b 100644 --- a/NXDNGateway/UDPSocket.cpp +++ b/NXDNGateway/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 @@ -24,6 +24,7 @@ #if !defined(_WIN32) && !defined(_WIN64) #include #include +#include #endif @@ -260,3 +261,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/NXDNGateway/UDPSocket.h b/NXDNGateway/UDPSocket.h index e0af272..ffc3b92 100644 --- a/NXDNGateway/UDPSocket.h +++ b/NXDNGateway/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,6 +47,8 @@ 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 bc8508c..4344528 100644 --- a/NXDNGateway/Version.h +++ b/NXDNGateway/Version.h @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -const char* VERSION = "20200505"; +const char* VERSION = "20200509"; #endif