bump version to 4.20G (from 4.11G) [THIS MARKS INCLUSION OF IN-CALL CONTROL IN MASTER]; ensure always peers can violate the rules as usual; add permitted RIDs assignment to JSON handling for REST APIs;

pull/86/head
Bryan Biedenkapp 11 months ago
parent 6812029491
commit 0ee2b5c756

@ -108,7 +108,7 @@ typedef unsigned long long ulong64_t;
#define __EXE_NAME__ ""
#define VERSION_MAJOR "04"
#define VERSION_MINOR "11"
#define VERSION_MINOR "20"
#define VERSION_REV "G"
#define __NETVER__ "DVM_R" VERSION_MAJOR VERSION_REV VERSION_MINOR

@ -4,7 +4,7 @@
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2024 Bryan Biedenkapp, N2PLL
* Copyright (C) 2024-2025 Bryan Biedenkapp, N2PLL
* Copyright (C) 2024 Patrick McDonnell, W3AXL
*
*/
@ -222,6 +222,16 @@ json::object tgToJson(const TalkgroupRuleGroupVoice& groupVoice)
}
config["preferred"].set<json::array>(preferreds);
json::array permittedRIDs = json::array();
std::vector<uint32_t> permittedRID = groupVoice.config().permittedRIDs();
if (permittedRID.size() > 0) {
for (auto entry : permittedRID) {
uint32_t rid = entry;
permittedRIDs.push_back(json::value((double)rid));
}
}
config["permittedRids"].set<json::array>(permittedRIDs);
tg["config"].set<json::object>(config);
}
@ -445,6 +455,27 @@ TalkgroupRuleGroupVoice jsonToTG(json::object& req, HTTPPayload& reply)
config.preferred(preferred);
}
if (!configObj["permittedRids"].is<json::array>()) {
errorPayload(reply, "TG configuration \"permittedRids\" was not a valid JSON array");
LogDebug(LOG_REST, "TG configuration \"permittedRids\" was not a valid JSON array");
return TalkgroupRuleGroupVoice();
}
json::array permittedRIDs = configObj["permittedRids"].get<json::array>();
std::vector<uint32_t> permittedRID = groupVoice.config().permittedRIDs();
if (permittedRIDs.size() > 0) {
for (auto entry : permittedRIDs) {
if (!entry.is<uint32_t>()) {
errorPayload(reply, "TG configuration permitted RID value was not a valid number");
LogDebug(LOG_REST, "TG configuration permitted RID value was not a valid number");
return TalkgroupRuleGroupVoice();
}
permittedRID.push_back(entry.get<uint32_t>());
}
config.permittedRIDs(permittedRID);
}
groupVoice.config(config);
}

@ -876,6 +876,16 @@ bool TagDMRData::validate(uint32_t peerId, data::NetData& data, uint32_t streamI
return false;
}
// peer always send list takes priority over any following affiliation rules
bool isAlwaysPeer = false;
std::vector<uint32_t> alwaysSend = tg.config().alwaysSend();
if (alwaysSend.size() > 0) {
auto it = std::find(alwaysSend.begin(), alwaysSend.end(), peerId);
if (it != alwaysSend.end()) {
isAlwaysPeer = true; // skip any following checks and always send traffic
}
}
// check the DMR slot number
if (tg.source().tgSlot() != data.getSlotNo()) {
// report error event to InfluxDB
@ -918,27 +928,30 @@ bool TagDMRData::validate(uint32_t peerId, data::NetData& data, uint32_t streamI
return false;
}
// does the TGID have a permitted RID list?
if (tg.config().permittedRIDs().size() > 0) {
// does the transmitting RID have permission?
std::vector<uint32_t> permittedRIDs = tg.config().permittedRIDs();
if (std::find(permittedRIDs.begin(), permittedRIDs.end(), data.getSrcId()) == permittedRIDs.end()) {
// report error event to InfluxDB
if (m_network->m_enableInfluxDB) {
influxdb::QueryBuilder()
.meas("call_error_event")
.tag("peerId", std::to_string(peerId))
.tag("streamId", std::to_string(streamId))
.tag("srcId", std::to_string(data.getSrcId()))
.tag("dstId", std::to_string(data.getDstId()))
.field("message", INFLUXDB_ERRSTR_RID_NOT_PERMITTED)
.timestamp(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count())
.request(m_network->m_influxServer);
}
// always peers can violate the rules...hurray
if (!isAlwaysPeer) {
// does the TGID have a permitted RID list?
if (tg.config().permittedRIDs().size() > 0) {
// does the transmitting RID have permission?
std::vector<uint32_t> permittedRIDs = tg.config().permittedRIDs();
if (std::find(permittedRIDs.begin(), permittedRIDs.end(), data.getSrcId()) == permittedRIDs.end()) {
// report error event to InfluxDB
if (m_network->m_enableInfluxDB) {
influxdb::QueryBuilder()
.meas("call_error_event")
.tag("peerId", std::to_string(peerId))
.tag("streamId", std::to_string(streamId))
.tag("srcId", std::to_string(data.getSrcId()))
.tag("dstId", std::to_string(data.getDstId()))
.field("message", INFLUXDB_ERRSTR_RID_NOT_PERMITTED)
.timestamp(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count())
.request(m_network->m_influxServer);
}
// report In-Call Control to the peer sending traffic
m_network->writePeerICC(peerId, streamId, NET_SUBFUNC::PROTOCOL_SUBFUNC_DMR, NET_ICC::REJECT_TRAFFIC, data.getDstId(), data.getSlotNo());
return false;
// report In-Call Control to the peer sending traffic
m_network->writePeerICC(peerId, streamId, NET_SUBFUNC::PROTOCOL_SUBFUNC_DMR, NET_ICC::REJECT_TRAFFIC, data.getDstId(), data.getSlotNo());
return false;
}
}
}
}

@ -682,6 +682,16 @@ bool TagNXDNData::validate(uint32_t peerId, lc::RTCH& lc, uint8_t messageType, u
return false;
}
// peer always send list takes priority over any following affiliation rules
bool isAlwaysPeer = false;
std::vector<uint32_t> alwaysSend = tg.config().alwaysSend();
if (alwaysSend.size() > 0) {
auto it = std::find(alwaysSend.begin(), alwaysSend.end(), peerId);
if (it != alwaysSend.end()) {
isAlwaysPeer = true; // skip any following checks and always send traffic
}
}
// is the TGID active?
if (!tg.config().active()) {
// report error event to InfluxDB
@ -702,27 +712,30 @@ bool TagNXDNData::validate(uint32_t peerId, lc::RTCH& lc, uint8_t messageType, u
return false;
}
// does the TGID have a permitted RID list?
if (tg.config().permittedRIDs().size() > 0) {
// does the transmitting RID have permission?
std::vector<uint32_t> permittedRIDs = tg.config().permittedRIDs();
if (std::find(permittedRIDs.begin(), permittedRIDs.end(), lc.getSrcId()) == permittedRIDs.end()) {
// report error event to InfluxDB
if (m_network->m_enableInfluxDB) {
influxdb::QueryBuilder()
.meas("call_error_event")
.tag("peerId", std::to_string(peerId))
.tag("streamId", std::to_string(streamId))
.tag("srcId", std::to_string(lc.getSrcId()))
.tag("dstId", std::to_string(lc.getDstId()))
.field("message", INFLUXDB_ERRSTR_RID_NOT_PERMITTED)
.timestamp(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count())
.request(m_network->m_influxServer);
}
// always peers can violate the rules...hurray
if (!isAlwaysPeer) {
// does the TGID have a permitted RID list?
if (tg.config().permittedRIDs().size() > 0) {
// does the transmitting RID have permission?
std::vector<uint32_t> permittedRIDs = tg.config().permittedRIDs();
if (std::find(permittedRIDs.begin(), permittedRIDs.end(), lc.getSrcId()) == permittedRIDs.end()) {
// report error event to InfluxDB
if (m_network->m_enableInfluxDB) {
influxdb::QueryBuilder()
.meas("call_error_event")
.tag("peerId", std::to_string(peerId))
.tag("streamId", std::to_string(streamId))
.tag("srcId", std::to_string(lc.getSrcId()))
.tag("dstId", std::to_string(lc.getDstId()))
.field("message", INFLUXDB_ERRSTR_RID_NOT_PERMITTED)
.timestamp(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count())
.request(m_network->m_influxServer);
}
// report In-Call Control to the peer sending traffic
m_network->writePeerICC(peerId, streamId, NET_SUBFUNC::PROTOCOL_SUBFUNC_NXDN, NET_ICC::REJECT_TRAFFIC, lc.getDstId());
return false;
// report In-Call Control to the peer sending traffic
m_network->writePeerICC(peerId, streamId, NET_SUBFUNC::PROTOCOL_SUBFUNC_NXDN, NET_ICC::REJECT_TRAFFIC, lc.getDstId());
return false;
}
}
}

@ -1072,7 +1072,7 @@ bool TagP25Data::validate(uint32_t peerId, lc::LC& control, DUID::E duid, const
skipRidCheck = true;
}
LogDebug(LOG_NET, "P25, duid = $%02X, mfId = $%02X, lco = $%02X, srcId = %u, dstId = %u", duid, control.getMFId(), control.getLCO(), control.getSrcId(), control.getDstId());
//LogDebug(LOG_NET, "P25, duid = $%02X, mfId = $%02X, lco = $%02X, srcId = %u, dstId = %u", duid, control.getMFId(), control.getLCO(), control.getSrcId(), control.getDstId());
// is the source ID a blacklisted ID?
if (!skipRidCheck) {
@ -1249,6 +1249,16 @@ bool TagP25Data::validate(uint32_t peerId, lc::LC& control, DUID::E duid, const
return false;
}
// peer always send list takes priority over any following affiliation rules
bool isAlwaysPeer = false;
std::vector<uint32_t> alwaysSend = tg.config().alwaysSend();
if (alwaysSend.size() > 0) {
auto it = std::find(alwaysSend.begin(), alwaysSend.end(), peerId);
if (it != alwaysSend.end()) {
isAlwaysPeer = true; // skip any following checks and always send traffic
}
}
// is the TGID active?
if (!tg.config().active()) {
// report error event to InfluxDB
@ -1269,34 +1279,36 @@ bool TagP25Data::validate(uint32_t peerId, lc::LC& control, DUID::E duid, const
return false;
}
// does the TGID have a permitted RID list?
if (tg.config().permittedRIDs().size() > 0) {
// does the transmitting RID have permission?
std::vector<uint32_t> permittedRIDs = tg.config().permittedRIDs();
if (std::find(permittedRIDs.begin(), permittedRIDs.end(), control.getSrcId()) == permittedRIDs.end()) {
// report error event to InfluxDB
if (m_network->m_enableInfluxDB) {
influxdb::QueryBuilder()
.meas("call_error_event")
.tag("peerId", std::to_string(peerId))
.tag("streamId", std::to_string(streamId))
.tag("srcId", std::to_string(control.getSrcId()))
.tag("dstId", std::to_string(control.getDstId()))
.field("message", INFLUXDB_ERRSTR_RID_NOT_PERMITTED)
.timestamp(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count())
.request(m_network->m_influxServer);
}
// always peers can violate the rules...hurray
if (!isAlwaysPeer) {
// does the TGID have a permitted RID list?
if (tg.config().permittedRIDs().size() > 0) {
// does the transmitting RID have permission?
std::vector<uint32_t> permittedRIDs = tg.config().permittedRIDs();
if (std::find(permittedRIDs.begin(), permittedRIDs.end(), control.getSrcId()) == permittedRIDs.end()) {
// report error event to InfluxDB
if (m_network->m_enableInfluxDB) {
influxdb::QueryBuilder()
.meas("call_error_event")
.tag("peerId", std::to_string(peerId))
.tag("streamId", std::to_string(streamId))
.tag("srcId", std::to_string(control.getSrcId()))
.tag("dstId", std::to_string(control.getDstId()))
.field("message", INFLUXDB_ERRSTR_RID_NOT_PERMITTED)
.timestamp(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count())
.request(m_network->m_influxServer);
}
// report In-Call Control to the peer sending traffic
m_network->writePeerICC(peerId, streamId, NET_SUBFUNC::PROTOCOL_SUBFUNC_P25, NET_ICC::REJECT_TRAFFIC, control.getDstId());
return false;
// report In-Call Control to the peer sending traffic
m_network->writePeerICC(peerId, streamId, NET_SUBFUNC::PROTOCOL_SUBFUNC_P25, NET_ICC::REJECT_TRAFFIC, control.getDstId());
return false;
}
}
}
return true;
}
/* Helper to write a grant packet. */
bool TagP25Data::write_TSDU_Grant(uint32_t peerId, uint32_t srcId, uint32_t dstId, uint8_t serviceOptions, bool grp)

Loading…
Cancel
Save

Powered by TurnKey Linux.