mirror of
https://github.com/g4klx/MMDVMHost
synced 2025-12-21 06:55:52 +08:00
Remove the D-Star fast data handling for now as it appears to be
mangling D-Star DTMF data.
This commit is contained in:
22
AMBEFEC.cpp
22
AMBEFEC.cpp
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2010,2014,2016,2018,2021 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2010,2014,2016,2018,2021,2025 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2016 Mathias Weyland, HB9FRV
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -798,8 +798,6 @@ unsigned int CAMBEFEC::regenerateDStar(unsigned int& a, unsigned int& b) const
|
||||
|
||||
unsigned int data;
|
||||
bool valid1 = CGolay24128::decode24128(a, data);
|
||||
if (!valid1)
|
||||
return 10U;
|
||||
|
||||
// The PRNG
|
||||
unsigned int p = PRNG_TABLE[data];
|
||||
@@ -808,14 +806,15 @@ unsigned int CAMBEFEC::regenerateDStar(unsigned int& a, unsigned int& b) const
|
||||
|
||||
unsigned int datb;
|
||||
bool valid2 = CGolay24128::decode24128(b, datb);
|
||||
if (!valid2)
|
||||
return 10U;
|
||||
|
||||
a = CGolay24128::encode24128(data);
|
||||
b = CGolay24128::encode24128(datb);
|
||||
|
||||
b ^= p;
|
||||
|
||||
if (!valid1 || !valid2)
|
||||
return 10U;
|
||||
|
||||
unsigned int v = a ^ orig_a;
|
||||
unsigned int errsA = CUtils::countBits(v);
|
||||
|
||||
@@ -832,12 +831,6 @@ unsigned int CAMBEFEC::regenerateDMR(unsigned int& a, unsigned int& b, unsigned
|
||||
|
||||
unsigned int data;
|
||||
bool valid = CGolay24128::decode24128(a, data);
|
||||
if (!valid) {
|
||||
a = 0xF00292U;
|
||||
b = 0x0E0B20U;
|
||||
c = 0x000000U;
|
||||
return 10U; // An invalid A block gives an error count of 10
|
||||
}
|
||||
|
||||
a = CGolay24128::encode24128(data);
|
||||
|
||||
@@ -852,6 +845,13 @@ unsigned int CAMBEFEC::regenerateDMR(unsigned int& a, unsigned int& b, unsigned
|
||||
|
||||
b ^= p;
|
||||
|
||||
if (!valid) {
|
||||
a = 0xF00292U;
|
||||
b = 0x0E0B20U;
|
||||
c = 0x000000U;
|
||||
return 10U; // An invalid A block gives an error count of 10
|
||||
}
|
||||
|
||||
unsigned int v = a ^ orig_a;
|
||||
unsigned int errsA = CUtils::countBits(v);
|
||||
|
||||
|
||||
197
DStarControl.cpp
197
DStarControl.cpp
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2019,2021,2023 Jonathan Naylor, G4KLX
|
||||
* Copyright (C) 2015-2019,2021,2023,2025 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,7 +24,6 @@
|
||||
#include <functional>
|
||||
|
||||
const unsigned int MAX_SYNC_BIT_ERRORS = 2U;
|
||||
const unsigned int FAST_DATA_BEEP_GRACE_FRAMES = 6U;
|
||||
|
||||
bool CallsignCompare(const std::string& arg, const unsigned char* my)
|
||||
{
|
||||
@@ -86,15 +85,7 @@ m_minRSSI(0U),
|
||||
m_aveRSSI(0U),
|
||||
m_rssiCount(0U),
|
||||
m_enabled(true),
|
||||
m_fp(NULL),
|
||||
m_rfVoiceSyncData(NULL),
|
||||
m_rfVoiceSyncDataLen(0U),
|
||||
m_netVoiceSyncData(NULL),
|
||||
m_netVoiceSyncDataLen(0U),
|
||||
m_rfNextFrameIsFastData(false),
|
||||
m_netNextFrameIsFastData(false),
|
||||
m_rfSkipDTMFBlankingFrames(0U),
|
||||
m_netSkipDTMFBlankingFrames(0U)
|
||||
m_fp(NULL)
|
||||
{
|
||||
assert(display != NULL);
|
||||
assert(rssiMapper != NULL);
|
||||
@@ -103,8 +94,6 @@ m_netSkipDTMFBlankingFrames(0U)
|
||||
m_gateway = new unsigned char[DSTAR_LONG_CALLSIGN_LENGTH];
|
||||
|
||||
m_lastFrame = new unsigned char[DSTAR_FRAME_LENGTH_BYTES + 1U];
|
||||
m_rfVoiceSyncData = new unsigned char[DSTAR_MODEM_DATA_LEN];
|
||||
m_netVoiceSyncData = new unsigned char[DSTAR_MODEM_DATA_LEN];
|
||||
|
||||
std::string call = callsign;
|
||||
call.resize(DSTAR_LONG_CALLSIGN_LENGTH - 1U, ' ');
|
||||
@@ -129,84 +118,6 @@ CDStarControl::~CDStarControl()
|
||||
delete[] m_callsign;
|
||||
delete[] m_gateway;
|
||||
delete[] m_lastFrame;
|
||||
delete[] m_rfVoiceSyncData;
|
||||
delete[] m_netVoiceSyncData;
|
||||
}
|
||||
|
||||
unsigned int CDStarControl::maybeFixupVoiceFrame(
|
||||
unsigned char* data,
|
||||
unsigned int len,
|
||||
unsigned int offset,
|
||||
const char* log_prefix,
|
||||
unsigned char n,
|
||||
bool blank_dtmf,
|
||||
unsigned char* voice_sync_data,
|
||||
unsigned int& voice_sync_data_len,
|
||||
bool& next_frame_is_fast_data,
|
||||
unsigned int& skip_dtmf_blanking_frames
|
||||
)
|
||||
{
|
||||
unsigned int errors = 0U;
|
||||
unsigned int voice_sync_errors = 0U;
|
||||
unsigned char mini_header = data[offset + 9U] ^ DSTAR_SCRAMBLER_BYTES[0U];
|
||||
unsigned char mini_header_type = mini_header & DSTAR_SLOW_DATA_TYPE_MASK;
|
||||
|
||||
if (n == 0U) {
|
||||
::memcpy(voice_sync_data, data, DSTAR_MODEM_DATA_LEN);
|
||||
voice_sync_data_len = len;
|
||||
} else if ((n % 2U != 0U) &&
|
||||
((mini_header_type == DSTAR_SLOW_DATA_TYPE_FASTDATA01) ||
|
||||
(mini_header_type == DSTAR_SLOW_DATA_TYPE_FASTDATA16))) {
|
||||
next_frame_is_fast_data = true;
|
||||
if (blank_dtmf)
|
||||
skip_dtmf_blanking_frames = FAST_DATA_BEEP_GRACE_FRAMES;
|
||||
if (n == 1U)
|
||||
LogDebug("D-Star, %s fastdata sequence no. 0", log_prefix);
|
||||
LogDebug("D-Star, %s fastdata sequence no. %2u", log_prefix, n);
|
||||
} else if (next_frame_is_fast_data) {
|
||||
next_frame_is_fast_data = false;
|
||||
if (blank_dtmf)
|
||||
skip_dtmf_blanking_frames = FAST_DATA_BEEP_GRACE_FRAMES;
|
||||
LogDebug("D-Star, %s fastdata sequence no. %2u", log_prefix, n);
|
||||
} else {
|
||||
bool voice_sync_data_is_null_ambe_data = false;
|
||||
bool data_is_null_ambe_data = false;
|
||||
|
||||
if ((n == 1U) && (::memcmp(voice_sync_data + offset, DSTAR_NULL_AMBE_DATA_BYTES_SCRAMBLED, DSTAR_VOICE_FRAME_LENGTH_BYTES) == 0))
|
||||
voice_sync_data_is_null_ambe_data = true;
|
||||
|
||||
if (::memcmp(data + offset, DSTAR_NULL_AMBE_DATA_BYTES_SCRAMBLED, DSTAR_VOICE_FRAME_LENGTH_BYTES) == 0)
|
||||
data_is_null_ambe_data = true;
|
||||
|
||||
if ((n == 1U) && !voice_sync_data_is_null_ambe_data)
|
||||
voice_sync_errors += m_fec.regenerateDStar(voice_sync_data + offset);
|
||||
|
||||
if (!data_is_null_ambe_data)
|
||||
errors += m_fec.regenerateDStar(data + offset);
|
||||
|
||||
if (blank_dtmf && skip_dtmf_blanking_frames > 0U) {
|
||||
skip_dtmf_blanking_frames--;
|
||||
} else if (blank_dtmf && skip_dtmf_blanking_frames == 0U) {
|
||||
if ((n == 1U) && !voice_sync_data_is_null_ambe_data)
|
||||
blankDTMF(voice_sync_data + offset);
|
||||
if (!data_is_null_ambe_data)
|
||||
blankDTMF(data + offset);
|
||||
}
|
||||
|
||||
if (n == 1U) {
|
||||
if (voice_sync_data_is_null_ambe_data)
|
||||
LogDebug("D-Star, %s nullaudio sequence no. 0", log_prefix);
|
||||
else
|
||||
LogDebug("D-Star, %s audio sequence no. 0, errs: %2u/48 (%5.1f%%)", log_prefix, voice_sync_errors, float(voice_sync_errors) / 0.48F);
|
||||
}
|
||||
|
||||
if (data_is_null_ambe_data)
|
||||
LogDebug("D-Star, %s nullaudio sequence no. %2u", log_prefix, n);
|
||||
else
|
||||
LogDebug("D-Star, %s audio sequence no. %2u, errs: %2u/48 (%5.1f%%)", log_prefix, n, errors, float(errors) / 0.48F);
|
||||
}
|
||||
|
||||
return voice_sync_errors + errors;
|
||||
}
|
||||
|
||||
bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
||||
@@ -416,9 +327,6 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
||||
if (m_duplex)
|
||||
writeQueueEOTRF();
|
||||
|
||||
m_rfNextFrameIsFastData = false;
|
||||
m_rfSkipDTMFBlankingFrames = 0U;
|
||||
|
||||
unsigned char my1[DSTAR_LONG_CALLSIGN_LENGTH];
|
||||
unsigned char my2[DSTAR_SHORT_CALLSIGN_LENGTH];
|
||||
unsigned char your[DSTAR_LONG_CALLSIGN_LENGTH];
|
||||
@@ -436,11 +344,13 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
||||
|
||||
return false;
|
||||
} else if (type == TAG_DATA) {
|
||||
if (m_rfState == RS_RF_REJECTED) {
|
||||
if (m_rfState == RS_RF_REJECTED)
|
||||
return true;
|
||||
} else if (m_rfState == RS_RF_INVALID) {
|
||||
|
||||
if (m_rfState == RS_RF_INVALID)
|
||||
return true;
|
||||
} else if (m_rfState == RS_RF_LISTENING) {
|
||||
|
||||
if (m_rfState == RS_RF_LISTENING) {
|
||||
// The sync is regenerated by the modem so can do exact match
|
||||
if (::memcmp(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES, DSTAR_SYNC_BYTES, DSTAR_DATA_FRAME_LENGTH_BYTES) == 0) {
|
||||
m_rfSlowData.start();
|
||||
@@ -448,7 +358,9 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
||||
}
|
||||
|
||||
return false;
|
||||
} else if (m_rfState == RS_RF_AUDIO) {
|
||||
}
|
||||
|
||||
if (m_rfState == RS_RF_AUDIO) {
|
||||
// The sync is regenerated by the modem so can do exact match
|
||||
if (::memcmp(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES, DSTAR_SYNC_BYTES, DSTAR_DATA_FRAME_LENGTH_BYTES) == 0) {
|
||||
m_rfSlowData.start();
|
||||
@@ -463,7 +375,7 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
||||
|
||||
unsigned int errors = 0U;
|
||||
if (!m_rfHeader.isDataPacket()) {
|
||||
errors = maybeFixupVoiceFrame(data, len, 1U, "RF", m_rfN, m_duplex, m_rfVoiceSyncData, m_rfVoiceSyncDataLen, m_rfNextFrameIsFastData, m_rfSkipDTMFBlankingFrames);
|
||||
errors = m_fec.regenerateDStar(data + 1U);
|
||||
m_display->writeDStarBER(float(errors) / 0.48F);
|
||||
m_rfErrs += errors;
|
||||
}
|
||||
@@ -471,21 +383,17 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
||||
m_rfBits += 48U;
|
||||
m_rfFrames++;
|
||||
|
||||
if (m_rfN != 0U) {
|
||||
const unsigned char* text = m_rfSlowData.addText(data + 1U);
|
||||
if (text != NULL)
|
||||
LogMessage("D-Star, slow data text = \"%s\"", text);
|
||||
|
||||
if (m_net) {
|
||||
if (m_rfN == 1U)
|
||||
writeNetworkDataRF(m_rfVoiceSyncData, 0U, false);
|
||||
if (m_rfN >= 1U)
|
||||
writeNetworkDataRF(data, errors, false);
|
||||
LogMessage("D-Star, RF slow data text = \"%s\"", text);
|
||||
}
|
||||
|
||||
if (m_net)
|
||||
writeNetworkDataRF(data, errors, false);
|
||||
|
||||
if (m_duplex) {
|
||||
if (m_rfN == 1U)
|
||||
writeQueueDataRF(m_rfVoiceSyncData);
|
||||
if (m_rfN >= 1U)
|
||||
blankDTMF(data + 1U);
|
||||
writeQueueDataRF(data);
|
||||
}
|
||||
|
||||
@@ -495,58 +403,55 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
||||
if (::memcmp(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES, DSTAR_SYNC_BYTES, DSTAR_DATA_FRAME_LENGTH_BYTES) == 0) {
|
||||
m_rfSlowData.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
CDStarHeader* header = m_rfSlowData.addHeader(data + 1U);
|
||||
if (header == NULL)
|
||||
return false;
|
||||
|
||||
m_rfHeader = *header;
|
||||
delete header;
|
||||
}
|
||||
|
||||
unsigned char my1[DSTAR_LONG_CALLSIGN_LENGTH];
|
||||
header->getMyCall1(my1);
|
||||
m_rfHeader.getMyCall1(my1);
|
||||
|
||||
// Is this a transmission destined for a repeater?
|
||||
if (!header->isRepeater()) {
|
||||
if (!m_rfHeader.isRepeater()) {
|
||||
LogMessage("D-Star, non repeater RF header received from %8.8s", my1);
|
||||
m_rfState = RS_RF_INVALID;
|
||||
delete header;
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned char callsign[DSTAR_LONG_CALLSIGN_LENGTH];
|
||||
header->getRPTCall1(callsign);
|
||||
m_rfHeader.getRPTCall1(callsign);
|
||||
|
||||
// Is it for us?
|
||||
if (::memcmp(callsign, m_callsign, DSTAR_LONG_CALLSIGN_LENGTH) != 0) {
|
||||
LogMessage("D-Star, received RF header for wrong repeater (%8.8s) from %8.8s", callsign, my1);
|
||||
m_rfState = RS_RF_INVALID;
|
||||
delete header;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_selfOnly && ::memcmp(my1, m_callsign, DSTAR_LONG_CALLSIGN_LENGTH - 1U) != 0 && !(std::find_if(m_whiteList.begin(), m_whiteList.end(), std::bind(CallsignCompare, std::placeholders::_1, my1)) != m_whiteList.end())) {
|
||||
LogMessage("D-Star, invalid access attempt from %8.8s", my1);
|
||||
m_rfState = RS_RF_REJECTED;
|
||||
delete header;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!m_selfOnly && std::find_if(m_blackList.begin(), m_blackList.end(), std::bind(CallsignCompare, std::placeholders::_1, my1)) != m_blackList.end()) {
|
||||
LogMessage("D-Star, invalid access attempt from %8.8s", my1);
|
||||
m_rfState = RS_RF_REJECTED;
|
||||
delete header;
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned char gateway[DSTAR_LONG_CALLSIGN_LENGTH];
|
||||
header->getRPTCall2(gateway);
|
||||
m_rfHeader.getRPTCall2(gateway);
|
||||
|
||||
unsigned char my2[DSTAR_SHORT_CALLSIGN_LENGTH];
|
||||
header->getMyCall2(my2);
|
||||
m_rfHeader.getMyCall2(my2);
|
||||
|
||||
unsigned char your[DSTAR_LONG_CALLSIGN_LENGTH];
|
||||
header->getYourCall(your);
|
||||
m_rfHeader.getYourCall(your);
|
||||
|
||||
m_net = ::memcmp(gateway, m_gateway, DSTAR_LONG_CALLSIGN_LENGTH) == 0;
|
||||
|
||||
@@ -574,10 +479,11 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
||||
start[0U] = TAG_HEADER;
|
||||
|
||||
// Modify the header
|
||||
header->setRepeater(false);
|
||||
header->setRPTCall1(m_callsign);
|
||||
header->setRPTCall2(m_callsign);
|
||||
header->get(start + 1U);
|
||||
CDStarHeader header(m_rfHeader);
|
||||
header.setRepeater(false);
|
||||
header.setRPTCall1(m_callsign);
|
||||
header.setRPTCall2(m_callsign);
|
||||
header.get(start + 1U);
|
||||
|
||||
writeQueueHeaderRF(start);
|
||||
}
|
||||
@@ -587,19 +493,19 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
||||
start[0U] = TAG_HEADER;
|
||||
|
||||
// Modify the header
|
||||
header->setRepeater(false);
|
||||
header->setRPTCall1(m_callsign);
|
||||
header->setRPTCall2(m_gateway);
|
||||
header->get(start + 1U);
|
||||
CDStarHeader header(m_rfHeader);
|
||||
header.setRepeater(false);
|
||||
header.setRPTCall1(m_callsign);
|
||||
header.setRPTCall2(m_gateway);
|
||||
header.get(start + 1U);
|
||||
|
||||
writeNetworkHeaderRF(start);
|
||||
}
|
||||
|
||||
delete header;
|
||||
|
||||
unsigned int errors = 0U;
|
||||
if (!m_rfHeader.isDataPacket()) {
|
||||
errors = maybeFixupVoiceFrame(data, len, 1U, "RF", m_rfN, m_duplex, m_rfVoiceSyncData, m_rfVoiceSyncDataLen, m_rfNextFrameIsFastData, m_rfSkipDTMFBlankingFrames);
|
||||
errors = m_fec.regenerateDStar(data + 1U);
|
||||
LogDebug("D-Star, audio sequence no. %u, errs: %u/48 (%.1f%%)", m_rfN, errors, float(errors) / 0.48F);
|
||||
m_rfErrs += errors;
|
||||
}
|
||||
|
||||
@@ -608,8 +514,10 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
||||
if (m_net)
|
||||
writeNetworkDataRF(data, errors, false);
|
||||
|
||||
if (m_duplex)
|
||||
if (m_duplex) {
|
||||
blankDTMF(data + 1U);
|
||||
writeQueueDataRF(data);
|
||||
}
|
||||
|
||||
m_rfState = RS_RF_AUDIO;
|
||||
|
||||
@@ -774,9 +682,6 @@ void CDStarControl::writeNetwork()
|
||||
writeFile(data + 1U, length - 1U);
|
||||
closeFile();
|
||||
#endif
|
||||
m_netNextFrameIsFastData = false;
|
||||
m_netSkipDTMFBlankingFrames = 0U;
|
||||
|
||||
unsigned char my1[DSTAR_LONG_CALLSIGN_LENGTH];
|
||||
unsigned char my2[DSTAR_SHORT_CALLSIGN_LENGTH];
|
||||
unsigned char your[DSTAR_LONG_CALLSIGN_LENGTH];
|
||||
@@ -793,13 +698,15 @@ void CDStarControl::writeNetwork()
|
||||
if (m_netState != RS_NET_AUDIO)
|
||||
return;
|
||||
|
||||
unsigned int errors = 0U;
|
||||
unsigned char n = data[1U];
|
||||
|
||||
data[1U] = TAG_DATA;
|
||||
|
||||
unsigned int errors = 0U;
|
||||
if (!m_netHeader.isDataPacket())
|
||||
errors = maybeFixupVoiceFrame(data, length, 2U, "Net", n, true, m_netVoiceSyncData, m_netVoiceSyncDataLen, m_netNextFrameIsFastData, m_netSkipDTMFBlankingFrames);
|
||||
errors = m_fec.regenerateDStar(data + 2U);
|
||||
|
||||
blankDTMF(data + 2U);
|
||||
|
||||
data[1U] = TAG_DATA;
|
||||
|
||||
// Insert silence and reject if in the past
|
||||
bool ret = insertSilence(data + 1U, n);
|
||||
@@ -817,22 +724,18 @@ void CDStarControl::writeNetwork()
|
||||
m_netSlowData.start();
|
||||
}
|
||||
|
||||
if (n != 0U) {
|
||||
const unsigned char* text = m_netSlowData.addText(data + 2U);
|
||||
if (text != NULL)
|
||||
LogMessage("D-Star, slow data text = \"%s\"", text);
|
||||
LogMessage("D-Star, network slow data text = \"%s\"", text);
|
||||
}
|
||||
|
||||
m_packetTimer.start();
|
||||
m_netFrames++;
|
||||
|
||||
#if defined(DUMP_DSTAR)
|
||||
if (n == 1U)
|
||||
writeFile(m_netVoiceSyncData + 1U, m_netVoiceSyncDataLen - 1U);
|
||||
if (n >= 1U)
|
||||
writeFile(data + 1U, length - 1U);
|
||||
#endif
|
||||
if (n == 1U)
|
||||
writeQueueDataNet(m_netVoiceSyncData + 1U);
|
||||
if (n >= 1U)
|
||||
writeQueueDataNet(data + 1U);
|
||||
} else {
|
||||
CUtils::dump("D-Star, unknown data from network", data, DSTAR_FRAME_LENGTH_BYTES + 1U);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2019 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015-2019,2025 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
|
||||
@@ -99,27 +99,6 @@ private:
|
||||
unsigned int m_rssiCount;
|
||||
bool m_enabled;
|
||||
FILE* m_fp;
|
||||
unsigned char* m_rfVoiceSyncData;
|
||||
unsigned int m_rfVoiceSyncDataLen;
|
||||
unsigned char* m_netVoiceSyncData;
|
||||
unsigned int m_netVoiceSyncDataLen;
|
||||
bool m_rfNextFrameIsFastData;
|
||||
bool m_netNextFrameIsFastData;
|
||||
unsigned int m_rfSkipDTMFBlankingFrames;
|
||||
unsigned int m_netSkipDTMFBlankingFrames;
|
||||
|
||||
unsigned int maybeFixupVoiceFrame(
|
||||
unsigned char* data,
|
||||
unsigned int len,
|
||||
unsigned int offset,
|
||||
const char* log_prefix,
|
||||
unsigned char n,
|
||||
bool blank_dtmf,
|
||||
unsigned char* voice_sync_data,
|
||||
unsigned int& voice_sync_data_len,
|
||||
bool& next_frame_is_fast_data,
|
||||
unsigned int& skip_dtmf_blanking_frames
|
||||
);
|
||||
|
||||
void writeNetwork();
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2024 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015-2025 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,6 +19,6 @@
|
||||
#if !defined(VERSION_H)
|
||||
#define VERSION_H
|
||||
|
||||
const char* VERSION = "20240930";
|
||||
const char* VERSION = "20250227";
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user