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/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()
/// </summary>
/// <param name="control"></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)
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();
}
/// <summary>
@ -1058,10 +1061,11 @@ void VoicePacket::checkNet_LDU1(const lc::LC& control, const data::LowSpeedData&
/// </summary>
/// <param name="control"></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();
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&
/// </summary>
/// <param name="control"></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)
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();
}
/// <summary>
@ -1360,10 +1359,10 @@ void VoicePacket::checkNet_LDU2(const lc::LC& control, const data::LowSpeedData&
/// </summary>
/// <param name="control"></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];
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&
/// <param name="data"></param>
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++;
}

@ -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
/// <summary>Helper to write a network P25 TDU packet.</summary>
void writeNet_TDU();
/// <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>
void writeNet_LDU1(const lc::LC& control, const data::LowSpeedData& lsd);
void writeNet_LDU1();
/// <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>
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>
void insertMissingAudio(uint8_t* data);

@ -60,13 +60,22 @@ LC::LC() :
::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>
/// Initializes a new instance of the LC class.
/// </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_lsd = lsd;
m_control = lc::LC(control);
m_lsd = data::LowSpeedData(lsd);
}
/// <summary>
@ -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
// ---------------------------------------------------------------------------
/// <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>
/// Decode start record data.
/// </summary>

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

@ -76,6 +76,15 @@ LC::LC() :
::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>
/// Initializes a new instance of the LC class.
/// </summary>
@ -91,7 +100,10 @@ LC::LC(SiteData siteData) : LC()
/// </summary>
LC::~LC()
{
delete[] m_mi;
if (m_mi != NULL) {
delete[] m_mi;
m_mi = NULL;
}
}
/// <summary>
@ -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
// ---------------------------------------------------------------------------
/// <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>
/// Decode link control.
/// </summary>

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

@ -42,6 +42,15 @@ using namespace p25;
// ---------------------------------------------------------------------------
// 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>
/// Initializes a new instance of the TDULC class.
/// </summary>
@ -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
// ---------------------------------------------------------------------------
/// <summary>
/// Initializes a new instance of the TDULC class.
/// </summary>
/// <remarks>This should never be used.</remarks>
TDULC::TDULC() : TDULC(SiteData())
{
/* stub */
}
/// <summary>
/// Initializes a new instance of the TDULC class.
/// </summary>
@ -245,6 +237,41 @@ TDULC::TDULC(SiteData siteData) :
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>
/// Decode link control.
/// </summary>

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

@ -41,6 +41,15 @@ using namespace p25;
// ---------------------------------------------------------------------------
// 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>
/// Initializes a new instance of the TSBK class.
/// </summary>
@ -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 */
}
/// <summary>
/// Initializes a new instance of the TSBK class.
/// </summary>
@ -1169,3 +1121,70 @@ TSBK::TSBK(SiteData siteData) :
::memset(m_siteCallsign, 0x00U, P25_MOT_CALLSIGN_LENGTH_BYTES);
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 {
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>
TSBK(SiteData siteData, lookups::IdenTable entry);
/// <summary>Initializes a new instance of the TSBK class.</summary>
@ -219,6 +221,9 @@ namespace p25
/** Local Site data */
uint8_t* m_siteCallsign;
/// <summary>Internal helper to copy the class.</summary>
void copy(const TSBK& data);
};
} // namespace lc
} // namespace p25

Loading…
Cancel
Save

Powered by TurnKey Linux.