correct issue where DMR would round-robin assign slots for TGs, instead ensure available channel resources for the request slot exist and grant or queue accordingly; add some experimental support to generate a CSBK grant from network traffic if the destination ID hasn't already been granted;

pull/72/head
Bryan Biedenkapp 1 year ago
parent 0fda70654c
commit 7b27eadbd7

@ -712,6 +712,16 @@ void Control::processNetwork()
data.setN(n);
}
// are we TSCC enabled?
if (m_enableTSCC) {
Slot* tscc = getTSCCSlot();
if (tscc != nullptr) {
if (!tscc->m_affiliations->isGranted(dstId)) {
tscc->m_control->writeRF_CSBK_Grant(srcId, dstId, 4U, (flco == FLCO::GROUP) ? true : false, true);
}
}
}
// forward onto the specific slot for final processing and delivery
switch (slotNo) {
case 1U:

@ -36,14 +36,8 @@ DMRAffiliationLookup::~DMRAffiliationLookup() = default;
bool DMRAffiliationLookup::grantCh(uint32_t dstId, uint32_t srcId, uint32_t grantTimeout, bool grp, bool netGranted)
{
uint32_t chNo = m_chLookup->getFirstRFChannel();
uint8_t slot = getAvailableSlotForChannel(chNo);
if (slot == 0U) {
return false;
}
return grantChSlot(dstId, srcId, slot, grantTimeout, grp, netGranted);
::LogDebug(LOG_HOST, "%s, DMRAffiliationLookup::grantCh() use grantChSlot() BUGBUG");
return false;
}
/* Helper to grant a channel and slot. */
@ -58,7 +52,11 @@ bool DMRAffiliationLookup::grantChSlot(uint32_t dstId, uint32_t srcId, uint8_t s
return false;
}
uint32_t chNo = m_chLookup->getFirstRFChannel();
uint32_t chNo = getAvailableChannelForSlot(slot);
if (chNo == 0U) {
return false;
}
if (chNo == m_tsccChNo && slot == m_tsccSlot) {
return false;
}
@ -212,6 +210,47 @@ void DMRAffiliationLookup::setSlotForChannelTSCC(uint32_t chNo, uint8_t slot)
m_tsccSlot = slot;
}
/* Helper to determine the an available channel for a slot. */
uint32_t DMRAffiliationLookup::getAvailableChannelForSlot(uint8_t slot) const
{
if (slot == 0U) {
return 0U;
}
uint32_t chNo = 0U;
for (auto entry : m_chLookup->rfChDataTable()) {
if (entry.second.chNo() == m_tsccChNo && slot == m_tsccSlot) {
continue;
} else {
// lookup dynamic channel slot grant table entry
bool chAvailSlot = false;
for (auto gntEntry : m_grantChSlotTable) {
uint32_t foundChNo = std::get<0>(gntEntry.second);
if (foundChNo == entry.second.chNo()) {
uint8_t foundSlot = std::get<1>(gntEntry.second);
if (slot == foundSlot)
continue;
else {
chAvailSlot = true;
break;
}
}
}
// if we have no granted channels -- return true
if (m_grantChSlotTable.size() == 0U)
chAvailSlot = true;
chNo = entry.second.chNo();
if (chAvailSlot)
break;
}
}
return chNo;
}
/* Helper to determine the first available slot for given the channel number. */
uint8_t DMRAffiliationLookup::getAvailableSlotForChannel(uint32_t chNo) const

@ -100,6 +100,12 @@ namespace dmr
*/
void setSlotForChannelTSCC(uint32_t chNo, uint8_t slot);
/**
* @brief Helper to determine the an available channel for a slot.
* @param chNo Channel Number.
*/
uint32_t getAvailableChannelForSlot(uint8_t slot) const;
/**
* @brief Helper to determine the first available slot for given the channel number.
* @param chNo Channel Number.

@ -854,7 +854,11 @@ bool ControlSignaling::writeRF_CSBK_Grant(uint32_t srcId, uint32_t dstId, uint8_
}
if (!m_tscc->m_affiliations->isGranted(dstId)) {
if (!m_tscc->m_affiliations->rfCh()->isRFChAvailable()) {
::lookups::TalkgroupRuleGroupVoice groupVoice = m_tscc->m_tidLookup->find(dstId);
slot = groupVoice.source().tgSlot();
uint32_t availChNo = m_tscc->m_affiliations->getAvailableChannelForSlot(slot);
if (!m_tscc->m_affiliations->rfCh()->isRFChAvailable() || availChNo == 0U) {
if (grp) {
if (!net) {
LogWarning(LOG_RF, "DMR Slot %u, CSBK, RAND (Random Access, GRP_VOICE_CALL (Group Voice Call) queued, no channels available, dstId = %u", m_tscc->m_slotNo, dstId);
@ -879,9 +883,10 @@ bool ControlSignaling::writeRF_CSBK_Grant(uint32_t srcId, uint32_t dstId, uint8_
}
}
else {
if (m_tscc->m_affiliations->grantCh(dstId, srcId, GRANT_TIMER_TIMEOUT, grp, net)) {
if (m_tscc->m_affiliations->grantChSlot(dstId, srcId, slot, GRANT_TIMER_TIMEOUT, grp, net)) {
chNo = m_tscc->m_affiliations->getGrantedCh(dstId);
slot = m_tscc->m_affiliations->getGrantedSlot(dstId);
LogDebug(LOG_RF, "DMR Slot %u, CSBK, RAND (Random Access, VOICE_CALL (Voice Call), chNo = %u, slot = %u, tsccChNo = %u", m_tscc->m_slotNo, chNo, slot, m_tscc->m_channelNo);
//m_tscc->m_siteData.setChCnt(m_tscc->m_affiliations->getRFChCnt() + m_tscc->m_affiliations->getGrantedRFChCnt());
}
}
@ -1136,7 +1141,11 @@ bool ControlSignaling::writeRF_CSBK_Data_Grant(uint32_t srcId, uint32_t dstId, u
}
if (!m_tscc->m_affiliations->isGranted(dstId)) {
if (!m_tscc->m_affiliations->rfCh()->isRFChAvailable()) {
::lookups::TalkgroupRuleGroupVoice groupVoice = m_tscc->m_tidLookup->find(dstId);
slot = groupVoice.source().tgSlot();
uint32_t availChNo = m_tscc->m_affiliations->getAvailableChannelForSlot(slot);
if (!m_tscc->m_affiliations->rfCh()->isRFChAvailable() || availChNo == 0U) {
if (grp) {
if (!net) {
LogWarning(LOG_RF, "DMR Slot %u, CSBK, RAND (Random Access, GRP_DATA_CALL (Group Data Call) queued, no channels available, dstId = %u", m_tscc->m_slotNo, dstId);
@ -1161,7 +1170,7 @@ bool ControlSignaling::writeRF_CSBK_Data_Grant(uint32_t srcId, uint32_t dstId, u
}
}
else {
if (m_tscc->m_affiliations->grantCh(dstId, srcId, GRANT_TIMER_TIMEOUT, grp, net)) {
if (m_tscc->m_affiliations->grantChSlot(dstId, srcId, slot, GRANT_TIMER_TIMEOUT, grp, net)) {
chNo = m_tscc->m_affiliations->getGrantedCh(dstId);
slot = m_tscc->m_affiliations->getGrantedSlot(dstId);

@ -85,6 +85,7 @@ namespace dmr
/** @} */
private:
friend class dmr::Control;
friend class dmr::Slot;
Slot* m_slot;

Loading…
Cancel
Save

Powered by TurnKey Linux.