refactor quick-and-dirty table entry check to a more proper unordered_map find; implement new REST API to return the current affiliations; correct instance where a affiliation response would be sent across the network for denied/rejected affiliations (this would result in the FNE2 for example erroneously adding affiliation entries to its internal tables);

pull/41/head
Bryan Biedenkapp 2 years ago
parent abb57affe2
commit a09338f57d

@ -499,7 +499,6 @@ dmr::lookups::DMRAffiliationLookup Control::affiliations()
return m_slot1->m_affiliations; return m_slot1->m_affiliations;
case 2U: case 2U:
return m_slot2->m_affiliations; return m_slot2->m_affiliations;
break;
default: default:
LogError(LOG_DMR, "DMR, invalid slot, slotNo = %u", m_tsccSlotNo); LogError(LOG_DMR, "DMR, invalid slot, slotNo = %u", m_tsccSlotNo);
break; break;

@ -161,13 +161,14 @@ void AffiliationLookup::groupAff(uint32_t srcId, uint32_t dstId)
bool AffiliationLookup::groupUnaff(uint32_t srcId) bool AffiliationLookup::groupUnaff(uint32_t srcId)
{ {
// lookup dynamic affiliation table entry // lookup dynamic affiliation table entry
try { auto entry = m_grpAffTable.find(srcId);
if (entry != m_grpAffTable.end()) {
uint32_t tblDstId = m_grpAffTable.at(srcId); uint32_t tblDstId = m_grpAffTable.at(srcId);
if (m_verbose) { if (m_verbose) {
LogMessage(LOG_HOST, "%s, group unaffiliation, srcId = %u, dstId = %u", LogMessage(LOG_HOST, "%s, group unaffiliation, srcId = %u, dstId = %u",
m_name, srcId, tblDstId); m_name, srcId, tblDstId);
} }
} catch (...) { } else {
return false; return false;
} }
@ -191,7 +192,8 @@ bool AffiliationLookup::groupUnaff(uint32_t srcId)
bool AffiliationLookup::isGroupAff(uint32_t srcId, uint32_t dstId) const bool AffiliationLookup::isGroupAff(uint32_t srcId, uint32_t dstId) const
{ {
// lookup dynamic affiliation table entry // lookup dynamic affiliation table entry
try { auto entry = m_grpAffTable.find(srcId);
if (entry != m_grpAffTable.end()) {
uint32_t tblDstId = m_grpAffTable.at(srcId); uint32_t tblDstId = m_grpAffTable.at(srcId);
if (tblDstId == dstId) { if (tblDstId == dstId) {
return true; return true;
@ -199,9 +201,9 @@ bool AffiliationLookup::isGroupAff(uint32_t srcId, uint32_t dstId) const
else { else {
return false; return false;
} }
} catch (...) {
return false;
} }
return false;
} }
/// <summary> /// <summary>

@ -54,6 +54,7 @@ using namespace modem;
#include <memory> #include <memory>
#include <stdexcept> #include <stdexcept>
#include <unordered_map>
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Macros // 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_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_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 ** Digital Mobile Radio
*/ */
@ -1475,6 +1478,87 @@ void RESTAPI::restAPI_GetRIDBlacklist(const HTTPPayload& request, HTTPPayload& r
} }
} }
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <param name="reply"></param>
/// <param name="match"></param>
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<uint32_t, uint32_t> globalAffTable = std::unordered_map<uint32_t, uint32_t>();
#if defined(ENABLE_DMR)
if (m_dmr != nullptr) {
std::unordered_map<uint32_t, uint32_t> 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<uint32_t, uint32_t> 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<uint32_t, uint32_t> 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<uint32_t>(srcId);
aff["grpId"].set<uint32_t>(grpId);
affs.push_back(json::value(aff));
}
}
response["affiliations"].set<json::array>(affs);
reply.payload(response);
}
/* /*
** Digital Mobile Radio ** Digital Mobile Radio
*/ */

@ -143,6 +143,9 @@ private:
/// <summary></summary> /// <summary></summary>
void restAPI_GetRIDBlacklist(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match); void restAPI_GetRIDBlacklist(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
/// <summary></summary>
void restAPI_GetAffList(const HTTPPayload& request, HTTPPayload& reply, const network::rest::RequestMatch& match);
/* /*
** Digital Mobile Radio ** Digital Mobile Radio
*/ */

@ -72,6 +72,8 @@
#define GET_RID_BLACKLIST_BASE "/rid-blacklist/" #define GET_RID_BLACKLIST_BASE "/rid-blacklist/"
#define GET_RID_BLACKLIST GET_RID_BLACKLIST_BASE"(\\d+)" #define GET_RID_BLACKLIST GET_RID_BLACKLIST_BASE"(\\d+)"
#define GET_AFF_LIST "/affs"
#define GET_DMR_BEACON "/dmr/beacon" #define GET_DMR_BEACON "/dmr/beacon"
#define GET_DMR_DEBUG_BASE "/dmr/debug/" #define GET_DMR_DEBUG_BASE "/dmr/debug/"
#define GET_DMR_DEBUG GET_DMR_DEBUG_BASE"(\\d+)/(\\d+)" #define GET_DMR_DEBUG GET_DMR_DEBUG_BASE"(\\d+)/(\\d+)"

@ -2561,11 +2561,14 @@ bool ControlSignaling::writeRF_TSDU_Grp_Aff_Rsp(uint32_t srcId, uint32_t dstId)
iosp->setDstId(dstId); iosp->setDstId(dstId);
iosp->setResponse(P25_RSP_ACCEPT); iosp->setResponse(P25_RSP_ACCEPT);
bool noNet = false;
// validate the source RID // validate the source RID
if (!acl::AccessControl::validateSrcId(srcId)) { if (!acl::AccessControl::validateSrcId(srcId)) {
LogWarning(LOG_RF, P25_TSDU_STR ", %s denial, RID rejection, srcId = %u", iosp->toString().c_str(), 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); ::ActivityLog("P25", true, "group affiliation request from %u to %s %u denied", srcId, "TG ", dstId);
iosp->setResponse(P25_RSP_REFUSED); iosp->setResponse(P25_RSP_REFUSED);
noNet = true;
} }
// validate the source RID is registered // 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); 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); ::ActivityLog("P25", true, "group affiliation request from %u to %s %u denied", srcId, "TG ", dstId);
iosp->setResponse(P25_RSP_REFUSED); iosp->setResponse(P25_RSP_REFUSED);
noNet = true;
} }
// validate the talkgroup ID // 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); 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); ::ActivityLog("P25", true, "group affiliation request from %u to %s %u denied", srcId, "TG ", dstId);
iosp->setResponse(P25_RSP_DENY); 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); m_p25->m_affiliations.groupAff(srcId, dstId);
} }
writeRF_TSDU_SBF_Imm(iosp.get(), false); writeRF_TSDU_SBF_Imm(iosp.get(), noNet);
return ret; return ret;
} }

@ -74,6 +74,8 @@
#define RCD_RELEASE_AFFS "rel-affs" #define RCD_RELEASE_AFFS "rel-affs"
#define RCD_RELEASE_AFF "rel-aff" #define RCD_RELEASE_AFF "rel-aff"
#define RCD_GET_AFFS "affs"
#define RCD_DMR_BEACON "dmr-beacon" #define RCD_DMR_BEACON "dmr-beacon"
#define RCD_P25_CC "p25-cc" #define RCD_P25_CC "p25-cc"
#define RCD_P25_CC_FALLBACK "p25-cc-fallback" #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-grnts Forcibly releases all channel grants\r\n";
reply += " rel-affs Forcibly releases all group affiliations\r\n"; reply += " rel-affs Forcibly releases all group affiliations\r\n";
reply += " rel-aff <state> <dstid> Forcibly releases specified group affiliations\r\n"; reply += " rel-aff <state> <dstid> Forcibly releases specified group affiliations\r\n";
reply += " affs Retrieves the list of currently affiliated SUs\r\n";
reply += "\r\n"; reply += "\r\n";
reply += " dmr-beacon Transmits a DMR beacon burst\r\n"; reply += " dmr-beacon Transmits a DMR beacon burst\r\n";
reply += " p25-cc Transmits a non-continous P25 CC 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); 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 ** Digital Mobile Radio

Loading…
Cancel
Save

Powered by TurnKey Linux.