diff --git a/src/dmr/Control.cpp b/src/dmr/Control.cpp index d263a436..afa15ab6 100644 --- a/src/dmr/Control.cpp +++ b/src/dmr/Control.cpp @@ -499,7 +499,6 @@ dmr::lookups::DMRAffiliationLookup Control::affiliations() return m_slot1->m_affiliations; case 2U: return m_slot2->m_affiliations; - break; default: LogError(LOG_DMR, "DMR, invalid slot, slotNo = %u", m_tsccSlotNo); break; diff --git a/src/lookups/AffiliationLookup.cpp b/src/lookups/AffiliationLookup.cpp index bc53f5cf..b31f489b 100644 --- a/src/lookups/AffiliationLookup.cpp +++ b/src/lookups/AffiliationLookup.cpp @@ -161,13 +161,14 @@ void AffiliationLookup::groupAff(uint32_t srcId, uint32_t dstId) bool AffiliationLookup::groupUnaff(uint32_t srcId) { // lookup dynamic affiliation table entry - try { + auto entry = m_grpAffTable.find(srcId); + if (entry != m_grpAffTable.end()) { uint32_t tblDstId = m_grpAffTable.at(srcId); if (m_verbose) { LogMessage(LOG_HOST, "%s, group unaffiliation, srcId = %u, dstId = %u", m_name, srcId, tblDstId); } - } catch (...) { + } else { return false; } @@ -191,7 +192,8 @@ bool AffiliationLookup::groupUnaff(uint32_t srcId) bool AffiliationLookup::isGroupAff(uint32_t srcId, uint32_t dstId) const { // lookup dynamic affiliation table entry - try { + auto entry = m_grpAffTable.find(srcId); + if (entry != m_grpAffTable.end()) { uint32_t tblDstId = m_grpAffTable.at(srcId); if (tblDstId == dstId) { return true; @@ -199,9 +201,9 @@ bool AffiliationLookup::isGroupAff(uint32_t srcId, uint32_t dstId) const else { return false; } - } catch (...) { - return false; } + + return false; } /// diff --git a/src/network/RESTAPI.cpp b/src/network/RESTAPI.cpp index b2c19737..0d69e4d5 100644 --- a/src/network/RESTAPI.cpp +++ b/src/network/RESTAPI.cpp @@ -54,6 +54,7 @@ using namespace modem; #include #include +#include // --------------------------------------------------------------------------- // Macros @@ -288,6 +289,8 @@ void RESTAPI::initializeEndpoints() m_dispatcher.match(GET_RID_WHITELIST, true).get(REST_API_BIND(RESTAPI::restAPI_GetRIDWhitelist, this)); m_dispatcher.match(GET_RID_BLACKLIST, true).get(REST_API_BIND(RESTAPI::restAPI_GetRIDBlacklist, this)); + m_dispatcher.match(GET_AFF_LIST).get(REST_API_BIND(RESTAPI::restAPI_GetAffList, this)); + /* ** Digital Mobile Radio */ @@ -1475,6 +1478,87 @@ void RESTAPI::restAPI_GetRIDBlacklist(const HTTPPayload& request, HTTPPayload& r } } +/// +/// +/// +/// +/// +/// +void RESTAPI::restAPI_GetAffList(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match) +{ + if (!validateAuth(request, reply)) { + return; + } + + json::object response = json::object(); + setResponseDefaultStatus(response); + + std::unordered_map globalAffTable = std::unordered_map(); + +#if defined(ENABLE_DMR) + if (m_dmr != nullptr) { + std::unordered_map affTable = m_dmr->affiliations().grpAffTable(); + for (auto entry : affTable) { + uint32_t srcId = entry.first; + uint32_t grpId = entry.second; + + // did we already catalog this affiliation? + auto globEntry = globalAffTable.find(srcId); + if (globEntry == globalAffTable.end()) { + globalAffTable[srcId] = grpId; + } + } + } +#endif // defined(ENABLE_DMR) +#if defined(ENABLE_P25) + if (m_p25 != nullptr) { + std::unordered_map affTable = m_p25->affiliations().grpAffTable(); + for (auto entry : affTable) { + uint32_t srcId = entry.first; + uint32_t grpId = entry.second; + + // did we already catalog this affiliation? + auto globEntry = globalAffTable.find(srcId); + if (globEntry == globalAffTable.end()) { + globalAffTable[srcId] = grpId; + } + } + } +#endif // defined(ENABLE_P25) +#if defined(ENABLE_NXDN) + if (m_nxdn != nullptr) { + std::unordered_map affTable = m_nxdn->affiliations().grpAffTable(); + for (auto entry : affTable) { + uint32_t srcId = entry.first; + uint32_t grpId = entry.second; + + // did we already catalog this affiliation? + auto globEntry = globalAffTable.find(srcId); + if (globEntry == globalAffTable.end()) { + globalAffTable[srcId] = grpId; + } + } + } +#endif // defined(ENABLE_NXDN) + + json::array affs = json::array(); + if (globalAffTable.size() > 0) { + for (auto entry : globalAffTable) { + uint32_t srcId = entry.first; + uint32_t grpId = entry.second; + + json::object aff = json::object(); + aff["srcId"].set(srcId); + aff["grpId"].set(grpId); + + affs.push_back(json::value(aff)); + } + } + + response["affiliations"].set(affs); + reply.payload(response); +} + /* ** Digital Mobile Radio */ diff --git a/src/network/RESTAPI.h b/src/network/RESTAPI.h index ffda3984..43b5b8de 100644 --- a/src/network/RESTAPI.h +++ b/src/network/RESTAPI.h @@ -143,6 +143,9 @@ private: /// void restAPI_GetRIDBlacklist(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match); + /// + void restAPI_GetAffList(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match); + /* ** Digital Mobile Radio */ diff --git a/src/network/RESTDefines.h b/src/network/RESTDefines.h index 2e3e9349..5bbb6e14 100644 --- a/src/network/RESTDefines.h +++ b/src/network/RESTDefines.h @@ -72,6 +72,8 @@ #define GET_RID_BLACKLIST_BASE "/rid-blacklist/" #define GET_RID_BLACKLIST GET_RID_BLACKLIST_BASE"(\\d+)" +#define GET_AFF_LIST "/affs" + #define GET_DMR_BEACON "/dmr/beacon" #define GET_DMR_DEBUG_BASE "/dmr/debug/" #define GET_DMR_DEBUG GET_DMR_DEBUG_BASE"(\\d+)/(\\d+)" diff --git a/src/p25/packet/ControlSignaling.cpp b/src/p25/packet/ControlSignaling.cpp index d2c77285..a0e08ade 100644 --- a/src/p25/packet/ControlSignaling.cpp +++ b/src/p25/packet/ControlSignaling.cpp @@ -2561,11 +2561,14 @@ bool ControlSignaling::writeRF_TSDU_Grp_Aff_Rsp(uint32_t srcId, uint32_t dstId) iosp->setDstId(dstId); iosp->setResponse(P25_RSP_ACCEPT); + bool noNet = false; + // validate the source RID if (!acl::AccessControl::validateSrcId(srcId)) { LogWarning(LOG_RF, P25_TSDU_STR ", %s denial, RID rejection, srcId = %u", iosp->toString().c_str(), srcId); ::ActivityLog("P25", true, "group affiliation request from %u to %s %u denied", srcId, "TG ", dstId); iosp->setResponse(P25_RSP_REFUSED); + noNet = true; } // validate the source RID is registered @@ -2573,6 +2576,7 @@ bool ControlSignaling::writeRF_TSDU_Grp_Aff_Rsp(uint32_t srcId, uint32_t dstId) LogWarning(LOG_RF, P25_TSDU_STR ", %s denial, RID not registered, srcId = %u", iosp->toString().c_str(), srcId); ::ActivityLog("P25", true, "group affiliation request from %u to %s %u denied", srcId, "TG ", dstId); iosp->setResponse(P25_RSP_REFUSED); + noNet = true; } // validate the talkgroup ID @@ -2584,6 +2588,7 @@ bool ControlSignaling::writeRF_TSDU_Grp_Aff_Rsp(uint32_t srcId, uint32_t dstId) LogWarning(LOG_RF, P25_TSDU_STR ", %s denial, TGID rejection, dstId = %u", iosp->toString().c_str(), dstId); ::ActivityLog("P25", true, "group affiliation request from %u to %s %u denied", srcId, "TG ", dstId); iosp->setResponse(P25_RSP_DENY); + noNet = true; } } @@ -2600,7 +2605,7 @@ bool ControlSignaling::writeRF_TSDU_Grp_Aff_Rsp(uint32_t srcId, uint32_t dstId) m_p25->m_affiliations.groupAff(srcId, dstId); } - writeRF_TSDU_SBF_Imm(iosp.get(), false); + writeRF_TSDU_SBF_Imm(iosp.get(), noNet); return ret; } diff --git a/src/remote/RESTClientMain.cpp b/src/remote/RESTClientMain.cpp index a2beaf63..c1e24426 100644 --- a/src/remote/RESTClientMain.cpp +++ b/src/remote/RESTClientMain.cpp @@ -74,6 +74,8 @@ #define RCD_RELEASE_AFFS "rel-affs" #define RCD_RELEASE_AFF "rel-aff" +#define RCD_GET_AFFS "affs" + #define RCD_DMR_BEACON "dmr-beacon" #define RCD_P25_CC "p25-cc" #define RCD_P25_CC_FALLBACK "p25-cc-fallback" @@ -199,6 +201,7 @@ void usage(const char* message, const char* arg) reply += " rel-grnts Forcibly releases all channel grants\r\n"; reply += " rel-affs Forcibly releases all group affiliations\r\n"; reply += " rel-aff Forcibly releases specified group affiliations\r\n"; + reply += " affs Retrieves the list of currently affiliated SUs\r\n"; reply += "\r\n"; reply += " dmr-beacon Transmits a DMR beacon burst\r\n"; reply += " p25-cc Transmits a non-continous P25 CC burst\r\n"; @@ -515,6 +518,9 @@ int main(int argc, char** argv) retCode = client->send(HTTP_PUT, PUT_RELEASE_TG, req, response); } + else if (rcom == RCD_GET_AFFS) { + retCode = client->send(HTTP_GET, GET_AFF_LIST, json::object(), response); + } /* ** Digital Mobile Radio