mirror of
https://github.com/ShaYmez/NXDNClients.git
synced 2025-02-03 09:44:25 -05:00
Latest changes for Kenwood repeater support.
This commit is contained in:
parent
d6e28630ff
commit
bfa1118726
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -19,6 +19,6 @@
|
||||
#if !defined(VERSION_H)
|
||||
#define VERSION_H
|
||||
|
||||
const char* VERSION = "20200505";
|
||||
const char* VERSION = "20200509";
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user