split unit registration, group affiliation and group grant handling into its own AffiliationLookup class; implement some more NXDN ISP/OSP trunking messages; reorganize how header includes were being done slightly;
parent
b64b5b12ba
commit
905b49736a
@ -0,0 +1,384 @@
|
|||||||
|
/**
|
||||||
|
* Digital Voice Modem - Host Software
|
||||||
|
* GPLv2 Open Source. Use is subject to license terms.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* @package DVM / Host Software
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2022 by Bryan Biedenkapp N2PLL
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
#include "lookups/AffiliationLookup.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
using namespace lookups;
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Public Class Members
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the AffiliationLookup class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Name of lookup table.</param>
|
||||||
|
/// <param name="verbose">Flag indicating whether verbose logging is enabled.</param>
|
||||||
|
AffiliationLookup::AffiliationLookup(const char* name, bool verbose) :
|
||||||
|
m_rfChTable(),
|
||||||
|
m_rfGrantChCnt(0U),
|
||||||
|
m_unitRegTable(),
|
||||||
|
m_grpAffTable(),
|
||||||
|
m_grantChTable(),
|
||||||
|
m_grantTimers(),
|
||||||
|
m_name(name),
|
||||||
|
m_verbose(verbose)
|
||||||
|
{
|
||||||
|
m_rfChTable.clear();
|
||||||
|
|
||||||
|
m_unitRegTable.clear();
|
||||||
|
m_grpAffTable.clear();
|
||||||
|
|
||||||
|
m_grantChTable.clear();
|
||||||
|
m_grantTimers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Finalizes a instance of the AffiliationLookup class.
|
||||||
|
/// </summary>
|
||||||
|
AffiliationLookup::~AffiliationLookup()
|
||||||
|
{
|
||||||
|
/* stub */
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper to group affiliate a source ID.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="srcId"></param>
|
||||||
|
void AffiliationLookup::unitReg(uint32_t srcId)
|
||||||
|
{
|
||||||
|
m_unitRegTable.push_back(srcId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper to group unaffiliate a source ID.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="srcId"></param>
|
||||||
|
bool AffiliationLookup::unitDereg(uint32_t srcId)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
|
||||||
|
groupUnaff(srcId);
|
||||||
|
|
||||||
|
// remove dynamic unit registration table entry
|
||||||
|
if (std::find(m_unitRegTable.begin(), m_unitRegTable.end(), srcId) != m_unitRegTable.end()) {
|
||||||
|
auto it = std::find(m_unitRegTable.begin(), m_unitRegTable.end(), srcId);
|
||||||
|
m_unitRegTable.erase(it);
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper to determine if the source ID has unit registered.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="srcId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool AffiliationLookup::isUnitReg(uint32_t srcId) const
|
||||||
|
{
|
||||||
|
// lookup dynamic unit registration table entry
|
||||||
|
if (std::find(m_unitRegTable.begin(), m_unitRegTable.end(), srcId) != m_unitRegTable.end()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper to group affiliate a source ID.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="srcId"></param>
|
||||||
|
/// <param name="dstId"></param>
|
||||||
|
void AffiliationLookup::groupAff(uint32_t srcId, uint32_t dstId)
|
||||||
|
{
|
||||||
|
// update dynamic affiliation table
|
||||||
|
m_grpAffTable[srcId] = dstId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper to group unaffiliate a source ID.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="srcId"></param>
|
||||||
|
bool AffiliationLookup::groupUnaff(uint32_t srcId)
|
||||||
|
{
|
||||||
|
// remove dynamic affiliation table entry
|
||||||
|
try {
|
||||||
|
m_grpAffTable.at(srcId);
|
||||||
|
m_grpAffTable.erase(srcId);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper to determine if the source ID has affiliated to the group destination ID.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="srcId"></param>
|
||||||
|
/// <param name="dstId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool AffiliationLookup::isGroupAff(uint32_t srcId, uint32_t dstId) const
|
||||||
|
{
|
||||||
|
// lookup dynamic affiliation table entry
|
||||||
|
try {
|
||||||
|
uint32_t tblDstId = m_grpAffTable.at(srcId);
|
||||||
|
if (tblDstId == dstId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (...) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper to release group affiliations.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dstId"></param>
|
||||||
|
/// <param name="releaseAll"></param>
|
||||||
|
std::vector<uint32_t> AffiliationLookup::clearGroupAff(uint32_t dstId, bool releaseAll)
|
||||||
|
{
|
||||||
|
std::vector<uint32_t> srcToRel = std::vector<uint32_t>();
|
||||||
|
if (dstId == 0U && !releaseAll) {
|
||||||
|
return srcToRel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dstId == 0U && releaseAll) {
|
||||||
|
LogWarning(LOG_HOST, "%s, releasing all group affiliations", m_name);
|
||||||
|
for (auto it = m_grpAffTable.begin(); it != m_grpAffTable.end(); ++it) {
|
||||||
|
uint32_t srcId = it->first;
|
||||||
|
srcToRel.push_back(srcId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LogWarning(LOG_HOST, "%s, releasing group affiliations, dstId = %u", m_name, dstId);
|
||||||
|
for (auto it = m_grpAffTable.begin(); it != m_grpAffTable.end(); ++it) {
|
||||||
|
uint32_t srcId = it->first;
|
||||||
|
uint32_t grpId = it->second;
|
||||||
|
if (grpId == dstId) {
|
||||||
|
srcToRel.push_back(srcId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return srcToRel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper to grant a channel.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dstId"></param>
|
||||||
|
/// <param name="grantTimeout"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool AffiliationLookup::grantCh(uint32_t dstId, uint32_t grantTimeout)
|
||||||
|
{
|
||||||
|
if (dstId == 0U) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isRFChAvailable()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t chNo = m_rfChTable.at(0);
|
||||||
|
auto it = std::find(m_rfChTable.begin(), m_rfChTable.end(), chNo);
|
||||||
|
m_rfChTable.erase(it);
|
||||||
|
|
||||||
|
m_grantChTable[dstId] = chNo;
|
||||||
|
m_rfGrantChCnt++;
|
||||||
|
|
||||||
|
m_grantTimers[dstId] = Timer(1000U, grantTimeout);
|
||||||
|
m_grantTimers[dstId].start();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper to start the destination ID grant timer.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dstId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
void AffiliationLookup::touchGrant(uint32_t dstId)
|
||||||
|
{
|
||||||
|
if (dstId == 0U) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isGranted(dstId)) {
|
||||||
|
m_grantTimers[dstId].start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper to release the channel grant for the destination ID.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dstId"></param>
|
||||||
|
/// <param name="releaseAll"></param>
|
||||||
|
bool AffiliationLookup::releaseGrant(uint32_t dstId, bool releaseAll)
|
||||||
|
{
|
||||||
|
if (dstId == 0U && !releaseAll) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// are we trying to release all grants?
|
||||||
|
if (dstId == 0U && releaseAll) {
|
||||||
|
LogWarning(LOG_HOST, "%s, force releasing all channel grants", m_name);
|
||||||
|
|
||||||
|
std::vector<uint32_t> gntsToRel = std::vector<uint32_t>();
|
||||||
|
for (auto it = m_grantChTable.begin(); it != m_grantChTable.end(); ++it) {
|
||||||
|
uint32_t dstId = it->first;
|
||||||
|
gntsToRel.push_back(dstId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// release grants
|
||||||
|
for (auto it = gntsToRel.begin(); it != gntsToRel.end(); ++it) {
|
||||||
|
releaseGrant(*it, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isGranted(dstId)) {
|
||||||
|
uint32_t chNo = m_grantChTable.at(dstId);
|
||||||
|
|
||||||
|
if (m_verbose) {
|
||||||
|
LogMessage(LOG_HOST, "%s, releasing channel grant, chNo = %u, dstId = %u",
|
||||||
|
m_name, chNo, dstId);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_grantChTable[dstId] = 0U;
|
||||||
|
m_rfChTable.push_back(chNo);
|
||||||
|
|
||||||
|
if (m_rfGrantChCnt > 0U) {
|
||||||
|
m_rfGrantChCnt--;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_rfGrantChCnt = 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_grantTimers[dstId].stop();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper to determine if the channel number is busy.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="chNo"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool AffiliationLookup::isChBusy(uint32_t chNo) const
|
||||||
|
{
|
||||||
|
if (chNo == 0U) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// lookup dynamic channel grant table entry
|
||||||
|
for (auto it = m_grantChTable.begin(); it != m_grantChTable.end(); ++it) {
|
||||||
|
if (it->second == chNo) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper to determine if the destination ID is already granted.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dstId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool AffiliationLookup::isGranted(uint32_t dstId) const
|
||||||
|
{
|
||||||
|
if (dstId == 0U) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// lookup dynamic channel grant table entry
|
||||||
|
try {
|
||||||
|
uint32_t chNo = m_grantChTable.at(dstId);
|
||||||
|
if (chNo != 0U) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (...) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper to get the channel granted for the given destination ID.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dstId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
uint32_t AffiliationLookup::getGrantedCh(uint32_t dstId)
|
||||||
|
{
|
||||||
|
if (dstId == 0U) {
|
||||||
|
return 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isGranted(dstId)) {
|
||||||
|
return m_grantChTable[dstId];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the processor by the passed number of milliseconds.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ms"></param>
|
||||||
|
void AffiliationLookup::clock(uint32_t ms)
|
||||||
|
{
|
||||||
|
// clock all the grant timers
|
||||||
|
std::vector<uint32_t> gntsToRel = std::vector<uint32_t>();
|
||||||
|
for (auto it = m_grantChTable.begin(); it != m_grantChTable.end(); ++it) {
|
||||||
|
uint32_t dstId = it->first;
|
||||||
|
|
||||||
|
m_grantTimers[dstId].clock(ms);
|
||||||
|
if (m_grantTimers[dstId].isRunning() && m_grantTimers[dstId].hasExpired()) {
|
||||||
|
gntsToRel.push_back(dstId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// release grants that have timed out
|
||||||
|
for (auto it = gntsToRel.begin(); it != gntsToRel.end(); ++it) {
|
||||||
|
releaseGrant(*it, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,123 @@
|
|||||||
|
/**
|
||||||
|
* Digital Voice Modem - Host Software
|
||||||
|
* GPLv2 Open Source. Use is subject to license terms.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* @package DVM / Host Software
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2022 by Bryan Biedenkapp N2PLL
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
#if !defined(__AFFILIATION_LOOKUP_H__)
|
||||||
|
#define __AFFILIATION_LOOKUP_H__
|
||||||
|
|
||||||
|
#include "Defines.h"
|
||||||
|
#include "Timer.h"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace lookups
|
||||||
|
{
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Class Declaration
|
||||||
|
// Implements a lookup table class that contains subscriber registration
|
||||||
|
// and group affiliation information.
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class HOST_SW_API AffiliationLookup {
|
||||||
|
public:
|
||||||
|
/// <summary>Initializes a new instance of the AffiliationLookup class.</summary>
|
||||||
|
AffiliationLookup(const char* name, bool verbose);
|
||||||
|
/// <summary>Finalizes a instance of the AffiliationLookup class.</summary>
|
||||||
|
virtual ~AffiliationLookup();
|
||||||
|
|
||||||
|
/// <summary>Gets the count of unit registrations.</summary>
|
||||||
|
uint8_t unitRegSize() const { return m_unitRegTable.size(); }
|
||||||
|
/// <summary>Gets the unit registration table.</summary>
|
||||||
|
std::vector<uint32_t> unitRegTable() const { return m_unitRegTable; }
|
||||||
|
/// <summary>Helper to register a source ID.</summary>
|
||||||
|
virtual void unitReg(uint32_t srcId);
|
||||||
|
/// <summary>Helper to deregister a source ID.</summary>
|
||||||
|
virtual bool unitDereg(uint32_t srcId);
|
||||||
|
/// <summary>Helper to determine if the source ID has unit registered.</summary>
|
||||||
|
virtual bool isUnitReg(uint32_t srcId) const;
|
||||||
|
|
||||||
|
/// <summary>Gets the count of affiliations.</summary>
|
||||||
|
uint8_t grpAffSize() const { return m_grpAffTable.size(); }
|
||||||
|
/// <summary>Gets the group affiliation table.</summary>
|
||||||
|
std::unordered_map<uint32_t, uint32_t> grpAffTable() const { return m_grpAffTable; }
|
||||||
|
/// <summary>Helper to group affiliate a source ID.</summary>
|
||||||
|
virtual void groupAff(uint32_t srcId, uint32_t dstId);
|
||||||
|
/// <summary>Helper to group unaffiliate a source ID.</summary>
|
||||||
|
virtual bool groupUnaff(uint32_t srcId);
|
||||||
|
/// <summary>Helper to determine if the source ID has affiliated to the group destination ID.</summary>
|
||||||
|
virtual bool isGroupAff(uint32_t srcId, uint32_t dstId) const;
|
||||||
|
/// <summary>Helper to release group affiliations.</summary>
|
||||||
|
virtual std::vector<uint32_t> clearGroupAff(uint32_t dstId, bool releaseAll);
|
||||||
|
|
||||||
|
/// <summary>Gets the count of grants.</summary>
|
||||||
|
uint8_t grantSize() const { return m_grantChTable.size(); }
|
||||||
|
/// <summary>Gets the grant table.</summary>
|
||||||
|
std::unordered_map<uint32_t, uint32_t> grantTable() const { return m_grantChTable; }
|
||||||
|
/// <summary>Helper to grant a channel.</summary>
|
||||||
|
virtual bool grantCh(uint32_t dstId, uint32_t grantTimeout);
|
||||||
|
/// <summary>Helper to start the destination ID grant timer.</summary>
|
||||||
|
virtual void touchGrant(uint32_t dstId);
|
||||||
|
/// <summary>Helper to release the channel grant for the destination ID.</summary>
|
||||||
|
virtual bool releaseGrant(uint32_t dstId, bool releaseAll);
|
||||||
|
/// <summary>Helper to determine if the channel number is busy.</summary>
|
||||||
|
virtual bool isChBusy(uint32_t chNo) const;
|
||||||
|
/// <summary>Helper to determine if the destination ID is already granted.</summary>
|
||||||
|
virtual bool isGranted(uint32_t dstId) const;
|
||||||
|
/// <summary>Helper to get the channel granted for the given destination ID.</summary>
|
||||||
|
virtual uint32_t getGrantedCh(uint32_t dstId);
|
||||||
|
|
||||||
|
/// <summary>Helper to add a RF channel.</summary>
|
||||||
|
void addRFCh(uint32_t chNo) { m_rfChTable.push_back(chNo); }
|
||||||
|
/// <summary>Helper to remove a RF channel.</summary>
|
||||||
|
void removeRFCh(uint32_t chNo) { m_rfChTable.push_back(chNo); }
|
||||||
|
/// <summary>Gets the count of RF channels.</summary>
|
||||||
|
uint8_t getRFChCnt() const { return m_rfChTable.size(); }
|
||||||
|
/// <summary>Helper to determine if there are any RF channels available..</summary>
|
||||||
|
bool isRFChAvailable() const { return !m_rfChTable.empty(); }
|
||||||
|
/// <summary>Gets the count of granted RF channels.</summary>
|
||||||
|
uint8_t getGrantedRFChCnt() const { return m_rfGrantChCnt; }
|
||||||
|
|
||||||
|
/// <summary>Updates the processor by the passed number of milliseconds.</summary>
|
||||||
|
void clock(uint32_t ms);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector<uint32_t> m_rfChTable;
|
||||||
|
uint8_t m_rfGrantChCnt;
|
||||||
|
|
||||||
|
std::vector<uint32_t> m_unitRegTable;
|
||||||
|
std::unordered_map<uint32_t, uint32_t> m_grpAffTable;
|
||||||
|
|
||||||
|
std::unordered_map<uint32_t, uint32_t> m_grantChTable;
|
||||||
|
std::unordered_map<uint32_t, Timer> m_grantTimers;
|
||||||
|
|
||||||
|
const char *m_name;
|
||||||
|
|
||||||
|
bool m_verbose;
|
||||||
|
};
|
||||||
|
} // namespace lookups
|
||||||
|
|
||||||
|
#endif // __AFFILIATION_LOOKUP_H__
|
||||||
@ -0,0 +1,97 @@
|
|||||||
|
/**
|
||||||
|
* Digital Voice Modem - Host Software
|
||||||
|
* GPLv2 Open Source. Use is subject to license terms.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* @package DVM / Host Software
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2022 by Bryan Biedenkapp N2PLL
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
#include "p25/lookups/P25AffiliationLookup.h"
|
||||||
|
#include "p25/packet/Trunk.h"
|
||||||
|
#include "p25/Control.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
using namespace p25::lookups;
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Public Class Members
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the P25AffiliationLookup class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Name of lookup table.</param>
|
||||||
|
/// <param name="verbose">Flag indicating whether verbose logging is enabled.</param>
|
||||||
|
P25AffiliationLookup::P25AffiliationLookup(Control* p25, bool verbose) : ::lookups::AffiliationLookup("P25 Aff", verbose),
|
||||||
|
m_p25(p25)
|
||||||
|
{
|
||||||
|
/* stub */
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Finalizes a instance of the P25AffiliationLookup class.
|
||||||
|
/// </summary>
|
||||||
|
P25AffiliationLookup::~P25AffiliationLookup()
|
||||||
|
{
|
||||||
|
/* stub */
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper to release the channel grant for the destination ID.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dstId"></param>
|
||||||
|
/// <param name="releaseAll"></param>
|
||||||
|
bool P25AffiliationLookup::releaseGrant(uint32_t dstId, bool releaseAll)
|
||||||
|
{
|
||||||
|
bool ret = ::lookups::AffiliationLookup::releaseGrant(dstId, releaseAll);
|
||||||
|
if (ret) {
|
||||||
|
if (m_rfGrantChCnt > 0U) {
|
||||||
|
m_p25->m_siteData.setChCnt(getRFChCnt() + m_rfGrantChCnt);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_p25->m_siteData.setChCnt(getRFChCnt());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper to release group affiliations.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dstId"></param>
|
||||||
|
/// <param name="releaseAll"></param>
|
||||||
|
std::vector<uint32_t> P25AffiliationLookup::clearGroupAff(uint32_t dstId, bool releaseAll)
|
||||||
|
{
|
||||||
|
std::vector<uint32_t> srcToRel = ::lookups::AffiliationLookup::clearGroupAff(dstId, releaseAll);
|
||||||
|
if (srcToRel.size() > 0U) {
|
||||||
|
// release affiliations
|
||||||
|
for (auto it = srcToRel.begin(); it != srcToRel.end(); ++it) {
|
||||||
|
m_p25->m_trunk->writeRF_TSDU_U_Dereg_Ack(*it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return srcToRel;
|
||||||
|
}
|
||||||
@ -0,0 +1,66 @@
|
|||||||
|
/**
|
||||||
|
* Digital Voice Modem - Host Software
|
||||||
|
* GPLv2 Open Source. Use is subject to license terms.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* @package DVM / Host Software
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2022 by Bryan Biedenkapp N2PLL
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
#if !defined(__P25_AFFILIATION_LOOKUP_H__)
|
||||||
|
#define __P25_AFFILIATION_LOOKUP_H__
|
||||||
|
|
||||||
|
#include "Defines.h"
|
||||||
|
#include "lookups/AffiliationLookup.h"
|
||||||
|
|
||||||
|
namespace p25
|
||||||
|
{
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Class Prototypes
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class HOST_SW_API Control;
|
||||||
|
|
||||||
|
namespace lookups
|
||||||
|
{
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Class Declaration
|
||||||
|
// Implements a lookup table class that contains subscriber registration
|
||||||
|
// and group affiliation information.
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class HOST_SW_API P25AffiliationLookup : public ::lookups::AffiliationLookup {
|
||||||
|
public:
|
||||||
|
/// <summary>Initializes a new instance of the P25AffiliationLookup class.</summary>
|
||||||
|
P25AffiliationLookup(Control* p25, bool verbose);
|
||||||
|
/// <summary>Finalizes a instance of the P25AffiliationLookup class.</summary>
|
||||||
|
virtual ~P25AffiliationLookup();
|
||||||
|
|
||||||
|
/// <summary>Helper to release the channel grant for the destination ID.</summary>
|
||||||
|
virtual bool releaseGrant(uint32_t dstId, bool releaseAll);
|
||||||
|
/// <summary>Helper to release group affiliations.</summary>
|
||||||
|
virtual std::vector<uint32_t> clearGroupAff(uint32_t dstId, bool releaseAll);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Control* m_p25;
|
||||||
|
};
|
||||||
|
} // namespace lookups
|
||||||
|
} // namespace p25
|
||||||
|
|
||||||
|
#endif // __P25_AFFILIATION_LOOKUP_H__
|
||||||
Loading…
Reference in new issue