From 45bd8519a396c13a470a43a9a4237806c21ce344 Mon Sep 17 00:00:00 2001 From: Bryan Biedenkapp Date: Sat, 26 Feb 2022 00:32:32 -0500 Subject: [PATCH] fix copy constructor and equality operator for LC, TDULC and TSBK (it was not properly copying the classes in all situations); refactor VoicePacket to use DFSI to demangle LDU1/LDU2 network packets; --- p25/VoicePacket.cpp | 205 ++++++++++++++++++++++---------------------- p25/VoicePacket.h | 10 ++- p25/dfsi/LC.cpp | 70 +++++++++------ p25/dfsi/LC.h | 11 ++- p25/lc/LC.cpp | 117 ++++++++++++++----------- p25/lc/LC.h | 5 ++ p25/lc/TDULC.cpp | 81 +++++++++++------ p25/lc/TDULC.h | 7 ++ p25/lc/TSBK.cpp | 137 ++++++++++++++++------------- p25/lc/TSBK.h | 5 ++ 10 files changed, 377 insertions(+), 271 deletions(-) diff --git a/p25/VoicePacket.cpp b/p25/VoicePacket.cpp index 7851471c..4df86fa9 100644 --- a/p25/VoicePacket.cpp +++ b/p25/VoicePacket.cpp @@ -32,6 +32,7 @@ #include "p25/P25Defines.h" #include "p25/VoicePacket.h" #include "p25/acl/AccessControl.h" +#include "p25/dfsi/DFSIDefines.h" #include "p25/P25Utils.h" #include "p25/Sync.h" #include "edac/CRC.h" @@ -685,46 +686,48 @@ bool VoicePacket::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, d switch (duid) { case P25_DUID_LDU1: - // The '62', '63', '64', '65', '66', '67', '68', '69', '6A' records are LDU1 - if ((data[0U] == 0x62U) && (data[22U] == 0x63U) && - (data[36U] == 0x64U) && (data[53U] == 0x65U) && - (data[70U] == 0x66U) && (data[87U] == 0x67U) && - (data[104U] == 0x68U) && (data[121U] == 0x69U) && - (data[138U] == 0x6AU)) { - // The '62' record - IMBE Voice 1 - ::memcpy(m_netLDU1 + 0U, data + count, 22U); + if ((data[0U] == dfsi::P25_DFSI_LDU1_VOICE1) && (data[22U] == dfsi::P25_DFSI_LDU1_VOICE2) && + (data[36U] == dfsi::P25_DFSI_LDU1_VOICE3) && (data[53U] == dfsi::P25_DFSI_LDU1_VOICE4) && + (data[70U] == dfsi::P25_DFSI_LDU1_VOICE5) && (data[87U] == dfsi::P25_DFSI_LDU1_VOICE6) && + (data[104U] == dfsi::P25_DFSI_LDU1_VOICE7) && (data[121U] == dfsi::P25_DFSI_LDU1_VOICE8) && + (data[138U] == dfsi::P25_DFSI_LDU1_VOICE9)) { + + m_dfsiLC = dfsi::LC(control, lsd); + + m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE1); + m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 10U); count += 22U; - // The '63' record - IMBE Voice 2 - ::memcpy(m_netLDU1 + 25U, data + count, 14U); + m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE2); + m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 26U); count += 14U; - // The '64' record - IMBE Voice 3 + Link Control - ::memcpy(m_netLDU1 + 50U, data + count, 17U); + m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE3); + m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 55U); count += 17U; - // The '65' record - IMBE Voice 4 + Link Control - ::memcpy(m_netLDU1 + 75U, data + count, 17U); + m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE4); + m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 80U); count += 17U; - // The '66' record - IMBE Voice 5 + Link Control - ::memcpy(m_netLDU1 + 100U, data + count, 17U); + m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE5); + m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 105U); count += 17U; - // The '67' record - IMBE Voice 6 + Link Control - ::memcpy(m_netLDU1 + 125U, data + count, 17U); + m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE6); + m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 130U); count += 17U; - // The '68' record - IMBE Voice 7 + Link Control - ::memcpy(m_netLDU1 + 150U, data + count, 17U); + m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE7); + m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 155U); count += 17U; - // The '69' record - IMBE Voice 8 + Link Control - ::memcpy(m_netLDU1 + 175U, data + count, 17U); + m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE8); + m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 180U); count += 17U; - // The '6A' record - IMBE Voice 9 + Low Speed Data - ::memcpy(m_netLDU1 + 200U, data + count, 16U); + m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE9); + m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 204U); count += 16U; m_netLastLDU1 = control; @@ -741,53 +744,52 @@ bool VoicePacket::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, d } } - checkNet_LDU2(control, lsd); + checkNet_LDU2(); if (m_p25->m_netState != RS_NET_IDLE) { - writeNet_LDU1(control, lsd); + writeNet_LDU1(); } } break; case P25_DUID_LDU2: - // The '6B', '6C', '6D', '6E', '6F', '70', '71', '72', '73' records are LDU2 - if ((data[0U] == 0x6BU) && (data[22U] == 0x6CU) && - (data[36U] == 0x6DU) && (data[53U] == 0x6EU) && - (data[70U] == 0x6FU) && (data[87U] == 0x70U) && - (data[104U] == 0x71U) && (data[121U] == 0x72U) && - (data[138U] == 0x73U)) { - // The '6B' record - IMBE Voice 10 - ::memcpy(m_netLDU2 + 0U, data + count, 22U); + if ((data[0U] == dfsi::P25_DFSI_LDU2_VOICE10) && (data[22U] == dfsi::P25_DFSI_LDU2_VOICE11) && + (data[36U] == dfsi::P25_DFSI_LDU2_VOICE12) && (data[53U] == dfsi::P25_DFSI_LDU2_VOICE13) && + (data[70U] == dfsi::P25_DFSI_LDU2_VOICE14) && (data[87U] == dfsi::P25_DFSI_LDU2_VOICE15) && + (data[104U] == dfsi::P25_DFSI_LDU2_VOICE16) && (data[121U] == dfsi::P25_DFSI_LDU2_VOICE17) && + (data[138U] == dfsi::P25_DFSI_LDU2_VOICE18)) { + m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE10); + m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 10U); count += 22U; - // The '6C' record - IMBE Voice 11 - ::memcpy(m_netLDU2 + 25U, data + count, 14U); + m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE11); + m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 26U); count += 14U; - // The '6D' record - IMBE Voice 12 + Encryption Sync - ::memcpy(m_netLDU2 + 50U, data + count, 17U); + m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE12); + m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 55U); count += 17U; - // The '6E' record - IMBE Voice 13 + Encryption Sync - ::memcpy(m_netLDU2 + 75U, data + count, 17U); + m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE13); + m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 80U); count += 17U; - // The '6F' record - IMBE Voice 14 + Encryption Sync - ::memcpy(m_netLDU2 + 100U, data + count, 17U); + m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE14); + m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 105U); count += 17U; - // The '70' record - IMBE Voice 15 + Encryption Sync - ::memcpy(m_netLDU2 + 125U, data + count, 17U); + m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE15); + m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 130U); count += 17U; - // The '71' record - IMBE Voice 16 + Encryption Sync - ::memcpy(m_netLDU2 + 150U, data + count, 17U); + m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE16); + m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 155U); count += 17U; - // The '72' record - IMBE Voice 17 + Encryption Sync - ::memcpy(m_netLDU2 + 175U, data + count, 17U); + m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE17); + m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 180U); count += 17U; - // The '73' record - IMBE Voice 18 + Low Speed Data - ::memcpy(m_netLDU2 + 200U, data + count, 16U); + m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE18); + m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 204U); count += 16U; if (m_p25->m_netState == RS_NET_IDLE) { @@ -802,14 +804,14 @@ bool VoicePacket::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, d m_p25->m_trunk->m_rfTSBK = lc::TSBK(m_p25->m_siteData, m_p25->m_idenEntry, m_p25->m_trunk->m_dumpTSBK); m_p25->m_trunk->m_netTSBK = lc::TSBK(m_p25->m_siteData, m_p25->m_idenEntry, m_p25->m_trunk->m_dumpTSBK); - writeNet_LDU1(control, lsd); + writeNet_LDU1(); } else { - checkNet_LDU1(control, lsd); + checkNet_LDU1(); } if (m_p25->m_netState != RS_NET_IDLE) { - writeNet_LDU2(control, lsd); + writeNet_LDU2(); } } break; @@ -896,6 +898,7 @@ VoicePacket::VoicePacket(Control* p25, network::BaseNetwork* network, bool debug m_netLastLDU1(SiteData()), m_rfLSD(), m_netLSD(), + m_dfsiLC(), m_netLDU1(NULL), m_netLDU2(NULL), m_lastDUID(P25_DUID_TDU), @@ -1041,16 +1044,16 @@ void VoicePacket::writeNet_TDU() /// /// /// -void VoicePacket::checkNet_LDU1(const lc::LC& control, const data::LowSpeedData& lsd) +void VoicePacket::checkNet_LDU1() { if (m_p25->m_netState == RS_NET_IDLE) return; // Check for an unflushed LDU1 - if (m_netLDU1[0U] != 0x00U || m_netLDU1[25U] != 0x00U || m_netLDU1[50U] != 0x00U || - m_netLDU1[75U] != 0x00U || m_netLDU1[100U] != 0x00U || m_netLDU1[125U] != 0x00U || - m_netLDU1[150U] != 0x00U || m_netLDU1[175U] != 0x00U || m_netLDU1[200U] != 0x00U) - writeNet_LDU1(control, lsd); + if (m_netLDU1[10U] != 0x00U || m_netLDU1[26U] != 0x00U || m_netLDU1[55U] != 0x00U || + m_netLDU1[80U] != 0x00U || m_netLDU1[105U] != 0x00U || m_netLDU1[130U] != 0x00U || + m_netLDU1[155U] != 0x00U || m_netLDU1[180U] != 0x00U || m_netLDU1[204U] != 0x00U) + writeNet_LDU1(); } /// @@ -1058,10 +1061,11 @@ void VoicePacket::checkNet_LDU1(const lc::LC& control, const data::LowSpeedData& /// /// /// -void VoicePacket::writeNet_LDU1(const lc::LC& control, const data::LowSpeedData& lsd) +void VoicePacket::writeNet_LDU1() { - uint8_t lco = control.getLCO(); - uint8_t mfId = control.getMFId(); + 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(); bool group = control.getLCO() == LC_GROUP; @@ -1117,40 +1121,35 @@ void VoicePacket::writeNet_LDU1(const lc::LC& control, const data::LowSpeedData& } } - uint8_t serviceOptions = (uint8_t)(m_netLDU1[53U]); - if (m_p25->m_control) { m_p25->m_trunk->touchDstIdGrant(m_rfLC.getDstId()); } + // set network and RF link control states m_netLC = lc::LC(m_p25->m_siteData); - m_netLC.setLCO(lco); - m_netLC.setMFId(mfId); + m_netLC.setLCO(control.getLCO()); + m_netLC.setMFId(control.getMFId()); m_netLC.setSrcId(srcId); m_netLC.setDstId(dstId); m_netLC.setGroup(group); - m_netLC.setEmergency((serviceOptions & 0x80U) == 0x80U); - m_netLC.setEncrypted((serviceOptions & 0x40U) == 0x40U); - m_netLC.setPriority((serviceOptions & 0x07U)); + m_netLC.setEmergency(control.getEmergency()); + m_netLC.setEncrypted(control.getEncrypted()); + m_netLC.setPriority(control.getPriority()); m_rfLC = lc::LC(m_p25->m_siteData); - m_rfLC.setMFId(mfId); + m_rfLC.setLCO(control.getLCO()); + m_rfLC.setMFId(control.getMFId()); m_rfLC.setSrcId(srcId); m_rfLC.setDstId(dstId); m_rfLC.setGroup(group); - m_rfLC.setEmergency((serviceOptions & 0x80U) == 0x80U); - m_rfLC.setEncrypted((serviceOptions & 0x40U) == 0x40U); - m_rfLC.setPriority((serviceOptions & 0x07U)); + m_rfLC.setEmergency(control.getEmergency()); + m_rfLC.setEncrypted(control.getEncrypted()); + m_rfLC.setPriority(control.getPriority()); // if we are idle lets generate HDU data if (m_p25->m_netState == RS_NET_IDLE) { - uint8_t algId = m_netLDU2[126U]; - uint32_t kId = (m_netLDU2[127U] << 8) + m_netLDU2[128U]; - uint8_t mi[P25_MI_LENGTH_BYTES]; - ::memcpy(mi + 0U, m_netLDU2 + 51U, 3U); - ::memcpy(mi + 3U, m_netLDU2 + 76U, 3U); - ::memcpy(mi + 6U, m_netLDU2 + 101U, 3U); + control.getMI(mi); if (m_verbose && m_debug) { Utils::dump(1U, "Network HDU MI", mi, P25_MI_LENGTH_BYTES); @@ -1158,10 +1157,10 @@ void VoicePacket::writeNet_LDU1(const lc::LC& control, const data::LowSpeedData& m_netLC.setMI(mi); m_rfLC.setMI(mi); - m_netLC.setAlgId(algId); - m_rfLC.setAlgId(algId); - m_netLC.setKId(kId); - m_rfLC.setKId(kId); + m_netLC.setAlgId(control.getAlgId()); + m_rfLC.setAlgId(control.getAlgId()); + m_netLC.setKId(control.getKId()); + m_rfLC.setKId(control.getKId()); m_p25->m_trunk->m_rfTSBK = lc::TSBK(&m_rfLC); m_p25->m_trunk->m_rfTSBK.setVerbose(m_p25->m_trunk->m_dumpTSBK); @@ -1343,16 +1342,16 @@ void VoicePacket::writeNet_LDU1(const lc::LC& control, const data::LowSpeedData& /// /// /// -void VoicePacket::checkNet_LDU2(const lc::LC& control, const data::LowSpeedData& lsd) +void VoicePacket::checkNet_LDU2() { if (m_p25->m_netState == RS_NET_IDLE) return; // Check for an unflushed LDU2 - if (m_netLDU2[0U] != 0x00U || m_netLDU2[25U] != 0x00U || m_netLDU2[50U] != 0x00U || - m_netLDU2[75U] != 0x00U || m_netLDU2[100U] != 0x00U || m_netLDU2[125U] != 0x00U || - m_netLDU2[150U] != 0x00U || m_netLDU2[175U] != 0x00U || m_netLDU2[200U] != 0x00U) - writeNet_LDU2(control, lsd); + if (m_netLDU2[10U] != 0x00U || m_netLDU2[26U] != 0x00U || m_netLDU2[55U] != 0x00U || + m_netLDU2[80U] != 0x00U || m_netLDU2[105U] != 0x00U || m_netLDU2[130U] != 0x00U || + m_netLDU2[155U] != 0x00U || m_netLDU2[180U] != 0x00U || m_netLDU2[204U] != 0x00U) + writeNet_LDU2(); } /// @@ -1360,10 +1359,10 @@ void VoicePacket::checkNet_LDU2(const lc::LC& control, const data::LowSpeedData& /// /// /// -void VoicePacket::writeNet_LDU2(const lc::LC& control, const data::LowSpeedData& lsd) +void VoicePacket::writeNet_LDU2() { - uint8_t algId = m_netLDU2[126U]; - uint32_t kId = (m_netLDU2[127U] << 8) + m_netLDU2[128U]; + 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) { @@ -1374,17 +1373,15 @@ void VoicePacket::writeNet_LDU2(const lc::LC& control, const data::LowSpeedData& } uint8_t mi[P25_MI_LENGTH_BYTES]; - ::memcpy(mi + 0U, m_netLDU2 + 51U, 3U); - ::memcpy(mi + 3U, m_netLDU2 + 76U, 3U); - ::memcpy(mi + 6U, m_netLDU2 + 101U, 3U); + control.getMI(mi); if (m_verbose && m_debug) { Utils::dump(1U, "Network LDU2 MI", mi, P25_MI_LENGTH_BYTES); } m_netLC.setMI(mi); - m_netLC.setAlgId(algId); - m_netLC.setKId(kId); + m_netLC.setAlgId(control.getAlgId()); + m_netLC.setKId(control.getKId()); insertMissingAudio(m_netLDU2); @@ -1449,7 +1446,7 @@ void VoicePacket::writeNet_LDU2(const lc::LC& control, const data::LowSpeedData& /// void VoicePacket::insertMissingAudio(uint8_t* data) { - if (data[0U] == 0x00U) { + if (data[10U] == 0x00U) { ::memcpy(data + 10U, m_lastIMBE, 11U); m_netLost++; } @@ -1457,7 +1454,7 @@ void VoicePacket::insertMissingAudio(uint8_t* data) ::memcpy(m_lastIMBE, data + 10U, 11U); } - if (data[25U] == 0x00U) { + if (data[26U] == 0x00U) { ::memcpy(data + 26U, m_lastIMBE, 11U); m_netLost++; } @@ -1465,7 +1462,7 @@ void VoicePacket::insertMissingAudio(uint8_t* data) ::memcpy(m_lastIMBE, data + 26U, 11U); } - if (data[50U] == 0x00U) { + if (data[55U] == 0x00U) { ::memcpy(data + 55U, m_lastIMBE, 11U); m_netLost++; } @@ -1473,7 +1470,7 @@ void VoicePacket::insertMissingAudio(uint8_t* data) ::memcpy(m_lastIMBE, data + 55U, 11U); } - if (data[75U] == 0x00U) { + if (data[80U] == 0x00U) { ::memcpy(data + 80U, m_lastIMBE, 11U); m_netLost++; } @@ -1481,7 +1478,7 @@ void VoicePacket::insertMissingAudio(uint8_t* data) ::memcpy(m_lastIMBE, data + 80U, 11U); } - if (data[100U] == 0x00U) { + if (data[105U] == 0x00U) { ::memcpy(data + 105U, m_lastIMBE, 11U); m_netLost++; } @@ -1489,7 +1486,7 @@ void VoicePacket::insertMissingAudio(uint8_t* data) ::memcpy(m_lastIMBE, data + 105U, 11U); } - if (data[125U] == 0x00U) { + if (data[130U] == 0x00U) { ::memcpy(data + 130U, m_lastIMBE, 11U); m_netLost++; } @@ -1497,7 +1494,7 @@ void VoicePacket::insertMissingAudio(uint8_t* data) ::memcpy(m_lastIMBE, data + 130U, 11U); } - if (data[150U] == 0x00U) { + if (data[155U] == 0x00U) { ::memcpy(data + 155U, m_lastIMBE, 11U); m_netLost++; } @@ -1505,7 +1502,7 @@ void VoicePacket::insertMissingAudio(uint8_t* data) ::memcpy(m_lastIMBE, data + 155U, 11U); } - if (data[175U] == 0x00U) { + if (data[180U] == 0x00U) { ::memcpy(data + 180U, m_lastIMBE, 11U); m_netLost++; } @@ -1513,7 +1510,7 @@ void VoicePacket::insertMissingAudio(uint8_t* data) ::memcpy(m_lastIMBE, data + 180U, 11U); } - if (data[200U] == 0x00U) { + if (data[204U] == 0x00U) { ::memcpy(data + 204U, m_lastIMBE, 11U); m_netLost++; } diff --git a/p25/VoicePacket.h b/p25/VoicePacket.h index 99478270..aa22b3ad 100644 --- a/p25/VoicePacket.h +++ b/p25/VoicePacket.h @@ -33,6 +33,7 @@ #include "Defines.h" #include "p25/data/LowSpeedData.h" +#include "p25/dfsi/LC.h" #include "p25/lc/LC.h" #include "p25/Control.h" #include "p25/Audio.h" @@ -96,6 +97,7 @@ namespace p25 data::LowSpeedData m_rfLSD; data::LowSpeedData m_netLSD; + dfsi::LC m_dfsiLC; uint8_t* m_netLDU1; uint8_t* m_netLDU2; @@ -128,13 +130,13 @@ namespace p25 /// Helper to write a network P25 TDU packet. void writeNet_TDU(); /// Helper to check for an unflushed LDU1 packet. - void checkNet_LDU1(const lc::LC& control, const data::LowSpeedData& lsd); + void checkNet_LDU1(); /// Helper to write a network P25 LDU1 packet. - void writeNet_LDU1(const lc::LC& control, const data::LowSpeedData& lsd); + void writeNet_LDU1(); /// Helper to check for an unflushed LDU2 packet. - void checkNet_LDU2(const lc::LC& control, const data::LowSpeedData& lsd); + void checkNet_LDU2(); /// Helper to write a network P25 LDU1 packet. - void writeNet_LDU2(const lc::LC& control, const data::LowSpeedData& lsd); + void writeNet_LDU2(); /// Helper to insert IMBE silence frames for missing audio. void insertMissingAudio(uint8_t* data); diff --git a/p25/dfsi/LC.cpp b/p25/dfsi/LC.cpp index ff57a19c..0d7ed71d 100644 --- a/p25/dfsi/LC.cpp +++ b/p25/dfsi/LC.cpp @@ -60,13 +60,22 @@ LC::LC() : ::memset(m_mi, 0x00U, P25_MI_LENGTH_BYTES); } +/// +/// Initializes a copy instance of the LC class. +/// +/// +LC::LC(const LC& data) : LC() +{ + copy(data); +} + /// /// Initializes a new instance of the LC class. /// -LC::LC(const p25::lc::LC& control, const p25::data::LowSpeedData& lsd) : LC() +LC::LC(const lc::LC& control, const data::LowSpeedData& lsd) : LC() { - m_control = control; - m_lsd = lsd; + m_control = lc::LC(control); + m_lsd = data::LowSpeedData(lsd); } /// @@ -85,25 +94,7 @@ LC::~LC() LC& LC::operator=(const LC& data) { if (this != &data) { - m_frameType = data.m_frameType; - m_rtModeFlag = data.m_rtModeFlag; - m_startStopFlag = data.m_startStopFlag; - m_typeFlag = data.m_typeFlag; - m_icwFlag = data.m_icwFlag; - - m_rssi = data.m_rssi; - m_source = data.m_source; - - m_control = data.m_control; - m_tsbk = data.m_tsbk; - m_lsd = data.m_lsd; - - delete[] m_mi; - - uint8_t* mi = new uint8_t[P25_MI_LENGTH_BYTES]; - ::memcpy(mi, data.m_mi, P25_MI_LENGTH_BYTES); - - m_mi = mi; + copy(data); } return *this; @@ -251,8 +242,8 @@ bool LC::decodeLDU1(const uint8_t* data, uint8_t* imbe) { case P25_DFSI_LDU1_VOICE1: { - m_control = p25::lc::LC(); - m_lsd = p25::data::LowSpeedData(); + m_control = lc::LC(); + m_lsd = data::LowSpeedData(); decodeStart(data + 1U); // Start Record m_icwFlag = data[5U]; // ICW Flag @@ -482,7 +473,7 @@ 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 = p25::data::LowSpeedData(); + m_lsd = data::LowSpeedData(); decodeStart(data + 1U); // Start Record m_icwFlag = data[5U]; // ICW Flag @@ -568,7 +559,7 @@ void LC::encodeLDU2(uint8_t* data, const uint8_t* imbe) assert(imbe != NULL); // generate MI data - uint8_t mi[p25::P25_MI_LENGTH_BYTES]; + uint8_t mi[P25_MI_LENGTH_BYTES]; m_control.getMI(mi); // determine the LDU2 DFSI frame length, its variable @@ -739,6 +730,33 @@ void LC::encodeTSBK(uint8_t* data) // --------------------------------------------------------------------------- // Private Class Members // --------------------------------------------------------------------------- +/// +/// Internal helper to copy the the class. +/// +/// +void LC::copy(const LC& data) +{ + m_frameType = data.m_frameType; + m_rtModeFlag = data.m_rtModeFlag; + m_startStopFlag = data.m_startStopFlag; + m_typeFlag = data.m_typeFlag; + m_icwFlag = data.m_icwFlag; + + 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; + + delete[] m_mi; + + uint8_t* mi = new uint8_t[P25_MI_LENGTH_BYTES]; + ::memcpy(mi, data.m_mi, P25_MI_LENGTH_BYTES); + + m_mi = mi; +} + /// /// Decode start record data. /// diff --git a/p25/dfsi/LC.h b/p25/dfsi/LC.h index a3fdee66..8d965090 100644 --- a/p25/dfsi/LC.h +++ b/p25/dfsi/LC.h @@ -46,6 +46,8 @@ namespace p25 public: /// Initializes a new instance of the LC class. LC(); + /// Initializes a copy instance of the LC class. + LC(const LC& data); /// Initializes a new instance of the LC class. LC(const p25::lc::LC& control, const p25::data::LowSpeedData& lsd); /// Finalizes a instance of the LC class. @@ -104,16 +106,19 @@ namespace p25 __PROPERTY(uint8_t, source, Source); /// Link control data. - __PROPERTY(p25::lc::LC, control, Control); + __PROPERTY_PLAIN(p25::lc::LC, control, control); /// TSBK. - __PROPERTY(p25::lc::TSBK, tsbk, TSBK); + __PROPERTY_PLAIN(p25::lc::TSBK, tsbk, tsbk); /// Low speed data. - __PROPERTY(p25::data::LowSpeedData, lsd, LSD); + __PROPERTY_PLAIN(p25::data::LowSpeedData, lsd, lsd); private: /** Encryption data */ uint8_t* m_mi; + /// Internal helper to copy the class. + void copy(const LC& data); + /// Decode start record data. bool decodeStart(const uint8_t* data); /// Encode start record data. diff --git a/p25/lc/LC.cpp b/p25/lc/LC.cpp index 6a1906c4..8d4e631c 100644 --- a/p25/lc/LC.cpp +++ b/p25/lc/LC.cpp @@ -76,6 +76,15 @@ LC::LC() : ::memset(m_mi, 0x00U, P25_MI_LENGTH_BYTES); } +/// +/// Initializes a copy instance of the LC class. +/// +/// +LC::LC(const LC& data) : LC() +{ + copy(data); +} + /// /// Initializes a new instance of the LC class. /// @@ -91,7 +100,10 @@ LC::LC(SiteData siteData) : LC() /// LC::~LC() { - delete[] m_mi; + if (m_mi != NULL) { + delete[] m_mi; + m_mi = NULL; + } } /// @@ -102,53 +114,7 @@ LC::~LC() LC& LC::operator=(const LC& data) { if (this != &data) { - m_protect = data.m_protect; - m_mfId = data.m_mfId; - - m_srcId = data.m_srcId; - m_dstId = data.m_dstId; - - m_grpVchNo = data.m_grpVchNo; - - m_emergency = data.m_emergency; - m_encrypted = data.m_encrypted; - m_priority = data.m_priority; - - m_group = data.m_group; - - m_callTimer = data.m_callTimer; - - m_algId = data.m_algId; - if (m_algId != P25_ALGO_UNENCRYPT) { - delete[] m_mi; - - uint8_t* mi = new uint8_t[P25_MI_LENGTH_BYTES]; - ::memcpy(mi, data.m_mi, P25_MI_LENGTH_BYTES); - - m_mi = mi; - - m_kId = data.m_kId; - if (!m_encrypted) { - m_encryptOverride = true; - m_encrypted = true; - } - } - else { - delete[] m_mi; - - uint8_t* mi = new uint8_t[P25_MI_LENGTH_BYTES]; - ::memset(m_mi, 0x00U, P25_MI_LENGTH_BYTES); - - m_mi = mi; - - m_kId = 0x0000U; - if (m_encrypted) { - m_encryptOverride = true; - m_encrypted = false; - } - } - - m_siteData = data.m_siteData; + copy(data); } return *this; @@ -504,6 +470,61 @@ void LC::getMI(uint8_t* mi) const // --------------------------------------------------------------------------- // Private Class Members // --------------------------------------------------------------------------- +/// +/// Internal helper to copy the the class. +/// +/// +void LC::copy(const LC& data) +{ + m_protect = data.m_protect; + m_mfId = data.m_mfId; + + m_srcId = data.m_srcId; + m_dstId = data.m_dstId; + + m_grpVchNo = data.m_grpVchNo; + + m_emergency = data.m_emergency; + m_encrypted = data.m_encrypted; + m_priority = data.m_priority; + + m_group = data.m_group; + + m_callTimer = data.m_callTimer; + + m_algId = data.m_algId; + if (m_algId != P25_ALGO_UNENCRYPT) { + delete[] m_mi; + + uint8_t* mi = new uint8_t[P25_MI_LENGTH_BYTES]; + ::memcpy(mi, data.m_mi, P25_MI_LENGTH_BYTES); + + m_mi = mi; + + m_kId = data.m_kId; + if (!m_encrypted) { + m_encryptOverride = true; + m_encrypted = true; + } + } + else { + delete[] m_mi; + + uint8_t* mi = new uint8_t[P25_MI_LENGTH_BYTES]; + ::memset(m_mi, 0x00U, P25_MI_LENGTH_BYTES); + + m_mi = mi; + + m_kId = 0x0000U; + if (m_encrypted) { + m_encryptOverride = true; + m_encrypted = false; + } + } + + m_siteData = data.m_siteData; +} + /// /// Decode link control. /// diff --git a/p25/lc/LC.h b/p25/lc/LC.h index e6c50d60..21bea459 100644 --- a/p25/lc/LC.h +++ b/p25/lc/LC.h @@ -59,6 +59,8 @@ namespace p25 public: /// Initializes a new instance of the LC class. LC(); + /// Initializes a copy instance of the LC class. + LC(const LC& data); /// Initializes a new instance of the LC class. LC(SiteData siteData); /// Finalizes a instance of the LC class. @@ -137,6 +139,9 @@ namespace p25 /** Encryption data */ uint8_t* m_mi; + /// Internal helper to copy the class. + void copy(const LC& data); + /// Decode link control. bool decodeLC(const uint8_t* rs); /// Encode link control. diff --git a/p25/lc/TDULC.cpp b/p25/lc/TDULC.cpp index c77689ca..5a79ce58 100644 --- a/p25/lc/TDULC.cpp +++ b/p25/lc/TDULC.cpp @@ -42,6 +42,15 @@ using namespace p25; // --------------------------------------------------------------------------- // Public Class Members // --------------------------------------------------------------------------- +/// +/// Initializes a copy instance of the TDULC class. +/// +/// +TDULC::TDULC(const TDULC& data) : TDULC() +{ + copy(data); +} + /// /// Initializes a new instance of the TDULC class. /// @@ -106,33 +115,7 @@ TDULC::~TDULC() TDULC& TDULC::operator=(const TDULC& data) { if (this != &data) { - m_verbose = data.m_verbose; - m_protect = data.m_protect; - m_lco = data.m_lco; - m_mfId = data.m_mfId; - - m_srcId = data.m_srcId; - m_dstId = data.m_dstId; - - m_grpVchNo = data.m_grpVchNo; - - m_adjCFVA = data.m_adjCFVA; - m_adjRfssId = data.m_adjRfssId; - m_adjSiteId = data.m_adjSiteId; - m_adjChannelId = data.m_adjChannelId; - m_adjChannelNo = data.m_adjChannelNo; - m_adjServiceClass = data.m_adjServiceClass; - - m_emergency = data.m_emergency; - m_encrypted = data.m_encrypted; - m_priority = data.m_priority; - - m_group = data.m_group; - - m_callTimer = data.m_callTimer; - - m_siteData = data.m_siteData; - m_siteIdenEntry = data.m_siteIdenEntry; + copy(data); } return *this; @@ -215,6 +198,15 @@ void TDULC::encode(uint8_t * data) // --------------------------------------------------------------------------- // Private Class Members // --------------------------------------------------------------------------- +/// +/// Initializes a new instance of the TDULC class. +/// +/// This should never be used. +TDULC::TDULC() : TDULC(SiteData()) +{ + /* stub */ +} + /// /// Initializes a new instance of the TDULC class. /// @@ -245,6 +237,41 @@ TDULC::TDULC(SiteData siteData) : m_grpVchNo = m_siteData.channelNo(); } +/// +/// Internal helper to copy the the class. +/// +/// +void TDULC::copy(const TDULC& data) +{ + m_verbose = data.m_verbose; + m_protect = data.m_protect; + m_lco = data.m_lco; + m_mfId = data.m_mfId; + + m_srcId = data.m_srcId; + m_dstId = data.m_dstId; + + m_grpVchNo = data.m_grpVchNo; + + m_adjCFVA = data.m_adjCFVA; + m_adjRfssId = data.m_adjRfssId; + m_adjSiteId = data.m_adjSiteId; + m_adjChannelId = data.m_adjChannelId; + m_adjChannelNo = data.m_adjChannelNo; + m_adjServiceClass = data.m_adjServiceClass; + + m_emergency = data.m_emergency; + m_encrypted = data.m_encrypted; + m_priority = data.m_priority; + + m_group = data.m_group; + + m_callTimer = data.m_callTimer; + + m_siteData = data.m_siteData; + m_siteIdenEntry = data.m_siteIdenEntry; +} + /// /// Decode link control. /// diff --git a/p25/lc/TDULC.h b/p25/lc/TDULC.h index 351a5e76..46fa03f5 100644 --- a/p25/lc/TDULC.h +++ b/p25/lc/TDULC.h @@ -53,6 +53,8 @@ namespace p25 class HOST_SW_API TDULC { public: + /// Initializes a copy instance of the TDULC class. + TDULC(const TDULC& data); /// Initializes a new instance of the TDULC class. TDULC(SiteData siteData, lookups::IdenTable entry); /// Initializes a new instance of the TDULC class. @@ -123,6 +125,8 @@ namespace p25 __PROPERTY_PLAIN(lookups::IdenTable, siteIdenEntry, siteIdenEntry); private: + /// Initializes a new instance of the TDULC class. + TDULC(); /// Initializes a new instance of the TDULC class. TDULC(SiteData siteData); @@ -132,6 +136,9 @@ namespace p25 uint32_t m_callTimer; + /// Internal helper to copy the class. + void copy(const TDULC& data); + /// Decode link control. bool decodeLC(const uint8_t* rs); /// Encode link control. diff --git a/p25/lc/TSBK.cpp b/p25/lc/TSBK.cpp index e6d20936..a0c58eb6 100644 --- a/p25/lc/TSBK.cpp +++ b/p25/lc/TSBK.cpp @@ -41,6 +41,15 @@ using namespace p25; // --------------------------------------------------------------------------- // Public Class Members // --------------------------------------------------------------------------- +/// +/// Initializes a copy instance of the TSBK class. +/// +/// +TSBK::TSBK(const TSBK& data) : TSBK() +{ + copy(data); +} + /// /// Initializes a new instance of the TSBK class. /// @@ -112,65 +121,7 @@ TSBK::~TSBK() TSBK& TSBK::operator=(const TSBK& data) { if (this != &data) { - m_verbose = data.m_verbose; - m_warnCRC = data.m_warnCRC; - m_protect = data.m_protect; - m_lco = data.m_lco; - m_mfId = data.m_mfId; - - m_srcId = data.m_srcId; - m_dstId = data.m_dstId; - - m_lastBlock = data.m_lastBlock; - m_aivFlag = data.m_aivFlag; - m_extendedAddrFlag = data.m_extendedAddrFlag; - - m_service = data.m_service; - m_response = data.m_response; - - m_netId = data.m_netId; - m_sysId = data.m_sysId; - - m_grpVchNo = data.m_grpVchNo; - - m_messageValue = data.m_messageValue; - m_statusValue = data.m_statusValue; - - m_extendedFunction = data.m_extendedFunction; - - m_adjCFVA = data.m_adjCFVA; - m_adjRfssId = data.m_adjRfssId; - m_adjSiteId = data.m_adjSiteId; - m_adjChannelId = data.m_adjChannelId; - m_adjChannelNo = data.m_adjChannelNo; - m_adjServiceClass = data.m_adjServiceClass; - - m_sccbChannelId1 = data.m_sccbChannelId1; - m_sccbChannelId2 = data.m_sccbChannelId2; - m_sccbChannelNo = data.m_sccbChannelNo; - - m_lra = data.m_lra; - - m_patchSuperGroupId = data.m_patchSuperGroupId; - m_patchGroup1Id = data.m_patchGroup1Id; - m_patchGroup2Id = data.m_patchGroup2Id; - m_patchGroup3Id = data.m_patchGroup3Id; - - m_emergency = data.m_emergency; - m_encrypted = data.m_encrypted; - m_priority = data.m_priority; - - m_group = data.m_group; - - m_siteData = data.m_siteData; - m_siteIdenEntry = data.m_siteIdenEntry; - - delete[] m_siteCallsign; - - uint8_t* callsign = new uint8_t[P25_MOT_CALLSIGN_LENGTH_BYTES]; - ::memcpy(callsign, data.m_siteCallsign, P25_MOT_CALLSIGN_LENGTH_BYTES); - - m_siteCallsign = callsign; + copy(data); } return *this; @@ -1113,6 +1064,7 @@ TSBK::TSBK() : TSBK(SiteData()) { /* stub */ } + /// /// Initializes a new instance of the TSBK class. /// @@ -1169,3 +1121,70 @@ TSBK::TSBK(SiteData siteData) : ::memset(m_siteCallsign, 0x00U, P25_MOT_CALLSIGN_LENGTH_BYTES); setCallsign(siteData.callsign()); } + +/// +/// Internal helper to copy the the class. +/// +/// +void TSBK::copy(const TSBK& data) +{ + m_verbose = data.m_verbose; + m_warnCRC = data.m_warnCRC; + m_protect = data.m_protect; + m_lco = data.m_lco; + m_mfId = data.m_mfId; + + m_srcId = data.m_srcId; + m_dstId = data.m_dstId; + + m_lastBlock = data.m_lastBlock; + m_aivFlag = data.m_aivFlag; + m_extendedAddrFlag = data.m_extendedAddrFlag; + + m_service = data.m_service; + m_response = data.m_response; + + m_netId = data.m_netId; + m_sysId = data.m_sysId; + + m_grpVchNo = data.m_grpVchNo; + + m_messageValue = data.m_messageValue; + m_statusValue = data.m_statusValue; + + m_extendedFunction = data.m_extendedFunction; + + m_adjCFVA = data.m_adjCFVA; + m_adjRfssId = data.m_adjRfssId; + m_adjSiteId = data.m_adjSiteId; + m_adjChannelId = data.m_adjChannelId; + m_adjChannelNo = data.m_adjChannelNo; + m_adjServiceClass = data.m_adjServiceClass; + + m_sccbChannelId1 = data.m_sccbChannelId1; + m_sccbChannelId2 = data.m_sccbChannelId2; + m_sccbChannelNo = data.m_sccbChannelNo; + + m_lra = data.m_lra; + + m_patchSuperGroupId = data.m_patchSuperGroupId; + m_patchGroup1Id = data.m_patchGroup1Id; + m_patchGroup2Id = data.m_patchGroup2Id; + m_patchGroup3Id = data.m_patchGroup3Id; + + m_emergency = data.m_emergency; + m_encrypted = data.m_encrypted; + m_priority = data.m_priority; + + m_group = data.m_group; + + m_siteData = data.m_siteData; + m_siteIdenEntry = data.m_siteIdenEntry; + + delete[] m_siteCallsign; + + uint8_t* callsign = new uint8_t[P25_MOT_CALLSIGN_LENGTH_BYTES]; + ::memcpy(callsign, data.m_siteCallsign, P25_MOT_CALLSIGN_LENGTH_BYTES); + + m_siteCallsign = callsign; +} diff --git a/p25/lc/TSBK.h b/p25/lc/TSBK.h index 122fd908..11300957 100644 --- a/p25/lc/TSBK.h +++ b/p25/lc/TSBK.h @@ -63,6 +63,8 @@ namespace p25 class HOST_SW_API TSBK { public: + /// Initializes a copy instance of the TSBK class. + TSBK(const TSBK& data); /// Initializes a new instance of the TSBK class. TSBK(SiteData siteData, lookups::IdenTable entry); /// Initializes a new instance of the TSBK class. @@ -219,6 +221,9 @@ namespace p25 /** Local Site data */ uint8_t* m_siteCallsign; + + /// Internal helper to copy the class. + void copy(const TSBK& data); }; } // namespace lc } // namespace p25