diff --git a/p25/TrunkPacket.cpp b/p25/TrunkPacket.cpp
index bd8a1178..e34a61c3 100644
--- a/p25/TrunkPacket.cpp
+++ b/p25/TrunkPacket.cpp
@@ -606,7 +606,7 @@ bool TrunkPacket::process(uint8_t* data, uint32_t len)
LogMessage(LOG_RF, P25_TSDU_STR ", TSBK_ISP_LOC_REG_REQ (Location Registration Request), srcId = %u, dstId = %u", srcId, dstId);
}
- writeRF_TSDU_U_Reg_Cmd(srcId);
+ writeRF_TSDU_Loc_Reg_Rsp(srcId, dstId);
break;
default:
LogError(LOG_RF, P25_TSDU_STR ", unhandled LCO, mfId = $%02X, lco = $%02X", m_rfTSBK.getMFId(), m_rfTSBK.getLCO());
@@ -2289,6 +2289,58 @@ void TrunkPacket::writeRF_TSDU_Queue(uint8_t reason, uint8_t service)
m_rfTSBK.setLCO(lco);
}
+///
+/// Helper to write a location registration response packet.
+///
+///
+///
+bool TrunkPacket::writeRF_TSDU_Loc_Reg_Rsp(uint32_t srcId, uint32_t dstId)
+{
+ bool ret = false;
+
+ m_rfTSBK.setLCO(TSBK_OSP_LOC_REG_RSP);
+ m_rfTSBK.setResponse(P25_RSP_ACCEPT);
+ m_rfTSBK.setDstId(dstId);
+ m_rfTSBK.setSrcId(srcId);
+
+ // validate the source RID
+ if (!acl::AccessControl::validateSrcId(srcId)) {
+ LogWarning(LOG_RF, P25_TSDU_STR ", TSBK_OSP_LOC_REG_RSP (Location Registration Response) denial, RID rejection, srcId = %u", srcId);
+ ::ActivityLog("P25", true, "location registration request from %u denied", srcId);
+ m_rfTSBK.setResponse(P25_RSP_REFUSED);
+ }
+
+ // validate the source RID is registered
+ if (!hasSrcIdUnitReg(srcId)) {
+ LogWarning(LOG_RF, P25_TSDU_STR ", TSBK_OSP_LOC_REG_RSP (Location Registration Response) denial, RID not registered, srcId = %u", srcId);
+ ::ActivityLog("P25", true, "location registration request from %u denied", srcId);
+ writeRF_TSDU_U_Reg_Cmd(srcId);
+ return false;
+ }
+
+ // validate the talkgroup ID
+ if (m_rfTSBK.getGroup()) {
+ if (!acl::AccessControl::validateTGId(dstId)) {
+ LogWarning(LOG_RF, P25_TSDU_STR ", TSBK_OSP_LOC_REG_RSP (Location Registration Response) denial, TGID rejection, dstId = %u", dstId);
+ ::ActivityLog("P25", true, "location registration request from %u to %s %u denied", srcId, "TG ", dstId);
+ m_rfTSBK.setResponse(P25_RSP_DENY);
+ }
+ }
+
+ if (m_rfTSBK.getResponse() == P25_RSP_ACCEPT) {
+ if (m_verbose) {
+ LogMessage(LOG_RF, P25_TSDU_STR ", TSBK_OSP_LOC_REG_RSP (Location Registration Response), lra = %u, srcId = %u, dstId = %u",
+ m_rfTSBK.getLRA(), srcId, dstId);
+ }
+
+ ::ActivityLog("P25", true, "location registration request from %u", srcId);
+ ret = true;
+ }
+
+ writeRF_TSDU_SBF(false);
+ return ret;
+}
+
///
/// Helper to write a network TSDU from the RF data queue.
///
diff --git a/p25/TrunkPacket.h b/p25/TrunkPacket.h
index 5a325b69..0345281d 100644
--- a/p25/TrunkPacket.h
+++ b/p25/TrunkPacket.h
@@ -229,6 +229,8 @@ namespace p25
void writeRF_TSDU_U_Dereg_Ack(uint32_t srcId);
/// Helper to write a queue packet.
void writeRF_TSDU_Queue(uint8_t reason, uint8_t service);
+ /// Helper to write a location registration response packet.
+ bool writeRF_TSDU_Loc_Reg_Rsp(uint32_t srcId, uint32_t dstId);
/// Helper to write a network TSDU from the RF data queue.
void writeNet_TSDU_From_RF(uint8_t* data);
diff --git a/p25/lc/TSBK.cpp b/p25/lc/TSBK.cpp
index d555b4cb..12ae981a 100644
--- a/p25/lc/TSBK.cpp
+++ b/p25/lc/TSBK.cpp
@@ -237,7 +237,7 @@ bool TSBK::decode(const uint8_t* data)
m_srcId = (uint32_t)(tsbkValue & 0xFFFFFFU); // Target Radio Address
break;
case TSBK_IOSP_GRP_AFF:
- m_sysId = (uint32_t)((tsbkValue >> 16) & 0xFFFU); // System ID
+ m_sysId = (uint32_t)((tsbkValue >> 40) & 0xFFFU); // System ID
m_dstId = (uint32_t)((tsbkValue >> 24) & 0xFFFFU); // Talkgroup Address
m_srcId = (uint32_t)(tsbkValue & 0xFFFFFFU); // Source Radio Address
break;
@@ -273,6 +273,7 @@ bool TSBK::decode(const uint8_t* data)
m_srcId = (uint32_t)(tsbkValue & 0xFFFFFFU); // Source Radio Address
break;
case TSBK_ISP_LOC_REG_REQ:
+ m_lra = (uint8_t)((tsbkValue >> 40) & 0xFFU); // LRA
m_dstId = (uint32_t)((tsbkValue >> 24) & 0xFFFFU); // Talkgroup Address
m_srcId = (uint32_t)(tsbkValue & 0xFFFFFFU); // Source Radio Address
break;
diff --git a/p25/lc/TSBK.h b/p25/lc/TSBK.h
index c609bb7f..73dd34e7 100644
--- a/p25/lc/TSBK.h
+++ b/p25/lc/TSBK.h
@@ -154,6 +154,10 @@ namespace p25
/// Explicit SCCB channel number.
__PROPERTY(uint32_t, sccbChannelNo, SCCBChnNo);
+ /** Location Data */
+ /// Location registration area.
+ __PROPERTY(uint8_t, lra, LRA);
+
/** Patch Group data */
/// Patch super group ID.
__PROPERTY(uint32_t, patchSuperGroupId, PatchSuperGroupId);