diff --git a/config.yml b/config.yml
index 36df4917..9fc5e862 100644
--- a/config.yml
+++ b/config.yml
@@ -62,13 +62,6 @@ protocols:
callHang: 5
noStatusAck: false
noMessageAck: true
- statusCmd:
- enable: true
- radioCheck: 1
- radioInhibit: 0
- radioUninhibit: 0
- radioForceReg: 0
- radioForceDereg: 0
silenceThreshold: 124
disableNetworkHDU: false
queueSize: 5000
diff --git a/dmr/Control.cpp b/dmr/Control.cpp
index 6c26ac4b..c29e8a8a 100644
--- a/dmr/Control.cpp
+++ b/dmr/Control.cpp
@@ -129,8 +129,7 @@ bool Control::processWakeup(const uint8_t* data)
return false;
// generate a new CSBK and check validity
- lc::CSBK csbk = lc::CSBK();
- csbk.setVerbose(m_dumpCSBKData);
+ lc::CSBK csbk = lc::CSBK(SiteData(), lookups::IdenTable(), m_dumpCSBKData);
bool valid = csbk.decode(data + 2U);
if (!valid)
diff --git a/dmr/ControlPacket.cpp b/dmr/ControlPacket.cpp
index 94bab4de..34e6a1f2 100644
--- a/dmr/ControlPacket.cpp
+++ b/dmr/ControlPacket.cpp
@@ -86,8 +86,7 @@ bool ControlPacket::process(uint8_t* data, uint32_t len)
if (dataType == DT_CSBK) {
// generate a new CSBK and check validity
- lc::CSBK csbk = lc::CSBK();
- csbk.setVerbose(m_dumpCSBKData);
+ lc::CSBK csbk = lc::CSBK(m_slot->m_siteData, m_slot->m_idenEntry, m_slot->m_dumpCSBKData);
bool valid = csbk.decode(data + 2U);
if (!valid)
@@ -230,7 +229,7 @@ void ControlPacket::processNetwork(const data::Data & dmrData)
dmrData.getData(data + 2U);
if (dataType == DT_CSBK) {
- lc::CSBK csbk = lc::CSBK();
+ lc::CSBK csbk = lc::CSBK(m_slot->m_siteData, m_slot->m_idenEntry, m_slot->m_dumpCSBKData);
csbk.setVerbose(m_dumpCSBKData);
bool valid = csbk.decode(data + 2U);
@@ -399,7 +398,7 @@ void ControlPacket::writeRF_Ext_Func(uint32_t func, uint32_t arg, uint32_t dstId
slotType.setColorCode(m_slot->m_colorCode);
slotType.setDataType(DT_CSBK);
- lc::CSBK csbk = lc::CSBK();
+ lc::CSBK csbk = lc::CSBK(m_slot->m_siteData, m_slot->m_idenEntry, m_slot->m_dumpCSBKData);
csbk.setVerbose(m_dumpCSBKData);
csbk.setCSBKO(CSBKO_EXT_FNCT);
csbk.setFID(FID_DMRA);
@@ -448,7 +447,7 @@ void ControlPacket::writeRF_Call_Alrt(uint32_t srcId, uint32_t dstId)
slotType.setColorCode(m_slot->m_colorCode);
slotType.setDataType(DT_CSBK);
- lc::CSBK csbk = lc::CSBK();
+ lc::CSBK csbk = lc::CSBK(m_slot->m_siteData, m_slot->m_idenEntry, m_slot->m_dumpCSBKData);
csbk.setVerbose(m_dumpCSBKData);
csbk.setCSBKO(CSBKO_CALL_ALRT);
csbk.setFID(FID_DMRA);
@@ -521,13 +520,12 @@ void ControlPacket::writeRF_TSCC_Bcast_Ann_Wd(uint32_t channelNo, bool annWd)
slotType.setColorCode(m_slot->m_colorCode);
slotType.setDataType(DT_CSBK);
- lc::CSBK csbk = lc::CSBK();
+ lc::CSBK csbk = lc::CSBK(m_slot->m_siteData, m_slot->m_idenEntry, m_slot->m_dumpCSBKData);
csbk.setVerbose(m_dumpCSBKData);
csbk.setCSBKO(CSBKO_BROADCAST);
csbk.setFID(FID_ETSI);
csbk.setAnncType(BCAST_ANNC_ANN_WD_TSCC);
- csbk.setSiteData(m_slot->m_siteData);
csbk.setLogicalCh1(channelNo);
csbk.setAnnWdCh1(annWd);
@@ -557,7 +555,6 @@ void ControlPacket::writeRF_TSCC_Bcast_Ann_Wd(uint32_t channelNo, bool annWd)
// MBC frame 2
csbk.setLastBlock(false);
csbk.setCdef(true);
- csbk.setIdenTable(m_slot->m_idenEntry);
// Regenerate the CSBK data
csbk.encode(data + 2U);
@@ -591,13 +588,12 @@ void ControlPacket::writeRF_TSCC_Bcast_Sys_Parm()
slotType.setColorCode(m_slot->m_colorCode);
slotType.setDataType(DT_CSBK);
- lc::CSBK csbk = lc::CSBK();
+ lc::CSBK csbk = lc::CSBK(m_slot->m_siteData, m_slot->m_idenEntry, m_slot->m_dumpCSBKData);
csbk.setVerbose(m_dumpCSBKData);
csbk.setCSBKO(CSBKO_BROADCAST);
csbk.setFID(FID_ETSI);
csbk.setAnncType(BCAST_ANNC_SITE_PARMS);
- csbk.setSiteData(m_slot->m_siteData);
// Regenerate the CSBK data
csbk.encode(data + 2U);
diff --git a/dmr/SiteData.h b/dmr/SiteData.h
index 92499bee..3c637a74 100644
--- a/dmr/SiteData.h
+++ b/dmr/SiteData.h
@@ -48,7 +48,8 @@ namespace dmr
m_netId(1U),
m_siteId(1U),
m_parId(3U),
- m_requireReg(false)
+ m_requireReg(false),
+ m_netActive(false)
{
/* stub */
}
@@ -63,7 +64,8 @@ namespace dmr
m_netId(netId),
m_siteId(siteId),
m_parId(parId),
- m_requireReg(requireReq)
+ m_requireReg(requireReq),
+ m_netActive(false)
{
// siteModel clamping
if (siteModel > SITE_MODEL_HUGE)
@@ -143,6 +145,13 @@ namespace dmr
parId = 3U;
}
+ /// Helper to set the site network active flag.
+ /// Network active.
+ void setNetActive(bool netActive)
+ {
+ m_netActive = netActive;
+ }
+
/// Returns the DMR system identity value.
///
///
@@ -197,6 +206,8 @@ namespace dmr
m_siteId = data.m_siteId;
m_requireReg = data.m_requireReg;
+
+ m_netActive = data.m_netActive;
}
return *this;
@@ -213,6 +224,8 @@ namespace dmr
__READONLY_PROPERTY_PLAIN(uint8_t, parId, parId);
/// DMR require registration.
__READONLY_PROPERTY_PLAIN(bool, requireReg, requireReg);
+ /// Flag indicating whether this site is a linked active network member.
+ __READONLY_PROPERTY_PLAIN(bool, netActive, netActive);
};
} // namespace dmr
diff --git a/dmr/Slot.cpp b/dmr/Slot.cpp
index ba6b4ded..8a6829c4 100644
--- a/dmr/Slot.cpp
+++ b/dmr/Slot.cpp
@@ -360,6 +360,15 @@ void Slot::clock()
uint32_t ms = m_interval.elapsed();
m_interval.start();
+ if (m_network != NULL) {
+ if (m_network->getStatus() == network::NET_STAT_RUNNING) {
+ m_siteData.setNetActive(true);
+ }
+ else {
+ m_siteData.setNetActive(false);
+ }
+ }
+
// increment the TSCC counter on every slot 1 clock
if (m_slotNo == 1U) {
m_tsccCnt++;
diff --git a/dmr/VoicePacket.cpp b/dmr/VoicePacket.cpp
index 7e9bf0ff..f1d076d6 100644
--- a/dmr/VoicePacket.cpp
+++ b/dmr/VoicePacket.cpp
@@ -588,7 +588,7 @@ void VoicePacket::processNetwork(const data::Data& dmrData)
return;
lc::FullLC fullLC;
- lc::LC * lc = fullLC.decode(data + 2U, DT_VOICE_LC_HEADER);
+ lc::LC* lc = fullLC.decode(data + 2U, DT_VOICE_LC_HEADER);
if (lc == NULL) {
LogWarning(LOG_NET, "DMR Slot %u, DT_VOICE_LC_HEADER, bad LC received from the network, replacing", m_slot->m_slotNo);
lc = new lc::LC(dmrData.getFLCO(), dmrData.getSrcId(), dmrData.getDstId());
diff --git a/dmr/lc/CSBK.cpp b/dmr/lc/CSBK.cpp
index 260e239e..1f18692c 100644
--- a/dmr/lc/CSBK.cpp
+++ b/dmr/lc/CSBK.cpp
@@ -47,25 +47,23 @@ using namespace dmr;
///
/// Initializes a new instance of the CSBK class.
///
-CSBK::CSBK() :
- m_verbose(false),
- m_CSBKO(CSBKO_NONE),
- m_FID(0x00U),
- m_lastBlock(true),
- m_bsId(0U),
- m_GI(false),
- m_Cdef(false),
- m_srcId(0U),
- m_dstId(0U),
- m_dataContent(false),
- m_CBF(0U),
- m_data(NULL),
- m_siteData(),
- m_siteNetActive(false)
+///
+///
+CSBK::CSBK(SiteData siteData, lookups::IdenTable entry) : CSBK(siteData)
{
- m_data = new uint8_t[12U];
+ m_siteIdenEntry = entry;
+}
- reset();
+///
+/// Initializes a new instance of the CSBK class.
+///
+///
+///
+///
+CSBK::CSBK(SiteData siteData, lookups::IdenTable entry, bool verbose) : CSBK(siteData)
+{
+ m_verbose = verbose;
+ m_siteIdenEntry = entry;
}
///
@@ -297,7 +295,7 @@ void CSBK::encode(uint8_t* bytes)
csbkValue = (csbkValue << 1) + ((m_siteTSSync) ? 1U : 0U); // Site Time Slot Synchronization
csbkValue = (csbkValue << 3) + DMR_ALOHA_VER_151; // DMR Spec. Version (1.5.1)
csbkValue = (csbkValue << 1) + ((m_siteOffsetTiming) ? 1U : 0U); // Site Timing: Aligned or Offset
- csbkValue = (csbkValue << 1) + ((m_siteNetActive) ? 1U : 0U); // Site Networked
+ csbkValue = (csbkValue << 1) + ((m_siteData.netActive()) ? 1U : 0U); // Site Networked
csbkValue = (csbkValue << 5) + (m_alohaMask & 0x1FU); // MS Mask
csbkValue = (csbkValue << 2) + 0U; // Service Function
csbkValue = (csbkValue << 4) + 0U; //
@@ -426,58 +424,43 @@ void CSBK::encode(uint8_t* bytes)
bptc.encode(m_data, bytes);
}
+// ---------------------------------------------------------------------------
+// Private Class Members
+// ---------------------------------------------------------------------------
///
-/// Helper to reset data values to defaults.
-///
-void CSBK::reset()
-{
- m_colorCode = 0U;
-
- m_backoffNo = 1U;
- m_serviceType = 0U;
- m_serviceOptions = 0U;
- m_targetAddress = TGT_ADRS_TGID;
-
- m_response = 0U;
-
- /* Broadcast */
- m_anncType = BCAST_ANNC_SITE_PARMS;
- m_hibernating = false;
-
- m_annWdCh1 = false;
- m_logicalCh1 = DMR_CHNULL;
- m_annWdCh2 = false;
- m_logicalCh2 = DMR_CHNULL;
-
- /* Aloha */
- m_siteTSSync = false;
- m_siteOffsetTiming = false;
-}
-
-/** Local Site data */
-///
-/// Sets local configured site data.
-///
-/// Site data.
-void CSBK::setSiteData(SiteData siteData)
-{
- m_siteData = siteData;
-}
-
-///
-/// Sets the identity lookup table entry.
-///
-/// Identity table entry.
-void CSBK::setIdenTable(lookups::IdenTable entry)
-{
- m_siteIdenEntry = entry;
-}
-
-///
-/// Sets a flag indicating whether or not networking is active.
+/// Initializes a new instance of the CSBK class.
///
-/// Network active flag.
-void CSBK::setNetActive(bool netActive)
+///
+CSBK::CSBK(SiteData siteData) :
+ m_verbose(false),
+ m_CSBKO(CSBKO_NONE),
+ m_FID(0x00U),
+ m_lastBlock(true),
+ m_bsId(0U),
+ m_GI(false),
+ m_Cdef(false),
+ m_srcId(0U),
+ m_dstId(0U),
+ m_dataContent(false),
+ m_CBF(0U),
+ m_colorCode(0U),
+ m_backoffNo(1U),
+ m_serviceType(0U),
+ m_serviceOptions(0U),
+ m_targetAddress(TGT_ADRS_TGID),
+ m_response(0U),
+ m_anncType(BCAST_ANNC_SITE_PARMS),
+ m_hibernating(false),
+ m_annWdCh1(false),
+ m_logicalCh1(DMR_CHNULL),
+ m_annWdCh2(false),
+ m_logicalCh2(DMR_CHNULL),
+ m_siteTSSync(false),
+ m_siteOffsetTiming(false),
+ m_alohaMask(0U),
+ m_siteData(siteData),
+ m_siteIdenEntry(lookups::IdenTable()),
+ m_data(NULL)
{
- m_siteNetActive = netActive;
+ m_data = new uint8_t[12U];
}
diff --git a/dmr/lc/CSBK.h b/dmr/lc/CSBK.h
index 904029d1..05dfffe6 100644
--- a/dmr/lc/CSBK.h
+++ b/dmr/lc/CSBK.h
@@ -48,7 +48,9 @@ namespace dmr
class HOST_SW_API CSBK {
public:
/// Initializes a new instance of the CSBK class.
- CSBK();
+ CSBK(SiteData siteData, lookups::IdenTable entry);
+ /// Initializes a new instance of the CSBK class.
+ CSBK(SiteData siteData, lookups::IdenTable entry, bool verbose);
/// Finalizes a instance of the CSBK class.
~CSBK();
@@ -57,17 +59,6 @@ namespace dmr
/// Encodes a DMR CSBK.
void encode(uint8_t* bytes);
- /// Helper to reset data values to defaults.
- void reset();
-
- /** Local Site data */
- /// Sets local configured site data.
- void setSiteData(SiteData siteData);
- /// Sets the identity lookup table entry.
- void setIdenTable(lookups::IdenTable entry);
- /// Sets a flag indicating whether or not networking is active.
- void setNetActive(bool netActive);
-
public:
/// Flag indicating verbose log output.
__PROPERTY(bool, verbose, Verbose);
@@ -141,13 +132,17 @@ namespace dmr
/// Aloha MS mask.
__PROPERTY(uint8_t, alohaMask, AlohaMask);
+ /** Local Site data */
+ /// Local Site Data.
+ __PROPERTY_PLAIN(SiteData, siteData, siteData);
+ /// Local Site Identity Entry.
+ __PROPERTY_PLAIN(lookups::IdenTable, siteIdenEntry, siteIdenEntry);
+
private:
- uint8_t* m_data;
+ /// Initializes a new instance of the CSBK class.
+ CSBK(SiteData siteData);
- /** Local Site data */
- SiteData m_siteData;
- lookups::IdenTable m_siteIdenEntry;
- bool m_siteNetActive;
+ uint8_t* m_data;
};
} // namespace lc
} // namespace dmr
diff --git a/host/calibrate/HostCal.cpp b/host/calibrate/HostCal.cpp
index fb9b2946..5b00c041 100644
--- a/host/calibrate/HostCal.cpp
+++ b/host/calibrate/HostCal.cpp
@@ -1349,7 +1349,7 @@ void HostCal::processP25BER(const uint8_t* buffer)
else if (duid == P25_DUID_TSDU) {
timerStop();
- lc::TSBK tsbk = lc::TSBK();
+ lc::TSBK tsbk = lc::TSBK(SiteData(), lookups::IdenTable());
bool ret = tsbk.decode(buffer + 1U);
if (!ret) {
LogWarning(LOG_CAL, "P25_DUID_TSDU (Trunking System Data Unit), undecodable LC");
diff --git a/p25/Control.cpp b/p25/Control.cpp
index b4ebba25..c9fa9b25 100644
--- a/p25/Control.cpp
+++ b/p25/Control.cpp
@@ -101,6 +101,7 @@ Control::Control(uint32_t nac, uint32_t callHang, uint32_t queueSize, modem::Mod
m_idenTable(idenTable),
m_ridLookup(ridLookup),
m_tidLookup(tidLookup),
+ m_idenEntry(),
m_queue(queueSize, "P25 Control"),
m_rfState(RS_RF_LISTENING),
m_rfLastDstId(0U),
@@ -119,6 +120,7 @@ Control::Control(uint32_t nac, uint32_t callHang, uint32_t queueSize, modem::Mod
m_ccFrameCnt(0U),
m_ccSeq(0U),
m_nid(nac),
+ m_siteData(),
m_rssiMapper(rssiMapper),
m_rssi(0U),
m_maxRSSI(0U),
@@ -160,7 +162,6 @@ void Control::reset()
m_rfState = RS_RF_LISTENING;
m_voice->resetRF();
- m_trunk->resetRF();
m_data->resetRF();
m_queue.clear();
}
@@ -186,8 +187,6 @@ void Control::setOptions(yaml::Node& conf, const std::string cwCallsign, const s
yaml::Node systemConf = conf["system"];
yaml::Node p25Protocol = conf["protocols"]["p25"];
- m_trunk->setCallsign(cwCallsign);
-
m_tduPreambleCount = p25Protocol["tduPreambleCount"].as(8U);
m_trunk->m_patchSuperGroup = pSuperGroup;
@@ -202,14 +201,6 @@ void Control::setOptions(yaml::Node& conf, const std::string cwCallsign, const s
m_trunk->m_noStatusAck = p25Protocol["noStatusAck"].as(false);
m_trunk->m_noMessageAck = p25Protocol["noMessageAck"].as(true);
- yaml::Node statusCmd = p25Protocol["statusCmd"];
- m_trunk->m_statusCmdEnable = statusCmd["enable"].as(false);
- m_trunk->m_statusRadioCheck = (uint8_t)statusCmd["radioCheck"].as(0U);
- m_trunk->m_statusRadioInhibit = (uint8_t)statusCmd["radioInhibit"].as(0U);
- m_trunk->m_statusRadioUninhibit = (uint8_t)statusCmd["radioUninhibit"].as(0U);
- m_trunk->m_statusRadioForceReg = (uint8_t)statusCmd["radioForceReg"].as(0U);
- m_trunk->m_statusRadioForceDereg = (uint8_t)statusCmd["radioForceDereg"].as(0U);
-
yaml::Node control = p25Protocol["control"];
m_control = control["enable"].as(false);
if (m_control) {
@@ -221,17 +212,35 @@ void Control::setOptions(yaml::Node& conf, const std::string cwCallsign, const s
m_voiceOnControl = p25Protocol["voiceOnControl"].as(false);
m_ackTSBKRequests = control["ackRequests"].as(true);
- m_trunk->setServiceClass(m_control, m_voiceOnControl);
m_voice->m_silenceThreshold = p25Protocol["silenceThreshold"].as(p25::DEFAULT_SILENCE_THRESHOLD);
m_disableNetworkHDU = p25Protocol["disableNetworkHDU"].as(false);
- m_trunk->setSiteData(netId, sysId, rfssId, siteId, 0U, channelId, channelNo);
+ uint8_t serviceClass = P25_SVC_CLS_VOICE | P25_SVC_CLS_DATA;
+ if (m_control) {
+ serviceClass |= P25_SVC_CLS_REG;
+ }
+
+ if (m_voiceOnControl) {
+ serviceClass |= P25_SVC_CLS_COMPOSITE;
+ }
+
+ m_siteData = SiteData(netId, sysId, rfssId, siteId, 0U, channelId, channelNo, serviceClass);
+ m_siteData.setCallsign(cwCallsign);
+
+ std::vector entries = m_idenTable->list();
+ for (auto it = entries.begin(); it != entries.end(); ++it) {
+ lookups::IdenTable entry = *it;
+ if (entry.channelId() == channelId) {
+ m_idenEntry = entry;
+ break;
+ }
+ }
std::vector availCh = voiceChNo;
m_trunk->m_voiceChCnt = (uint8_t)availCh.size();
- m_trunk->setSiteChCnt((uint8_t)availCh.size());
+ m_siteData.setChCnt((uint8_t)availCh.size());
for (auto it = availCh.begin(); it != availCh.end(); ++it) {
m_trunk->m_voiceChTable.push_back(*it);
@@ -255,15 +264,14 @@ void Control::setOptions(yaml::Node& conf, const std::string cwCallsign, const s
LogInfo(" No Status ACK: %s", m_trunk->m_noStatusAck ? "yes" : "no");
LogInfo(" No Message ACK: %s", m_trunk->m_noMessageAck ? "yes" : "no");
- LogInfo(" Status Command Support: %s", m_trunk->m_statusCmdEnable ? "yes" : "no");
- if (m_trunk->m_statusCmdEnable) {
- LogInfo(" Status Radio Check: $%02X", m_trunk->m_statusRadioCheck);
- LogInfo(" Status Radio Inhibit: $%02X", m_trunk->m_statusRadioInhibit);
- LogInfo(" Status Radio Uninhibit: $%02X", m_trunk->m_statusRadioUninhibit);
- LogInfo(" Status Radio Force Register: $%02X", m_trunk->m_statusRadioForceReg);
- LogInfo(" Status Radio Force Deregister: $%02X", m_trunk->m_statusRadioForceDereg);
- }
}
+
+ m_voice->resetRF();
+ m_voice->resetNet();
+ m_data->resetRF();
+
+ m_trunk->m_rfTSBK = lc::TSBK(m_siteData, m_idenEntry);
+ m_trunk->m_netTSBK = lc::TSBK(m_siteData, m_idenEntry);
}
///
@@ -342,9 +350,10 @@ bool Control::processFrame(uint8_t* data, uint32_t len)
m_rfState = RS_RF_LISTENING;
m_voice->resetRF();
- m_trunk->resetRF();
m_data->resetRF();
+ m_trunk->m_rfTSBK = lc::TSBK(m_siteData, m_idenEntry);
+
return false;
}
@@ -561,10 +570,10 @@ void Control::clock(uint32_t ms)
processNetwork();
if (m_network->getStatus() == network::NET_STAT_RUNNING) {
- m_trunk->setNetActive(true);
+ m_siteData.setNetActive(true);
}
else {
- m_trunk->setNetActive(false);
+ m_siteData.setNetActive(false);
}
}
@@ -610,7 +619,8 @@ void Control::clock(uint32_t ms)
m_tailOnIdle = true;
m_voice->resetNet();
- m_trunk->resetNet();
+
+ m_trunk->m_netTSBK = lc::TSBK(m_siteData, m_idenEntry);
m_netTimeout.stop();
}
@@ -620,12 +630,13 @@ void Control::clock(uint32_t ms)
m_queue.clear();
m_voice->resetRF();
- m_voice->m_rfLastHDU.reset();
m_voice->resetNet();
- m_trunk->resetRF();
- m_trunk->resetNet();
+
m_data->resetRF();
+ m_trunk->m_rfTSBK = lc::TSBK(m_siteData, m_idenEntry);
+ m_trunk->m_netTSBK = lc::TSBK(m_siteData, m_idenEntry);
+
if (m_network != NULL)
m_network->resetP25();
@@ -633,6 +644,17 @@ void Control::clock(uint32_t ms)
}
m_trunk->clock(ms);
+
+ // if the states are "idle" ensure LC data isn't being held in memory
+ if (m_rfState == RS_RF_LISTENING && m_netState == RS_NET_IDLE) {
+ m_voice->resetRF();
+ m_voice->resetNet();
+
+ m_data->resetRF();
+
+ m_trunk->m_rfTSBK = lc::TSBK(m_siteData, m_idenEntry);
+ m_trunk->m_netTSBK = lc::TSBK(m_siteData, m_idenEntry);
+ }
}
///
diff --git a/p25/Control.h b/p25/Control.h
index 92b794d1..6ba27458 100644
--- a/p25/Control.h
+++ b/p25/Control.h
@@ -36,6 +36,7 @@
#include "p25/DataPacket.h"
#include "p25/VoicePacket.h"
#include "p25/NID.h"
+#include "p25/SiteData.h"
#include "network/BaseNetwork.h"
#include "network/RemoteControl.h"
#include "lookups/RSSIInterpolator.h"
@@ -138,6 +139,8 @@ namespace p25
lookups::RadioIdLookup* m_ridLookup;
lookups::TalkgroupIdLookup* m_tidLookup;
+ lookups::IdenTable m_idenEntry;
+
RingBuffer m_queue;
RPT_RF_STATE m_rfState;
@@ -163,6 +166,8 @@ namespace p25
NID m_nid;
+ SiteData m_siteData;
+
lookups::RSSIInterpolator* m_rssiMapper;
uint8_t m_rssi;
uint8_t m_maxRSSI;
diff --git a/p25/DataPacket.cpp b/p25/DataPacket.cpp
index 45b73bf7..cd4166fe 100644
--- a/p25/DataPacket.cpp
+++ b/p25/DataPacket.cpp
@@ -91,8 +91,6 @@ bool DataPacket::process(uint8_t* data, uint32_t len)
// handle individual DUIDs
if (duid == P25_DUID_PDU) {
- m_p25->m_trunk->resetStatusCommand();
-
if (m_p25->m_rfState != RS_RF_DATA) {
m_rfDataHeader.reset();
m_rfDataBlockCnt = 0U;
diff --git a/p25/SiteData.h b/p25/SiteData.h
index 10ad1307..3d9d413b 100644
--- a/p25/SiteData.h
+++ b/p25/SiteData.h
@@ -52,7 +52,10 @@ namespace p25
m_channelId(1U),
m_channelNo(1U),
m_serviceClass(P25_SVC_CLS_VOICE | P25_SVC_CLS_DATA),
- m_isAdjSite(false)
+ m_isAdjSite(false),
+ m_callsign("CHANGEME"),
+ m_chCnt(0U),
+ m_netActive(false)
{
/* stub */
}
@@ -74,7 +77,10 @@ namespace p25
m_channelId(1U),
m_channelNo(1U),
m_serviceClass(P25_SVC_CLS_VOICE | P25_SVC_CLS_DATA),
- m_isAdjSite(false)
+ m_isAdjSite(false),
+ m_callsign("CHANGEME"),
+ m_chCnt(0U),
+ m_netActive(false)
{
// lra clamping
if (lra > 0xFFU) // clamp to $FF
@@ -128,6 +134,27 @@ namespace p25
m_serviceClass = serviceClass;
}
+ /// Helper to set the site callsign.
+ /// Callsign.
+ void setCallsign(std::string callsign)
+ {
+ m_callsign = callsign;
+ }
+
+ /// Helper to set the site channel count.
+ /// Channel count.
+ void setChCnt(uint8_t chCnt)
+ {
+ m_chCnt = m_chCnt;
+ }
+
+ /// Helper to set the site network active flag.
+ /// Network active.
+ void setNetActive(bool netActive)
+ {
+ m_netActive = netActive;
+ }
+
/// Helper to set adjacent site data.
/// P25 System ID.
/// P25 RFSS ID.
@@ -179,6 +206,10 @@ namespace p25
m_serviceClass = serviceClass;
m_isAdjSite = true;
+
+ m_callsign = "ADJSITE ";
+ m_chCnt = -1; // don't store channel count for adjacent sites
+ m_netActive = true; // adjacent sites are explicitly network active
}
/// Equals operator.
@@ -201,6 +232,11 @@ namespace p25
m_serviceClass = data.m_serviceClass;
m_isAdjSite = data.m_isAdjSite;
+
+ m_callsign = data.m_callsign;
+ m_chCnt = data.m_chCnt;
+
+ m_netActive = data.m_netActive;
}
return *this;
@@ -225,6 +261,12 @@ namespace p25
__READONLY_PROPERTY_PLAIN(uint8_t, serviceClass, serviceClass);
/// Flag indicating whether this site data is for an adjacent site.
__READONLY_PROPERTY_PLAIN(bool, isAdjSite, isAdjSite);
+ /// Callsign.
+ __READONLY_PROPERTY_PLAIN(std::string, callsign, callsign);
+ /// Count of available channels.
+ __READONLY_PROPERTY_PLAIN(uint8_t, chCnt, chCnt);
+ /// Flag indicating whether this site is a linked active network member.
+ __READONLY_PROPERTY_PLAIN(bool, netActive, netActive);
};
} // namespace p25
diff --git a/p25/TrunkPacket.cpp b/p25/TrunkPacket.cpp
index a6a58b7f..83c10528 100644
--- a/p25/TrunkPacket.cpp
+++ b/p25/TrunkPacket.cpp
@@ -138,173 +138,6 @@ const uint32_t GRANT_TIMER_TIMEOUT = 15U;
// ---------------------------------------------------------------------------
// Public Class Members
// ---------------------------------------------------------------------------
-///
-/// Sets local configured site data.
-///
-/// P25 Network ID.
-/// P25 System ID.
-/// P25 RFSS ID.
-/// P25 Site ID.
-/// P25 Location Resource Area.
-/// Channel ID.
-/// Channel Number.
-void TrunkPacket::setSiteData(uint32_t netId, uint32_t sysId, uint8_t rfssId, uint8_t siteId, uint8_t lra,
- uint8_t channelId, uint32_t channelNo)
-{
- uint8_t serviceClass = m_rfTSBK.getServiceClass();
- m_siteData = SiteData(netId, sysId, rfssId, siteId, lra, channelId, channelNo, serviceClass);
-
- m_rfTSBK.setSiteData(m_siteData);
- m_rfTDULC.setSiteData(m_siteData);
- m_p25->m_voice->m_rfLC.setSiteData(m_siteData);
-
- m_netTSBK.setSiteData(m_siteData);
- m_netTDULC.setSiteData(m_siteData);
- m_p25->m_voice->m_netLC.setSiteData(m_siteData);
-}
-
-///
-/// Sets local configured site callsign.
-///
-///
-void TrunkPacket::setCallsign(std::string callsign)
-{
- m_rfTSBK.setCallsign(callsign);
- m_netTSBK.setCallsign(callsign);
-}
-
-///
-/// Sets a flag indicating whether or not networking is active.
-///
-///
-void TrunkPacket::setNetActive(bool active)
-{
- m_rfTSBK.setNetActive(active);
- m_rfTDULC.setNetActive(active);
- m_netTSBK.setNetActive(active);
- m_netTDULC.setNetActive(active);
-}
-
-///
-/// Sets the total number of channels at the site.
-///
-///
-void TrunkPacket::setSiteChCnt(uint8_t chCnt)
-{
- m_rfTSBK.setSiteChCnt(chCnt);
- m_netTSBK.setSiteChCnt(chCnt);
-}
-
-///
-/// Sets the service class for this site.
-///
-///
-///
-void TrunkPacket::setServiceClass(bool control, bool voiceOnControl)
-{
- uint8_t serviceClass = P25_SVC_CLS_VOICE | P25_SVC_CLS_DATA;
- if (control) {
- serviceClass |= P25_SVC_CLS_REG;
- }
-
- if (voiceOnControl) {
- serviceClass |= P25_SVC_CLS_COMPOSITE;
- }
-
- m_rfTSBK.setServiceClass(serviceClass);
- m_netTSBK.setServiceClass(serviceClass);
-
- m_rfTDULC.setServiceClass(serviceClass);
- m_netTDULC.setServiceClass(serviceClass);
-
- m_p25->m_voice->m_rfLC.setServiceClass(serviceClass);
- m_p25->m_voice->m_netLC.setServiceClass(serviceClass);
-}
-
-///
-/// Resets the data states for the RF interface.
-///
-void TrunkPacket::resetRF()
-{
- m_rfTSBK.reset();
- m_rfTDULC.reset();
-}
-
-///
-/// Resets the data states for the network.
-///
-void TrunkPacket::resetNet()
-{
- m_netTSBK.reset();
- m_netTDULC.reset();
-}
-
-///
-/// Sets the RF TSBK and TDULC data to match the given LC data.
-///
-///
-void TrunkPacket::setRFLC(const lc::LC& lc)
-{
- m_rfTSBK.reset();
- m_rfTDULC.reset();
-
- m_rfTSBK.setProtect(lc.getProtect());
- m_rfTDULC.setProtect(lc.getProtect());
- m_rfTSBK.setMFId(lc.getMFId());
- m_rfTDULC.setMFId(lc.getMFId());
-
- m_rfTSBK.setSrcId(lc.getSrcId());
- m_rfTDULC.setSrcId(lc.getSrcId());
- m_rfTSBK.setDstId(lc.getDstId());
- m_rfTDULC.setDstId(lc.getDstId());
-
- m_rfTSBK.setGrpVchNo(lc.getGrpVchNo());
- m_rfTDULC.setGrpVchNo(lc.getGrpVchNo());
-
- m_rfTSBK.setEmergency(lc.getEmergency());
- m_rfTDULC.setEmergency(lc.getEmergency());
- m_rfTSBK.setEncrypted(lc.getEncrypted());
- m_rfTDULC.setEncrypted(lc.getEmergency());
- m_rfTSBK.setPriority(lc.getPriority());
- m_rfTDULC.setPriority(lc.getPriority());
-
- m_rfTSBK.setGroup(lc.getGroup());
- m_rfTDULC.setGroup(lc.getGroup());
-}
-
-///
-/// Sets the network TSBK and TDULC data to match the given LC data.
-///
-///
-void TrunkPacket::setNetLC(const lc::LC& lc)
-{
- m_netTSBK.reset();
- m_netTDULC.reset();
-
- m_netTSBK.setProtect(lc.getProtect());
- m_netTDULC.setProtect(lc.getProtect());
- m_netTSBK.setMFId(lc.getMFId());
- m_netTDULC.setMFId(lc.getMFId());
-
- m_netTSBK.setSrcId(lc.getSrcId());
- m_netTDULC.setSrcId(lc.getSrcId());
- m_netTSBK.setDstId(lc.getDstId());
- m_netTDULC.setDstId(lc.getDstId());
-
- m_netTSBK.setGrpVchNo(lc.getGrpVchNo());
- m_netTDULC.setGrpVchNo(lc.getGrpVchNo());
-
- m_netTSBK.setEmergency(lc.getEmergency());
- m_netTDULC.setEmergency(lc.getEmergency());
- m_netTSBK.setEncrypted(lc.getEncrypted());
- m_netTDULC.setEncrypted(lc.getEmergency());
- m_netTSBK.setPriority(lc.getPriority());
- m_netTDULC.setPriority(lc.getPriority());
-
- m_netTSBK.setGroup(lc.getGroup());
- m_netTDULC.setGroup(lc.getGroup());
-}
-
///
/// Process a data frame from the RF interface.
///
@@ -334,8 +167,9 @@ bool TrunkPacket::process(uint8_t* data, uint32_t len)
}
m_p25->m_queue.clear();
- m_rfTSBK.reset();
- m_netTSBK.reset();
+
+ m_rfTSBK = lc::TSBK(m_p25->m_siteData, m_p25->m_idenEntry, m_dumpTSBK);
+ m_netTSBK = lc::TSBK(m_p25->m_siteData, m_p25->m_idenEntry, m_dumpTSBK);
bool ret = m_rfTSBK.decode(data + 2U);
if (!ret) {
@@ -347,8 +181,6 @@ bool TrunkPacket::process(uint8_t* data, uint32_t len)
uint32_t srcId = m_rfTSBK.getSrcId();
uint32_t dstId = m_rfTSBK.getDstId();
- resetStatusCommand(m_rfTSBK);
-
switch (m_rfTSBK.getLCO()) {
case TSBK_IOSP_GRP_VCH:
// make sure control data is supported
@@ -448,23 +280,17 @@ bool TrunkPacket::process(uint8_t* data, uint32_t len)
// validate the source RID
VALID_SRCID("TSBK_IOSP_STS_UPDT (Status Update)", TSBK_IOSP_STS_UPDT, srcId);
- if ((m_statusSrcId == 0U) && (m_statusValue == 0U)) {
- RF_TO_WRITE_NET();
- }
+ RF_TO_WRITE_NET();
if (m_verbose) {
LogMessage(LOG_RF, P25_TSDU_STR ", TSBK_IOSP_STS_UPDT (Status Update), status = $%02X, srcId = %u", m_rfTSBK.getStatus(), srcId);
}
- ::ActivityLog("P25", true, "status update from %u", srcId);
-
if (!m_noStatusAck) {
writeRF_TSDU_ACK_FNE(srcId, TSBK_IOSP_STS_UPDT, false, false);
}
- if (m_statusCmdEnable) {
- preprocessStatusCommand();
- }
+ ::ActivityLog("P25", true, "status update from %u", srcId);
break;
case TSBK_IOSP_MSG_UPDT:
// validate the source RID
@@ -487,16 +313,6 @@ bool TrunkPacket::process(uint8_t* data, uint32_t len)
// validate the source RID
VALID_SRCID("TSBK_IOSP_CALL_ALRT (Call Alert)", TSBK_IOSP_CALL_ALRT, srcId);
- // is status command mode enabled with status data?
- if (m_statusCmdEnable) {
- if (processStatusCommand(srcId, dstId)) {
- m_p25->m_rfState = prevRfState;
- return true;
- }
-
- resetStatusCommand();
- }
-
// validate the target RID
VALID_DSTID("TSBK_IOSP_CALL_ALRT (Call Alert)", TSBK_IOSP_CALL_ALRT, dstId);
@@ -548,18 +364,6 @@ bool TrunkPacket::process(uint8_t* data, uint32_t len)
m_rfTSBK.getExtendedFunction(), dstId, srcId);
}
- // is status control mode enabled with status data?
- if (m_statusCmdEnable && (m_statusValue != 0U)) {
- m_rfTSBK.setLCO(TSBK_IOSP_ACK_RSP);
- m_rfTSBK.setAIV(true);
- m_rfTSBK.setService(TSBK_IOSP_CALL_ALRT);
-
- if (m_verbose) {
- LogMessage(LOG_RF, P25_TSDU_STR ", TSBK_IOSP_ACK_RSP (Acknowledge Response), serviceType = $%02X, srcId = %u",
- m_rfTSBK.getService(), m_statusSrcId);
- }
- }
-
// generate activity log entry
if (m_rfTSBK.getExtendedFunction() == P25_EXT_FNCT_CHECK_ACK) {
::ActivityLog("P25", true, "radio check response from %u to %u", dstId, srcId);
@@ -572,7 +376,6 @@ bool TrunkPacket::process(uint8_t* data, uint32_t len)
}
writeRF_TSDU_SBF(true);
- resetStatusCommand();
break;
case TSBK_IOSP_GRP_AFF:
// make sure control data is supported
@@ -677,8 +480,8 @@ bool TrunkPacket::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, d
switch (duid) {
case P25_DUID_TSDU:
if (m_p25->m_netState == RS_NET_IDLE) {
- m_rfTSBK.reset();
- m_netTSBK.reset();
+ m_rfTSBK = lc::TSBK(m_p25->m_siteData, m_p25->m_idenEntry, m_dumpTSBK);
+ m_netTSBK = lc::TSBK(m_p25->m_siteData, m_p25->m_idenEntry, m_dumpTSBK);
bool ret = m_netTSBK.decode(data);
if (!ret) {
@@ -691,7 +494,7 @@ bool TrunkPacket::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, d
return false;
}
- if (m_netTSBK.getAdjSiteId() != m_siteData.siteId()) {
+ if (m_netTSBK.getAdjSiteId() != m_p25->m_siteData.siteId()) {
// update site table data
SiteData site;
try {
@@ -741,8 +544,6 @@ bool TrunkPacket::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, d
uint32_t srcId = m_netTSBK.getSrcId();
uint32_t dstId = m_netTSBK.getDstId();
- resetStatusCommand(m_netTSBK);
-
switch (m_netTSBK.getLCO()) {
case TSBK_IOSP_UU_ANS:
if (m_netTSBK.getResponse() > 0U) {
@@ -820,8 +621,6 @@ bool TrunkPacket::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, d
LogMessage(LOG_NET, P25_TSDU_STR ", TSBK_IOSP_EXT_FNCT (Extended Function), serviceType = $%02X, arg = %u, tgt = %u",
m_netTSBK.getService(), srcId, dstId);
}
-
- resetStatusCommand();
break;
case TSBK_IOSP_GRP_AFF:
// ignore a network group affiliation command
@@ -868,15 +667,13 @@ void TrunkPacket::writeAdjSSNetwork()
return;
}
- m_rfTSBK.reset();
- m_netTSBK.reset();
+ m_rfTSBK = lc::TSBK(m_p25->m_siteData, m_p25->m_idenEntry, m_dumpTSBK);
+ m_netTSBK = lc::TSBK(m_p25->m_siteData, m_p25->m_idenEntry, m_dumpTSBK);
if (m_network != NULL) {
- uint8_t serviceClass = m_rfTSBK.getServiceClass();
-
if (m_verbose) {
LogMessage(LOG_NET, P25_TSDU_STR ", TSBK_OSP_ADJ_STS_BCAST (Adjacent Site Status Broadcast), network announce, sysId = $%03X, rfss = $%02X, site = $%02X, chId = %u, chNo = %u, svcClass = $%02X",
- m_siteData.sysId(), m_siteData.rfssId(), m_siteData.siteId(), m_siteData.channelId(), m_siteData.channelNo(), serviceClass);
+ m_p25->m_siteData.sysId(), m_p25->m_siteData.rfssId(), m_p25->m_siteData.siteId(), m_p25->m_siteData.channelId(), m_p25->m_siteData.channelNo(), m_p25->m_siteData.serviceClass());
}
uint8_t cfva = P25_CFVA_VALID;
@@ -887,12 +684,12 @@ void TrunkPacket::writeAdjSSNetwork()
// transmit adjacent site broadcast
m_rfTSBK.setLCO(TSBK_OSP_ADJ_STS_BCAST);
m_rfTSBK.setAdjSiteCFVA(cfva);
- m_rfTSBK.setAdjSiteSysId(m_siteData.sysId());
- m_rfTSBK.setAdjSiteRFSSId(m_siteData.rfssId());
- m_rfTSBK.setAdjSiteId(m_siteData.siteId());
- m_rfTSBK.setAdjSiteChnId(m_siteData.channelId());
- m_rfTSBK.setAdjSiteChnNo(m_siteData.channelNo());
- m_rfTSBK.setAdjSiteSvcClass(serviceClass);
+ m_rfTSBK.setAdjSiteSysId(m_p25->m_siteData.sysId());
+ m_rfTSBK.setAdjSiteRFSSId(m_p25->m_siteData.rfssId());
+ m_rfTSBK.setAdjSiteId(m_p25->m_siteData.siteId());
+ m_rfTSBK.setAdjSiteChnId(m_p25->m_siteData.channelId());
+ m_rfTSBK.setAdjSiteChnNo(m_p25->m_siteData.channelNo());
+ m_rfTSBK.setAdjSiteSvcClass(m_p25->m_siteData.serviceClass());
RF_TO_WRITE_NET();
}
@@ -1039,11 +836,11 @@ void TrunkPacket::releaseDstIdGrant(uint32_t dstId, bool releaseAll)
if (m_voiceGrantChCnt > 0U) {
m_voiceGrantChCnt--;
- setSiteChCnt(m_voiceChCnt + m_voiceGrantChCnt);
+ m_p25->m_siteData.setChCnt(m_voiceChCnt + m_voiceGrantChCnt);
}
else {
m_voiceGrantChCnt = 0U;
- setSiteChCnt(m_voiceChCnt);
+ m_p25->m_siteData.setChCnt(m_voiceChCnt);
}
m_grantTimers[dstId].stop();
@@ -1086,24 +883,6 @@ void TrunkPacket::clearGrpAff(uint32_t dstId, bool releaseAll)
}
}
-///
-/// Resets the state of the status commands.
-///
-void TrunkPacket::resetStatusCommand()
-{
- // reset status control data
- if (m_statusCmdEnable) {
- if (m_statusSrcId != 0U && m_statusValue != 0U) {
- if (m_verbose) {
- LogMessage(LOG_RF, P25_TSDU_STR ", TSBK_IOSP_STS_UPDT (Status Update), canceled command mode, statusCurrentStatus = $%02X", m_statusValue);
- }
- }
-
- m_statusSrcId = 0U;
- m_statusValue = 0U;
- }
-}
-
///
/// Updates the processor by the passed number of milliseconds.
///
@@ -1300,11 +1079,7 @@ void TrunkPacket::writeRF_TSDU_Mot_Patch(uint32_t group1, uint32_t group2, uint3
/// Flag indicating whether TSBK dumping is enabled.
void TrunkPacket::setTSBKVerbose(bool verbose)
{
- m_rfTSBK.setVerbose(verbose);
- m_netTSBK.setVerbose(verbose);
-
- m_rfTDULC.setVerbose(verbose);
- m_netTDULC.setVerbose(verbose);
+ m_dumpTSBK = verbose;
}
// ---------------------------------------------------------------------------
@@ -1324,15 +1099,13 @@ TrunkPacket::TrunkPacket(Control* p25, network::BaseNetwork* network, bool dumpT
m_patchSuperGroup(0xFFFFU),
m_verifyAff(false),
m_verifyReg(false),
- m_rfTSBK(),
- m_netTSBK(),
+ m_rfTSBK(SiteData(), lookups::IdenTable()),
+ m_netTSBK(SiteData(), lookups::IdenTable()),
m_rfMBF(NULL),
m_mbfCnt(0U),
m_mbfIdenCnt(0U),
m_mbfAdjSSCnt(0U),
m_mbfSCCBCnt(0U),
- m_rfTDULC(),
- m_netTDULC(),
m_voiceChTable(),
m_adjSiteTable(),
m_adjSiteUpdateCnt(),
@@ -1346,36 +1119,15 @@ TrunkPacket::TrunkPacket(Control* p25, network::BaseNetwork* network, bool dumpT
m_voiceGrantChCnt(0U),
m_noStatusAck(false),
m_noMessageAck(true),
- m_statusCmdEnable(false),
- m_statusRadioCheck(0U),
- m_statusRadioInhibit(0U),
- m_statusRadioUninhibit(0U),
- m_statusRadioForceReg(0U),
- m_statusRadioForceDereg(0U),
- m_statusSrcId(0U),
- m_statusValue(0U),
- m_siteData(),
m_adjSiteUpdateTimer(1000U),
m_adjSiteUpdateInterval(ADJ_SITE_TIMER_TIMEOUT),
+ m_dumpTSBK(false),
m_verbose(verbose),
m_debug(debug)
{
m_rfMBF = new uint8_t[P25_MAX_PDU_COUNT * P25_LDU_FRAME_LENGTH_BYTES + 2U];
::memset(m_rfMBF, 0x00U, P25_MAX_PDU_COUNT * P25_LDU_FRAME_LENGTH_BYTES + 2U);
- // set metadata defaults
- m_rfTSBK.setSiteData(m_siteData);
- m_netTSBK.setSiteData(m_siteData);
- m_rfTSBK.setCallsign("CHANGEME");
- m_netTSBK.setCallsign("CHANGEME");
- m_rfTSBK.setVerbose(dumpTSBKData);
- m_netTSBK.setVerbose(dumpTSBKData);
-
- m_rfTDULC.setSiteData(m_siteData);
- m_netTDULC.setSiteData(m_siteData);
- m_rfTDULC.setVerbose(dumpTSBKData);
- m_netTDULC.setVerbose(dumpTSBKData);
-
m_voiceChTable.clear();
m_adjSiteTable.clear();
@@ -1443,7 +1195,7 @@ void TrunkPacket::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adjSS)
do
{
- m_rfTSBK.reset();
+ m_rfTSBK = lc::TSBK(m_p25->m_siteData, m_p25->m_idenEntry, m_dumpTSBK);
if (m_debug) {
LogDebug(LOG_P25, "writeRF_ControlData, mbfCnt = %u, frameCnt = %u, seq = %u, adjSS = %u", m_mbfCnt, frameCnt, n, adjSS);
@@ -1523,9 +1275,9 @@ void TrunkPacket::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adjSS)
///
/// Helper to write a P25 TDU w/ link control packet.
///
-///
+///
///
-void TrunkPacket::writeRF_TDULC(uint8_t duid, bool noNetwork)
+void TrunkPacket::writeRF_TDULC(lc::TDULC lc, bool noNetwork)
{
uint8_t data[P25_TDULC_FRAME_LENGTH_BYTES + 2U];
::memset(data + 2U, 0x00U, P25_TDULC_FRAME_LENGTH_BYTES);
@@ -1537,7 +1289,7 @@ void TrunkPacket::writeRF_TDULC(uint8_t duid, bool noNetwork)
m_p25->m_nid.encode(data + 2U, P25_DUID_TDULC);
// Generate TDULC Data
- m_rfTDULC.encode(data + 2U);
+ lc.encode(data + 2U);
// Add busy bits
m_p25->addBusyBits(data + 2U, P25_TDULC_FRAME_LENGTH_BITS, true, true);
@@ -1568,39 +1320,38 @@ void TrunkPacket::writeRF_TDULC(uint8_t duid, bool noNetwork)
void TrunkPacket::writeRF_TDULC_ChanRelease(bool grp, uint32_t srcId, uint32_t dstId)
{
uint32_t count = m_p25->m_hangCount / 2;
+ lc::TDULC lc = lc::TDULC(m_p25->m_siteData, m_p25->m_idenEntry, m_dumpTSBK);
if (m_p25->m_control) {
for (uint32_t i = 0; i < count; i++) {
if ((srcId != 0U) && (dstId != 0U)) {
- m_rfTDULC.setSrcId(srcId);
- m_rfTDULC.setDstId(dstId);
- m_rfTDULC.setEmergency(false);
+ lc.setSrcId(srcId);
+ lc.setDstId(dstId);
+ lc.setEmergency(false);
if (grp) {
- m_rfTDULC.setLCO(LC_GROUP);
- writeRF_TDULC(P25_DUID_TDULC, true);
+ lc.setLCO(LC_GROUP);
+ writeRF_TDULC(lc, true);
}
else {
- m_rfTDULC.setLCO(LC_PRIVATE);
- writeRF_TDULC(P25_DUID_TDULC, true);
+ lc.setLCO(LC_PRIVATE);
+ writeRF_TDULC(lc, true);
}
}
- m_rfTDULC.setLCO(LC_NET_STS_BCAST);
- writeRF_TDULC(P25_DUID_TDULC, true);
- m_rfTDULC.setLCO(LC_RFSS_STS_BCAST);
- writeRF_TDULC(P25_DUID_TDULC, true);
+ lc.setLCO(LC_NET_STS_BCAST);
+ writeRF_TDULC(lc, true);
+ lc.setLCO(LC_RFSS_STS_BCAST);
+ writeRF_TDULC(lc, true);
}
}
if (m_verbose) {
- LogMessage(LOG_RF, P25_TDULC_STR ", LC_CALL_TERM (Call Termination), srcId = %u, dstId = %u", m_rfTDULC.getSrcId(), m_rfTDULC.getDstId());
+ LogMessage(LOG_RF, P25_TDULC_STR ", LC_CALL_TERM (Call Termination), srcId = %u, dstId = %u", lc.getSrcId(), lc.getDstId());
}
- m_rfTDULC.setLCO(LC_CALL_TERM);
- writeRF_TDULC(P25_DUID_TDULC, true);
-
- m_rfTDULC.reset();
+ lc.setLCO(LC_CALL_TERM);
+ writeRF_TDULC(lc, true);
}
///
@@ -1777,7 +1528,7 @@ void TrunkPacket::queueRF_TSBK_Ctrl_MBF(uint8_t lco)
if (!m_p25->m_control)
return;
- m_rfTSBK.reset();
+ m_rfTSBK = lc::TSBK(m_p25->m_siteData, m_p25->m_idenEntry, m_dumpTSBK);
switch (lco) {
case TSBK_OSP_IDEN_UP:
@@ -1805,14 +1556,14 @@ void TrunkPacket::queueRF_TSBK_Ctrl_MBF(uint8_t lco)
// handle 700/800/900 identities
if (entry.baseFrequency() >= 762000000U) {
- m_rfTSBK.setIdenTable(entry);
+ m_rfTSBK.siteIdenEntry(entry);
// transmit channel ident broadcast
m_rfTSBK.setLCO(TSBK_OSP_IDEN_UP);
}
else {
// handle as a VHF/UHF identity
- m_rfTSBK.setIdenTable(entry);
+ m_rfTSBK.siteIdenEntry(entry);
// transmit channel ident broadcast
m_rfTSBK.setLCO(TSBK_OSP_IDEN_UP_VU);
@@ -1867,12 +1618,7 @@ void TrunkPacket::queueRF_TSBK_Ctrl_MBF(uint8_t lco)
else {
cfva |= P25_CFVA_VALID;
}
-/*
- uint8_t serviceClass = site.serviceClass();
- if ((serviceClass & P25_SVC_CLS_COMPOSITE) == P25_SVC_CLS_COMPOSITE) {
- cfva |= P25_CFVA_CONV;
- }
-*/
+
// transmit adjacent site broadcast
m_rfTSBK.setLCO(TSBK_OSP_ADJ_STS_BCAST);
m_rfTSBK.setAdjSiteCFVA(cfva);
@@ -2056,7 +1802,7 @@ bool TrunkPacket::writeRF_TSDU_Grant(bool grp, bool skip, bool net)
m_grantTimers[m_rfTSBK.getDstId()].start();
m_voiceGrantChCnt++;
- setSiteChCnt(m_voiceChCnt + m_voiceGrantChCnt);
+ m_p25->m_siteData.setChCnt(m_voiceChCnt + m_voiceGrantChCnt);
}
}
else {
@@ -2239,7 +1985,7 @@ void TrunkPacket::writeRF_TSDU_U_Reg_Rsp(uint32_t srcId)
m_rfTSBK.setResponse(P25_RSP_ACCEPT);
// validate the system ID
- if (m_rfTSBK.getSysId() != m_siteData.sysId()) {
+ if (m_rfTSBK.getSysId() != m_p25->m_siteData.sysId()) {
LogWarning(LOG_RF, P25_TSDU_STR ", TSBK_IOSP_U_REG (Unit Registration Response) denial, SYSID rejection, sysId = $%03X", m_rfTSBK.getSysId());
::ActivityLog("P25", true, "unit registration request from %u denied", srcId);
m_rfTSBK.setResponse(P25_RSP_DENY);
@@ -2424,7 +2170,8 @@ void TrunkPacket::writeNet_TSDU_From_RF(uint8_t* data)
///
/// Helper to write a network P25 TDU w/ link control packet.
///
-void TrunkPacket::writeNet_TDULC()
+///
+void TrunkPacket::writeNet_TDULC(lc::TDULC lc)
{
uint8_t buffer[P25_TDULC_FRAME_LENGTH_BYTES + 2U];
::memset(buffer, 0x00U, P25_TDULC_FRAME_LENGTH_BYTES + 2U);
@@ -2439,7 +2186,7 @@ void TrunkPacket::writeNet_TDULC()
m_p25->m_nid.encode(buffer + 2U, P25_DUID_TDULC);
// Regenerate TDULC Data
- m_netTDULC.encode(buffer + 2U);
+ lc.encode(buffer + 2U);
// Add busy bits
m_p25->addBusyBits(buffer + 2U, P25_TDULC_FRAME_LENGTH_BITS, true, true);
@@ -2447,7 +2194,7 @@ void TrunkPacket::writeNet_TDULC()
m_p25->writeQueueNet(buffer, P25_TDULC_FRAME_LENGTH_BYTES + 2U);
if (m_verbose) {
- LogMessage(LOG_NET, P25_TDULC_STR ", lc = $%02X, srcId = %u", m_netTDULC.getLCO(), m_netTDULC.getSrcId());
+ LogMessage(LOG_NET, P25_TDULC_STR ", lc = $%02X, srcId = %u", lc.getLCO(), lc.getSrcId());
}
if (m_p25->m_voice->m_netFrames > 0) {
@@ -2463,7 +2210,6 @@ void TrunkPacket::writeNet_TDULC()
m_p25->m_netTimeout.stop();
m_p25->m_networkWatchdog.stop();
- m_netTDULC.reset();
m_p25->m_netState = RS_NET_IDLE;
m_p25->m_tailOnIdle = true;
}
@@ -2518,93 +2264,6 @@ void TrunkPacket::denialInhibit(uint32_t srcId)
}
}
-///
-///
-///
-///
-void TrunkPacket::resetStatusCommand(const lc::TSBK& tsbk)
-{
- // reset status control data if the status current mode is set and the LCO isn't CALL ALERT
- if (m_statusCmdEnable && ((m_rfTSBK.getLCO() != TSBK_IOSP_CALL_ALRT) && (m_rfTSBK.getLCO() != TSBK_IOSP_EXT_FNCT))) {
- resetStatusCommand();
- }
-}
-
-///
-///
-///
-void TrunkPacket::preprocessStatusCommand()
-{
- if (m_statusCmdEnable) {
- m_statusSrcId = m_rfTSBK.getSrcId();
- m_statusValue = m_rfTSBK.getStatus();
-
- if (m_statusValue != 0U) {
- if ((m_statusValue == m_statusRadioCheck) ||
- (m_statusValue == m_statusRadioInhibit) || (m_statusValue == m_statusRadioUninhibit) ||
- (m_statusValue == m_statusRadioForceReg) || (m_statusValue == m_statusRadioForceDereg)) {
- if (m_verbose) {
- LogMessage(LOG_RF, P25_TSDU_STR ", TSBK_IOSP_STS_UPDT (Status Update), command mode, statusCurrentStatus = $%02X", m_statusValue);
- }
- }
- else {
- resetStatusCommand();
- }
- }
- }
-}
-
-///
-///
-///
-///
-///
-///
-bool TrunkPacket::processStatusCommand(uint32_t srcId, uint32_t dstId)
-{
- // is status command mode enabled with status data?
- if (m_statusCmdEnable && (m_statusValue != 0U)) {
- // if the status srcId isn't the CALL ALERT srcId ignore
- if (m_statusSrcId == srcId) {
- if ((m_statusRadioCheck != 0U) && (m_statusValue == m_statusRadioCheck)) {
- writeRF_TSDU_Ext_Func(P25_EXT_FNCT_CHECK, srcId, dstId);
- }
- else if ((m_statusRadioInhibit != 0U) && (m_statusValue == m_statusRadioInhibit)) {
- writeRF_TSDU_Ext_Func(P25_EXT_FNCT_INHIBIT, P25_WUID_SYS, dstId);
- }
- else if ((m_statusRadioUninhibit != 0U) && (m_statusValue == m_statusRadioUninhibit)) {
- writeRF_TSDU_Ext_Func(P25_EXT_FNCT_UNINHIBIT, P25_WUID_SYS, dstId);
- }
- else if ((m_statusRadioForceReg != 0U) && (m_statusValue == m_statusRadioForceReg)) {
- // update dynamic unit registration table
- if (!hasSrcIdUnitReg(srcId)) {
- m_unitRegTable.push_back(srcId);
- }
-
- writeRF_TSDU_Grp_Aff_Rsp(srcId, dstId);
- }
- else if ((m_statusRadioForceDereg != 0U) && (m_statusValue == m_statusRadioForceDereg)) {
- writeRF_TSDU_U_Dereg_Ack(srcId);
- }
- else {
- LogError(LOG_P25, P25_TSDU_STR ", unhandled command mode, statusCurrentStatus = $%02X, srcId = %u, dstId = %u", m_statusValue, srcId, dstId);
- resetStatusCommand();
- }
-
- writeRF_TSDU_ACK_FNE(srcId, TSBK_IOSP_CALL_ALRT, false, false);
- return true;
- }
- else {
- if (m_verbose) {
- LogWarning(LOG_P25, P25_TSDU_STR ", TSBK_IOSP_STS_UPDT (Status Update), illegal attempt by srcId = %u to access status command", srcId);
- }
- }
- }
-
- resetStatusCommand();
- return false;
-}
-
///
/// Helper to add the idle status bits on P25 frame data.
///
diff --git a/p25/TrunkPacket.h b/p25/TrunkPacket.h
index da904913..3062aef4 100644
--- a/p25/TrunkPacket.h
+++ b/p25/TrunkPacket.h
@@ -34,7 +34,6 @@
#include "p25/lc/TSBK.h"
#include "p25/lc/TDULC.h"
#include "p25/Control.h"
-#include "p25/SiteData.h"
#include "network/BaseNetwork.h"
#include "network/RemoteControl.h"
#include "Timer.h"
@@ -60,27 +59,6 @@ namespace p25
class HOST_SW_API TrunkPacket {
public:
- /// Sets local configured site data.
- void setSiteData(uint32_t netId, uint32_t sysId, uint8_t rfssId, uint8_t siteId, uint8_t lra,
- uint8_t channelId, uint32_t channelNo);
- /// Sets local configured site callsign.
- void setCallsign(std::string callsign);
- /// Sets a flag indicating whether or not networking is active.
- void setNetActive(bool active);
- /// Sets the total number of channels at the site.
- void setSiteChCnt(uint8_t chCnt);
- /// Sets the service class for this site.
- void setServiceClass(bool control, bool voiceOnControl);
-
- /// Resets the data states for the RF interface.
- void resetRF();
- /// Resets the data states for the network.
- void resetNet();
- /// Sets the RF TSBK and TDULC data to match the given LC data.
- void setRFLC(const lc::LC& lc);
- /// Sets the network TSBK and TDULC data to match the given LC data.
- void setNetLC(const lc::LC& lc);
-
/// Process a data frame from the RF interface.
bool process(uint8_t* data, uint32_t len);
/// Process a data frame from the network.
@@ -105,9 +83,6 @@ namespace p25
/// Helper to release group affiliations.
void clearGrpAff(uint32_t dstId, bool releaseAll);
- /// Resets the state of the status commands.
- void resetStatusCommand();
-
/// Updates the processor by the passed number of milliseconds.
void clock(uint32_t ms);
@@ -150,9 +125,6 @@ namespace p25
uint8_t m_mbfAdjSSCnt;
uint8_t m_mbfSCCBCnt;
- lc::TDULC m_rfTDULC;
- lc::TDULC m_netTDULC;
-
std::vector m_voiceChTable;
std::unordered_map m_adjSiteTable;
@@ -173,21 +145,11 @@ namespace p25
bool m_noStatusAck;
bool m_noMessageAck;
- bool m_statusCmdEnable;
- uint8_t m_statusRadioCheck;
- uint8_t m_statusRadioInhibit;
- uint8_t m_statusRadioUninhibit;
- uint8_t m_statusRadioForceReg;
- uint8_t m_statusRadioForceDereg;
-
- uint32_t m_statusSrcId;
- uint8_t m_statusValue;
-
- SiteData m_siteData;
-
Timer m_adjSiteUpdateTimer;
uint32_t m_adjSiteUpdateInterval;
+ bool m_dumpTSBK;
+
bool m_verbose;
bool m_debug;
@@ -203,7 +165,7 @@ namespace p25
void writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adjSS);
/// Helper to write a P25 TDU w/ link control packet.
- void writeRF_TDULC(uint8_t duid, bool noNetwork);
+ void writeRF_TDULC(lc::TDULC lc, bool noNetwork);
/// Helper to write a P25 TDU w/ link control channel release packet.
void writeRF_TDULC_ChanRelease(bool grp, uint32_t srcId, uint32_t dstId);
@@ -238,20 +200,13 @@ namespace p25
void writeNet_TSDU_From_RF(uint8_t* data);
/// Helper to write a network P25 TDU w/ link control packet.
- void writeNet_TDULC();
+ void writeNet_TDULC(lc::TDULC lc);
/// Helper to write a network single-block P25 TSDU packet.
void writeNet_TSDU();
/// Helper to automatically inhibit a source ID on a denial.
void denialInhibit(uint32_t srcId);
- ///
- void resetStatusCommand(const lc::TSBK& tsbk);
- ///
- void preprocessStatusCommand();
- ///
- bool processStatusCommand(uint32_t srcId, uint32_t dstId);
-
/// Helper to add the idle status bits on P25 frame data.
void addIdleBits(uint8_t* data, uint32_t length, bool b1, bool b2);
};
diff --git a/p25/VoicePacket.cpp b/p25/VoicePacket.cpp
index 86421b40..d6d96942 100644
--- a/p25/VoicePacket.cpp
+++ b/p25/VoicePacket.cpp
@@ -60,9 +60,10 @@ const uint32_t VOC_LDU1_COUNT = 3U;
///
void VoicePacket::resetRF()
{
- m_rfLC.reset();
- m_rfLastLDU1.reset();
- m_rfLastLDU2.reset();
+ m_rfLC = lc::LC(m_p25->m_siteData);
+ //m_rfLastHDU = lc::LC(m_p25->m_siteData);
+ m_rfLastLDU1 = lc::LC(m_p25->m_siteData);
+ m_rfLastLDU2 = lc::LC(m_p25->m_siteData);;
m_rfFrames = 0U;
m_rfErrs = 0U;
@@ -76,8 +77,9 @@ void VoicePacket::resetRF()
///
void VoicePacket::resetNet()
{
- m_netLC.reset();
- m_netLastLDU1.reset();
+ m_netLC = lc::LC(m_p25->m_siteData);
+ m_netLastLDU1 = lc::LC(m_p25->m_siteData);
+
m_netFrames = 0U;
m_netLost = 0U;
m_vocLDU1Count = 0U;
@@ -129,8 +131,6 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
// handle individual DUIDs
if (duid == P25_DUID_HDU) {
- m_p25->m_trunk->resetStatusCommand();
-
m_lastDUID = P25_DUID_HDU;
if (m_p25->m_rfState == RS_RF_LISTENING && m_p25->m_ccRunning) {
@@ -144,7 +144,8 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
resetRF();
resetNet();
- bool ret = m_rfLC.decodeHDU(data + 2U);
+ lc::LC lc = lc::LC(m_p25->m_siteData);
+ bool ret = lc.decodeHDU(data + 2U);
if (!ret) {
LogWarning(LOG_RF, P25_HDU_STR ", undecodable LC");
m_rfUndecodableLC++;
@@ -152,11 +153,11 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
}
if (m_verbose) {
- LogMessage(LOG_RF, P25_HDU_STR ", HDU_BSDWNACT, dstId = %u, algo = $%02X, kid = $%04X", m_rfLC.getDstId(), m_rfLC.getAlgId(), m_rfLC.getKId());
+ LogMessage(LOG_RF, P25_HDU_STR ", HDU_BSDWNACT, dstId = %u, algo = $%02X, kid = $%04X", lc.getDstId(), lc.getAlgId(), lc.getKId());
}
// don't process RF frames if the network isn't in a idle state and the RF destination is the network destination
- if (m_p25->m_netState != RS_NET_IDLE && m_rfLC.getDstId() == m_p25->m_netLastDstId) {
+ if (m_p25->m_netState != RS_NET_IDLE && lc.getDstId() == m_p25->m_netLastDstId) {
LogWarning(LOG_RF, "Traffic collision detect, preempting new RF traffic to existing network traffic!");
resetRF();
return false;
@@ -164,7 +165,7 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
// stop network frames from processing -- RF wants to transmit on a different talkgroup
if (m_p25->m_netState != RS_NET_IDLE) {
- LogWarning(LOG_RF, "Traffic collision detect, preempting existing network traffic to new RF traffic, rfDstId = %u, netDstId = %u", m_rfLC.getDstId(),
+ LogWarning(LOG_RF, "Traffic collision detect, preempting existing network traffic to new RF traffic, rfDstId = %u, netDstId = %u", lc.getDstId(),
m_p25->m_netLastDstId);
resetNet();
@@ -178,17 +179,14 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
}
m_p25->m_rfTGHang.start();
- m_p25->m_rfLastDstId = m_rfLC.getDstId();
+ m_p25->m_rfLastDstId = lc.getDstId();
- m_rfLastHDU.reset();
- m_rfLastHDU = m_rfLC;
+ m_rfLastHDU = lc;
}
return true;
}
else if (duid == P25_DUID_LDU1) {
- m_p25->m_trunk->resetStatusCommand();
-
bool alreadyDecoded = false;
m_lastDUID = P25_DUID_LDU1;
@@ -199,16 +197,18 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
}
}
- bool ret = m_rfLC.decodeLDU1(data + 2U);
+ lc::LC lc = lc::LC(m_p25->m_siteData);
+ bool ret = lc.decodeLDU1(data + 2U);
if (!ret) {
return false;
}
- m_rfLastLDU1 = m_rfLC;
- alreadyDecoded = true;
+ uint32_t srcId = lc.getSrcId();
+ uint32_t dstId = lc.getDstId();
+ bool group = lc.getGroup();
+ bool encrypted = lc.getEncrypted();
- uint32_t srcId = m_rfLC.getSrcId();
- uint32_t dstId = m_rfLC.getDstId();
+ alreadyDecoded = true;
// don't process RF frames if the network isn't in a idle state and the RF destination is the network destination
if (m_p25->m_netState != RS_NET_IDLE && dstId == m_p25->m_netLastDstId) {
@@ -219,34 +219,32 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
// stop network frames from processing -- RF wants to transmit on a different talkgroup
if (m_p25->m_netState != RS_NET_IDLE) {
- if (m_netLC.getSrcId() == srcId && m_netLC.getDstId() == dstId) {
- LogWarning(LOG_RF, "Traffic collision detect, preempting new RF traffic to existing RF traffic (Are we in a voting condition?), rfSrcId = %u, rfDstId = %u, netSrcId = %u, netDstId = %u", m_rfLC.getSrcId(), m_rfLC.getDstId(),
- srcId, dstId);
+ if (m_netLC.getSrcId() == srcId && m_p25->m_netLastDstId == dstId) {
+ LogWarning(LOG_RF, "Traffic collision detect, preempting new RF traffic to existing RF traffic (Are we in a voting condition?), rfSrcId = %u, rfDstId = %u, netSrcId = %u, netDstId = %u", srcId, dstId,
+ m_netLC.getSrcId(), m_p25->m_netLastDstId);
resetRF();
return false;
}
else {
- LogWarning(LOG_RF, "Traffic collision detect, preempting existing network traffic to new RF traffic, rfDstId = %u, netDstId = %u", m_rfLC.getDstId(),
+ LogWarning(LOG_RF, "Traffic collision detect, preempting existing network traffic to new RF traffic, rfDstId = %u, netDstId = %u", dstId,
m_p25->m_netLastDstId);
resetNet();
-/*
- m_p25->writeRF_TDU(true);
-*/
}
}
- m_p25->m_trunk->setRFLC(m_rfLC);
+ m_p25->m_trunk->m_rfTSBK = lc::TSBK(&lc);
+ m_p25->m_trunk->m_rfTSBK.setVerbose(m_p25->m_trunk->m_dumpTSBK);
// validate the source RID
if (!acl::AccessControl::validateSrcId(srcId)) {
if (m_lastRejectId == 0U || m_lastRejectId != srcId) {
LogWarning(LOG_RF, P25_HDU_STR " denial, RID rejection, srcId = %u", srcId);
if (m_p25->m_control) {
- m_p25->m_trunk->writeRF_TSDU_Deny(P25_DENY_RSN_REQ_UNIT_NOT_VALID, (m_rfLC.getGroup() ? TSBK_IOSP_GRP_VCH : TSBK_IOSP_UU_VCH));
+ m_p25->m_trunk->writeRF_TSDU_Deny(P25_DENY_RSN_REQ_UNIT_NOT_VALID, (group ? TSBK_IOSP_GRP_VCH : TSBK_IOSP_UU_VCH));
m_p25->m_trunk->denialInhibit(srcId);
}
- ::ActivityLog("P25", true, "RF voice rejection from %u to %s%u ", srcId, m_rfLC.getGroup() ? "TG " : "", dstId);
+ ::ActivityLog("P25", true, "RF voice rejection from %u to %s%u ", srcId, group ? "TG " : "", dstId);
m_lastRejectId = srcId;
}
@@ -257,7 +255,7 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
}
// is this a group or individual operation?
- if (!m_rfLC.getGroup()) {
+ if (!group) {
// validate the target RID
if (!acl::AccessControl::validateSrcId(dstId)) {
if (m_lastRejectId == 0 || m_lastRejectId != dstId) {
@@ -266,7 +264,7 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
m_p25->m_trunk->writeRF_TSDU_Deny(P25_DENY_RSN_TGT_UNIT_NOT_VALID, TSBK_IOSP_UU_VCH);
}
- ::ActivityLog("P25", true, "RF voice rejection from %u to %s%u ", srcId, m_rfLC.getGroup() ? "TG " : "", dstId);
+ ::ActivityLog("P25", true, "RF voice rejection from %u to %s%u ", srcId, group ? "TG " : "", dstId);
m_lastRejectId = dstId;
}
@@ -285,7 +283,7 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
m_p25->m_trunk->writeRF_TSDU_Deny(P25_DENY_RSN_TGT_GROUP_NOT_VALID, TSBK_IOSP_GRP_VCH);
}
- ::ActivityLog("P25", true, "RF voice rejection from %u to %s%u ", srcId, m_rfLC.getGroup() ? "TG " : "", dstId);
+ ::ActivityLog("P25", true, "RF voice rejection from %u to %s%u ", srcId, group ? "TG " : "", dstId);
m_lastRejectId = dstId;
}
@@ -298,15 +296,14 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
// verify the source RID is affiliated to the group TGID; only if control data
// is supported
- if (m_rfLC.getGroup() && m_p25->m_control) {
- if (!m_p25->m_trunk->hasSrcIdGrpAff(srcId, dstId) &&
- m_p25->m_trunk->m_verifyAff) {
+ if (group && m_p25->m_control) {
+ if (!m_p25->m_trunk->hasSrcIdGrpAff(srcId, dstId) && m_p25->m_trunk->m_verifyAff) {
if (m_lastRejectId == 0 || m_lastRejectId != srcId) {
LogWarning(LOG_RF, P25_HDU_STR " denial, RID not affiliated to TGID, srcId = %u, dstId = %u", srcId, dstId);
m_p25->m_trunk->writeRF_TSDU_Deny(P25_DENY_RSN_REQ_UNIT_NOT_AUTH, TSBK_IOSP_GRP_VCH);
m_p25->m_trunk->writeRF_TSDU_U_Reg_Cmd(srcId);
- ::ActivityLog("P25", true, "RF voice rejection from %u to %s%u ", srcId, m_rfLC.getGroup() ? "TG " : "", dstId);
+ ::ActivityLog("P25", true, "RF voice rejection from %u to %s%u ", srcId, group ? "TG " : "", dstId);
m_lastRejectId = srcId;
}
@@ -317,11 +314,14 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
}
}
+ m_rfLC = lc;
+ m_rfLastLDU1 = m_rfLC;
+
m_lastRejectId = 0U;
- ::ActivityLog("P25", true, "RF %svoice transmission from %u to %s%u", m_rfLC.getEncrypted() ? "encrypted ": "", srcId, m_rfLC.getGroup() ? "TG " : "", dstId);
+ ::ActivityLog("P25", true, "RF %svoice transmission from %u to %s%u", encrypted ? "encrypted ": "", srcId, group ? "TG " : "", dstId);
if (m_p25->m_control) {
- if (m_rfLC.getGroup() && (m_lastPatchGroup != dstId) &&
+ if (group && (m_lastPatchGroup != dstId) &&
(dstId != m_p25->m_trunk->m_patchSuperGroup)) {
m_p25->m_trunk->writeRF_TSDU_Mot_Patch(dstId, 0U, 0U);
m_lastPatchGroup = dstId;
@@ -331,7 +331,7 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
if (!m_p25->m_trunk->hasDstIdGranted(dstId)) {
if (m_p25->m_legacyGroupGrnt) {
// are we auto-registering legacy radios to groups?
- if (m_p25->m_legacyGroupReg && m_rfLC.getGroup()) {
+ if (m_p25->m_legacyGroupReg && group) {
if (!m_p25->m_trunk->hasSrcIdGrpAff(srcId, dstId)) {
if (!m_p25->m_trunk->writeRF_TSDU_Grp_Aff_Rsp(srcId, dstId)) {
return false;
@@ -339,7 +339,7 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
}
}
- if (!m_p25->m_trunk->writeRF_TSDU_Grant(m_rfLC.getGroup(), false, false)) {
+ if (!m_p25->m_trunk->writeRF_TSDU_Grant(group, false, false)) {
return false;
}
}
@@ -352,22 +352,9 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
// single-channel trunking or voice on control support?
if (m_p25->m_control && m_p25->m_voiceOnControl) {
m_p25->m_ccRunning = false; // otherwise the grant will be bundled with other packets
- m_p25->m_trunk->writeRF_TSDU_Grant(m_rfLC.getGroup(), true, false);
- }
-
- if (m_rfLC.getDstId() != m_rfLastHDU.getDstId()) {
- m_rfLC.setDstId(m_rfLastHDU.getDstId());
+ m_p25->m_trunk->writeRF_TSDU_Grant(group, true, false);
}
- m_rfLC.setAlgId(m_rfLastHDU.getAlgId());
- m_rfLC.setKId(m_rfLastHDU.getKId());
-
- uint8_t mi[P25_MI_LENGTH_BYTES];
- m_rfLastHDU.getMI(mi);
- m_rfLC.setMI(mi);
-
- m_rfLastHDU.reset();
-
m_hadVoice = true;
m_p25->m_rfState = RS_RF_AUDIO;
@@ -375,20 +362,50 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
m_p25->m_rfTGHang.start();
m_p25->m_rfLastDstId = dstId;
- uint8_t buffer[P25_HDU_FRAME_LENGTH_BYTES + 2U];
- ::memset(buffer, 0x00U, P25_HDU_FRAME_LENGTH_BYTES + 2U);
+ // make sure we actually got a HDU -- otherwise treat the call as a late entry
+ if (m_rfLastHDU.getDstId() != 0U) {
+ // copy destination and encryption parameters from the last HDU received (if possible)
+ if (m_rfLC.getDstId() != m_rfLastHDU.getDstId()) {
+ m_rfLC.setDstId(m_rfLastHDU.getDstId());
+ }
- // Generate Sync
- Sync::addP25Sync(buffer + 2U);
+ m_rfLC.setAlgId(m_rfLastHDU.getAlgId());
+ m_rfLC.setKId(m_rfLastHDU.getKId());
- // Generate NID
- m_p25->m_nid.encode(buffer + 2U, P25_DUID_HDU);
+ uint8_t mi[P25_MI_LENGTH_BYTES];
+ m_rfLastHDU.getMI(mi);
+ m_rfLC.setMI(mi);
- // Generate HDU
- m_rfLC.encodeHDU(buffer + 2U);
+ uint8_t buffer[P25_HDU_FRAME_LENGTH_BYTES + 2U];
+ ::memset(buffer, 0x00U, P25_HDU_FRAME_LENGTH_BYTES + 2U);
- // Add busy bits
- m_p25->addBusyBits(buffer + 2U, P25_HDU_FRAME_LENGTH_BITS, false, true);
+ // Generate Sync
+ Sync::addP25Sync(buffer + 2U);
+
+ // Generate NID
+ m_p25->m_nid.encode(buffer + 2U, P25_DUID_HDU);
+
+ // Generate HDU
+ m_rfLC.encodeHDU(buffer + 2U);
+
+ // Add busy bits
+ m_p25->addBusyBits(buffer + 2U, P25_HDU_FRAME_LENGTH_BITS, false, true);
+
+ writeNetworkRF(buffer, P25_DUID_HDU);
+
+ if (m_p25->m_duplex) {
+ buffer[0U] = TAG_DATA;
+ buffer[1U] = 0x00U;
+ m_p25->writeQueueRF(buffer, P25_HDU_FRAME_LENGTH_BYTES + 2U);
+ }
+
+ if (m_verbose) {
+ LogMessage(LOG_RF, P25_HDU_STR ", dstId = %u, algo = $%02X, kid = $%04X", m_rfLC.getDstId(), m_rfLC.getAlgId(), m_rfLC.getKId());
+ }
+ }
+ else {
+ LogWarning(LOG_RF, P25_HDU_STR ", not transmitted; possible late entry, dstId = %u, algo = $%02X, kid = $%04X", m_rfLastHDU.getDstId(), m_rfLastHDU.getAlgId(), m_rfLastHDU.getKId());
+ }
m_rfFrames = 0U;
m_rfErrs = 0U;
@@ -398,17 +415,7 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
m_p25->m_rfTimeout.start();
m_lastDUID = P25_DUID_HDU;
- writeNetworkRF(buffer, P25_DUID_HDU);
-
- if (m_p25->m_duplex) {
- buffer[0U] = TAG_DATA;
- buffer[1U] = 0x00U;
- m_p25->writeQueueRF(buffer, P25_HDU_FRAME_LENGTH_BYTES + 2U);
- }
-
- if (m_verbose) {
- LogMessage(LOG_RF, P25_HDU_STR ", dstId = %u, algo = $%02X, kid = $%04X", m_rfLC.getDstId(), m_rfLC.getAlgId(), m_rfLC.getKId());
- }
+ m_rfLastHDU = lc::LC(m_p25->m_siteData);
}
if (m_p25->m_rfState == RS_RF_AUDIO) {
@@ -526,8 +533,6 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
}
}
else if (duid == P25_DUID_LDU2) {
- m_p25->m_trunk->resetStatusCommand();
-
m_lastDUID = P25_DUID_LDU2;
if (m_p25->m_rfState == RS_RF_LISTENING) {
@@ -606,8 +611,6 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
}
}
else if (duid == P25_DUID_TDU || duid == P25_DUID_TDULC) {
- m_p25->m_trunk->resetStatusCommand();
-
if (m_p25->m_control) {
m_p25->m_trunk->releaseDstIdGrant(m_rfLC.getDstId(), false);
}
@@ -619,8 +622,16 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
m_p25->m_rfTimeout.stop();
}
- else
- m_p25->m_trunk->writeRF_TDULC(duid, false);
+ else {
+ lc::TDULC tdulc = lc::TDULC(m_p25->m_siteData, m_p25->m_idenEntry, m_p25->m_trunk->m_dumpTSBK);
+ bool ret = tdulc.decode(data + 2U);
+ if (!ret) {
+ LogWarning(LOG_RF, P25_LDU2_STR ", undecodable TDULC");
+ }
+ else {
+ m_p25->m_trunk->writeRF_TDULC(tdulc, false);
+ }
+ }
if (m_p25->m_rfState == RS_RF_AUDIO) {
if (m_p25->m_rssi != 0U) {
@@ -712,8 +723,6 @@ bool VoicePacket::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, d
::memcpy(m_netLDU1 + 200U, data + count, 16U);
count += 16U;
- m_p25->m_trunk->resetStatusCommand();
-
m_netLastLDU1 = control;
checkNet_LDU2(control, lsd);
@@ -765,21 +774,15 @@ bool VoicePacket::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, d
::memcpy(m_netLDU2 + 200U, data + count, 16U);
count += 16U;
- m_p25->m_trunk->resetStatusCommand();
-
if (m_p25->m_netState == RS_NET_IDLE) {
m_p25->m_modem->clearP25Data();
m_p25->m_queue.clear();
resetRF();
- m_rfLastHDU.reset();
-
- m_netLC.reset();
- m_netFrames = 0U;
- m_netLost = 0U;
+ resetNet();
- m_p25->m_trunk->resetRF();
- m_p25->m_trunk->resetNet();
+ 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);
}
@@ -805,12 +808,10 @@ bool VoicePacket::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, d
}
if (m_p25->m_netState != RS_NET_IDLE) {
- m_p25->m_trunk->resetStatusCommand();
-
if (duid == P25_DUID_TDU)
writeNet_TDU();
- else
- m_p25->m_trunk->writeNet_TDULC();
+
+ resetNet();
}
break;
}
@@ -869,12 +870,12 @@ VoicePacket::VoicePacket(Control* p25, network::BaseNetwork* network, bool debug
m_netFrames(0U),
m_netLost(0U),
m_audio(),
- m_rfLC(),
- m_rfLastHDU(),
- m_rfLastLDU1(),
- m_rfLastLDU2(),
- m_netLC(),
- m_netLastLDU1(),
+ m_rfLC(SiteData()),
+ m_rfLastHDU(SiteData()),
+ m_rfLastLDU1(SiteData()),
+ m_rfLastLDU2(SiteData()),
+ m_netLC(SiteData()),
+ m_netLastLDU1(SiteData()),
m_rfLSD(),
m_netLSD(),
m_netLDU1(NULL),
@@ -959,17 +960,10 @@ void VoicePacket::writeRF_EndOfVoice()
uint32_t dstId = m_rfLC.getDstId();
resetRF();
- m_rfLastHDU.reset();
-
resetNet();
// transmit channelNo release burst
m_p25->m_trunk->writeRF_TDULC_ChanRelease(grp, srcId, dstId);
-/*
- if (grp && (m_lastPatchGroup != 0U)) {
- m_p25->m_trunk->writeRF_TSDU_Mot_Patch(m_p25->m_trunk->m_patchSuperGroup, 0U, 0U);
- }
-*/
}
///
@@ -1018,8 +1012,7 @@ void VoicePacket::writeNet_TDU()
m_p25->m_netTimeout.stop();
m_p25->m_networkWatchdog.stop();
- m_netLC.reset();
- m_netLastLDU1.reset();
+ resetNet();
m_p25->m_netState = RS_NET_IDLE;
m_p25->m_netLastDstId = 0U;
m_p25->m_tailOnIdle = true;
@@ -1112,7 +1105,7 @@ void VoicePacket::writeNet_LDU1(const lc::LC& control, const data::LowSpeedData&
m_p25->m_trunk->touchDstIdGrant(m_rfLC.getDstId());
}
- m_netLC.reset();
+ m_netLC = lc::LC(m_p25->m_siteData);
m_netLC.setLCO(lco);
m_netLC.setMFId(mfId);
m_netLC.setSrcId(srcId);
@@ -1122,7 +1115,7 @@ void VoicePacket::writeNet_LDU1(const lc::LC& control, const data::LowSpeedData&
m_netLC.setEncrypted((serviceOptions & 0x40U) == 0x40U);
m_netLC.setPriority((serviceOptions & 0x07U));
- m_rfLC.reset();
+ m_rfLC = lc::LC(m_p25->m_siteData);
m_rfLC.setMFId(mfId);
m_rfLC.setSrcId(srcId);
m_rfLC.setDstId(dstId);
@@ -1152,8 +1145,10 @@ void VoicePacket::writeNet_LDU1(const lc::LC& control, const data::LowSpeedData&
m_netLC.setKId(kId);
m_rfLC.setKId(kId);
- m_p25->m_trunk->setNetLC(m_netLC);
- m_p25->m_trunk->setRFLC(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_netTSBK = lc::TSBK(&m_netLC);
+ m_p25->m_trunk->m_netTSBK.setVerbose(m_p25->m_trunk->m_dumpTSBK);
// validate source RID
if (!acl::AccessControl::validateSrcId(srcId)) {
@@ -1197,8 +1192,10 @@ void VoicePacket::writeNet_LDU1(const lc::LC& control, const data::LowSpeedData&
m_p25->m_netTimeout.stop();
m_p25->m_networkWatchdog.stop();
- m_netLC.reset();
- m_netLastLDU1.reset();
+
+ m_netLC = lc::LC(m_p25->m_siteData);
+ m_netLastLDU1 = lc::LC(m_p25->m_siteData);
+
m_p25->m_netState = RS_NET_IDLE;
m_p25->m_netLastDstId = 0U;
if (m_p25->m_rfState == RS_RF_REJECTED) {
@@ -1248,7 +1245,7 @@ void VoicePacket::writeNet_LDU1(const lc::LC& control, const data::LowSpeedData&
}
else {
if (m_verbose) {
- LogMessage(LOG_NET, P25_HDU_STR ", network does not transmit, dstId = %u, algo = $%02X, kid = $%04X", m_netLC.getDstId(), m_netLC.getAlgId(), m_netLC.getKId());
+ LogMessage(LOG_NET, P25_HDU_STR ", not transmitted; network HDU disabled, dstId = %u, algo = $%02X, kid = $%04X", m_netLC.getDstId(), m_netLC.getAlgId(), m_netLC.getKId());
}
}
}
diff --git a/p25/lc/LC.cpp b/p25/lc/LC.cpp
index 74ae8ddb..d5795cd6 100644
--- a/p25/lc/LC.cpp
+++ b/p25/lc/LC.cpp
@@ -51,29 +51,39 @@ using namespace p25;
///
/// Initializes a new instance of the LC class.
///
+///
LC::LC() :
m_protect(false),
m_lco(LC_GROUP),
m_mfId(P25_MFG_STANDARD),
m_srcId(0U),
m_dstId(0U),
- m_serviceClass(P25_SVC_CLS_VOICE | P25_SVC_CLS_DATA),
+ m_grpVchNo(0U),
m_emergency(false),
m_encrypted(false),
m_priority(4U),
m_group(true),
m_algId(P25_ALGO_UNENCRYPT),
m_kId(0U),
+ m_siteData(SiteData()),
m_rs(),
m_encryptOverride(false),
m_tsbkVendorSkip(false),
m_callTimer(0U),
- m_mi(NULL),
- m_siteData()
+ m_mi(NULL)
{
m_mi = new uint8_t[P25_MI_LENGTH_BYTES];
+ ::memset(m_mi, 0x00U, P25_MI_LENGTH_BYTES);
+}
- reset();
+///
+/// Initializes a new instance of the LC class.
+///
+///
+LC::LC(SiteData siteData) : LC()
+{
+ m_siteData = siteData;
+ m_grpVchNo = m_siteData.channelNo();
}
///
@@ -98,8 +108,6 @@ LC& LC::operator=(const LC& data)
m_srcId = data.m_srcId;
m_dstId = data.m_dstId;
- m_serviceClass = data.m_serviceClass;
-
m_grpVchNo = data.m_grpVchNo;
m_emergency = data.m_emergency;
@@ -130,6 +138,8 @@ LC& LC::operator=(const LC& data)
m_encrypted = false;
}
}
+
+ m_siteData = data.m_siteData;
}
return *this;
@@ -457,46 +467,6 @@ void LC::encodeLDU2(uint8_t * data)
// Utils::dump(2U, "LDU2 Interleave", data, P25_LDU_FRAME_LENGTH_BYTES + P25_PREAMBLE_LENGTH_BYTES);
}
-///
-/// Helper to reset data values to defaults.
-///
-void LC::reset()
-{
- m_encryptOverride = false;
- m_tsbkVendorSkip = false;
-
- m_protect = false;
- m_lco = LC_GROUP;
- m_mfId = P25_MFG_STANDARD;
-
- m_srcId = 0U;
- m_dstId = 0U;
-
- m_callTimer = 0U;
-
- m_grpVchNo = m_siteData.channelNo();
-
- /* Service Options */
- m_emergency = false;
- m_encrypted = false;
- m_priority = 4U;
- m_group = true;
-
- /* HDU/LDU2 data */
- m_algId = P25_ALGO_UNENCRYPT;
- m_kId = 0x0000U;
-
- ::memset(m_mi, 0x00U, P25_MI_LENGTH_BYTES);
-}
-
-/** Local Site data */
-/// Sets local configured site data.
-///
-void LC::setSiteData(SiteData siteData)
-{
- m_siteData = siteData;
-}
-
/** Encryption data */
/// Sets the encryption message indicator.
///
@@ -644,7 +614,7 @@ void LC::encodeLC(uint8_t * rs)
rsValue = (rsValue << 8) + m_siteData.siteId(); // Site ID
rsValue = (rsValue << 4) + m_siteData.channelId(); // Channel ID
rsValue = (rsValue << 12) + m_siteData.channelNo(); // Channel Number
- rsValue = (rsValue << 8) + m_serviceClass; // System Service Class
+ rsValue = (rsValue << 8) + m_siteData.serviceClass(); // System Service Class
break;
default:
LogError(LOG_P25, "unknown LC value, mfId = $%02X, lco = $%02X", m_mfId, m_lco);
diff --git a/p25/lc/LC.h b/p25/lc/LC.h
index 7be2078f..e6c50d60 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 new instance of the LC class.
+ LC(SiteData siteData);
/// Finalizes a instance of the LC class.
~LC();
@@ -80,13 +82,6 @@ namespace p25
/// Encode a logical link data unit 2.
void encodeLDU2(uint8_t* data);
- /// Helper to reset data values to defaults.
- void reset();
-
- /** Local Site data */
- /// Sets local configured site data.
- void setSiteData(SiteData siteData);
-
/** Encryption data */
/// Sets the encryption message indicator.
void setMI(const uint8_t* mi);
@@ -107,9 +102,6 @@ namespace p25
/// Destination ID.
__PROPERTY(uint32_t, dstId, DstId);
- /// Service class.
- __PROPERTY(uint8_t, serviceClass, ServiceClass);
-
/// Voice channel number.
__PROPERTY(uint32_t, grpVchNo, GrpVchNo);
@@ -129,6 +121,10 @@ namespace p25
/// Encryption key ID.
__PROPERTY(uint32_t, kId, KId);
+ /** Local Site data */
+ /// Local Site Data.
+ __PROPERTY_PLAIN(SiteData, siteData, siteData);
+
private:
friend class TSBK;
friend class TDULC;
@@ -141,9 +137,6 @@ namespace p25
/** Encryption data */
uint8_t* m_mi;
- /** Local Site data */
- SiteData m_siteData;
-
/// 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 dd1a80de..ab236e47 100644
--- a/p25/lc/TDULC.cpp
+++ b/p25/lc/TDULC.cpp
@@ -49,26 +49,49 @@ using namespace p25;
///
/// Initializes a new instance of the TDULC class.
///
-TDULC::TDULC() :
- m_verbose(false),
- m_protect(false),
- m_lco(LC_GROUP),
- m_mfId(P25_MFG_STANDARD),
- m_srcId(0U),
- m_dstId(0U),
- m_serviceClass(P25_SVC_CLS_VOICE | P25_SVC_CLS_DATA),
- m_emergency(false),
- m_encrypted(false),
- m_priority(4U),
- m_group(true),
- m_rs(),
- m_callTimer(0U),
- m_siteData(),
- m_siteNetActive(false)
+///
+///
+TDULC::TDULC(SiteData siteData, lookups::IdenTable entry) : TDULC(siteData)
{
- m_siteIdenEntry = lookups::IdenTable();
+ m_siteIdenEntry = entry;
+ m_grpVchNo = m_siteData.channelNo();
+}
- reset();
+///
+/// Initializes a new instance of the TDULC class.
+///
+///
+///
+///
+TDULC::TDULC(SiteData siteData, lookups::IdenTable entry, bool verbose) : TDULC(siteData)
+{
+ m_verbose = verbose;
+ m_siteIdenEntry = entry;
+ m_grpVchNo = m_siteData.channelNo();
+}
+
+///
+/// Initializes a new instance of the TDULC class.
+///
+///
+TDULC::TDULC(LC* lc) : TDULC(lc->siteData())
+{
+ m_protect = lc->m_protect;
+ m_lco = lc->m_lco;
+ m_mfId = lc->m_mfId;
+
+ m_srcId = lc->m_srcId;
+ m_dstId = lc->m_dstId;
+
+ m_grpVchNo = lc->m_grpVchNo;
+
+ m_emergency = lc->m_emergency;
+ m_encrypted = lc->m_encrypted;
+ m_priority = lc->m_priority;
+
+ m_group = lc->m_group;
+
+ m_callTimer = lc->m_callTimer;
}
///
@@ -79,6 +102,46 @@ TDULC::~TDULC()
/* stub */
}
+///
+/// Equals operator.
+///
+///
+///
+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;
+ }
+
+ return *this;
+}
+
///
/// Decode a terminator data unit w/ link control.
///
@@ -151,66 +214,39 @@ void TDULC::encode(uint8_t * data)
// Utils::dump(2U, "TDULC Interleave", data, P25_TDULC_FRAME_LENGTH_BYTES + P25_PREAMBLE_LENGTH_BYTES);
}
+// ---------------------------------------------------------------------------
+// Private Class Members
+// ---------------------------------------------------------------------------
///
-/// Helper to reset data values to defaults.
+/// Initializes a new instance of the TDULC class.
///
-void TDULC::reset()
+///
+TDULC::TDULC(SiteData siteData) :
+ m_verbose(false),
+ m_protect(false),
+ m_lco(LC_GROUP),
+ m_mfId(P25_MFG_STANDARD),
+ m_srcId(0U),
+ m_dstId(0U),
+ m_grpVchNo(0U),
+ m_adjCFVA(P25_CFVA_FAILURE),
+ m_adjRfssId(0U),
+ m_adjSiteId(0U),
+ m_adjChannelId(0U),
+ m_adjChannelNo(0U),
+ m_adjServiceClass(P25_SVC_CLS_INVALID),
+ m_emergency(false),
+ m_encrypted(false),
+ m_priority(4U),
+ m_group(true),
+ m_siteData(siteData),
+ m_siteIdenEntry(),
+ m_rs(),
+ m_callTimer(0U)
{
- m_protect = false;
- m_lco = LC_GROUP;
- m_mfId = P25_MFG_STANDARD;
-
- m_srcId = 0U;
- m_dstId = 0U;
-
- m_callTimer = 0U;
-
m_grpVchNo = m_siteData.channelNo();
-
- m_adjCFVA = P25_CFVA_CONV | P25_CFVA_FAILURE;
- m_adjRfssId = 0U;
- m_adjSiteId = 0U;
- m_adjChannelId = 0U;
- m_adjChannelNo = 0U;
-
- /* Service Options */
- m_emergency = false;
- m_encrypted = false;
- m_priority = 4U;
- m_group = true;
}
-/** Local Site data */
-///
-/// Sets local configured site data.
-///
-/// Site data.
-void TDULC::setSiteData(SiteData siteData)
-{
- m_siteData = siteData;
-}
-
-///
-/// Sets the identity lookup table entry.
-///
-/// Identity table entry.
-void TDULC::setIdenTable(lookups::IdenTable entry)
-{
- m_siteIdenEntry = entry;
-}
-
-///
-/// Sets a flag indicating whether or not networking is active.
-///
-/// Network active flag.
-void TDULC::setNetActive(bool netActive)
-{
- m_siteNetActive = netActive;
-}
-
-// ---------------------------------------------------------------------------
-// Private Class Members
-// ---------------------------------------------------------------------------
///
/// Decode link control.
///
@@ -281,7 +317,7 @@ bool TDULC::decodeLC(const uint8_t* rs)
///
void TDULC::encodeLC(uint8_t* rs)
{
- const uint32_t services = (m_siteNetActive) ? P25_SYS_SRV_NET_ACTIVE : 0U | P25_SYS_SRV_DEFAULT;
+ const uint32_t services = (m_siteData.netActive()) ? P25_SYS_SRV_NET_ACTIVE : 0U | P25_SYS_SRV_DEFAULT;
ulong64_t rsValue = 0U;
rs[0U] = m_lco; // LCO
@@ -376,7 +412,7 @@ void TDULC::encodeLC(uint8_t* rs)
rsValue = (rsValue << 8) + m_adjSiteId; // Site ID
rsValue = (rsValue << 4) + m_adjChannelId; // Channel ID
rsValue = (rsValue << 12) + m_adjChannelNo; // Channel Number
- rsValue = (rsValue << 8) + m_serviceClass; // System Service Class
+ rsValue = (rsValue << 8) + m_adjServiceClass; // System Service Class
}
else {
LogError(LOG_P25, "invalid values for LC_ADJ_STS_BCAST, tsbkAdjSiteRFSSId = $%02X, tsbkAdjSiteId = $%02X, tsbkAdjSiteChannel = $%02X",
@@ -393,7 +429,7 @@ void TDULC::encodeLC(uint8_t* rs)
rsValue = (rsValue << 8) + m_siteData.siteId(); // Site ID
rsValue = (rsValue << 4) + m_siteData.channelId(); // Channel ID
rsValue = (rsValue << 12) + m_siteData.channelNo(); // Channel Number
- rsValue = (rsValue << 8) + m_serviceClass; // System Service Class
+ rsValue = (rsValue << 8) + m_siteData.serviceClass(); // System Service Class
break;
case LC_NET_STS_BCAST:
rs[0U] |= 0x40U; // Implicit Operation
@@ -402,7 +438,7 @@ void TDULC::encodeLC(uint8_t* rs)
rsValue = (rsValue << 12) + m_siteData.sysId(); // System ID
rsValue = (rsValue << 4) + m_siteData.channelId(); // Channel ID
rsValue = (rsValue << 12) + m_siteData.channelNo(); // Channel Number
- rsValue = (rsValue << 8) + m_serviceClass; // System Service Class
+ rsValue = (rsValue << 8) + m_siteData.serviceClass(); // System Service Class
break;
default:
LogError(LOG_P25, "unknown LC value, mfId = $%02X, lco = $%02X", m_mfId, m_lco);
diff --git a/p25/lc/TDULC.h b/p25/lc/TDULC.h
index 04dcaffa..ada8e94c 100644
--- a/p25/lc/TDULC.h
+++ b/p25/lc/TDULC.h
@@ -59,26 +59,22 @@ namespace p25
class HOST_SW_API TDULC {
public:
/// Initializes a new instance of the TDULC class.
- TDULC();
+ TDULC(SiteData siteData, lookups::IdenTable entry);
+ /// Initializes a new instance of the TDULC class.
+ TDULC(SiteData siteData, lookups::IdenTable entry, bool verbose);
+ /// Initializes a new instance of the TDULC class.
+ TDULC(LC* lc);
/// Finalizes a instance of the TDULC class.
~TDULC();
+ /// Equals operator.
+ TDULC& operator=(const TDULC& data);
+
/// Decode a trunking signalling block.
bool decode(const uint8_t* data);
/// Encode a trunking signalling block.
void encode(uint8_t* data);
- /// Helper to reset data values to defaults.
- void reset();
-
- /** Local Site data */
- /// Sets local configured site data.
- void setSiteData(SiteData siteData);
- /// Sets the identity lookup table entry.
- void setIdenTable(lookups::IdenTable entry);
- /// Sets a flag indicating whether or not networking is active.
- void setNetActive(bool netActive);
-
public:
/// Flag indicating verbose log output.
__PROPERTY(bool, verbose, Verbose);
@@ -96,9 +92,6 @@ namespace p25
/// Destination ID.
__PROPERTY(uint32_t, dstId, DstId);
- /// Service class.
- __PROPERTY(uint8_t, serviceClass, ServiceClass);
-
/// Voice channel number.
__PROPERTY(uint32_t, grpVchNo, GrpVchNo);
@@ -115,6 +108,8 @@ namespace p25
__PROPERTY(uint8_t, adjChannelId, AdjSiteChnId);
/// Adjacent site channel number.
__PROPERTY(uint32_t, adjChannelNo, AdjSiteChnNo);
+ /// Adjacent site service class.
+ __PROPERTY(uint8_t, adjServiceClass, AdjSiteSvcClass);
/** Service Options */
/// Flag indicating the emergency bits are set.
@@ -126,18 +121,22 @@ namespace p25
/// Flag indicating a group/talkgroup operation.
__PROPERTY(bool, group, Group);
+ /** Local Site data */
+ /// Local Site Data.
+ __PROPERTY_PLAIN(SiteData, siteData, siteData);
+ /// Local Site Identity Entry.
+ __PROPERTY_PLAIN(lookups::IdenTable, siteIdenEntry, siteIdenEntry);
+
private:
+ /// Initializes a new instance of the TDULC class.
+ TDULC(SiteData siteData);
+
friend class LC;
friend class TSBK;
edac::RS634717 m_rs;
uint32_t m_callTimer;
- /** Local Site data */
- SiteData m_siteData;
- lookups::IdenTable m_siteIdenEntry;
- bool m_siteNetActive;
-
/// 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 97f1ef95..3c8b92ab 100644
--- a/p25/lc/TSBK.cpp
+++ b/p25/lc/TSBK.cpp
@@ -48,46 +48,45 @@ using namespace p25;
///
/// Initializes a new instance of the TSBK class.
///
-TSBK::TSBK() :
- m_verbose(false),
- m_protect(false),
- m_lco(LC_GROUP),
- m_mfId(P25_MFG_STANDARD),
- m_srcId(0U),
- m_dstId(0U),
- m_lastBlock(false),
- m_aivFlag(true),
- m_extendedAddrFlag(false),
- m_serviceClass(P25_SVC_CLS_VOICE | P25_SVC_CLS_DATA),
- m_emergency(false),
- m_encrypted(false),
- m_priority(4U),
- m_group(true),
- m_rs(),
- m_trellis(),
- m_vendorSkip(false),
- m_sndcpAutoAccess(true),
- m_sndcpReqAccess(false),
- m_sndcpDAC(1U),
- m_siteData(),
- m_siteNetActive(false),
- m_siteChCnt(1U)
+///
+///
+TSBK::TSBK(SiteData siteData, lookups::IdenTable entry) : TSBK(siteData)
{
- m_siteCallsign = new uint8_t[P25_MOT_CALLSIGN_LENGTH_BYTES];
- ::memset(m_siteCallsign, 0x00U, P25_MOT_CALLSIGN_LENGTH_BYTES);
+ m_siteIdenEntry = entry;
+}
+
+///
+/// Initializes a new instance of the TSBK class.
+///
+///
+///
+///
+TSBK::TSBK(SiteData siteData, lookups::IdenTable entry, bool verbose) : TSBK(siteData)
+{
+ m_verbose = verbose;
+ m_siteIdenEntry = entry;
+}
+
+///
+/// Initializes a new instance of the TSBK class.
+///
+///
+TSBK::TSBK(LC* lc) : TSBK(lc->siteData())
+{
+ m_protect = lc->m_protect;
+ m_lco = lc->m_lco;
+ m_mfId = lc->m_mfId;
- m_siteCallsign[0] = 'C';
- m_siteCallsign[1] = 'H';
- m_siteCallsign[2] = 'A';
- m_siteCallsign[3] = 'N';
- m_siteCallsign[4] = 'G';
- m_siteCallsign[5] = 'E';
- m_siteCallsign[6] = 'M';
- m_siteCallsign[7] = 'E';
+ m_srcId = lc->m_srcId;
+ m_dstId = lc->m_dstId;
- m_siteIdenEntry = lookups::IdenTable();
+ m_grpVchNo = lc->m_grpVchNo;
- reset();
+ m_emergency = lc->m_emergency;
+ m_encrypted = lc->m_encrypted;
+ m_priority = lc->m_priority;
+
+ m_group = lc->m_group;
}
///
@@ -98,6 +97,73 @@ TSBK::~TSBK()
delete[] m_siteCallsign;
}
+///
+/// Equals operator.
+///
+///
+///
+TSBK& TSBK::operator=(const TSBK& 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_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;
+
+ m_siteCallsign = new uint8_t[P25_MOT_CALLSIGN_LENGTH_BYTES];
+ ::memcpy(m_siteCallsign, data.m_siteCallsign, P25_MOT_CALLSIGN_LENGTH_BYTES);
+ }
+
+ return *this;
+}
+
///
/// Decode a trunking signalling block.
///
@@ -302,7 +368,7 @@ void TSBK::encode(uint8_t * data, bool singleBlock)
{
assert(data != NULL);
- const uint32_t services = (m_siteNetActive) ? P25_SYS_SRV_NET_ACTIVE : 0U | P25_SYS_SRV_DEFAULT;
+ const uint32_t services = (m_siteData.netActive()) ? P25_SYS_SRV_NET_ACTIVE : 0U | P25_SYS_SRV_DEFAULT;
uint8_t tsbk[P25_TSBK_LENGTH_BYTES];
::memset(tsbk, 0x00U, P25_TSBK_LENGTH_BYTES);
@@ -446,7 +512,7 @@ void TSBK::encode(uint8_t * data, bool singleBlock)
tsbkValue = (tsbkValue << 12) + m_sccbChannelNo; // Channel (R) Number
if (m_sccbChannelId1 > 0) {
- tsbkValue = (tsbkValue << 8) + m_serviceClass; // System Service Class
+ tsbkValue = (tsbkValue << 8) + m_siteData.serviceClass(); // System Service Class
}
else {
tsbkValue = (tsbkValue << 8) + (P25_SVC_CLS_INVALID); // System Service Class
@@ -512,14 +578,14 @@ void TSBK::encode(uint8_t * data, bool singleBlock)
tsbkValue = (tsbkValue << 8) + m_siteData.siteId(); // Site ID
tsbkValue = (tsbkValue << 16) + m_sccbChannelId1; // SCCB Channel ID 1
if (m_sccbChannelId1 > 0) {
- tsbkValue = (tsbkValue << 8) + m_serviceClass; // System Service Class
+ tsbkValue = (tsbkValue << 8) + m_siteData.serviceClass(); // System Service Class
}
else {
tsbkValue = (tsbkValue << 8) + (P25_SVC_CLS_INVALID); // System Service Class
}
tsbkValue = (tsbkValue << 16) + m_sccbChannelId2; // SCCB Channel ID 2
if (m_sccbChannelId2 > 0) {
- tsbkValue = (tsbkValue << 8) + m_serviceClass; // System Service Class
+ tsbkValue = (tsbkValue << 8) + m_siteData.serviceClass(); // System Service Class
}
else {
tsbkValue = (tsbkValue << 8) + (P25_SVC_CLS_INVALID); // System Service Class
@@ -528,13 +594,13 @@ void TSBK::encode(uint8_t * data, bool singleBlock)
case TSBK_OSP_RFSS_STS_BCAST:
tsbkValue = m_siteData.lra(); // Location Registration Area
tsbkValue = (tsbkValue << 4) +
- (m_siteNetActive) ? P25_CFVA_NETWORK : 0U; // CFVA
+ (m_siteData.netActive()) ? P25_CFVA_NETWORK : 0U; // CFVA
tsbkValue = (tsbkValue << 12) + m_siteData.sysId(); // System ID
tsbkValue = (tsbkValue << 8) + m_siteData.rfssId(); // RF Sub-System ID
tsbkValue = (tsbkValue << 8) + m_siteData.siteId(); // Site ID
tsbkValue = (tsbkValue << 4) + m_siteData.channelId(); // Channel ID
tsbkValue = (tsbkValue << 12) + m_siteData.channelNo(); // Channel Number
- tsbkValue = (tsbkValue << 8) + m_serviceClass; // System Service Class
+ tsbkValue = (tsbkValue << 8) + m_siteData.serviceClass(); // System Service Class
break;
case TSBK_OSP_NET_STS_BCAST:
tsbkValue = m_siteData.lra(); // Location Registration Area
@@ -542,7 +608,7 @@ void TSBK::encode(uint8_t * data, bool singleBlock)
tsbkValue = (tsbkValue << 12) + m_siteData.sysId(); // System ID
tsbkValue = (tsbkValue << 4) + m_siteData.channelId(); // Channel ID
tsbkValue = (tsbkValue << 12) + m_siteData.channelNo(); // Channel Number
- tsbkValue = (tsbkValue << 8) + m_serviceClass; // System Service Class
+ tsbkValue = (tsbkValue << 8) + m_siteData.serviceClass(); // System Service Class
break;
case TSBK_OSP_ADJ_STS_BCAST:
{
@@ -754,57 +820,6 @@ void TSBK::encode(uint8_t * data, bool singleBlock)
}
}
-///
-/// Helper to reset data values to defaults.
-///
-void TSBK::reset()
-{
- m_vendorSkip = false;
-
- m_protect = false;
- m_lco = LC_GROUP;
- m_mfId = P25_MFG_STANDARD;
-
- m_srcId = 0U;
- m_dstId = 0U;
-
- m_lastBlock = true;
- m_aivFlag = true;
- m_extendedAddrFlag = false;
-
- m_service = 0U;
- m_response = P25_RSP_ACCEPT;
-
- m_netId = P25_WACN_STD_DEFAULT;
- m_sysId = P25_SID_STD_DEFAULT;
-
- m_grpVchNo = m_siteData.channelNo();
-
- m_messageValue = 0U;
- m_statusValue = 0U;
-
- m_extendedFunction = P25_EXT_FNCT_CHECK;
-
- m_adjCFVA = P25_CFVA_FAILURE;
- m_adjRfssId = 0U;
- m_adjSiteId = 0U;
- m_adjChannelId = 0U;
- m_adjChannelNo = 0U;
- m_adjServiceClass = P25_SVC_CLS_INVALID;
-
- /* TSBK Patch Group data */
- m_patchSuperGroupId = 0U;
- m_patchGroup1Id = 0U;
- m_patchGroup2Id = 0U;
- m_patchGroup3Id = 0U;
-
- /* Service Options */
- m_emergency = false;
- m_encrypted = false;
- m_priority = 4U;
- m_group = true;
-}
-
///
/// Sets the flag to skip vendor opcode processing.
///
@@ -814,18 +829,8 @@ void TSBK::setVendorSkip(bool skip)
m_vendorSkip = skip;
}
-/** Local Site data */
-///
-/// Sets local configured site data.
-///
-/// Site data.
-void TSBK::setSiteData(SiteData siteData)
-{
- m_siteData = siteData;
-}
-
///
-/// Sets local configured site callsign.
+/// Sets the callsign.
///
/// Callsign.
void TSBK::setCallsign(std::string callsign)
@@ -841,29 +846,60 @@ void TSBK::setCallsign(std::string callsign)
}
}
+// ---------------------------------------------------------------------------
+// Private Class Members
+// ---------------------------------------------------------------------------
///
-/// Sets the identity lookup table entry.
-///
-/// Identity table entry.
-void TSBK::setIdenTable(lookups::IdenTable entry)
-{
- m_siteIdenEntry = entry;
-}
-
-///
-/// Sets a flag indicating whether or not networking is active.
-///
-/// Network active flag.
-void TSBK::setNetActive(bool netActive)
-{
- m_siteNetActive = netActive;
-}
-
-///
-/// Sets the total number of channels at the site.
+/// Initializes a new instance of the TSBK class.
///
-/// Channel count.
-void TSBK::setSiteChCnt(uint8_t chCnt)
+///
+TSBK::TSBK(SiteData siteData) :
+ m_verbose(false),
+ m_protect(false),
+ m_lco(LC_GROUP),
+ m_mfId(P25_MFG_STANDARD),
+ m_srcId(0U),
+ m_dstId(0U),
+ m_lastBlock(false),
+ m_aivFlag(true),
+ m_extendedAddrFlag(false),
+ m_service(0U),
+ m_response(P25_RSP_ACCEPT),
+ m_netId(P25_WACN_STD_DEFAULT),
+ m_sysId(P25_SID_STD_DEFAULT),
+ m_grpVchNo(0U),
+ m_messageValue(0U),
+ m_statusValue(0U),
+ m_extendedFunction(P25_EXT_FNCT_CHECK),
+ m_adjCFVA(P25_CFVA_FAILURE),
+ m_adjRfssId(0U),
+ m_adjSiteId(0U),
+ m_adjChannelId(0U),
+ m_adjChannelNo(0U),
+ m_adjServiceClass(P25_SVC_CLS_INVALID),
+ m_sccbChannelId1(0U),
+ m_sccbChannelId2(0U),
+ m_sccbChannelNo(0U),
+ m_lra(0U),
+ m_patchSuperGroupId(0U),
+ m_patchGroup1Id(0U),
+ m_patchGroup2Id(0U),
+ m_patchGroup3Id(0U),
+ m_emergency(false),
+ m_encrypted(false),
+ m_priority(4U),
+ m_group(true),
+ m_siteData(siteData),
+ m_siteIdenEntry(),
+ m_rs(),
+ m_trellis(),
+ m_vendorSkip(false),
+ m_sndcpAutoAccess(true),
+ m_sndcpReqAccess(false),
+ m_sndcpDAC(1U),
+ m_siteCallsign(NULL)
{
- m_siteChCnt = chCnt;
+ m_siteCallsign = new uint8_t[P25_MOT_CALLSIGN_LENGTH_BYTES];
+ ::memset(m_siteCallsign, 0x00U, P25_MOT_CALLSIGN_LENGTH_BYTES);
+ setCallsign(siteData.callsign());
}
diff --git a/p25/lc/TSBK.h b/p25/lc/TSBK.h
index 785efd27..68d95fdc 100644
--- a/p25/lc/TSBK.h
+++ b/p25/lc/TSBK.h
@@ -59,32 +59,27 @@ namespace p25
class HOST_SW_API TSBK {
public:
/// Initializes a new instance of the TSBK class.
- TSBK();
+ TSBK(SiteData siteData, lookups::IdenTable entry);
+ /// Initializes a new instance of the TSBK class.
+ TSBK(SiteData siteData, lookups::IdenTable entry, bool verbose);
+ /// Initializes a new instance of the TSBK class.
+ TSBK(LC* lc);
/// Finalizes a instance of the TSBK class.
~TSBK();
+ /// Equals operator.
+ TSBK& operator=(const TSBK& data);
+
/// Decode a trunking signalling block.
bool decode(const uint8_t* data);
/// Encode a trunking signalling block.
void encode(uint8_t* data, bool singleBlock);
- /// Helper to reset data values to defaults.
- void reset();
-
/// Sets the flag to skip vendor opcode processing.
void setVendorSkip(bool skip);
- /** Local Site data */
- /// Sets local configured site data.
- void setSiteData(SiteData siteData);
- /// Sets local configured site callsign.
+ /// Sets the callsign.
void setCallsign(std::string callsign);
- /// Sets the identity lookup table entry.
- void setIdenTable(lookups::IdenTable entry);
- /// Sets a flag indicating whether or not networking is active.
- void setNetActive(bool netActive);
- /// Sets the total number of channels at the site.
- void setSiteChCnt(uint8_t chCnt);
public:
/// Flag indicating verbose log output.
@@ -112,10 +107,6 @@ namespace p25
/// Service type.
__PROPERTY(uint8_t, service, Service);
-
- /// Service class.
- __PROPERTY(uint8_t, serviceClass, ServiceClass);
-
/// Response type.
__PROPERTY(uint8_t, response, Response);
@@ -148,7 +139,7 @@ namespace p25
__PROPERTY(uint8_t, adjChannelId, AdjSiteChnId);
/// Adjacent site channel number.
__PROPERTY(uint32_t, adjChannelNo, AdjSiteChnNo);
- /// Adjacent site channel number.
+ /// Adjacent site service class.
__PROPERTY(uint8_t, adjServiceClass, AdjSiteSvcClass);
/** SCCB Data */
@@ -183,7 +174,16 @@ namespace p25
/// Flag indicating a group/talkgroup operation.
__PROPERTY(bool, group, Group);
+ /** Local Site data */
+ /// Local Site Data.
+ __PROPERTY_PLAIN(SiteData, siteData, siteData);
+ /// Local Site Identity Entry.
+ __PROPERTY_PLAIN(lookups::IdenTable, siteIdenEntry, siteIdenEntry);
+
private:
+ /// Initializes a new instance of the TSBK class.
+ TSBK(SiteData siteData);
+
friend class LC;
friend class TDULC;
edac::RS634717 m_rs;
@@ -195,11 +195,7 @@ namespace p25
uint16_t m_sndcpDAC;
/** Local Site data */
- SiteData m_siteData;
uint8_t* m_siteCallsign;
- lookups::IdenTable m_siteIdenEntry;
- bool m_siteNetActive;
- uint8_t m_siteChCnt;
};
} // namespace lc
} // namespace p25