mirror of
https://github.com/g4klx/MMDVMHost
synced 2025-12-23 08:45:48 +08:00
Avoid DMR buffer overflows, hopefully.
This commit is contained in:
106
DMRSlot.cpp
106
DMRSlot.cpp
@@ -77,8 +77,8 @@ m_rfFrames(0U),
|
|||||||
m_netFrames(0U),
|
m_netFrames(0U),
|
||||||
m_netLost(0U),
|
m_netLost(0U),
|
||||||
m_fec(),
|
m_fec(),
|
||||||
m_rfBits(0U),
|
m_rfBits(1U),
|
||||||
m_netBits(0U),
|
m_netBits(1U),
|
||||||
m_rfErrs(0U),
|
m_rfErrs(0U),
|
||||||
m_netErrs(0U),
|
m_netErrs(0U),
|
||||||
m_lastFrame(NULL),
|
m_lastFrame(NULL),
|
||||||
@@ -100,7 +100,6 @@ void CDMRSlot::writeModem(unsigned char *data)
|
|||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
if (data[0U] == TAG_LOST && m_rfState == RS_RF_AUDIO) {
|
if (data[0U] == TAG_LOST && m_rfState == RS_RF_AUDIO) {
|
||||||
if (m_rfBits == 0U) m_rfBits = 1U;
|
|
||||||
LogMessage("DMR Slot %u, RF transmission lost, %.1f seconds, BER: %.1f%%", m_slotNo, float(m_rfFrames) / 16.667F, float(m_rfErrs * 100U) / float(m_rfBits));
|
LogMessage("DMR Slot %u, RF transmission lost, %.1f seconds, BER: %.1f%%", m_slotNo, float(m_rfFrames) / 16.667F, float(m_rfErrs * 100U) / float(m_rfBits));
|
||||||
writeEndRF(true);
|
writeEndRF(true);
|
||||||
return;
|
return;
|
||||||
@@ -137,8 +136,7 @@ void CDMRSlot::writeModem(unsigned char *data)
|
|||||||
|
|
||||||
unsigned int id = lc->getSrcId();
|
unsigned int id = lc->getSrcId();
|
||||||
unsigned int did = lc->getDstId();
|
unsigned int did = lc->getDstId();
|
||||||
|
if (!DMRAccessControl::validateAccess(id, did, m_slotNo, false)) {
|
||||||
if (!DMRAccessControl::validateAccess(id,did,m_slotNo,false)) {
|
|
||||||
delete lc;
|
delete lc;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -237,7 +235,6 @@ void CDMRSlot::writeModem(unsigned char *data)
|
|||||||
writeQueueRF(data);
|
writeQueueRF(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_rfBits == 0U) m_rfBits = 1U;
|
|
||||||
LogMessage("DMR Slot %u, received RF end of voice transmission, %.1f seconds, BER: %.1f%%", m_slotNo, float(m_rfFrames) / 16.667F, float(m_rfErrs * 100U) / float(m_rfBits));
|
LogMessage("DMR Slot %u, received RF end of voice transmission, %.1f seconds, BER: %.1f%%", m_slotNo, float(m_rfFrames) / 16.667F, float(m_rfErrs * 100U) / float(m_rfBits));
|
||||||
|
|
||||||
writeEndRF();
|
writeEndRF();
|
||||||
@@ -253,11 +250,8 @@ void CDMRSlot::writeModem(unsigned char *data)
|
|||||||
bool gi = dataHeader.getGI();
|
bool gi = dataHeader.getGI();
|
||||||
unsigned int srcId = dataHeader.getSrcId();
|
unsigned int srcId = dataHeader.getSrcId();
|
||||||
unsigned int dstId = dataHeader.getDstId();
|
unsigned int dstId = dataHeader.getDstId();
|
||||||
|
if (!DMRAccessControl::validateAccess(srcId, dstId, m_slotNo, false))
|
||||||
|
|
||||||
if (!DMRAccessControl::validateAccess(srcId,dstId,m_slotNo,false)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
m_rfFrames = dataHeader.getBlocks();
|
m_rfFrames = dataHeader.getBlocks();
|
||||||
|
|
||||||
@@ -311,10 +305,8 @@ void CDMRSlot::writeModem(unsigned char *data)
|
|||||||
bool gi = csbk.getGI();
|
bool gi = csbk.getGI();
|
||||||
unsigned int srcId = csbk.getSrcId();
|
unsigned int srcId = csbk.getSrcId();
|
||||||
unsigned int dstId = csbk.getDstId();
|
unsigned int dstId = csbk.getDstId();
|
||||||
|
if (!DMRAccessControl::validateAccess(srcId, dstId, m_slotNo, false))
|
||||||
if (!DMRAccessControl::validateAccess(srcId,dstId,m_slotNo,false)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// Regenerate the CSBK data
|
// Regenerate the CSBK data
|
||||||
csbk.get(data + 2U);
|
csbk.get(data + 2U);
|
||||||
@@ -464,10 +456,8 @@ void CDMRSlot::writeModem(unsigned char *data)
|
|||||||
|
|
||||||
CDMRLC* lc = m_rfEmbeddedLC.addData(data + 2U, emb.getLCSS());
|
CDMRLC* lc = m_rfEmbeddedLC.addData(data + 2U, emb.getLCSS());
|
||||||
if (lc != NULL) {
|
if (lc != NULL) {
|
||||||
|
|
||||||
unsigned int id = lc->getSrcId();
|
unsigned int id = lc->getSrcId();
|
||||||
unsigned int did = lc->getDstId();
|
unsigned int did = lc->getDstId();
|
||||||
|
|
||||||
if (!DMRAccessControl::validateAccess(id,did,m_slotNo,false)) {
|
if (!DMRAccessControl::validateAccess(id,did,m_slotNo,false)) {
|
||||||
delete lc;
|
delete lc;
|
||||||
return;
|
return;
|
||||||
@@ -613,7 +603,7 @@ void CDMRSlot::writeEndRF(bool writeEnd)
|
|||||||
|
|
||||||
m_rfFrames = 0U;
|
m_rfFrames = 0U;
|
||||||
m_rfErrs = 0U;
|
m_rfErrs = 0U;
|
||||||
m_rfBits = 0U;
|
m_rfBits = 1U;
|
||||||
|
|
||||||
if (writeEnd) {
|
if (writeEnd) {
|
||||||
if (m_netState == RS_NET_IDLE && m_duplex) {
|
if (m_netState == RS_NET_IDLE && m_duplex) {
|
||||||
@@ -685,7 +675,7 @@ void CDMRSlot::writeEndNet(bool writeEnd)
|
|||||||
m_netLost = 0U;
|
m_netLost = 0U;
|
||||||
|
|
||||||
m_netErrs = 0U;
|
m_netErrs = 0U;
|
||||||
m_netBits = 0U;
|
m_netBits = 1U;
|
||||||
|
|
||||||
if (writeEnd) {
|
if (writeEnd) {
|
||||||
// Create a dummy start end frame
|
// Create a dummy start end frame
|
||||||
@@ -721,7 +711,6 @@ void CDMRSlot::writeEndNet(bool writeEnd)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//add
|
|
||||||
void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
{
|
{
|
||||||
if (m_rfState != RS_RF_LISTENING && m_netState == RS_NET_IDLE)
|
if (m_rfState != RS_RF_LISTENING && m_netState == RS_NET_IDLE)
|
||||||
@@ -747,10 +736,8 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||||||
|
|
||||||
unsigned int did = m_netLC->getDstId();
|
unsigned int did = m_netLC->getDstId();
|
||||||
unsigned int id = m_netLC->getSrcId();
|
unsigned int id = m_netLC->getSrcId();
|
||||||
|
if (!DMRAccessControl::validateAccess(id, did, m_slotNo, true))
|
||||||
if (!DMRAccessControl::validateAccess(id,did,m_slotNo,true)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// Store the LC for the embedded LC
|
// Store the LC for the embedded LC
|
||||||
m_netEmbeddedLC.setData(*m_netLC);
|
m_netEmbeddedLC.setData(*m_netLC);
|
||||||
@@ -772,12 +759,18 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||||||
|
|
||||||
m_netTimeoutTimer.start();
|
m_netTimeoutTimer.start();
|
||||||
|
|
||||||
|
m_packetTimer.start();
|
||||||
|
m_elapsed.start();
|
||||||
|
|
||||||
m_netFrames = 0U;
|
m_netFrames = 0U;
|
||||||
m_netLost = 0U;
|
m_netLost = 0U;
|
||||||
|
|
||||||
m_netBits = 1U;
|
m_netBits = 1U;
|
||||||
m_netErrs = 0U;
|
m_netErrs = 0U;
|
||||||
|
|
||||||
|
m_netN = dmrData.getN();
|
||||||
|
m_netSeqNo = dmrData.getSeqNo();
|
||||||
|
|
||||||
if (m_duplex) {
|
if (m_duplex) {
|
||||||
m_queue.clear();
|
m_queue.clear();
|
||||||
m_modem->writeDMRAbort(m_slotNo);
|
m_modem->writeDMRAbort(m_slotNo);
|
||||||
@@ -810,13 +803,10 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||||||
if (m_netState != RS_NET_AUDIO)
|
if (m_netState != RS_NET_AUDIO)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
unsigned int did = m_netLC->getDstId();
|
unsigned int did = m_netLC->getDstId();
|
||||||
unsigned int id = m_netLC->getSrcId();
|
unsigned int id = m_netLC->getSrcId();
|
||||||
|
if (!DMRAccessControl::validateAccess(id, did, m_slotNo, true))
|
||||||
if (!DMRAccessControl::validateAccess(id,did,m_slotNo,true)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// Regenerate the Slot Type
|
// Regenerate the Slot Type
|
||||||
CDMRSlotType slotType;
|
CDMRSlotType slotType;
|
||||||
@@ -847,10 +837,8 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||||||
|
|
||||||
unsigned int did = m_netLC->getDstId();
|
unsigned int did = m_netLC->getDstId();
|
||||||
unsigned int id = m_netLC->getSrcId();
|
unsigned int id = m_netLC->getSrcId();
|
||||||
|
if (!DMRAccessControl::validateAccess(id, did, m_slotNo, true))
|
||||||
if (!DMRAccessControl::validateAccess(id,did,m_slotNo,true)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// Regenerate the LC data
|
// Regenerate the LC data
|
||||||
CDMRFullLC fullLC;
|
CDMRFullLC fullLC;
|
||||||
@@ -882,7 +870,6 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||||||
#endif
|
#endif
|
||||||
// We've received the voice header and terminator haven't we?
|
// We've received the voice header and terminator haven't we?
|
||||||
m_netFrames += 2U;
|
m_netFrames += 2U;
|
||||||
if (m_netBits == 0U) m_netBits = 1U;
|
|
||||||
LogMessage("DMR Slot %u, received network end of voice transmission, %.1f seconds, %u%% packet loss, BER: %.1f%%", m_slotNo, float(m_netFrames) / 16.667F, (m_netLost * 100U) / m_netFrames, float(m_netErrs * 100U) / float(m_netBits));
|
LogMessage("DMR Slot %u, received network end of voice transmission, %.1f seconds, %u%% packet loss, BER: %.1f%%", m_slotNo, float(m_netFrames) / 16.667F, (m_netLost * 100U) / m_netFrames, float(m_netErrs * 100U) / float(m_netBits));
|
||||||
|
|
||||||
writeEndNet();
|
writeEndNet();
|
||||||
@@ -902,10 +889,8 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||||||
bool gi = dataHeader.getGI();
|
bool gi = dataHeader.getGI();
|
||||||
unsigned int srcId = dataHeader.getSrcId();
|
unsigned int srcId = dataHeader.getSrcId();
|
||||||
unsigned int dstId = dataHeader.getDstId();
|
unsigned int dstId = dataHeader.getDstId();
|
||||||
|
if (!DMRAccessControl::validateAccess(srcId, dstId, m_slotNo, true))
|
||||||
if (!DMRAccessControl::validateAccess(srcId,dstId,m_slotNo,true)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
m_netFrames = dataHeader.getBlocks();
|
m_netFrames = dataHeader.getBlocks();
|
||||||
|
|
||||||
@@ -949,13 +934,14 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||||||
|
|
||||||
unsigned int did = dmrData.getDstId();
|
unsigned int did = dmrData.getDstId();
|
||||||
unsigned int id = dmrData.getSrcId();
|
unsigned int id = dmrData.getSrcId();
|
||||||
|
if (!DMRAccessControl::validateAccess(id, did, m_slotNo, true))
|
||||||
if (!DMRAccessControl::validateAccess(id,did,m_slotNo,true)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
m_netTimeoutTimer.start();
|
m_netTimeoutTimer.start();
|
||||||
|
|
||||||
|
m_packetTimer.start();
|
||||||
|
m_elapsed.start();
|
||||||
|
|
||||||
if (m_duplex) {
|
if (m_duplex) {
|
||||||
m_queue.clear();
|
m_queue.clear();
|
||||||
m_modem->writeDMRAbort(m_slotNo);
|
m_modem->writeDMRAbort(m_slotNo);
|
||||||
@@ -1015,20 +1001,13 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||||||
data[0U] = TAG_DATA;
|
data[0U] = TAG_DATA;
|
||||||
data[1U] = 0x00U;
|
data[1U] = 0x00U;
|
||||||
|
|
||||||
// Initialise the lost packet data
|
|
||||||
if (m_netFrames == 0U) {
|
|
||||||
::memcpy(m_lastFrame, data, DMR_FRAME_LENGTH_BYTES + 2U);
|
|
||||||
m_netSeqNo = dmrData.getSeqNo();
|
|
||||||
m_netN = dmrData.getN();
|
|
||||||
m_elapsed.start();
|
|
||||||
m_netLost = 0U;
|
|
||||||
} else {
|
|
||||||
insertSilence(data, dmrData.getSeqNo());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert the Audio Sync to be from the BS
|
// Convert the Audio Sync to be from the BS
|
||||||
CSync::addDMRAudioSync(data + 2U);
|
CSync::addDMRAudioSync(data + 2U);
|
||||||
|
|
||||||
|
bool ret = insertSilence(data, dmrData.getSeqNo());
|
||||||
|
if (!ret)
|
||||||
|
return;
|
||||||
|
|
||||||
writeQueueNet(data);
|
writeQueueNet(data);
|
||||||
|
|
||||||
m_packetTimer.start();
|
m_packetTimer.start();
|
||||||
@@ -1049,10 +1028,8 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||||||
|
|
||||||
unsigned int did = m_netLC->getDstId();
|
unsigned int did = m_netLC->getDstId();
|
||||||
unsigned int id = m_netLC->getSrcId();
|
unsigned int id = m_netLC->getSrcId();
|
||||||
|
if (!DMRAccessControl::validateAccess(id, did, m_slotNo, true))
|
||||||
if (!DMRAccessControl::validateAccess(id,did,m_slotNo,true)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char fid = m_netLC->getFID();
|
unsigned char fid = m_netLC->getFID();
|
||||||
if (fid == FID_ETSI || fid == FID_DMRA)
|
if (fid == FID_ETSI || fid == FID_DMRA)
|
||||||
@@ -1071,16 +1048,9 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||||||
data[0U] = TAG_DATA;
|
data[0U] = TAG_DATA;
|
||||||
data[1U] = 0x00U;
|
data[1U] = 0x00U;
|
||||||
|
|
||||||
// Initialise the lost packet data
|
bool ret = insertSilence(data, dmrData.getSeqNo());
|
||||||
if (m_netFrames == 0U) {
|
if (!ret)
|
||||||
::memcpy(m_lastFrame, data, DMR_FRAME_LENGTH_BYTES + 2U);
|
return;
|
||||||
m_netSeqNo = dmrData.getSeqNo();
|
|
||||||
m_netN = dmrData.getN();
|
|
||||||
m_elapsed.start();
|
|
||||||
m_netLost = 0U;
|
|
||||||
} else {
|
|
||||||
insertSilence(data, dmrData.getSeqNo());
|
|
||||||
}
|
|
||||||
|
|
||||||
writeQueueNet(data);
|
writeQueueNet(data);
|
||||||
|
|
||||||
@@ -1110,11 +1080,8 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||||||
bool gi = csbk.getGI();
|
bool gi = csbk.getGI();
|
||||||
unsigned int srcId = csbk.getSrcId();
|
unsigned int srcId = csbk.getSrcId();
|
||||||
unsigned int dstId = csbk.getDstId();
|
unsigned int dstId = csbk.getDstId();
|
||||||
|
if (!DMRAccessControl::validateAccess(srcId,dstId,m_slotNo,true))
|
||||||
|
|
||||||
if (!DMRAccessControl::validateAccess(srcId,dstId,m_slotNo,true)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// Regenerate the CSBK data
|
// Regenerate the CSBK data
|
||||||
csbk.get(data + 2U);
|
csbk.get(data + 2U);
|
||||||
@@ -1219,7 +1186,6 @@ void CDMRSlot::clock()
|
|||||||
if (m_netState == RS_NET_AUDIO) {
|
if (m_netState == RS_NET_AUDIO) {
|
||||||
// We've received the voice header haven't we?
|
// We've received the voice header haven't we?
|
||||||
m_netFrames += 1U;
|
m_netFrames += 1U;
|
||||||
if (m_netBits == 0U) m_netBits = 1U;
|
|
||||||
LogMessage("DMR Slot %u, network watchdog has expired, %.1f seconds, %u%% packet loss, BER: %.1f%%", m_slotNo, float(m_netFrames) / 16.667F, (m_netLost * 100U) / m_netFrames, float(m_netErrs * 100U) / float(m_netBits));
|
LogMessage("DMR Slot %u, network watchdog has expired, %.1f seconds, %u%% packet loss, BER: %.1f%%", m_slotNo, float(m_netFrames) / 16.667F, (m_netLost * 100U) / m_netFrames, float(m_netErrs * 100U) / float(m_netBits));
|
||||||
writeEndNet(true);
|
writeEndNet(true);
|
||||||
#if defined(DUMP_DMR)
|
#if defined(DUMP_DMR)
|
||||||
@@ -1497,7 +1463,7 @@ void CDMRSlot::closeFile()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDMRSlot::insertSilence(const unsigned char* data, unsigned char seqNo)
|
bool CDMRSlot::insertSilence(const unsigned char* data, unsigned char seqNo)
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
@@ -1506,7 +1472,7 @@ void CDMRSlot::insertSilence(const unsigned char* data, unsigned char seqNo)
|
|||||||
if (seq == seqNo) {
|
if (seq == seqNo) {
|
||||||
// Just copy the data, nothing else to do here
|
// Just copy the data, nothing else to do here
|
||||||
::memcpy(m_lastFrame, data, DMR_FRAME_LENGTH_BYTES + 2U);
|
::memcpy(m_lastFrame, data, DMR_FRAME_LENGTH_BYTES + 2U);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int oldSeqNo = m_netSeqNo + 1U;
|
unsigned int oldSeqNo = m_netSeqNo + 1U;
|
||||||
@@ -1518,10 +1484,14 @@ void CDMRSlot::insertSilence(const unsigned char* data, unsigned char seqNo)
|
|||||||
else
|
else
|
||||||
count = (256U + newSeqNo) - oldSeqNo;
|
count = (256U + newSeqNo) - oldSeqNo;
|
||||||
|
|
||||||
if (count < 10U)
|
if (count >= 10U)
|
||||||
insertSilence(count);
|
return false;
|
||||||
|
|
||||||
|
insertSilence(count);
|
||||||
|
|
||||||
::memcpy(m_lastFrame, data, DMR_FRAME_LENGTH_BYTES + 2U);
|
::memcpy(m_lastFrame, data, DMR_FRAME_LENGTH_BYTES + 2U);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDMRSlot::insertSilence(unsigned int count)
|
void CDMRSlot::insertSilence(unsigned int count)
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ private:
|
|||||||
bool writeFile(const unsigned char* data);
|
bool writeFile(const unsigned char* data);
|
||||||
void closeFile();
|
void closeFile();
|
||||||
|
|
||||||
void insertSilence(const unsigned char* data, unsigned char seqNo);
|
bool insertSilence(const unsigned char* data, unsigned char seqNo);
|
||||||
void insertSilence(unsigned int count);
|
void insertSilence(unsigned int count);
|
||||||
|
|
||||||
static void setShortLC(unsigned int slotNo, unsigned int id, FLCO flco = FLCO_GROUP, bool voice = true);
|
static void setShortLC(unsigned int slotNo, unsigned int id, FLCO flco = FLCO_GROUP, bool voice = true);
|
||||||
|
|||||||
Reference in New Issue
Block a user