implement a fixed internal TG hangtimer for network traffic, this will put a hold on the last received TG for 2 seconds; refactor how P25 handles simultaneous calls from the network and how RF preemption of in-progress network calls when RF wants to transmit on a different TG works;

pull/39/head
Bryan Biedenkapp 3 years ago
parent 1128d28d97
commit bed079f68e

@ -140,6 +140,7 @@ Slot::Slot(uint32_t slotNo, uint32_t timeout, uint32_t tgHang, uint32_t queueSiz
m_rfTimeoutTimer(1000U, timeout),
m_rfTGHang(1000U, tgHang),
m_netTimeoutTimer(1000U, timeout),
m_netTGHang(1000U, 2U),
m_packetTimer(1000U, 0U, 50U),
m_ccPacketInterval(1000U, 0U, DMR_SLOT_TIME),
m_interval(),
@ -363,6 +364,17 @@ void Slot::processNetwork(const data::Data& dmrData)
}
}
// don't process network frames if the destination ID's don't match and the network TG hang timer is running
if (m_netLastDstId != 0U && dmrData.getDstId() != 0U && m_netState != RS_NET_IDLE) {
if (m_netLastDstId != dmrData.getDstId() && (m_netTGHang.isRunning() && !m_netTGHang.hasExpired())) {
return;
}
if (m_netLastDstId == dmrData.getDstId() && (m_netTGHang.isRunning() && !m_netTGHang.hasExpired())) {
m_netTGHang.start();
}
}
m_networkWatchdog.start();
uint8_t dataType = dmrData.getDataType();
@ -514,6 +526,19 @@ void Slot::clock()
}
}
if (m_netTGHang.isRunning()) {
m_netTGHang.clock(ms);
if (m_netTGHang.hasExpired()) {
m_netTGHang.stop();
if (m_verbose) {
LogMessage(LOG_NET, "Slot %u, talkgroup hang has expired, lastDstId = %u", m_slotNo, m_netLastDstId);
}
m_netLastDstId = 0U;
m_netLastSrcId = 0U;
}
}
if (m_netState == RS_NET_AUDIO || m_netState == RS_NET_DATA) {
m_networkWatchdog.clock(ms);

@ -173,6 +173,7 @@ namespace dmr
Timer m_rfTimeoutTimer;
Timer m_rfTGHang;
Timer m_netTimeoutTimer;
Timer m_netTGHang;
Timer m_packetTimer;
Timer m_ccPacketInterval;

@ -70,12 +70,20 @@ using namespace dmr::packet;
return false; \
}
#define CHECK_TG_HANG(_DST_ID) \
// Don't process network frames if the destination ID's don't match and the network TG hang
// timer is running, and don't process network frames if the RF modem isn't in a listening state
#define CHECK_NET_TRAFFIC_COLLISION(_DST_ID) \
if (m_slot->m_rfLastDstId != 0U) { \
if (m_slot->m_rfLastDstId != _DST_ID && (m_slot->m_rfTGHang.isRunning() && !m_slot->m_rfTGHang.hasExpired())) { \
return; \
} \
}
} \
\
if (m_slot->m_netLastDstId != 0U) { \
if (m_slot->m_netLastDstId != _DST_ID && (m_slot->m_netTGHang.isRunning() && !m_slot->m_netTGHang.hasExpired())) { \
return; \
} \
} \
// ---------------------------------------------------------------------------
// Public Class Members
@ -291,6 +299,7 @@ bool Voice::process(uint8_t* data, uint32_t len)
m_slot->m_rfFrames++;
m_slot->m_rfTGHang.start();
m_slot->m_netTGHang.stop();
m_slot->m_rfLastDstId = m_slot->m_rfLC->getDstId();
m_slot->m_rfLastSrcId = m_slot->m_rfLC->getSrcId();
@ -359,6 +368,7 @@ bool Voice::process(uint8_t* data, uint32_t len)
m_slot->m_rfFrames++;
m_slot->m_rfTGHang.start();
m_slot->m_netTGHang.stop();
m_slot->m_rfLastDstId = m_slot->m_rfLC->getDstId();
m_slot->m_rfLastSrcId = m_slot->m_rfLC->getSrcId();
@ -615,6 +625,7 @@ bool Voice::process(uint8_t* data, uint32_t len)
m_slot->m_rfState = RS_RF_AUDIO;
m_slot->m_rfTGHang.start();
m_slot->m_netTGHang.stop();
m_slot->m_rfLastDstId = dstId;
m_slot->m_rfLastSrcId = srcId;
@ -658,7 +669,7 @@ void Voice::processNetwork(const data::Data& dmrData)
uint8_t flco = lc->getFLCO();
CHECK_NET_AUTHORITATIVE(dstId);
CHECK_TG_HANG(dstId);
CHECK_NET_TRAFFIC_COLLISION(dstId);
if (dstId != dmrData.getDstId() || srcId != dmrData.getSrcId() || flco != dmrData.getFLCO())
LogWarning(LOG_NET, "DMR Slot %u, DT_VOICE_LC_HEADER, header doesn't match the DMR RF header: %u->%s%u %u->%s%u", m_slot->m_slotNo,
@ -725,6 +736,7 @@ void Voice::processNetwork(const data::Data& dmrData)
m_slot->m_netState = RS_NET_AUDIO;
m_slot->m_netLastDstId = dstId;
m_slot->m_netLastSrcId = srcId;
m_slot->m_netTGHang.start();
m_slot->setShortLC(m_slot->m_slotNo, dstId, flco, true);
@ -743,7 +755,7 @@ void Voice::processNetwork(const data::Data& dmrData)
uint32_t dstId = lc->getDstId();
CHECK_NET_AUTHORITATIVE(dstId);
CHECK_TG_HANG(dstId);
CHECK_NET_TRAFFIC_COLLISION(dstId);
m_slot->m_netLC = std::move(lc);
@ -793,6 +805,7 @@ void Voice::processNetwork(const data::Data& dmrData)
m_slot->m_netState = RS_NET_AUDIO;
m_slot->m_netLastDstId = dstId;
m_slot->m_netLastSrcId = srcId;
m_slot->m_netTGHang.start();
m_slot->setShortLC(m_slot->m_slotNo, dstId, m_slot->m_netLC->getFLCO(), true);
@ -898,6 +911,7 @@ void Voice::processNetwork(const data::Data& dmrData)
m_slot->m_netState = RS_NET_AUDIO;
m_slot->m_netLastDstId = dstId;
m_slot->m_netLastSrcId = srcId;
m_slot->m_netTGHang.start();
m_slot->setShortLC(m_slot->m_slotNo, dstId, m_slot->m_netLC->getFLCO(), true);
@ -965,6 +979,7 @@ void Voice::processNetwork(const data::Data& dmrData)
}
}
m_slot->m_netBits += 141U;
m_slot->m_netTGHang.start();
// Get the LCSS from the EMB
data::EMB emb;

@ -306,9 +306,11 @@ void Network::clock(uint32_t ms)
LogWarning(LOG_NET, "DMR Stream %u out-of-sequence; %u != %u", streamId, m_pktSeq, m_pktLastSeq + 1);
}
}
/*
else {
m_rxDMRStreamId[slotNo] = streamId;
}
*/
}
m_pktLastSeq = m_pktSeq;
@ -333,9 +335,11 @@ void Network::clock(uint32_t ms)
LogWarning(LOG_NET, "P25 Stream %u out-of-sequence; %u != %u", streamId, m_pktSeq, m_pktLastSeq + 1);
}
}
/*
else {
m_rxP25StreamId = streamId;
}
*/
}
m_pktLastSeq = m_pktSeq;
@ -360,9 +364,11 @@ void Network::clock(uint32_t ms)
LogWarning(LOG_NET, "NXDN Stream %u out-of-sequence; %u != %u", streamId, m_pktSeq, m_pktLastSeq + 1);
}
}
/*
else {
m_rxNXDNStreamId = streamId;
}
*/
}
m_pktLastSeq = m_pktSeq;

@ -132,6 +132,7 @@ Control::Control(bool authoritative, uint32_t ran, uint32_t callHang, uint32_t q
m_rfTimeout(1000U, timeout),
m_rfTGHang(1000U, tgHang),
m_netTimeout(1000U, timeout),
m_netTGHang(1000U, 2U),
m_networkWatchdog(1000U, 0U, 1500U),
m_ccPacketInterval(1000U, 0U, 80U),
m_frameLossCnt(0U),
@ -603,6 +604,19 @@ void Control::clock(uint32_t ms)
}
}
if (m_netTGHang.isRunning()) {
m_netTGHang.clock(ms);
if (m_netTGHang.hasExpired()) {
m_netTGHang.stop();
if (m_verbose) {
LogMessage(LOG_NET, "talkgroup hang has expired, lastDstId = %u", m_netLastDstId);
}
m_netLastDstId = 0U;
m_netLastSrcId = 0U;
}
}
if (m_netState == RS_NET_AUDIO) {
m_networkWatchdog.clock(ms);

@ -191,6 +191,7 @@ namespace nxdn
Timer m_rfTimeout;
Timer m_rfTGHang;
Timer m_netTimeout;
Timer m_netTGHang;
Timer m_networkWatchdog;
Timer m_ccPacketInterval;

@ -75,6 +75,8 @@ using namespace nxdn::packet;
LogWarning(LOG_RF, "Traffic collision detect, preempting existing network traffic to new RF traffic, rfDstId = %u, netDstId = %u", dstId, \
m_nxdn->m_netLastDstId); \
resetNet(); \
if (m_network != nullptr) \
m_network->resetNXDN(); \
} \
}
@ -82,27 +84,41 @@ using namespace nxdn::packet;
// timer is running, and don't process network frames if the RF modem isn't in a listening state
#define CHECK_NET_TRAFFIC_COLLISION(_LAYER3, _SRC_ID, _DST_ID) \
if (m_nxdn->m_rfLastDstId != 0U) { \
if (m_nxdn->m_rfLastDstId != dstId && (m_nxdn->m_rfTGHang.isRunning() && !m_nxdn->m_rfTGHang.hasExpired())) { \
if (m_nxdn->m_rfLastDstId != _DST_ID && (m_nxdn->m_rfTGHang.isRunning() && !m_nxdn->m_rfTGHang.hasExpired())) { \
resetNet(); \
return false; \
} \
\
if (m_nxdn->m_rfLastDstId == dstId && (m_nxdn->m_rfTGHang.isRunning() && !m_nxdn->m_rfTGHang.hasExpired())) { \
if (m_nxdn->m_rfLastDstId == _DST_ID && (m_nxdn->m_rfTGHang.isRunning() && !m_nxdn->m_rfTGHang.hasExpired())) { \
m_nxdn->m_rfTGHang.start(); \
} \
} \
\
if (m_nxdn->m_netLastDstId != 0U) { \
if (m_nxdn->m_netLastDstId != _DST_ID && (m_nxdn->m_netTGHang.isRunning() && !m_nxdn->m_netTGHang.hasExpired())) { \
return false; \
} \
\
if (m_nxdn->m_netLastDstId == _DST_ID && (m_nxdn->m_netTGHang.isRunning() && !m_nxdn->m_netTGHang.hasExpired())) { \
m_nxdn->m_netTGHang.start(); \
} \
} \
\
if (m_nxdn->m_rfState != RS_RF_LISTENING) { \
if (_LAYER3.getSrcId() == srcId && _LAYER3.getDstId() == dstId) { \
if (_LAYER3.getSrcId() == _SRC_ID && _LAYER3.getDstId() == _DST_ID) { \
LogWarning(LOG_RF, "Traffic collision detect, preempting new network traffic to existing RF traffic (Are we in a voting condition?), rfSrcId = %u, rfDstId = %u, netSrcId = %u, netDstId = %u", _LAYER3.getSrcId(), _LAYER3.getDstId(), \
srcId, dstId); \
_SRC_ID, _DST_ID); \
resetNet(); \
if (m_network != nullptr) \
m_network->resetNXDN(); \
return false; \
} \
else { \
LogWarning(LOG_RF, "Traffic collision detect, preempting new network traffic to existing RF traffic, rfDstId = %u, netDstId = %u", _LAYER3.getDstId(), \
dstId); \
_DST_ID); \
resetNet(); \
if (m_network != nullptr) \
m_network->resetNXDN(); \
return false; \
} \
}
@ -253,6 +269,8 @@ bool Voice::process(uint8_t fct, uint8_t option, uint8_t* data, uint32_t len)
return false;
}
m_nxdn->m_rfTGHang.start();
m_nxdn->m_netTGHang.stop();
m_nxdn->m_rfLastDstId = lc.getDstId();
m_nxdn->m_rfLastSrcId = lc.getSrcId();
m_nxdn->m_rfLC = lc;
@ -414,6 +432,8 @@ bool Voice::process(uint8_t fct, uint8_t option, uint8_t* data, uint32_t len)
// validate destination ID
VALID_DSTID(srcId, dstId, group);
m_nxdn->m_rfTGHang.start();
m_nxdn->m_netTGHang.stop();
m_nxdn->m_rfLastDstId = m_nxdn->m_rfLC.getDstId();
m_nxdn->m_rfLastSrcId = m_nxdn->m_rfLC.getSrcId();
m_rfFrames = 0U;
@ -685,6 +705,8 @@ bool Voice::processNetwork(uint8_t fct, uint8_t option, lc::RTCH& netLC, uint8_t
m_nxdn->m_netState = RS_NET_IDLE;
m_nxdn->m_netMask = 0x00U;
m_nxdn->m_netLC.reset();
m_nxdn->m_netLastDstId = 0U;
m_nxdn->m_netLastSrcId = 0U;
return false;
}
} else if (type == RTCH_MESSAGE_TYPE_VCALL) {
@ -699,6 +721,7 @@ bool Voice::processNetwork(uint8_t fct, uint8_t option, lc::RTCH& netLC, uint8_t
return false;
}
m_nxdn->m_netTGHang.start();
m_nxdn->m_netLastDstId = lc.getDstId();
m_nxdn->m_netLastSrcId = lc.getSrcId();
m_nxdn->m_netLC = lc;
@ -839,6 +862,7 @@ bool Voice::processNetwork(uint8_t fct, uint8_t option, lc::RTCH& netLC, uint8_t
// validate destination ID
VALID_DSTID(srcId, dstId, group);
m_nxdn->m_netTGHang.start();
m_nxdn->m_netLastDstId = m_nxdn->m_netLC.getDstId();
m_nxdn->m_netLastSrcId = m_nxdn->m_netLC.getSrcId();
m_rfFrames = 0U;

@ -129,6 +129,7 @@ Control::Control(bool authoritative, uint32_t nac, uint32_t callHang, uint32_t q
m_rfTGHang(1000U, tgHang),
m_rfLossWatchdog(1000U, 0U, 1500U),
m_netTimeout(1000U, timeout),
m_netTGHang(1000U, 2U),
m_networkWatchdog(1000U, 0U, 1500U),
m_ccPacketInterval(1000U, 0U, 10U),
m_hangCount(3U * 8U),
@ -763,6 +764,19 @@ void Control::clock(uint32_t ms)
}
}
if (m_netTGHang.isRunning()) {
m_netTGHang.clock(ms);
if (m_netTGHang.hasExpired()) {
m_netTGHang.stop();
if (m_verbose) {
LogMessage(LOG_NET, "talkgroup hang has expired, lastDstId = %u", m_netLastDstId);
}
m_netLastDstId = 0U;
m_netLastSrcId = 0U;
}
}
if (m_netState == RS_NET_AUDIO || m_netState == RS_NET_DATA) {
m_networkWatchdog.clock(ms);

@ -204,6 +204,7 @@ namespace p25
Timer m_rfTGHang;
Timer m_rfLossWatchdog;
Timer m_netTimeout;
Timer m_netTGHang;
Timer m_networkWatchdog;
Timer m_ccPacketInterval;

@ -180,7 +180,13 @@ bool Voice::process(uint8_t* data, uint32_t len)
if (m_p25->m_netState != RS_NET_IDLE) {
LogWarning(LOG_RF, "Traffic collision detect, preempting existing network traffic to new RF traffic, rfDstId = %u, netDstId = %u", lc.getDstId(),
m_p25->m_netLastDstId);
if (!m_p25->m_dedicatedControl) {
m_p25->m_affiliations.releaseGrant(m_p25->m_netLastDstId, false);
}
resetNet();
if (m_network != nullptr)
m_network->resetP25();
if (m_p25->m_duplex) {
m_p25->writeRF_TDU(true);
@ -192,6 +198,7 @@ bool Voice::process(uint8_t* data, uint32_t len)
}
m_p25->m_rfTGHang.start();
m_p25->m_netTGHang.stop();
m_p25->m_rfLastDstId = lc.getDstId();
m_p25->m_rfLastSrcId = lc.getSrcId();
@ -265,7 +272,19 @@ bool Voice::process(uint8_t* data, uint32_t len)
else {
LogWarning(LOG_RF, "Traffic collision detect, preempting existing network traffic to new RF traffic, rfDstId = %u, netDstId = %u", dstId,
m_p25->m_netLastDstId);
if (!m_p25->m_dedicatedControl) {
m_p25->m_affiliations.releaseGrant(m_p25->m_netLastDstId, false);
}
resetNet();
if (m_network != nullptr)
m_network->resetP25();
if (m_p25->m_duplex) {
m_p25->writeRF_TDU(true);
}
m_p25->m_netTGHang.stop();
}
}
@ -400,7 +419,7 @@ bool Voice::process(uint8_t* data, uint32_t len)
else {
m_p25->m_rfTGHang.stop();
}
m_p25->m_netTGHang.stop();
m_p25->m_rfLastDstId = dstId;
m_p25->m_rfLastSrcId = srcId;
@ -763,8 +782,55 @@ bool Voice::process(uint8_t* data, uint32_t len)
/// <returns></returns>
bool Voice::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::LowSpeedData& lsd, uint8_t& duid, uint8_t& frameType)
{
uint32_t count = 0U;
uint32_t dstId = control.getDstId();
uint32_t srcId = control.getSrcId();
// don't process network frames if the destination ID's don't match and the RF TG hang timer is running
if (m_p25->m_rfLastDstId != 0U && dstId != 0U) {
if (m_p25->m_rfLastDstId != dstId && (m_p25->m_rfTGHang.isRunning() && !m_p25->m_rfTGHang.hasExpired())) {
resetNet();
if (m_network != nullptr)
m_network->resetP25();
return false;
}
if (m_p25->m_rfLastDstId == dstId && (m_p25->m_rfTGHang.isRunning() && !m_p25->m_rfTGHang.hasExpired())) {
m_p25->m_rfTGHang.start();
}
}
// don't process network frames if the destination ID's don't match and the network TG hang timer is running
if (m_p25->m_netLastDstId != 0U && dstId != 0U && (duid == P25_DUID_LDU1 || duid == P25_DUID_LDU2)) {
if (m_p25->m_netLastDstId != dstId && (m_p25->m_netTGHang.isRunning() && !m_p25->m_netTGHang.hasExpired())) {
return false;
}
if (m_p25->m_netLastDstId == dstId && (m_p25->m_netTGHang.isRunning() && !m_p25->m_netTGHang.hasExpired())) {
m_p25->m_netTGHang.start();
}
}
// don't process network frames if the RF modem isn't in a listening state
if (m_p25->m_rfState != RS_RF_LISTENING) {
if (m_rfLC.getSrcId() == srcId && m_rfLC.getDstId() == dstId) {
LogWarning(LOG_RF, "Traffic collision detect, preempting new network traffic to existing RF traffic (Are we in a voting condition?), rfSrcId = %u, rfDstId = %u, netSrcId = %u, netDstId = %u", m_rfLC.getSrcId(), m_rfLC.getDstId(),
srcId, dstId);
resetNet();
if (m_network != nullptr)
m_network->resetP25();
return false;
}
else {
LogWarning(LOG_RF, "Traffic collision detect, preempting new network traffic to existing RF traffic, rfDstId = %u, netDstId = %u", m_rfLC.getDstId(),
dstId);
resetNet();
if (m_network != nullptr)
m_network->resetP25();
return false;
}
}
uint32_t count = 0U;
switch (duid) {
case P25_DUID_LDU1:
if ((data[0U] == dfsi::P25_DFSI_LDU1_VOICE1) && (data[22U] == dfsi::P25_DFSI_LDU1_VOICE2) &&
@ -839,6 +905,7 @@ bool Voice::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L
checkNet_LDU2();
if (m_p25->m_netState != RS_NET_IDLE) {
m_p25->m_netTGHang.start();
writeNet_LDU1();
}
}
@ -914,6 +981,7 @@ bool Voice::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L
}
if (m_p25->m_netState != RS_NET_IDLE) {
m_p25->m_netTGHang.start();
writeNet_LDU2();
}
}
@ -1111,8 +1179,6 @@ void Voice::writeNet_TDU()
m_p25->m_networkWatchdog.stop();
resetNet();
m_p25->m_netState = RS_NET_IDLE;
m_p25->m_netLastDstId = 0U;
m_p25->m_netLastSrcId = 0U;
m_p25->m_tailOnIdle = true;
}
@ -1151,40 +1217,27 @@ void Voice::writeNet_LDU1()
uint32_t srcId = control.getSrcId();
bool group = control.getLCO() == LC_GROUP;
// don't process network frames if the destination ID's don't match and the network TG hang timer is running
if (m_p25->m_rfLastDstId != 0U && dstId != 0U) {
if (m_p25->m_rfLastDstId != dstId && (m_p25->m_rfTGHang.isRunning() && !m_p25->m_rfTGHang.hasExpired())) {
resetNet();
return;
}
if (m_p25->m_rfLastDstId == dstId && (m_p25->m_rfTGHang.isRunning() && !m_p25->m_rfTGHang.hasExpired())) {
m_p25->m_rfTGHang.start();
}
}
// ensure our srcId and dstId are sane from the last LDU1
// ensure our dstId are sane from the last LDU1
if (m_netLastLDU1.getDstId() != 0U) {
if (dstId != m_netLastLDU1.getDstId()) {
LogWarning(LOG_NET, P25_LDU1_STR ", dstId = %u doesn't match last LDU1 dstId = %u, fixing",
m_rfLC.getDstId(), m_rfLastLDU1.getDstId());
if (m_verbose) {
LogMessage(LOG_NET, P25_LDU1_STR ", dstId = %u doesn't match last LDU1 dstId = %u, fixing",
dstId, m_netLastLDU1.getDstId());
}
dstId = m_netLastLDU1.getDstId();
}
}
else {
LogWarning(LOG_NET, P25_LDU1_STR ", last LDU1 LC has bad data, dstId = 0");
}
// ensure our srcId are sane from the last LDU1
if (m_netLastLDU1.getSrcId() != 0U) {
if (srcId != m_netLastLDU1.getSrcId()) {
LogWarning(LOG_NET, P25_LDU1_STR ", srcId = %u doesn't match last LDU1 srcId = %u, fixing",
m_rfLC.getSrcId(), m_rfLastLDU1.getSrcId());
if (m_verbose) {
LogMessage(LOG_NET, P25_LDU1_STR ", srcId = %u doesn't match last LDU1 srcId = %u, fixing",
srcId, m_netLastLDU1.getSrcId());
}
srcId = m_netLastLDU1.getSrcId();
}
}
else {
LogWarning(LOG_NET, P25_LDU1_STR ", last LDU1 LC has bad data, srcId = 0");
}
// don't process network frames if this modem isn't authoritative
if (!m_p25->m_authoritative && m_p25->m_permittedDstId != dstId) {
@ -1193,22 +1246,6 @@ void Voice::writeNet_LDU1()
return;
}
// don't process network frames if the RF modem isn't in a listening state
if (m_p25->m_rfState != RS_RF_LISTENING) {
if (m_rfLC.getSrcId() == srcId && m_rfLC.getDstId() == dstId) {
LogWarning(LOG_RF, "Traffic collision detect, preempting new network traffic to existing RF traffic (Are we in a voting condition?), rfSrcId = %u, rfDstId = %u, netSrcId = %u, netDstId = %u", m_rfLC.getSrcId(), m_rfLC.getDstId(),
srcId, dstId);
resetNet();
return;
}
else {
LogWarning(LOG_RF, "Traffic collision detect, preempting new network traffic to existing RF traffic, rfDstId = %u, netDstId = %u", m_rfLC.getDstId(),
dstId);
resetNet();
return;
}
}
if (m_debug) {
LogMessage(LOG_NET, P25_LDU1_STR " service flags, emerg = %u, encrypt = %u, prio = %u, DFSI emerg = %u, DFSI encrypt = %u, DFSI prio = %u",
control.getEmergency(), control.getEncrypted(), control.getPriority(),
@ -1294,7 +1331,7 @@ void Voice::writeNet_LDU1()
(m_netLC.getPriority() & 0x07U); // Priority
if (!m_p25->m_trunk->writeRF_TSDU_Grant(srcId, dstId, serviceOptions, group, true)) {
LogError(LOG_NET, P25_HDU_STR " call failure, not granted, this should not happen, dstId = %u", dstId);
LogError(LOG_NET, P25_HDU_STR " call failure, network call not granted, dstId = %u", dstId);
if (m_network != nullptr)
m_network->resetP25();
@ -1327,6 +1364,7 @@ void Voice::writeNet_LDU1()
m_p25->m_netState = RS_NET_AUDIO;
m_p25->m_netLastDstId = dstId;
m_p25->m_netLastSrcId = srcId;
m_p25->m_netTGHang.start();
m_p25->m_netTimeout.start();
m_netFrames = 0U;
m_netLost = 0U;
@ -1465,14 +1503,6 @@ void Voice::writeNet_LDU2()
return;
}
// don't process network frames if the destination ID's don't match and the network TG hang timer is running
if (m_p25->m_rfLastDstId != 0U) {
if (m_p25->m_rfLastDstId != m_netLastLDU1.getDstId() && (m_p25->m_rfTGHang.isRunning() && !m_p25->m_rfTGHang.hasExpired())) {
resetNet();
return;
}
}
uint8_t mi[P25_MI_LENGTH_BYTES];
control.getMI(mi);

Loading…
Cancel
Save

Powered by TurnKey Linux.