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;

pull/12/head
Bryan Biedenkapp 4 years ago
parent 87e633737b
commit 45bd8519a3

@ -32,6 +32,7 @@
#include "p25/P25Defines.h" #include "p25/P25Defines.h"
#include "p25/VoicePacket.h" #include "p25/VoicePacket.h"
#include "p25/acl/AccessControl.h" #include "p25/acl/AccessControl.h"
#include "p25/dfsi/DFSIDefines.h"
#include "p25/P25Utils.h" #include "p25/P25Utils.h"
#include "p25/Sync.h" #include "p25/Sync.h"
#include "edac/CRC.h" #include "edac/CRC.h"
@ -685,46 +686,48 @@ bool VoicePacket::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, d
switch (duid) { switch (duid) {
case P25_DUID_LDU1: case P25_DUID_LDU1:
// The '62', '63', '64', '65', '66', '67', '68', '69', '6A' records are LDU1 if ((data[0U] == dfsi::P25_DFSI_LDU1_VOICE1) && (data[22U] == dfsi::P25_DFSI_LDU1_VOICE2) &&
if ((data[0U] == 0x62U) && (data[22U] == 0x63U) && (data[36U] == dfsi::P25_DFSI_LDU1_VOICE3) && (data[53U] == dfsi::P25_DFSI_LDU1_VOICE4) &&
(data[36U] == 0x64U) && (data[53U] == 0x65U) && (data[70U] == dfsi::P25_DFSI_LDU1_VOICE5) && (data[87U] == dfsi::P25_DFSI_LDU1_VOICE6) &&
(data[70U] == 0x66U) && (data[87U] == 0x67U) && (data[104U] == dfsi::P25_DFSI_LDU1_VOICE7) && (data[121U] == dfsi::P25_DFSI_LDU1_VOICE8) &&
(data[104U] == 0x68U) && (data[121U] == 0x69U) && (data[138U] == dfsi::P25_DFSI_LDU1_VOICE9)) {
(data[138U] == 0x6AU)) {
// The '62' record - IMBE Voice 1 m_dfsiLC = dfsi::LC(control, lsd);
::memcpy(m_netLDU1 + 0U, data + count, 22U);
m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE1);
m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 10U);
count += 22U; count += 22U;
// The '63' record - IMBE Voice 2 m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE2);
::memcpy(m_netLDU1 + 25U, data + count, 14U); m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 26U);
count += 14U; count += 14U;
// The '64' record - IMBE Voice 3 + Link Control m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE3);
::memcpy(m_netLDU1 + 50U, data + count, 17U); m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 55U);
count += 17U; count += 17U;
// The '65' record - IMBE Voice 4 + Link Control m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE4);
::memcpy(m_netLDU1 + 75U, data + count, 17U); m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 80U);
count += 17U; count += 17U;
// The '66' record - IMBE Voice 5 + Link Control m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE5);
::memcpy(m_netLDU1 + 100U, data + count, 17U); m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 105U);
count += 17U; count += 17U;
// The '67' record - IMBE Voice 6 + Link Control m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE6);
::memcpy(m_netLDU1 + 125U, data + count, 17U); m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 130U);
count += 17U; count += 17U;
// The '68' record - IMBE Voice 7 + Link Control m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE7);
::memcpy(m_netLDU1 + 150U, data + count, 17U); m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 155U);
count += 17U; count += 17U;
// The '69' record - IMBE Voice 8 + Link Control m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE8);
::memcpy(m_netLDU1 + 175U, data + count, 17U); m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 180U);
count += 17U; count += 17U;
// The '6A' record - IMBE Voice 9 + Low Speed Data m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE9);
::memcpy(m_netLDU1 + 200U, data + count, 16U); m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 204U);
count += 16U; count += 16U;
m_netLastLDU1 = control; 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) { if (m_p25->m_netState != RS_NET_IDLE) {
writeNet_LDU1(control, lsd); writeNet_LDU1();
} }
} }
break; break;
case P25_DUID_LDU2: case P25_DUID_LDU2:
// The '6B', '6C', '6D', '6E', '6F', '70', '71', '72', '73' records are LDU2 if ((data[0U] == dfsi::P25_DFSI_LDU2_VOICE10) && (data[22U] == dfsi::P25_DFSI_LDU2_VOICE11) &&
if ((data[0U] == 0x6BU) && (data[22U] == 0x6CU) && (data[36U] == dfsi::P25_DFSI_LDU2_VOICE12) && (data[53U] == dfsi::P25_DFSI_LDU2_VOICE13) &&
(data[36U] == 0x6DU) && (data[53U] == 0x6EU) && (data[70U] == dfsi::P25_DFSI_LDU2_VOICE14) && (data[87U] == dfsi::P25_DFSI_LDU2_VOICE15) &&
(data[70U] == 0x6FU) && (data[87U] == 0x70U) && (data[104U] == dfsi::P25_DFSI_LDU2_VOICE16) && (data[121U] == dfsi::P25_DFSI_LDU2_VOICE17) &&
(data[104U] == 0x71U) && (data[121U] == 0x72U) && (data[138U] == dfsi::P25_DFSI_LDU2_VOICE18)) {
(data[138U] == 0x73U)) { m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE10);
// The '6B' record - IMBE Voice 10 m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 10U);
::memcpy(m_netLDU2 + 0U, data + count, 22U);
count += 22U; count += 22U;
// The '6C' record - IMBE Voice 11 m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE11);
::memcpy(m_netLDU2 + 25U, data + count, 14U); m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 26U);
count += 14U; count += 14U;
// The '6D' record - IMBE Voice 12 + Encryption Sync m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE12);
::memcpy(m_netLDU2 + 50U, data + count, 17U); m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 55U);
count += 17U; count += 17U;
// The '6E' record - IMBE Voice 13 + Encryption Sync m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE13);
::memcpy(m_netLDU2 + 75U, data + count, 17U); m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 80U);
count += 17U; count += 17U;
// The '6F' record - IMBE Voice 14 + Encryption Sync m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE14);
::memcpy(m_netLDU2 + 100U, data + count, 17U); m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 105U);
count += 17U; count += 17U;
// The '70' record - IMBE Voice 15 + Encryption Sync m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE15);
::memcpy(m_netLDU2 + 125U, data + count, 17U); m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 130U);
count += 17U; count += 17U;
// The '71' record - IMBE Voice 16 + Encryption Sync m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE16);
::memcpy(m_netLDU2 + 150U, data + count, 17U); m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 155U);
count += 17U; count += 17U;
// The '72' record - IMBE Voice 17 + Encryption Sync m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE17);
::memcpy(m_netLDU2 + 175U, data + count, 17U); m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 180U);
count += 17U; count += 17U;
// The '73' record - IMBE Voice 18 + Low Speed Data m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE18);
::memcpy(m_netLDU2 + 200U, data + count, 16U); m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 204U);
count += 16U; count += 16U;
if (m_p25->m_netState == RS_NET_IDLE) { 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_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); 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 { else {
checkNet_LDU1(control, lsd); checkNet_LDU1();
} }
if (m_p25->m_netState != RS_NET_IDLE) { if (m_p25->m_netState != RS_NET_IDLE) {
writeNet_LDU2(control, lsd); writeNet_LDU2();
} }
} }
break; break;
@ -896,6 +898,7 @@ VoicePacket::VoicePacket(Control* p25, network::BaseNetwork* network, bool debug
m_netLastLDU1(SiteData()), m_netLastLDU1(SiteData()),
m_rfLSD(), m_rfLSD(),
m_netLSD(), m_netLSD(),
m_dfsiLC(),
m_netLDU1(NULL), m_netLDU1(NULL),
m_netLDU2(NULL), m_netLDU2(NULL),
m_lastDUID(P25_DUID_TDU), m_lastDUID(P25_DUID_TDU),
@ -1041,16 +1044,16 @@ void VoicePacket::writeNet_TDU()
/// </summary> /// </summary>
/// <param name="control"></param> /// <param name="control"></param>
/// <param name="lsd"></param> /// <param name="lsd"></param>
void VoicePacket::checkNet_LDU1(const lc::LC& control, const data::LowSpeedData& lsd) void VoicePacket::checkNet_LDU1()
{ {
if (m_p25->m_netState == RS_NET_IDLE) if (m_p25->m_netState == RS_NET_IDLE)
return; return;
// Check for an unflushed LDU1 // Check for an unflushed LDU1
if (m_netLDU1[0U] != 0x00U || m_netLDU1[25U] != 0x00U || m_netLDU1[50U] != 0x00U || if (m_netLDU1[10U] != 0x00U || m_netLDU1[26U] != 0x00U || m_netLDU1[55U] != 0x00U ||
m_netLDU1[75U] != 0x00U || m_netLDU1[100U] != 0x00U || m_netLDU1[125U] != 0x00U || m_netLDU1[80U] != 0x00U || m_netLDU1[105U] != 0x00U || m_netLDU1[130U] != 0x00U ||
m_netLDU1[150U] != 0x00U || m_netLDU1[175U] != 0x00U || m_netLDU1[200U] != 0x00U) m_netLDU1[155U] != 0x00U || m_netLDU1[180U] != 0x00U || m_netLDU1[204U] != 0x00U)
writeNet_LDU1(control, lsd); writeNet_LDU1();
} }
/// <summary> /// <summary>
@ -1058,10 +1061,11 @@ void VoicePacket::checkNet_LDU1(const lc::LC& control, const data::LowSpeedData&
/// </summary> /// </summary>
/// <param name="control"></param> /// <param name="control"></param>
/// <param name="lsd"></param> /// <param name="lsd"></param>
void VoicePacket::writeNet_LDU1(const lc::LC& control, const data::LowSpeedData& lsd) void VoicePacket::writeNet_LDU1()
{ {
uint8_t lco = control.getLCO(); lc::LC control = lc::LC(m_dfsiLC.control());
uint8_t mfId = control.getMFId(); data::LowSpeedData lsd = data::LowSpeedData(m_dfsiLC.lsd());
uint32_t dstId = control.getDstId(); uint32_t dstId = control.getDstId();
uint32_t srcId = control.getSrcId(); uint32_t srcId = control.getSrcId();
bool group = control.getLCO() == LC_GROUP; 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) { if (m_p25->m_control) {
m_p25->m_trunk->touchDstIdGrant(m_rfLC.getDstId()); 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 = lc::LC(m_p25->m_siteData);
m_netLC.setLCO(lco); m_netLC.setLCO(control.getLCO());
m_netLC.setMFId(mfId); m_netLC.setMFId(control.getMFId());
m_netLC.setSrcId(srcId); m_netLC.setSrcId(srcId);
m_netLC.setDstId(dstId); m_netLC.setDstId(dstId);
m_netLC.setGroup(group); m_netLC.setGroup(group);
m_netLC.setEmergency((serviceOptions & 0x80U) == 0x80U); m_netLC.setEmergency(control.getEmergency());
m_netLC.setEncrypted((serviceOptions & 0x40U) == 0x40U); m_netLC.setEncrypted(control.getEncrypted());
m_netLC.setPriority((serviceOptions & 0x07U)); m_netLC.setPriority(control.getPriority());
m_rfLC = lc::LC(m_p25->m_siteData); 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.setSrcId(srcId);
m_rfLC.setDstId(dstId); m_rfLC.setDstId(dstId);
m_rfLC.setGroup(group); m_rfLC.setGroup(group);
m_rfLC.setEmergency((serviceOptions & 0x80U) == 0x80U); m_rfLC.setEmergency(control.getEmergency());
m_rfLC.setEncrypted((serviceOptions & 0x40U) == 0x40U); m_rfLC.setEncrypted(control.getEncrypted());
m_rfLC.setPriority((serviceOptions & 0x07U)); m_rfLC.setPriority(control.getPriority());
// if we are idle lets generate HDU data // if we are idle lets generate HDU data
if (m_p25->m_netState == RS_NET_IDLE) { 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]; uint8_t mi[P25_MI_LENGTH_BYTES];
::memcpy(mi + 0U, m_netLDU2 + 51U, 3U); control.getMI(mi);
::memcpy(mi + 3U, m_netLDU2 + 76U, 3U);
::memcpy(mi + 6U, m_netLDU2 + 101U, 3U);
if (m_verbose && m_debug) { if (m_verbose && m_debug) {
Utils::dump(1U, "Network HDU MI", mi, P25_MI_LENGTH_BYTES); 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_netLC.setMI(mi);
m_rfLC.setMI(mi); m_rfLC.setMI(mi);
m_netLC.setAlgId(algId); m_netLC.setAlgId(control.getAlgId());
m_rfLC.setAlgId(algId); m_rfLC.setAlgId(control.getAlgId());
m_netLC.setKId(kId); m_netLC.setKId(control.getKId());
m_rfLC.setKId(kId); m_rfLC.setKId(control.getKId());
m_p25->m_trunk->m_rfTSBK = lc::TSBK(&m_rfLC); m_p25->m_trunk->m_rfTSBK = lc::TSBK(&m_rfLC);
m_p25->m_trunk->m_rfTSBK.setVerbose(m_p25->m_trunk->m_dumpTSBK); 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&
/// </summary> /// </summary>
/// <param name="control"></param> /// <param name="control"></param>
/// <param name="lsd"></param> /// <param name="lsd"></param>
void VoicePacket::checkNet_LDU2(const lc::LC& control, const data::LowSpeedData& lsd) void VoicePacket::checkNet_LDU2()
{ {
if (m_p25->m_netState == RS_NET_IDLE) if (m_p25->m_netState == RS_NET_IDLE)
return; return;
// Check for an unflushed LDU2 // Check for an unflushed LDU2
if (m_netLDU2[0U] != 0x00U || m_netLDU2[25U] != 0x00U || m_netLDU2[50U] != 0x00U || if (m_netLDU2[10U] != 0x00U || m_netLDU2[26U] != 0x00U || m_netLDU2[55U] != 0x00U ||
m_netLDU2[75U] != 0x00U || m_netLDU2[100U] != 0x00U || m_netLDU2[125U] != 0x00U || m_netLDU2[80U] != 0x00U || m_netLDU2[105U] != 0x00U || m_netLDU2[130U] != 0x00U ||
m_netLDU2[150U] != 0x00U || m_netLDU2[175U] != 0x00U || m_netLDU2[200U] != 0x00U) m_netLDU2[155U] != 0x00U || m_netLDU2[180U] != 0x00U || m_netLDU2[204U] != 0x00U)
writeNet_LDU2(control, lsd); writeNet_LDU2();
} }
/// <summary> /// <summary>
@ -1360,10 +1359,10 @@ void VoicePacket::checkNet_LDU2(const lc::LC& control, const data::LowSpeedData&
/// </summary> /// </summary>
/// <param name="control"></param> /// <param name="control"></param>
/// <param name="lsd"></param> /// <param name="lsd"></param>
void VoicePacket::writeNet_LDU2(const lc::LC& control, const data::LowSpeedData& lsd) void VoicePacket::writeNet_LDU2()
{ {
uint8_t algId = m_netLDU2[126U]; lc::LC control = lc::LC(m_dfsiLC.control());
uint32_t kId = (m_netLDU2[127U] << 8) + m_netLDU2[128U]; 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 // 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) { 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]; uint8_t mi[P25_MI_LENGTH_BYTES];
::memcpy(mi + 0U, m_netLDU2 + 51U, 3U); control.getMI(mi);
::memcpy(mi + 3U, m_netLDU2 + 76U, 3U);
::memcpy(mi + 6U, m_netLDU2 + 101U, 3U);
if (m_verbose && m_debug) { if (m_verbose && m_debug) {
Utils::dump(1U, "Network LDU2 MI", mi, P25_MI_LENGTH_BYTES); Utils::dump(1U, "Network LDU2 MI", mi, P25_MI_LENGTH_BYTES);
} }
m_netLC.setMI(mi); m_netLC.setMI(mi);
m_netLC.setAlgId(algId); m_netLC.setAlgId(control.getAlgId());
m_netLC.setKId(kId); m_netLC.setKId(control.getKId());
insertMissingAudio(m_netLDU2); insertMissingAudio(m_netLDU2);
@ -1449,7 +1446,7 @@ void VoicePacket::writeNet_LDU2(const lc::LC& control, const data::LowSpeedData&
/// <param name="data"></param> /// <param name="data"></param>
void VoicePacket::insertMissingAudio(uint8_t* data) void VoicePacket::insertMissingAudio(uint8_t* data)
{ {
if (data[0U] == 0x00U) { if (data[10U] == 0x00U) {
::memcpy(data + 10U, m_lastIMBE, 11U); ::memcpy(data + 10U, m_lastIMBE, 11U);
m_netLost++; m_netLost++;
} }
@ -1457,7 +1454,7 @@ void VoicePacket::insertMissingAudio(uint8_t* data)
::memcpy(m_lastIMBE, data + 10U, 11U); ::memcpy(m_lastIMBE, data + 10U, 11U);
} }
if (data[25U] == 0x00U) { if (data[26U] == 0x00U) {
::memcpy(data + 26U, m_lastIMBE, 11U); ::memcpy(data + 26U, m_lastIMBE, 11U);
m_netLost++; m_netLost++;
} }
@ -1465,7 +1462,7 @@ void VoicePacket::insertMissingAudio(uint8_t* data)
::memcpy(m_lastIMBE, data + 26U, 11U); ::memcpy(m_lastIMBE, data + 26U, 11U);
} }
if (data[50U] == 0x00U) { if (data[55U] == 0x00U) {
::memcpy(data + 55U, m_lastIMBE, 11U); ::memcpy(data + 55U, m_lastIMBE, 11U);
m_netLost++; m_netLost++;
} }
@ -1473,7 +1470,7 @@ void VoicePacket::insertMissingAudio(uint8_t* data)
::memcpy(m_lastIMBE, data + 55U, 11U); ::memcpy(m_lastIMBE, data + 55U, 11U);
} }
if (data[75U] == 0x00U) { if (data[80U] == 0x00U) {
::memcpy(data + 80U, m_lastIMBE, 11U); ::memcpy(data + 80U, m_lastIMBE, 11U);
m_netLost++; m_netLost++;
} }
@ -1481,7 +1478,7 @@ void VoicePacket::insertMissingAudio(uint8_t* data)
::memcpy(m_lastIMBE, data + 80U, 11U); ::memcpy(m_lastIMBE, data + 80U, 11U);
} }
if (data[100U] == 0x00U) { if (data[105U] == 0x00U) {
::memcpy(data + 105U, m_lastIMBE, 11U); ::memcpy(data + 105U, m_lastIMBE, 11U);
m_netLost++; m_netLost++;
} }
@ -1489,7 +1486,7 @@ void VoicePacket::insertMissingAudio(uint8_t* data)
::memcpy(m_lastIMBE, data + 105U, 11U); ::memcpy(m_lastIMBE, data + 105U, 11U);
} }
if (data[125U] == 0x00U) { if (data[130U] == 0x00U) {
::memcpy(data + 130U, m_lastIMBE, 11U); ::memcpy(data + 130U, m_lastIMBE, 11U);
m_netLost++; m_netLost++;
} }
@ -1497,7 +1494,7 @@ void VoicePacket::insertMissingAudio(uint8_t* data)
::memcpy(m_lastIMBE, data + 130U, 11U); ::memcpy(m_lastIMBE, data + 130U, 11U);
} }
if (data[150U] == 0x00U) { if (data[155U] == 0x00U) {
::memcpy(data + 155U, m_lastIMBE, 11U); ::memcpy(data + 155U, m_lastIMBE, 11U);
m_netLost++; m_netLost++;
} }
@ -1505,7 +1502,7 @@ void VoicePacket::insertMissingAudio(uint8_t* data)
::memcpy(m_lastIMBE, data + 155U, 11U); ::memcpy(m_lastIMBE, data + 155U, 11U);
} }
if (data[175U] == 0x00U) { if (data[180U] == 0x00U) {
::memcpy(data + 180U, m_lastIMBE, 11U); ::memcpy(data + 180U, m_lastIMBE, 11U);
m_netLost++; m_netLost++;
} }
@ -1513,7 +1510,7 @@ void VoicePacket::insertMissingAudio(uint8_t* data)
::memcpy(m_lastIMBE, data + 180U, 11U); ::memcpy(m_lastIMBE, data + 180U, 11U);
} }
if (data[200U] == 0x00U) { if (data[204U] == 0x00U) {
::memcpy(data + 204U, m_lastIMBE, 11U); ::memcpy(data + 204U, m_lastIMBE, 11U);
m_netLost++; m_netLost++;
} }

@ -33,6 +33,7 @@
#include "Defines.h" #include "Defines.h"
#include "p25/data/LowSpeedData.h" #include "p25/data/LowSpeedData.h"
#include "p25/dfsi/LC.h"
#include "p25/lc/LC.h" #include "p25/lc/LC.h"
#include "p25/Control.h" #include "p25/Control.h"
#include "p25/Audio.h" #include "p25/Audio.h"
@ -96,6 +97,7 @@ namespace p25
data::LowSpeedData m_rfLSD; data::LowSpeedData m_rfLSD;
data::LowSpeedData m_netLSD; data::LowSpeedData m_netLSD;
dfsi::LC m_dfsiLC;
uint8_t* m_netLDU1; uint8_t* m_netLDU1;
uint8_t* m_netLDU2; uint8_t* m_netLDU2;
@ -128,13 +130,13 @@ namespace p25
/// <summary>Helper to write a network P25 TDU packet.</summary> /// <summary>Helper to write a network P25 TDU packet.</summary>
void writeNet_TDU(); void writeNet_TDU();
/// <summary>Helper to check for an unflushed LDU1 packet.</summary> /// <summary>Helper to check for an unflushed LDU1 packet.</summary>
void checkNet_LDU1(const lc::LC& control, const data::LowSpeedData& lsd); void checkNet_LDU1();
/// <summary>Helper to write a network P25 LDU1 packet.</summary> /// <summary>Helper to write a network P25 LDU1 packet.</summary>
void writeNet_LDU1(const lc::LC& control, const data::LowSpeedData& lsd); void writeNet_LDU1();
/// <summary>Helper to check for an unflushed LDU2 packet.</summary> /// <summary>Helper to check for an unflushed LDU2 packet.</summary>
void checkNet_LDU2(const lc::LC& control, const data::LowSpeedData& lsd); void checkNet_LDU2();
/// <summary>Helper to write a network P25 LDU1 packet.</summary> /// <summary>Helper to write a network P25 LDU1 packet.</summary>
void writeNet_LDU2(const lc::LC& control, const data::LowSpeedData& lsd); void writeNet_LDU2();
/// <summary>Helper to insert IMBE silence frames for missing audio.</summary> /// <summary>Helper to insert IMBE silence frames for missing audio.</summary>
void insertMissingAudio(uint8_t* data); void insertMissingAudio(uint8_t* data);

@ -60,13 +60,22 @@ LC::LC() :
::memset(m_mi, 0x00U, P25_MI_LENGTH_BYTES); ::memset(m_mi, 0x00U, P25_MI_LENGTH_BYTES);
} }
/// <summary>
/// Initializes a copy instance of the LC class.
/// </summary>
/// <param name="data"></param>
LC::LC(const LC& data) : LC()
{
copy(data);
}
/// <summary> /// <summary>
/// Initializes a new instance of the LC class. /// Initializes a new instance of the LC class.
/// </summary> /// </summary>
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_control = lc::LC(control);
m_lsd = lsd; m_lsd = data::LowSpeedData(lsd);
} }
/// <summary> /// <summary>
@ -85,25 +94,7 @@ LC::~LC()
LC& LC::operator=(const LC& data) LC& LC::operator=(const LC& data)
{ {
if (this != &data) { if (this != &data) {
m_frameType = data.m_frameType; copy(data);
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;
} }
return *this; return *this;
@ -251,8 +242,8 @@ bool LC::decodeLDU1(const uint8_t* data, uint8_t* imbe)
{ {
case P25_DFSI_LDU1_VOICE1: case P25_DFSI_LDU1_VOICE1:
{ {
m_control = p25::lc::LC(); m_control = lc::LC();
m_lsd = p25::data::LowSpeedData(); m_lsd = data::LowSpeedData();
decodeStart(data + 1U); // Start Record decodeStart(data + 1U); // Start Record
m_icwFlag = data[5U]; // ICW Flag 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: case P25_DFSI_LDU2_VOICE10:
{ {
::memset(m_mi, 0x00U, P25_MI_LENGTH_BYTES); ::memset(m_mi, 0x00U, P25_MI_LENGTH_BYTES);
m_lsd = p25::data::LowSpeedData(); m_lsd = data::LowSpeedData();
decodeStart(data + 1U); // Start Record decodeStart(data + 1U); // Start Record
m_icwFlag = data[5U]; // ICW Flag m_icwFlag = data[5U]; // ICW Flag
@ -568,7 +559,7 @@ void LC::encodeLDU2(uint8_t* data, const uint8_t* imbe)
assert(imbe != NULL); assert(imbe != NULL);
// generate MI data // generate MI data
uint8_t mi[p25::P25_MI_LENGTH_BYTES]; uint8_t mi[P25_MI_LENGTH_BYTES];
m_control.getMI(mi); m_control.getMI(mi);
// determine the LDU2 DFSI frame length, its variable // determine the LDU2 DFSI frame length, its variable
@ -739,6 +730,33 @@ void LC::encodeTSBK(uint8_t* data)
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Private Class Members // Private Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary>
/// Internal helper to copy the the class.
/// </summary>
/// <param name="data"></param>
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;
}
/// <summary> /// <summary>
/// Decode start record data. /// Decode start record data.
/// </summary> /// </summary>

@ -46,6 +46,8 @@ namespace p25
public: public:
/// <summary>Initializes a new instance of the LC class.</summary> /// <summary>Initializes a new instance of the LC class.</summary>
LC(); LC();
/// <summary>Initializes a copy instance of the LC class.</summary>
LC(const LC& data);
/// <summary>Initializes a new instance of the LC class.</summary> /// <summary>Initializes a new instance of the LC class.</summary>
LC(const p25::lc::LC& control, const p25::data::LowSpeedData& lsd); LC(const p25::lc::LC& control, const p25::data::LowSpeedData& lsd);
/// <summary>Finalizes a instance of the LC class.</summary> /// <summary>Finalizes a instance of the LC class.</summary>
@ -104,16 +106,19 @@ namespace p25
__PROPERTY(uint8_t, source, Source); __PROPERTY(uint8_t, source, Source);
/// <summary>Link control data.</summary> /// <summary>Link control data.</summary>
__PROPERTY(p25::lc::LC, control, Control); __PROPERTY_PLAIN(p25::lc::LC, control, control);
/// <summary>TSBK.</summary> /// <summary>TSBK.</summary>
__PROPERTY(p25::lc::TSBK, tsbk, TSBK); __PROPERTY_PLAIN(p25::lc::TSBK, tsbk, tsbk);
/// <summary>Low speed data.</summary> /// <summary>Low speed data.</summary>
__PROPERTY(p25::data::LowSpeedData, lsd, LSD); __PROPERTY_PLAIN(p25::data::LowSpeedData, lsd, lsd);
private: private:
/** Encryption data */ /** Encryption data */
uint8_t* m_mi; uint8_t* m_mi;
/// <summary>Internal helper to copy the class.</summary>
void copy(const LC& data);
/// <summary>Decode start record data.</summary> /// <summary>Decode start record data.</summary>
bool decodeStart(const uint8_t* data); bool decodeStart(const uint8_t* data);
/// <summary>Encode start record data.</summary> /// <summary>Encode start record data.</summary>

@ -76,6 +76,15 @@ LC::LC() :
::memset(m_mi, 0x00U, P25_MI_LENGTH_BYTES); ::memset(m_mi, 0x00U, P25_MI_LENGTH_BYTES);
} }
/// <summary>
/// Initializes a copy instance of the LC class.
/// </summary>
/// <param name="data"></param>
LC::LC(const LC& data) : LC()
{
copy(data);
}
/// <summary> /// <summary>
/// Initializes a new instance of the LC class. /// Initializes a new instance of the LC class.
/// </summary> /// </summary>
@ -91,7 +100,10 @@ LC::LC(SiteData siteData) : LC()
/// </summary> /// </summary>
LC::~LC() LC::~LC()
{ {
delete[] m_mi; if (m_mi != NULL) {
delete[] m_mi;
m_mi = NULL;
}
} }
/// <summary> /// <summary>
@ -102,53 +114,7 @@ LC::~LC()
LC& LC::operator=(const LC& data) LC& LC::operator=(const LC& data)
{ {
if (this != &data) { if (this != &data) {
m_protect = data.m_protect; copy(data);
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;
} }
return *this; return *this;
@ -504,6 +470,61 @@ void LC::getMI(uint8_t* mi) const
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Private Class Members // Private Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary>
/// Internal helper to copy the the class.
/// </summary>
/// <param name="data"></param>
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;
}
/// <summary> /// <summary>
/// Decode link control. /// Decode link control.
/// </summary> /// </summary>

@ -59,6 +59,8 @@ namespace p25
public: public:
/// <summary>Initializes a new instance of the LC class.</summary> /// <summary>Initializes a new instance of the LC class.</summary>
LC(); LC();
/// <summary>Initializes a copy instance of the LC class.</summary>
LC(const LC& data);
/// <summary>Initializes a new instance of the LC class.</summary> /// <summary>Initializes a new instance of the LC class.</summary>
LC(SiteData siteData); LC(SiteData siteData);
/// <summary>Finalizes a instance of the LC class.</summary> /// <summary>Finalizes a instance of the LC class.</summary>
@ -137,6 +139,9 @@ namespace p25
/** Encryption data */ /** Encryption data */
uint8_t* m_mi; uint8_t* m_mi;
/// <summary>Internal helper to copy the class.</summary>
void copy(const LC& data);
/// <summary>Decode link control.</summary> /// <summary>Decode link control.</summary>
bool decodeLC(const uint8_t* rs); bool decodeLC(const uint8_t* rs);
/// <summary>Encode link control.</summary> /// <summary>Encode link control.</summary>

@ -42,6 +42,15 @@ using namespace p25;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Public Class Members // Public Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary>
/// Initializes a copy instance of the TDULC class.
/// </summary>
/// <param name="data"></param>
TDULC::TDULC(const TDULC& data) : TDULC()
{
copy(data);
}
/// <summary> /// <summary>
/// Initializes a new instance of the TDULC class. /// Initializes a new instance of the TDULC class.
/// </summary> /// </summary>
@ -106,33 +115,7 @@ TDULC::~TDULC()
TDULC& TDULC::operator=(const TDULC& data) TDULC& TDULC::operator=(const TDULC& data)
{ {
if (this != &data) { if (this != &data) {
m_verbose = data.m_verbose; copy(data);
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;
} }
return *this; return *this;
@ -215,6 +198,15 @@ void TDULC::encode(uint8_t * data)
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Private Class Members // Private Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary>
/// Initializes a new instance of the TDULC class.
/// </summary>
/// <remarks>This should never be used.</remarks>
TDULC::TDULC() : TDULC(SiteData())
{
/* stub */
}
/// <summary> /// <summary>
/// Initializes a new instance of the TDULC class. /// Initializes a new instance of the TDULC class.
/// </summary> /// </summary>
@ -245,6 +237,41 @@ TDULC::TDULC(SiteData siteData) :
m_grpVchNo = m_siteData.channelNo(); m_grpVchNo = m_siteData.channelNo();
} }
/// <summary>
/// Internal helper to copy the the class.
/// </summary>
/// <param name="data"></param>
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;
}
/// <summary> /// <summary>
/// Decode link control. /// Decode link control.
/// </summary> /// </summary>

@ -53,6 +53,8 @@ namespace p25
class HOST_SW_API TDULC { class HOST_SW_API TDULC {
public: public:
/// <summary>Initializes a copy instance of the TDULC class.</summary>
TDULC(const TDULC& data);
/// <summary>Initializes a new instance of the TDULC class.</summary> /// <summary>Initializes a new instance of the TDULC class.</summary>
TDULC(SiteData siteData, lookups::IdenTable entry); TDULC(SiteData siteData, lookups::IdenTable entry);
/// <summary>Initializes a new instance of the TDULC class.</summary> /// <summary>Initializes a new instance of the TDULC class.</summary>
@ -123,6 +125,8 @@ namespace p25
__PROPERTY_PLAIN(lookups::IdenTable, siteIdenEntry, siteIdenEntry); __PROPERTY_PLAIN(lookups::IdenTable, siteIdenEntry, siteIdenEntry);
private: private:
/// <summary>Initializes a new instance of the TDULC class.</summary>
TDULC();
/// <summary>Initializes a new instance of the TDULC class.</summary> /// <summary>Initializes a new instance of the TDULC class.</summary>
TDULC(SiteData siteData); TDULC(SiteData siteData);
@ -132,6 +136,9 @@ namespace p25
uint32_t m_callTimer; uint32_t m_callTimer;
/// <summary>Internal helper to copy the class.</summary>
void copy(const TDULC& data);
/// <summary>Decode link control.</summary> /// <summary>Decode link control.</summary>
bool decodeLC(const uint8_t* rs); bool decodeLC(const uint8_t* rs);
/// <summary>Encode link control.</summary> /// <summary>Encode link control.</summary>

@ -41,6 +41,15 @@ using namespace p25;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Public Class Members // Public Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary>
/// Initializes a copy instance of the TSBK class.
/// </summary>
/// <param name="data"></param>
TSBK::TSBK(const TSBK& data) : TSBK()
{
copy(data);
}
/// <summary> /// <summary>
/// Initializes a new instance of the TSBK class. /// Initializes a new instance of the TSBK class.
/// </summary> /// </summary>
@ -112,65 +121,7 @@ TSBK::~TSBK()
TSBK& TSBK::operator=(const TSBK& data) TSBK& TSBK::operator=(const TSBK& data)
{ {
if (this != &data) { if (this != &data) {
m_verbose = data.m_verbose; copy(data);
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;
} }
return *this; return *this;
@ -1113,6 +1064,7 @@ TSBK::TSBK() : TSBK(SiteData())
{ {
/* stub */ /* stub */
} }
/// <summary> /// <summary>
/// Initializes a new instance of the TSBK class. /// Initializes a new instance of the TSBK class.
/// </summary> /// </summary>
@ -1169,3 +1121,70 @@ TSBK::TSBK(SiteData siteData) :
::memset(m_siteCallsign, 0x00U, P25_MOT_CALLSIGN_LENGTH_BYTES); ::memset(m_siteCallsign, 0x00U, P25_MOT_CALLSIGN_LENGTH_BYTES);
setCallsign(siteData.callsign()); setCallsign(siteData.callsign());
} }
/// <summary>
/// Internal helper to copy the the class.
/// </summary>
/// <param name="data"></param>
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;
}

@ -63,6 +63,8 @@ namespace p25
class HOST_SW_API TSBK { class HOST_SW_API TSBK {
public: public:
/// <summary>Initializes a copy instance of the TSBK class.</summary>
TSBK(const TSBK& data);
/// <summary>Initializes a new instance of the TSBK class.</summary> /// <summary>Initializes a new instance of the TSBK class.</summary>
TSBK(SiteData siteData, lookups::IdenTable entry); TSBK(SiteData siteData, lookups::IdenTable entry);
/// <summary>Initializes a new instance of the TSBK class.</summary> /// <summary>Initializes a new instance of the TSBK class.</summary>
@ -219,6 +221,9 @@ namespace p25
/** Local Site data */ /** Local Site data */
uint8_t* m_siteCallsign; uint8_t* m_siteCallsign;
/// <summary>Internal helper to copy the class.</summary>
void copy(const TSBK& data);
}; };
} // namespace lc } // namespace lc
} // namespace p25 } // namespace p25

Loading…
Cancel
Save

Powered by TurnKey Linux.