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) {