add support to transmit dynamic regroup IR extended commands;

4.04d_maint
Bryan Biedenkapp 2 years ago
parent 0db1425af5
commit 6542443ca7

@ -312,7 +312,17 @@ namespace p25
INHIBIT = 0x007FU, //! Radio Inhibit
CHECK_ACK = 0x0080U, //! Radio Check Ack
UNINHIBIT_ACK = 0x00FEU, //! Radio Uninhibit Ack
INHIBIT_ACK = 0x00FFU //! Radio Inhibit Ack
INHIBIT_ACK = 0x00FFU, //! Radio Inhibit Ack
DYN_REGRP_REQ = 0x0200U, //! MFID $90 (Motorola) Dynamic Regroup IR
DYN_REGRP_CANCEL = 0x0201U, //! MFID $90 (Motorola) Dynamic Regroup IR Cancellation
DYN_REGRP_LOCK = 0x0202U, //! MFID $90 (Motorola) Lock Selector
DYN_REGRP_UNLOCK = 0x0203U, //! MFID $90 (Motorola) Unlock Selector
DYN_REGRP_REQ_ACK = 0x0280U, //! MFID $90 (Motorola) Dynamic Regroup IR Ack
DYN_REGRP_CANCEL_ACK = 0x0281U, //! MFID $90 (Motorola) Dynamic Regroup IR Cancellation Ack
DYN_REGRP_LOCK_ACK = 0x0282U, //! MFID $90 (Motorola) Lock Selector Ack
DYN_REGRP_UNLOCK_ACK = 0x0283U, //! MFID $90 (Motorola) Unlock Selector Ack
};
}

@ -1517,6 +1517,26 @@ void RESTAPI::restAPI_PutP25RID(const HTTPPayload& request, HTTPPayload& reply,
else if (::strtolower(command) == RID_CMD_UNINHIBIT) {
m_network->m_tagP25->write_TSDU_Ext_Func(peerId, ExtendedFunctions::UNINHIBIT, WUID_FNE, dstId);
}
else if (::strtolower(command) == RID_CMD_DYN_REGRP) {
// validate source ID is a integer within the JSON blob
if (!req["tgId"].is<uint32_t>()) {
errorPayload(reply, "talkgroup ID was not valid");
return;
}
uint32_t tgId = req["tgId"].get<uint32_t>();
m_network->m_tagP25->write_TSDU_Ext_Func(peerId, ExtendedFunctions::DYN_REGRP_REQ, tgId, dstId);
}
else if (::strtolower(command) == RID_CMD_DYN_REGRP_CANCEL) {
m_network->m_tagP25->write_TSDU_Ext_Func(peerId, ExtendedFunctions::DYN_REGRP_CANCEL, 0U, dstId);
}
else if (::strtolower(command) == RID_CMD_DYN_REGRP_LOCK) {
m_network->m_tagP25->write_TSDU_Ext_Func(peerId, ExtendedFunctions::DYN_REGRP_LOCK, 0U, dstId);
}
else if (::strtolower(command) == RID_CMD_DYN_REGRP_UNLOCK) {
m_network->m_tagP25->write_TSDU_Ext_Func(peerId, ExtendedFunctions::DYN_REGRP_UNLOCK, 0U, dstId);
}
else if (::strtolower(command) == RID_CMD_GAQ) {
m_network->m_tagP25->write_TSDU_Grp_Aff_Q(peerId, dstId);
}

@ -534,8 +534,13 @@ void TagP25Data::write_TSDU_Ext_Func(uint32_t peerId, uint32_t func, uint32_t ar
iosp->setSrcId(arg);
iosp->setDstId(dstId);
LogMessage(LOG_NET, P25_TSDU_STR ", %s, op = $%02X, arg = %u, tgt = %u",
iosp->toString().c_str(), iosp->getExtendedFunction(), iosp->getSrcId(), iosp->getDstId());
// class $02 is Motorola -- set the MFID properly
if ((func >> 8) == 0x02U) {
iosp->setMFId(MFG_MOT);
}
LogMessage(LOG_NET, P25_TSDU_STR ", %s, mfId = $%02X, op = $%02X, arg = %u, tgt = %u",
iosp->toString().c_str(), iosp->getMFId(), iosp->getExtendedFunction(), iosp->getSrcId(), iosp->getDstId());
write_TSDU(peerId, iosp.get());
}

@ -1779,6 +1779,26 @@ void RESTAPI::restAPI_PutP25RID(const HTTPPayload& request, HTTPPayload& reply,
else if (::strtolower(command) == RID_CMD_UNINHIBIT) {
m_p25->control()->writeRF_TSDU_Ext_Func(ExtendedFunctions::UNINHIBIT, WUID_FNE, dstId);
}
else if (::strtolower(command) == RID_CMD_DYN_REGRP) {
// validate source ID is a integer within the JSON blob
if (!req["tgId"].is<uint32_t>()) {
errorPayload(reply, "talkgroup ID was not valid");
return;
}
uint32_t tgId = req["tgId"].get<uint32_t>();
m_p25->control()->writeRF_TSDU_Ext_Func(ExtendedFunctions::DYN_REGRP_REQ, tgId, dstId);
}
else if (::strtolower(command) == RID_CMD_DYN_REGRP_CANCEL) {
m_p25->control()->writeRF_TSDU_Ext_Func(ExtendedFunctions::DYN_REGRP_CANCEL, 0U, dstId);
}
else if (::strtolower(command) == RID_CMD_DYN_REGRP_LOCK) {
m_p25->control()->writeRF_TSDU_Ext_Func(ExtendedFunctions::DYN_REGRP_LOCK, 0U, dstId);
}
else if (::strtolower(command) == RID_CMD_DYN_REGRP_UNLOCK) {
m_p25->control()->writeRF_TSDU_Ext_Func(ExtendedFunctions::DYN_REGRP_UNLOCK, 0U, dstId);
}
else if (::strtolower(command) == RID_CMD_GAQ) {
m_p25->control()->writeRF_TSDU_Grp_Aff_Q(dstId);
}

@ -49,6 +49,10 @@
#define RID_CMD_CHECK "check"
#define RID_CMD_INHIBIT "inhibit"
#define RID_CMD_UNINHIBIT "uninhibit"
#define RID_CMD_DYN_REGRP "dyn-regrp"
#define RID_CMD_DYN_REGRP_CANCEL "dyn-regrp-cancel"
#define RID_CMD_DYN_REGRP_LOCK "dyn-regrp-lock"
#define RID_CMD_DYN_REGRP_UNLOCK "dyn-regrp-unlock"
#define RID_CMD_GAQ "group-aff-req"
#define RID_CMD_UREG "unit-reg"
#define RID_CMD_EMERG "emerg"

@ -487,14 +487,30 @@ bool ControlSignaling::process(uint8_t* data, uint32_t len, std::unique_ptr<lc::
}
// generate activity log entry
if (iosp->getExtendedFunction() == ExtendedFunctions::CHECK_ACK) {
switch (iosp->getExtendedFunction()) {
// Standard
case ExtendedFunctions::CHECK_ACK:
::ActivityLog("P25", true, "radio check response from %u to %u", srcId, dstId);
}
else if (iosp->getExtendedFunction() == ExtendedFunctions::INHIBIT_ACK) {
break;
case ExtendedFunctions::INHIBIT_ACK:
::ActivityLog("P25", true, "radio inhibit response from %u to %u", srcId, dstId);
}
else if (iosp->getExtendedFunction() == ExtendedFunctions::UNINHIBIT_ACK) {
break;
case ExtendedFunctions::UNINHIBIT_ACK:
::ActivityLog("P25", true, "radio uninhibit response from %u to %u", srcId, dstId);
break;
// Dynamic Regroup
case ExtendedFunctions::DYN_REGRP_REQ_ACK:
::ActivityLog("P25", true, "radio dynamic regroup response from %u to TG%u", srcId, dstId);
break;
case ExtendedFunctions::DYN_REGRP_CANCEL_ACK:
::ActivityLog("P25", true, "radio dynamic regroup cancel response from %u to TG%u", srcId, dstId);
break;
case ExtendedFunctions::DYN_REGRP_LOCK_ACK:
::ActivityLog("P25", true, "radio dynamic regroup selector lock response from %u", srcId);
break;
case ExtendedFunctions::DYN_REGRP_UNLOCK_ACK:
::ActivityLog("P25", true, "radio dynamic regroup selector unlock response from %u", srcId);
break;
}
writeRF_TSDU_SBF(iosp, true);
@ -913,14 +929,30 @@ bool ControlSignaling::processNetwork(uint8_t* data, uint32_t len, lc::LC& contr
}
// generate activity log entry
if (iosp->getExtendedFunction() == ExtendedFunctions::CHECK_ACK) {
switch (iosp->getExtendedFunction()) {
// Standard
case ExtendedFunctions::CHECK_ACK:
::ActivityLog("P25", false, "radio check response from %u to %u", srcId, dstId);
}
else if (iosp->getExtendedFunction() == ExtendedFunctions::INHIBIT_ACK) {
break;
case ExtendedFunctions::INHIBIT_ACK:
::ActivityLog("P25", false, "radio inhibit response from %u to %u", srcId, dstId);
}
else if (iosp->getExtendedFunction() == ExtendedFunctions::UNINHIBIT_ACK) {
break;
case ExtendedFunctions::UNINHIBIT_ACK:
::ActivityLog("P25", false, "radio uninhibit response from %u to %u", srcId, dstId);
break;
// Dynamic Regroup
case ExtendedFunctions::DYN_REGRP_REQ_ACK:
::ActivityLog("P25", false, "radio dynamic regroup response from %u to TG%u", srcId, dstId);
break;
case ExtendedFunctions::DYN_REGRP_CANCEL_ACK:
::ActivityLog("P25", false, "radio dynamic regroup cancel response from %u to TG%u", srcId, dstId);
break;
case ExtendedFunctions::DYN_REGRP_LOCK_ACK:
::ActivityLog("P25", false, "radio dynamic regroup selector lock response from %u", srcId);
break;
case ExtendedFunctions::DYN_REGRP_UNLOCK_ACK:
::ActivityLog("P25", false, "radio dynamic regroup selector unlock response from %u", srcId);
break;
}
}
break;
@ -1070,20 +1102,41 @@ void ControlSignaling::writeRF_TSDU_Ext_Func(uint32_t func, uint32_t arg, uint32
m_lastMFID = MFG_STANDARD;
}
// class $02 is Motorola -- set the MFID properly
if ((func >> 8) == 0x02U) {
iosp->setMFId(MFG_MOT);
}
if (m_verbose) {
LogMessage(LOG_RF, P25_TSDU_STR ", %s, op = $%02X, arg = %u, tgt = %u",
iosp->toString().c_str(), iosp->getExtendedFunction(), iosp->getSrcId(), iosp->getDstId());
LogMessage(LOG_RF, P25_TSDU_STR ", %s, mfId = $%02X, op = $%02X, arg = %u, tgt = %u",
iosp->toString().c_str(), iosp->getMFId(), iosp->getExtendedFunction(), iosp->getSrcId(), iosp->getDstId());
}
// generate activity log entry
if (func == ExtendedFunctions::CHECK) {
switch (func) {
// Standard
case ExtendedFunctions::CHECK:
::ActivityLog("P25", true, "radio check request from %u to %u", arg, dstId);
}
else if (func == ExtendedFunctions::INHIBIT) {
break;
case ExtendedFunctions::INHIBIT:
::ActivityLog("P25", true, "radio inhibit request from %u to %u", arg, dstId);
}
else if (func == ExtendedFunctions::UNINHIBIT) {
break;
case ExtendedFunctions::UNINHIBIT:
::ActivityLog("P25", true, "radio uninhibit request from %u to %u", arg, dstId);
break;
// Dynamic Regroup
case ExtendedFunctions::DYN_REGRP_REQ:
::ActivityLog("P25", true, "radio dynamic regroup request TG%u for %u", arg, dstId);
break;
case ExtendedFunctions::DYN_REGRP_CANCEL:
::ActivityLog("P25", true, "radio dynamic regroup cancel for %u", dstId);
break;
case ExtendedFunctions::DYN_REGRP_LOCK:
::ActivityLog("P25", true, "radio dynamic regroup selector lock for %u", dstId);
break;
case ExtendedFunctions::DYN_REGRP_UNLOCK:
::ActivityLog("P25", true, "radio dynamic regroup selector unlock for %u", dstId);
break;
}
writeRF_TSDU_SBF_Imm(iosp.get(), false);

@ -92,12 +92,20 @@
#define RCD_P25_RID_CHECK "p25-rid-check"
#define RCD_P25_RID_INHIBIT "p25-rid-inhibit"
#define RCD_P25_RID_UNINHIBIT "p25-rid-uninhibit"
#define RCD_P25_RID_DYN_REGRP "p25-rid-dyn-regrp"
#define RCD_P25_RID_DYN_REGRP_CANCEL "p25-rid-dyn-regrp-cancel"
#define RCD_P25_RID_DYN_REGRP_LOCK "p25-rid-dyn-regrp-lock"
#define RCD_P25_RID_DYN_REGRP_UNLOCK "p25-rid-dyn-regrp-unlock"
#define RCD_P25_RID_GAQ "p25-rid-gaq"
#define RCD_P25_RID_UREG "p25-rid-ureg"
#define RCD_FNE_P25_RID_PAGE "fne-p25-rid-page"
#define RCD_FNE_P25_RID_CHECK "fne-p25-rid-check"
#define RCD_FNE_P25_RID_INHIBIT "fne-p25-rid-inhibit"
#define RCD_FNE_P25_RID_UNINHIBIT "fne-p25-rid-uninhibit"
#define RCD_FNE_P25_RID_DYN_REGRP "fne-p25-rid-dyn-regrp"
#define RCD_FNE_P25_RID_DYN_REGRP_CANCEL "fne-p25-rid-dyn-regrp-cancel"
#define RCD_FNE_P25_RID_DYN_REGRP_LOCK "fne-p25-rid-dyn-regrp-lock"
#define RCD_FNE_P25_RID_DYN_REGRP_UNLOCK "fne-p25-rid-dyn-regrp-unlock"
#define RCD_FNE_P25_RID_GAQ "fne-p25-rid-gaq"
#define RCD_FNE_P25_RID_UREG "fne-p25-rid-ureg"
@ -254,6 +262,14 @@ void usage(const char* message, const char* arg)
reply += " p25-rid-check <rid> Radio Checks the specified RID\r\n";
reply += " p25-rid-inhibit <rid> Inhibits the specified RID\r\n";
reply += " p25-rid-uninhibit <rid> Uninhibits the specified RID\r\n";
reply += " p25-rid-dyn-regrp <rid> <tg>\r\n";
reply += " Dynamic Regroup Request to the specified RID\r\n";
reply += " p25-rid-dyn-regrp-cancel <rid>\r\n";
reply += " Dynamic Regroup Cancellation to the specified RID\r\n";
reply += " p25-rid-dyn-regrp-lock <rid>\r\n";
reply += " Dynamic Regroup Selector Lock to the specified RID\r\n";
reply += " p25-rid-dyn-regrp-unlock <rid>\r\n";
reply += " Dynamic Regroup Selector Unlock to the specified RID\r\n";
reply += " p25-rid-gaq <rid> Group affiliation queries the specified RID\r\n";
reply += " p25-rid-ureg <rid> Demand unit registration for the specified RID\r\n";
reply += "\r\n";
@ -695,7 +711,7 @@ int main(int argc, char** argv)
req["dstId"].set<uint32_t>(dstId);
if (rcom == RCD_FNE_P25_RID_PAGE) {
uint32_t peerId = getArgUInt32(args, 2U);
uint32_t peerId = getArgUInt32(args, 1U);
req["peerId"].set<uint32_t>(peerId);
}
@ -708,7 +724,7 @@ int main(int argc, char** argv)
req["dstId"].set<uint32_t>(dstId);
if (rcom == RCD_P25_RID_CHECK) {
uint32_t peerId = getArgUInt32(args, 2U);
uint32_t peerId = getArgUInt32(args, 1U);
req["peerId"].set<uint32_t>(peerId);
}
@ -721,7 +737,7 @@ int main(int argc, char** argv)
req["dstId"].set<uint32_t>(dstId);
if (rcom == RCD_FNE_P25_RID_INHIBIT) {
uint32_t peerId = getArgUInt32(args, 2U);
uint32_t peerId = getArgUInt32(args, 1U);
req["peerId"].set<uint32_t>(peerId);
}
@ -734,12 +750,66 @@ int main(int argc, char** argv)
req["dstId"].set<uint32_t>(dstId);
if (rcom == RCD_FNE_P25_RID_UNINHIBIT) {
uint32_t peerId = getArgUInt32(args, 1U);
req["peerId"].set<uint32_t>(peerId);
}
retCode = client->send(HTTP_PUT, PUT_P25_RID, req, response);
}
else if ((rcom == RCD_P25_RID_DYN_REGRP || rcom == RCD_FNE_P25_RID_DYN_REGRP) && argCnt >= 1U) {
json::object req = json::object();
req["command"].set<std::string>(std::string(RID_CMD_DYN_REGRP));
uint32_t dstId = getArgUInt32(args, 0U);
req["dstId"].set<uint32_t>(dstId);
uint32_t tgId = getArgUInt32(args, 1U);
req["tgId"].set<uint32_t>(tgId);
if (rcom == RCD_FNE_P25_RID_DYN_REGRP) {
uint32_t peerId = getArgUInt32(args, 2U);
req["peerId"].set<uint32_t>(peerId);
}
retCode = client->send(HTTP_PUT, PUT_P25_RID, req, response);
}
else if ((rcom == RCD_P25_RID_DYN_REGRP_CANCEL || rcom == RCD_FNE_P25_RID_DYN_REGRP_CANCEL) && argCnt >= 1U) {
json::object req = json::object();
req["command"].set<std::string>(std::string(RID_CMD_DYN_REGRP_CANCEL));
uint32_t dstId = getArgUInt32(args, 0U);
req["dstId"].set<uint32_t>(dstId);
if (rcom == RCD_FNE_P25_RID_DYN_REGRP_CANCEL) {
uint32_t peerId = getArgUInt32(args, 1U);
req["peerId"].set<uint32_t>(peerId);
}
retCode = client->send(HTTP_PUT, PUT_P25_RID, req, response);
}
else if ((rcom == RCD_P25_RID_DYN_REGRP_LOCK || rcom == RCD_FNE_P25_RID_DYN_REGRP_LOCK) && argCnt >= 1U) {
json::object req = json::object();
req["command"].set<std::string>(std::string(RID_CMD_DYN_REGRP_LOCK));
uint32_t dstId = getArgUInt32(args, 0U);
req["dstId"].set<uint32_t>(dstId);
if (rcom == RCD_FNE_P25_RID_DYN_REGRP_LOCK) {
uint32_t peerId = getArgUInt32(args, 1U);
req["peerId"].set<uint32_t>(peerId);
}
retCode = client->send(HTTP_PUT, PUT_P25_RID, req, response);
}
else if ((rcom == RCD_P25_RID_DYN_REGRP_UNLOCK || rcom == RCD_FNE_P25_RID_DYN_REGRP_UNLOCK) && argCnt >= 1U) {
json::object req = json::object();
req["command"].set<std::string>(std::string(RID_CMD_DYN_REGRP_UNLOCK));
uint32_t dstId = getArgUInt32(args, 0U);
req["dstId"].set<uint32_t>(dstId);
if (rcom == RCD_FNE_P25_RID_DYN_REGRP_UNLOCK) {
uint32_t peerId = getArgUInt32(args, 1U);
req["peerId"].set<uint32_t>(peerId);
}
retCode = client->send(HTTP_PUT, PUT_P25_RID, req, response);
}
else if ((rcom == RCD_P25_RID_GAQ || rcom == RCD_FNE_P25_RID_GAQ) && argCnt >= 1U) {
json::object req = json::object();
req["command"].set<std::string>(std::string(RID_CMD_GAQ));
@ -747,7 +817,7 @@ int main(int argc, char** argv)
req["dstId"].set<uint32_t>(dstId);
if (rcom == RCD_FNE_P25_RID_GAQ) {
uint32_t peerId = getArgUInt32(args, 2U);
uint32_t peerId = getArgUInt32(args, 1U);
req["peerId"].set<uint32_t>(peerId);
}
@ -760,7 +830,7 @@ int main(int argc, char** argv)
req["dstId"].set<uint32_t>(dstId);
if (rcom == RCD_FNE_P25_RID_UREG) {
uint32_t peerId = getArgUInt32(args, 2U);
uint32_t peerId = getArgUInt32(args, 1U);
req["peerId"].set<uint32_t>(peerId);
}

Loading…
Cancel
Save

Powered by TurnKey Linux.