diff --git a/host/Host.cpp b/host/Host.cpp
index 29eae300..834290f0 100644
--- a/host/Host.cpp
+++ b/host/Host.cpp
@@ -485,6 +485,11 @@ int Host::run()
g_killed = true;
}
+ if (!m_duplex && m_dmrBeacons) {
+ ::LogError(LOG_HOST, "Cannot have DMR roaming beacons and simplex mode at the same time.");
+ g_killed = true;
+ }
+
if (!m_duplex && m_controlData) {
::LogError(LOG_HOST, "Cannot have P25 control and simplex mode at the same time.");
g_killed = true;
diff --git a/network/UDPSocket.cpp b/network/UDPSocket.cpp
index f098b1a1..7ea661ff 100644
--- a/network/UDPSocket.cpp
+++ b/network/UDPSocket.cpp
@@ -246,7 +246,7 @@ int UDPSocket::read(uint8_t* buffer, uint32_t length, sockaddr_storage& address,
LogError(LOG_NET, "Error returned from recvfrom, err: %d", errno);
if (len == -1 && errno == ENOTSOCK) {
- LogMessage(LOG_NET, "Re-opening UDP port on %u", m_port);
+ LogMessage(LOG_NET, "Re-opening UDP port on %u", m_port[index]);
close();
open();
}
diff --git a/p25/TrunkPacket.cpp b/p25/TrunkPacket.cpp
index cf8f2fed..7a062e81 100644
--- a/p25/TrunkPacket.cpp
+++ b/p25/TrunkPacket.cpp
@@ -315,6 +315,9 @@ bool TrunkPacket::process(uint8_t* data, uint32_t len)
{
assert(data != NULL);
+ if (!m_p25->m_control)
+ return false;
+
// Decode the NID
bool valid = m_p25->m_nid.decode(data + 2U);
@@ -666,6 +669,8 @@ bool TrunkPacket::process(uint8_t* data, uint32_t len)
///
bool TrunkPacket::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::LowSpeedData& lsd, uint8_t& duid)
{
+ if (!m_p25->m_control)
+ return false;
if (m_p25->m_rfState != RS_RF_LISTENING && m_p25->m_netState == RS_NET_IDLE)
return false;
@@ -1428,9 +1433,8 @@ void TrunkPacket::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adjSS)
{
uint8_t i = 0U, seqCnt = 0U;
- if (!m_p25->m_control) {
+ if (!m_p25->m_control)
return;
- }
// loop to generate 6 control sequences
if (frameCnt == 255U) {
@@ -1565,26 +1569,28 @@ void TrunkPacket::writeRF_TDULC_ChanRelease(bool grp, uint32_t srcId, uint32_t d
{
uint32_t count = m_p25->m_hangCount / 2;
- for (uint32_t i = 0; i < count; i++) {
- if ((srcId != 0U) && (dstId != 0U)) {
- m_rfTDULC.setSrcId(srcId);
- m_rfTDULC.setDstId(dstId);
- m_rfTDULC.setEmergency(false);
+ if (m_p25->m_control) {
+ for (uint32_t i = 0; i < count; i++) {
+ if ((srcId != 0U) && (dstId != 0U)) {
+ m_rfTDULC.setSrcId(srcId);
+ m_rfTDULC.setDstId(dstId);
+ m_rfTDULC.setEmergency(false);
- if (grp) {
- m_rfTDULC.setLCO(LC_GROUP);
- writeRF_TDULC(P25_DUID_TDULC, true);
- }
- else {
- m_rfTDULC.setLCO(LC_PRIVATE);
- writeRF_TDULC(P25_DUID_TDULC, true);
+ if (grp) {
+ m_rfTDULC.setLCO(LC_GROUP);
+ writeRF_TDULC(P25_DUID_TDULC, true);
+ }
+ else {
+ m_rfTDULC.setLCO(LC_PRIVATE);
+ writeRF_TDULC(P25_DUID_TDULC, true);
+ }
}
- }
- m_rfTDULC.setLCO(LC_NET_STS_BCAST);
- writeRF_TDULC(P25_DUID_TDULC, true);
- m_rfTDULC.setLCO(LC_RFSS_STS_BCAST);
- writeRF_TDULC(P25_DUID_TDULC, true);
+ m_rfTDULC.setLCO(LC_NET_STS_BCAST);
+ writeRF_TDULC(P25_DUID_TDULC, true);
+ m_rfTDULC.setLCO(LC_RFSS_STS_BCAST);
+ writeRF_TDULC(P25_DUID_TDULC, true);
+ }
}
if (m_verbose) {
@@ -1604,6 +1610,9 @@ void TrunkPacket::writeRF_TDULC_ChanRelease(bool grp, uint32_t srcId, uint32_t d
///
void TrunkPacket::writeRF_TSDU_SBF(bool noNetwork, bool clearBeforeWrite)
{
+ if (!m_p25->m_control)
+ return;
+
uint8_t data[P25_TSDU_FRAME_LENGTH_BYTES + 2U];
::memset(data + 2U, 0x00U, P25_TSDU_FRAME_LENGTH_BYTES);
@@ -1663,12 +1672,18 @@ void TrunkPacket::writeRF_TSDU_SBF(bool noNetwork, bool clearBeforeWrite)
///
void TrunkPacket::writeRF_TSDU_MBF(bool clearBeforeWrite)
{
+ if (!m_p25->m_control) {
+ ::memset(m_rfMBF, 0x00U, P25_MAX_PDU_COUNT * P25_LDU_FRAME_LENGTH_BYTES + 2U);
+ m_mbfCnt = 0U;
+ return;
+ }
+
uint8_t tsbk[P25_TSBK_FEC_LENGTH_BYTES];
::memset(tsbk, 0x00U, P25_TSBK_FEC_LENGTH_BYTES);
// LogDebug(LOG_P25, "writeRF_TSDU_MBF, mbfCnt = %u", m_mbfCnt);
- // can't transmit MBF with duplex disabled
+ // trunking data is unsupported in simplex operation
if (!m_p25->m_duplex) {
::memset(m_rfMBF, 0x00U, P25_MAX_PDU_COUNT * P25_LDU_FRAME_LENGTH_BYTES + 2U);
m_mbfCnt = 0U;
@@ -1767,6 +1782,9 @@ void TrunkPacket::writeRF_TSDU_MBF(bool clearBeforeWrite)
///
void TrunkPacket::queueRF_TSBK_Ctrl_MBF(uint8_t lco)
{
+ if (!m_p25->m_control)
+ return;
+
m_rfTSBK.reset();
switch (lco) {
@@ -2274,6 +2292,7 @@ void TrunkPacket::writeRF_TSDU_U_Reg_Rsp(uint32_t srcId)
void TrunkPacket::writeRF_TSDU_U_Dereg_Ack(uint32_t srcId)
{
bool dereged = false;
+
m_rfTSBK.setLCO(TSBK_OSP_U_DEREG_ACK);
if (m_verbose) {
diff --git a/p25/VoicePacket.cpp b/p25/VoicePacket.cpp
index df02d64b..b874b4e4 100644
--- a/p25/VoicePacket.cpp
+++ b/p25/VoicePacket.cpp
@@ -167,10 +167,15 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
LogWarning(LOG_RF, "Traffic collision detect, preempting existing network traffic to new RF traffic, rfDstId = %u, netDstId = %u", m_rfLC.getDstId(),
m_p25->m_netLastDstId);
resetNet();
- m_p25->writeRF_TDU(true);
+
+ if (m_p25->m_duplex) {
+ m_p25->writeRF_TDU(true);
+ }
}
- m_p25->writeRF_Preamble();
+ if (m_p25->m_duplex) {
+ m_p25->writeRF_Preamble();
+ }
m_p25->m_rfTGHang.start();
m_p25->m_rfLastDstId = m_rfLC.getDstId();
@@ -188,8 +193,10 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
m_lastDUID = P25_DUID_LDU1;
if (m_p25->m_rfState == RS_RF_LISTENING) {
- if (!m_p25->m_ccRunning && m_p25->m_voiceOnControl) {
- m_p25->m_trunk->writeRF_ControlData(255U, 0U, false);
+ if (m_p25->m_control) {
+ if (!m_p25->m_ccRunning && m_p25->m_voiceOnControl) {
+ m_p25->m_trunk->writeRF_ControlData(255U, 0U, false);
+ }
}
bool ret = m_rfLC.decodeLDU1(data + 2U);
@@ -234,8 +241,10 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
if (!acl::AccessControl::validateSrcId(srcId)) {
if (m_lastRejectId == 0U || m_lastRejectId != srcId) {
LogWarning(LOG_RF, P25_HDU_STR " denial, RID rejection, srcId = %u", srcId);
- m_p25->m_trunk->writeRF_TSDU_Deny(P25_DENY_RSN_REQ_UNIT_NOT_VALID, (m_rfLC.getGroup() ? TSBK_IOSP_GRP_VCH : TSBK_IOSP_UU_VCH));
- m_p25->m_trunk->denialInhibit(srcId);
+ if (m_p25->m_control) {
+ m_p25->m_trunk->writeRF_TSDU_Deny(P25_DENY_RSN_REQ_UNIT_NOT_VALID, (m_rfLC.getGroup() ? TSBK_IOSP_GRP_VCH : TSBK_IOSP_UU_VCH));
+ m_p25->m_trunk->denialInhibit(srcId);
+ }
::ActivityLog("P25", true, "RF voice rejection from %u to %s%u ", srcId, m_rfLC.getGroup() ? "TG " : "", dstId);
m_lastRejectId = srcId;
@@ -253,7 +262,9 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
if (!acl::AccessControl::validateSrcId(dstId)) {
if (m_lastRejectId == 0 || m_lastRejectId != dstId) {
LogWarning(LOG_RF, P25_HDU_STR " denial, RID rejection, dstId = %u", dstId);
- m_p25->m_trunk->writeRF_TSDU_Deny(P25_DENY_RSN_TGT_UNIT_NOT_VALID, TSBK_IOSP_UU_VCH);
+ if (m_p25->m_control) {
+ m_p25->m_trunk->writeRF_TSDU_Deny(P25_DENY_RSN_TGT_UNIT_NOT_VALID, TSBK_IOSP_UU_VCH);
+ }
::ActivityLog("P25", true, "RF voice rejection from %u to %s%u ", srcId, m_rfLC.getGroup() ? "TG " : "", dstId);
m_lastRejectId = dstId;
@@ -270,7 +281,9 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
if (!acl::AccessControl::validateTGId(dstId)) {
if (m_lastRejectId == 0 || m_lastRejectId != dstId) {
LogWarning(LOG_RF, P25_HDU_STR " denial, TGID rejection, dstId = %u", dstId);
- m_p25->m_trunk->writeRF_TSDU_Deny(P25_DENY_RSN_TGT_GROUP_NOT_VALID, TSBK_IOSP_GRP_VCH);
+ if (m_p25->m_control) {
+ m_p25->m_trunk->writeRF_TSDU_Deny(P25_DENY_RSN_TGT_GROUP_NOT_VALID, TSBK_IOSP_GRP_VCH);
+ }
::ActivityLog("P25", true, "RF voice rejection from %u to %s%u ", srcId, m_rfLC.getGroup() ? "TG " : "", dstId);
m_lastRejectId = dstId;
@@ -832,7 +845,7 @@ bool VoicePacket::writeEndRF()
m_hadVoice = false;
}
- if (!m_p25->m_ccRunning) {
+ if (m_p25->m_control && !m_p25->m_ccRunning) {
m_p25->m_trunk->writeRF_ControlData(255U, 0U, false);
m_p25->writeControlEndRF();
}