Latest changes for Kenwood repeater support.

This commit is contained in:
Jonathan Naylor 2020-05-09 15:08:24 +01:00
parent d6e28630ff
commit bfa1118726
5 changed files with 105 additions and 20 deletions

View File

@ -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);
}

View File

@ -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);
};

View File

@ -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 <cerrno>
#include <cstring>
#include <ifaddrs.h>
#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;
}

View File

@ -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:

View File

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