diff --git a/configs/talkgroup_rules.example.yml b/configs/talkgroup_rules.example.yml index 73a56508..f7467983 100644 --- a/configs/talkgroup_rules.example.yml +++ b/configs/talkgroup_rules.example.yml @@ -16,6 +16,8 @@ groupVoice: config: # Flag indicating whether this talkgroup is active or not. active: true + # Flag indicating whether this talkgroup will only repeat with affiliations. + affiliated: false # List of peer IDs included for this talkgroup (peers listed here will be selected for traffic). inclusion: [] # List of peer IDs excluded for this talkgroup (peers listed here will be ignored for traffic). @@ -39,6 +41,8 @@ groupVoice: config: # Flag indicating whether this talkgroup is active or not. active: true + # Flag indicating whether this talkgroup will only repeat with affiliations. + affiliated: false # Flag indicating whether or not this talkgroup is a parrot talkgroup. parrot: true # List of peer IDs included for this talkgroup (peers listed here will be selected for traffic). @@ -57,13 +61,15 @@ groupVoice: slot: 1 # Textual name of the talkgroup. - - name: Parrot Mutation Example + - name: Rewrite Example # # Talkgroup Configuration # config: # Flag indicating whether this talkgroup is active or not. active: true + # Flag indicating whether this talkgroup will only repeat with affiliations. + affiliated: false # Flag indicating whether or not this talkgroup is a parrot talkgroup. parrot: true # List of peer IDs included for this talkgroup (peers listed here will be selected for traffic). @@ -83,7 +89,7 @@ groupVoice: # source: # Numerical talkgroup ID number. - tgid: 9990 + tgid: 5 # DMR slot number. slot: 1 @@ -95,6 +101,8 @@ groupVoice: config: # Flag indicating whether this talkgroup is active or not. active: true + # Flag indicating whether this talkgroup will only repeat with affiliations. + affiliated: false # List of peer IDs included for this talkgroup (peers listed here will be selected for traffic). inclusion: [] # List of peer IDs excluded for this talkgroup (peers listed here will be ignored for traffic). @@ -118,6 +126,8 @@ groupVoice: config: # Flag indicating whether this talkgroup is active or not. active: true + # Flag indicating whether this talkgroup will only repeat with affiliations. + affiliated: false # List of peer IDs included for this talkgroup (peers listed here will be selected for traffic). inclusion: [] # List of peer IDs excluded for this talkgroup (peers listed here will be ignored for traffic). @@ -141,6 +151,8 @@ groupVoice: config: # Flag indicating whether this talkgroup is active or not. active: true + # Flag indicating whether this talkgroup will only repeat with affiliations. + affiliated: false # List of peer IDs included for this talkgroup (peers listed here will be selected for traffic). inclusion: [] # List of peer IDs excluded for this talkgroup (peers listed here will be ignored for traffic). diff --git a/src/common/lookups/AffiliationLookup.cpp b/src/common/lookups/AffiliationLookup.cpp index c8e50140..972c639d 100644 --- a/src/common/lookups/AffiliationLookup.cpp +++ b/src/common/lookups/AffiliationLookup.cpp @@ -177,6 +177,23 @@ bool AffiliationLookup::groupUnaff(uint32_t srcId) } } +/// +/// Helper to determine if the group destination ID has any affiations. +/// +/// +/// +/// +bool AffiliationLookup::hasGroupAff(uint32_t dstId) const +{ + for (auto entry : m_grpAffTable) { + if (entry.second == dstId) { + return true; + } + } + + return false; +} + /// /// Helper to determine if the source ID has affiliated to the group destination ID. /// diff --git a/src/common/lookups/AffiliationLookup.h b/src/common/lookups/AffiliationLookup.h index 38494acd..e37f0c3f 100644 --- a/src/common/lookups/AffiliationLookup.h +++ b/src/common/lookups/AffiliationLookup.h @@ -125,6 +125,8 @@ namespace lookups virtual void groupAff(uint32_t srcId, uint32_t dstId); /// Helper to group unaffiliate a source ID. virtual bool groupUnaff(uint32_t srcId); + /// Helper to determine if the group destination ID has any affiations. + virtual bool hasGroupAff(uint32_t dstId) const; /// Helper to determine if the source ID has affiliated to the group destination ID. virtual bool isGroupAff(uint32_t srcId, uint32_t dstId) const; /// Helper to release group affiliations. diff --git a/src/common/lookups/TalkgroupRulesLookup.h b/src/common/lookups/TalkgroupRulesLookup.h index 923823ae..430bf9b8 100644 --- a/src/common/lookups/TalkgroupRulesLookup.h +++ b/src/common/lookups/TalkgroupRulesLookup.h @@ -121,6 +121,7 @@ namespace lookups /// Initializes a new instance of the TalkgroupRuleConfig class. TalkgroupRuleConfig() : m_active(false), + m_affiliated(false), m_parrot(false), m_inclusion(), m_exclusion(), @@ -134,6 +135,7 @@ namespace lookups TalkgroupRuleConfig() { m_active = node["active"].as(false); + m_affiliated = node["affiliated"].as(false); m_parrot = node["parrot"].as(false); yaml::Node& inclusionList = node["inclusion"]; @@ -166,6 +168,7 @@ namespace lookups { if (this != &data) { m_active = data.m_active; + m_affiliated = data.m_affiliated; m_parrot = data.m_parrot; m_inclusion = data.m_inclusion; m_exclusion = data.m_exclusion; @@ -178,6 +181,8 @@ namespace lookups public: /// Flag indicating whether the rule is active. __PROPERTY_PLAIN(bool, active); + /// Flag indicating whether this talkgroup will only repeat with affiliations. + __PROPERTY_PLAIN(bool, affiliated); /// Flag indicating whether or not the talkgroup is a parrot. __PROPERTY_PLAIN(bool, parrot); /// List of peer IDs included by this rule. diff --git a/src/fne/network/fne/TagDMRData.cpp b/src/fne/network/fne/TagDMRData.cpp index 4389df27..2c7b4eb5 100644 --- a/src/fne/network/fne/TagDMRData.cpp +++ b/src/fne/network/fne/TagDMRData.cpp @@ -438,6 +438,15 @@ bool TagDMRData::isPeerPermitted(uint32_t peerId, data::Data& data, uint32_t str } } } + + // is this a TG that requires affiliations to repeat? + if (tg.config().affiliated()) { + // check the affiliations for this peer to see if we can repeat traffic + lookups::AffiliationLookup* aff = m_network->m_peerAffiliations[peerId]; + if (!aff->hasGroupAff(data.getDstId())) { + return false; + } + } } return true; diff --git a/src/fne/network/fne/TagNXDNData.cpp b/src/fne/network/fne/TagNXDNData.cpp index e53d94b2..db63f689 100644 --- a/src/fne/network/fne/TagNXDNData.cpp +++ b/src/fne/network/fne/TagNXDNData.cpp @@ -360,6 +360,15 @@ bool TagNXDNData::isPeerPermitted(uint32_t peerId, lc::RTCH& lc, uint8_t message } } } + + // is this a TG that requires affiliations to repeat? + if (tg.config().affiliated()) { + // check the affiliations for this peer to see if we can repeat traffic + lookups::AffiliationLookup* aff = m_network->m_peerAffiliations[peerId]; + if (!aff->hasGroupAff(lc.getDstId())) { + return false; + } + } } return true; diff --git a/src/fne/network/fne/TagP25Data.cpp b/src/fne/network/fne/TagP25Data.cpp index 9eab1249..d7484234 100644 --- a/src/fne/network/fne/TagP25Data.cpp +++ b/src/fne/network/fne/TagP25Data.cpp @@ -495,6 +495,15 @@ bool TagP25Data::isPeerPermitted(uint32_t peerId, lc::LC& control, uint8_t duid, } } + // is this a TG that requires affiliations to repeat? + if (tg.config().affiliated()) { + // check the affiliations for this peer to see if we can repeat traffic + lookups::AffiliationLookup* aff = m_network->m_peerAffiliations[peerId]; + if (!aff->hasGroupAff(control.getDstId())) { + return false; + } + } + return true; }