diff --git a/src/common/nxdn/NXDNUtils.cpp b/src/common/nxdn/NXDNUtils.cpp
index dd59e611..5d67eee9 100644
--- a/src/common/nxdn/NXDNUtils.cpp
+++ b/src/common/nxdn/NXDNUtils.cpp
@@ -15,6 +15,7 @@
#include "Defines.h"
#include "nxdn/NXDNDefines.h"
#include "nxdn/NXDNUtils.h"
+#include "Utils.h"
using namespace nxdn;
@@ -45,3 +46,19 @@ void NXDNUtils::scrambler(uint8_t* data)
for (uint32_t i = 0U; i < NXDN_FRAME_LENGTH_BYTES; i++)
data[i] ^= SCRAMBLER[i];
}
+
+///
+/// Helper to add the post field bits on NXDN frame data.
+///
+///
+void NXDNUtils::addPostBits(uint8_t* data)
+{
+ assert(data != nullptr);
+
+ // post field
+ for (uint32_t i = 0U; i < NXDN_CAC_E_POST_FIELD_BITS; i++) {
+ uint32_t n = i + NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_CAC_FEC_LENGTH_BITS + NXDN_CAC_E_POST_FIELD_BITS;
+ bool b = READ_BIT(NXDN_PREAMBLE, i);
+ WRITE_BIT(data, n, b);
+ }
+}
diff --git a/src/common/nxdn/NXDNUtils.h b/src/common/nxdn/NXDNUtils.h
index 6ac2b185..68ca8f63 100644
--- a/src/common/nxdn/NXDNUtils.h
+++ b/src/common/nxdn/NXDNUtils.h
@@ -28,6 +28,8 @@ namespace nxdn
public:
/// Helper to scramble the NXDN frame data.
static void scrambler(uint8_t* data);
+ /// Helper to add the post field bits on NXDN frame data.
+ static void addPostBits(uint8_t* data);
};
} // namespace nxdn
diff --git a/src/fne/network/fne/TagDMRData.cpp b/src/fne/network/fne/TagDMRData.cpp
index 9cc9ffed..27d74c00 100644
--- a/src/fne/network/fne/TagDMRData.cpp
+++ b/src/fne/network/fne/TagDMRData.cpp
@@ -11,8 +11,11 @@
*
*/
#include "fne/Defines.h"
+#include "common/dmr/lc/csbk/CSBKFactory.h"
#include "common/dmr/lc/LC.h"
#include "common/dmr/lc/FullLC.h"
+#include "common/dmr/SlotType.h"
+#include "common/dmr/Sync.h"
#include "common/Clock.h"
#include "common/Log.h"
#include "common/Utils.h"
@@ -542,4 +545,68 @@ bool TagDMRData::validate(uint32_t peerId, data::Data& data, uint32_t streamId)
}
return true;
-}
\ No newline at end of file
+}
+
+///
+/// Helper to write a NACK RSP packet.
+///
+///
+///
+///
+///
+void TagDMRData::write_CSBK_NACK_RSP(uint32_t peerId, uint32_t dstId, uint8_t reason, uint8_t service)
+{
+ std::unique_ptr csbk = std::make_unique();
+ csbk->setServiceKind(service);
+ csbk->setReason(reason);
+ csbk->setSrcId(DMR_WUID_ALL); // hmmm...
+ csbk->setDstId(dstId);
+
+ write_CSBK(peerId, csbk.get());
+}
+
+///
+/// Helper to write a network CSBK.
+///
+///
+///
+void TagDMRData::write_CSBK(uint32_t peerId, lc::CSBK* csbk)
+{
+ uint8_t data[DMR_FRAME_LENGTH_BYTES + 2U];
+ ::memset(data + 2U, 0x00U, DMR_FRAME_LENGTH_BYTES);
+
+ SlotType slotType;
+ slotType.setColorCode(0U);
+ slotType.setDataType(DT_CSBK);
+
+ // Regenerate the CSBK data
+ csbk->encode(data + 2U);
+
+ // Regenerate the Slot Type
+ slotType.encode(data + 2U);
+
+ // Convert the Data Sync to be from the BS or MS as needed
+ Sync::addDMRDataSync(data + 2U, true);
+
+ data::Data dmrData;
+ dmrData.setSlotNo(1U);
+ dmrData.setDataType(DT_CSBK);
+ dmrData.setSrcId(csbk->getSrcId());
+ dmrData.setDstId(csbk->getDstId());
+ dmrData.setFLCO(csbk->getGI() ? FLCO_GROUP : FLCO_PRIVATE);
+ dmrData.setN(0U);
+ dmrData.setSeqNo(0U);
+ dmrData.setBER(0U);
+ dmrData.setRSSI(0U);
+
+ dmrData.setData(data + 2U);
+
+ uint32_t streamId = m_network->createStreamId();
+ uint32_t messageLength = 0U;
+ UInt8Array message = m_network->createDMR_Message(messageLength, streamId, dmrData);
+ if (message == nullptr) {
+ return;
+ }
+
+ m_network->writePeer(peerId, { NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_DMR }, message.get(), messageLength, RTP_END_OF_CALL_SEQ, streamId, false, true);
+}
diff --git a/src/fne/network/fne/TagDMRData.h b/src/fne/network/fne/TagDMRData.h
index 8502c2b8..7551c02f 100644
--- a/src/fne/network/fne/TagDMRData.h
+++ b/src/fne/network/fne/TagDMRData.h
@@ -16,6 +16,7 @@
#include "fne/Defines.h"
#include "common/dmr/DMRDefines.h"
#include "common/dmr/data/Data.h"
+#include "common/dmr/lc/CSBK.h"
#include "common/Clock.h"
#include "network/FNENetwork.h"
@@ -75,6 +76,12 @@ namespace network
bool isPeerPermitted(uint32_t peerId, dmr::data::Data& data, uint32_t streamId);
/// Helper to validate the DMR call stream.
bool validate(uint32_t peerId, dmr::data::Data& data, uint32_t streamId);
+
+ /// Helper to write a NACK RSP packet.
+ void write_CSBK_NACK_RSP(uint32_t peerId, uint32_t dstId, uint8_t reason, uint8_t service);
+
+ /// Helper to write a network CSBK.
+ void write_CSBK(uint32_t peerId, dmr::lc::CSBK* csbk);
};
} // namespace fne
} // namespace network
diff --git a/src/fne/network/fne/TagNXDNData.cpp b/src/fne/network/fne/TagNXDNData.cpp
index 4fcf8fd4..1bdb1838 100644
--- a/src/fne/network/fne/TagNXDNData.cpp
+++ b/src/fne/network/fne/TagNXDNData.cpp
@@ -12,6 +12,12 @@
*/
#include "fne/Defines.h"
#include "common/nxdn/NXDNDefines.h"
+#include "common/nxdn/channel/LICH.h"
+#include "common/nxdn/channel/CAC.h"
+#include "common/nxdn/lc/rcch/RCCHFactory.h"
+#include "common/nxdn/lc/RTCH.h"
+#include "common/nxdn/NXDNUtils.h"
+#include "common/nxdn/Sync.h"
#include "common/Clock.h"
#include "common/Log.h"
#include "common/Utils.h"
@@ -460,4 +466,86 @@ bool TagNXDNData::validate(uint32_t peerId, lc::RTCH& lc, uint8_t messageType, u
}
return true;
-}
\ No newline at end of file
+}
+
+///
+/// Helper to write a deny packet.
+///
+///
+///
+///
+///
+///
+void TagNXDNData::write_Message_Deny(uint32_t peerId, uint32_t srcId, uint32_t dstId, uint8_t reason, uint8_t service)
+{
+ std::unique_ptr rcch = nullptr;
+
+ switch (service) {
+ case RTCH_MESSAGE_TYPE_VCALL:
+ rcch = std::make_unique();
+ rcch->setMessageType(RTCH_MESSAGE_TYPE_VCALL);
+ default:
+ return;
+ }
+
+ rcch->setCauseResponse(reason);
+ rcch->setSrcId(srcId);
+ rcch->setDstId(dstId);
+
+ if (m_network->m_verbose) {
+ LogMessage(LOG_RF, "NXDN, MSG_DENIAL (Message Denial), reason = $%02X, service = $%02X, srcId = %u, dstId = %u",
+ service, srcId, dstId);
+ }
+
+ write_Message(peerId, rcch.get());
+}
+
+///
+/// Helper to write a network RCCH.
+///
+///
+///
+void TagNXDNData::write_Message(uint32_t peerId, lc::RCCH* rcch)
+{
+ uint8_t data[NXDN_FRAME_LENGTH_BYTES + 2U];
+ ::memset(data + 2U, 0x00U, NXDN_FRAME_LENGTH_BYTES);
+
+ Sync::addNXDNSync(data + 2U);
+
+ // generate the LICH
+ channel::LICH lich;
+ lich.setRFCT(NXDN_LICH_RFCT_RCCH);
+ lich.setFCT(NXDN_LICH_CAC_OUTBOUND);
+ lich.setOption(NXDN_LICH_DATA_COMMON);
+ lich.setOutbound(true);
+ lich.encode(data + 2U);
+
+ uint8_t buffer[NXDN_RCCH_LC_LENGTH_BYTES];
+ ::memset(buffer, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES);
+
+ rcch->encode(buffer, NXDN_RCCH_LC_LENGTH_BITS);
+
+ // generate the CAC
+ channel::CAC cac;
+ cac.setRAN(0U);
+ cac.setStructure(NXDN_SR_RCCH_SINGLE);
+ cac.setData(buffer);
+ cac.encode(data + 2U);
+
+ NXDNUtils::scrambler(data + 2U);
+ NXDNUtils::addPostBits(data + 2U);
+
+ lc::RTCH lc = lc::RTCH();
+ lc.setMessageType(rcch->getMessageType());
+ lc.setSrcId(rcch->getSrcId());
+ lc.setDstId(rcch->getDstId());
+
+ uint32_t messageLength = 0U;
+ UInt8Array message = m_network->createNXDN_Message(messageLength, lc, data, NXDN_FRAME_LENGTH_BYTES + 2U);
+ if (message == nullptr) {
+ return;
+ }
+
+ uint32_t streamId = m_network->createStreamId();
+ m_network->writePeer(peerId, { NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_NXDN }, message.get(), messageLength, RTP_END_OF_CALL_SEQ, streamId, false, true);
+}
diff --git a/src/fne/network/fne/TagNXDNData.h b/src/fne/network/fne/TagNXDNData.h
index 0bd15fd7..92aab94a 100644
--- a/src/fne/network/fne/TagNXDNData.h
+++ b/src/fne/network/fne/TagNXDNData.h
@@ -17,6 +17,7 @@
#include "common/Clock.h"
#include "common/nxdn/NXDNDefines.h"
#include "common/nxdn/lc/RTCH.h"
+#include "common/nxdn/lc/RCCH.h"
#include "network/FNENetwork.h"
#include
@@ -74,6 +75,12 @@ namespace network
bool isPeerPermitted(uint32_t peerId, nxdn::lc::RTCH& lc, uint8_t messageType, uint32_t streamId);
/// Helper to validate the NXDN call stream.
bool validate(uint32_t peerId, nxdn::lc::RTCH& control, uint8_t messageType, uint32_t streamId);
+
+ /// Helper to write a deny packet.
+ void write_Message_Deny(uint32_t peerId, uint32_t srcId, uint32_t dstId, uint8_t reason, uint8_t service);
+
+ /// Helper to write a network RCCH.
+ void write_Message(uint32_t peerId, nxdn::lc::RCCH* rcch);
};
} // namespace fne
} // namespace network
diff --git a/src/fne/network/fne/TagP25Data.cpp b/src/fne/network/fne/TagP25Data.cpp
index dc8c6cc1..0f41b80a 100644
--- a/src/fne/network/fne/TagP25Data.cpp
+++ b/src/fne/network/fne/TagP25Data.cpp
@@ -684,4 +684,97 @@ bool TagP25Data::validate(uint32_t peerId, lc::LC& control, uint8_t duid, const
}
return true;
-}
\ No newline at end of file
+}
+
+///
+/// Helper to write a deny packet.
+///
+///
+///
+///
+///
+///
+void TagP25Data::write_TSDU_Deny(uint32_t peerId, uint32_t srcId, uint32_t dstId, uint8_t reason, uint8_t service, bool aiv)
+{
+ std::unique_ptr osp = std::make_unique();
+ osp->setAIV(aiv);
+ osp->setSrcId(srcId);
+ osp->setDstId(dstId);
+ osp->setService(service);
+ osp->setResponse(reason);
+
+ if (m_network->m_verbose) {
+ LogMessage(LOG_RF, P25_TSDU_STR ", %s, AIV = %u, reason = $%02X, srcId = %u, dstId = %u",
+ osp->toString().c_str(), osp->getAIV(), reason, osp->getSrcId(), osp->getDstId());
+ }
+
+ write_TSDU(peerId, osp.get());
+}
+
+///
+/// Helper to write a queue packet.
+///
+///
+///
+///
+///
+///
+///
+void TagP25Data::write_TSDU_Queue(uint32_t peerId, uint32_t srcId, uint32_t dstId, uint8_t reason, uint8_t service, bool aiv, bool grp)
+{
+ std::unique_ptr osp = std::make_unique();
+ osp->setAIV(aiv);
+ osp->setSrcId(srcId);
+ osp->setDstId(dstId);
+ osp->setService(service);
+ osp->setResponse(reason);
+ osp->setGroup(grp);
+
+ if (m_network->m_verbose) {
+ LogMessage(LOG_RF, P25_TSDU_STR ", %s, AIV = %u, reason = $%02X, srcId = %u, dstId = %u",
+ osp->toString().c_str(), osp->getAIV(), reason, osp->getSrcId(), osp->getDstId());
+ }
+
+ write_TSDU(peerId, osp.get());
+}
+
+///
+/// Helper to write a network TSDU.
+///
+///
+///
+void TagP25Data::write_TSDU(uint32_t peerId, lc::TSBK* tsbk)
+{
+ uint8_t data[P25_TSDU_FRAME_LENGTH_BYTES + 2U];
+ ::memset(data + 2U, 0x00U, P25_TSDU_FRAME_LENGTH_BYTES);
+
+ // Generate Sync
+ Sync::addP25Sync(data + 2U);
+
+ // Generate TSBK block
+ tsbk->setLastBlock(true); // always set last block -- this a Single Block TSDU
+ tsbk->encode(data + 2U);
+
+ if (m_debug) {
+ LogDebug(LOG_RF, P25_TSDU_STR ", lco = $%02X, mfId = $%02X, lastBlock = %u, AIV = %u, EX = %u, srcId = %u, dstId = %u, sysId = $%03X, netId = $%05X",
+ tsbk->getLCO(), tsbk->getMFId(), tsbk->getLastBlock(), tsbk->getAIV(), tsbk->getEX(), tsbk->getSrcId(), tsbk->getDstId(),
+ tsbk->getSysId(), tsbk->getNetId());
+
+ Utils::dump(1U, "!!! *TSDU (SBF) TSBK Block Data", data + P25_PREAMBLE_LENGTH_BYTES + 2U, P25_TSBK_FEC_LENGTH_BYTES);
+ }
+
+ lc::LC lc = lc::LC();
+ lc.setLCO(tsbk->getLCO());
+ lc.setMFId(tsbk->getMFId());
+ lc.setSrcId(tsbk->getSrcId());
+ lc.setDstId(tsbk->getDstId());
+
+ uint32_t messageLength = 0U;
+ UInt8Array message = m_network->createP25_TSDUMessage(messageLength, lc, data);
+ if (message == nullptr) {
+ return;
+ }
+
+ uint32_t streamId = m_network->createStreamId();
+ m_network->writePeer(peerId, { NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_P25 }, message.get(), messageLength, RTP_END_OF_CALL_SEQ, streamId, false, true);
+}
diff --git a/src/fne/network/fne/TagP25Data.h b/src/fne/network/fne/TagP25Data.h
index c76adc78..e7d83928 100644
--- a/src/fne/network/fne/TagP25Data.h
+++ b/src/fne/network/fne/TagP25Data.h
@@ -84,6 +84,14 @@ namespace network
bool isPeerPermitted(uint32_t peerId, p25::lc::LC& control, uint8_t duid, uint32_t streamId);
/// Helper to validate the P25 call stream.
bool validate(uint32_t peerId, p25::lc::LC& control, uint8_t duid, const p25::lc::TSBK* tsbk, uint32_t streamId);
+
+ /// Helper to write a deny packet.
+ void write_TSDU_Deny(uint32_t peerId, uint32_t srcId, uint32_t dstId, uint8_t reason, uint8_t service, bool aiv = false);
+ /// Helper to write a queue packet.
+ void write_TSDU_Queue(uint32_t peerId, uint32_t srcId, uint32_t dstId, uint8_t reason, uint8_t service, bool aiv = false, bool group = true);
+
+ /// Helper to write a network TSDU.
+ void write_TSDU(uint32_t peerId, p25::lc::TSBK* tsbk);
};
} // namespace fne
} // namespace network
diff --git a/src/host/dmr/packet/ControlSignaling.cpp b/src/host/dmr/packet/ControlSignaling.cpp
index b826f05e..81eacb76 100644
--- a/src/host/dmr/packet/ControlSignaling.cpp
+++ b/src/host/dmr/packet/ControlSignaling.cpp
@@ -442,36 +442,28 @@ void ControlSignaling::processNetwork(const data::Data & dmrData)
case SVC_KIND_IND_VOICE_CALL:
writeRF_CSBK_ACK_RSP(srcId, TS_WAIT_RSN, 1U);
- if (m_slot->m_authoritative) {
- if (!m_slot->m_affiliations->isGranted(dstId)) {
- writeRF_CSBK_Grant(srcId, dstId, isp->getServiceOptions(), false, true);
- }
+ if (!m_slot->m_affiliations->isGranted(dstId)) {
+ writeRF_CSBK_Grant(srcId, dstId, isp->getServiceOptions(), false, true);
}
break;
case SVC_KIND_GRP_VOICE_CALL:
writeRF_CSBK_ACK_RSP(srcId, TS_WAIT_RSN, 1U);
- if (m_slot->m_authoritative) {
- if (!m_slot->m_affiliations->isGranted(dstId)) {
- writeRF_CSBK_Grant(srcId, dstId, isp->getServiceOptions(), true, true);
- }
+ if (!m_slot->m_affiliations->isGranted(dstId)) {
+ writeRF_CSBK_Grant(srcId, dstId, isp->getServiceOptions(), true, true);
}
break;
case SVC_KIND_IND_DATA_CALL:
case SVC_KIND_IND_UDT_DATA_CALL:
writeRF_CSBK_ACK_RSP(srcId, TS_WAIT_RSN, 0U);
- if (!m_slot->m_affiliations->isGranted(dstId)) {
- writeRF_CSBK_Data_Grant(srcId, dstId, isp->getServiceOptions(), false, true);
- }
+ writeRF_CSBK_Data_Grant(srcId, dstId, isp->getServiceOptions(), false, true);
break;
case SVC_KIND_GRP_DATA_CALL:
case SVC_KIND_GRP_UDT_DATA_CALL:
writeRF_CSBK_ACK_RSP(srcId, TS_WAIT_RSN, 0U);
- if (!m_slot->m_affiliations->isGranted(dstId)) {
- writeRF_CSBK_Data_Grant(srcId, dstId, isp->getServiceOptions(), true, true);
- }
+ writeRF_CSBK_Data_Grant(srcId, dstId, isp->getServiceOptions(), true, true);
break;
case SVC_KIND_REG_SVC:
break;
@@ -725,7 +717,7 @@ void ControlSignaling::writeRF_CSBK(lc::CSBK* csbk, bool clearBeforeWrite, bool
*/
///
-/// Helper to write a deny packet.
+/// Helper to write a ACK RSP packet.
///
///
///
@@ -742,7 +734,7 @@ void ControlSignaling::writeRF_CSBK_ACK_RSP(uint32_t dstId, uint8_t reason, uint
}
///
-/// Helper to write a deny packet.
+/// Helper to write a NACK RSP packet.
///
///
///
diff --git a/src/host/nxdn/packet/ControlSignaling.cpp b/src/host/nxdn/packet/ControlSignaling.cpp
index af6bc030..b6c53446 100644
--- a/src/host/nxdn/packet/ControlSignaling.cpp
+++ b/src/host/nxdn/packet/ControlSignaling.cpp
@@ -257,7 +257,7 @@ bool ControlSignaling::processNetwork(uint8_t fct, uint8_t option, lc::RTCH& net
uint16_t srcId = rcch->getSrcId();
uint16_t dstId = rcch->getDstId();
- // handle standard P25 reference opcodes
+ // handle standard NXDN message opcodes
switch (rcch->getMessageType()) {
case RTCH_MESSAGE_TYPE_VCALL:
{
@@ -277,6 +277,8 @@ bool ControlSignaling::processNetwork(uint8_t fct, uint8_t option, lc::RTCH& net
}
}
return true; // don't allow this to write to the air
+ case RCCH_MESSAGE_TYPE_VCALL_CONN:
+ break; // the FNE may explicitly send these
default:
LogError(LOG_NET, "NXDN, unhandled message type, messageType = $%02X", rcch->getMessageType());
return false;
@@ -395,8 +397,7 @@ void ControlSignaling::writeRF_Message(RCCH* rcch, bool noNetwork, bool clearBef
data[1U] = 0x00U;
NXDNUtils::scrambler(data + 2U);
-
- addPostBits(data + 2U);
+ NXDNUtils::addPostBits(data + 2U);
if (!noNetwork)
writeNetwork(data, NXDN_FRAME_LENGTH_BYTES + 2U);
@@ -823,8 +824,7 @@ void ControlSignaling::writeRF_CC_Message_Site_Info()
data[1U] = 0x00U;
NXDNUtils::scrambler(data + 2U);
-
- addPostBits(data + 2U);
+ NXDNUtils::addPostBits(data + 2U);
if (m_nxdn->m_duplex) {
m_nxdn->addFrame(data, NXDN_FRAME_LENGTH_BYTES + 2U);
@@ -868,26 +868,9 @@ void ControlSignaling::writeRF_CC_Message_Service_Info()
data[1U] = 0x00U;
NXDNUtils::scrambler(data + 2U);
-
- addPostBits(data + 2U);
+ NXDNUtils::addPostBits(data + 2U);
if (m_nxdn->m_duplex) {
m_nxdn->addFrame(data, NXDN_FRAME_LENGTH_BYTES + 2U);
}
}
-
-///
-/// Helper to add the post field bits on NXDN frame data.
-///
-///
-void ControlSignaling::addPostBits(uint8_t* data)
-{
- assert(data != nullptr);
-
- // post field
- for (uint32_t i = 0U; i < NXDN_CAC_E_POST_FIELD_BITS; i++) {
- uint32_t n = i + NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_CAC_FEC_LENGTH_BITS + NXDN_CAC_E_POST_FIELD_BITS;
- bool b = READ_BIT(NXDN_PREAMBLE, i);
- WRITE_BIT(data, n, b);
- }
-}
diff --git a/src/host/nxdn/packet/ControlSignaling.h b/src/host/nxdn/packet/ControlSignaling.h
index 2aa36268..323b3f9f 100644
--- a/src/host/nxdn/packet/ControlSignaling.h
+++ b/src/host/nxdn/packet/ControlSignaling.h
@@ -106,9 +106,6 @@ namespace nxdn
void writeRF_CC_Message_Site_Info();
/// Helper to write a CC SRV_INFO broadcast packet on the RF interface.
void writeRF_CC_Message_Service_Info();
-
- /// Helper to add the post field bits on NXDN frame data.
- void addPostBits(uint8_t* data);
};
} // namespace packet
} // namespace nxdn
diff --git a/src/host/p25/packet/ControlSignaling.cpp b/src/host/p25/packet/ControlSignaling.cpp
index 1227786b..c562a753 100644
--- a/src/host/p25/packet/ControlSignaling.cpp
+++ b/src/host/p25/packet/ControlSignaling.cpp
@@ -894,12 +894,9 @@ bool ControlSignaling::processNetwork(uint8_t* data, uint32_t len, lc::LC& contr
break;
case TSBK_ISP_EMERG_ALRM_REQ:
{
- ISP_EMERG_ALRM_REQ* isp = static_cast(tsbk.get());
-
// non-emergency mode is a TSBK_OSP_DENY_RSP
- if (!isp->getEmergency()) {
- // ignore a network deny command
- return true; // don't allow this to write to the air
+ if (!tsbk->getEmergency()) {
+ break; // the FNE may explicitly send these
} else {
VERBOSE_LOG_TSBK_NET(tsbk->toString(true), srcId, dstId);
return true; // don't allow this to write to the air
@@ -915,9 +912,10 @@ bool ControlSignaling::processNetwork(uint8_t* data, uint32_t len, lc::LC& contr
case TSBK_OSP_LOC_REG_RSP:
// ignore a network location registration command
return true; // don't allow this to write to the air
+ case TSBK_OSP_U_REG_CMD:
+ break; // the FNE may explicitly send these
case TSBK_OSP_QUE_RSP:
- // ignore a network queue command
- return true; // don't allow this to write to the air
+ break; // the FNE may explicitly send these
default:
LogError(LOG_NET, P25_TSDU_STR ", unhandled LCO, mfId = $%02X, lco = $%02X", tsbk->getMFId(), tsbk->getLCO());
return false;
diff --git a/src/host/p25/packet/ControlSignaling.h b/src/host/p25/packet/ControlSignaling.h
index b566646f..dccc258a 100644
--- a/src/host/p25/packet/ControlSignaling.h
+++ b/src/host/p25/packet/ControlSignaling.h
@@ -218,7 +218,7 @@ namespace p25
bool writeNet_TSDU_Call_Term(uint32_t srcId, uint32_t dstId);
/// Helper to write a network TSDU from the RF data queue.
- void writeNet_TSDU_From_RF(lc::TSBK* tsbk, uint8_t * data);
+ void writeNet_TSDU_From_RF(lc::TSBK* tsbk, uint8_t* data);
/// Helper to automatically inhibit a source ID on a denial.
void denialInhibit(uint32_t srcId);