rename and reorganize some code to better be consistent across the project;

pull/39/head
Bryan Biedenkapp 3 years ago
parent e4cc23a3a3
commit 09dd03f946

@ -1924,7 +1924,7 @@ void RESTAPI::restAPI_GetP25DumpTSBK(const HTTPPayload& request, HTTPPayload& re
errorPayload(reply, "OK", HTTPPayload::OK);
if (m_p25 != nullptr) {
if (match.size() <= 1) {
bool tsbkDump = m_p25->trunk()->getTSBKVerbose();
bool tsbkDump = m_p25->control()->getTSBKVerbose();
response["verbose"].set<bool>(tsbkDump);
@ -1934,7 +1934,7 @@ void RESTAPI::restAPI_GetP25DumpTSBK(const HTTPPayload& request, HTTPPayload& re
else {
if (match.size() == 2) {
uint8_t enable = (uint8_t)::strtoul(match.str(1).c_str(), NULL, 10);
m_p25->trunk()->setTSBKVerbose((enable == 1U) ? true : false);
m_p25->control()->setTSBKVerbose((enable == 1U) ? true : false);
}
}
}
@ -2003,25 +2003,25 @@ void RESTAPI::restAPI_PutP25RID(const HTTPPayload& request, HTTPPayload& reply,
}
uint8_t mfId = req["mfId"].get<uint8_t>();
m_p25->trunk()->setLastMFId(mfId);
m_p25->control()->setLastMFId(mfId);
}
else if (::strtolower(command) == RID_CMD_PAGE) {
m_p25->trunk()->writeRF_TSDU_Call_Alrt(p25::P25_WUID_FNE, dstId);
m_p25->control()->writeRF_TSDU_Call_Alrt(p25::P25_WUID_FNE, dstId);
}
else if (::strtolower(command) == RID_CMD_CHECK) {
m_p25->trunk()->writeRF_TSDU_Ext_Func(p25::P25_EXT_FNCT_CHECK, p25::P25_WUID_FNE, dstId);
m_p25->control()->writeRF_TSDU_Ext_Func(p25::P25_EXT_FNCT_CHECK, p25::P25_WUID_FNE, dstId);
}
else if (::strtolower(command) == RID_CMD_INHIBIT) {
m_p25->trunk()->writeRF_TSDU_Ext_Func(p25::P25_EXT_FNCT_INHIBIT, p25::P25_WUID_FNE, dstId);
m_p25->control()->writeRF_TSDU_Ext_Func(p25::P25_EXT_FNCT_INHIBIT, p25::P25_WUID_FNE, dstId);
}
else if (::strtolower(command) == RID_CMD_UNINHIBIT) {
m_p25->trunk()->writeRF_TSDU_Ext_Func(p25::P25_EXT_FNCT_UNINHIBIT, p25::P25_WUID_FNE, dstId);
m_p25->control()->writeRF_TSDU_Ext_Func(p25::P25_EXT_FNCT_UNINHIBIT, p25::P25_WUID_FNE, dstId);
}
else if (::strtolower(command) == RID_CMD_GAQ) {
m_p25->trunk()->writeRF_TSDU_Grp_Aff_Q(dstId);
m_p25->control()->writeRF_TSDU_Grp_Aff_Q(dstId);
}
else if (::strtolower(command) == RID_CMD_UREG) {
m_p25->trunk()->writeRF_TSDU_U_Reg_Cmd(dstId);
m_p25->control()->writeRF_TSDU_U_Reg_Cmd(dstId);
}
else if (::strtolower(command) == RID_CMD_EMERG) {
// validate source ID is a integer within the JSON blob
@ -2037,7 +2037,7 @@ void RESTAPI::restAPI_PutP25RID(const HTTPPayload& request, HTTPPayload& reply,
return;
}
m_p25->trunk()->writeRF_TSDU_Emerg_Alrm(srcId, dstId);
m_p25->control()->writeRF_TSDU_Emerg_Alrm(srcId, dstId);
}
else {
errorPayload(reply, "invalid command");
@ -2188,7 +2188,7 @@ void RESTAPI::restAPI_PutP25RawTSBK(const HTTPPayload& request, HTTPPayload& rep
Utils::dump("Raw TSBK", tsbk, p25::P25_TSBK_LENGTH_BYTES);
}
m_p25->trunk()->writeRF_TSDU_Raw(tsbk);
m_p25->control()->writeRF_TSDU_Raw(tsbk);
#else
errorPayload(reply, "P25 operations are unavailable", HTTPPayload::SERVICE_UNAVAILABLE);
#endif // defined(ENABLE_P25)

@ -94,6 +94,7 @@ Control::Control(bool authoritative, uint32_t ran, uint32_t callHang, uint32_t q
bool dumpRCCHData, bool debug, bool verbose) :
m_voice(nullptr),
m_data(nullptr),
m_control(nullptr),
m_authoritative(authoritative),
m_supervisor(false),
m_ran(ran),
@ -101,7 +102,7 @@ Control::Control(bool authoritative, uint32_t ran, uint32_t callHang, uint32_t q
m_modem(modem),
m_network(network),
m_duplex(duplex),
m_control(false),
m_enableControl(false),
m_dedicatedControl(false),
m_voiceOnControl(false),
m_rfLastLICH(),
@ -156,9 +157,9 @@ Control::Control(bool authoritative, uint32_t ran, uint32_t callHang, uint32_t q
acl::AccessControl::init(m_ridLookup, m_tidLookup);
m_voice = new Voice(this, network, debug, verbose);
m_trunk = new Trunk(this, network, debug, verbose);
m_data = new Data(this, network, debug, verbose);
m_voice = new Voice(this, debug, verbose);
m_control = new ControlSignaling(this, debug, verbose);
m_data = new Data(this, debug, verbose);
lc::RCCH::setVerbose(dumpRCCHData);
lc::RTCH::setVerbose(dumpRCCHData);
@ -173,8 +174,8 @@ Control::~Control()
delete m_voice;
}
if (m_trunk != nullptr) {
delete m_trunk;
if (m_control != nullptr) {
delete m_control;
}
if (m_data != nullptr) {
@ -232,12 +233,12 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, const std::string cw
m_supervisor = supervisor;
m_trunk->m_verifyAff = nxdnProtocol["verifyAff"].as<bool>(false);
m_trunk->m_verifyReg = nxdnProtocol["verifyReg"].as<bool>(false);
m_control->m_verifyAff = nxdnProtocol["verifyAff"].as<bool>(false);
m_control->m_verifyReg = nxdnProtocol["verifyReg"].as<bool>(false);
yaml::Node control = nxdnProtocol["control"];
m_control = control["enable"].as<bool>(false);
if (m_control) {
m_enableControl = control["enable"].as<bool>(false);
if (m_enableControl) {
m_dedicatedControl = control["dedicated"].as<bool>(false);
}
else {
@ -246,7 +247,7 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, const std::string cw
m_voiceOnControl = nxdnProtocol["voiceOnControl"].as<bool>(false);
m_trunk->m_disableGrantSrcIdCheck = control["disableGrantSourceIdCheck"].as<bool>(false);
m_control->m_disableGrantSrcIdCheck = control["disableGrantSourceIdCheck"].as<bool>(false);
yaml::Node rfssConfig = systemConf["config"];
yaml::Node controlCh = rfssConfig["controlCh"];
@ -280,7 +281,7 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, const std::string cw
*/
bool disableCompositeFlag = nxdnProtocol["disableCompositeFlag"].as<bool>(false);
uint8_t serviceClass = NXDN_SIF1_VOICE_CALL_SVC | NXDN_SIF1_DATA_CALL_SVC;
if (m_control) {
if (m_enableControl) {
serviceClass |= NXDN_SIF1_GRP_REG_SVC;
}
@ -347,16 +348,16 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, const std::string cw
LogInfo(" Silence Threshold: %u (%.1f%%)", m_voice->m_silenceThreshold, float(m_voice->m_silenceThreshold) / 12.33F);
LogInfo(" Frame Loss Threshold: %u", m_frameLossThreshold);
if (m_control) {
if (m_enableControl) {
LogInfo(" Voice on Control: %s", m_voiceOnControl ? "yes" : "no");
if (m_trunk->m_disableGrantSrcIdCheck) {
if (m_control->m_disableGrantSrcIdCheck) {
LogInfo(" Disable Grant Source ID Check: yes");
}
}
LogInfo(" Notify Control: %s", m_notifyCC ? "yes" : "no");
LogInfo(" Verify Affiliation: %s", m_trunk->m_verifyAff ? "yes" : "no");
LogInfo(" Verify Registration: %s", m_trunk->m_verifyReg ? "yes" : "no");
LogInfo(" Verify Affiliation: %s", m_control->m_verifyAff ? "yes" : "no");
LogInfo(" Verify Registration: %s", m_control->m_verifyReg ? "yes" : "no");
}
if (m_voice != nullptr) {
@ -491,7 +492,7 @@ bool Control::processFrame(uint8_t* data, uint32_t len)
bool ret = false;
if (rfct == NXDN_LICH_RFCT_RCCH) {
ret = m_trunk->process(fct, option, data, len);
ret = m_control->process(fct, option, data, len);
}
else if (rfct == NXDN_LICH_RFCT_RTCH || rfct == NXDN_LICH_RFCT_RDCH) {
switch (fct) {
@ -566,7 +567,7 @@ void Control::clock(uint32_t ms)
}
// if we have control enabled; do clocking to generate a CC data stream
if (m_control) {
if (m_enableControl) {
if (m_ccRunning && !m_ccPacketInterval.isRunning()) {
m_ccPacketInterval.start();
}
@ -653,7 +654,7 @@ void Control::clock(uint32_t ms)
m_networkWatchdog.stop();
if (m_control) {
if (m_enableControl) {
m_affiliations.releaseGrant(m_netLC.getDstId(), false);
}
@ -692,8 +693,8 @@ void Control::clock(uint32_t ms)
}
// clock data and trunking
if (m_trunk != nullptr) {
m_trunk->clock(ms);
if (m_control != nullptr) {
m_control->clock(ms);
}
}
@ -722,7 +723,7 @@ void Control::permittedTG(uint32_t dstId)
/// <param name="grp"></param>
void Control::grantTG(uint32_t srcId, uint32_t dstId, bool grp)
{
if (!m_control) {
if (!m_enableControl) {
return;
}
@ -730,7 +731,7 @@ void Control::grantTG(uint32_t srcId, uint32_t dstId, bool grp)
LogMessage(LOG_NXDN, "network TG grant demand, srcId = %u, dstId = %u", srcId, dstId);
}
m_trunk->writeRF_Message_Grant(srcId, dstId, 4U, grp);
m_control->writeRF_Message_Grant(srcId, dstId, 4U, grp);
}
/// <summary>
@ -739,7 +740,7 @@ void Control::grantTG(uint32_t srcId, uint32_t dstId, bool grp)
/// <param name="dstId"></param>
void Control::releaseGrantTG(uint32_t dstId)
{
if (!m_control) {
if (!m_enableControl) {
return;
}
@ -762,7 +763,7 @@ void Control::releaseGrantTG(uint32_t dstId)
/// <param name="dstId"></param>
void Control::touchGrantTG(uint32_t dstId)
{
if (!m_control) {
if (!m_enableControl) {
return;
}
@ -1005,7 +1006,7 @@ void Control::processFrameLoss()
m_voice->m_rfFrames, m_voice->m_rfBits, m_voice->m_rfUndecodableLC, m_voice->m_rfErrs, float(m_voice->m_rfErrs * 100U) / float(m_voice->m_rfBits));
m_affiliations.releaseGrant(m_rfLC.getDstId(), false);
if (!m_control) {
if (!m_enableControl) {
notifyCC_ReleaseGrant(m_rfLC.getDstId());
}
@ -1091,7 +1092,7 @@ void Control::notifyCC_TouchGrant(uint32_t dstId)
/// <returns></returns>
bool Control::writeRF_ControlData()
{
if (!m_control)
if (!m_enableControl)
return false;
if (m_ccFrameCnt == 254U) {
@ -1105,14 +1106,14 @@ bool Control::writeRF_ControlData()
return false;
}
const uint8_t maxSeq = m_trunk->m_bcchCnt + (m_trunk->m_ccchPagingCnt + m_trunk->m_ccchMultiCnt) *
m_trunk->m_rcchGroupingCnt * m_trunk->m_rcchIterateCnt;
const uint8_t maxSeq = m_control->m_bcchCnt + (m_control->m_ccchPagingCnt + m_control->m_ccchMultiCnt) *
m_control->m_rcchGroupingCnt * m_control->m_rcchIterateCnt;
if (m_ccSeq == maxSeq) {
m_ccSeq = 0U;
}
if (m_netState == RS_NET_IDLE && m_rfState == RS_RF_LISTENING) {
m_trunk->writeRF_ControlData(m_ccFrameCnt, m_ccSeq, true);
m_control->writeRF_ControlData(m_ccFrameCnt, m_ccSeq, true);
m_ccSeq++;
if (m_ccSeq == maxSeq) {

@ -36,7 +36,7 @@
#include "nxdn/channel/LICH.h"
#include "nxdn/lc/RTCH.h"
#include "nxdn/packet/Voice.h"
#include "nxdn/packet/Trunk.h"
#include "nxdn/packet/ControlSignaling.h"
#include "nxdn/packet/Data.h"
#include "nxdn/SiteData.h"
#include "network/Network.h"
@ -60,7 +60,7 @@ namespace nxdn
// ---------------------------------------------------------------------------
namespace packet { class HOST_SW_API Voice; }
namespace packet { class HOST_SW_API Trunk; }
namespace packet { class HOST_SW_API ControlSignaling; }
namespace packet { class HOST_SW_API Data; }
// ---------------------------------------------------------------------------
@ -141,8 +141,8 @@ namespace nxdn
packet::Voice* m_voice;
friend class packet::Data;
packet::Data* m_data;
friend class packet::Trunk;
packet::Trunk* m_trunk;
friend class packet::ControlSignaling;
packet::ControlSignaling* m_control;
bool m_authoritative;
bool m_supervisor;
@ -154,7 +154,7 @@ namespace nxdn
network::Network* m_network;
bool m_duplex;
bool m_control;
bool m_enableControl;
bool m_dedicatedControl;
bool m_voiceOnControl;

@ -30,7 +30,7 @@
#include "Defines.h"
#include "nxdn/NXDNDefines.h"
#include "nxdn/channel/CAC.h"
#include "nxdn/packet/Trunk.h"
#include "nxdn/packet/ControlSignaling.h"
#include "nxdn/acl/AccessControl.h"
#include "nxdn/lc/rcch/RCCHFactory.h"
#include "nxdn/Sync.h"
@ -57,7 +57,7 @@ using namespace nxdn::packet;
// Make sure control data is supported.
#define IS_SUPPORT_CONTROL_CHECK(_PCKT_STR, _PCKT, _SRCID) \
if (!m_nxdn->m_control) { \
if (!m_nxdn->m_enableControl) { \
LogWarning(LOG_RF, "NXDN, %s denial, unsupported service, srcId = %u", _PCKT_STR.c_str(), _SRCID); \
writeRF_Message_Deny(0U, _SRCID, NXDN_CAUSE_SVC_UNAVAILABLE, _PCKT); \
m_nxdn->m_rfState = RS_RF_REJECTED; \
@ -151,7 +151,7 @@ const uint32_t GRANT_TIMER_TIMEOUT = 15U;
/// <param name="data">Buffer containing data frame.</param>
/// <param name="len">Length of data frame.</param>
/// <returns></returns>
bool Trunk::process(uint8_t fct, uint8_t option, uint8_t* data, uint32_t len)
bool ControlSignaling::process(uint8_t fct, uint8_t option, uint8_t* data, uint32_t len)
{
assert(data != nullptr);
@ -207,7 +207,7 @@ bool Trunk::process(uint8_t fct, uint8_t option, uint8_t* data, uint32_t len)
if (m_nxdn->m_authoritative) {
writeRF_Message_Grant(srcId, dstId, serviceOptions, true);
} else {
m_network->writeGrantReq(modem::DVM_STATE::STATE_NXDN, srcId, dstId, 0U, false);
m_nxdn->m_network->writeGrantReq(modem::DVM_STATE::STATE_NXDN, srcId, dstId, 0U, false);
}
}
break;
@ -255,11 +255,11 @@ bool Trunk::process(uint8_t fct, uint8_t option, uint8_t* data, uint32_t len)
/// <param name="data">Buffer containing data frame.</param>
/// <param name="len">Length of data frame.</param>
/// <returns></returns>
bool Trunk::processNetwork(uint8_t fct, uint8_t option, lc::RTCH& netLC, uint8_t* data, uint32_t len)
bool ControlSignaling::processNetwork(uint8_t fct, uint8_t option, lc::RTCH& netLC, uint8_t* data, uint32_t len)
{
assert(data != nullptr);
if (!m_nxdn->m_control)
if (!m_nxdn->m_enableControl)
return false;
if (m_nxdn->m_rfState != RS_RF_LISTENING && m_nxdn->m_netState == RS_NET_IDLE)
return false;
@ -312,9 +312,9 @@ bool Trunk::processNetwork(uint8_t fct, uint8_t option, lc::RTCH& netLC, uint8_t
/// Updates the processor by the passed number of milliseconds.
/// </summary>
/// <param name="ms"></param>
void Trunk::clock(uint32_t ms)
void ControlSignaling::clock(uint32_t ms)
{
if (m_nxdn->m_control) {
if (m_nxdn->m_enableControl) {
// clock all the grant timers
m_nxdn->m_affiliations.clock(ms);
}
@ -325,15 +325,13 @@ void Trunk::clock(uint32_t ms)
// ---------------------------------------------------------------------------
/// <summary>
/// Initializes a new instance of the Trunk class.
/// Initializes a new instance of the ControlSignaling class.
/// </summary>
/// <param name="nxdn">Instance of the Control class.</param>
/// <param name="network">Instance of the BaseNetwork class.</param>
/// <param name="debug">Flag indicating whether NXDN debug is enabled.</param>
/// <param name="verbose">Flag indicating whether NXDN verbose logging is enabled.</param>
Trunk::Trunk(Control* nxdn, network::BaseNetwork* network, bool debug, bool verbose) :
ControlSignaling::ControlSignaling(Control* nxdn, bool debug, bool verbose) :
m_nxdn(nxdn),
m_network(network),
m_bcchCnt(1U),
m_rcchGroupingCnt(1U),
m_ccchPagingCnt(2U),
@ -350,9 +348,9 @@ Trunk::Trunk(Control* nxdn, network::BaseNetwork* network, bool debug, bool verb
}
/// <summary>
/// Finalizes a instance of the Trunk class.
/// Finalizes a instance of the ControlSignaling class.
/// </summary>
Trunk::~Trunk()
ControlSignaling::~ControlSignaling()
{
/* stub */
}
@ -362,59 +360,17 @@ Trunk::~Trunk()
/// </summary>
/// <param name="data"></param>
/// <param name="len"></param>
void Trunk::writeNetwork(const uint8_t *data, uint32_t len)
void ControlSignaling::writeNetwork(const uint8_t *data, uint32_t len)
{
assert(data != nullptr);
if (m_network == nullptr)
if (m_nxdn->m_network == nullptr)
return;
if (m_nxdn->m_rfTimeout.isRunning() && m_nxdn->m_rfTimeout.hasExpired())
return;
m_network->writeNXDN(m_nxdn->m_rfLC, data, len);
}
/// <summary>
/// Helper to write control channel packet data.
/// </summary>
/// <param name="frameCnt"></param>
/// <param name="n"></param>
/// <param name="adjSS"></param>
void Trunk::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adjSS)
{
uint8_t i = 0U, seqCnt = 0U;
if (!m_nxdn->m_control)
return;
// don't add any frames if the queue is full
uint8_t len = NXDN_FRAME_LENGTH_BYTES + 2U;
uint32_t space = m_nxdn->m_txQueue.freeSpace();
if (space < (len + 1U)) {
return;
}
do
{
if (m_debug) {
LogDebug(LOG_NXDN, "writeRF_ControlData, frameCnt = %u, seq = %u", frameCnt, n);
}
switch (n)
{
case 0:
writeRF_CC_Message_Site_Info();
break;
default:
writeRF_CC_Message_Service_Info();
break;
}
if (seqCnt > 0U)
n++;
i++;
} while (i <= seqCnt);
m_nxdn->m_network->writeNXDN(m_nxdn->m_rfLC, data, len);
}
/// <summary>
@ -424,9 +380,9 @@ void Trunk::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adjSS)
/// <param name="noNetwork"></param>
/// <param name="clearBeforeWrite"></param>
/// <param name="imm"></param>
void Trunk::writeRF_Message(RCCH* rcch, bool noNetwork, bool clearBeforeWrite, bool imm)
void ControlSignaling::writeRF_Message(RCCH* rcch, bool noNetwork, bool clearBeforeWrite, bool imm)
{
if (!m_nxdn->m_control)
if (!m_nxdn->m_enableControl)
return;
uint8_t data[NXDN_FRAME_LENGTH_BYTES + 2U];
@ -474,6 +430,48 @@ void Trunk::writeRF_Message(RCCH* rcch, bool noNetwork, bool clearBeforeWrite, b
}
}
/// <summary>
/// Helper to write control channel packet data.
/// </summary>
/// <param name="frameCnt"></param>
/// <param name="n"></param>
/// <param name="adjSS"></param>
void ControlSignaling::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adjSS)
{
uint8_t i = 0U, seqCnt = 0U;
if (!m_nxdn->m_enableControl)
return;
// don't add any frames if the queue is full
uint8_t len = NXDN_FRAME_LENGTH_BYTES + 2U;
uint32_t space = m_nxdn->m_txQueue.freeSpace();
if (space < (len + 1U)) {
return;
}
do
{
if (m_debug) {
LogDebug(LOG_NXDN, "writeRF_ControlData, frameCnt = %u, seq = %u", frameCnt, n);
}
switch (n)
{
case 0:
writeRF_CC_Message_Site_Info();
break;
default:
writeRF_CC_Message_Service_Info();
break;
}
if (seqCnt > 0U)
n++;
i++;
} while (i <= seqCnt);
}
/// <summary>
/// Helper to write a grant packet.
/// </summary>
@ -485,7 +483,7 @@ void Trunk::writeRF_Message(RCCH* rcch, bool noNetwork, bool clearBeforeWrite, b
/// <param name="skip"></param>
/// <param name="chNo"></param>
/// <returns></returns>
bool Trunk::writeRF_Message_Grant(uint32_t srcId, uint32_t dstId, uint8_t serviceOptions, bool grp, bool net, bool skip, uint32_t chNo)
bool ControlSignaling::writeRF_Message_Grant(uint32_t srcId, uint32_t dstId, uint8_t serviceOptions, bool grp, bool net, bool skip, uint32_t chNo)
{
bool emergency = ((serviceOptions & 0xFFU) & 0x80U) == 0x80U; // Emergency Flag
bool encryption = ((serviceOptions & 0xFFU) & 0x40U) == 0x40U; // Encryption Flag
@ -660,7 +658,7 @@ bool Trunk::writeRF_Message_Grant(uint32_t srcId, uint32_t dstId, uint8_t servic
/// <param name="dstId"></param>
/// <param name="reason"></param>
/// <param name="service"></param>
void Trunk::writeRF_Message_Deny(uint32_t srcId, uint32_t dstId, uint8_t reason, uint8_t service)
void ControlSignaling::writeRF_Message_Deny(uint32_t srcId, uint32_t dstId, uint8_t reason, uint8_t service)
{
std::unique_ptr<RCCH> rcch = nullptr;
@ -690,7 +688,7 @@ void Trunk::writeRF_Message_Deny(uint32_t srcId, uint32_t dstId, uint8_t reason,
/// <param name="srcId"></param>
/// <param name="dstId"></param>
/// <param name="locId"></param>
bool Trunk::writeRF_Message_Grp_Reg_Rsp(uint32_t srcId, uint32_t dstId, uint32_t locId)
bool ControlSignaling::writeRF_Message_Grp_Reg_Rsp(uint32_t srcId, uint32_t dstId, uint32_t locId)
{
bool ret = false;
@ -748,7 +746,7 @@ bool Trunk::writeRF_Message_Grp_Reg_Rsp(uint32_t srcId, uint32_t dstId, uint32_t
/// Helper to write a unit registration response packet.
/// </summary>
/// <param name="srcId"></param>
void Trunk::writeRF_Message_U_Reg_Rsp(uint32_t srcId, uint32_t locId)
void ControlSignaling::writeRF_Message_U_Reg_Rsp(uint32_t srcId, uint32_t locId)
{
std::unique_ptr<rcch::MESSAGE_TYPE_REG> rcch = new_unique(rcch::MESSAGE_TYPE_REG);
rcch->setCauseResponse(NXDN_CAUSE_MM_REG_ACCEPTED);
@ -790,7 +788,7 @@ void Trunk::writeRF_Message_U_Reg_Rsp(uint32_t srcId, uint32_t locId)
/// <summary>
/// Helper to write a CC SITE_INFO broadcast packet on the RF interface.
/// </summary>
void Trunk::writeRF_CC_Message_Site_Info()
void ControlSignaling::writeRF_CC_Message_Site_Info()
{
uint8_t data[NXDN_FRAME_LENGTH_BYTES + 2U];
::memset(data + 2U, 0x00U, NXDN_FRAME_LENGTH_BYTES);
@ -840,7 +838,7 @@ void Trunk::writeRF_CC_Message_Site_Info()
/// <summary>
/// Helper to write a CC SRV_INFO broadcast packet on the RF interface.
/// </summary>
void Trunk::writeRF_CC_Message_Service_Info()
void ControlSignaling::writeRF_CC_Message_Service_Info()
{
uint8_t data[NXDN_FRAME_LENGTH_BYTES + 2U];
::memset(data + 2U, 0x00U, NXDN_FRAME_LENGTH_BYTES);
@ -886,7 +884,7 @@ void Trunk::writeRF_CC_Message_Service_Info()
/// Helper to add the post field bits on NXDN frame data.
/// </summary>
/// <param name="data"></param>
void Trunk::addPostBits(uint8_t* data)
void ControlSignaling::addPostBits(uint8_t* data)
{
assert(data != nullptr);

@ -11,7 +11,7 @@
// Licensed under the GPLv2 License (https://opensource.org/licenses/GPL-2.0)
//
/*
* Copyright (C) 2022 by Bryan Biedenkapp N2PLL
* Copyright (C) 2022-2023 by Bryan Biedenkapp N2PLL
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -27,13 +27,12 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if !defined(__NXDN_PACKET_TRUNK_H__)
#define __NXDN_PACKET_TRUNK_H__
#if !defined(__NXDN_PACKET_CONTROL_SIGNALING_H__)
#define __NXDN_PACKET_CONTROL_SIGNALING_H__
#include "Defines.h"
#include "nxdn/Control.h"
#include "nxdn/lc/RCCH.h"
#include "network/BaseNetwork.h"
#include <cstdio>
#include <string>
@ -52,10 +51,10 @@ namespace nxdn
{
// ---------------------------------------------------------------------------
// Class Declaration
// This class implements handling logic for NXDN control signalling packets.
// This class implements handling logic for NXDN RCCH packets.
// ---------------------------------------------------------------------------
class HOST_SW_API Trunk {
class HOST_SW_API ControlSignaling {
public:
/// <summary>Process a data frame from the RF interface.</summary>
virtual bool process(uint8_t fct, uint8_t option, uint8_t* data, uint32_t len);
@ -71,8 +70,6 @@ namespace nxdn
friend class nxdn::Control;
Control* m_nxdn;
network::BaseNetwork* m_network;
uint8_t m_bcchCnt;
uint8_t m_rcchGroupingCnt;
uint8_t m_ccchPagingCnt;
@ -89,22 +86,22 @@ namespace nxdn
bool m_verbose;
bool m_debug;
/// <summary>Initializes a new instance of the Trunk class.</summary>
Trunk(Control* nxdn, network::BaseNetwork* network, bool debug, bool verbose);
/// <summary>Finalizes a instance of the Trunk class.</summary>
virtual ~Trunk();
/// <summary>Initializes a new instance of the ControlSignaling class.</summary>
ControlSignaling(Control* nxdn, bool debug, bool verbose);
/// <summary>Finalizes a instance of the ControlSignaling class.</summary>
virtual ~ControlSignaling();
/// <summary>Write data processed from RF to the network.</summary>
void writeNetwork(const uint8_t* data, uint32_t len);
/// <summary>Helper to write control channel packet data.</summary>
void writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adjSS);
/// <summary>Helper to write a immediate single-block RCCH packet.</summary>
void writeRF_Message_Imm(lc::RCCH *rcch, bool noNetwork) { writeRF_Message(rcch, noNetwork, false, true); }
/// <summary>Helper to write a single-block RCCH packet.</summary>
void writeRF_Message(lc::RCCH* rcch, bool noNetwork, bool clearBeforeWrite = false, bool imm = false);
/// <summary>Helper to write control channel packet data.</summary>
void writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adjSS);
/// <summary>Helper to write a grant packet.</summary>
bool writeRF_Message_Grant(uint32_t srcId, uint32_t dstId, uint8_t serviceOptions, bool grp, bool net = false, bool skip = false, uint32_t chNo = 0U);
/// <summary>Helper to write a deny packet.</summary>
@ -125,4 +122,4 @@ namespace nxdn
} // namespace packet
} // namespace nxdn
#endif // __NXDN_PACKET_TRUNK_H__
#endif // __NXDN_PACKET_CONTROL_SIGNALING_H__

@ -394,12 +394,10 @@ bool Data::processNetwork(uint8_t option, lc::RTCH& netLC, uint8_t* data, uint32
/// Initializes a new instance of the Data class.
/// </summary>
/// <param name="nxdn">Instance of the Control class.</param>
/// <param name="network">Instance of the BaseNetwork class.</param>
/// <param name="debug">Flag indicating whether NXDN debug is enabled.</param>
/// <param name="verbose">Flag indicating whether NXDN verbose logging is enabled.</param>
Data::Data(Control* nxdn, network::BaseNetwork* network, bool debug, bool verbose) :
Data::Data(Control* nxdn, bool debug, bool verbose) :
m_nxdn(nxdn),
m_network(network),
m_lastRejectId(0U),
m_verbose(verbose),
m_debug(debug)
@ -424,11 +422,11 @@ void Data::writeNetwork(const uint8_t *data, uint32_t len)
{
assert(data != nullptr);
if (m_network == nullptr)
if (m_nxdn->m_network == nullptr)
return;
if (m_nxdn->m_rfTimeout.isRunning() && m_nxdn->m_rfTimeout.hasExpired())
return;
m_network->writeNXDN(m_nxdn->m_rfLC, data, len);
m_nxdn->m_network->writeNXDN(m_nxdn->m_rfLC, data, len);
}

@ -33,7 +33,6 @@
#include "Defines.h"
#include "nxdn/Control.h"
#include "network/BaseNetwork.h"
#include <cstdio>
#include <string>
@ -69,15 +68,13 @@ namespace nxdn
friend class nxdn::Control;
Control* m_nxdn;
network::BaseNetwork* m_network;
uint16_t m_lastRejectId;
bool m_verbose;
bool m_debug;
/// <summary>Initializes a new instance of the Data class.</summary>
Data(Control* nxdn, network::BaseNetwork* network, bool debug, bool verbose);
Data(Control* nxdn, bool debug, bool verbose);
/// <summary>Finalizes a instance of the Data class.</summary>
virtual ~Data();

@ -75,8 +75,8 @@ using namespace nxdn::packet;
LogWarning(LOG_RF, "Traffic collision detect, preempting existing network traffic to new RF traffic, rfDstId = %u, netDstId = %u", dstId, \
m_nxdn->m_netLastDstId); \
resetNet(); \
if (m_network != nullptr) \
m_network->resetNXDN(); \
if (m_nxdn->m_network != nullptr) \
m_nxdn->m_network->resetNXDN(); \
} \
}
@ -110,16 +110,16 @@ using namespace nxdn::packet;
LogWarning(LOG_RF, "Traffic collision detect, preempting new network traffic to existing RF traffic (Are we in a voting condition?), rfSrcId = %u, rfDstId = %u, netSrcId = %u, netDstId = %u", _LAYER3.getSrcId(), _LAYER3.getDstId(), \
_SRC_ID, _DST_ID); \
resetNet(); \
if (m_network != nullptr) \
m_network->resetNXDN(); \
if (m_nxdn->m_network != nullptr) \
m_nxdn->m_network->resetNXDN(); \
return false; \
} \
else { \
LogWarning(LOG_RF, "Traffic collision detect, preempting new network traffic to existing RF traffic, rfDstId = %u, netDstId = %u", _LAYER3.getDstId(), \
_DST_ID); \
resetNet(); \
if (m_network != nullptr) \
m_network->resetNXDN(); \
if (m_nxdn->m_network != nullptr) \
m_nxdn->m_network->resetNXDN(); \
return false; \
} \
} \
@ -128,8 +128,8 @@ using namespace nxdn::packet;
if (!m_nxdn->m_authoritative && m_nxdn->m_permittedDstId != _DST_ID) { \
LogWarning(LOG_NET, "[NON-AUTHORITATIVE] Ignoring network traffic, destination not permitted, dstId = %u", _DST_ID); \
resetNet(); \
if (m_network != nullptr) \
m_network->resetNXDN(); \
if (m_nxdn->m_network != nullptr) \
m_nxdn->m_network->resetNXDN(); \
return false; \
}
@ -1040,12 +1040,10 @@ bool Voice::processNetwork(uint8_t fct, uint8_t option, lc::RTCH& netLC, uint8_t
/// Initializes a new instance of the Voice class.
/// </summary>
/// <param name="nxdn">Instance of the Control class.</param>
/// <param name="network">Instance of the BaseNetwork class.</param>
/// <param name="debug">Flag indicating whether NXDN debug is enabled.</param>
/// <param name="verbose">Flag indicating whether NXDN verbose logging is enabled.</param>
Voice::Voice(Control* nxdn, network::BaseNetwork* network, bool debug, bool verbose) :
Voice::Voice(Control* nxdn, bool debug, bool verbose) :
m_nxdn(nxdn),
m_network(network),
m_rfFrames(0U),
m_rfBits(0U),
m_rfErrs(0U),
@ -1077,11 +1075,11 @@ void Voice::writeNetwork(const uint8_t *data, uint32_t len)
{
assert(data != nullptr);
if (m_network == nullptr)
if (m_nxdn->m_network == nullptr)
return;
if (m_nxdn->m_rfTimeout.isRunning() && m_nxdn->m_rfTimeout.hasExpired())
return;
m_network->writeNXDN(m_nxdn->m_rfLC, data, len);
m_nxdn->m_network->writeNXDN(m_nxdn->m_rfLC, data, len);
}

@ -33,7 +33,6 @@
#include "Defines.h"
#include "nxdn/Control.h"
#include "network/BaseNetwork.h"
#include <cstdio>
#include <string>
@ -71,8 +70,6 @@ namespace nxdn
friend class nxdn::Control;
Control* m_nxdn;
network::BaseNetwork* m_network;
uint32_t m_rfFrames;
uint32_t m_rfBits;
uint32_t m_rfErrs;
@ -88,7 +85,7 @@ namespace nxdn
bool m_debug;
/// <summary>Initializes a new instance of the Voice class.</summary>
Voice(Control* nxdn, network::BaseNetwork* network, bool debug, bool verbose);
Voice(Control* nxdn, bool debug, bool verbose);
/// <summary>Finalizes a instance of the Voice class.</summary>
virtual ~Voice();

@ -87,7 +87,7 @@ Control::Control(bool authoritative, uint32_t nac, uint32_t callHang, uint32_t q
bool dumpPDUData, bool repeatPDU, bool dumpTSBKData, bool debug, bool verbose) :
m_voice(nullptr),
m_data(nullptr),
m_trunk(nullptr),
m_control(nullptr),
m_authoritative(authoritative),
m_supervisor(false),
m_nac(nac),
@ -99,7 +99,7 @@ Control::Control(bool authoritative, uint32_t nac, uint32_t callHang, uint32_t q
m_legacyGroupGrnt(true),
m_legacyGroupReg(false),
m_duplex(duplex),
m_control(false),
m_enableControl(false),
m_dedicatedControl(false),
m_voiceOnControl(false),
m_ackTSBKRequests(true),
@ -158,9 +158,9 @@ Control::Control(bool authoritative, uint32_t nac, uint32_t callHang, uint32_t q
m_hangCount = callHang * 4U;
m_voice = new Voice(this, network, debug, verbose);
m_trunk = new Trunk(this, network, dumpTSBKData, debug, verbose);
m_data = new Data(this, network, dumpPDUData, repeatPDU, debug, verbose);
m_voice = new Voice(this, debug, verbose);
m_control = new ControlSignaling(this, dumpTSBKData, debug, verbose);
m_data = new Data(this, dumpPDUData, repeatPDU, debug, verbose);
}
/// <summary>
@ -172,8 +172,8 @@ Control::~Control()
delete m_voice;
}
if (m_trunk != nullptr) {
delete m_trunk;
if (m_control != nullptr) {
delete m_control;
}
if (m_data != nullptr) {
@ -230,25 +230,25 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, const std::string cw
m_tduPreambleCount = p25Protocol["tduPreambleCount"].as<uint32_t>(8U);
yaml::Node rfssConfig = systemConf["config"];
m_trunk->m_patchSuperGroup = (uint32_t)::strtoul(rfssConfig["pSuperGroup"].as<std::string>("FFFE").c_str(), NULL, 16);
m_trunk->m_announcementGroup = (uint32_t)::strtoul(rfssConfig["announcementGroup"].as<std::string>("FFFE").c_str(), NULL, 16);
m_control->m_patchSuperGroup = (uint32_t)::strtoul(rfssConfig["pSuperGroup"].as<std::string>("FFFE").c_str(), NULL, 16);
m_control->m_announcementGroup = (uint32_t)::strtoul(rfssConfig["announcementGroup"].as<std::string>("FFFE").c_str(), NULL, 16);
m_inhibitUnauth = p25Protocol["inhibitUnauthorized"].as<bool>(false);
m_legacyGroupGrnt = p25Protocol["legacyGroupGrnt"].as<bool>(true);
m_legacyGroupReg = p25Protocol["legacyGroupReg"].as<bool>(false);
m_trunk->m_verifyAff = p25Protocol["verifyAff"].as<bool>(false);
m_trunk->m_verifyReg = p25Protocol["verifyReg"].as<bool>(false);
m_control->m_verifyAff = p25Protocol["verifyAff"].as<bool>(false);
m_control->m_verifyReg = p25Protocol["verifyReg"].as<bool>(false);
m_trunk->m_noStatusAck = p25Protocol["noStatusAck"].as<bool>(false);
m_trunk->m_noMessageAck = p25Protocol["noMessageAck"].as<bool>(true);
m_trunk->m_unitToUnitAvailCheck = p25Protocol["unitToUnitAvailCheck"].as<bool>(true);
m_control->m_noStatusAck = p25Protocol["noStatusAck"].as<bool>(false);
m_control->m_noMessageAck = p25Protocol["noMessageAck"].as<bool>(true);
m_control->m_unitToUnitAvailCheck = p25Protocol["unitToUnitAvailCheck"].as<bool>(true);
m_trunk->m_sndcpChGrant = p25Protocol["sndcpGrant"].as<bool>(false);
m_control->m_sndcpChGrant = p25Protocol["sndcpGrant"].as<bool>(false);
yaml::Node control = p25Protocol["control"];
m_control = control["enable"].as<bool>(false);
if (m_control) {
m_enableControl = control["enable"].as<bool>(false);
if (m_enableControl) {
m_dedicatedControl = control["dedicated"].as<bool>(false);
}
else {
@ -258,7 +258,7 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, const std::string cw
m_voiceOnControl = p25Protocol["voiceOnControl"].as<bool>(false);
// if control channel is off for voice on control off
if (!m_control) {
if (!m_enableControl) {
m_voiceOnControl = false;
}
@ -270,16 +270,16 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, const std::string cw
}
m_ackTSBKRequests = control["ackRequests"].as<bool>(true);
m_trunk->m_ctrlTSDUMBF = !control["disableTSDUMBF"].as<bool>(false);
m_trunk->m_ctrlTimeDateAnn = control["enableTimeDateAnn"].as<bool>(false);
m_trunk->m_redundantGrant = control["redundantGrantTransmit"].as<bool>(false);
m_control->m_ctrlTSDUMBF = !control["disableTSDUMBF"].as<bool>(false);
m_control->m_ctrlTimeDateAnn = control["enableTimeDateAnn"].as<bool>(false);
m_control->m_redundantGrant = control["redundantGrantTransmit"].as<bool>(false);
m_allowExplicitSourceId = p25Protocol["allowExplicitSourceId"].as<bool>(true);
uint32_t ccBcstInterval = p25Protocol["control"]["interval"].as<uint32_t>(300U);
m_trunk->m_adjSiteUpdateInterval += ccBcstInterval;
m_control->m_adjSiteUpdateInterval += ccBcstInterval;
m_trunk->m_disableGrantSrcIdCheck = p25Protocol["control"]["disableGrantSourceIdCheck"].as<bool>(false);
m_control->m_disableGrantSrcIdCheck = p25Protocol["control"]["disableGrantSourceIdCheck"].as<bool>(false);
yaml::Node controlCh = rfssConfig["controlCh"];
m_notifyCC = controlCh["notifyEnable"].as<bool>(false);
@ -318,7 +318,7 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, const std::string cw
m_disableNetworkGrant = p25Protocol["disableNetworkGrant"].as<bool>(false);
m_disableNetworkHDU = p25Protocol["disableNetworkHDU"].as<bool>(false);
if (m_disableNetworkGrant && m_control && m_dedicatedControl) {
if (m_disableNetworkGrant && m_enableControl && m_dedicatedControl) {
LogWarning(LOG_P25, "Cannot disable network traffic grants for dedicated control configuration.");
m_disableNetworkGrant = false;
}
@ -333,7 +333,7 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, const std::string cw
*/
bool disableCompositeFlag = p25Protocol["disableCompositeFlag"].as<bool>(false);
uint8_t serviceClass = P25_SVC_CLS_VOICE | P25_SVC_CLS_DATA;
if (m_control) {
if (m_enableControl) {
serviceClass |= P25_SVC_CLS_REG;
}
@ -405,10 +405,10 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, const std::string cw
LogInfo(" Silence Threshold: %u (%.1f%%)", m_voice->m_silenceThreshold, float(m_voice->m_silenceThreshold) / 12.33F);
LogInfo(" Frame Loss Threshold: %u", m_frameLossThreshold);
if (m_control) {
if (m_enableControl) {
LogInfo(" Voice on Control: %s", m_voiceOnControl ? "yes" : "no");
LogInfo(" Ack Requests: %s", m_ackTSBKRequests ? "yes" : "no");
if (m_trunk->m_disableGrantSrcIdCheck) {
if (m_control->m_disableGrantSrcIdCheck) {
LogInfo(" Disable Grant Source ID Check: yes");
}
}
@ -417,8 +417,8 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, const std::string cw
LogInfo(" Control Data Only: yes");
}
LogInfo(" Patch Super Group: $%04X", m_trunk->m_patchSuperGroup);
LogInfo(" Announcement Group: $%04X", m_trunk->m_announcementGroup);
LogInfo(" Patch Super Group: $%04X", m_control->m_patchSuperGroup);
LogInfo(" Announcement Group: $%04X", m_control->m_announcementGroup);
LogInfo(" Notify Control: %s", m_notifyCC ? "yes" : "no");
if (m_disableNetworkHDU) {
@ -427,25 +427,25 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, const std::string cw
if (m_disableNetworkGrant) {
LogInfo(" Disable Network Grants: yes");
}
if (!m_trunk->m_ctrlTSDUMBF) {
if (!m_control->m_ctrlTSDUMBF) {
LogInfo(" Disable Multi-Block TSDUs: yes");
}
LogInfo(" Time/Date Announcement TSBK: %s", m_trunk->m_ctrlTimeDateAnn ? "yes" : "no");
LogInfo(" Time/Date Announcement TSBK: %s", m_control->m_ctrlTimeDateAnn ? "yes" : "no");
LogInfo(" Inhibit Unauthorized: %s", m_inhibitUnauth ? "yes" : "no");
LogInfo(" Legacy Group Grant: %s", m_legacyGroupGrnt ? "yes" : "no");
LogInfo(" Legacy Group Registration: %s", m_legacyGroupReg ? "yes" : "no");
LogInfo(" Verify Affiliation: %s", m_trunk->m_verifyAff ? "yes" : "no");
LogInfo(" Verify Registration: %s", m_trunk->m_verifyReg ? "yes" : "no");
LogInfo(" Verify Affiliation: %s", m_control->m_verifyAff ? "yes" : "no");
LogInfo(" Verify Registration: %s", m_control->m_verifyReg ? "yes" : "no");
LogInfo(" SNDCP Channel Grant: %s", m_trunk->m_sndcpChGrant ? "yes" : "no");
LogInfo(" SNDCP Channel Grant: %s", m_control->m_sndcpChGrant ? "yes" : "no");
LogInfo(" No Status ACK: %s", m_trunk->m_noStatusAck ? "yes" : "no");
LogInfo(" No Message ACK: %s", m_trunk->m_noMessageAck ? "yes" : "no");
LogInfo(" Unit-to-Unit Availability Check: %s", m_trunk->m_unitToUnitAvailCheck ? "yes" : "no");
LogInfo(" No Status ACK: %s", m_control->m_noStatusAck ? "yes" : "no");
LogInfo(" No Message ACK: %s", m_control->m_noMessageAck ? "yes" : "no");
LogInfo(" Unit-to-Unit Availability Check: %s", m_control->m_unitToUnitAvailCheck ? "yes" : "no");
LogInfo(" Explicit Source ID Support: %s", m_allowExplicitSourceId ? "yes" : "no");
if (!m_trunk->m_redundantGrant) {
if (!m_control->m_redundantGrant) {
LogInfo(" Redundant Grant Transmit: yes");
}
}
@ -596,7 +596,7 @@ bool Control::processFrame(uint8_t* data, uint32_t len)
break;
}
if (!m_dedicatedControl || m_trunk->m_convFallback)
if (!m_dedicatedControl || m_control->m_convFallback)
ret = m_voice->process(data, len);
else {
if (m_voiceOnControl && m_affiliations.isChBusy(m_siteData.channelNo())) {
@ -616,7 +616,7 @@ bool Control::processFrame(uint8_t* data, uint32_t len)
break;
case P25_DUID_TSDU:
ret = m_trunk->process(data, len);
ret = m_control->process(data, len);
break;
default:
@ -681,7 +681,7 @@ uint32_t Control::getFrame(uint8_t* data)
/// </summary>
void Control::writeAdjSSNetwork()
{
m_trunk->writeAdjSSNetwork();
m_control->writeAdjSSNetwork();
}
/// <summary>
@ -709,7 +709,7 @@ bool Control::writeRF_VoiceEnd()
ret = true;
}
if (!m_control && m_duplex) {
if (!m_enableControl && m_duplex) {
writeRF_Nulls();
}
@ -741,7 +741,7 @@ void Control::clock(uint32_t ms)
}
// if we have control enabled; do clocking to generate a CC data stream
if (m_control) {
if (m_enableControl) {
if (m_ccRunning && !m_ccPacketInterval.isRunning()) {
m_ccPacketInterval.start();
}
@ -882,8 +882,8 @@ void Control::clock(uint32_t ms)
m_data->clock(ms);
}
if (m_trunk != nullptr) {
m_trunk->clock(ms);
if (m_control != nullptr) {
m_control->clock(ms);
}
}
@ -912,7 +912,7 @@ void Control::permittedTG(uint32_t dstId)
/// <param name="grp"></param>
void Control::grantTG(uint32_t srcId, uint32_t dstId, bool grp)
{
if (!m_control) {
if (!m_enableControl) {
return;
}
@ -920,7 +920,7 @@ void Control::grantTG(uint32_t srcId, uint32_t dstId, bool grp)
LogMessage(LOG_P25, "network TG grant demand, srcId = %u, dstId = %u", srcId, dstId);
}
m_trunk->writeRF_TSDU_Grant(srcId, dstId, 4U, grp);
m_control->writeRF_TSDU_Grant(srcId, dstId, 4U, grp);
}
/// <summary>
@ -929,7 +929,7 @@ void Control::grantTG(uint32_t srcId, uint32_t dstId, bool grp)
/// <param name="dstId"></param>
void Control::releaseGrantTG(uint32_t dstId)
{
if (!m_control) {
if (!m_enableControl) {
return;
}
@ -951,7 +951,7 @@ void Control::releaseGrantTG(uint32_t dstId)
/// <param name="dstId"></param>
void Control::touchGrantTG(uint32_t dstId)
{
if (!m_control) {
if (!m_enableControl) {
return;
}
@ -980,8 +980,8 @@ bool Control::isBusy() const
/// <param name="verbose">Flag indicating whether P25 verbose logging is enabled.</param>
void Control::setDebugVerbose(bool debug, bool verbose)
{
m_debug = m_voice->m_debug = m_data->m_debug = m_trunk->m_debug = debug;
m_verbose = m_voice->m_verbose = m_data->m_verbose = m_trunk->m_verbose = verbose;
m_debug = m_voice->m_debug = m_data->m_debug = m_control->m_debug = debug;
m_verbose = m_voice->m_verbose = m_data->m_verbose = m_control->m_verbose = verbose;
}
/// <summary>
@ -1258,7 +1258,7 @@ void Control::processNetwork()
case P25_DUID_TDU:
case P25_DUID_TDULC:
// is this an TDU with a grant demand?
if (duid == P25_DUID_TDU && m_control && grantDemand) {
if (duid == P25_DUID_TDU && m_enableControl && grantDemand) {
if (m_disableNetworkGrant) {
return;
}
@ -1281,7 +1281,7 @@ void Control::processNetwork()
LogMessage(LOG_NET, P25_TSDU_STR " remote grant demand, srcId = %u, dstId = %u", srcId, dstId);
}
if (!m_trunk->writeRF_TSDU_Grant(srcId, dstId, serviceOptions, true, true)) {
if (!m_control->writeRF_TSDU_Grant(srcId, dstId, serviceOptions, true, true)) {
LogError(LOG_NET, P25_TSDU_STR " call failure, network call not granted, dstId = %u", dstId);
return;
}
@ -1293,7 +1293,7 @@ void Control::processNetwork()
break;
case P25_DUID_TSDU:
m_trunk->processNetwork(data.get(), frameLength, control, lsd, duid);
m_control->processNetwork(data.get(), frameLength, control, lsd, duid);
break;
}
}
@ -1317,10 +1317,10 @@ void Control::processFrameLoss()
m_voice->m_rfFrames, m_voice->m_rfBits, m_voice->m_rfUndecodableLC, m_voice->m_rfErrs, float(m_voice->m_rfErrs * 100U) / float(m_voice->m_rfBits));
m_affiliations.releaseGrant(m_voice->m_rfLC.getDstId(), false);
if (!m_control) {
if (!m_enableControl) {
notifyCC_ReleaseGrant(m_voice->m_rfLC.getDstId());
}
m_trunk->writeNet_TSDU_Call_Term(m_voice->m_rfLC.getSrcId(), m_voice->m_rfLC.getDstId());
m_control->writeNet_TSDU_Call_Term(m_voice->m_rfLC.getSrcId(), m_voice->m_rfLC.getDstId());
writeRF_TDU(false);
m_voice->m_lastDUID = P25_DUID_TDU;
@ -1431,11 +1431,11 @@ void Control::notifyCC_TouchGrant(uint32_t dstId)
/// <returns></returns>
bool Control::writeRF_ControlData()
{
if (!m_control)
if (!m_enableControl)
return false;
if (m_ccFrameCnt == 254U) {
m_trunk->writeAdjSSNetwork();
m_control->writeAdjSSNetwork();
m_ccFrameCnt = 0U;
}
@ -1452,7 +1452,7 @@ bool Control::writeRF_ControlData()
}
if (m_netState == RS_NET_IDLE && m_rfState == RS_RF_LISTENING) {
m_trunk->writeRF_ControlData(m_ccFrameCnt, m_ccSeq, true);
m_control->writeRF_ControlData(m_ccFrameCnt, m_ccSeq, true);
m_ccSeq++;
if (m_ccSeq == maxSeq) {
@ -1471,7 +1471,7 @@ bool Control::writeRF_ControlData()
/// <returns></returns>
bool Control::writeRF_ControlEnd()
{
if (!m_control)
if (!m_enableControl)
return false;
m_txQueue.clear();
@ -1479,7 +1479,7 @@ bool Control::writeRF_ControlEnd()
if (m_netState == RS_NET_IDLE && m_rfState == RS_RF_LISTENING) {
for (uint32_t i = 0; i < TSBK_PCH_CCH_CNT; i++) {
m_trunk->queueRF_TSBK_Ctrl(TSBK_OSP_MOT_PSH_CCH);
m_control->queueRF_TSBK_Ctrl(TSBK_OSP_MOT_PSH_CCH);
}
writeRF_Nulls();

@ -36,7 +36,7 @@
#include "p25/SiteData.h"
#include "p25/packet/Data.h"
#include "p25/packet/Voice.h"
#include "p25/packet/Trunk.h"
#include "p25/packet/ControlSignaling.h"
#include "network/Network.h"
#include "lookups/RSSIInterpolator.h"
#include "lookups/IdenTableLookup.h"
@ -124,8 +124,8 @@ namespace p25
/// <summary>Gets instance of the NID class.</summary>
NID nid() { return m_nid; }
/// <summary>Gets instance of the Trunk class.</summary>
packet::Trunk* trunk() { return m_trunk; }
/// <summary>Gets instance of the ControlSignaling class.</summary>
packet::ControlSignaling* control() { return m_control; }
/// <summary>Gets instance of the P25AffiliationLookup class.</summary>
lookups::P25AffiliationLookup affiliations() { return m_affiliations; }
@ -149,8 +149,8 @@ namespace p25
packet::Voice* m_voice;
friend class packet::Data;
packet::Data* m_data;
friend class packet::Trunk;
packet::Trunk* m_trunk;
friend class packet::ControlSignaling;
packet::ControlSignaling* m_control;
friend class lookups::P25AffiliationLookup;
bool m_authoritative;
@ -168,7 +168,7 @@ namespace p25
bool m_legacyGroupReg;
bool m_duplex;
bool m_control;
bool m_enableControl;
bool m_dedicatedControl;
bool m_voiceOnControl;
bool m_controlOnly;

@ -24,7 +24,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "p25/lookups/P25AffiliationLookup.h"
#include "p25/packet/Trunk.h"
#include "p25/packet/ControlSignaling.h"
#include "p25/Control.h"
#include "Log.h"
@ -89,7 +89,7 @@ std::vector<uint32_t> P25AffiliationLookup::clearGroupAff(uint32_t dstId, bool r
if (srcToRel.size() > 0U) {
// release affiliations
for (uint32_t srcId : srcToRel) {
m_p25->m_trunk->writeRF_TSDU_U_Dereg_Ack(srcId);
m_p25->m_control->writeRF_TSDU_U_Dereg_Ack(srcId);
}
}

@ -27,7 +27,7 @@
#include "Defines.h"
#include "p25/P25Defines.h"
#include "p25/packet/Voice.h"
#include "p25/packet/Trunk.h"
#include "p25/packet/ControlSignaling.h"
#include "p25/acl/AccessControl.h"
#include "p25/lc/tsbk/TSBKFactory.h"
#include "p25/lc/tdulc/TDULCFactory.h"
@ -57,7 +57,7 @@ using namespace p25::packet;
// Make sure control data is supported.
#define IS_SUPPORT_CONTROL_CHECK(_PCKT_STR, _PCKT, _SRCID) \
if (!m_p25->m_control) { \
if (!m_p25->m_enableControl) { \
LogWarning(LOG_RF, P25_TSDU_STR ", %s denial, unsupported service, srcId = %u", _PCKT_STR.c_str(), _SRCID); \
writeRF_TSDU_Deny(P25_WUID_FNE, _SRCID, P25_DENY_RSN_SYS_UNSUPPORTED_SVC, _PCKT); \
m_p25->m_rfState = RS_RF_REJECTED; \
@ -151,7 +151,7 @@ using namespace p25::packet;
}
#define RF_TO_WRITE_NET(OSP) \
if (m_network != nullptr) { \
if (m_p25->m_network != nullptr) { \
uint8_t _buf[P25_TSDU_FRAME_LENGTH_BYTES]; \
writeNet_TSDU_From_RF(OSP, _buf); \
writeNetworkRF(OSP, _buf, true); \
@ -179,11 +179,11 @@ const uint8_t CONV_FALLBACK_PACKET_DELAY = 8U;
/// <param name="len">Length of data frame.</param>
/// <param name="preDecodedTSBK">Pre-decoded TSBK.</param>
/// <returns></returns>
bool Trunk::process(uint8_t* data, uint32_t len, std::unique_ptr<lc::TSBK> preDecodedTSBK)
bool ControlSignaling::process(uint8_t* data, uint32_t len, std::unique_ptr<lc::TSBK> preDecodedTSBK)
{
assert(data != nullptr);
if (!m_p25->m_control)
if (!m_p25->m_enableControl)
return false;
uint8_t duid = 0U;
@ -255,7 +255,7 @@ bool Trunk::process(uint8_t* data, uint32_t len, std::unique_ptr<lc::TSBK> preDe
writeRF_TSDU_Grant(srcId, dstId, serviceOptions, true);
} else {
m_network->writeGrantReq(modem::DVM_STATE::STATE_P25, srcId, dstId, 0U, false);
m_p25->m_network->writeGrantReq(modem::DVM_STATE::STATE_P25, srcId, dstId, 0U, false);
}
}
break;
@ -285,7 +285,7 @@ bool Trunk::process(uint8_t* data, uint32_t len, std::unique_ptr<lc::TSBK> preDe
writeRF_TSDU_Grant(srcId, dstId, serviceOptions, false);
} else {
m_network->writeGrantReq(modem::DVM_STATE::STATE_P25, srcId, dstId, 0U, true);
m_p25->m_network->writeGrantReq(modem::DVM_STATE::STATE_P25, srcId, dstId, 0U, true);
}
}
}
@ -319,7 +319,7 @@ bool Trunk::process(uint8_t* data, uint32_t len, std::unique_ptr<lc::TSBK> preDe
writeRF_TSDU_Grant(srcId, dstId, serviceOptions, false);
} else {
m_network->writeGrantReq(modem::DVM_STATE::STATE_P25, srcId, dstId, 0U, true);
m_p25->m_network->writeGrantReq(modem::DVM_STATE::STATE_P25, srcId, dstId, 0U, true);
}
}
else if (iosp->getResponse() == P25_ANS_RSP_DENY) {
@ -616,9 +616,9 @@ bool Trunk::process(uint8_t* data, uint32_t len, std::unique_ptr<lc::TSBK> preDe
/// <param name="lsd"></param>
/// <param name="duid"></param>
/// <returns></returns>
bool Trunk::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::LowSpeedData& lsd, uint8_t& duid)
bool ControlSignaling::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::LowSpeedData& lsd, uint8_t& duid)
{
if (!m_p25->m_control)
if (!m_p25->m_enableControl)
return false;
if (m_p25->m_rfState != RS_RF_LISTENING && m_p25->m_netState == RS_NET_IDLE)
return false;
@ -633,7 +633,7 @@ bool Trunk::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L
// handle updating internal adjacent site information
if (tsbk->getLCO() == TSBK_OSP_ADJ_STS_BCAST) {
if (!m_p25->m_control) {
if (!m_p25->m_enableControl) {
return false;
}
@ -907,9 +907,9 @@ bool Trunk::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L
/// </summary>
/// <param name="dataHeader"></param>
/// <param name="dataBlock"></param>
bool Trunk::processMBT(DataHeader& dataHeader, DataBlock* blocks)
bool ControlSignaling::processMBT(DataHeader& dataHeader, DataBlock* blocks)
{
if (!m_p25->m_control) {
if (!m_p25->m_enableControl) {
return false;
}
@ -929,15 +929,15 @@ bool Trunk::processMBT(DataHeader& dataHeader, DataBlock* blocks)
/// <summary>
/// Helper to write P25 adjacent site information to the network.
/// </summary>
void Trunk::writeAdjSSNetwork()
void ControlSignaling::writeAdjSSNetwork()
{
if (!m_p25->m_control) {
if (!m_p25->m_enableControl) {
return;
}
if (m_network != nullptr) {
if (m_p25->m_network != nullptr) {
uint8_t cfva = P25_CFVA_VALID;
if (m_p25->m_control && m_p25->m_voiceOnControl) {
if (m_p25->m_enableControl && m_p25->m_voiceOnControl) {
cfva |= P25_CFVA_CONV;
}
@ -965,9 +965,9 @@ void Trunk::writeAdjSSNetwork()
/// Updates the processor by the passed number of milliseconds.
/// </summary>
/// <param name="ms"></param>
void Trunk::clock(uint32_t ms)
void ControlSignaling::clock(uint32_t ms)
{
if (m_p25->m_control) {
if (m_p25->m_enableControl) {
// clock all the grant timers
m_p25->m_affiliations.clock(ms);
@ -1019,7 +1019,7 @@ void Trunk::clock(uint32_t ms)
/// </summary>
/// <param name="srcId"></param>
/// <param name="dstId"></param>
void Trunk::writeRF_TSDU_Call_Alrt(uint32_t srcId, uint32_t dstId)
void ControlSignaling::writeRF_TSDU_Call_Alrt(uint32_t srcId, uint32_t dstId)
{
std::unique_ptr<IOSP_CALL_ALRT> iosp = new_unique(IOSP_CALL_ALRT);
iosp->setSrcId(srcId);
@ -1037,7 +1037,7 @@ void Trunk::writeRF_TSDU_Call_Alrt(uint32_t srcId, uint32_t dstId)
/// <param name="srcId"></param>
/// <param name="dstId"></param>
/// <param name="txMult"></param>
void Trunk::writeRF_TSDU_Radio_Mon(uint32_t srcId, uint32_t dstId, uint8_t txMult)
void ControlSignaling::writeRF_TSDU_Radio_Mon(uint32_t srcId, uint32_t dstId, uint8_t txMult)
{
std::unique_ptr<IOSP_RAD_MON> iosp = new_unique(IOSP_RAD_MON);
iosp->setSrcId(srcId);
@ -1059,7 +1059,7 @@ void Trunk::writeRF_TSDU_Radio_Mon(uint32_t srcId, uint32_t dstId, uint8_t txMul
/// <param name="func"></param>
/// <param name="arg"></param>
/// <param name="dstId"></param>
void Trunk::writeRF_TSDU_Ext_Func(uint32_t func, uint32_t arg, uint32_t dstId)
void ControlSignaling::writeRF_TSDU_Ext_Func(uint32_t func, uint32_t arg, uint32_t dstId)
{
std::unique_ptr<IOSP_EXT_FNCT> iosp = new_unique(IOSP_EXT_FNCT);
iosp->setExtendedFunction(func);
@ -1089,7 +1089,7 @@ void Trunk::writeRF_TSDU_Ext_Func(uint32_t func, uint32_t arg, uint32_t dstId)
/// Helper to write a group affiliation query packet.
/// </summary>
/// <param name="dstId"></param>
void Trunk::writeRF_TSDU_Grp_Aff_Q(uint32_t dstId)
void ControlSignaling::writeRF_TSDU_Grp_Aff_Q(uint32_t dstId)
{
std::unique_ptr<OSP_GRP_AFF_Q> osp = new_unique(OSP_GRP_AFF_Q);
osp->setSrcId(P25_WUID_FNE);
@ -1105,7 +1105,7 @@ void Trunk::writeRF_TSDU_Grp_Aff_Q(uint32_t dstId)
/// Helper to write a unit registration command packet.
/// </summary>
/// <param name="dstId"></param>
void Trunk::writeRF_TSDU_U_Reg_Cmd(uint32_t dstId)
void ControlSignaling::writeRF_TSDU_U_Reg_Cmd(uint32_t dstId)
{
std::unique_ptr<OSP_U_REG_CMD> osp = new_unique(OSP_U_REG_CMD);
osp->setSrcId(P25_WUID_FNE);
@ -1122,7 +1122,7 @@ void Trunk::writeRF_TSDU_U_Reg_Cmd(uint32_t dstId)
/// </summary>
/// <param name="srcId"></param>
/// <param name="dstId"></param>
void Trunk::writeRF_TSDU_Emerg_Alrm(uint32_t srcId, uint32_t dstId)
void ControlSignaling::writeRF_TSDU_Emerg_Alrm(uint32_t srcId, uint32_t dstId)
{
std::unique_ptr<ISP_EMERG_ALRM_REQ> isp = new_unique(ISP_EMERG_ALRM_REQ);
isp->setSrcId(srcId);
@ -1136,7 +1136,7 @@ void Trunk::writeRF_TSDU_Emerg_Alrm(uint32_t srcId, uint32_t dstId)
/// Helper to write a raw TSBK.
/// </summary>
/// <param name="tsbk"></param>
void Trunk::writeRF_TSDU_Raw(const uint8_t* tsbk)
void ControlSignaling::writeRF_TSDU_Raw(const uint8_t* tsbk)
{
if (tsbk == nullptr) {
return;
@ -1152,10 +1152,10 @@ void Trunk::writeRF_TSDU_Raw(const uint8_t* tsbk)
/// Helper to change the conventional fallback state.
/// </summary>
/// <param name="verbose">Flag indicating whether conventional fallback is enabled.</param>
void Trunk::setConvFallback(bool fallback)
void ControlSignaling::setConvFallback(bool fallback)
{
m_convFallback = fallback;
if (m_convFallback && m_p25->m_control) {
if (m_convFallback && m_p25->m_enableControl) {
m_convFallbackPacketDelay = 0U;
std::unique_ptr<OSP_MOT_PSH_CCH> osp = new_unique(OSP_MOT_PSH_CCH);
@ -1169,7 +1169,7 @@ void Trunk::setConvFallback(bool fallback)
/// Helper to change the TSBK verbose state.
/// </summary>
/// <param name="verbose">Flag indicating whether TSBK dumping is enabled.</param>
void Trunk::setTSBKVerbose(bool verbose)
void ControlSignaling::setTSBKVerbose(bool verbose)
{
m_dumpTSBK = verbose;
lc::TSBK::setVerbose(verbose);
@ -1181,16 +1181,14 @@ void Trunk::setTSBKVerbose(bool verbose)
// ---------------------------------------------------------------------------
/// <summary>
/// Initializes a new instance of the Trunk class.
/// Initializes a new instance of the ControlSignaling class.
/// </summary>
/// <param name="p25">Instance of the Control class.</param>
/// <param name="network">Instance of the BaseNetwork class.</param>
/// <param name="dumpTSBKData">Flag indicating whether TSBK data is dumped to the log.</param>
/// <param name="debug">Flag indicating whether P25 debug is enabled.</param>
/// <param name="verbose">Flag indicating whether P25 verbose logging is enabled.</param>
Trunk::Trunk(Control* p25, network::BaseNetwork* network, bool dumpTSBKData, bool debug, bool verbose) :
ControlSignaling::ControlSignaling(Control* p25, bool dumpTSBKData, bool debug, bool verbose) :
m_p25(p25),
m_network(network),
m_patchSuperGroup(0xFFFEU),
m_announcementGroup(0xFFFEU),
m_verifyAff(false),
@ -1241,9 +1239,9 @@ Trunk::Trunk(Control* p25, network::BaseNetwork* network, bool dumpTSBKData, boo
}
/// <summary>
/// Finalizes a instance of the Trunk class.
/// Finalizes a instance of the ControlSignaling class.
/// </summary>
Trunk::~Trunk()
ControlSignaling::~ControlSignaling()
{
delete[] m_rfMBF;
}
@ -1254,12 +1252,12 @@ Trunk::~Trunk()
/// <param name="tsbk"></param>
/// <param name="data"></param>
/// <param name="autoReset"></param>
void Trunk::writeNetworkRF(lc::TSBK* tsbk, const uint8_t* data, bool autoReset)
void ControlSignaling::writeNetworkRF(lc::TSBK* tsbk, const uint8_t* data, bool autoReset)
{
assert(tsbk != nullptr);
assert(data != nullptr);
if (m_network == nullptr)
if (m_p25->m_network == nullptr)
return;
if (m_p25->m_rfTimeout.isRunning() && m_p25->m_rfTimeout.hasExpired())
@ -1271,9 +1269,9 @@ void Trunk::writeNetworkRF(lc::TSBK* tsbk, const uint8_t* data, bool autoReset)
lc.setSrcId(tsbk->getSrcId());
lc.setDstId(tsbk->getDstId());
m_network->writeP25TSDU(lc, data);
m_p25->m_network->writeP25TSDU(lc, data);
if (autoReset)
m_network->resetP25();
m_p25->m_network->resetP25();
}
/// <summary>
@ -1282,11 +1280,11 @@ void Trunk::writeNetworkRF(lc::TSBK* tsbk, const uint8_t* data, bool autoReset)
/// <param name="tduLc"></param>
/// <param name="data"></param>
/// <param name="autoReset"></param>
void Trunk::writeNetworkRF(lc::TDULC* tduLc, const uint8_t* data, bool autoReset)
void ControlSignaling::writeNetworkRF(lc::TDULC* tduLc, const uint8_t* data, bool autoReset)
{
assert(data != nullptr);
if (m_network == nullptr)
if (m_p25->m_network == nullptr)
return;
if (m_p25->m_rfTimeout.isRunning() && m_p25->m_rfTimeout.hasExpired())
@ -1298,162 +1296,9 @@ void Trunk::writeNetworkRF(lc::TDULC* tduLc, const uint8_t* data, bool autoReset
lc.setSrcId(tduLc->getSrcId());
lc.setDstId(tduLc->getDstId());
m_network->writeP25TSDU(lc, data);
m_p25->m_network->writeP25TSDU(lc, data);
if (autoReset)
m_network->resetP25();
}
/// <summary>
/// Helper to write control channel packet data.
/// </summary>
/// <param name="frameCnt"></param>
/// <param name="n"></param>
/// <param name="adjSS"></param>
void Trunk::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adjSS)
{
if (!m_p25->m_control)
return;
if (m_convFallback) {
bool fallbackTx = (frameCnt % 253U) == 0U;
if (fallbackTx && n == 8U) {
if (m_convFallbackPacketDelay >= CONV_FALLBACK_PACKET_DELAY) {
std::unique_ptr<lc::tdulc::LC_CONV_FALLBACK> lc = new_unique(lc::tdulc::LC_CONV_FALLBACK);
for (uint8_t i = 0U; i < 3U; i++) {
writeRF_TDULC(lc.get(), true);
}
m_convFallbackPacketDelay = 0U;
} else {
m_convFallbackPacketDelay++;
}
}
else {
if (n == 8U) {
std::unique_ptr<lc::tdulc::LC_FAILSOFT> lc = new_unique(lc::tdulc::LC_FAILSOFT);
writeRF_TDULC(lc.get(), true);
}
}
return;
}
if (m_debug) {
LogDebug(LOG_P25, "writeRF_ControlData, mbfCnt = %u, frameCnt = %u, seq = %u, adjSS = %u", m_mbfCnt, frameCnt, n, adjSS);
}
// bryanb: this is just a simple counter because we treat the SYNC_BCST as unlocked
m_microslotCount++;
if (m_microslotCount > 7999U)
m_microslotCount = 0;
bool forcePad = false;
bool alt = (frameCnt % 2U) > 0U;
switch (n)
{
/** required data */
case 0:
default:
queueRF_TSBK_Ctrl(TSBK_OSP_IDEN_UP);
break;
case 1:
if (alt)
queueRF_TSBK_Ctrl(TSBK_OSP_RFSS_STS_BCAST);
else
queueRF_TSBK_Ctrl(TSBK_OSP_NET_STS_BCAST);
break;
case 2:
if (alt)
queueRF_TSBK_Ctrl(TSBK_OSP_NET_STS_BCAST);
else
queueRF_TSBK_Ctrl(TSBK_OSP_RFSS_STS_BCAST);
break;
case 3:
if (alt)
queueRF_TSBK_Ctrl(TSBK_OSP_RFSS_STS_BCAST);
else
queueRF_TSBK_Ctrl(TSBK_OSP_NET_STS_BCAST);
break;
case 4:
queueRF_TSBK_Ctrl(TSBK_OSP_SYNC_BCAST);
break;
/** update data */
case 5:
if (m_p25->m_affiliations.grantSize() > 0) {
queueRF_TSBK_Ctrl(TSBK_OSP_GRP_VCH_GRANT_UPD);
}
break;
/** extra data */
case 6:
queueRF_TSBK_Ctrl(TSBK_OSP_SNDCP_CH_ANN);
break;
case 7:
// write ADJSS
if (adjSS && m_adjSiteTable.size() > 0) {
queueRF_TSBK_Ctrl(TSBK_OSP_ADJ_STS_BCAST);
break;
} else {
forcePad = true;
}
break;
case 8:
// write SCCB
if (adjSS && m_sccbTable.size() > 0) {
queueRF_TSBK_Ctrl(TSBK_OSP_SCCB_EXP);
break;
}
break;
}
// are we transmitting the time/date annoucement?
bool timeDateAnn = (frameCnt % 64U) == 0U;
if (m_ctrlTimeDateAnn && timeDateAnn && n > 4U) {
queueRF_TSBK_Ctrl(TSBK_OSP_TIME_DATE_ANN);
}
// should we insert the BSI bursts?
bool bsi = (frameCnt % 127U) == 0U;
if (bsi && n > 4U) {
queueRF_TSBK_Ctrl(TSBK_OSP_MOT_CC_BSI);
}
// should we insert the Git Hash burst?
bool hash = (frameCnt % 125U) == 0U;
if (hash && n > 4U) {
queueRF_TSBK_Ctrl(TSBK_OSP_DVM_GIT_HASH);
}
// add padding after the last sequence or if forced; and only
// if we're doing multiblock frames (MBF)
if ((n >= 4U || forcePad) && m_ctrlTSDUMBF)
{
// pad MBF if we have 1 queued TSDUs
if (m_mbfCnt == 1U) {
queueRF_TSBK_Ctrl(TSBK_OSP_RFSS_STS_BCAST);
queueRF_TSBK_Ctrl(TSBK_OSP_NET_STS_BCAST);
if (m_debug) {
LogDebug(LOG_P25, "writeRF_ControlData, have 1 pad 2, mbfCnt = %u", m_mbfCnt);
}
}
// pad MBF if we have 2 queued TSDUs
if (m_mbfCnt == 2U) {
std::vector<::lookups::IdenTable> entries = m_p25->m_idenTable->list();
if (entries.size() > 1U) {
queueRF_TSBK_Ctrl(TSBK_OSP_IDEN_UP);
}
else {
queueRF_TSBK_Ctrl(TSBK_OSP_RFSS_STS_BCAST);
}
if (m_debug) {
LogDebug(LOG_P25, "writeRF_ControlData, have 2 pad 1, mbfCnt = %u", m_mbfCnt);
}
}
// reset MBF count
m_mbfCnt = 0U;
}
m_p25->m_network->resetP25();
}
/// <summary>
@ -1461,7 +1306,7 @@ void Trunk::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adjSS)
/// </summary>
/// <param name="lc"></param>
/// <param name="noNetwork"></param>
void Trunk::writeRF_TDULC(lc::TDULC* lc, bool noNetwork)
void ControlSignaling::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);
@ -1499,7 +1344,7 @@ void Trunk::writeRF_TDULC(lc::TDULC* lc, bool noNetwork)
/// Helper to write a network P25 TDU w/ link control packet.
/// </summary>
/// <param name="lc"></param>
void Trunk::writeNet_TDULC(lc::TDULC* lc)
void ControlSignaling::writeNet_TDULC(lc::TDULC* lc)
{
uint8_t buffer[P25_TDULC_FRAME_LENGTH_BYTES + 2U];
::memset(buffer, 0x00U, P25_TDULC_FRAME_LENGTH_BYTES + 2U);
@ -1533,8 +1378,8 @@ void Trunk::writeNet_TDULC(lc::TDULC* lc)
::ActivityLog("P25", false, "network end of transmission, %u frames", m_p25->m_voice->m_netFrames);
}
if (m_network != nullptr)
m_network->resetP25();
if (m_p25->m_network != nullptr)
m_p25->m_network->resetP25();
m_p25->m_netTimeout.stop();
m_p25->m_networkWatchdog.stop();
@ -1542,59 +1387,6 @@ void Trunk::writeNet_TDULC(lc::TDULC* lc)
m_p25->m_tailOnIdle = true;
}
/// <summary>
/// Helper to write a P25 TDU w/ link control channel release packet.
/// </summary>
/// <param name="grp"></param>
/// <param name="srcId"></param>
/// <param name="dstId"></param>
void Trunk::writeRF_TDULC_ChanRelease(bool grp, uint32_t srcId, uint32_t dstId)
{
if (!m_p25->m_duplex) {
return;
}
uint32_t count = m_p25->m_hangCount / 2;
if (m_p25->m_voiceOnControl) {
count = count / 2;
}
std::unique_ptr<lc::TDULC> lc = nullptr;
if (m_p25->m_control) {
for (uint32_t i = 0; i < count; i++) {
if ((srcId != 0U) && (dstId != 0U)) {
if (grp) {
lc = new_unique(lc::tdulc::LC_GROUP);
} else {
lc = new_unique(lc::tdulc::LC_PRIVATE);
}
lc->setSrcId(srcId);
lc->setDstId(dstId);
lc->setEmergency(false);
writeRF_TDULC(lc.get(), true);
}
lc = new_unique(lc::tdulc::LC_NET_STS_BCAST);
writeRF_TDULC(lc.get(), true);
lc = new_unique(lc::tdulc::LC_RFSS_STS_BCAST);
writeRF_TDULC(lc.get(), true);
}
}
if (m_verbose) {
LogMessage(LOG_RF, P25_TDULC_STR ", LC_CALL_TERM (Call Termination), srcId = %u, dstId = %u", srcId, dstId);
}
lc = new_unique(lc::tdulc::LC_CALL_TERM);
writeRF_TDULC(lc.get(), true);
if (m_p25->m_control) {
writeNet_TSDU_Call_Term(srcId, dstId);
}
}
/// <summary>
/// Helper to write a single-block P25 TSDU packet.
/// </summary>
@ -1603,9 +1395,9 @@ void Trunk::writeRF_TDULC_ChanRelease(bool grp, uint32_t srcId, uint32_t dstId)
/// <param name="clearBeforeWrite"></param>
/// <param name="force"></param>
/// <param name="imm"></param>
void Trunk::writeRF_TSDU_SBF(lc::TSBK* tsbk, bool noNetwork, bool clearBeforeWrite, bool force, bool imm)
void ControlSignaling::writeRF_TSDU_SBF(lc::TSBK* tsbk, bool noNetwork, bool clearBeforeWrite, bool force, bool imm)
{
if (!m_p25->m_control)
if (!m_p25->m_enableControl)
return;
assert(tsbk != nullptr);
@ -1674,7 +1466,7 @@ void Trunk::writeRF_TSDU_SBF(lc::TSBK* tsbk, bool noNetwork, bool clearBeforeWri
/// Helper to write a network single-block P25 TSDU packet.
/// </summary>
/// <param name="tsbk"></param>
void Trunk::writeNet_TSDU(lc::TSBK* tsbk)
void ControlSignaling::writeNet_TSDU(lc::TSBK* tsbk)
{
assert(tsbk != nullptr);
@ -1702,8 +1494,8 @@ void Trunk::writeNet_TSDU(lc::TSBK* tsbk)
m_p25->addFrame(buffer, P25_TSDU_FRAME_LENGTH_BYTES + 2U, true);
if (m_network != nullptr)
m_network->resetP25();
if (m_p25->m_network != nullptr)
m_p25->m_network->resetP25();
}
/// <summary>
@ -1711,9 +1503,9 @@ void Trunk::writeNet_TSDU(lc::TSBK* tsbk)
/// </summary>
/// <param name="tsbk"></param>
/// <param name="clearBeforeWrite"></param>
void Trunk::writeRF_TSDU_MBF(lc::TSBK* tsbk, bool clearBeforeWrite)
void ControlSignaling::writeRF_TSDU_MBF(lc::TSBK* tsbk, bool clearBeforeWrite)
{
if (!m_p25->m_control) {
if (!m_p25->m_enableControl) {
::memset(m_rfMBF, 0x00U, P25_MAX_PDU_COUNT * P25_LDU_FRAME_LENGTH_BYTES + 2U);
m_mbfCnt = 0U;
return;
@ -1832,9 +1624,9 @@ void Trunk::writeRF_TSDU_MBF(lc::TSBK* tsbk, bool clearBeforeWrite)
/// </summary>
/// <param name="ambt"></param>
/// <param name="clearBeforeWrite"></param>
void Trunk::writeRF_TSDU_AMBT(lc::AMBT* ambt, bool clearBeforeWrite)
void ControlSignaling::writeRF_TSDU_AMBT(lc::AMBT* ambt, bool clearBeforeWrite)
{
if (!m_p25->m_control)
if (!m_p25->m_enableControl)
return;
assert(ambt != nullptr);
@ -1862,13 +1654,219 @@ void Trunk::writeRF_TSDU_AMBT(lc::AMBT* ambt, bool clearBeforeWrite)
m_p25->m_data->writeRF_PDU_User(header, pduUserData, clearBeforeWrite);
}
/// <summary>
/// Helper to write a P25 TDU w/ link control channel release packet.
/// </summary>
/// <param name="grp"></param>
/// <param name="srcId"></param>
/// <param name="dstId"></param>
void ControlSignaling::writeRF_TDULC_ChanRelease(bool grp, uint32_t srcId, uint32_t dstId)
{
if (!m_p25->m_duplex) {
return;
}
uint32_t count = m_p25->m_hangCount / 2;
if (m_p25->m_voiceOnControl) {
count = count / 2;
}
std::unique_ptr<lc::TDULC> lc = nullptr;
if (m_p25->m_enableControl) {
for (uint32_t i = 0; i < count; i++) {
if ((srcId != 0U) && (dstId != 0U)) {
if (grp) {
lc = new_unique(lc::tdulc::LC_GROUP);
} else {
lc = new_unique(lc::tdulc::LC_PRIVATE);
}
lc->setSrcId(srcId);
lc->setDstId(dstId);
lc->setEmergency(false);
writeRF_TDULC(lc.get(), true);
}
lc = new_unique(lc::tdulc::LC_NET_STS_BCAST);
writeRF_TDULC(lc.get(), true);
lc = new_unique(lc::tdulc::LC_RFSS_STS_BCAST);
writeRF_TDULC(lc.get(), true);
}
}
if (m_verbose) {
LogMessage(LOG_RF, P25_TDULC_STR ", LC_CALL_TERM (Call Termination), srcId = %u, dstId = %u", srcId, dstId);
}
lc = new_unique(lc::tdulc::LC_CALL_TERM);
writeRF_TDULC(lc.get(), true);
if (m_p25->m_enableControl) {
writeNet_TSDU_Call_Term(srcId, dstId);
}
}
/// <summary>
/// Helper to write control channel packet data.
/// </summary>
/// <param name="frameCnt"></param>
/// <param name="n"></param>
/// <param name="adjSS"></param>
void ControlSignaling::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adjSS)
{
if (!m_p25->m_enableControl)
return;
if (m_convFallback) {
bool fallbackTx = (frameCnt % 253U) == 0U;
if (fallbackTx && n == 8U) {
if (m_convFallbackPacketDelay >= CONV_FALLBACK_PACKET_DELAY) {
std::unique_ptr<lc::tdulc::LC_CONV_FALLBACK> lc = new_unique(lc::tdulc::LC_CONV_FALLBACK);
for (uint8_t i = 0U; i < 3U; i++) {
writeRF_TDULC(lc.get(), true);
}
m_convFallbackPacketDelay = 0U;
} else {
m_convFallbackPacketDelay++;
}
}
else {
if (n == 8U) {
std::unique_ptr<lc::tdulc::LC_FAILSOFT> lc = new_unique(lc::tdulc::LC_FAILSOFT);
writeRF_TDULC(lc.get(), true);
}
}
return;
}
if (m_debug) {
LogDebug(LOG_P25, "writeRF_ControlData, mbfCnt = %u, frameCnt = %u, seq = %u, adjSS = %u", m_mbfCnt, frameCnt, n, adjSS);
}
// bryanb: this is just a simple counter because we treat the SYNC_BCST as unlocked
m_microslotCount++;
if (m_microslotCount > 7999U)
m_microslotCount = 0;
bool forcePad = false;
bool alt = (frameCnt % 2U) > 0U;
switch (n)
{
/** required data */
case 0:
default:
queueRF_TSBK_Ctrl(TSBK_OSP_IDEN_UP);
break;
case 1:
if (alt)
queueRF_TSBK_Ctrl(TSBK_OSP_RFSS_STS_BCAST);
else
queueRF_TSBK_Ctrl(TSBK_OSP_NET_STS_BCAST);
break;
case 2:
if (alt)
queueRF_TSBK_Ctrl(TSBK_OSP_NET_STS_BCAST);
else
queueRF_TSBK_Ctrl(TSBK_OSP_RFSS_STS_BCAST);
break;
case 3:
if (alt)
queueRF_TSBK_Ctrl(TSBK_OSP_RFSS_STS_BCAST);
else
queueRF_TSBK_Ctrl(TSBK_OSP_NET_STS_BCAST);
break;
case 4:
queueRF_TSBK_Ctrl(TSBK_OSP_SYNC_BCAST);
break;
/** update data */
case 5:
if (m_p25->m_affiliations.grantSize() > 0) {
queueRF_TSBK_Ctrl(TSBK_OSP_GRP_VCH_GRANT_UPD);
}
break;
/** extra data */
case 6:
queueRF_TSBK_Ctrl(TSBK_OSP_SNDCP_CH_ANN);
break;
case 7:
// write ADJSS
if (adjSS && m_adjSiteTable.size() > 0) {
queueRF_TSBK_Ctrl(TSBK_OSP_ADJ_STS_BCAST);
break;
} else {
forcePad = true;
}
break;
case 8:
// write SCCB
if (adjSS && m_sccbTable.size() > 0) {
queueRF_TSBK_Ctrl(TSBK_OSP_SCCB_EXP);
break;
}
break;
}
// are we transmitting the time/date annoucement?
bool timeDateAnn = (frameCnt % 64U) == 0U;
if (m_ctrlTimeDateAnn && timeDateAnn && n > 4U) {
queueRF_TSBK_Ctrl(TSBK_OSP_TIME_DATE_ANN);
}
// should we insert the BSI bursts?
bool bsi = (frameCnt % 127U) == 0U;
if (bsi && n > 4U) {
queueRF_TSBK_Ctrl(TSBK_OSP_MOT_CC_BSI);
}
// should we insert the Git Hash burst?
bool hash = (frameCnt % 125U) == 0U;
if (hash && n > 4U) {
queueRF_TSBK_Ctrl(TSBK_OSP_DVM_GIT_HASH);
}
// add padding after the last sequence or if forced; and only
// if we're doing multiblock frames (MBF)
if ((n >= 4U || forcePad) && m_ctrlTSDUMBF)
{
// pad MBF if we have 1 queued TSDUs
if (m_mbfCnt == 1U) {
queueRF_TSBK_Ctrl(TSBK_OSP_RFSS_STS_BCAST);
queueRF_TSBK_Ctrl(TSBK_OSP_NET_STS_BCAST);
if (m_debug) {
LogDebug(LOG_P25, "writeRF_ControlData, have 1 pad 2, mbfCnt = %u", m_mbfCnt);
}
}
// pad MBF if we have 2 queued TSDUs
if (m_mbfCnt == 2U) {
std::vector<::lookups::IdenTable> entries = m_p25->m_idenTable->list();
if (entries.size() > 1U) {
queueRF_TSBK_Ctrl(TSBK_OSP_IDEN_UP);
}
else {
queueRF_TSBK_Ctrl(TSBK_OSP_RFSS_STS_BCAST);
}
if (m_debug) {
LogDebug(LOG_P25, "writeRF_ControlData, have 2 pad 1, mbfCnt = %u", m_mbfCnt);
}
}
// reset MBF count
m_mbfCnt = 0U;
}
}
/// <summary>
/// Helper to generate the given control TSBK into the TSDU frame queue.
/// </summary>
/// <param name="lco"></param>
void Trunk::queueRF_TSBK_Ctrl(uint8_t lco)
void ControlSignaling::queueRF_TSBK_Ctrl(uint8_t lco)
{
if (!m_p25->m_control)
if (!m_p25->m_enableControl)
return;
std::unique_ptr<lc::TSBK> tsbk;
@ -2122,7 +2120,7 @@ void Trunk::queueRF_TSBK_Ctrl(uint8_t lco)
/// <param name="skip"></param>
/// <param name="chNo"></param>
/// <returns></returns>
bool Trunk::writeRF_TSDU_Grant(uint32_t srcId, uint32_t dstId, uint8_t serviceOptions, bool grp, bool net, bool skip, uint32_t chNo)
bool ControlSignaling::writeRF_TSDU_Grant(uint32_t srcId, uint32_t dstId, uint8_t serviceOptions, bool grp, bool net, bool skip, uint32_t chNo)
{
bool emergency = ((serviceOptions & 0xFFU) & 0x80U) == 0x80U; // Emergency Flag
bool encryption = ((serviceOptions & 0xFFU) & 0x40U) == 0x40U; // Encryption Flag
@ -2394,7 +2392,7 @@ bool Trunk::writeRF_TSDU_Grant(uint32_t srcId, uint32_t dstId, uint8_t serviceOp
/// <param name="skip"></param>
/// <param name="net"></param>
/// <returns></returns>
bool Trunk::writeRF_TSDU_SNDCP_Grant(uint32_t srcId, uint32_t dstId, bool skip, bool net)
bool ControlSignaling::writeRF_TSDU_SNDCP_Grant(uint32_t srcId, uint32_t dstId, bool skip, bool net)
{
std::unique_ptr<OSP_SNDCP_CH_GNT> osp = new_unique(OSP_SNDCP_CH_GNT);
osp->setMFId(m_lastMFID);
@ -2468,7 +2466,7 @@ bool Trunk::writeRF_TSDU_SNDCP_Grant(uint32_t srcId, uint32_t dstId, bool skip,
/// </summary>
/// <param name="srcId"></param>
/// <param name="dstId"></param>
void Trunk::writeRF_TSDU_UU_Ans_Req(uint32_t srcId, uint32_t dstId)
void ControlSignaling::writeRF_TSDU_UU_Ans_Req(uint32_t srcId, uint32_t dstId)
{
std::unique_ptr<IOSP_UU_ANS> iosp = new_unique(IOSP_UU_ANS);
iosp->setMFId(m_lastMFID);
@ -2485,7 +2483,7 @@ void Trunk::writeRF_TSDU_UU_Ans_Req(uint32_t srcId, uint32_t dstId)
/// <param name="srcId"></param>
/// <param name="service"></param>
/// <param name="noNetwork"></param>
void Trunk::writeRF_TSDU_ACK_FNE(uint32_t srcId, uint32_t service, bool extended, bool noNetwork)
void ControlSignaling::writeRF_TSDU_ACK_FNE(uint32_t srcId, uint32_t service, bool extended, bool noNetwork)
{
std::unique_ptr<IOSP_ACK_RSP> iosp = new_unique(IOSP_ACK_RSP);
iosp->setSrcId(srcId);
@ -2511,7 +2509,7 @@ void Trunk::writeRF_TSDU_ACK_FNE(uint32_t srcId, uint32_t service, bool extended
/// <param name="reason"></param>
/// <param name="service"></param>
/// <param name="aiv"></param>
void Trunk::writeRF_TSDU_Deny(uint32_t srcId, uint32_t dstId, uint8_t reason, uint8_t service, bool aiv)
void ControlSignaling::writeRF_TSDU_Deny(uint32_t srcId, uint32_t dstId, uint8_t reason, uint8_t service, bool aiv)
{
std::unique_ptr<OSP_DENY_RSP> osp = new_unique(OSP_DENY_RSP);
osp->setAIV(aiv);
@ -2533,7 +2531,7 @@ void Trunk::writeRF_TSDU_Deny(uint32_t srcId, uint32_t dstId, uint8_t reason, ui
/// </summary>
/// <param name="srcId"></param>
/// <param name="dstId"></param>
bool Trunk::writeRF_TSDU_Grp_Aff_Rsp(uint32_t srcId, uint32_t dstId)
bool ControlSignaling::writeRF_TSDU_Grp_Aff_Rsp(uint32_t srcId, uint32_t dstId)
{
bool ret = false;
@ -2592,7 +2590,7 @@ bool Trunk::writeRF_TSDU_Grp_Aff_Rsp(uint32_t srcId, uint32_t dstId)
/// </summary>
/// <param name="srcId"></param>
/// <param name="sysId"></param>
void Trunk::writeRF_TSDU_U_Reg_Rsp(uint32_t srcId, uint32_t sysId)
void ControlSignaling::writeRF_TSDU_U_Reg_Rsp(uint32_t srcId, uint32_t sysId)
{
std::unique_ptr<IOSP_U_REG> iosp = new_unique(IOSP_U_REG);
iosp->setMFId(m_lastMFID);
@ -2639,7 +2637,7 @@ void Trunk::writeRF_TSDU_U_Reg_Rsp(uint32_t srcId, uint32_t sysId)
/// Helper to write a unit de-registration acknowledge packet.
/// </summary>
/// <param name="srcId"></param>
void Trunk::writeRF_TSDU_U_Dereg_Ack(uint32_t srcId)
void ControlSignaling::writeRF_TSDU_U_Dereg_Ack(uint32_t srcId)
{
bool dereged = false;
@ -2670,7 +2668,7 @@ void Trunk::writeRF_TSDU_U_Dereg_Ack(uint32_t srcId)
/// <param name="service"></param>
/// <param name="aiv"></param>
/// <param name="grp"></param>
void Trunk::writeRF_TSDU_Queue(uint32_t srcId, uint32_t dstId, uint8_t reason, uint8_t service, bool aiv, bool grp)
void ControlSignaling::writeRF_TSDU_Queue(uint32_t srcId, uint32_t dstId, uint8_t reason, uint8_t service, bool aiv, bool grp)
{
std::unique_ptr<OSP_QUE_RSP> osp = new_unique(OSP_QUE_RSP);
osp->setAIV(aiv);
@ -2694,7 +2692,7 @@ void Trunk::writeRF_TSDU_Queue(uint32_t srcId, uint32_t dstId, uint8_t reason, u
/// <param name="srcId"></param>
/// <param name="dstId"></param>
/// <param name="group"></param>
bool Trunk::writeRF_TSDU_Loc_Reg_Rsp(uint32_t srcId, uint32_t dstId, bool grp)
bool ControlSignaling::writeRF_TSDU_Loc_Reg_Rsp(uint32_t srcId, uint32_t dstId, bool grp)
{
bool ret = false;
@ -2751,7 +2749,7 @@ bool Trunk::writeRF_TSDU_Loc_Reg_Rsp(uint32_t srcId, uint32_t dstId, bool grp)
/// </summary>
/// <param name="srcId"></param>
/// <param name="dstId"></param>
bool Trunk::writeNet_TSDU_Call_Term(uint32_t srcId, uint32_t dstId)
bool ControlSignaling::writeNet_TSDU_Call_Term(uint32_t srcId, uint32_t dstId)
{
// is the specified channel granted?
if (m_p25->m_affiliations.isGranted(dstId)) {
@ -2773,7 +2771,7 @@ bool Trunk::writeNet_TSDU_Call_Term(uint32_t srcId, uint32_t dstId)
/// </summary>
/// <paran name="tsbk"></param>
/// <param name="data"></param>
void Trunk::writeNet_TSDU_From_RF(lc::TSBK* tsbk, uint8_t* data)
void ControlSignaling::writeNet_TSDU_From_RF(lc::TSBK* tsbk, uint8_t* data)
{
assert(tsbk != nullptr);
assert(data != nullptr);
@ -2801,7 +2799,7 @@ void Trunk::writeNet_TSDU_From_RF(lc::TSBK* tsbk, uint8_t* data)
/// Helper to automatically inhibit a source ID on a denial.
/// </summary>
/// <param name="srcId"></param>
void Trunk::denialInhibit(uint32_t srcId)
void ControlSignaling::denialInhibit(uint32_t srcId)
{
if (!m_p25->m_inhibitUnauth) {
return;
@ -2821,7 +2819,7 @@ void Trunk::denialInhibit(uint32_t srcId)
/// <param name="length"></param>
/// <param name="b1"></param>
/// <param name="b2"></param>
void Trunk::addIdleBits(uint8_t* data, uint32_t length, bool b1, bool b2)
void ControlSignaling::addIdleBits(uint8_t* data, uint32_t length, bool b1, bool b2)
{
assert(data != nullptr);

@ -23,8 +23,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if !defined(__P25_PACKET_TRUNK_H__)
#define __P25_PACKET_TRUNK_H__
#if !defined(__P25_PACKET_CONTROL_SIGNALING_H__)
#define __P25_PACKET_CONTROL_SIGNALING_H__
#include "Defines.h"
#include "p25/data/DataHeader.h"
@ -33,7 +33,6 @@
#include "p25/lc/AMBT.h"
#include "p25/lc/TDULC.h"
#include "p25/Control.h"
#include "network/BaseNetwork.h"
#include "Timer.h"
#include <cstdio>
@ -56,10 +55,10 @@ namespace p25
{
// ---------------------------------------------------------------------------
// Class Declaration
// This class implements handling logic for P25 trunking packets.
// This class implements handling logic for P25 TSDU and TDULC packets.
// ---------------------------------------------------------------------------
class HOST_SW_API Trunk {
class HOST_SW_API ControlSignaling {
public:
/// <summary>Process a data frame from the RF interface.</summary>
virtual bool process(uint8_t* data, uint32_t len, std::unique_ptr<lc::TSBK> preDecodedTSBK = nullptr);
@ -108,8 +107,6 @@ namespace p25
Control* m_p25;
friend class lookups::P25AffiliationLookup;
network::BaseNetwork* m_network;
uint32_t m_patchSuperGroup;
uint32_t m_announcementGroup;
@ -157,25 +154,20 @@ namespace p25
bool m_verbose;
bool m_debug;
/// <summary>Initializes a new instance of the Trunk class.</summary>
Trunk(Control* p25, network::BaseNetwork* network, bool dumpTSBKData, bool debug, bool verbose);
/// <summary>Finalizes a instance of the Trunk class.</summary>
virtual ~Trunk();
/// <summary>Initializes a new instance of the ControlSignaling class.</summary>
ControlSignaling(Control* p25, bool dumpTSBKData, bool debug, bool verbose);
/// <summary>Finalizes a instance of the ControlSignaling class.</summary>
virtual ~ControlSignaling();
/// <summary>Write data processed from RF to the network.</summary>
void writeNetworkRF(lc::TSBK* tsbk, const uint8_t* data, bool autoReset);
/// <summary>Write data processed from RF to the network.</summary>
void writeNetworkRF(lc::TDULC* tduLc, const uint8_t* data, bool autoReset);
/// <summary>Helper to write control channel packet data.</summary>
void writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adjSS);
/// <summary>Helper to write a P25 TDU w/ link control packet.</summary>
virtual void writeRF_TDULC(lc::TDULC* lc, bool noNetwork);
/// <summary>Helper to write a network P25 TDU w/ link control packet.</summary>
virtual void writeNet_TDULC(lc::TDULC* lc);
/// <summary>Helper to write a P25 TDU w/ link control channel release packet.</summary>
void writeRF_TDULC_ChanRelease(bool grp, uint32_t srcId, uint32_t dstId);
/// <summary>Helper to write a immediate single-block P25 TSDU packet.</summary>
virtual void writeRF_TSDU_SBF_Imm(lc::TSBK *tsbk, bool noNetwork) { writeRF_TSDU_SBF(tsbk, noNetwork, false, false, true); }
@ -185,9 +177,15 @@ namespace p25
virtual void writeNet_TSDU(lc::TSBK* tsbk);
/// <summary>Helper to write a multi-block (3-block) P25 TSDU packet.</summary>
void writeRF_TSDU_MBF(lc::TSBK* tsbk, bool clearBeforeWrite = false);
/// <summary>Helper to write a alternate multi-block trunking PDU packet.</summary>
/// <summary>Helper to write a alternate multi-block ControlSignalinging PDU packet.</summary>
virtual void writeRF_TSDU_AMBT(lc::AMBT* ambt, bool clearBeforeWrite = false);
/// <summary>Helper to write a P25 TDU w/ link control channel release packet.</summary>
void writeRF_TDULC_ChanRelease(bool grp, uint32_t srcId, uint32_t dstId);
/// <summary>Helper to write control channel packet data.</summary>
void writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adjSS);
/// <summary>Helper to generate the given control TSBK into the TSDU frame queue.</summary>
void queueRF_TSBK_Ctrl(uint8_t lco);
@ -227,4 +225,4 @@ namespace p25
} // namespace packet
} // namespace p25
#endif // __P25_PACKET_TRUNK_H__
#endif // __P25_PACKET_CONTROL_SIGNALING_H__

@ -31,7 +31,7 @@
#include "Defines.h"
#include "p25/P25Defines.h"
#include "p25/packet/Data.h"
#include "p25/packet/Trunk.h"
#include "p25/packet/ControlSignaling.h"
#include "p25/acl/AccessControl.h"
#include "p25/P25Utils.h"
#include "p25/Sync.h"
@ -410,7 +410,7 @@ bool Data::process(uint8_t* data, uint32_t len)
m_rfDataHeader.getAMBTOpcode(), m_rfDataHeader.getBlocksToFollow());
}
m_p25->m_trunk->processMBT(m_rfDataHeader, m_rfData);
m_p25->m_control->processMBT(m_rfDataHeader, m_rfData);
}
break;
default:
@ -802,14 +802,12 @@ void Data::clock(uint32_t ms)
/// Initializes a new instance of the Data class.
/// </summary>
/// <param name="p25">Instance of the Control class.</param>
/// <param name="network">Instance of the BaseNetwork class.</param>
/// <param name="dumpPDUData"></param>
/// <param name="repeatPDU"></param>
/// <param name="debug">Flag indicating whether P25 debug is enabled.</param>
/// <param name="verbose">Flag indicating whether P25 verbose logging is enabled.</param>
Data::Data(Control* p25, network::BaseNetwork* network, bool dumpPDUData, bool repeatPDU, bool debug, bool verbose) :
Data::Data(Control* p25, bool dumpPDUData, bool repeatPDU, bool debug, bool verbose) :
m_p25(p25),
m_network(network),
m_prevRfState(RS_RF_LISTENING),
m_rfData(nullptr),
m_rfDataHeader(),
@ -879,7 +877,7 @@ void Data::writeNetwork(const uint8_t currentBlock, const uint8_t *data, uint32_
{
assert(data != nullptr);
if (m_network == nullptr)
if (m_p25->m_network == nullptr)
return;
if (m_p25->m_rfTimeout.isRunning() && m_p25->m_rfTimeout.hasExpired())
@ -887,7 +885,7 @@ void Data::writeNetwork(const uint8_t currentBlock, const uint8_t *data, uint32_
// Utils::dump(1U, "Outgoing Network PDU Frame", data, len);
m_network->writeP25PDU(m_rfDataHeader, currentBlock, data, len);
m_p25->m_network->writeP25PDU(m_rfDataHeader, currentBlock, data, len);
}
/// <summary>

@ -37,7 +37,6 @@
#include "p25/data/LowSpeedData.h"
#include "p25/lc/LC.h"
#include "p25/Control.h"
#include "network/BaseNetwork.h"
#include "Timer.h"
#include <cstdio>
@ -83,8 +82,6 @@ namespace p25
friend class p25::Control;
Control* m_p25;
network::BaseNetwork* m_network;
RPT_RF_STATE m_prevRfState;
data::DataBlock* m_rfData;
@ -122,7 +119,7 @@ namespace p25
bool m_debug;
/// <summary>Initializes a new instance of the Data class.</summary>
Data(Control* p25, network::BaseNetwork* network, bool dumpPDUData, bool repeatPDU, bool debug, bool verbose);
Data(Control* p25, bool dumpPDUData, bool repeatPDU, bool debug, bool verbose);
/// <summary>Finalizes a instance of the Data class.</summary>
~Data();

@ -31,7 +31,7 @@
#include "Defines.h"
#include "p25/P25Defines.h"
#include "p25/packet/Voice.h"
#include "p25/packet/Trunk.h"
#include "p25/packet/ControlSignaling.h"
#include "p25/acl/AccessControl.h"
#include "p25/dfsi/DFSIDefines.h"
#include "p25/lc/tdulc/TDULCFactory.h"
@ -189,8 +189,8 @@ bool Voice::process(uint8_t* data, uint32_t len)
}
resetNet();
if (m_network != nullptr)
m_network->resetP25();
if (m_p25->m_network != nullptr)
m_p25->m_network->resetP25();
if (m_p25->m_duplex) {
m_p25->writeRF_TDU(true);
@ -232,9 +232,9 @@ bool Voice::process(uint8_t* data, uint32_t len)
resetNet();
}
if (m_p25->m_control) {
if (m_p25->m_enableControl) {
if (!m_p25->m_ccRunning && m_p25->m_voiceOnControl) {
m_p25->m_trunk->writeRF_ControlData(255U, 0U, false);
m_p25->m_control->writeRF_ControlData(255U, 0U, false);
}
}
@ -281,8 +281,8 @@ bool Voice::process(uint8_t* data, uint32_t len)
}
resetNet();
if (m_network != nullptr)
m_network->resetP25();
if (m_p25->m_network != nullptr)
m_p25->m_network->resetP25();
if (m_p25->m_duplex) {
m_p25->writeRF_TDU(true);
@ -296,9 +296,9 @@ bool Voice::process(uint8_t* data, uint32_t len)
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(srcId, dstId, P25_DENY_RSN_REQ_UNIT_NOT_VALID, (group ? TSBK_IOSP_GRP_VCH : TSBK_IOSP_UU_VCH));
m_p25->m_trunk->denialInhibit(srcId);
if (m_p25->m_enableControl) {
m_p25->m_control->writeRF_TSDU_Deny(srcId, dstId, P25_DENY_RSN_REQ_UNIT_NOT_VALID, (group ? TSBK_IOSP_GRP_VCH : TSBK_IOSP_UU_VCH));
m_p25->m_control->denialInhibit(srcId);
}
::ActivityLog("P25", true, "RF voice rejection from %u to %s%u ", srcId, group ? "TG " : "", dstId);
@ -318,8 +318,8 @@ bool Voice::process(uint8_t* data, uint32_t len)
if (!acl::AccessControl::validateSrcId(dstId)) {
if (m_lastRejectId == 0 || m_lastRejectId != dstId) {
LogWarning(LOG_RF, P25_HDU_STR " denial, RID rejection, dstId = %u", dstId);
if (m_p25->m_control) {
m_p25->m_trunk->writeRF_TSDU_Deny(srcId, dstId, P25_DENY_RSN_TGT_UNIT_NOT_VALID, TSBK_IOSP_UU_VCH);
if (m_p25->m_enableControl) {
m_p25->m_control->writeRF_TSDU_Deny(srcId, dstId, P25_DENY_RSN_TGT_UNIT_NOT_VALID, TSBK_IOSP_UU_VCH);
}
::ActivityLog("P25", true, "RF voice rejection from %u to %s%u ", srcId, group ? "TG " : "", dstId);
@ -338,8 +338,8 @@ bool Voice::process(uint8_t* data, uint32_t len)
if (!acl::AccessControl::validateTGId(dstId)) {
if (m_lastRejectId == 0 || m_lastRejectId != dstId) {
LogWarning(LOG_RF, P25_HDU_STR " denial, TGID rejection, dstId = %u", dstId);
if (m_p25->m_control) {
m_p25->m_trunk->writeRF_TSDU_Deny(srcId, dstId, P25_DENY_RSN_TGT_GROUP_NOT_VALID, TSBK_IOSP_GRP_VCH);
if (m_p25->m_enableControl) {
m_p25->m_control->writeRF_TSDU_Deny(srcId, dstId, P25_DENY_RSN_TGT_GROUP_NOT_VALID, TSBK_IOSP_GRP_VCH);
}
::ActivityLog("P25", true, "RF voice rejection from %u to %s%u ", srcId, group ? "TG " : "", dstId);
@ -356,12 +356,12 @@ bool Voice::process(uint8_t* data, uint32_t len)
// verify the source RID is affiliated to the group TGID; only if control data
// is supported
if (group && m_p25->m_control) {
if (!m_p25->m_affiliations.isGroupAff(srcId, dstId) && m_p25->m_trunk->m_verifyAff) {
if (group && m_p25->m_enableControl) {
if (!m_p25->m_affiliations.isGroupAff(srcId, dstId) && m_p25->m_control->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(srcId, dstId, P25_DENY_RSN_REQ_UNIT_NOT_AUTH, TSBK_IOSP_GRP_VCH);
m_p25->m_trunk->writeRF_TSDU_U_Reg_Cmd(srcId);
m_p25->m_control->writeRF_TSDU_Deny(srcId, dstId, P25_DENY_RSN_REQ_UNIT_NOT_AUTH, TSBK_IOSP_GRP_VCH);
m_p25->m_control->writeRF_TSDU_U_Reg_Cmd(srcId);
::ActivityLog("P25", true, "RF voice rejection from %u to %s%u ", srcId, group ? "TG " : "", dstId);
m_lastRejectId = srcId;
@ -385,20 +385,20 @@ bool Voice::process(uint8_t* data, uint32_t len)
(m_rfLC.getEncrypted() ? 0x40U : 0x00U) + // Encrypted Flag
(m_rfLC.getPriority() & 0x07U); // Priority
if (m_p25->m_control) {
if (m_p25->m_enableControl) {
// if the group wasn't granted out -- explicitly grant the group
if (!m_p25->m_affiliations.isGranted(dstId)) {
if (m_p25->m_legacyGroupGrnt) {
// are we auto-registering legacy radios to groups?
if (m_p25->m_legacyGroupReg && group) {
if (!m_p25->m_affiliations.isGroupAff(srcId, dstId)) {
if (!m_p25->m_trunk->writeRF_TSDU_Grp_Aff_Rsp(srcId, dstId)) {
if (!m_p25->m_control->writeRF_TSDU_Grp_Aff_Rsp(srcId, dstId)) {
return false;
}
}
}
if (!m_p25->m_trunk->writeRF_TSDU_Grant(srcId, dstId, serviceOptions, group)) {
if (!m_p25->m_control->writeRF_TSDU_Grant(srcId, dstId, serviceOptions, group)) {
return false;
}
}
@ -409,8 +409,8 @@ bool Voice::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_trunk->writeRF_TSDU_Grant(srcId, dstId, serviceOptions, group, true, true);
if (m_p25->m_enableControl && m_p25->m_voiceOnControl) {
m_p25->m_control->writeRF_TSDU_Grant(srcId, dstId, serviceOptions, group, true, true);
}
m_hadVoice = true;
@ -527,7 +527,7 @@ bool Voice::process(uint8_t* data, uint32_t len)
alreadyDecoded = false;
if (m_p25->m_control) {
if (m_p25->m_enableControl) {
m_p25->m_affiliations.touchGrant(m_rfLC.getDstId());
}
@ -536,7 +536,7 @@ bool Voice::process(uint8_t* data, uint32_t len)
}
// single-channel trunking or voice on control support?
if (m_p25->m_control && m_p25->m_voiceOnControl) {
if (m_p25->m_enableControl && m_p25->m_voiceOnControl) {
// per TIA-102.AABD-B transmit RFSS_STS_BCAST every 3 superframes (e.g. every 3 LDU1s)
m_vocLDU1Count++;
if (m_vocLDU1Count > VOC_LDU1_COUNT) {
@ -719,7 +719,7 @@ bool Voice::process(uint8_t* data, uint32_t len)
}
}
else if (duid == P25_DUID_TDU || duid == P25_DUID_TDULC) {
if (!m_p25->m_control) {
if (!m_p25->m_enableControl) {
m_p25->m_affiliations.releaseGrant(m_rfLC.getDstId(), false);
m_p25->notifyCC_ReleaseGrant(m_rfLC.getDstId());
}
@ -737,7 +737,7 @@ bool Voice::process(uint8_t* data, uint32_t len)
LogWarning(LOG_RF, P25_TDULC_STR ", undecodable TDULC");
}
else {
m_p25->m_trunk->writeRF_TDULC(tdulc.get(), false);
m_p25->m_control->writeRF_TDULC(tdulc.get(), false);
}
}
@ -761,7 +761,7 @@ bool Voice::process(uint8_t* data, uint32_t len)
}
else {
m_p25->m_tailOnIdle = true;
m_p25->m_trunk->writeNet_TSDU_Call_Term(m_rfLC.getSrcId(), m_rfLC.getDstId());
m_p25->m_control->writeNet_TSDU_Call_Term(m_rfLC.getSrcId(), m_rfLC.getDstId());
}
}
@ -794,8 +794,8 @@ bool Voice::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L
if (m_p25->m_rfLastDstId != 0U && dstId != 0U) {
if (m_p25->m_rfLastDstId != dstId && (m_p25->m_rfTGHang.isRunning() && !m_p25->m_rfTGHang.hasExpired())) {
resetNet();
if (m_network != nullptr)
m_network->resetP25();
if (m_p25->m_network != nullptr)
m_p25->m_network->resetP25();
return false;
}
@ -823,16 +823,16 @@ bool Voice::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L
LogWarning(LOG_RF, "Traffic collision detect, preempting new network 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);
resetNet();
if (m_network != nullptr)
m_network->resetP25();
if (m_p25->m_network != nullptr)
m_p25->m_network->resetP25();
return false;
}
else {
LogWarning(LOG_RF, "Traffic collision detect, preempting new network traffic to existing RF traffic, rfDstId = %u, netDstId = %u", m_rfLC.getDstId(),
dstId);
resetNet();
if (m_network != nullptr)
m_network->resetP25();
if (m_p25->m_network != nullptr)
m_p25->m_network->resetP25();
return false;
}
}
@ -842,8 +842,8 @@ bool Voice::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L
if (!m_p25->m_authoritative && m_p25->m_permittedDstId != dstId) {
LogWarning(LOG_NET, "[NON-AUTHORITATIVE] Ignoring network traffic, destination not permitted, dstId = %u", dstId);
resetNet();
if (m_network != nullptr)
m_network->resetP25();
if (m_p25->m_network != nullptr)
m_p25->m_network->resetP25();
return false;
}
@ -905,7 +905,7 @@ bool Voice::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L
// save MI to member variable before writing to RF
control.getMI(m_lastMI);
if (m_p25->m_control) {
if (m_p25->m_enableControl) {
lc::LC control = lc::LC(*m_dfsiLC.control());
m_p25->m_affiliations.touchGrant(control.getDstId());
}
@ -974,7 +974,7 @@ bool Voice::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L
m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 204U);
count += dfsi::P25_DFSI_LDU2_VOICE18_FRAME_LENGTH_BYTES;
if (m_p25->m_control) {
if (m_p25->m_enableControl) {
lc::LC control = lc::LC(*m_dfsiLC.control());
m_p25->m_affiliations.touchGrant(control.getDstId());
}
@ -1021,7 +1021,7 @@ bool Voice::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L
return false;
}
if (!m_p25->m_control) {
if (!m_p25->m_enableControl) {
m_p25->m_affiliations.releaseGrant(m_netLC.getDstId(), false);
m_p25->notifyCC_ReleaseGrant(m_netLC.getDstId());
}
@ -1046,12 +1046,10 @@ bool Voice::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L
/// Initializes a new instance of the Voice class.
/// </summary>
/// <param name="p25">Instance of the Control class.</param>
/// <param name="network">Instance of the BaseNetwork class.</param>
/// <param name="debug">Flag indicating whether P25 debug is enabled.</param>
/// <param name="verbose">Flag indicating whether P25 verbose logging is enabled.</param>
Voice::Voice(Control* p25, network::BaseNetwork* network, bool debug, bool verbose) :
Voice::Voice(Control* p25, bool debug, bool verbose) :
m_p25(p25),
m_network(network),
m_rfFrames(0U),
m_rfBits(0U),
m_rfErrs(0U),
@ -1116,7 +1114,7 @@ void Voice::writeNetwork(const uint8_t *data, uint8_t duid, uint8_t frameType)
{
assert(data != nullptr);
if (m_network == nullptr)
if (m_p25->m_network == nullptr)
return;
if (m_p25->m_rfTimeout.isRunning() && m_p25->m_rfTimeout.hasExpired())
@ -1127,14 +1125,14 @@ void Voice::writeNetwork(const uint8_t *data, uint8_t duid, uint8_t frameType)
// ignore HDU
break;
case P25_DUID_LDU1:
m_network->writeP25LDU1(m_rfLC, m_rfLSD, data, frameType);
m_p25->m_network->writeP25LDU1(m_rfLC, m_rfLSD, data, frameType);
break;
case P25_DUID_LDU2:
m_network->writeP25LDU2(m_rfLC, m_rfLSD, data);
m_p25->m_network->writeP25LDU2(m_rfLC, m_rfLSD, data);
break;
case P25_DUID_TDU:
case P25_DUID_TDULC:
m_network->writeP25TDU(m_rfLC, m_rfLSD);
m_p25->m_network->writeP25TDU(m_rfLC, m_rfLSD);
break;
default:
LogError(LOG_NET, "P25 unhandled voice DUID, duid = $%02X", duid);
@ -1160,7 +1158,7 @@ void Voice::writeRF_EndOfVoice()
resetNet();
// transmit channelNo release burst
m_p25->m_trunk->writeRF_TDULC_ChanRelease(grp, srcId, dstId);
m_p25->m_control->writeRF_TDULC_ChanRelease(grp, srcId, dstId);
}
/// <summary>
@ -1197,8 +1195,8 @@ void Voice::writeNet_TDU()
::ActivityLog("P25", false, "network end of transmission, %u frames", m_netFrames);
}
if (m_network != nullptr)
m_network->resetP25();
if (m_p25->m_network != nullptr)
m_p25->m_network->resetP25();
::memset(m_netLDU1, 0x00U, 9U * 25U);
::memset(m_netLDU2, 0x00U, 9U * 25U);
@ -1345,16 +1343,16 @@ void Voice::writeNet_LDU1()
::ActivityLog("P25", false, "network %svoice transmission from %u to %s%u", m_netLC.getEncrypted() ? "encrypted " : "", srcId, group ? "TG " : "", dstId);
// single-channel trunking or voice on control support?
if (m_p25->m_control && m_p25->m_voiceOnControl && !m_p25->m_disableNetworkGrant) {
if (m_p25->m_enableControl && m_p25->m_voiceOnControl && !m_p25->m_disableNetworkGrant) {
uint8_t serviceOptions = (m_netLC.getEmergency() ? 0x80U : 0x00U) + // Emergency Flag
(m_netLC.getEncrypted() ? 0x40U : 0x00U) + // Encrypted Flag
(m_netLC.getPriority() & 0x07U); // Priority
if (!m_p25->m_trunk->writeRF_TSDU_Grant(srcId, dstId, serviceOptions, group, true)) {
if (!m_p25->m_control->writeRF_TSDU_Grant(srcId, dstId, serviceOptions, group, true)) {
LogError(LOG_NET, P25_HDU_STR " call failure, network call not granted, dstId = %u", dstId);
if (m_network != nullptr)
m_network->resetP25();
if (m_p25->m_network != nullptr)
m_p25->m_network->resetP25();
::memset(m_netLDU1, 0x00U, 9U * 25U);
::memset(m_netLDU2, 0x00U, 9U * 25U);
@ -1434,7 +1432,7 @@ void Voice::writeNet_LDU1()
uint32_t sysId = control.getSysId();
// is the network peer a different WACN or system ID?
if (m_p25->m_control && m_p25->m_allowExplicitSourceId) {
if (m_p25->m_enableControl && m_p25->m_allowExplicitSourceId) {
if (sysId != lc::LC::getSiteData().sysId()) {
// per TIA-102.AABD-D transmit EXPLICIT_SOURCE_ID every other frame (e.g. every other LDU1)
m_roamLDU1Count++;
@ -1458,7 +1456,7 @@ void Voice::writeNet_LDU1()
}
// single-channel trunking or voice on control support?
if (m_p25->m_control && m_p25->m_voiceOnControl) {
if (m_p25->m_enableControl && m_p25->m_voiceOnControl) {
// per TIA-102.AABD-B transmit RFSS_STS_BCAST every 3 superframes (e.g. every 3 LDU1s)
m_vocLDU1Count++;
if (m_vocLDU1Count > VOC_LDU1_COUNT) {

@ -37,7 +37,6 @@
#include "p25/lc/LC.h"
#include "p25/Control.h"
#include "p25/Audio.h"
#include "network/BaseNetwork.h"
#include <cstdio>
#include <string>
@ -48,7 +47,7 @@ namespace p25
// Class Prototypes
// ---------------------------------------------------------------------------
namespace packet { class HOST_SW_API Trunk; }
namespace packet { class HOST_SW_API ControlSignaling; }
class HOST_SW_API Control;
namespace packet
@ -71,12 +70,10 @@ namespace p25
virtual bool processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::LowSpeedData& lsd, uint8_t& duid, uint8_t& frameType);
protected:
friend class packet::Trunk;
friend class packet::ControlSignaling;
friend class p25::Control;
Control* m_p25;
network::BaseNetwork* m_network;
uint32_t m_rfFrames;
uint32_t m_rfBits;
uint32_t m_rfErrs;
@ -118,7 +115,7 @@ namespace p25
bool m_debug;
/// <summary>Initializes a new instance of the Voice class.</summary>
Voice(Control* p25, network::BaseNetwork* network, bool debug, bool verbose);
Voice(Control* p25, bool debug, bool verbose);
/// <summary>Finalizes a instance of the Voice class.</summary>
virtual ~Voice();

Loading…
Cancel
Save

Powered by TurnKey Linux.