diff --git a/p25/dfsi/LC.cpp b/p25/dfsi/LC.cpp index 76a886bd..e683bea7 100644 --- a/p25/dfsi/LC.cpp +++ b/p25/dfsi/LC.cpp @@ -53,13 +53,16 @@ LC::LC() : m_icwFlag(P25_DFSI_DEF_ICW_SOURCE), m_rssi(0U), m_source(P25_DFSI_DEF_SOURCE), - m_control(), + m_control(nullptr), + m_lsd(nullptr), m_tsbk(nullptr), - m_lsd(), m_mi(nullptr) { m_mi = new uint8_t[P25_MI_LENGTH_BYTES]; ::memset(m_mi, 0x00U, P25_MI_LENGTH_BYTES); + + m_control = new lc::LC(); + m_lsd = new data::LowSpeedData(); } /// @@ -76,8 +79,8 @@ LC::LC(const LC& data) : LC() /// LC::LC(const lc::LC& control, const data::LowSpeedData& lsd) : LC() { - m_control = lc::LC(control); - m_lsd = data::LowSpeedData(lsd); + m_control = new lc::LC(control); + m_lsd = new data::LowSpeedData(lsd); } /// @@ -85,6 +88,12 @@ LC::LC(const lc::LC& control, const data::LowSpeedData& lsd) : LC() /// LC::~LC() { + if (m_control != nullptr) { + delete m_control; + } + if (m_lsd != nullptr) { + delete m_lsd; + } delete[] m_mi; } @@ -102,6 +111,18 @@ LC& LC::operator=(const LC& data) return *this; } +/// +/// Helper to set the LC data. +/// +/// +void LC::setControl(const lc::LC& data) +{ + if (m_control != nullptr) { + delete m_control; + } + m_control = new lc::LC(data); +} + /// /// Decode a NID start/stop. /// @@ -199,7 +220,11 @@ void LC::encodeVHDR1(uint8_t* data) bool LC::decodeVHDR2(const uint8_t* data) { assert(data != nullptr); - m_control = lc::LC(); + + if (m_control != nullptr) { + delete m_control; + } + m_control = new lc::LC(); m_frameType = data[0U]; // Frame Type if (m_frameType != P25_DFSI_VHDR2) { @@ -208,7 +233,7 @@ bool LC::decodeVHDR2(const uint8_t* data) } uint32_t dstId = (data[1U] << 16) | (data[2U] << 8) | (data[3U] << 0); - m_control.setDstId(dstId); // Talkgroup Address + m_control->setDstId(dstId); // Talkgroup Address return true; } @@ -226,7 +251,7 @@ void LC::encodeVHDR2(uint8_t* data) dfsiFrame[0U] = P25_DFSI_VHDR2; // Frame Type - uint32_t dstId = m_control.getDstId(); + uint32_t dstId = m_control->getDstId(); dfsiFrame[1U] = (dstId >> 16) & 0xFFU; // Talkgroup Address dfsiFrame[2U] = (dstId >> 8) & 0xFFU; dfsiFrame[3U] = (dstId >> 0) & 0xFFU; @@ -256,8 +281,14 @@ bool LC::decodeLDU1(const uint8_t* data, uint8_t* imbe) { case P25_DFSI_LDU1_VOICE1: { - m_control = lc::LC(); - m_lsd = data::LowSpeedData(); + if (m_control != nullptr) { + delete m_control; + } + m_control = new lc::LC(); + + if (m_lsd != nullptr) { + m_lsd = new data::LowSpeedData(); + } decodeStart(data + 1U); // Start Record m_icwFlag = data[5U]; // ICW Flag @@ -274,26 +305,26 @@ bool LC::decodeLDU1(const uint8_t* data, uint8_t* imbe) break; case P25_DFSI_LDU1_VOICE3: { - m_control.setLCO(data[1U]); // LCO - m_control.setMFId(data[2U]); // MFId + m_control->setLCO(data[1U]); // LCO + m_control->setMFId(data[2U]); // MFId uint8_t serviceOptions = (uint8_t)(data[3U]); // Service Options - m_control.setEmergency((serviceOptions & 0x80U) == 0x80U); - m_control.setEncrypted((serviceOptions & 0x40U) == 0x40U); - m_control.setPriority((serviceOptions & 0x07U)); + m_control->setEmergency((serviceOptions & 0x80U) == 0x80U); + m_control->setEncrypted((serviceOptions & 0x40U) == 0x40U); + m_control->setPriority((serviceOptions & 0x07U)); ::memcpy(imbe, data + 5U, P25_RAW_IMBE_LENGTH_BYTES); // IMBE } break; case P25_DFSI_LDU1_VOICE4: { uint32_t dstId = (data[1U] << 16) | (data[2U] << 8) | (data[3U] << 0); - m_control.setDstId(dstId); // Talkgroup Address + m_control->setDstId(dstId); // Talkgroup Address ::memcpy(imbe, data + 5U, P25_RAW_IMBE_LENGTH_BYTES); // IMBE } break; case P25_DFSI_LDU1_VOICE5: { uint32_t srcId = (data[1U] << 16) | (data[2U] << 8) | (data[3U] << 0); - m_control.setSrcId(srcId); // Source Address + m_control->setSrcId(srcId); // Source Address ::memcpy(imbe, data + 5U, P25_RAW_IMBE_LENGTH_BYTES); // IMBE } break; @@ -314,8 +345,8 @@ bool LC::decodeLDU1(const uint8_t* data, uint8_t* imbe) break; case P25_DFSI_LDU1_VOICE9: { - m_lsd.setLSD1(data[1U]); // LSD MSB - m_lsd.setLSD2(data[2U]); // LSD LSB + m_lsd->setLSD1(data[1U]); // LSD MSB + m_lsd->setLSD2(data[2U]); // LSD LSB ::memcpy(imbe, data + 4U, P25_RAW_IMBE_LENGTH_BYTES); // IMBE } break; @@ -341,9 +372,9 @@ void LC::encodeLDU1(uint8_t* data, const uint8_t* imbe) assert(imbe != nullptr); uint8_t serviceOptions = - (m_control.getEmergency() ? 0x80U : 0x00U) + - (m_control.getEncrypted() ? 0x40U : 0x00U) + - (m_control.getPriority() & 0x07U); + (m_control->getEmergency() ? 0x80U : 0x00U) + + (m_control->getEncrypted() ? 0x40U : 0x00U) + + (m_control->getPriority() & 0x07U); // determine the LDU1 DFSI frame length, its variable uint32_t frameLength = P25_DFSI_LDU1_VOICE1_FRAME_LENGTH_BYTES; @@ -399,8 +430,8 @@ void LC::encodeLDU1(uint8_t* data, const uint8_t* imbe) break; case P25_DFSI_LDU1_VOICE3: { - dfsiFrame[1U] = m_control.getLCO(); // LCO - dfsiFrame[2U] = m_control.getMFId(); // MFId + dfsiFrame[1U] = m_control->getLCO(); // LCO + dfsiFrame[2U] = m_control->getMFId(); // MFId dfsiFrame[3U] = serviceOptions; // Service Options ::memcpy(dfsiFrame + 5U, imbe, P25_RAW_IMBE_LENGTH_BYTES); // IMBE dfsiFrame[16U] = P25_DFSI_STATUS; // Status @@ -408,7 +439,7 @@ void LC::encodeLDU1(uint8_t* data, const uint8_t* imbe) break; case P25_DFSI_LDU1_VOICE4: { - uint32_t dstId = m_control.getDstId(); + uint32_t dstId = m_control->getDstId(); dfsiFrame[1U] = (dstId >> 16) & 0xFFU; // Target Address dfsiFrame[2U] = (dstId >> 8) & 0xFFU; dfsiFrame[3U] = (dstId >> 0) & 0xFFU; @@ -418,7 +449,7 @@ void LC::encodeLDU1(uint8_t* data, const uint8_t* imbe) break; case P25_DFSI_LDU1_VOICE5: { - uint32_t srcId = m_control.getSrcId(); + uint32_t srcId = m_control->getSrcId(); dfsiFrame[1U] = (srcId >> 16) & 0xFFU; // Source Address dfsiFrame[2U] = (srcId >> 8) & 0xFFU; dfsiFrame[3U] = (srcId >> 0) & 0xFFU; @@ -446,8 +477,8 @@ void LC::encodeLDU1(uint8_t* data, const uint8_t* imbe) break; case P25_DFSI_LDU1_VOICE9: { - dfsiFrame[1U] = m_lsd.getLSD1(); // LSD MSB - dfsiFrame[2U] = m_lsd.getLSD2(); // LSD LSB + dfsiFrame[1U] = m_lsd->getLSD1(); // LSD MSB + dfsiFrame[2U] = m_lsd->getLSD2(); // LSD LSB ::memcpy(dfsiFrame + 4U, imbe, P25_RAW_IMBE_LENGTH_BYTES); // IMBE } break; @@ -491,7 +522,10 @@ bool LC::decodeLDU2(const uint8_t* data, uint8_t* imbe) case P25_DFSI_LDU2_VOICE10: { ::memset(m_mi, 0x00U, P25_MI_LENGTH_BYTES); - m_lsd = data::LowSpeedData(); + if (m_lsd != nullptr) { + delete m_lsd; + } + m_lsd = new data::LowSpeedData(); decodeStart(data + 1U); // Start Record m_icwFlag = data[5U]; // ICW Flag @@ -526,15 +560,15 @@ bool LC::decodeLDU2(const uint8_t* data, uint8_t* imbe) m_mi[6U] = data[1U]; // Message Indicator m_mi[7U] = data[2U]; m_mi[8U] = data[3U]; - m_control.setMI(m_mi); + m_control->setMI(m_mi); ::memcpy(imbe, data + 5U, P25_RAW_IMBE_LENGTH_BYTES); // IMBE } break; case P25_DFSI_LDU2_VOICE15: { - m_control.setAlgId(data[1U]); // Algorithm ID + m_control->setAlgId(data[1U]); // Algorithm ID uint32_t kid = (data[2U] << 8) | (data[3U] << 0); // Key ID - m_control.setKId(kid); + m_control->setKId(kid); ::memcpy(imbe, data + 5U, P25_RAW_IMBE_LENGTH_BYTES); // IMBE } break; @@ -550,8 +584,8 @@ bool LC::decodeLDU2(const uint8_t* data, uint8_t* imbe) break; case P25_DFSI_LDU2_VOICE18: { - m_lsd.setLSD1(data[1U]); // LSD MSB - m_lsd.setLSD2(data[2U]); // LSD LSB + m_lsd->setLSD1(data[1U]); // LSD MSB + m_lsd->setLSD2(data[2U]); // LSD LSB ::memcpy(imbe, data + 4U, P25_RAW_IMBE_LENGTH_BYTES); // IMBE } break; @@ -579,7 +613,7 @@ void LC::encodeLDU2(uint8_t* data, const uint8_t* imbe) // generate MI data uint8_t mi[P25_MI_LENGTH_BYTES]; ::memset(mi, 0x00U, P25_MI_LENGTH_BYTES); - m_control.getMI(mi); + m_control->getMI(mi); // determine the LDU2 DFSI frame length, its variable uint32_t frameLength = P25_DFSI_LDU2_VOICE10_FRAME_LENGTH_BYTES; @@ -662,8 +696,8 @@ void LC::encodeLDU2(uint8_t* data, const uint8_t* imbe) break; case P25_DFSI_LDU2_VOICE15: { - dfsiFrame[1U] = m_control.getAlgId(); // Algorithm ID - uint32_t kid = m_control.getKId(); + dfsiFrame[1U] = m_control->getAlgId(); // Algorithm ID + uint32_t kid = m_control->getKId(); dfsiFrame[2U] = (kid >> 8) & 0xFFU; // Key ID dfsiFrame[3U] = (kid >> 0) & 0xFFU; ::memcpy(dfsiFrame + 5U, imbe, P25_RAW_IMBE_LENGTH_BYTES); // IMBE @@ -684,8 +718,8 @@ void LC::encodeLDU2(uint8_t* data, const uint8_t* imbe) break; case P25_DFSI_LDU2_VOICE18: { - dfsiFrame[1U] = m_lsd.getLSD1(); // LSD MSB - dfsiFrame[2U] = m_lsd.getLSD2(); // LSD LSB + dfsiFrame[1U] = m_lsd->getLSD1(); // LSD MSB + dfsiFrame[2U] = m_lsd->getLSD2(); // LSD LSB ::memcpy(dfsiFrame + 4U, imbe, P25_RAW_IMBE_LENGTH_BYTES); // IMBE } break; @@ -788,9 +822,8 @@ void LC::copy(const LC& data) m_rssi = data.m_rssi; m_source = data.m_source; - m_control = lc::LC(data.m_control); - //m_tsbk = lc::TSBK(data.m_tsbk); - m_lsd = data.m_lsd; + m_control = new lc::LC(*data.m_control); + m_lsd = new data::LowSpeedData(*data.m_lsd); delete[] m_mi; diff --git a/p25/dfsi/LC.h b/p25/dfsi/LC.h index 6f0f2122..529e5b4e 100644 --- a/p25/dfsi/LC.h +++ b/p25/dfsi/LC.h @@ -56,6 +56,9 @@ namespace p25 /// Equals operator. LC& operator=(const LC& data); + /// Helper to set the LC data. + void setControl(const lc::LC& data); + /// Decode a NID start/stop. bool decodeNID(const uint8_t* data); /// Encode a NID start/stop. @@ -106,11 +109,11 @@ namespace p25 __PROPERTY(uint8_t, source, Source); /// Link control data. - __PROPERTY_PLAIN(p25::lc::LC, control, control); + __READONLY_PROPERTY_PLAIN(p25::lc::LC*, control, control); + /// Low speed data. + __READONLY_PROPERTY_PLAIN(p25::data::LowSpeedData*, lsd, lsd); /// TSBK. __PROPERTY_PLAIN(p25::lc::TSBK*, tsbk, tsbk); - /// Low speed data. - __PROPERTY_PLAIN(p25::data::LowSpeedData, lsd, lsd); private: /** Encryption data */ diff --git a/p25/dfsi/packet/DFSIVoice.cpp b/p25/dfsi/packet/DFSIVoice.cpp index f1ce1caf..d4be64d3 100644 --- a/p25/dfsi/packet/DFSIVoice.cpp +++ b/p25/dfsi/packet/DFSIVoice.cpp @@ -113,7 +113,7 @@ bool DFSIVoice::process(uint8_t* data, uint32_t len) return false; } - m_rfLC = m_rfDFSILC.control(); + m_rfLC = lc::LC(*m_rfDFSILC.control()); if (m_verbose) { LogMessage(LOG_RF, P25_HDU_STR " DFSI, HDU_BSDWNACT, dstId = %u, algo = $%02X, kid = $%04X", m_rfLC.getDstId(), m_rfLC.getAlgId(), m_rfLC.getKId()); @@ -196,7 +196,7 @@ bool DFSIVoice::process(uint8_t* data, uint32_t len) } } - lc::LC lc = m_rfDFSILC.control(); + lc::LC lc = lc::LC(*m_rfDFSILC.control()); uint32_t srcId = lc.getSrcId(); uint32_t dstId = lc.getDstId(); @@ -412,7 +412,7 @@ bool DFSIVoice::process(uint8_t* data, uint32_t len) if (m_p25->m_rfState == RS_RF_AUDIO) { if (!alreadyDecoded) { - m_rfLC = m_rfDFSILC.control(); + m_rfLC = lc::LC(*m_rfDFSILC.control()); m_rfLastLDU1 = m_rfLC; } @@ -519,7 +519,7 @@ bool DFSIVoice::process(uint8_t* data, uint32_t len) return false; } else if (m_p25->m_rfState == RS_RF_AUDIO) { - m_rfLC = m_rfDFSILC.control(); + m_rfLC = lc::LC(*m_rfDFSILC.control()); m_rfLastLDU2 = m_rfLC; uint8_t buffer[P25_LDU_FRAME_LENGTH_BYTES + 2U]; @@ -869,8 +869,8 @@ void DFSIVoice::writeNet_TDU() /// void DFSIVoice::writeNet_LDU1() { - lc::LC control = lc::LC(m_dfsiLC.control()); - data::LowSpeedData lsd = data::LowSpeedData(m_dfsiLC.lsd()); + lc::LC control = lc::LC(*m_dfsiLC.control()); + data::LowSpeedData lsd = data::LowSpeedData(*m_dfsiLC.lsd()); uint32_t dstId = control.getDstId(); uint32_t srcId = control.getSrcId(); @@ -1032,8 +1032,7 @@ void DFSIVoice::writeNet_LDU1() m_netLost = 0U; m_vocLDU1Count = 0U; - m_netDFSILC.control(m_netLC); - m_netDFSILC.lsd(lsd); + m_netDFSILC = dfsi::LC(m_netLC, lsd); m_trunk->writeRF_DFSI_Start(P25_DFSI_TYPE_VOICE); @@ -1163,8 +1162,8 @@ void DFSIVoice::writeNet_LDU1() /// void DFSIVoice::writeNet_LDU2() { - lc::LC control = lc::LC(m_dfsiLC.control()); - data::LowSpeedData lsd = data::LowSpeedData(m_dfsiLC.lsd()); + lc::LC control = lc::LC(*m_dfsiLC.control()); + data::LowSpeedData lsd = data::LowSpeedData(*m_dfsiLC.lsd()); // don't process network frames if the destination ID's don't match and the network TG hang timer is running if (m_p25->m_rfLastDstId != 0U) { @@ -1185,7 +1184,7 @@ void DFSIVoice::writeNet_LDU2() m_netLC.setAlgId(control.getAlgId()); m_netLC.setKId(control.getKId()); - m_netDFSILC.control(m_netLC); + m_netDFSILC.setControl(m_netLC); insertMissingAudio(m_netLDU2); diff --git a/p25/packet/Voice.cpp b/p25/packet/Voice.cpp index 4a9c3c57..8d3e4e71 100644 --- a/p25/packet/Voice.cpp +++ b/p25/packet/Voice.cpp @@ -1050,8 +1050,12 @@ void Voice::checkNet_LDU1() /// void Voice::writeNet_LDU1() { - lc::LC control = lc::LC(m_dfsiLC.control()); - data::LowSpeedData lsd = data::LowSpeedData(m_dfsiLC.lsd()); + lc::LC control = lc::LC(*m_dfsiLC.control()); + + // because the lc::LC internal copy routine will reset the encrypted flag -- lets force it + control.setEncrypted(m_dfsiLC.control()->getEncrypted()); + + data::LowSpeedData lsd = data::LowSpeedData(*m_dfsiLC.lsd()); uint32_t dstId = control.getDstId(); uint32_t srcId = control.getSrcId(); @@ -1120,6 +1124,12 @@ void Voice::writeNet_LDU1() m_p25->m_affiliations.touchGrant(m_rfLC.getDstId()); } + if (m_debug) { + LogMessage(LOG_NET, P25_LDU1_STR " service flags, emerg = %u, encrypt = %u, prio = %u, DFSI emerg = %u, DFSI encrypt = %u, DFSI prio = %u", + control.getEmergency(), control.getEncrypted(), control.getPriority(), + m_dfsiLC.control()->getEmergency(), m_dfsiLC.control()->getEncrypted(), m_dfsiLC.control()->getPriority()); + } + // set network and RF link control states m_netLC = lc::LC(); m_netLC.setLCO(control.getLCO()); @@ -1348,8 +1358,8 @@ void Voice::checkNet_LDU2() /// void Voice::writeNet_LDU2() { - lc::LC control = lc::LC(m_dfsiLC.control()); - data::LowSpeedData lsd = data::LowSpeedData(m_dfsiLC.lsd()); + lc::LC control = lc::LC(*m_dfsiLC.control()); + data::LowSpeedData lsd = data::LowSpeedData(*m_dfsiLC.lsd()); // don't process network frames if the destination ID's don't match and the network TG hang timer is running if (m_p25->m_rfLastDstId != 0U) {