diff --git a/host/Host.cpp b/host/Host.cpp index 518b848a..ba1f7bea 100644 --- a/host/Host.cpp +++ b/host/Host.cpp @@ -1029,44 +1029,48 @@ int Host::run() } } else { - // if we have no P25 data, and we're either idle or P25 state, check if we - // need to be starting the CC running flag or writing end of voice call data - if (m_state == STATE_IDLE || m_state == STATE_P25) { - if (p25->getCCHalted()) { - p25->setCCHalted(false); - } - - // write end of voice if necessary - ret = p25->writeRF_VoiceEnd(); - if (ret) { - if (m_state == STATE_IDLE) { - m_modeTimer.setTimeout(m_netModeHang); - setState(STATE_P25); - } - - if (m_state == STATE_P25) { - m_modeTimer.start(); - } - } - } + nextLen = 0U; } + } + } - // if the modem is in duplex -- handle P25 CC burst control - if (m_duplex) { - if (p25BcastDurationTimer.isPaused() && !p25->getCCHalted()) { - p25BcastDurationTimer.resume(); - } + if (nextLen == 0U) { + // if we have no P25 data, and we're either idle or P25 state, check if we + // need to be starting the CC running flag or writing end of voice call data + if (m_state == STATE_IDLE || m_state == STATE_P25) { + if (p25->getCCHalted()) { + p25->setCCHalted(false); + } - if (p25->getCCHalted()) { - p25->setCCHalted(false); + // write end of voice if necessary + ret = p25->writeRF_VoiceEnd(); + if (ret) { + if (m_state == STATE_IDLE) { + m_modeTimer.setTimeout(m_netModeHang); + setState(STATE_P25); } - if (g_fireP25Control) { - m_modeTimer.stop(); + if (m_state == STATE_P25) { + m_modeTimer.start(); } } } } + + // if the modem is in duplex -- handle P25 CC burst control + if (m_duplex) { + if (p25BcastDurationTimer.isPaused() && !p25->getCCHalted()) { + p25BcastDurationTimer.resume(); + } + + if (p25->getCCHalted()) { + p25->setCCHalted(false); + } + + if (g_fireP25Control) { + m_modeTimer.stop(); + } + } } #endif // defined(ENABLE_P25) diff --git a/p25/lc/TDULC.cpp b/p25/lc/TDULC.cpp index 5d917b08..bff5413a 100644 --- a/p25/lc/TDULC.cpp +++ b/p25/lc/TDULC.cpp @@ -199,7 +199,7 @@ bool TDULC::decode(const uint8_t* data, uint8_t* rs) } if (m_verbose) { - Utils::dump(2U, "Decoded TDULC", rs, P25_TDULC_LENGTH_BYTES); + Utils::dump(2U, "TDULC::decode(), TDULC Value", rs, P25_TDULC_LENGTH_BYTES); } return true; @@ -215,17 +215,18 @@ void TDULC::encode(uint8_t* data, const uint8_t* rs) assert(data != nullptr); assert(rs != nullptr); - if (m_verbose) { - Utils::dump(2U, "Encoded TDULC", rs, P25_TDULC_LENGTH_BYTES); - } - uint8_t outRs[P25_TDULC_LENGTH_BYTES]; ::memset(outRs, 0x00U, P25_TDULC_LENGTH_BYTES); ::memcpy(outRs, rs, P25_TDULC_LENGTH_BYTES); + outRs[0U] = m_lco; // LCO if (m_implicit) outRs[0U] |= 0x40U; // Implicit Operation + if (m_verbose) { + Utils::dump(2U, "TDULC::encode(), TDULC Value", outRs, P25_TDULC_LENGTH_BYTES); + } + // encode RS (24,12,13) FEC m_rs.encode241213(outRs); diff --git a/p25/lc/TSBK.cpp b/p25/lc/TSBK.cpp index a117ac7f..31adf050 100644 --- a/p25/lc/TSBK.cpp +++ b/p25/lc/TSBK.cpp @@ -257,7 +257,7 @@ bool TSBK::decode(const uint8_t* data, uint8_t* tsbk, bool rawTSBK) } if (m_verbose) { - Utils::dump(2U, "Decoded TSBK", tsbk, P25_TSBK_LENGTH_BYTES); + Utils::dump(2U, "TSBK::decode(), TSBK Value", tsbk, P25_TSBK_LENGTH_BYTES); } m_lco = tsbk[0U] & 0x3F; // LCO diff --git a/p25/packet/Trunk.cpp b/p25/packet/Trunk.cpp index 0d4979f1..1ca1fdac 100644 --- a/p25/packet/Trunk.cpp +++ b/p25/packet/Trunk.cpp @@ -197,6 +197,8 @@ bool Trunk::process(uint8_t* data, uint32_t len, lc::TSBK* preDecodedTSBK) uint32_t srcId = tsbk->getSrcId(); uint32_t dstId = tsbk->getDstId(); + m_lastMFID = tsbk->getMFId(); + // handle standard P25 reference opcodes switch (tsbk->getLCO()) { case TSBK_IOSP_GRP_VCH: @@ -1151,6 +1153,7 @@ void Trunk::setTSBKVerbose(bool verbose) { m_dumpTSBK = verbose; lc::TSBK::setVerbose(verbose); + lc::TDULC::setVerbose(verbose); } // --------------------------------------------------------------------------- @@ -1181,6 +1184,7 @@ Trunk::Trunk(Control* p25, network::BaseNetwork* network, bool dumpTSBKData, boo m_adjSiteUpdateCnt(), m_sccbTable(), m_sccbUpdateCnt(), + m_lastMFID(P25_MFG_STANDARD), m_noStatusAck(false), m_noMessageAck(true), m_unitToUnitAvailCheck(true), @@ -1208,6 +1212,9 @@ Trunk::Trunk(Control* p25, network::BaseNetwork* network, bool dumpTSBKData, boo m_adjSiteUpdateInterval = ADJ_SITE_TIMER_TIMEOUT; m_adjSiteUpdateTimer.setTimeout(m_adjSiteUpdateInterval); m_adjSiteUpdateTimer.start(); + + lc::TSBK::setVerbose(verbose); + lc::TDULC::setVerbose(verbose); } /// @@ -2195,6 +2202,7 @@ bool Trunk::writeRF_TSDU_Grant(uint32_t srcId, uint32_t dstId, uint8_t serviceOp } std::unique_ptr iosp = new_unique(IOSP_GRP_VCH); + iosp->setMFId(m_lastMFID); iosp->setSrcId(srcId); iosp->setDstId(dstId); iosp->setGrpVchNo(chNo); @@ -2216,6 +2224,7 @@ bool Trunk::writeRF_TSDU_Grant(uint32_t srcId, uint32_t dstId, uint8_t serviceOp } std::unique_ptr iosp = new_unique(IOSP_UU_VCH); + iosp->setMFId(m_lastMFID); iosp->setSrcId(srcId); iosp->setDstId(dstId); iosp->setGrpVchNo(chNo); @@ -2247,6 +2256,7 @@ bool Trunk::writeRF_TSDU_Grant(uint32_t srcId, uint32_t dstId, uint8_t serviceOp bool Trunk::writeRF_TSDU_SNDCP_Grant(uint32_t srcId, uint32_t dstId, bool skip, bool net) { std::unique_ptr osp = new_unique(OSP_SNDCP_CH_GNT); + osp->setMFId(m_lastMFID); osp->setSrcId(srcId); osp->setDstId(dstId); @@ -2320,6 +2330,7 @@ bool Trunk::writeRF_TSDU_SNDCP_Grant(uint32_t srcId, uint32_t dstId, bool skip, void Trunk::writeRF_TSDU_UU_Ans_Req(uint32_t srcId, uint32_t dstId) { std::unique_ptr iosp = new_unique(IOSP_UU_ANS); + iosp->setMFId(m_lastMFID); iosp->setSrcId(srcId); iosp->setDstId(dstId); @@ -2339,6 +2350,7 @@ void Trunk::writeRF_TSDU_UU_Ans_Req(uint32_t srcId, uint32_t dstId) void Trunk::writeRF_TSDU_ACK_FNE(uint32_t srcId, uint32_t service, bool extended, bool noNetwork) { std::unique_ptr iosp = new_unique(IOSP_ACK_RSP); + iosp->setMFId(m_lastMFID); iosp->setSrcId(srcId); iosp->setService(service); @@ -2365,6 +2377,7 @@ void Trunk::writeRF_TSDU_ACK_FNE(uint32_t srcId, uint32_t service, bool extended void Trunk::writeRF_TSDU_Deny(uint32_t dstId, uint8_t reason, uint8_t service, bool aiv) { std::unique_ptr osp = new_unique(OSP_DENY_RSP); + osp->setMFId(m_lastMFID); osp->setAIV(aiv); osp->setSrcId(P25_WUID_FNE); osp->setDstId(dstId); @@ -2389,6 +2402,7 @@ bool Trunk::writeRF_TSDU_Grp_Aff_Rsp(uint32_t srcId, uint32_t dstId) bool ret = false; std::unique_ptr iosp = new_unique(IOSP_GRP_AFF); + iosp->setMFId(m_lastMFID); iosp->setAnnounceGroup(m_patchSuperGroup); // this isn't right... iosp->setSrcId(srcId); iosp->setDstId(dstId); @@ -2445,6 +2459,7 @@ bool Trunk::writeRF_TSDU_Grp_Aff_Rsp(uint32_t srcId, uint32_t dstId) void Trunk::writeRF_TSDU_U_Reg_Rsp(uint32_t srcId, uint32_t sysId) { std::unique_ptr iosp = new_unique(IOSP_U_REG); + iosp->setMFId(m_lastMFID); iosp->setResponse(P25_RSP_ACCEPT); iosp->setSrcId(srcId); iosp->setDstId(srcId); @@ -2503,6 +2518,7 @@ void Trunk::writeRF_TSDU_U_Dereg_Ack(uint32_t srcId) ::ActivityLog("P25", true, "unit deregistration request from %u", srcId); std::unique_ptr osp = new_unique(OSP_U_DEREG_ACK); + osp->setMFId(m_lastMFID); osp->setSrcId(P25_WUID_FNE); osp->setDstId(srcId); @@ -2523,6 +2539,7 @@ void Trunk::writeRF_TSDU_U_Dereg_Ack(uint32_t srcId) void Trunk::writeRF_TSDU_Queue(uint32_t dstId, uint8_t reason, uint8_t service, bool aiv) { std::unique_ptr osp = new_unique(OSP_QUE_RSP); + osp->setMFId(m_lastMFID); osp->setAIV(aiv); osp->setSrcId(P25_WUID_FNE); osp->setDstId(dstId); @@ -2548,6 +2565,7 @@ bool Trunk::writeRF_TSDU_Loc_Reg_Rsp(uint32_t srcId, uint32_t dstId, bool grp) bool ret = false; std::unique_ptr osp = new_unique(OSP_LOC_REG_RSP); + osp->setMFId(m_lastMFID); osp->setResponse(P25_RSP_ACCEPT); osp->setDstId(dstId); osp->setSrcId(srcId); diff --git a/p25/packet/Trunk.h b/p25/packet/Trunk.h index c4c8a152..f06ba68a 100644 --- a/p25/packet/Trunk.h +++ b/p25/packet/Trunk.h @@ -127,6 +127,8 @@ namespace p25 std::unordered_map m_sccbTable; std::unordered_map m_sccbUpdateCnt; + uint8_t m_lastMFID; + bool m_noStatusAck; bool m_noMessageAck; bool m_unitToUnitAvailCheck;