refactor how grants are handled across the network;

pull/25/head
Bryan Biedenkapp 3 years ago
parent 9512e0c256
commit 8b4002246a

@ -443,6 +443,43 @@ void ControlSignaling::processNetwork(const data::Data & dmrData)
LogMessage(LOG_NET, "DMR Slot %u, DT_CSBK, CSBKO_RAND (Random Access), serviceKind = $%02X, serviceOptions = $%02X, serviceExtra = $%02X, srcId = %u, dstId = %u", LogMessage(LOG_NET, "DMR Slot %u, DT_CSBK, CSBKO_RAND (Random Access), serviceKind = $%02X, serviceOptions = $%02X, serviceExtra = $%02X, srcId = %u, dstId = %u",
m_slot->m_slotNo, isp->getServiceKind(), isp->getServiceOptions(), isp->getServiceExtra(), isp->getSrcId(), isp->getDstId()); m_slot->m_slotNo, isp->getServiceKind(), isp->getServiceOptions(), isp->getServiceExtra(), isp->getSrcId(), isp->getDstId());
} }
switch (isp->getServiceKind()) {
case SVC_KIND_IND_VOICE_CALL:
writeRF_CSBK_ACK_RSP(srcId, TS_WAIT_RSN, 1U);
if (m_slot->m_authoritative) {
writeRF_CSBK_Grant(srcId, dstId, isp->getServiceOptions(), false);
}
break;
case SVC_KIND_GRP_VOICE_CALL:
writeRF_CSBK_ACK_RSP(srcId, TS_WAIT_RSN, 1U);
if (m_slot->m_authoritative) {
writeRF_CSBK_Grant(srcId, dstId, isp->getServiceOptions(), true);
}
break;
case SVC_KIND_IND_DATA_CALL:
case SVC_KIND_IND_UDT_DATA_CALL:
writeRF_CSBK_ACK_RSP(srcId, TS_WAIT_RSN, 0U);
writeRF_CSBK_Data_Grant(srcId, dstId, isp->getServiceOptions(), false);
break;
case SVC_KIND_GRP_DATA_CALL:
case SVC_KIND_GRP_UDT_DATA_CALL:
writeRF_CSBK_ACK_RSP(srcId, TS_WAIT_RSN, 0U);
writeRF_CSBK_Data_Grant(srcId, dstId, isp->getServiceOptions(), true);
break;
case SVC_KIND_REG_SVC:
break;
default:
LogWarning(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_RAND (Random Access), unhandled service, serviceKind = %02X", m_slot->m_slotNo, isp->getServiceKind());
// should we drop the CSBK and not repeat it?
break;
}
handled = true;
} }
} }
break; break;

@ -43,6 +43,7 @@
using namespace nxdn; using namespace nxdn;
using namespace nxdn::lc; using namespace nxdn::lc;
using namespace nxdn::lc::rcch;
using namespace nxdn::packet; using namespace nxdn::packet;
#include <cassert> #include <cassert>
@ -235,10 +236,50 @@ bool Trunk::processNetwork(uint8_t fct, uint8_t option, lc::RTCH& netLC, uint8_t
{ {
assert(data != nullptr); assert(data != nullptr);
if (!m_nxdn->m_control)
return false;
if (m_nxdn->m_rfState != RS_RF_LISTENING && m_nxdn->m_netState == RS_NET_IDLE)
return false;
if (m_nxdn->m_netState == RS_NET_IDLE) { if (m_nxdn->m_netState == RS_NET_IDLE) {
m_nxdn->m_queue.clear(); m_nxdn->m_queue.clear();
} }
if (m_nxdn->m_netState == RS_NET_IDLE) {
std::unique_ptr<lc::RCCH> rcch = RCCHFactory::createRCCH(data, len);
if (rcch == nullptr) {
return false;
}
uint16_t srcId = rcch->getSrcId();
uint16_t dstId = rcch->getDstId();
// handle standard P25 reference opcodes
switch (rcch->getMessageType()) {
case RTCH_MESSAGE_TYPE_VCALL:
{
if (m_verbose) {
LogMessage(LOG_NET, NXDN_RCCH_MSG_TYPE_VCALL_CONN_REQ ", emerg = %u, encrypt = %u, prio = %u, chNo = %u, srcId = %u, dstId = %u",
rcch->getEmergency(), rcch->getEncrypted(), rcch->getPriority(), rcch->getGrpVchNo(), srcId, dstId);
}
uint8_t serviceOptions = (rcch->getEmergency() ? 0x80U : 0x00U) + // Emergency Flag
(rcch->getEncrypted() ? 0x40U : 0x00U) + // Encrypted Flag
(rcch->getPriority() & 0x07U); // Priority
if (m_nxdn->m_dedicatedControl && !m_nxdn->m_voiceOnControl) {
writeRF_Message_Grant(srcId, dstId, serviceOptions, true);
}
}
return true; // don't allow this to write to the air
default:
LogError(LOG_NET, "NXDN, unhandled message type, messageType = $%02X", rcch->getMessageType());
return false;
} // switch (rcch->getMessageType())
writeRF_Message(rcch.get(), true);
}
return true; return true;
} }

@ -710,8 +710,7 @@ bool Trunk::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L
(tsbk->getEncrypted() ? 0x40U : 0x00U) + // Encrypted Flag (tsbk->getEncrypted() ? 0x40U : 0x00U) + // Encrypted Flag
(tsbk->getPriority() & 0x07U); // Priority (tsbk->getPriority() & 0x07U); // Priority
// workaround for single channel dedicated sites to pass network traffic on a lone VC if (m_p25->m_dedicatedControl && !m_p25->m_voiceOnControl) {
if (m_p25->m_dedicatedControl && !m_p25->m_voiceOnControl && m_p25->m_affiliations.getRFChCnt() == 1U) {
writeRF_TSDU_Grant(srcId, dstId, serviceOptions, true); writeRF_TSDU_Grant(srcId, dstId, serviceOptions, true);
} }
} }
@ -727,8 +726,7 @@ bool Trunk::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L
(tsbk->getEncrypted() ? 0x40U : 0x00U) + // Encrypted Flag (tsbk->getEncrypted() ? 0x40U : 0x00U) + // Encrypted Flag
(tsbk->getPriority() & 0x07U); // Priority (tsbk->getPriority() & 0x07U); // Priority
// workaround for single channel dedicated sites to pass network traffic on a lone VC if (m_p25->m_dedicatedControl && !m_p25->m_voiceOnControl) {
if (m_p25->m_dedicatedControl && !m_p25->m_voiceOnControl && m_p25->m_affiliations.getRFChCnt() == 1U) {
writeRF_TSDU_Grant(srcId, dstId, serviceOptions, false); writeRF_TSDU_Grant(srcId, dstId, serviceOptions, false);
} }
} }

Loading…
Cancel
Save

Powered by TurnKey Linux.