diff --git a/src/dmr/lookups/DMRAffiliationLookup.cpp b/src/dmr/lookups/DMRAffiliationLookup.cpp
index da906e1b..84a36c3e 100644
--- a/src/dmr/lookups/DMRAffiliationLookup.cpp
+++ b/src/dmr/lookups/DMRAffiliationLookup.cpp
@@ -63,8 +63,9 @@ DMRAffiliationLookup::~DMRAffiliationLookup()
///
///
///
+///
///
-bool DMRAffiliationLookup::grantCh(uint32_t dstId, uint32_t srcId, uint32_t grantTimeout)
+bool DMRAffiliationLookup::grantCh(uint32_t dstId, uint32_t srcId, uint32_t grantTimeout, bool netGranted)
{
uint32_t chNo = m_rfChTable.at(0);
uint8_t slot = getAvailableSlotForChannel(chNo);
@@ -73,7 +74,7 @@ bool DMRAffiliationLookup::grantCh(uint32_t dstId, uint32_t srcId, uint32_t gran
return false;
}
- return grantChSlot(dstId, srcId, slot, grantTimeout);
+ return grantChSlot(dstId, srcId, slot, grantTimeout, netGranted);
}
///
@@ -83,8 +84,9 @@ bool DMRAffiliationLookup::grantCh(uint32_t dstId, uint32_t srcId, uint32_t gran
///
///
///
+///
///
-bool DMRAffiliationLookup::grantChSlot(uint32_t dstId, uint32_t srcId, uint8_t slot, uint32_t grantTimeout)
+bool DMRAffiliationLookup::grantChSlot(uint32_t dstId, uint32_t srcId, uint8_t slot, uint32_t grantTimeout, bool netGranted)
{
if (dstId == 0U) {
return false;
@@ -109,6 +111,8 @@ bool DMRAffiliationLookup::grantChSlot(uint32_t dstId, uint32_t srcId, uint8_t s
m_grantChSlotTable[dstId] = std::make_tuple(chNo, slot);
m_rfGrantChCnt++;
+ m_netGrantedTable[dstId] = netGranted;
+
m_grantTimers[dstId] = Timer(1000U, grantTimeout);
m_grantTimers[dstId].start();
@@ -166,6 +170,7 @@ bool DMRAffiliationLookup::releaseGrant(uint32_t dstId, bool releaseAll)
m_grantChTable.erase(dstId);
m_grantSrcIdTable.erase(dstId);
m_grantChSlotTable.erase(dstId);
+ m_netGrantedTable.erase(dstId);
auto it = std::find(m_rfChTable.begin(), m_rfChTable.end(), chNo);
if (it == m_rfChTable.end()) {
diff --git a/src/dmr/lookups/DMRAffiliationLookup.h b/src/dmr/lookups/DMRAffiliationLookup.h
index 72f59409..0809681d 100644
--- a/src/dmr/lookups/DMRAffiliationLookup.h
+++ b/src/dmr/lookups/DMRAffiliationLookup.h
@@ -49,9 +49,9 @@ namespace dmr
virtual ~DMRAffiliationLookup();
/// Helper to grant a channel.
- bool grantCh(uint32_t dstId, uint32_t srcId, uint32_t grantTimeout) override;
+ bool grantCh(uint32_t dstId, uint32_t srcId, uint32_t grantTimeout, bool netGranted) override;
/// Helper to grant a channel and slot.
- bool grantChSlot(uint32_t dstId, uint32_t srcId, uint8_t slot, uint32_t grantTimeout);
+ bool grantChSlot(uint32_t dstId, uint32_t srcId, uint8_t slot, uint32_t grantTimeout, bool netGranted);
/// Helper to release the channel grant for the destination ID.
bool releaseGrant(uint32_t dstId, bool releaseAll) override;
/// Helper to determine if the channel number is busy.
diff --git a/src/dmr/packet/ControlSignaling.cpp b/src/dmr/packet/ControlSignaling.cpp
index 99c29969..92e0b95a 100644
--- a/src/dmr/packet/ControlSignaling.cpp
+++ b/src/dmr/packet/ControlSignaling.cpp
@@ -861,7 +861,7 @@ bool ControlSignaling::writeRF_CSBK_Grant(uint32_t srcId, uint32_t dstId, uint8_
}
}
else {
- if (m_tscc->m_affiliations->grantCh(dstId, srcId, GRANT_TIMER_TIMEOUT)) {
+ if (m_tscc->m_affiliations->grantCh(dstId, srcId, GRANT_TIMER_TIMEOUT, net)) {
chNo = m_tscc->m_affiliations->getGrantedCh(dstId);
slot = m_tscc->m_affiliations->getGrantedSlot(dstId);
//m_tscc->m_siteData.setChCnt(m_tscc->m_affiliations->getRFChCnt() + m_tscc->m_affiliations->getGrantedRFChCnt());
@@ -1150,7 +1150,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)) {
+ if (m_tscc->m_affiliations->grantCh(dstId, srcId, GRANT_TIMER_TIMEOUT, net)) {
chNo = m_tscc->m_affiliations->getGrantedCh(dstId);
slot = m_tscc->m_affiliations->getGrantedSlot(dstId);
diff --git a/src/lookups/AffiliationLookup.cpp b/src/lookups/AffiliationLookup.cpp
index b31f489b..b73f86fb 100644
--- a/src/lookups/AffiliationLookup.cpp
+++ b/src/lookups/AffiliationLookup.cpp
@@ -50,6 +50,7 @@ AffiliationLookup::AffiliationLookup(const char* name, bool verbose) :
m_grpAffTable(),
m_grantChTable(),
m_grantSrcIdTable(),
+ m_netGrantedTable(),
m_grantTimers(),
m_releaseGrant(nullptr),
m_name(name),
@@ -245,8 +246,9 @@ std::vector AffiliationLookup::clearGroupAff(uint32_t dstId, bool rele
///
///
///
+///
///
-bool AffiliationLookup::grantCh(uint32_t dstId, uint32_t srcId, uint32_t grantTimeout)
+bool AffiliationLookup::grantCh(uint32_t dstId, uint32_t srcId, uint32_t grantTimeout, bool netGranted)
{
if (dstId == 0U) {
return false;
@@ -264,6 +266,8 @@ bool AffiliationLookup::grantCh(uint32_t dstId, uint32_t srcId, uint32_t grantTi
m_grantSrcIdTable[dstId] = srcId;
m_rfGrantChCnt++;
+ m_netGrantedTable[dstId] = netGranted;
+
m_grantTimers[dstId] = Timer(1000U, grantTimeout);
m_grantTimers[dstId].start();
@@ -334,6 +338,7 @@ bool AffiliationLookup::releaseGrant(uint32_t dstId, bool releaseAll)
m_grantChTable.erase(dstId);
m_grantSrcIdTable.erase(dstId);
+ m_netGrantedTable.erase(dstId);
m_rfChTable.push_back(chNo);
if (m_rfGrantChCnt > 0U) {
@@ -396,6 +401,26 @@ bool AffiliationLookup::isGranted(uint32_t dstId) const
}
}
+///
+/// Helper to determine if the destination ID is network granted.
+///
+///
+///
+bool AffiliationLookup::isNetGranted(uint32_t dstId) const
+{
+ if (dstId == 0U) {
+ return false;
+ }
+
+ // lookup dynamic channel grant table entry
+ try {
+ bool net = m_netGrantedTable.at(dstId);
+ return net;
+ } catch (...) {
+ return false;
+ }
+}
+
///
/// Helper to get the channel granted for the given destination ID.
///
diff --git a/src/lookups/AffiliationLookup.h b/src/lookups/AffiliationLookup.h
index 15967de1..9f4aa99e 100644
--- a/src/lookups/AffiliationLookup.h
+++ b/src/lookups/AffiliationLookup.h
@@ -138,7 +138,7 @@ namespace lookups
/// Gets the grant table.
std::unordered_map grantTable() const { return m_grantChTable; }
/// Helper to grant a channel.
- virtual bool grantCh(uint32_t dstId, uint32_t srcId, uint32_t grantTimeout);
+ virtual bool grantCh(uint32_t dstId, uint32_t srcId, uint32_t grantTimeout, bool netGranted);
/// Helper to start the destination ID grant timer.
virtual void touchGrant(uint32_t dstId);
/// Helper to release the channel grant for the destination ID.
@@ -147,6 +147,8 @@ namespace lookups
virtual bool isChBusy(uint32_t chNo) const;
/// Helper to determine if the destination ID is already granted.
virtual bool isGranted(uint32_t dstId) const;
+ /// Helper to determine if the destination ID is granted by network traffic.
+ virtual bool isNetGranted(uint32_t dstId) const;
/// Helper to get the channel granted for the given destination ID.
virtual uint32_t getGrantedCh(uint32_t dstId);
/// Helper to get the source ID granted for the given destination ID.
@@ -184,6 +186,7 @@ namespace lookups
std::unordered_map m_grantChTable;
std::unordered_map m_grantSrcIdTable;
+ std::unordered_map m_netGrantedTable;
std::unordered_map m_grantTimers;
// chNo dstId slot
diff --git a/src/nxdn/packet/ControlSignaling.cpp b/src/nxdn/packet/ControlSignaling.cpp
index f8e23bae..191cd2d3 100644
--- a/src/nxdn/packet/ControlSignaling.cpp
+++ b/src/nxdn/packet/ControlSignaling.cpp
@@ -563,7 +563,7 @@ bool ControlSignaling::writeRF_Message_Grant(uint32_t srcId, uint32_t dstId, uin
}
}
else {
- if (m_nxdn->m_affiliations.grantCh(dstId, srcId, GRANT_TIMER_TIMEOUT)) {
+ if (m_nxdn->m_affiliations.grantCh(dstId, srcId, GRANT_TIMER_TIMEOUT, net)) {
chNo = m_nxdn->m_affiliations.getGrantedCh(dstId);
}
}
diff --git a/src/p25/packet/ControlSignaling.cpp b/src/p25/packet/ControlSignaling.cpp
index 7611986a..68f058ed 100644
--- a/src/p25/packet/ControlSignaling.cpp
+++ b/src/p25/packet/ControlSignaling.cpp
@@ -2190,7 +2190,7 @@ bool ControlSignaling::writeRF_TSDU_Grant(uint32_t srcId, uint32_t dstId, uint8_
}
}
else {
- if (m_p25->m_affiliations.grantCh(dstId, srcId, GRANT_TIMER_TIMEOUT)) {
+ if (m_p25->m_affiliations.grantCh(dstId, srcId, GRANT_TIMER_TIMEOUT, net)) {
chNo = m_p25->m_affiliations.getGrantedCh(dstId);
m_p25->m_siteData.setChCnt(m_p25->m_affiliations.getRFChCnt() + m_p25->m_affiliations.getGrantedRFChCnt());
}
@@ -2449,7 +2449,7 @@ bool ControlSignaling::writeRF_TSDU_SNDCP_Grant(uint32_t srcId, uint32_t dstId,
return false;
}
else {
- if (m_p25->m_affiliations.grantCh(srcId, srcId, GRANT_TIMER_TIMEOUT)) {
+ if (m_p25->m_affiliations.grantCh(srcId, srcId, GRANT_TIMER_TIMEOUT, net)) {
uint32_t chNo = m_p25->m_affiliations.getGrantedCh(srcId);
osp->setGrpVchNo(chNo);
osp->setDataChnNo(chNo);