diff --git a/CMakeLists.txt b/CMakeLists.txt index 317796ff..2266788c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,8 @@ file(GLOB dvmhost_SRC "nxdn/channel/*.cpp" "nxdn/lc/*.h" "nxdn/lc/*.cpp" + "nxdn/lc/rcch/*.h" + "nxdn/lc/rcch/*.cpp" "nxdn/packet/*.h" "nxdn/packet/*.cpp" diff --git a/dmr/lc/csbk/CSBKFactory.h b/dmr/lc/csbk/CSBKFactory.h index e7c78511..d90f6643 100644 --- a/dmr/lc/csbk/CSBKFactory.h +++ b/dmr/lc/csbk/CSBKFactory.h @@ -69,7 +69,7 @@ namespace dmr private: /// - static std::unique_ptr decode(CSBK* tsbk, const uint8_t* data); + static std::unique_ptr decode(CSBK* csbk, const uint8_t* data); }; } // namespace csbk } // namespace lc diff --git a/nxdn/Control.cpp b/nxdn/Control.cpp index 25fd41ee..ed3a9030 100644 --- a/nxdn/Control.cpp +++ b/nxdn/Control.cpp @@ -34,6 +34,7 @@ #include "nxdn/acl/AccessControl.h" #include "nxdn/channel/SACCH.h" #include "nxdn/channel/FACCH1.h" +#include "nxdn/lc/RCCH.h" #include "nxdn/lc/RTCH.h" #include "nxdn/Sync.h" #include "nxdn/NXDNUtils.h" @@ -142,12 +143,12 @@ Control::Control(uint32_t ran, uint32_t callHang, uint32_t queueSize, uint32_t t acl::AccessControl::init(m_ridLookup, m_tidLookup); - m_voice = new Voice(this, network, dumpRCCHData, debug, verbose); - m_trunk = new Trunk(this, network, dumpRCCHData, debug, verbose); + 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_rfLC.setVerbose(m_dumpRCCH); - m_netLC.setVerbose(m_dumpRCCH); + lc::RCCH::setVerbose(dumpRCCHData); + lc::RTCH::setVerbose(dumpRCCHData); } /// @@ -187,13 +188,11 @@ void Control::reset() m_queue.clear(); m_rfMask = 0x00U; - m_rfLC.setVerbose(m_dumpRCCH); m_rfLC.reset(); m_netState = RS_NET_IDLE; m_netMask = 0x00U; - m_netLC.setVerbose(m_dumpRCCH); m_netLC.reset(); } @@ -248,6 +247,9 @@ void Control::setOptions(yaml::Node& conf, const std::string cwCallsign, const s m_siteData = SiteData(locId, channelId, channelNo, serviceClass, false); m_siteData.setCallsign(cwCallsign); + lc::RCCH::setSiteData(m_siteData); + lc::RCCH::setCallsign(cwCallsign); + std::vector entries = m_idenTable->list(); for (auto it = entries.begin(); it != entries.end(); ++it) { lookups::IdenTable entry = *it; @@ -281,11 +283,6 @@ void Control::setOptions(yaml::Node& conf, const std::string cwCallsign, const s if (m_data != nullptr) { m_data->resetRF(); } - - if (m_trunk != nullptr) { - m_trunk->resetRF(); - m_trunk->resetNet(); - } } /// @@ -613,6 +610,8 @@ void Control::setDebugVerbose(bool debug, bool verbose) void Control::setRCCHVerbose(bool verbose) { m_dumpRCCH = verbose; + lc::RCCH::setVerbose(verbose); + lc::RTCH::setVerbose(verbose); } // --------------------------------------------------------------------------- @@ -731,8 +730,8 @@ bool Control::writeRF_ControlData() return false; } - const uint8_t maxSeq = m_trunk->m_rfLC.getBcchCnt() + (m_trunk->m_rfLC.getCcchPagingCnt() + m_trunk->m_rfLC.getCcchMultiCnt()) * - m_trunk->m_rfLC.getRcchGroupingCnt() * m_trunk->m_rfLC.getRcchIterateCount(); + const uint8_t maxSeq = m_trunk->m_bcchCnt + (m_trunk->m_ccchPagingCnt + m_trunk->m_ccchMultiCnt) * + m_trunk->m_rcchGroupingCnt * m_trunk->m_rcchIterateCnt; if (m_ccSeq == maxSeq) { m_ccSeq = 0U; } diff --git a/nxdn/lc/RCCH.cpp b/nxdn/lc/RCCH.cpp index b317d010..8ce5691e 100644 --- a/nxdn/lc/RCCH.cpp +++ b/nxdn/lc/RCCH.cpp @@ -39,6 +39,15 @@ using namespace nxdn::lc; #include #include +// --------------------------------------------------------------------------- +// Static Class Members +// --------------------------------------------------------------------------- + +bool RCCH::m_verbose = false; + +uint8_t *RCCH::m_siteCallsign = nullptr; +SiteData RCCH::m_siteData = SiteData(); + // --------------------------------------------------------------------------- // Public Class Members // --------------------------------------------------------------------------- @@ -47,7 +56,7 @@ using namespace nxdn::lc; /// Initializes a copy instance of the RCCH class. /// /// -RCCH::RCCH(const RCCH& data) : RCCH(SiteData()) +RCCH::RCCH(const RCCH& data) : RCCH() { copy(data); } @@ -55,23 +64,28 @@ RCCH::RCCH(const RCCH& data) : RCCH(SiteData()) /// /// Initializes a new instance of the RCCH class. /// -/// -/// -RCCH::RCCH(SiteData siteData, lookups::IdenTable entry) : RCCH(siteData) -{ - m_siteIdenEntry = entry; -} - -/// -/// Initializes a new instance of the RCCH class. -/// -/// -/// -/// -RCCH::RCCH(SiteData siteData, lookups::IdenTable entry, bool verbose) : RCCH(siteData) +RCCH::RCCH() : + m_messageType(MESSAGE_TYPE_IDLE), + m_srcId(0U), + m_dstId(0U), + m_locId(0U), + m_regOption(0U), + m_version(0U), + m_causeRsp(NXDN_CAUSE_MM_REG_ACCEPTED), + m_grpVchNo(0U), + m_callType(CALL_TYPE_UNSPECIFIED), + m_emergency(false), + m_encrypted(false), + m_priority(false), + m_group(true), + m_duplex(false), + m_transmissionMode(TRANSMISSION_MODE_4800), + m_siteIdenEntry() { - m_verbose = verbose; - m_siteIdenEntry = entry; + if (m_siteCallsign == nullptr) { + m_siteCallsign = new uint8_t[NXDN_CALLSIGN_LENGTH_BYTES]; + ::memset(m_siteCallsign, 0x00U, NXDN_CALLSIGN_LENGTH_BYTES); + } } /// @@ -83,32 +97,43 @@ RCCH::~RCCH() } /// -/// Equals operator. +/// Sets the callsign. /// -/// -/// -RCCH& RCCH::operator=(const RCCH& data) +/// Callsign. +void RCCH::setCallsign(std::string callsign) { - if (&data != this) { - copy(data); + if (m_siteCallsign == nullptr) { + m_siteCallsign = new uint8_t[NXDN_CALLSIGN_LENGTH_BYTES]; + ::memset(m_siteCallsign, 0x00U, NXDN_CALLSIGN_LENGTH_BYTES); } - return *this; + uint32_t idLength = callsign.length(); + if (idLength > 0) { + ::memset(m_siteCallsign, 0x20U, NXDN_CALLSIGN_LENGTH_BYTES); + + if (idLength > NXDN_CALLSIGN_LENGTH_BYTES) + idLength = NXDN_CALLSIGN_LENGTH_BYTES; + for (uint32_t i = 0; i < idLength; i++) + m_siteCallsign[i] = callsign[i]; + } } +/// --------------------------------------------------------------------------- +// Protected Class Members +// --------------------------------------------------------------------------- + /// -/// Decode call link control data. +/// Internal helper to decode a trunking signalling block. /// /// +/// /// /// /// True, if RCCH was decoded, otherwise false. -void RCCH::decode(const uint8_t* data, uint32_t length, uint32_t offset) +void RCCH::decode(const uint8_t* data, uint8_t* rcch, uint32_t length, uint32_t offset) { assert(data != nullptr); - - uint8_t rcch[22U]; - ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); + assert(rcch != nullptr); for (uint32_t i = 0U; i < length; i++, offset++) { bool b = READ_BIT(data, offset); @@ -119,23 +144,22 @@ void RCCH::decode(const uint8_t* data, uint32_t length, uint32_t offset) Utils::dump(2U, "Decoded RCCH Data", rcch, NXDN_RCCH_LC_LENGTH_BYTES); } - decodeLC(rcch); + m_messageType = data[0U] & 0x3FU; // Message Type } /// -/// Encode call link control data. +/// Internal helper to encode a RCCH. /// /// +/// /// /// -void RCCH::encode(uint8_t* data, uint32_t length, uint32_t offset) +void RCCH::encode(uint8_t* data, const uint8_t* rcch, uint32_t length, uint32_t offset) { assert(data != nullptr); + assert(rcch != nullptr); - uint8_t rcch[22U]; - ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); - - encodeLC(rcch); + data[0U] = m_messageType & 0x3FU; // Message Type for (uint32_t i = 0U; i < length; i++, offset++) { bool b = READ_BIT(rcch, i); @@ -147,315 +171,13 @@ void RCCH::encode(uint8_t* data, uint32_t length, uint32_t offset) } } -/// -/// -/// -void RCCH::reset() -{ - m_messageType = MESSAGE_TYPE_IDLE; - - m_srcId = 0U; - m_dstId = 0U; - - m_locId = 0U; - m_regOption = 0U; - - m_version = 0U; - - m_causeRsp = NXDN_CAUSE_MM_REG_ACCEPTED; - - m_grpVchNo = 0U; - - m_emergency = false; - m_encrypted = false; - m_priority = false; - m_group = true; - m_duplex = false; - m_transmissionMode = TRANSMISSION_MODE_4800; -} - -/// -/// Sets the callsign. -/// -/// Callsign. -void RCCH::setCallsign(std::string callsign) -{ - uint32_t idLength = callsign.length(); - if (idLength > 0) { - ::memset(m_siteCallsign, 0x20U, NXDN_CALLSIGN_LENGTH_BYTES); - - if (idLength > NXDN_CALLSIGN_LENGTH_BYTES) - idLength = NXDN_CALLSIGN_LENGTH_BYTES; - for (uint32_t i = 0; i < idLength; i++) - m_siteCallsign[i] = callsign[i]; - } -} - -/// --------------------------------------------------------------------------- -// Private Class Members -// --------------------------------------------------------------------------- - -/// -/// Initializes a new instance of the RCCH class. -/// -RCCH::RCCH() : RCCH(SiteData()) -{ - /* stub */ -} - -/// -/// Initializes a new instance of the RCCH class. -/// -/// -RCCH::RCCH(SiteData siteData) : - m_verbose(false), - m_messageType(MESSAGE_TYPE_IDLE), - m_srcId(0U), - m_dstId(0U), - m_locId(0U), - m_regOption(0U), - m_version(0U), - m_causeRsp(NXDN_CAUSE_MM_REG_ACCEPTED), - m_grpVchNo(0U), - m_callType(CALL_TYPE_UNSPECIFIED), - m_emergency(false), - m_encrypted(false), - m_priority(false), - m_group(true), - m_duplex(false), - m_transmissionMode(TRANSMISSION_MODE_4800), - m_siteData(siteData), - m_siteIdenEntry(), - m_bcchCnt(1U), - m_rcchGroupingCnt(1U), - m_ccchPagingCnt(2U), - m_ccchMultiCnt(2U), - m_rcchIterateCnt(2U) -{ - m_siteCallsign = new uint8_t[NXDN_CALLSIGN_LENGTH_BYTES]; - ::memset(m_siteCallsign, 0x00U, NXDN_CALLSIGN_LENGTH_BYTES); - setCallsign(siteData.callsign()); -} - -/// -/// Decode link control. -/// -/// -/// -bool RCCH::decodeLC(const uint8_t* data) -{ - assert(data != nullptr); - - m_messageType = data[0U] & 0x3FU; // Message Type - - // message type opcodes - switch (m_messageType) { - case RTCH_MESSAGE_TYPE_VCALL: - case RCCH_MESSAGE_TYPE_VCALL_CONN: - m_callType = (data[2U] >> 5) & 0x07U; // Call Type - m_emergency = (data[1U] & 0x80U) == 0x80U; // Emergency Flag - m_priority = (data[1U] & 0x20U) == 0x20U; // Priority Flag - m_duplex = (data[2U] & 0x10U) == 0x10U; // Half/Full Duplex Flag - m_transmissionMode = (data[2U] & 0x07U); // Transmission Mode - m_srcId = (uint16_t)((data[3U] << 8) | data[4U]) & 0xFFFFU; // Source Radio Address - m_dstId = (uint16_t)((data[5U] << 8) | data[6U]) & 0xFFFFU; // Target Radio Address - break; - case RTCH_MESSAGE_TYPE_DCALL_HDR: - m_callType = (data[2U] >> 5) & 0x07U; // Call Type - m_emergency = (data[1U] & 0x80U) == 0x80U; // Emergency Flag - m_priority = (data[1U] & 0x20U) == 0x20U; // Priority Flag - m_duplex = (data[2U] & 0x10U) == 0x10U; // Half/Full Duplex Flag - m_transmissionMode = (data[2U] & 0x07U); // Transmission Mode - m_srcId = (uint16_t)((data[3U] << 8) | data[4U]) & 0xFFFFU; // Source Radio Address - m_dstId = (uint16_t)((data[5U] << 8) | data[6U]) & 0xFFFFU; // Target Radio Address - break; - case MESSAGE_TYPE_IDLE: - break; - case RCCH_MESSAGE_TYPE_REG: - m_regOption = data[1U] >> 3; // Registration Option - m_locId = (uint16_t)((data[2U] << 8) | data[3U]) & 0xFFFFU; // Location ID - m_srcId = (uint16_t)((data[4U] << 8) | data[5U]) & 0xFFFFU; // Source Radio Address - m_dstId = (uint16_t)((data[6U] << 8) | data[7U]) & 0xFFFFU; // Target Radio Address - // bryanb: maybe process subscriber type? (byte 8 and 9) - m_version = data[10U]; // Version - break; - case RCCH_MESSAGE_TYPE_REG_C: - m_regOption = data[1U] >> 3; // Registration Option - m_locId = (uint16_t)((data[2U] << 8) | data[3U]) & 0xFFFFU; // Location ID - m_srcId = (uint16_t)((data[4U] << 8) | data[5U]) & 0xFFFFU; // Source Radio Address - break; - case RCCH_MESSAGE_TYPE_GRP_REG: - m_regOption = data[1U]; // Group Registration Option - m_srcId = (uint16_t)((data[2U] << 8) | data[3U]) & 0xFFFFU; // Source Radio Address - m_dstId = (uint16_t)((data[4U] << 8) | data[5U]) & 0xFFFFU; // Target Radio Address - break; - default: - LogError(LOG_NXDN, "RCCH::decodeRCCH(), unknown RCCH value, messageType = $%02X", m_messageType); - return false; - } - - return true; -} - -/// -/// Encode link control. -/// -/// -void RCCH::encodeLC(uint8_t* data) -{ - assert(data != nullptr); - - data[0U] = m_messageType & 0x3FU; // Message Type - - // message type opcodes - switch (m_messageType) { - case RTCH_MESSAGE_TYPE_VCALL: - case RCCH_MESSAGE_TYPE_VCALL_CONN: - data[1U] = (m_emergency ? 0x80U : 0x00U) + // Emergency Flag - (m_priority ? 0x20U : 0x00U); // Priority Flag - data[2U] = ((m_callType & 0x07U) << 5) + // Call Type - (m_duplex ? 0x10U : 0x00U) + // Half/Full Duplex Flag - (m_transmissionMode & 0x07U); // Transmission Mode - - data[3U] = (m_srcId >> 8U) & 0xFFU; // Source Radio Address - data[4U] = (m_srcId >> 0U) & 0xFFU; // ... - data[5U] = (m_dstId >> 8U) & 0xFFU; // Target Radio Address - data[6U] = (m_dstId >> 0U) & 0xFFU; // ... - - data[7U] = m_causeRsp; // Cause (VD) - data[9U] = (m_siteData.locId() >> 8) & 0xFFU; // Location ID - data[10U] = (m_siteData.locId() >> 0) & 0xFFU; // ... - break; - case RCCH_MESSAGE_TYPE_VCALL_ASSGN: - case RCCH_MESSAGE_TYPE_DCALL_ASSGN: - data[1U] = (m_emergency ? 0x80U : 0x00U) + // Emergency Flag - (m_priority ? 0x20U : 0x00U); // Priority Flag - data[2U] = ((m_callType & 0x07U) << 5) + // Call Type - (m_duplex ? 0x10U : 0x00U) + // Half/Full Duplex Flag - (m_transmissionMode & 0x07U); // Transmission Mode - - data[3U] = (m_srcId >> 8U) & 0xFFU; // Source Radio Address - data[4U] = (m_srcId >> 0U) & 0xFFU; // ... - data[5U] = (m_dstId >> 8U) & 0xFFU; // Target Radio Address - data[6U] = (m_dstId >> 0U) & 0xFFU; // ... - - data[7U] = (m_grpVchNo >> 10) & 0x03U; // Channel - data[8U] = (m_grpVchNo & 0xFFU); // ... - - data[10U] = (m_siteData.locId() >> 8) & 0xFFU; // Location ID - data[11U] = (m_siteData.locId() >> 0) & 0xFFU; // ... - break; - case RTCH_MESSAGE_TYPE_DCALL_HDR: - data[1U] = (m_emergency ? 0x80U : 0x00U) + // Emergency Flag - (m_priority ? 0x20U : 0x00U); // Priority Flag - data[2U] = ((m_callType & 0x07U) << 5) + // Call Type - (m_duplex ? 0x10U : 0x00U) + // Half/Full Duplex Flag - (m_transmissionMode & 0x07U); // Transmission Mode - - data[3U] = (m_srcId >> 8U) & 0xFFU; // Source Radio Address - data[4U] = (m_srcId >> 0U) & 0xFFU; // ... - data[5U] = (m_dstId >> 8U) & 0xFFU; // Target Radio Address - data[6U] = (m_dstId >> 0U) & 0xFFU; // ... - - data[7U] = m_causeRsp; // Cause (VD) - data[9U] = (m_siteData.locId() >> 8) & 0xFFU; // Location ID - data[10U] = (m_siteData.locId() >> 0) & 0xFFU; // ... - break; - case MESSAGE_TYPE_IDLE: - break; - case MESSAGE_TYPE_DST_ID_INFO: - data[1U] = 0xC0U + NXDN_CALLSIGN_LENGTH_BYTES; // Station ID Option - Start / End / Character Count - data[2U] = (m_siteCallsign[0]); // Character 0 - for (uint8_t i = 1; i < NXDN_CALLSIGN_LENGTH_BYTES; i++) { - data[i + 2U] = m_siteCallsign[i]; // Character 1 - 7 - } - break; - case RCCH_MESSAGE_TYPE_SITE_INFO: - { - data[1U] = (m_siteData.locId() >> 16) & 0xFFU; // Location ID - data[2U] = (m_siteData.locId() >> 8) & 0xFFU; // ... - data[3U] = (m_siteData.locId() >> 0) & 0xFFU; // ... - data[4U] = ((m_bcchCnt & 0x03U) << 6) + // Channel Structure - Number of BCCH - ((m_rcchGroupingCnt & 0x07U) << 3) + // ... - Number of Grouping - (((m_ccchPagingCnt >> 1) & 0x07U) << 0); // ... - Number of Paging Frames - data[5U] = ((m_ccchPagingCnt & 0x01U) << 7) + // ... - Number of Paging Frames - ((m_ccchMultiCnt & 0x07U) << 4) + // ... - Number of Multipurpose Frames - ((m_rcchIterateCnt & 0x0FU) << 0); // ... - Number of Iteration - - data[6U] = m_siteData.serviceClass(); // Service Information - data[7U] = (m_siteData.netActive() ? NXDN_SIF2_IP_NETWORK : 0x00U); // ... - - // bryanb: this is currently fixed -- maybe dynamic in the future - data[8U] = 0U; // Restriction Information - No access restriction / No cycle restriction - data[9U] = 0x08U; // ... - No group restriction / GMS; Location Registration Restriction - data[10U] = (!m_siteData.netActive() ? 0x01U : 0x00U); // ... - No group ratio restriction / No delay time extension / ISO - - // bryanb: this is currently fixed -- maybe dynamic in the future - data[11U] = NXDN_CH_ACCESS_BASE_FREQ_SYS_DEFINED; // Channel Access Information - Channel Version / Sys Defined Step / Sys Defined Base Freq - - data[14U] = 1U; // Version - - uint16_t channelNo = m_siteData.channelNo() & 0x3FFU; - data[15U] = (channelNo >> 6) & 0x0FU; // 1st Control Channel - data[16U] = (channelNo & 0x3FU) << 2; // ... - } - break; - case MESSAGE_TYPE_SRV_INFO: - data[1U] = (m_siteData.locId() >> 16) & 0xFFU; // Location ID - data[2U] = (m_siteData.locId() >> 8) & 0xFFU; // ... - data[3U] = (m_siteData.locId() >> 0) & 0xFFU; // ... - data[4U] = m_siteData.serviceClass(); // Service Information - data[5U] = (m_siteData.netActive() ? NXDN_SIF2_IP_NETWORK : 0x00U); // ... - - // bryanb: this is currently fixed -- maybe dynamic in the future - data[6U] = 0U; // Restriction Information - No access restriction / No cycle restriction - data[7U] = 0x08U; // ... - No group restriction / GMS; Location Registration Restriction - data[8U] = (!m_siteData.netActive() ? 0x01U : 0x00U); // ... - No group ratio restriction / No delay time extension / ISO - break; - case RCCH_MESSAGE_TYPE_REG: - data[2U] = (m_siteData.locId() >> 8) & 0xFFU; // ... - data[3U] = (m_siteData.locId() >> 0) & 0xFFU; // ... - data[4U] = (m_srcId >> 8U) & 0xFFU; // Source Radio Address - data[5U] = (m_srcId >> 0U) & 0xFFU; // ... - data[6U] = (m_dstId >> 8U) & 0xFFU; // Target Radio Address - data[7U] = (m_dstId >> 0U) & 0xFFU; // ... - data[8U] = m_causeRsp; // Cause (MM) - break; - case RCCH_MESSAGE_TYPE_REG_C: - data[2U] = (m_siteData.locId() >> 8) & 0xFFU; // Location ID - data[3U] = (m_siteData.locId() >> 0) & 0xFFU; // ... - data[4U] = (m_dstId >> 8U) & 0xFFU; // Target Radio Address - data[5U] = (m_dstId >> 0U) & 0xFFU; // ... - data[6U] = m_causeRsp; // Cause (MM) - break; - case RCCH_MESSAGE_TYPE_REG_COMM: - data[2U] = (m_siteData.locId() >> 8) & 0xFFU; // Location ID - data[3U] = (m_siteData.locId() >> 0) & 0xFFU; // ... - data[4U] = (m_dstId >> 8U) & 0xFFU; // Target Radio Address - data[5U] = (m_dstId >> 0U) & 0xFFU; // ... - break; - case RCCH_MESSAGE_TYPE_GRP_REG: - data[2U] = (m_srcId >> 8U) & 0xFFU; // Source Radio Address - data[3U] = (m_srcId >> 0U) & 0xFFU; // ... - data[4U] = (m_dstId >> 8U) & 0xFFU; // Target Radio Address - data[5U] = (m_dstId >> 0U) & 0xFFU; // ... - data[6U] = m_causeRsp; // Cause (MM) - data[8U] = (m_siteData.locId() >> 8) & 0xFFU; // Location ID - data[9U] = (m_siteData.locId() >> 0) & 0xFFU; // ... - break; - default: - LogError(LOG_NXDN, "RCCH::encodeRCCH(), unknown RCCH value, messageType = $%02X", m_messageType); - return; - } -} - // /// Internal helper to copy the the class. /// /// void RCCH::copy(const RCCH& data) { - m_verbose = data.m_verbose; + m_messageType = data.m_messageType; m_srcId = data.m_srcId; m_dstId = data.m_dstId; @@ -479,19 +201,5 @@ void RCCH::copy(const RCCH& data) m_transmissionMode = data.m_transmissionMode; - m_siteData = data.m_siteData; m_siteIdenEntry = data.m_siteIdenEntry; - - delete[] m_siteCallsign; - - uint8_t* callsign = new uint8_t[NXDN_CALLSIGN_LENGTH_BYTES]; - ::memcpy(callsign, data.m_siteCallsign, NXDN_CALLSIGN_LENGTH_BYTES); - - m_siteCallsign = callsign; - - m_bcchCnt = data.m_bcchCnt; - m_rcchGroupingCnt = data.m_rcchGroupingCnt; - m_ccchPagingCnt = data.m_ccchPagingCnt; - m_ccchMultiCnt = data.m_ccchMultiCnt; - m_rcchIterateCnt = data.m_rcchIterateCnt; } diff --git a/nxdn/lc/RCCH.h b/nxdn/lc/RCCH.h index b95c2ca1..ce9b1ad2 100644 --- a/nxdn/lc/RCCH.h +++ b/nxdn/lc/RCCH.h @@ -48,107 +48,88 @@ namespace nxdn public: /// Initializes a copy instance of the RCCH class. RCCH(const RCCH& data); - /// Initializes a new instance of the TSBK class. - RCCH(SiteData siteData, lookups::IdenTable entry); - /// Initializes a new instance of the TSBK class. - RCCH(SiteData siteData, lookups::IdenTable entry, bool verbose); + /// Initializes a new instance of the RCCH class. + RCCH(); /// Finalizes a instance of the RCCH class. - ~RCCH(); - - /// Equals operator. - RCCH& operator=(const RCCH& data); + virtual ~RCCH(); /// Decode layer 3 data. - void decode(const uint8_t* data, uint32_t length, uint32_t offset = 0U); + virtual void decode(const uint8_t* data, uint32_t length, uint32_t offset = 0U) = 0; /// Encode layer 3 data. - void encode(uint8_t* data, uint32_t length, uint32_t offset = 0U); + virtual void encode(uint8_t* data, uint32_t length, uint32_t offset = 0U) = 0; - /// - void reset(); + /// Sets the flag indicating verbose log output. + static void setVerbose(bool verbose) { m_verbose = verbose; } + /** Local Site data */ /// Sets the callsign. - void setCallsign(std::string callsign); + static void setCallsign(std::string callsign); - public: - /// Flag indicating verbose log output. - __PROPERTY(bool, verbose, Verbose); + /// Gets the local site data. + static SiteData getSiteData() { return m_siteData; } + /// Sets the local site data. + static void setSiteData(SiteData siteData) { m_siteData = siteData; } + public: /** Common Data */ /// Message Type - __PROPERTY(uint8_t, messageType, MessageType); + __PROTECTED_PROPERTY(uint8_t, messageType, MessageType); /// Source ID. - __PROPERTY(uint16_t, srcId, SrcId); + __PROTECTED_PROPERTY(uint16_t, srcId, SrcId); /// Destination ID. - __PROPERTY(uint16_t, dstId, DstId); + __PROTECTED_PROPERTY(uint16_t, dstId, DstId); /// Location ID. - __PROPERTY(uint32_t, locId, LocId); + __PROTECTED_PROPERTY(uint32_t, locId, LocId); /// Registration Option. - __PROPERTY(uint8_t, regOption, RegOption); + __PROTECTED_PROPERTY(uint8_t, regOption, RegOption); /// Version Number. - __PROPERTY(uint8_t, version, Version); + __PROTECTED_PROPERTY(uint8_t, version, Version); /// Cause Response. - __PROPERTY(uint8_t, causeRsp, CauseResponse); + __PROTECTED_PROPERTY(uint8_t, causeRsp, CauseResponse); /// Voice channel number. - __PROPERTY(uint32_t, grpVchNo, GrpVchNo); + __PROTECTED_PROPERTY(uint32_t, grpVchNo, GrpVchNo); /** Call Data */ /// Call Type - __PROPERTY(uint8_t, callType, CallType); + __PROTECTED_PROPERTY(uint8_t, callType, CallType); /** Common Call Options */ /// Flag indicating the emergency bits are set. - __PROPERTY(bool, emergency, Emergency); + __PROTECTED_PROPERTY(bool, emergency, Emergency); /// Flag indicating that encryption is enabled. - __PROPERTY(bool, encrypted, Encrypted); + __PROTECTED_PROPERTY(bool, encrypted, Encrypted); /// Flag indicating priority paging. - __PROPERTY(bool, priority, Priority); + __PROTECTED_PROPERTY(bool, priority, Priority); /// Flag indicating a group/talkgroup operation. - __PROPERTY(bool, group, Group); + __PROTECTED_PROPERTY(bool, group, Group); /// Flag indicating a half/full duplex operation. - __PROPERTY(bool, duplex, Duplex); + __PROTECTED_PROPERTY(bool, duplex, Duplex); /// Transmission mode. - __PROPERTY(uint8_t, transmissionMode, TransmissionMode); + __PROTECTED_PROPERTY(uint8_t, transmissionMode, TransmissionMode); /** Local Site data */ - /// Local Site Data. - __PROPERTY_PLAIN(SiteData, siteData, siteData); /// Local Site Identity Entry. - __PROPERTY_PLAIN(lookups::IdenTable, siteIdenEntry, siteIdenEntry); - - /** Channel Structure Data */ - /// Count of BCCH frames per RCCH superframe. - __PROPERTY(uint8_t, bcchCnt, BcchCnt); - /// Count of RCCH frame groupings per RCCH superframe. - __PROPERTY(uint8_t, rcchGroupingCnt, RcchGroupingCnt); - /// Count of CCCH/UPCH paging frames per RCCH superframe. - __PROPERTY(uint8_t, ccchPagingCnt, CcchPagingCnt); - /// Count of CCCH/UPCH multi-purpose frames per RCCH superframe. - __PROPERTY(uint8_t, ccchMultiCnt, CcchMultiCnt); - /// Count of group iterations per RCCH superframe. - __PROPERTY(uint8_t, rcchIterateCnt, RcchIterateCount); - - private: - /// Initializes a new instance of the RCCH class. - RCCH(); - /// Initializes a new instance of the RCCH class. - RCCH(SiteData siteData); + __PROTECTED_PROPERTY_PLAIN(lookups::IdenTable, siteIdenEntry, siteIdenEntry); + + protected: + static bool m_verbose; /** Local Site data */ - uint8_t* m_siteCallsign; + static uint8_t* m_siteCallsign; + static SiteData m_siteData; - /// Decode link control. - bool decodeLC(const uint8_t* data); - /// Encode link control. - void encodeLC(uint8_t* data); + /// Internal helper to decode a RCCH. + void decode(const uint8_t* data, uint8_t* rcch, uint32_t length, uint32_t offset = 0U); + /// Internal helper to encode a RCCH. + void encode(uint8_t* data, const uint8_t* rcch, uint32_t length, uint32_t offset = 0U); - /// Internal helper to copy the class. - void copy(const RCCH& data); + __PROTECTED_COPY(RCCH); }; } // namespace lc } // namespace nxdn diff --git a/nxdn/lc/RTCH.cpp b/nxdn/lc/RTCH.cpp index d53fb00f..ae630b85 100644 --- a/nxdn/lc/RTCH.cpp +++ b/nxdn/lc/RTCH.cpp @@ -40,6 +40,12 @@ using namespace nxdn::lc; #include #include +// --------------------------------------------------------------------------- +// Static Class Members +// --------------------------------------------------------------------------- + +bool RTCH::m_verbose = false; + // --------------------------------------------------------------------------- // Public Class Members // --------------------------------------------------------------------------- @@ -48,7 +54,6 @@ using namespace nxdn::lc; /// Initializes a new instance of the RTCH class. /// RTCH::RTCH() : - m_verbose(false), m_messageType(MESSAGE_TYPE_IDLE), m_callType(CALL_TYPE_UNSPECIFIED), m_srcId(0U), @@ -77,7 +82,6 @@ RTCH::RTCH() : /// /// RTCH::RTCH(const RTCH& data) : - m_verbose(false), m_messageType(MESSAGE_TYPE_IDLE), m_callType(CALL_TYPE_UNSPECIFIED), m_srcId(0U), @@ -449,8 +453,6 @@ void RTCH::encodeLC(uint8_t* data) /// void RTCH::copy(const RTCH& data) { - m_verbose = data.m_verbose; - m_messageType = data.m_messageType; m_callType = data.m_callType; diff --git a/nxdn/lc/RTCH.h b/nxdn/lc/RTCH.h index 642320e4..23a5c8cf 100644 --- a/nxdn/lc/RTCH.h +++ b/nxdn/lc/RTCH.h @@ -63,10 +63,10 @@ namespace nxdn /// void reset(); - public: - /// Flag indicating verbose log output. - __PROPERTY(bool, verbose, Verbose); + /// Sets the flag indicating verbose log output. + static void setVerbose(bool verbose) { m_verbose = verbose; } + public: /** Common Data */ /// Message Type __PROPERTY(uint8_t, messageType, MessageType); @@ -118,6 +118,8 @@ namespace nxdn __PROPERTY(uint8_t, causeRsp, CauseResponse); private: + static bool m_verbose; + /** Encryption data */ uint8_t* m_mi; diff --git a/nxdn/lc/rcch/MESSAGE_TYPE_DCALL_HDR.cpp b/nxdn/lc/rcch/MESSAGE_TYPE_DCALL_HDR.cpp new file mode 100644 index 00000000..2d00870b --- /dev/null +++ b/nxdn/lc/rcch/MESSAGE_TYPE_DCALL_HDR.cpp @@ -0,0 +1,103 @@ +/** +* Digital Voice Modem - Host Software +* GPLv2 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / Host Software +* +*/ +/* +* Copyright (C) 2022 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 +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#include "Defines.h" +#include "nxdn/lc/rcch/MESSAGE_TYPE_DCALL_HDR.h" +#include "Log.h" +#include "Utils.h" + +using namespace nxdn::lc::rcch; +using namespace nxdn::lc; +using namespace nxdn; + +#include +#include + +// --------------------------------------------------------------------------- +// Public Class Members +// --------------------------------------------------------------------------- + +/// +/// Initializes a new instance of the MESSAGE_TYPE_DCALL_HDR class. +/// +MESSAGE_TYPE_DCALL_HDR::MESSAGE_TYPE_DCALL_HDR() : RCCH() +{ + m_messageType = RTCH_MESSAGE_TYPE_DCALL_HDR; +} + +/// +/// Decode layer 3 data. +/// +/// +/// +/// +void MESSAGE_TYPE_DCALL_HDR::decode(const uint8_t* data, uint32_t length, uint32_t offset) +{ + assert(data != NULL); + + uint8_t rcch[22U]; + ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); + + RCCH::decode(data, rcch, length, offset); + + m_callType = (rcch[2U] >> 5) & 0x07U; // Call Type + m_emergency = (rcch[1U] & 0x80U) == 0x80U; // Emergency Flag + m_priority = (rcch[1U] & 0x20U) == 0x20U; // Priority Flag + m_duplex = (rcch[2U] & 0x10U) == 0x10U; // Half/Full Duplex Flag + m_transmissionMode = (rcch[2U] & 0x07U); // Transmission Mode + m_srcId = (uint16_t)((rcch[3U] << 8) | rcch[4U]) & 0xFFFFU; // Source Radio Address + m_dstId = (uint16_t)((rcch[5U] << 8) | rcch[6U]) & 0xFFFFU; // Target Radio Address +} + +/// +/// Encode a control signalling block. +/// +/// +/// +/// +void MESSAGE_TYPE_DCALL_HDR::encode(uint8_t* data, uint32_t length, uint32_t offset) +{ + assert(data != NULL); + + uint8_t rcch[22U]; + ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); + + rcch[1U] = (m_emergency ? 0x80U : 0x00U) + // Emergency Flag + (m_priority ? 0x20U : 0x00U); // Priority Flag + rcch[2U] = ((m_callType & 0x07U) << 5) + // Call Type + (m_duplex ? 0x10U : 0x00U) + // Half/Full Duplex Flag + (m_transmissionMode & 0x07U); // Transmission Mode + + rcch[3U] = (m_srcId >> 8U) & 0xFFU; // Source Radio Address + rcch[4U] = (m_srcId >> 0U) & 0xFFU; // ... + rcch[5U] = (m_dstId >> 8U) & 0xFFU; // Target Radio Address + rcch[6U] = (m_dstId >> 0U) & 0xFFU; // ... + + rcch[7U] = m_causeRsp; // Cause (VD) + rcch[9U] = (m_siteData.locId() >> 8) & 0xFFU; // Location ID + rcch[10U] = (m_siteData.locId() >> 0) & 0xFFU; // ... + + RCCH::encode(data, rcch, length, offset); +} diff --git a/nxdn/lc/rcch/MESSAGE_TYPE_DCALL_HDR.h b/nxdn/lc/rcch/MESSAGE_TYPE_DCALL_HDR.h new file mode 100644 index 00000000..2ffd72be --- /dev/null +++ b/nxdn/lc/rcch/MESSAGE_TYPE_DCALL_HDR.h @@ -0,0 +1,58 @@ +/** +* Digital Voice Modem - Host Software +* GPLv2 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / Host Software +* +*/ +/* +* Copyright (C) 2022 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 +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#if !defined(__NXDN_LC_RCCH__MESSAGE_TYPE_DCALL_HDR_H__) +#define __NXDN_LC_RCCH__MESSAGE_TYPE_DCALL_HDR_H__ + +#include "Defines.h" +#include "nxdn/lc/RCCH.h" + +namespace nxdn +{ + namespace lc + { + namespace rcch + { + // --------------------------------------------------------------------------- + // Class Declaration + // Implements VCALL_CONN - Voice Call Connection Request (ISP) and + // Voice Call Connection Response (OSP) + // --------------------------------------------------------------------------- + + class HOST_SW_API MESSAGE_TYPE_DCALL_HDR : public RCCH { + public: + /// Initializes a new instance of the MESSAGE_TYPE_DCALL_HDR class. + MESSAGE_TYPE_DCALL_HDR(); + + /// Decode layer 3 data. + virtual void decode(const uint8_t* data, uint32_t length, uint32_t offset = 0U); + /// Encode layer 3 data. + virtual void encode(uint8_t* data, uint32_t length, uint32_t offset = 0U); + }; + } // namespace rcch + } // namespace lc +} // namespace nxdn + +#endif // __NXDN_LC_RCCH__MESSAGE_TYPE_DCALL_HDR_H__ diff --git a/nxdn/lc/rcch/MESSAGE_TYPE_DST_ID_INFO.cpp b/nxdn/lc/rcch/MESSAGE_TYPE_DST_ID_INFO.cpp new file mode 100644 index 00000000..a15e5f1c --- /dev/null +++ b/nxdn/lc/rcch/MESSAGE_TYPE_DST_ID_INFO.cpp @@ -0,0 +1,86 @@ +/** +* Digital Voice Modem - Host Software +* GPLv2 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / Host Software +* +*/ +/* +* Copyright (C) 2022 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 +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#include "Defines.h" +#include "nxdn/lc/rcch/MESSAGE_TYPE_DST_ID_INFO.h" +#include "Log.h" +#include "Utils.h" + +using namespace nxdn::lc::rcch; +using namespace nxdn::lc; +using namespace nxdn; + +#include +#include + +// --------------------------------------------------------------------------- +// Public Class Members +// --------------------------------------------------------------------------- + +/// +/// Initializes a new instance of the MESSAGE_TYPE_DST_ID_INFO class. +/// +MESSAGE_TYPE_DST_ID_INFO::MESSAGE_TYPE_DST_ID_INFO() : RCCH() +{ + m_messageType = nxdn::MESSAGE_TYPE_DST_ID_INFO; +} + +/// +/// Decode layer 3 data. +/// +/// +/// +/// +void MESSAGE_TYPE_DST_ID_INFO::decode(const uint8_t* data, uint32_t length, uint32_t offset) +{ + assert(data != NULL); + + uint8_t rcch[22U]; + ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); + + RCCH::decode(data, rcch, length, offset); +} + +/// +/// Encode a control signalling block. +/// +/// +/// +/// +void MESSAGE_TYPE_DST_ID_INFO::encode(uint8_t* data, uint32_t length, uint32_t offset) +{ + assert(data != NULL); + + uint8_t rcch[22U]; + ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); + + rcch[1U] = 0xC0U + NXDN_CALLSIGN_LENGTH_BYTES; // Station ID Option - Start / End / Character Count + rcch[2U] = (m_siteCallsign[0]); // Character 0 + for (uint8_t i = 1; i < NXDN_CALLSIGN_LENGTH_BYTES; i++) { + rcch[i + 2U] = m_siteCallsign[i]; // Character 1 - 7 + } + + RCCH::encode(data, rcch, length, offset); +} diff --git a/nxdn/lc/rcch/MESSAGE_TYPE_DST_ID_INFO.h b/nxdn/lc/rcch/MESSAGE_TYPE_DST_ID_INFO.h new file mode 100644 index 00000000..73d52e0b --- /dev/null +++ b/nxdn/lc/rcch/MESSAGE_TYPE_DST_ID_INFO.h @@ -0,0 +1,57 @@ +/** +* Digital Voice Modem - Host Software +* GPLv2 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / Host Software +* +*/ +/* +* Copyright (C) 2022 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 +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#if !defined(__NXDN_LC_RCCH__MESSAGE_TYPE_DST_ID_INFO_H__) +#define __NXDN_LC_RCCH__MESSAGE_TYPE_DST_ID_INFO_H__ + +#include "Defines.h" +#include "nxdn/lc/RCCH.h" + +namespace nxdn +{ + namespace lc + { + namespace rcch + { + // --------------------------------------------------------------------------- + // Class Declaration + // Implements DST_ID_INFO - Digital Station ID + // --------------------------------------------------------------------------- + + class HOST_SW_API MESSAGE_TYPE_DST_ID_INFO : public RCCH { + public: + /// Initializes a new instance of the MESSAGE_TYPE_DST_ID_INFO class. + MESSAGE_TYPE_DST_ID_INFO(); + + /// Decode layer 3 data. + virtual void decode(const uint8_t* data, uint32_t length, uint32_t offset = 0U); + /// Encode layer 3 data. + virtual void encode(uint8_t* data, uint32_t length, uint32_t offset = 0U); + }; + } // namespace rcch + } // namespace lc +} // namespace nxdn + +#endif // __NXDN_LC_RCCH__MESSAGE_TYPE_DST_ID_INFO_H__ diff --git a/nxdn/lc/rcch/MESSAGE_TYPE_GRP_REG.cpp b/nxdn/lc/rcch/MESSAGE_TYPE_GRP_REG.cpp new file mode 100644 index 00000000..4163935e --- /dev/null +++ b/nxdn/lc/rcch/MESSAGE_TYPE_GRP_REG.cpp @@ -0,0 +1,92 @@ +/** +* Digital Voice Modem - Host Software +* GPLv2 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / Host Software +* +*/ +/* +* Copyright (C) 2022 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 +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#include "Defines.h" +#include "nxdn/lc/rcch/MESSAGE_TYPE_GRP_REG.h" +#include "Log.h" +#include "Utils.h" + +using namespace nxdn::lc::rcch; +using namespace nxdn::lc; +using namespace nxdn; + +#include +#include + +// --------------------------------------------------------------------------- +// Public Class Members +// --------------------------------------------------------------------------- + +/// +/// Initializes a new instance of the MESSAGE_TYPE_GRP_REG class. +/// +MESSAGE_TYPE_GRP_REG::MESSAGE_TYPE_GRP_REG() : RCCH() +{ + m_messageType = RCCH_MESSAGE_TYPE_GRP_REG; +} + +/// +/// Decode layer 3 data. +/// +/// +/// +/// +void MESSAGE_TYPE_GRP_REG::decode(const uint8_t* data, uint32_t length, uint32_t offset) +{ + assert(data != NULL); + + uint8_t rcch[22U]; + ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); + + RCCH::decode(data, rcch, length, offset); + + m_regOption = rcch[1U]; // Group Registration Option + m_srcId = (uint16_t)((rcch[2U] << 8) | rcch[3U]) & 0xFFFFU; // Source Radio Address + m_dstId = (uint16_t)((rcch[4U] << 8) | rcch[5U]) & 0xFFFFU; // Target Radio Address +} + +/// +/// Encode a control signalling block. +/// +/// +/// +/// +void MESSAGE_TYPE_GRP_REG::encode(uint8_t* data, uint32_t length, uint32_t offset) +{ + assert(data != NULL); + + uint8_t rcch[22U]; + ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); + + rcch[2U] = (m_srcId >> 8U) & 0xFFU; // Source Radio Address + rcch[3U] = (m_srcId >> 0U) & 0xFFU; // ... + rcch[4U] = (m_dstId >> 8U) & 0xFFU; // Target Radio Address + rcch[5U] = (m_dstId >> 0U) & 0xFFU; // ... + rcch[6U] = m_causeRsp; // Cause (MM) + rcch[8U] = (m_siteData.locId() >> 8) & 0xFFU; // Location ID + rcch[9U] = (m_siteData.locId() >> 0) & 0xFFU; // ... + + RCCH::encode(data, rcch, length, offset); +} diff --git a/nxdn/lc/rcch/MESSAGE_TYPE_GRP_REG.h b/nxdn/lc/rcch/MESSAGE_TYPE_GRP_REG.h new file mode 100644 index 00000000..56ac0df1 --- /dev/null +++ b/nxdn/lc/rcch/MESSAGE_TYPE_GRP_REG.h @@ -0,0 +1,58 @@ +/** +* Digital Voice Modem - Host Software +* GPLv2 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / Host Software +* +*/ +/* +* Copyright (C) 2022 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 +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#if !defined(__NXDN_LC_RCCH__MESSAGE_TYPE_GRP_REG_H__) +#define __NXDN_LC_RCCH__MESSAGE_TYPE_GRP_REG_H__ + +#include "Defines.h" +#include "nxdn/lc/RCCH.h" + +namespace nxdn +{ + namespace lc + { + namespace rcch + { + // --------------------------------------------------------------------------- + // Class Declaration + // Implements GRP_REG - Group Registration Request (ISP) and + // Group Registration Response (OSP) + // --------------------------------------------------------------------------- + + class HOST_SW_API MESSAGE_TYPE_GRP_REG : public RCCH { + public: + /// Initializes a new instance of the MESSAGE_TYPE_GRP_REG class. + MESSAGE_TYPE_GRP_REG(); + + /// Decode layer 3 data. + virtual void decode(const uint8_t* data, uint32_t length, uint32_t offset = 0U); + /// Encode layer 3 data. + virtual void encode(uint8_t* data, uint32_t length, uint32_t offset = 0U); + }; + } // namespace rcch + } // namespace lc +} // namespace nxdn + +#endif // __NXDN_LC_RCCH__MESSAGE_TYPE_GRP_REG_H__ diff --git a/nxdn/lc/rcch/MESSAGE_TYPE_IDLE.cpp b/nxdn/lc/rcch/MESSAGE_TYPE_IDLE.cpp new file mode 100644 index 00000000..344a6b3c --- /dev/null +++ b/nxdn/lc/rcch/MESSAGE_TYPE_IDLE.cpp @@ -0,0 +1,80 @@ +/** +* Digital Voice Modem - Host Software +* GPLv2 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / Host Software +* +*/ +/* +* Copyright (C) 2022 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 +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#include "Defines.h" +#include "nxdn/lc/rcch/MESSAGE_TYPE_IDLE.h" +#include "Log.h" +#include "Utils.h" + +using namespace nxdn::lc::rcch; +using namespace nxdn::lc; +using namespace nxdn; + +#include +#include + +// --------------------------------------------------------------------------- +// Public Class Members +// --------------------------------------------------------------------------- + +/// +/// Initializes a new instance of the MESSAGE_TYPE_IDLE class. +/// +MESSAGE_TYPE_IDLE::MESSAGE_TYPE_IDLE() : RCCH() +{ + m_messageType = nxdn::MESSAGE_TYPE_IDLE; +} + +/// +/// Decode layer 3 data. +/// +/// +/// +/// +void MESSAGE_TYPE_IDLE::decode(const uint8_t* data, uint32_t length, uint32_t offset) +{ + assert(data != NULL); + + uint8_t rcch[22U]; + ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); + + RCCH::decode(data, rcch, length, offset); +} + +/// +/// Encode a control signalling block. +/// +/// +/// +/// +void MESSAGE_TYPE_IDLE::encode(uint8_t* data, uint32_t length, uint32_t offset) +{ + assert(data != NULL); + + uint8_t rcch[22U]; + ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); + + RCCH::encode(data, rcch, length, offset); +} diff --git a/nxdn/lc/rcch/MESSAGE_TYPE_IDLE.h b/nxdn/lc/rcch/MESSAGE_TYPE_IDLE.h new file mode 100644 index 00000000..868a21d3 --- /dev/null +++ b/nxdn/lc/rcch/MESSAGE_TYPE_IDLE.h @@ -0,0 +1,57 @@ +/** +* Digital Voice Modem - Host Software +* GPLv2 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / Host Software +* +*/ +/* +* Copyright (C) 2022 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 +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#if !defined(__NXDN_LC_RCCH__MESSAGE_TYPE_IDLE_H__) +#define __NXDN_LC_RCCH__MESSAGE_TYPE_IDLE_H__ + +#include "Defines.h" +#include "nxdn/lc/RCCH.h" + +namespace nxdn +{ + namespace lc + { + namespace rcch + { + // --------------------------------------------------------------------------- + // Class Declaration + // Implements IDLE - Idle + // --------------------------------------------------------------------------- + + class HOST_SW_API MESSAGE_TYPE_IDLE : public RCCH { + public: + /// Initializes a new instance of the MESSAGE_TYPE_IDLE class. + MESSAGE_TYPE_IDLE(); + + /// Decode layer 3 data. + virtual void decode(const uint8_t* data, uint32_t length, uint32_t offset = 0U); + /// Encode layer 3 data. + virtual void encode(uint8_t* data, uint32_t length, uint32_t offset = 0U); + }; + } // namespace rcch + } // namespace lc +} // namespace nxdn + +#endif // __NXDN_LC_RCCH__MESSAGE_TYPE_IDLE_H__ diff --git a/nxdn/lc/rcch/MESSAGE_TYPE_REG.cpp b/nxdn/lc/rcch/MESSAGE_TYPE_REG.cpp new file mode 100644 index 00000000..c4699eb4 --- /dev/null +++ b/nxdn/lc/rcch/MESSAGE_TYPE_REG.cpp @@ -0,0 +1,95 @@ +/** +* Digital Voice Modem - Host Software +* GPLv2 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / Host Software +* +*/ +/* +* Copyright (C) 2022 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 +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#include "Defines.h" +#include "nxdn/lc/rcch/MESSAGE_TYPE_REG.h" +#include "Log.h" +#include "Utils.h" + +using namespace nxdn::lc::rcch; +using namespace nxdn::lc; +using namespace nxdn; + +#include +#include + +// --------------------------------------------------------------------------- +// Public Class Members +// --------------------------------------------------------------------------- + +/// +/// Initializes a new instance of the MESSAGE_TYPE_REG class. +/// +MESSAGE_TYPE_REG::MESSAGE_TYPE_REG() : RCCH() +{ + m_messageType = RCCH_MESSAGE_TYPE_REG; +} + +/// +/// Decode layer 3 data. +/// +/// +/// +/// +void MESSAGE_TYPE_REG::decode(const uint8_t* data, uint32_t length, uint32_t offset) +{ + assert(data != NULL); + + uint8_t rcch[22U]; + ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); + + RCCH::decode(data, rcch, length, offset); + + m_regOption = rcch[1U] >> 3; // Registration Option + m_locId = (uint16_t)((rcch[2U] << 8) | rcch[3U]) & 0xFFFFU; // Location ID + m_srcId = (uint16_t)((rcch[4U] << 8) | rcch[5U]) & 0xFFFFU; // Source Radio Address + m_dstId = (uint16_t)((rcch[6U] << 8) | rcch[7U]) & 0xFFFFU; // Target Radio Address + // bryanb: maybe process subscriber type? (byte 8 and 9) + m_version = rcch[10U]; // Version +} + +/// +/// Encode a control signalling block. +/// +/// +/// +/// +void MESSAGE_TYPE_REG::encode(uint8_t* data, uint32_t length, uint32_t offset) +{ + assert(data != NULL); + + uint8_t rcch[22U]; + ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); + + rcch[2U] = (m_siteData.locId() >> 8) & 0xFFU; // ... + rcch[3U] = (m_siteData.locId() >> 0) & 0xFFU; // ... + rcch[4U] = (m_srcId >> 8U) & 0xFFU; // Source Radio Address + rcch[5U] = (m_srcId >> 0U) & 0xFFU; // ... + rcch[6U] = (m_dstId >> 8U) & 0xFFU; // Target Radio Address + rcch[7U] = (m_dstId >> 0U) & 0xFFU; // ... + rcch[8U] = m_causeRsp; // Cause (MM) + + RCCH::encode(data, rcch, length, offset); +} diff --git a/nxdn/lc/rcch/MESSAGE_TYPE_REG.h b/nxdn/lc/rcch/MESSAGE_TYPE_REG.h new file mode 100644 index 00000000..d2914cc5 --- /dev/null +++ b/nxdn/lc/rcch/MESSAGE_TYPE_REG.h @@ -0,0 +1,58 @@ +/** +* Digital Voice Modem - Host Software +* GPLv2 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / Host Software +* +*/ +/* +* Copyright (C) 2022 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 +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#if !defined(__NXDN_LC_RCCH__MESSAGE_TYPE_REG_H__) +#define __NXDN_LC_RCCH__MESSAGE_TYPE_REG_H__ + +#include "Defines.h" +#include "nxdn/lc/RCCH.h" + +namespace nxdn +{ + namespace lc + { + namespace rcch + { + // --------------------------------------------------------------------------- + // Class Declaration + // Implements REG - Registration Request (ISP) and + // Registration Response (OSP) + // --------------------------------------------------------------------------- + + class HOST_SW_API MESSAGE_TYPE_REG : public RCCH { + public: + /// Initializes a new instance of the MESSAGE_TYPE_REG class. + MESSAGE_TYPE_REG(); + + /// Decode layer 3 data. + virtual void decode(const uint8_t* data, uint32_t length, uint32_t offset = 0U); + /// Encode layer 3 data. + virtual void encode(uint8_t* data, uint32_t length, uint32_t offset = 0U); + }; + } // namespace rcch + } // namespace lc +} // namespace nxdn + +#endif // __NXDN_LC_RCCH__MESSAGE_TYPE_REG_H__ diff --git a/nxdn/lc/rcch/MESSAGE_TYPE_REG_C.cpp b/nxdn/lc/rcch/MESSAGE_TYPE_REG_C.cpp new file mode 100644 index 00000000..b55fe352 --- /dev/null +++ b/nxdn/lc/rcch/MESSAGE_TYPE_REG_C.cpp @@ -0,0 +1,90 @@ +/** +* Digital Voice Modem - Host Software +* GPLv2 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / Host Software +* +*/ +/* +* Copyright (C) 2022 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 +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#include "Defines.h" +#include "nxdn/lc/rcch/MESSAGE_TYPE_REG_C.h" +#include "Log.h" +#include "Utils.h" + +using namespace nxdn::lc::rcch; +using namespace nxdn::lc; +using namespace nxdn; + +#include +#include + +// --------------------------------------------------------------------------- +// Public Class Members +// --------------------------------------------------------------------------- + +/// +/// Initializes a new instance of the MESSAGE_TYPE_REG_C class. +/// +MESSAGE_TYPE_REG_C::MESSAGE_TYPE_REG_C() : RCCH() +{ + m_messageType = RCCH_MESSAGE_TYPE_REG_C; +} + +/// +/// Decode layer 3 data. +/// +/// +/// +/// +void MESSAGE_TYPE_REG_C::decode(const uint8_t* data, uint32_t length, uint32_t offset) +{ + assert(data != NULL); + + uint8_t rcch[22U]; + ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); + + RCCH::decode(data, rcch, length, offset); + + m_regOption = rcch[1U] >> 3; // Registration Option + m_locId = (uint16_t)((rcch[2U] << 8) | rcch[3U]) & 0xFFFFU; // Location ID + m_srcId = (uint16_t)((rcch[4U] << 8) | rcch[5U]) & 0xFFFFU; // Source Radio Address +} + +/// +/// Encode a control signalling block. +/// +/// +/// +/// +void MESSAGE_TYPE_REG_C::encode(uint8_t* data, uint32_t length, uint32_t offset) +{ + assert(data != NULL); + + uint8_t rcch[22U]; + ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); + + rcch[2U] = (m_siteData.locId() >> 8) & 0xFFU; // Location ID + rcch[3U] = (m_siteData.locId() >> 0) & 0xFFU; // ... + rcch[4U] = (m_dstId >> 8U) & 0xFFU; // Target Radio Address + rcch[5U] = (m_dstId >> 0U) & 0xFFU; // ... + rcch[6U] = m_causeRsp; // Cause (MM) + + RCCH::encode(data, rcch, length, offset); +} diff --git a/nxdn/lc/rcch/MESSAGE_TYPE_REG_C.h b/nxdn/lc/rcch/MESSAGE_TYPE_REG_C.h new file mode 100644 index 00000000..91322abb --- /dev/null +++ b/nxdn/lc/rcch/MESSAGE_TYPE_REG_C.h @@ -0,0 +1,58 @@ +/** +* Digital Voice Modem - Host Software +* GPLv2 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / Host Software +* +*/ +/* +* Copyright (C) 2022 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 +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#if !defined(__NXDN_LC_RCCH__MESSAGE_TYPE_REG_C_H__) +#define __NXDN_LC_RCCH__MESSAGE_TYPE_REG_C_H__ + +#include "Defines.h" +#include "nxdn/lc/RCCH.h" + +namespace nxdn +{ + namespace lc + { + namespace rcch + { + // --------------------------------------------------------------------------- + // Class Declaration + // Implements REG_C - Registration Clear Request (ISP) and + // Registration Clear Response (OSP) + // --------------------------------------------------------------------------- + + class HOST_SW_API MESSAGE_TYPE_REG_C : public RCCH { + public: + /// Initializes a new instance of the MESSAGE_TYPE_REG_C class. + MESSAGE_TYPE_REG_C(); + + /// Decode layer 3 data. + virtual void decode(const uint8_t* data, uint32_t length, uint32_t offset = 0U); + /// Encode layer 3 data. + virtual void encode(uint8_t* data, uint32_t length, uint32_t offset = 0U); + }; + } // namespace rcch + } // namespace lc +} // namespace nxdn + +#endif // __NXDN_LC_RCCH__MESSAGE_TYPE_REG_C_H__ diff --git a/nxdn/lc/rcch/MESSAGE_TYPE_REG_COMM.cpp b/nxdn/lc/rcch/MESSAGE_TYPE_REG_COMM.cpp new file mode 100644 index 00000000..f20b740d --- /dev/null +++ b/nxdn/lc/rcch/MESSAGE_TYPE_REG_COMM.cpp @@ -0,0 +1,85 @@ +/** +* Digital Voice Modem - Host Software +* GPLv2 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / Host Software +* +*/ +/* +* Copyright (C) 2022 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 +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#include "Defines.h" +#include "nxdn/lc/rcch/MESSAGE_TYPE_REG_COMM.h" +#include "Log.h" +#include "Utils.h" + +using namespace nxdn::lc::rcch; +using namespace nxdn::lc; +using namespace nxdn; + +#include +#include + +// --------------------------------------------------------------------------- +// Public Class Members +// --------------------------------------------------------------------------- + +/// +/// Initializes a new instance of the MESSAGE_TYPE_REG_COMM class. +/// +MESSAGE_TYPE_REG_COMM::MESSAGE_TYPE_REG_COMM() : RCCH() +{ + m_messageType = RCCH_MESSAGE_TYPE_REG_COMM; +} + +/// +/// Decode layer 3 data. +/// +/// +/// +/// +void MESSAGE_TYPE_REG_COMM::decode(const uint8_t* data, uint32_t length, uint32_t offset) +{ + assert(data != NULL); + + uint8_t rcch[22U]; + ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); + + RCCH::decode(data, rcch, length, offset); +} + +/// +/// Encode a control signalling block. +/// +/// +/// +/// +void MESSAGE_TYPE_REG_COMM::encode(uint8_t* data, uint32_t length, uint32_t offset) +{ + assert(data != NULL); + + uint8_t rcch[22U]; + ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); + + rcch[2U] = (m_siteData.locId() >> 8) & 0xFFU; // Location ID + rcch[3U] = (m_siteData.locId() >> 0) & 0xFFU; // ... + rcch[4U] = (m_dstId >> 8U) & 0xFFU; // Target Radio Address + rcch[5U] = (m_dstId >> 0U) & 0xFFU; // ... + + RCCH::encode(data, rcch, length, offset); +} diff --git a/nxdn/lc/rcch/MESSAGE_TYPE_REG_COMM.h b/nxdn/lc/rcch/MESSAGE_TYPE_REG_COMM.h new file mode 100644 index 00000000..00f8491e --- /dev/null +++ b/nxdn/lc/rcch/MESSAGE_TYPE_REG_COMM.h @@ -0,0 +1,57 @@ +/** +* Digital Voice Modem - Host Software +* GPLv2 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / Host Software +* +*/ +/* +* Copyright (C) 2022 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 +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#if !defined(__NXDN_LC_RCCH__MESSAGE_TYPE_REG_COMM_H__) +#define __NXDN_LC_RCCH__MESSAGE_TYPE_REG_COMM_H__ + +#include "Defines.h" +#include "nxdn/lc/RCCH.h" + +namespace nxdn +{ + namespace lc + { + namespace rcch + { + // --------------------------------------------------------------------------- + // Class Declaration + // Implements REG_COMM - Registration Command + // --------------------------------------------------------------------------- + + class HOST_SW_API MESSAGE_TYPE_REG_COMM : public RCCH { + public: + /// Initializes a new instance of the MESSAGE_TYPE_REG_COMM class. + MESSAGE_TYPE_REG_COMM(); + + /// Decode layer 3 data. + virtual void decode(const uint8_t* data, uint32_t length, uint32_t offset = 0U); + /// Encode layer 3 data. + virtual void encode(uint8_t* data, uint32_t length, uint32_t offset = 0U); + }; + } // namespace rcch + } // namespace lc +} // namespace nxdn + +#endif // __NXDN_LC_RCCH__MESSAGE_TYPE_REG_COMM_H__ diff --git a/nxdn/lc/rcch/MESSAGE_TYPE_SITE_INFO.cpp b/nxdn/lc/rcch/MESSAGE_TYPE_SITE_INFO.cpp new file mode 100644 index 00000000..50a730a6 --- /dev/null +++ b/nxdn/lc/rcch/MESSAGE_TYPE_SITE_INFO.cpp @@ -0,0 +1,131 @@ +/** +* Digital Voice Modem - Host Software +* GPLv2 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / Host Software +* +*/ +/* +* Copyright (C) 2022 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 +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#include "Defines.h" +#include "nxdn/lc/rcch/MESSAGE_TYPE_SITE_INFO.h" +#include "Log.h" +#include "Utils.h" + +using namespace nxdn::lc::rcch; +using namespace nxdn::lc; +using namespace nxdn; + +#include +#include + +// --------------------------------------------------------------------------- +// Public Class Members +// --------------------------------------------------------------------------- + +/// +/// Initializes a new instance of the MESSAGE_TYPE_SITE_INFO class. +/// +MESSAGE_TYPE_SITE_INFO::MESSAGE_TYPE_SITE_INFO() : RCCH(), + m_bcchCnt(1U), + m_rcchGroupingCnt(1U), + m_ccchPagingCnt(2U), + m_ccchMultiCnt(2U), + m_rcchIterateCnt(2U) +{ + m_messageType = RCCH_MESSAGE_TYPE_SITE_INFO; +} + +/// +/// Decode layer 3 data. +/// +/// +/// +/// +void MESSAGE_TYPE_SITE_INFO::decode(const uint8_t* data, uint32_t length, uint32_t offset) +{ + assert(data != NULL); + + uint8_t rcch[22U]; + ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); + + RCCH::decode(data, rcch, length, offset); +} + +/// +/// Encode a control signalling block. +/// +/// +/// +/// +void MESSAGE_TYPE_SITE_INFO::encode(uint8_t* data, uint32_t length, uint32_t offset) +{ + assert(data != NULL); + + uint8_t rcch[22U]; + ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); + + rcch[1U] = (m_siteData.locId() >> 16) & 0xFFU; // Location ID + rcch[2U] = (m_siteData.locId() >> 8) & 0xFFU; // ... + rcch[3U] = (m_siteData.locId() >> 0) & 0xFFU; // ... + rcch[4U] = ((m_bcchCnt & 0x03U) << 6) + // Channel Structure - Number of BCCH + ((m_rcchGroupingCnt & 0x07U) << 3) + // ... - Number of Grouping + (((m_ccchPagingCnt >> 1) & 0x07U) << 0); // ... - Number of Paging Frames + rcch[5U] = ((m_ccchPagingCnt & 0x01U) << 7) + // ... - Number of Paging Frames + ((m_ccchMultiCnt & 0x07U) << 4) + // ... - Number of Multipurpose Frames + ((m_rcchIterateCnt & 0x0FU) << 0); // ... - Number of Iteration + + rcch[6U] = m_siteData.serviceClass(); // Service Information + rcch[7U] = (m_siteData.netActive() ? NXDN_SIF2_IP_NETWORK : 0x00U); // ... + + // bryanb: this is currently fixed -- maybe dynamic in the future + rcch[8U] = 0U; // Restriction Information - No access restriction / No cycle restriction + rcch[9U] = 0x08U; // ... - No group restriction / GMS; Location Registration Restriction + rcch[10U] = (!m_siteData.netActive() ? 0x01U : 0x00U); // ... - No group ratio restriction / No delay time extension / ISO + + // bryanb: this is currently fixed -- maybe dynamic in the future + rcch[11U] = NXDN_CH_ACCESS_BASE_FREQ_SYS_DEFINED; // Channel Access Information - Channel Version / Sys Defined Step / Sys Defined Base Freq + + rcch[14U] = 1U; // Version + + uint16_t channelNo = m_siteData.channelNo() & 0x3FFU; + rcch[15U] = (channelNo >> 6) & 0x0FU; // 1st Control Channel + rcch[16U] = (channelNo & 0x3FU) << 2; // ... + + RCCH::encode(data, rcch, length, offset); +} + +// --------------------------------------------------------------------------- +// Private Class Members +// --------------------------------------------------------------------------- + +/// +/// Internal helper to copy the the class. +/// +/// +void MESSAGE_TYPE_SITE_INFO::copy(const MESSAGE_TYPE_SITE_INFO& data) +{ + RCCH::copy(data); + + m_bcchCnt = data.m_bcchCnt; + m_rcchGroupingCnt = data.m_rcchGroupingCnt; + m_ccchPagingCnt = data.m_ccchPagingCnt; + m_ccchMultiCnt = data.m_ccchMultiCnt; + m_rcchIterateCnt = data.m_rcchIterateCnt; +} diff --git a/nxdn/lc/rcch/MESSAGE_TYPE_SITE_INFO.h b/nxdn/lc/rcch/MESSAGE_TYPE_SITE_INFO.h new file mode 100644 index 00000000..d439865b --- /dev/null +++ b/nxdn/lc/rcch/MESSAGE_TYPE_SITE_INFO.h @@ -0,0 +1,72 @@ +/** +* Digital Voice Modem - Host Software +* GPLv2 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / Host Software +* +*/ +/* +* Copyright (C) 2022 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 +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#if !defined(__NXDN_LC_RCCH__MESSAGE_TYPE_SITE_INFO_H__) +#define __NXDN_LC_RCCH__MESSAGE_TYPE_SITE_INFO_H__ + +#include "Defines.h" +#include "nxdn/lc/RCCH.h" + +namespace nxdn +{ + namespace lc + { + namespace rcch + { + // --------------------------------------------------------------------------- + // Class Declaration + // Implements SITE_INFO - Site Information + // --------------------------------------------------------------------------- + + class HOST_SW_API MESSAGE_TYPE_SITE_INFO : public RCCH { + public: + /// Initializes a new instance of the MESSAGE_TYPE_SITE_INFO class. + MESSAGE_TYPE_SITE_INFO(); + + /// Decode layer 3 data. + virtual void decode(const uint8_t* data, uint32_t length, uint32_t offset = 0U); + /// Encode layer 3 data. + virtual void encode(uint8_t* data, uint32_t length, uint32_t offset = 0U); + + public: + /** Channel Structure Data */ + /// Count of BCCH frames per RCCH superframe. + __PROPERTY(uint8_t, bcchCnt, BcchCnt); + /// Count of RCCH frame groupings per RCCH superframe. + __PROPERTY(uint8_t, rcchGroupingCnt, RcchGroupingCnt); + /// Count of CCCH/UPCH paging frames per RCCH superframe. + __PROPERTY(uint8_t, ccchPagingCnt, CcchPagingCnt); + /// Count of CCCH/UPCH multi-purpose frames per RCCH superframe. + __PROPERTY(uint8_t, ccchMultiCnt, CcchMultiCnt); + /// Count of group iterations per RCCH superframe. + __PROPERTY(uint8_t, rcchIterateCnt, RcchIterateCount); + + __COPY(MESSAGE_TYPE_SITE_INFO); + }; + } // namespace rcch + } // namespace lc +} // namespace nxdn + +#endif // __NXDN_LC_RCCH__MESSAGE_TYPE_SITE_INFO_H__ diff --git a/nxdn/lc/rcch/MESSAGE_TYPE_SRV_INFO.cpp b/nxdn/lc/rcch/MESSAGE_TYPE_SRV_INFO.cpp new file mode 100644 index 00000000..2309adac --- /dev/null +++ b/nxdn/lc/rcch/MESSAGE_TYPE_SRV_INFO.cpp @@ -0,0 +1,91 @@ +/** +* Digital Voice Modem - Host Software +* GPLv2 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / Host Software +* +*/ +/* +* Copyright (C) 2022 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 +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#include "Defines.h" +#include "nxdn/lc/rcch/MESSAGE_TYPE_SRV_INFO.h" +#include "Log.h" +#include "Utils.h" + +using namespace nxdn::lc::rcch; +using namespace nxdn::lc; +using namespace nxdn; + +#include +#include + +// --------------------------------------------------------------------------- +// Public Class Members +// --------------------------------------------------------------------------- + +/// +/// Initializes a new instance of the MESSAGE_TYPE_SRV_INFO class. +/// +MESSAGE_TYPE_SRV_INFO::MESSAGE_TYPE_SRV_INFO() : RCCH() +{ + m_messageType = nxdn::MESSAGE_TYPE_SRV_INFO; +} + +/// +/// Decode layer 3 data. +/// +/// +/// +/// +void MESSAGE_TYPE_SRV_INFO::decode(const uint8_t* data, uint32_t length, uint32_t offset) +{ + assert(data != NULL); + + uint8_t rcch[22U]; + ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); + + RCCH::decode(data, rcch, length, offset); +} + +/// +/// Encode a control signalling block. +/// +/// +/// +/// +void MESSAGE_TYPE_SRV_INFO::encode(uint8_t* data, uint32_t length, uint32_t offset) +{ + assert(data != NULL); + + uint8_t rcch[22U]; + ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); + + rcch[1U] = (m_siteData.locId() >> 16) & 0xFFU; // Location ID + rcch[2U] = (m_siteData.locId() >> 8) & 0xFFU; // ... + rcch[3U] = (m_siteData.locId() >> 0) & 0xFFU; // ... + rcch[4U] = m_siteData.serviceClass(); // Service Information + rcch[5U] = (m_siteData.netActive() ? NXDN_SIF2_IP_NETWORK : 0x00U); // ... + + // bryanb: this is currently fixed -- maybe dynamic in the future + rcch[6U] = 0U; // Restriction Information - No access restriction / No cycle restriction + rcch[7U] = 0x08U; // ... - No group restriction / GMS; Location Registration Restriction + rcch[8U] = (!m_siteData.netActive() ? 0x01U : 0x00U); // ... - No group ratio restriction / No delay time extension / ISO + + RCCH::encode(data, rcch, length, offset); +} diff --git a/nxdn/lc/rcch/MESSAGE_TYPE_SRV_INFO.h b/nxdn/lc/rcch/MESSAGE_TYPE_SRV_INFO.h new file mode 100644 index 00000000..b6a6b689 --- /dev/null +++ b/nxdn/lc/rcch/MESSAGE_TYPE_SRV_INFO.h @@ -0,0 +1,57 @@ +/** +* Digital Voice Modem - Host Software +* GPLv2 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / Host Software +* +*/ +/* +* Copyright (C) 2022 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 +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#if !defined(__NXDN_LC_RCCH__MESSAGE_TYPE_SRV_INFO_H__) +#define __NXDN_LC_RCCH__MESSAGE_TYPE_SRV_INFO_H__ + +#include "Defines.h" +#include "nxdn/lc/RCCH.h" + +namespace nxdn +{ + namespace lc + { + namespace rcch + { + // --------------------------------------------------------------------------- + // Class Declaration + // Implements SRV_INFO - Service Information + // --------------------------------------------------------------------------- + + class HOST_SW_API MESSAGE_TYPE_SRV_INFO : public RCCH { + public: + /// Initializes a new instance of the MESSAGE_TYPE_SRV_INFO class. + MESSAGE_TYPE_SRV_INFO(); + + /// Decode layer 3 data. + virtual void decode(const uint8_t* data, uint32_t length, uint32_t offset = 0U); + /// Encode layer 3 data. + virtual void encode(uint8_t* data, uint32_t length, uint32_t offset = 0U); + }; + } // namespace rcch + } // namespace lc +} // namespace nxdn + +#endif // __NXDN_LC_RCCH__MESSAGE_TYPE_SRV_INFO_H__ diff --git a/nxdn/lc/rcch/MESSAGE_TYPE_VCALL_ASSGN.cpp b/nxdn/lc/rcch/MESSAGE_TYPE_VCALL_ASSGN.cpp new file mode 100644 index 00000000..a2978763 --- /dev/null +++ b/nxdn/lc/rcch/MESSAGE_TYPE_VCALL_ASSGN.cpp @@ -0,0 +1,97 @@ +/** +* Digital Voice Modem - Host Software +* GPLv2 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / Host Software +* +*/ +/* +* Copyright (C) 2022 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 +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#include "Defines.h" +#include "nxdn/lc/rcch/MESSAGE_TYPE_VCALL_ASSGN.h" +#include "Log.h" +#include "Utils.h" + +using namespace nxdn::lc::rcch; +using namespace nxdn::lc; +using namespace nxdn; + +#include +#include + +// --------------------------------------------------------------------------- +// Public Class Members +// --------------------------------------------------------------------------- + +/// +/// Initializes a new instance of the MESSAGE_TYPE_VCALL_ASSGN class. +/// +MESSAGE_TYPE_VCALL_ASSGN::MESSAGE_TYPE_VCALL_ASSGN() : RCCH() +{ + m_messageType = RCCH_MESSAGE_TYPE_VCALL_ASSGN; +} + +/// +/// Decode layer 3 data. +/// +/// +/// +/// +void MESSAGE_TYPE_VCALL_ASSGN::decode(const uint8_t* data, uint32_t length, uint32_t offset) +{ + assert(data != NULL); + + uint8_t rcch[22U]; + ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); + + RCCH::decode(data, rcch, length, offset); +} + +/// +/// Encode a control signalling block. +/// +/// +/// +/// +void MESSAGE_TYPE_VCALL_ASSGN::encode(uint8_t* data, uint32_t length, uint32_t offset) +{ + assert(data != NULL); + + uint8_t rcch[22U]; + ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); + + rcch[1U] = (m_emergency ? 0x80U : 0x00U) + // Emergency Flag + (m_priority ? 0x20U : 0x00U); // Priority Flag + rcch[2U] = ((m_callType & 0x07U) << 5) + // Call Type + (m_duplex ? 0x10U : 0x00U) + // Half/Full Duplex Flag + (m_transmissionMode & 0x07U); // Transmission Mode + + rcch[3U] = (m_srcId >> 8U) & 0xFFU; // Source Radio Address + rcch[4U] = (m_srcId >> 0U) & 0xFFU; // ... + rcch[5U] = (m_dstId >> 8U) & 0xFFU; // Target Radio Address + rcch[6U] = (m_dstId >> 0U) & 0xFFU; // ... + + rcch[7U] = (m_grpVchNo >> 10) & 0x03U; // Channel + rcch[8U] = (m_grpVchNo & 0xFFU); // ... + + rcch[10U] = (m_siteData.locId() >> 8) & 0xFFU; // Location ID + rcch[11U] = (m_siteData.locId() >> 0) & 0xFFU; // ... + + RCCH::encode(data, rcch, length, offset); +} diff --git a/nxdn/lc/rcch/MESSAGE_TYPE_VCALL_ASSGN.h b/nxdn/lc/rcch/MESSAGE_TYPE_VCALL_ASSGN.h new file mode 100644 index 00000000..b78b806b --- /dev/null +++ b/nxdn/lc/rcch/MESSAGE_TYPE_VCALL_ASSGN.h @@ -0,0 +1,57 @@ +/** +* Digital Voice Modem - Host Software +* GPLv2 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / Host Software +* +*/ +/* +* Copyright (C) 2022 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 +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#if !defined(__NXDN_LC_RCCH__MESSAGE_TYPE_VCALL_ASSGN_H__) +#define __NXDN_LC_RCCH__MESSAGE_TYPE_VCALL_ASSGN_H__ + +#include "Defines.h" +#include "nxdn/lc/RCCH.h" + +namespace nxdn +{ + namespace lc + { + namespace rcch + { + // --------------------------------------------------------------------------- + // Class Declaration + // Implements VCALL_ASSGN - Voice Call Assignment + // --------------------------------------------------------------------------- + + class HOST_SW_API MESSAGE_TYPE_VCALL_ASSGN : public RCCH { + public: + /// Initializes a new instance of the MESSAGE_TYPE_VCALL_ASSGN class. + MESSAGE_TYPE_VCALL_ASSGN(); + + /// Decode layer 3 data. + virtual void decode(const uint8_t* data, uint32_t length, uint32_t offset = 0U); + /// Encode layer 3 data. + virtual void encode(uint8_t* data, uint32_t length, uint32_t offset = 0U); + }; + } // namespace rcch + } // namespace lc +} // namespace nxdn + +#endif // __NXDN_LC_RCCH__MESSAGE_TYPE_VCALL_ASSGN_H__ diff --git a/nxdn/lc/rcch/MESSAGE_TYPE_VCALL_CONN.cpp b/nxdn/lc/rcch/MESSAGE_TYPE_VCALL_CONN.cpp new file mode 100644 index 00000000..0ee8ecee --- /dev/null +++ b/nxdn/lc/rcch/MESSAGE_TYPE_VCALL_CONN.cpp @@ -0,0 +1,103 @@ +/** +* Digital Voice Modem - Host Software +* GPLv2 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / Host Software +* +*/ +/* +* Copyright (C) 2022 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 +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#include "Defines.h" +#include "nxdn/lc/rcch/MESSAGE_TYPE_VCALL_CONN.h" +#include "Log.h" +#include "Utils.h" + +using namespace nxdn::lc::rcch; +using namespace nxdn::lc; +using namespace nxdn; + +#include +#include + +// --------------------------------------------------------------------------- +// Public Class Members +// --------------------------------------------------------------------------- + +/// +/// Initializes a new instance of the MESSAGE_TYPE_VCALL_CONN class. +/// +MESSAGE_TYPE_VCALL_CONN::MESSAGE_TYPE_VCALL_CONN() : RCCH() +{ + m_messageType = RCCH_MESSAGE_TYPE_VCALL_CONN; +} + +/// +/// Decode layer 3 data. +/// +/// +/// +/// +void MESSAGE_TYPE_VCALL_CONN::decode(const uint8_t* data, uint32_t length, uint32_t offset) +{ + assert(data != NULL); + + uint8_t rcch[22U]; + ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); + + RCCH::decode(data, rcch, length, offset); + + m_callType = (rcch[2U] >> 5) & 0x07U; // Call Type + m_emergency = (rcch[1U] & 0x80U) == 0x80U; // Emergency Flag + m_priority = (rcch[1U] & 0x20U) == 0x20U; // Priority Flag + m_duplex = (rcch[2U] & 0x10U) == 0x10U; // Half/Full Duplex Flag + m_transmissionMode = (rcch[2U] & 0x07U); // Transmission Mode + m_srcId = (uint16_t)((rcch[3U] << 8) | rcch[4U]) & 0xFFFFU; // Source Radio Address + m_dstId = (uint16_t)((rcch[5U] << 8) | rcch[6U]) & 0xFFFFU; // Target Radio Address +} + +/// +/// Encode a control signalling block. +/// +/// +/// +/// +void MESSAGE_TYPE_VCALL_CONN::encode(uint8_t* data, uint32_t length, uint32_t offset) +{ + assert(data != NULL); + + uint8_t rcch[22U]; + ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); + + rcch[1U] = (m_emergency ? 0x80U : 0x00U) + // Emergency Flag + (m_priority ? 0x20U : 0x00U); // Priority Flag + rcch[2U] = ((m_callType & 0x07U) << 5) + // Call Type + (m_duplex ? 0x10U : 0x00U) + // Half/Full Duplex Flag + (m_transmissionMode & 0x07U); // Transmission Mode + + rcch[3U] = (m_srcId >> 8U) & 0xFFU; // Source Radio Address + rcch[4U] = (m_srcId >> 0U) & 0xFFU; // ... + rcch[5U] = (m_dstId >> 8U) & 0xFFU; // Target Radio Address + rcch[6U] = (m_dstId >> 0U) & 0xFFU; // ... + + rcch[7U] = m_causeRsp; // Cause (VD) + rcch[9U] = (m_siteData.locId() >> 8) & 0xFFU; // Location ID + rcch[10U] = (m_siteData.locId() >> 0) & 0xFFU; // ... + + RCCH::encode(data, rcch, length, offset); +} diff --git a/nxdn/lc/rcch/MESSAGE_TYPE_VCALL_CONN.h b/nxdn/lc/rcch/MESSAGE_TYPE_VCALL_CONN.h new file mode 100644 index 00000000..e6d5a29a --- /dev/null +++ b/nxdn/lc/rcch/MESSAGE_TYPE_VCALL_CONN.h @@ -0,0 +1,58 @@ +/** +* Digital Voice Modem - Host Software +* GPLv2 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / Host Software +* +*/ +/* +* Copyright (C) 2022 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 +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#if !defined(__NXDN_LC_RCCH__MESSAGE_TYPE_VCALL_CONN_H__) +#define __NXDN_LC_RCCH__MESSAGE_TYPE_VCALL_CONN_H__ + +#include "Defines.h" +#include "nxdn/lc/RCCH.h" + +namespace nxdn +{ + namespace lc + { + namespace rcch + { + // --------------------------------------------------------------------------- + // Class Declaration + // Implements VCALL_CONN - Voice Call Connection Request (ISP) and + // Voice Call Connection Response (OSP) + // --------------------------------------------------------------------------- + + class HOST_SW_API MESSAGE_TYPE_VCALL_CONN : public RCCH { + public: + /// Initializes a new instance of the MESSAGE_TYPE_VCALL_CONN class. + MESSAGE_TYPE_VCALL_CONN(); + + /// Decode layer 3 data. + virtual void decode(const uint8_t* data, uint32_t length, uint32_t offset = 0U); + /// Encode layer 3 data. + virtual void encode(uint8_t* data, uint32_t length, uint32_t offset = 0U); + }; + } // namespace rcch + } // namespace lc +} // namespace nxdn + +#endif // __NXDN_LC_RCCH__MESSAGE_TYPE_VCALL_CONN_H__ diff --git a/nxdn/lc/rcch/RCCHFactory.cpp b/nxdn/lc/rcch/RCCHFactory.cpp new file mode 100644 index 00000000..4c28ee67 --- /dev/null +++ b/nxdn/lc/rcch/RCCHFactory.cpp @@ -0,0 +1,120 @@ +/** +* Digital Voice Modem - Host Software +* GPLv2 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / Host Software +* +*/ +/* +* Copyright (C) 2022 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 +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#include "Defines.h" +#include "nxdn/lc/rcch/RCCHFactory.h" +#include "Log.h" +#include "Utils.h" + +using namespace nxdn::lc::rcch; +using namespace nxdn::lc; +using namespace nxdn; + +#include + +// --------------------------------------------------------------------------- +// Public Class Members +// --------------------------------------------------------------------------- + +/// +/// Initializes a new instance of the RCCHFactory class. +/// +RCCHFactory::RCCHFactory() +{ + /* stub */ +} + +/// +/// Finalizes a instance of RCCHFactory class. +/// +RCCHFactory::~RCCHFactory() +{ + /* stub */ +} + +/// +/// Create an instance of a RCCH. +/// +/// +/// +/// +/// True, if RCCH was decoded, otherwise false. +std::unique_ptr RCCHFactory::createRCCH(const uint8_t* data, uint32_t length, uint32_t offset) +{ + assert(data != nullptr); + + uint8_t rcch[22U]; + ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); + + for (uint32_t i = 0U; i < length; i++, offset++) { + bool b = READ_BIT(data, offset); + WRITE_BIT(rcch, i, b); + } + + uint8_t messageType = data[0U] & 0x3FU; // Message Type + + // message type opcodes + switch (messageType) { + case RTCH_MESSAGE_TYPE_VCALL: + case RCCH_MESSAGE_TYPE_VCALL_CONN: + return decode(new MESSAGE_TYPE_VCALL_CONN(), data, length, offset); + case RTCH_MESSAGE_TYPE_DCALL_HDR: + return decode(new MESSAGE_TYPE_DCALL_HDR(), data, length, offset); + case nxdn::MESSAGE_TYPE_IDLE: + return decode(new MESSAGE_TYPE_IDLE(), data, length, offset); + case RCCH_MESSAGE_TYPE_REG: + return decode(new MESSAGE_TYPE_REG(), data, length, offset); + case RCCH_MESSAGE_TYPE_REG_C: + return decode(new MESSAGE_TYPE_REG_C(), data, length, offset); + case RCCH_MESSAGE_TYPE_GRP_REG: + return decode(new MESSAGE_TYPE_GRP_REG(), data, length, offset); + default: + LogError(LOG_NXDN, "RCCH::decodeRCCH(), unknown RCCH value, messageType = $%02X", messageType); + return nullptr; + } + + return nullptr; +} + +// --------------------------------------------------------------------------- +// Private Class Members +// --------------------------------------------------------------------------- + +/// +/// +/// +/// +/// +/// +/// +/// +std::unique_ptr RCCHFactory::decode(RCCH* rcch, const uint8_t* data, uint32_t length, uint32_t offset) +{ + assert(rcch != nullptr); + assert(data != nullptr); + + rcch->decode(data, length, offset); + return std::unique_ptr(rcch); +} diff --git a/nxdn/lc/rcch/RCCHFactory.h b/nxdn/lc/rcch/RCCHFactory.h new file mode 100644 index 00000000..0dd83549 --- /dev/null +++ b/nxdn/lc/rcch/RCCHFactory.h @@ -0,0 +1,73 @@ +/** +* Digital Voice Modem - Host Software +* GPLv2 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / Host Software +* +*/ +/* +* Copyright (C) 2022 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 +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#if !defined(__NXDN_LC__RCCH_FACTORY_H__) +#define __NXDN_LC__RCCH_FACTORY_H__ + +#include "Defines.h" + +#include "nxdn/lc/RCCH.h" +#include "nxdn/lc/rcch/MESSAGE_TYPE_DCALL_HDR.h" +#include "nxdn/lc/rcch/MESSAGE_TYPE_DST_ID_INFO.h" +#include "nxdn/lc/rcch/MESSAGE_TYPE_GRP_REG.h" +#include "nxdn/lc/rcch/MESSAGE_TYPE_IDLE.h" +#include "nxdn/lc/rcch/MESSAGE_TYPE_REG_C.h" +#include "nxdn/lc/rcch/MESSAGE_TYPE_REG_COMM.h" +#include "nxdn/lc/rcch/MESSAGE_TYPE_REG.h" +#include "nxdn/lc/rcch/MESSAGE_TYPE_SITE_INFO.h" +#include "nxdn/lc/rcch/MESSAGE_TYPE_SRV_INFO.h" +#include "nxdn/lc/rcch/MESSAGE_TYPE_VCALL_ASSGN.h" +#include "nxdn/lc/rcch/MESSAGE_TYPE_VCALL_CONN.h" + +namespace nxdn +{ + namespace lc + { + namespace rcch + { + // --------------------------------------------------------------------------- + // Class Declaration + // Helper class to instantiate an instance of a RCCH. + // --------------------------------------------------------------------------- + + class HOST_SW_API RCCHFactory { + public: + /// Initializes a new instance of the RCCHFactory class. + RCCHFactory(); + /// Finalizes a instance of the RCCHFactory class. + ~RCCHFactory(); + + /// Create an instance of a RCCH. + static std::unique_ptr createRCCH(const uint8_t* data, uint32_t length, uint32_t offset = 0U); + + private: + /// + static std::unique_ptr decode(RCCH* rcch, const uint8_t* data, uint32_t length, uint32_t offset = 0U); + }; + } // namespace rcch + } // namespace lc +} // namespace nxdn + +#endif // __NXDN_LC__RCCH_FACTORY_H__ diff --git a/nxdn/packet/Trunk.cpp b/nxdn/packet/Trunk.cpp index aeb353f7..5efe5fd8 100644 --- a/nxdn/packet/Trunk.cpp +++ b/nxdn/packet/Trunk.cpp @@ -32,6 +32,7 @@ #include "nxdn/channel/CAC.h" #include "nxdn/packet/Trunk.h" #include "nxdn/acl/AccessControl.h" +#include "nxdn/lc/rcch/RCCHFactory.h" #include "nxdn/Sync.h" #include "nxdn/NXDNUtils.h" #include "edac/CRC.h" @@ -40,6 +41,7 @@ #include "Utils.h" using namespace nxdn; +using namespace nxdn::lc; using namespace nxdn::packet; #include @@ -55,7 +57,7 @@ using namespace nxdn::packet; #define IS_SUPPORT_CONTROL_CHECK(_PCKT_STR, _PCKT, _SRCID) \ if (!m_nxdn->m_control) { \ LogWarning(LOG_RF, "NXDN, " _PCKT_STR " denial, unsupported service, srcId = %u", _SRCID); \ - writeRF_Message_Deny(NXDN_CAUSE_SVC_UNAVAILABLE, _PCKT); \ + writeRF_Message_Deny(0U, _SRCID, NXDN_CAUSE_SVC_UNAVAILABLE, _PCKT); \ m_nxdn->m_rfState = RS_RF_REJECTED; \ return false; \ } @@ -64,7 +66,7 @@ using namespace nxdn::packet; #define VALID_SRCID(_PCKT_STR, _PCKT, _SRCID, _RSN) \ if (!acl::AccessControl::validateSrcId(_SRCID)) { \ LogWarning(LOG_RF, "NXDN, " _PCKT_STR " denial, RID rejection, srcId = %u", _SRCID); \ - writeRF_Message_Deny(_RSN, _PCKT); \ + writeRF_Message_Deny(0U, _SRCID, _RSN, _PCKT); \ m_nxdn->m_rfState = RS_RF_REJECTED; \ return false; \ } @@ -73,16 +75,16 @@ using namespace nxdn::packet; #define VALID_DSTID(_PCKT_STR, _PCKT, _DSTID, _RSN) \ if (!acl::AccessControl::validateSrcId(_DSTID)) { \ LogWarning(LOG_RF, "NXDN, " _PCKT_STR " denial, RID rejection, dstId = %u", _DSTID); \ - writeRF_Message_Deny(_RSN, _PCKT); \ + writeRF_Message_Deny(0U, _SRCID, _RSN, _PCKT); \ m_nxdn->m_rfState = RS_RF_REJECTED; \ return false; \ } // Validate the talkgroup ID. -#define VALID_TGID(_PCKT_STR, _PCKT, _DSTID, _RSN) \ +#define VALID_TGID(_PCKT_STR, _PCKT, _DSTID, _SRCID, _RSN) \ if (!acl::AccessControl::validateTGId(_DSTID)) { \ LogWarning(LOG_RF, "NXDN, " _PCKT_STR " denial, TGID rejection, dstId = %u", _DSTID); \ - writeRF_Message_Deny(_RSN, _PCKT); \ + writeRF_Message_Deny(0U, _SRCID, _RSN, _PCKT); \ m_nxdn->m_rfState = RS_RF_REJECTED; \ return false; \ } @@ -91,7 +93,7 @@ using namespace nxdn::packet; #define VERIFY_SRCID_REG(_PCKT_STR, _PCKT, _SRCID, _RSN) \ if (!m_nxdn->m_affiliations.isUnitReg(_SRCID) && m_verifyReg) { \ LogWarning(LOG_RF, "NXDN, " _PCKT_STR " denial, RID not registered, srcId = %u", _SRCID); \ - writeRF_Message_Deny(_RSN, _PCKT); \ + writeRF_Message_Deny(0U, _SRCID, _RSN, _PCKT); \ m_nxdn->m_rfState = RS_RF_REJECTED; \ return false; \ } @@ -100,7 +102,7 @@ using namespace nxdn::packet; #define VERIFY_SRCID_AFF(_PCKT_STR, _PCKT, _SRCID, _DSTID, _RSN) \ if (!m_nxdn->m_affiliations.isGroupAff(_SRCID, _DSTID) && m_verifyAff) { \ LogWarning(LOG_RF, "NXDN, " _PCKT_STR " denial, RID not affiliated to TGID, srcId = %u, dstId = %u", _SRCID, _DSTID); \ - writeRF_Message_Deny(_RSN, _PCKT); \ + writeRF_Message_Deny(0U, _SRCID, _RSN, _PCKT); \ m_nxdn->m_rfState = RS_RF_REJECTED; \ return false; \ } @@ -115,24 +117,6 @@ const uint32_t GRANT_TIMER_TIMEOUT = 15U; // Public Class Members // --------------------------------------------------------------------------- -/// -/// Resets the data states for the RF interface. -/// -void Trunk::resetRF() -{ - lc::RCCH lc = lc::RCCH(m_nxdn->m_siteData, m_nxdn->m_idenEntry, m_dumpRCCH); - m_rfLC = lc; -} - -/// -/// Resets the data states for the network. -/// -void Trunk::resetNet() -{ - lc::RCCH lc = lc::RCCH(m_nxdn->m_siteData, m_nxdn->m_idenEntry, m_dumpRCCH); - m_netLC = lc; -} - /// /// Process a data frame from the RF interface. /// @@ -167,13 +151,16 @@ bool Trunk::process(uint8_t fct, uint8_t option, uint8_t* data, uint32_t len) uint8_t buffer[NXDN_FRAME_LENGTH_BYTES]; cac.getData(buffer); - m_rfLC.decode(buffer, NXDN_RCCH_CAC_LC_SHORT_LENGTH_BITS); + std::unique_ptr rcch = rcch::RCCHFactory::createRCCH(buffer, NXDN_RCCH_CAC_LC_SHORT_LENGTH_BITS); + if (rcch == nullptr) + return false; - uint16_t srcId = m_rfLC.getSrcId(); - uint16_t dstId = m_rfLC.getDstId(); + uint16_t srcId = rcch->getSrcId(); + uint16_t dstId = rcch->getDstId(); - switch (m_rfLC.getMessageType()) { + switch (rcch->getMessageType()) { case RTCH_MESSAGE_TYPE_VCALL: + { // make sure control data is supported IS_SUPPORT_CONTROL_CHECK(NXDN_RTCH_MSG_TYPE_VCALL_REQ, RTCH_MESSAGE_TYPE_VCALL, srcId); @@ -181,7 +168,7 @@ bool Trunk::process(uint8_t fct, uint8_t option, uint8_t* data, uint32_t len) VALID_SRCID(NXDN_RTCH_MSG_TYPE_VCALL_REQ, RTCH_MESSAGE_TYPE_VCALL, srcId, NXDN_CAUSE_VD_REQ_UNIT_NOT_PERM); // validate the talkgroup ID - VALID_TGID(NXDN_RTCH_MSG_TYPE_VCALL_REQ, RTCH_MESSAGE_TYPE_VCALL, dstId, NXDN_CAUSE_VD_TGT_UNIT_NOT_PERM); + VALID_TGID(NXDN_RTCH_MSG_TYPE_VCALL_REQ, RTCH_MESSAGE_TYPE_VCALL, dstId, srcId, NXDN_CAUSE_VD_TGT_UNIT_NOT_PERM); // verify the source RID is affiliated VERIFY_SRCID_AFF(NXDN_RTCH_MSG_TYPE_VCALL_REQ, RTCH_MESSAGE_TYPE_VCALL, srcId, dstId, NXDN_CAUSE_VD_REQ_UNIT_NOT_REG); @@ -190,30 +177,39 @@ bool Trunk::process(uint8_t fct, uint8_t option, uint8_t* data, uint32_t len) LogMessage(LOG_RF, "NXDN, " NXDN_RTCH_MSG_TYPE_VCALL_REQ ", srcId = %u, dstId = %u", srcId, dstId); } - writeRF_Message_Grant(true); - break; + uint8_t serviceOptions = (rcch->getEmergency() ? 0x80U : 0x00U) + // Emergency Flag + (rcch->getEncrypted() ? 0x40U : 0x00U) + // Encrypted Flag + (rcch->getPriority() & 0x07U); // Priority + + writeRF_Message_Grant(srcId, dstId, serviceOptions, true); + } + break; case RCCH_MESSAGE_TYPE_REG: + { // make sure control data is supported IS_SUPPORT_CONTROL_CHECK(NXDN_RCCH_MSG_TYPE_REG_REQ, RCCH_MESSAGE_TYPE_REG, srcId); if (m_verbose) { - LogMessage(LOG_RF, "NXDN, " NXDN_RCCH_MSG_TYPE_REG_REQ ", srcId = %u", srcId); + LogMessage(LOG_RF, "NXDN, " NXDN_RCCH_MSG_TYPE_REG_REQ ", srcId = %u, locId = %u", srcId, rcch->getLocId()); } - writeRF_Message_U_Reg_Rsp(srcId); - break; + writeRF_Message_U_Reg_Rsp(srcId, rcch->getLocId()); + } + break; case RCCH_MESSAGE_TYPE_GRP_REG: + { // make sure control data is supported IS_SUPPORT_CONTROL_CHECK(NXDN_RCCH_MSG_TYPE_GRP_REG_REQ, RCCH_MESSAGE_TYPE_GRP_REG, srcId); if (m_verbose) { - LogMessage(LOG_RF, "NXDN, " NXDN_RCCH_MSG_TYPE_GRP_REG_REQ ", srcId = %u, dstId = %u", srcId, dstId); + LogMessage(LOG_RF, "NXDN, " NXDN_RCCH_MSG_TYPE_GRP_REG_REQ ", srcId = %u, dstId = %u, locId = %u", srcId, dstId, rcch->getLocId()); } - writeRF_Message_Grp_Reg_Rsp(srcId, dstId); - break; + writeRF_Message_Grp_Reg_Rsp(srcId, dstId, rcch->getLocId()); + } + break; default: - LogError(LOG_RF, "NXDN, unhandled message type, messageType = $%02X", m_rfLC.getMessageType()); + LogError(LOG_RF, "NXDN, unhandled message type, messageType = $%02X", rcch->getMessageType()); break; } @@ -236,9 +232,6 @@ bool Trunk::processNetwork(uint8_t fct, uint8_t option, lc::RTCH& netLC, uint8_t if (m_nxdn->m_netState == RS_NET_IDLE) { m_nxdn->m_queue.clear(); - - resetRF(); - resetNet(); } return true; @@ -260,11 +253,7 @@ void Trunk::clock(uint32_t ms) // do we have a grant response? if (m_nxdn->m_network->readGrantRsp(grp, srcId, dstId, grpVchNo)) { - m_rfLC.setSrcId(srcId); - m_rfLC.setDstId(dstId); - m_rfLC.setGrpVchNo(grpVchNo); - - writeRF_Message_Grant(grp, true, true, true); + writeRF_Message_Grant(srcId, dstId, 0U, grp, true, grpVchNo, true, true); } } } @@ -283,18 +272,19 @@ void Trunk::clock(uint32_t ms) /// /// Instance of the Control class. /// Instance of the BaseNetwork class. -/// Flag indicating whether RCCH data is dumped to the log. /// Flag indicating whether NXDN debug is enabled. /// Flag indicating whether NXDN verbose logging is enabled. -Trunk::Trunk(Control* nxdn, network::BaseNetwork* network, bool dumpRCCHData, bool debug, bool verbose) : +Trunk::Trunk(Control* nxdn, network::BaseNetwork* network, bool debug, bool verbose) : m_nxdn(nxdn), m_network(network), + m_bcchCnt(1U), + m_rcchGroupingCnt(1U), + m_ccchPagingCnt(2U), + m_ccchMultiCnt(2U), + m_rcchIterateCnt(2U), m_verifyAff(false), m_verifyReg(false), - m_rfLC(SiteData(), lookups::IdenTable()), - m_netLC(SiteData(), lookups::IdenTable()), m_lastRejectId(0U), - m_dumpRCCH(dumpRCCHData), m_verbose(verbose), m_debug(debug) { @@ -372,9 +362,10 @@ void Trunk::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adjSS) /// /// Helper to write a single-block RCCH packet. /// +/// /// /// -void Trunk::writeRF_Message(bool noNetwork, bool clearBeforeWrite) +void Trunk::writeRF_Message(RCCH* rcch, bool noNetwork, bool clearBeforeWrite) { if (!m_nxdn->m_control) return; @@ -395,8 +386,7 @@ void Trunk::writeRF_Message(bool noNetwork, bool clearBeforeWrite) uint8_t buffer[NXDN_RCCH_LC_LENGTH_BYTES]; ::memset(buffer, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES); - m_rfLC.setVerbose(m_dumpRCCH); - m_rfLC.encode(buffer, NXDN_RCCH_LC_LENGTH_BITS); + rcch->encode(buffer, NXDN_RCCH_LC_LENGTH_BITS); // generate the CAC channel::CAC cac; @@ -428,19 +418,25 @@ void Trunk::writeRF_Message(bool noNetwork, bool clearBeforeWrite) /// /// Helper to write a grant packet. /// +/// +/// +/// /// /// +/// /// /// /// -bool Trunk::writeRF_Message_Grant(bool grp, bool skip, bool net, bool skipNetCheck) +bool Trunk::writeRF_Message_Grant(uint32_t srcId, uint32_t dstId, uint8_t serviceOptions, bool grp, bool skip, uint32_t chNo, bool net, bool skipNetCheck) { - uint8_t messageType = m_rfLC.getMessageType(); + bool emergency = ((serviceOptions & 0xFFU) & 0x80U) == 0x80U; // Emergency Flag + bool encryption = ((serviceOptions & 0xFFU) & 0x40U) == 0x40U; // Encryption Flag + uint8_t priority = ((serviceOptions & 0xFFU) & 0x07U); // Priority // do we have a network connection and are we handling grants at the network? if (m_nxdn->m_network != nullptr) { if (m_nxdn->m_network->isHandlingChGrants() && m_nxdn->m_siteData.netActive() && !skipNetCheck) { - return m_nxdn->m_network->writeGrantReq(grp, m_rfLC.getSrcId(), m_rfLC.getDstId()); + return m_nxdn->m_network->writeGrantReq(grp, srcId, dstId); } } @@ -448,127 +444,137 @@ bool Trunk::writeRF_Message_Grant(bool grp, bool skip, bool net, bool skipNetChe if (!skip) { if (m_nxdn->m_rfState != RS_RF_LISTENING && m_nxdn->m_rfState != RS_RF_DATA) { if (!net) { - LogWarning(LOG_RF, "NXDN, " NXDN_RTCH_MSG_TYPE_VCALL_REQ " denied, traffic in progress, dstId = %u", m_rfLC.getDstId()); - writeRF_Message_Deny(NXDN_CAUSE_VD_QUE_GRP_BUSY, RTCH_MESSAGE_TYPE_VCALL); + LogWarning(LOG_RF, "NXDN, " NXDN_RTCH_MSG_TYPE_VCALL_REQ " denied, traffic in progress, dstId = %u", dstId); + writeRF_Message_Deny(0U, srcId, NXDN_CAUSE_VD_QUE_GRP_BUSY, RTCH_MESSAGE_TYPE_VCALL); - ::ActivityLog("NXDN", true, "group grant request from %u to TG %u denied", m_rfLC.getSrcId(), m_rfLC.getDstId()); + ::ActivityLog("NXDN", true, "group grant request from %u to TG %u denied", srcId, dstId); m_nxdn->m_rfState = RS_RF_REJECTED; } - m_rfLC.setMessageType(messageType); return false; } - if (m_nxdn->m_netState != RS_NET_IDLE && m_rfLC.getDstId() == m_nxdn->m_netLastDstId) { + if (m_nxdn->m_netState != RS_NET_IDLE && dstId == m_nxdn->m_netLastDstId) { if (!net) { - LogWarning(LOG_RF, "NXDN, " NXDN_RTCH_MSG_TYPE_VCALL_REQ " denied, traffic in progress, dstId = %u", m_rfLC.getDstId()); - writeRF_Message_Deny(NXDN_CAUSE_VD_QUE_GRP_BUSY, RTCH_MESSAGE_TYPE_VCALL); + LogWarning(LOG_RF, "NXDN, " NXDN_RTCH_MSG_TYPE_VCALL_REQ " denied, traffic in progress, dstId = %u", dstId); + writeRF_Message_Deny(0U, srcId, NXDN_CAUSE_VD_QUE_GRP_BUSY, RTCH_MESSAGE_TYPE_VCALL); - ::ActivityLog("NXDN", true, "group grant request from %u to TG %u denied", m_rfLC.getSrcId(), m_rfLC.getDstId()); + ::ActivityLog("NXDN", true, "group grant request from %u to TG %u denied", srcId, dstId); m_nxdn->m_rfState = RS_RF_REJECTED; } - m_rfLC.setMessageType(messageType); return false; } // don't transmit grants if the destination ID's don't match and the network TG hang timer is running if (m_nxdn->m_rfLastDstId != 0U) { - if (m_nxdn->m_rfLastDstId != m_rfLC.getDstId() && (m_nxdn->m_rfTGHang.isRunning() && !m_nxdn->m_rfTGHang.hasExpired())) { + if (m_nxdn->m_rfLastDstId != dstId && (m_nxdn->m_rfTGHang.isRunning() && !m_nxdn->m_rfTGHang.hasExpired())) { if (!net) { - writeRF_Message_Deny(NXDN_CAUSE_VD_QUE_GRP_BUSY, RTCH_MESSAGE_TYPE_VCALL); + writeRF_Message_Deny(0U, srcId, NXDN_CAUSE_VD_QUE_GRP_BUSY, RTCH_MESSAGE_TYPE_VCALL); m_nxdn->m_rfState = RS_RF_REJECTED; } - m_rfLC.setMessageType(messageType); return false; } } - if (!m_nxdn->m_affiliations.isGranted(m_rfLC.getDstId())) { + if (!m_nxdn->m_affiliations.isGranted(dstId)) { if (!m_nxdn->m_affiliations.isRFChAvailable()) { if (grp) { if (!net) { - LogWarning(LOG_RF, "NXDN, " NXDN_RTCH_MSG_TYPE_VCALL_REQ " queued, no channels available, dstId = %u", m_rfLC.getDstId()); - writeRF_Message_Deny(NXDN_CAUSE_VD_QUE_CHN_RESOURCE_NOT_AVAIL, RTCH_MESSAGE_TYPE_VCALL); + LogWarning(LOG_RF, "NXDN, " NXDN_RTCH_MSG_TYPE_VCALL_REQ " queued, no channels available, dstId = %u", dstId); + writeRF_Message_Deny(0U, srcId, NXDN_CAUSE_VD_QUE_CHN_RESOURCE_NOT_AVAIL, RTCH_MESSAGE_TYPE_VCALL); - ::ActivityLog("NXDN", true, "group grant request from %u to TG %u queued", m_rfLC.getSrcId(), m_rfLC.getDstId()); + ::ActivityLog("NXDN", true, "group grant request from %u to TG %u queued", srcId, dstId); m_nxdn->m_rfState = RS_RF_REJECTED; } - m_rfLC.setMessageType(messageType); return false; } else { if (!net) { - LogWarning(LOG_RF, "NXDN, " NXDN_RTCH_MSG_TYPE_VCALL_REQ " queued, no channels available, dstId = %u", m_rfLC.getDstId()); - writeRF_Message_Deny(NXDN_CAUSE_VD_QUE_CHN_RESOURCE_NOT_AVAIL, RTCH_MESSAGE_TYPE_VCALL); + LogWarning(LOG_RF, "NXDN, " NXDN_RTCH_MSG_TYPE_VCALL_REQ " queued, no channels available, dstId = %u", dstId); + writeRF_Message_Deny(0U, srcId, NXDN_CAUSE_VD_QUE_CHN_RESOURCE_NOT_AVAIL, RTCH_MESSAGE_TYPE_VCALL); - ::ActivityLog("P25", true, "unit-to-unit grant request from %u to %u queued", m_rfLC.getSrcId(), m_rfLC.getDstId()); + ::ActivityLog("P25", true, "unit-to-unit grant request from %u to %u queued", srcId, dstId); m_nxdn->m_rfState = RS_RF_REJECTED; } - m_rfLC.setMessageType(messageType); return false; } } else { - if (m_nxdn->m_affiliations.grantCh(m_rfLC.getDstId(), GRANT_TIMER_TIMEOUT)) { - uint32_t chNo = m_nxdn->m_affiliations.getGrantedCh(m_rfLC.getDstId()); - m_rfLC.setGrpVchNo(chNo); + if (m_nxdn->m_affiliations.grantCh(dstId, GRANT_TIMER_TIMEOUT)) { + chNo = m_nxdn->m_affiliations.getGrantedCh(dstId); } } } else { - uint32_t chNo = m_nxdn->m_affiliations.getGrantedCh(m_rfLC.getDstId()); - m_rfLC.setGrpVchNo(chNo); + chNo = m_nxdn->m_affiliations.getGrantedCh(dstId); } } if (grp) { if (!net) { - ::ActivityLog("NXDN", true, "group grant request from %u to TG %u", m_rfLC.getSrcId(), m_rfLC.getDstId()); + ::ActivityLog("NXDN", true, "group grant request from %u to TG %u", srcId, dstId); } } else { if (!net) { - ::ActivityLog("NXDN", true, "unit-to-unit grant request from %u to %u", m_rfLC.getSrcId(), m_rfLC.getDstId()); + ::ActivityLog("NXDN", true, "unit-to-unit grant request from %u to %u", srcId, dstId); } } + std::unique_ptr rcch = new_unique(rcch::MESSAGE_TYPE_VCALL_CONN); + rcch->setMessageType(RTCH_MESSAGE_TYPE_VCALL); + rcch->setGrpVchNo(chNo); + rcch->setGroup(grp); + rcch->setSrcId(srcId); + rcch->setDstId(dstId); + + rcch->setEmergency(emergency); + rcch->setEncrypted(encryption); + rcch->setPriority(priority); + if (m_verbose) { LogMessage((net) ? LOG_NET : LOG_RF, "NXDN, " NXDN_RTCH_MSG_TYPE_VCALL_RESP ", emerg = %u, encrypt = %u, prio = %u, chNo = %u, srcId = %u, dstId = %u", - m_rfLC.getEmergency(), m_rfLC.getEncrypted(), m_rfLC.getPriority(), m_rfLC.getGrpVchNo(), m_rfLC.getSrcId(), m_rfLC.getDstId()); + rcch->getEmergency(), rcch->getEncrypted(), rcch->getPriority(), rcch->getGrpVchNo(), rcch->getSrcId(), rcch->getDstId()); } // transmit group grant - m_rfLC.setMessageType(RTCH_MESSAGE_TYPE_VCALL); - writeRF_Message(false, true); - - m_rfLC.setMessageType(messageType); + writeRF_Message(rcch.get(), false, true); return true; } /// /// Helper to write a deny packet. /// +/// +/// /// /// -void Trunk::writeRF_Message_Deny(uint8_t reason, uint8_t service) +void Trunk::writeRF_Message_Deny(uint32_t srcId, uint32_t dstId, uint8_t reason, uint8_t service) { - uint8_t messageType = m_rfLC.getMessageType(); + std::unique_ptr rcch = nullptr; + + switch (service) { + case RTCH_MESSAGE_TYPE_VCALL: + rcch = new_unique(rcch::MESSAGE_TYPE_VCALL_CONN); + rcch->setMessageType(RTCH_MESSAGE_TYPE_VCALL); + default: + return; + } - m_rfLC.setMessageType(service); - m_rfLC.setCauseResponse(reason); + rcch->setCauseResponse(reason); + rcch->setSrcId(srcId); + rcch->setDstId(dstId); if (m_verbose) { LogMessage(LOG_RF, "NXDN, MSG_DENIAL (Message Denial), reason = $%02X, service = $%02X, srcId = %u, dstId = %u", - service, m_rfLC.getSrcId(), m_rfLC.getDstId()); + service, srcId, dstId); } - writeRF_Message(false); - - m_rfLC.setMessageType(messageType); + writeRF_Message(rcch.get(), false); } /// @@ -576,49 +582,48 @@ void Trunk::writeRF_Message_Deny(uint8_t reason, uint8_t service) /// /// /// -bool Trunk::writeRF_Message_Grp_Reg_Rsp(uint32_t srcId, uint32_t dstId) +/// +bool Trunk::writeRF_Message_Grp_Reg_Rsp(uint32_t srcId, uint32_t dstId, uint32_t locId) { bool ret = false; - m_rfLC.setMessageType(RCCH_MESSAGE_TYPE_GRP_REG); - m_rfLC.setCauseResponse(NXDN_CAUSE_MM_REG_ACCEPTED); + std::unique_ptr rcch = new_unique(rcch::MESSAGE_TYPE_GRP_REG); + rcch->setCauseResponse(NXDN_CAUSE_MM_REG_ACCEPTED); // validate the location ID - if (m_rfLC.getLocId() != m_nxdn->m_siteData.locId()) { - LogWarning(LOG_RF, "NXDN, " NXDN_RCCH_MSG_TYPE_GRP_REG_REQ " denial, LOCID rejection, locId = $%04X", m_rfLC.getLocId()); + if (locId != m_nxdn->m_siteData.locId()) { + LogWarning(LOG_RF, "NXDN, " NXDN_RCCH_MSG_TYPE_GRP_REG_REQ " denial, LOCID rejection, locId = $%04X", locId); ::ActivityLog("NXDN", true, "group affiliation request from %u denied", srcId); - m_rfLC.setCauseResponse(NXDN_CAUSE_MM_REG_FAILED); + rcch->setCauseResponse(NXDN_CAUSE_MM_REG_FAILED); } // validate the source RID if (!acl::AccessControl::validateSrcId(srcId)) { LogWarning(LOG_RF, "NXDN, " NXDN_RCCH_MSG_TYPE_GRP_REG_REQ " denial, RID rejection, srcId = %u", srcId); ::ActivityLog("NXDN", true, "group affiliation request from %u to %s %u denied", srcId, "TG ", dstId); - m_rfLC.setCauseResponse(NXDN_CAUSE_MM_REG_FAILED); + rcch->setCauseResponse(NXDN_CAUSE_MM_REG_FAILED); } // validate the source RID is registered if (!m_nxdn->m_affiliations.isUnitReg(srcId) && m_verifyReg) { LogWarning(LOG_RF, "NXDN, " NXDN_RCCH_MSG_TYPE_GRP_REG_REQ " denial, RID not registered, srcId = %u", srcId); ::ActivityLog("NXDN", true, "group affiliation request from %u to %s %u denied", srcId, "TG ", dstId); - m_rfLC.setCauseResponse(NXDN_CAUSE_MM_REG_REFUSED); + rcch->setCauseResponse(NXDN_CAUSE_MM_REG_REFUSED); } // validate the talkgroup ID - if (m_rfLC.getGroup()) { - if (dstId == 0U) { - LogWarning(LOG_RF, "NXDN, " NXDN_RCCH_MSG_TYPE_GRP_REG_REQ ", TGID 0, dstId = %u", dstId); - } - else { - if (!acl::AccessControl::validateTGId(dstId)) { - LogWarning(LOG_RF, "NXDN, " NXDN_RCCH_MSG_TYPE_GRP_REG_REQ " denial, TGID rejection, dstId = %u", dstId); - ::ActivityLog("NXDN", true, "group affiliation request from %u to %s %u denied", srcId, "TG ", dstId); - m_rfLC.setCauseResponse(NXDN_CAUSE_MM_LOC_ACPT_GRP_REFUSE); - } + if (dstId == 0U) { + LogWarning(LOG_RF, "NXDN, " NXDN_RCCH_MSG_TYPE_GRP_REG_REQ ", TGID 0, dstId = %u", dstId); + } + else { + if (!acl::AccessControl::validateTGId(dstId)) { + LogWarning(LOG_RF, "NXDN, " NXDN_RCCH_MSG_TYPE_GRP_REG_REQ " denial, TGID rejection, dstId = %u", dstId); + ::ActivityLog("NXDN", true, "group affiliation request from %u to %s %u denied", srcId, "TG ", dstId); + rcch->setCauseResponse(NXDN_CAUSE_MM_LOC_ACPT_GRP_REFUSE); } } - if (m_rfLC.getCauseResponse() == NXDN_CAUSE_MM_REG_ACCEPTED) { + if (rcch->getCauseResponse() == NXDN_CAUSE_MM_REG_ACCEPTED) { if (m_verbose) { LogMessage(LOG_RF, "NXDN, " NXDN_RCCH_MSG_TYPE_GRP_REG_REQ ", srcId = %u, dstId = %u", srcId, dstId); } @@ -630,7 +635,7 @@ bool Trunk::writeRF_Message_Grp_Reg_Rsp(uint32_t srcId, uint32_t dstId) m_nxdn->m_affiliations.groupAff(srcId, dstId); } - writeRF_Message(false); + writeRF_Message(rcch.get(), false); return ret; } @@ -638,28 +643,28 @@ bool Trunk::writeRF_Message_Grp_Reg_Rsp(uint32_t srcId, uint32_t dstId) /// Helper to write a unit registration response packet. /// /// -void Trunk::writeRF_Message_U_Reg_Rsp(uint32_t srcId) +void Trunk::writeRF_Message_U_Reg_Rsp(uint32_t srcId, uint32_t locId) { - m_rfLC.setMessageType(RCCH_MESSAGE_TYPE_REG); - m_rfLC.setCauseResponse(NXDN_CAUSE_MM_REG_ACCEPTED); + std::unique_ptr rcch = new_unique(rcch::MESSAGE_TYPE_REG); + rcch->setCauseResponse(NXDN_CAUSE_MM_REG_ACCEPTED); // validate the location ID - if (m_rfLC.getLocId() != m_nxdn->m_siteData.locId()) { - LogWarning(LOG_RF, "NXDN, " NXDN_RCCH_MSG_TYPE_REG_REQ " denial, LOCID rejection, locId = $%04X", m_rfLC.getLocId()); + if (locId != m_nxdn->m_siteData.locId()) { + LogWarning(LOG_RF, "NXDN, " NXDN_RCCH_MSG_TYPE_REG_REQ " denial, LOCID rejection, locId = $%04X", locId); ::ActivityLog("NXDN", true, "unit registration request from %u denied", srcId); - m_rfLC.setCauseResponse(NXDN_CAUSE_MM_REG_FAILED); + rcch->setCauseResponse(NXDN_CAUSE_MM_REG_FAILED); } // validate the source RID if (!acl::AccessControl::validateSrcId(srcId)) { LogWarning(LOG_RF, "NXDN, " NXDN_RCCH_MSG_TYPE_REG_REQ " denial, RID rejection, srcId = %u", srcId); ::ActivityLog("NXDN", true, "unit registration request from %u denied", srcId); - m_rfLC.setCauseResponse(NXDN_CAUSE_MM_REG_FAILED); + rcch->setCauseResponse(NXDN_CAUSE_MM_REG_FAILED); } - if (m_rfLC.getCauseResponse() == NXDN_CAUSE_MM_REG_ACCEPTED) { + if (rcch->getCauseResponse() == NXDN_CAUSE_MM_REG_ACCEPTED) { if (m_verbose) { - LogMessage(LOG_RF, "NXDN, " NXDN_RCCH_MSG_TYPE_REG_REQ ", srcId = %u, locId = %u", srcId, m_rfLC.getLocId()); + LogMessage(LOG_RF, "NXDN, " NXDN_RCCH_MSG_TYPE_REG_REQ ", srcId = %u, locId = %u", srcId, locId); } ::ActivityLog("NXDN", true, "unit registration request from %u", srcId); @@ -670,10 +675,10 @@ void Trunk::writeRF_Message_U_Reg_Rsp(uint32_t srcId) } } - m_rfLC.setSrcId(srcId); - m_rfLC.setDstId(srcId); + rcch->setSrcId(srcId); + rcch->setDstId(srcId); - writeRF_Message(true); + writeRF_Message(rcch.get(), true); } /// @@ -701,9 +706,14 @@ void Trunk::writeRF_CC_Message_Site_Info() uint8_t buffer[NXDN_RCCH_LC_LENGTH_BYTES]; ::memset(buffer, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES); - m_rfLC.setVerbose(m_dumpRCCH); - m_rfLC.setMessageType(RCCH_MESSAGE_TYPE_SITE_INFO); - m_rfLC.encode(buffer, NXDN_RCCH_LC_LENGTH_BITS); + std::unique_ptr rcch = new_unique(rcch::MESSAGE_TYPE_SITE_INFO); + rcch->setBcchCnt(m_bcchCnt); + rcch->setRcchGroupingCnt(m_rcchGroupingCnt); + rcch->setCcchPagingCnt(m_ccchPagingCnt); + rcch->setCcchMultiCnt(m_ccchMultiCnt); + rcch->setRcchIterateCount(m_rcchIterateCnt); + + rcch->encode(buffer, NXDN_RCCH_LC_LENGTH_BITS); // generate the CAC channel::CAC cac; @@ -749,10 +759,9 @@ void Trunk::writeRF_CC_Message_Service_Info() uint8_t buffer[NXDN_RCCH_LC_LENGTH_BYTES]; ::memset(buffer, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES); - m_rfLC.setVerbose(m_dumpRCCH); - m_rfLC.setMessageType(MESSAGE_TYPE_SRV_INFO); - m_rfLC.encode(buffer, NXDN_RCCH_LC_LENGTH_BITS / 2U); - m_rfLC.encode(buffer, NXDN_RCCH_LC_LENGTH_BITS / 2U, NXDN_RCCH_LC_LENGTH_BITS / 2U); + std::unique_ptr rcch = new_unique(rcch::MESSAGE_TYPE_SRV_INFO); + rcch->encode(buffer, NXDN_RCCH_LC_LENGTH_BITS / 2U); + rcch->encode(buffer, NXDN_RCCH_LC_LENGTH_BITS / 2U, NXDN_RCCH_LC_LENGTH_BITS / 2U); // generate the CAC channel::CAC cac; diff --git a/nxdn/packet/Trunk.h b/nxdn/packet/Trunk.h index 6d01cbc2..e4d9d182 100644 --- a/nxdn/packet/Trunk.h +++ b/nxdn/packet/Trunk.h @@ -57,11 +57,6 @@ namespace nxdn class HOST_SW_API Trunk { public: - /// Resets the data states for the RF interface. - virtual void resetRF(); - /// Resets the data states for the network. - virtual void resetNet(); - /// Process a data frame from the RF interface. virtual bool process(uint8_t fct, uint8_t option, uint8_t* data, uint32_t len); /// Process a data frame from the network. @@ -78,21 +73,22 @@ namespace nxdn network::BaseNetwork* m_network; + uint8_t m_bcchCnt; + uint8_t m_rcchGroupingCnt; + uint8_t m_ccchPagingCnt; + uint8_t m_ccchMultiCnt; + uint8_t m_rcchIterateCnt; + bool m_verifyAff; bool m_verifyReg; - lc::RCCH m_rfLC; - lc::RCCH m_netLC; - uint16_t m_lastRejectId; - bool m_dumpRCCH; - bool m_verbose; bool m_debug; /// Initializes a new instance of the Trunk class. - Trunk(Control* nxdn, network::BaseNetwork* network, bool dumpRCCHData, bool debug, bool verbose); + Trunk(Control* nxdn, network::BaseNetwork* network, bool debug, bool verbose); /// Finalizes a instance of the Trunk class. virtual ~Trunk(); @@ -103,16 +99,16 @@ namespace nxdn void writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adjSS); /// Helper to write a single-block RCCH packet. - void writeRF_Message(bool noNetwork, bool clearBeforeWrite = false); + void writeRF_Message(lc::RCCH* rcch, bool noNetwork, bool clearBeforeWrite = false); /// Helper to write a grant packet. - bool writeRF_Message_Grant(bool grp, bool skip = false, bool net = false, bool skipNetCheck = false); + bool writeRF_Message_Grant(uint32_t srcId, uint32_t dstId, uint8_t serviceOptions, bool grp, bool skip = false, uint32_t chNo = 0U, bool net = false, bool skipNetCheck = false); /// Helper to write a deny packet. - void writeRF_Message_Deny(uint8_t reason, uint8_t service); + void writeRF_Message_Deny(uint32_t srcId, uint32_t dstId, uint8_t reason, uint8_t service); /// Helper to write a group registration response packet. - bool writeRF_Message_Grp_Reg_Rsp(uint32_t srcId, uint32_t dstId); + bool writeRF_Message_Grp_Reg_Rsp(uint32_t srcId, uint32_t dstId, uint32_t locId); /// Helper to write a unit registration response packet. - void writeRF_Message_U_Reg_Rsp(uint32_t srcId); + void writeRF_Message_U_Reg_Rsp(uint32_t srcId, uint32_t locId); /// Helper to write a CC SITE_INFO broadcast packet on the RF interface. void writeRF_CC_Message_Site_Info(); diff --git a/nxdn/packet/Voice.cpp b/nxdn/packet/Voice.cpp index 266ae0c5..23ecf0e5 100644 --- a/nxdn/packet/Voice.cpp +++ b/nxdn/packet/Voice.cpp @@ -212,7 +212,6 @@ bool Voice::process(uint8_t fct, uint8_t option, uint8_t* data, uint32_t len) facch.getData(buffer); lc::RTCH lc; - lc.setVerbose(m_dumpRTCH); lc.decode(buffer, NXDN_FACCH1_FEC_LENGTH_BITS); uint16_t dstId = lc.getDstId(); uint16_t srcId = lc.getSrcId(); @@ -340,7 +339,6 @@ bool Voice::process(uint8_t fct, uint8_t option, uint8_t* data, uint32_t len) facch.getData(buffer); lc::RTCH lc; - lc.setVerbose(m_dumpRTCH); lc.decode(buffer, NXDN_FACCH1_FEC_LENGTH_BITS); hasInfo = lc.getMessageType() == RTCH_MESSAGE_TYPE_VCALL; @@ -646,7 +644,6 @@ bool Voice::processNetwork(uint8_t fct, uint8_t option, lc::RTCH& netLC, uint8_t facch.getData(buffer); lc::RTCH lc; - lc.setVerbose(m_dumpRTCH); lc.decode(buffer, NXDN_FACCH1_FEC_LENGTH_BITS); uint16_t dstId = lc.getDstId(); uint16_t srcId = lc.getSrcId(); @@ -753,7 +750,6 @@ bool Voice::processNetwork(uint8_t fct, uint8_t option, lc::RTCH& netLC, uint8_t facch.getData(buffer); lc::RTCH lc; - lc.setVerbose(m_dumpRTCH); lc.decode(buffer, NXDN_FACCH1_FEC_LENGTH_BITS); hasInfo = lc.getMessageType() == RTCH_MESSAGE_TYPE_VCALL; @@ -980,10 +976,9 @@ bool Voice::processNetwork(uint8_t fct, uint8_t option, lc::RTCH& netLC, uint8_t /// /// Instance of the Control class. /// Instance of the BaseNetwork class. -/// Flag indicating whether RTCH data is dumped to the log. /// Flag indicating whether NXDN debug is enabled. /// Flag indicating whether NXDN verbose logging is enabled. -Voice::Voice(Control* nxdn, network::BaseNetwork* network, bool dumpRTCHData, bool debug, bool verbose) : +Voice::Voice(Control* nxdn, network::BaseNetwork* network, bool debug, bool verbose) : m_nxdn(nxdn), m_network(network), m_rfFrames(0U), @@ -994,7 +989,6 @@ Voice::Voice(Control* nxdn, network::BaseNetwork* network, bool dumpRTCHData, bo m_netLost(0U), m_lastRejectId(0U), m_silenceThreshold(DEFAULT_SILENCE_THRESHOLD), - m_dumpRTCH(dumpRTCHData), m_verbose(verbose), m_debug(debug) { diff --git a/nxdn/packet/Voice.h b/nxdn/packet/Voice.h index e3b60bee..e12e3689 100644 --- a/nxdn/packet/Voice.h +++ b/nxdn/packet/Voice.h @@ -84,13 +84,11 @@ namespace nxdn uint32_t m_silenceThreshold; - bool m_dumpRTCH; - bool m_verbose; bool m_debug; /// Initializes a new instance of the Voice class. - Voice(Control* nxdn, network::BaseNetwork* network, bool dumpRTCHData, bool debug, bool verbose); + Voice(Control* nxdn, network::BaseNetwork* network, bool debug, bool verbose); /// Finalizes a instance of the Voice class. virtual ~Voice();