diff --git a/config.example.yml b/config.example.yml index 50c66890..5f435215 100644 --- a/config.example.yml +++ b/config.example.yml @@ -315,8 +315,6 @@ system: channelId: 2 # Channel Number (used to calculate actual host frequency based on the identity table). channelNo: 1 - # DMR network ID. - dmrNetId: 1 # # Voice Channels @@ -339,15 +337,19 @@ system: # txNAC: 293 # NXDN Random Access Number. ran: 1 + # P25 Patch Super Group. pSuperGroup: FFFF + + # DMR network ID. + dmrNetId: 1 # P25 Network ID (WACN). netId: BB800 - # P25 System ID. + # P25/NXDN System ID. sysId: 001 # P25 RFSS (RF Sub-System) ID. rfssId: 1 - # P25 Site ID. + # DMR/P25/NXDN Site ID. siteId: 1 # diff --git a/dmr/Control.cpp b/dmr/Control.cpp index d12d39ce..9ae44af4 100644 --- a/dmr/Control.cpp +++ b/dmr/Control.cpp @@ -171,7 +171,7 @@ void Control::setOptions(yaml::Node& conf, bool controlPermitTG, const std::vect // either MAX_DMR_VOICE_ERRORS or 0 will disable the threshold logic if (silenceThreshold == 0) { - LogWarning(LOG_P25, "Silence threshold set to zero, defaulting to %u", dmr::MAX_DMR_VOICE_ERRORS); + LogWarning(LOG_DMR, "Silence threshold set to zero, defaulting to %u", dmr::MAX_DMR_VOICE_ERRORS); silenceThreshold = dmr::MAX_DMR_VOICE_ERRORS; } diff --git a/host/Host.cpp b/host/Host.cpp index b944ec60..463c1dc9 100644 --- a/host/Host.cpp +++ b/host/Host.cpp @@ -128,12 +128,12 @@ Host::Host(const std::string& confFile) : m_nxdnCtrlChannel(false), m_nxdnCtrlBroadcast(false), m_siteId(1U), + m_sysId(1U), m_dmrNetId(1U), m_dmrColorCode(1U), m_p25NAC(0x293U), m_p25PatchSuperGroup(0xFFFFU), m_p25NetId(0xBB800U), - m_p25SysId(1U), m_p25RfssId(1U), m_nxdnRAN(1U), m_dmrQueueSizeBytes(3960U), // 24 frames @@ -507,7 +507,7 @@ int Host::run() p25 = std::unique_ptr(new p25::Control(m_authoritative, m_p25NAC, callHang, m_p25QueueSizeBytes, m_modem, m_network, m_timeout, m_rfTalkgroupHang, m_duplex, m_ridLookup, m_tidLookup, m_idenTable, rssi, p25DumpDataPacket, p25RepeatDataPacket, p25DumpTsbkData, p25Debug, p25Verbose)); - p25->setOptions(m_conf, m_controlPermitTG, m_cwCallsign, m_voiceChNo, m_voiceChData, m_p25PatchSuperGroup, m_p25NetId, m_p25SysId, m_p25RfssId, + p25->setOptions(m_conf, m_controlPermitTG, m_cwCallsign, m_voiceChNo, m_voiceChData, m_p25PatchSuperGroup, m_p25NetId, m_sysId, m_p25RfssId, m_siteId, m_channelId, m_channelNo, true); if (p25CtrlChannel) { @@ -572,7 +572,7 @@ int Host::run() nxdn = std::unique_ptr(new nxdn::Control(m_authoritative, m_nxdnRAN, callHang, m_nxdnQueueSizeBytes, m_timeout, m_rfTalkgroupHang, m_modem, m_network, m_duplex, m_ridLookup, m_tidLookup, m_idenTable, rssi, nxdnDumpRcchData, nxdnDebug, nxdnVerbose)); - nxdn->setOptions(m_conf, m_controlPermitTG, m_cwCallsign, m_voiceChNo, m_voiceChData, m_siteId, m_channelId, m_channelNo, true); + nxdn->setOptions(m_conf, m_controlPermitTG, m_cwCallsign, m_voiceChNo, m_voiceChData, m_siteId, m_sysId, m_channelId, m_channelNo, true); if (nxdnCtrlChannel) { nxdn->setCCRunning(true); @@ -1888,8 +1888,8 @@ bool Host::readParams() m_p25NetId = (uint32_t)::strtoul(rfssConfig["netId"].as("BB800").c_str(), NULL, 16); m_p25NetId = p25::P25Utils::netId(m_p25NetId); - m_p25SysId = (uint32_t)::strtoul(rfssConfig["sysId"].as("001").c_str(), NULL, 16); - m_p25SysId = p25::P25Utils::sysId(m_p25SysId); + m_sysId = (uint32_t)::strtoul(rfssConfig["sysId"].as("001").c_str(), NULL, 16); + m_sysId = p25::P25Utils::sysId(m_sysId); m_p25RfssId = (uint8_t)::strtoul(rfssConfig["rfssId"].as("1").c_str(), NULL, 16); m_p25RfssId = p25::P25Utils::rfssId(m_p25RfssId); @@ -1910,6 +1910,7 @@ bool Host::readParams() LogInfo(" Channel No.: $%04X", m_channelNo); LogInfo(" Voice Channel No(s).: %s", strVoiceChNo.c_str()); LogInfo(" Site Id: $%02X", m_siteId); + LogInfo(" System Id: $%03X", m_sysId); LogInfo(" DMR Color Code: %u", m_dmrColorCode); LogInfo(" DMR Network Id: $%05X", m_dmrNetId); LogInfo(" P25 NAC: $%03X", m_p25NAC); @@ -1918,12 +1919,10 @@ bool Host::readParams() LogInfo(" P25 Tx NAC: $%03X", p25TxNAC); } - LogInfo(" NXDN RAN: %u", m_nxdnRAN); - LogInfo(" P25 Patch Super Group: $%04X", m_p25PatchSuperGroup); LogInfo(" P25 Network Id: $%05X", m_p25NetId); - LogInfo(" P25 System Id: $%03X", m_p25SysId); LogInfo(" P25 RFSS Id: $%02X", m_p25RfssId); + LogInfo(" NXDN RAN: %u", m_nxdnRAN); if (!m_authoritative) { m_controlPermitTG = false; diff --git a/host/Host.h b/host/Host.h index ff9c7f74..2fad6f54 100644 --- a/host/Host.h +++ b/host/Host.h @@ -133,12 +133,12 @@ private: bool m_nxdnCtrlBroadcast; uint8_t m_siteId; + uint32_t m_sysId; uint32_t m_dmrNetId; uint32_t m_dmrColorCode; uint32_t m_p25NAC; uint32_t m_p25PatchSuperGroup; uint32_t m_p25NetId; - uint32_t m_p25SysId; uint8_t m_p25RfssId; uint32_t m_nxdnRAN; diff --git a/nxdn/Control.cpp b/nxdn/Control.cpp index dd34cf1a..05e4393a 100644 --- a/nxdn/Control.cpp +++ b/nxdn/Control.cpp @@ -208,12 +208,13 @@ void Control::reset() /// /// Voice Channel Number list. /// Voice Channel data map. -/// NXDN Location ID. +/// NXDN Site Code. +/// NXDN System Code. /// Channel ID. /// Channel Number. /// void Control::setOptions(yaml::Node& conf, bool controlPermitTG, const std::string cwCallsign, const std::vector voiceChNo, - const std::unordered_map voiceChData, uint16_t locId, + const std::unordered_map voiceChData, uint16_t siteId, uint32_t sysId, uint8_t channelId, uint32_t channelNo, bool printOptions) { yaml::Node systemConf = conf["system"]; @@ -243,7 +244,7 @@ void Control::setOptions(yaml::Node& conf, bool controlPermitTG, const std::stri // either MAX_NXDN_VOICE_ERRORS or 0 will disable the threshold logic if (m_voice->m_silenceThreshold == 0) { - LogWarning(LOG_P25, "Silence threshold set to zero, defaulting to %u", nxdn::MAX_NXDN_VOICE_ERRORS); + LogWarning(LOG_NXDN, "Silence threshold set to zero, defaulting to %u", nxdn::MAX_NXDN_VOICE_ERRORS); m_voice->m_silenceThreshold = nxdn::MAX_NXDN_VOICE_ERRORS; } @@ -259,6 +260,11 @@ void Control::setOptions(yaml::Node& conf, bool controlPermitTG, const std::stri } } + // calculate the NXDN location ID + uint32_t locId = NXDN_LOC_CAT_LOCAL; // DVM is currently fixed to "local" category + locId = (locId << 17) + sysId; + locId = (locId << 5) + (siteId & 0x1FU); + m_siteData = SiteData(locId, channelId, channelNo, serviceClass, false); m_siteData.setCallsign(cwCallsign); diff --git a/nxdn/Control.h b/nxdn/Control.h index 1699f1de..c98fbf93 100644 --- a/nxdn/Control.h +++ b/nxdn/Control.h @@ -84,7 +84,7 @@ namespace nxdn /// Helper to set NXDN configuration options. void setOptions(yaml::Node& conf, bool controlPermitTG, const std::string cwCallsign, const std::vector voiceChNo, - const std::unordered_map voiceChData, uint16_t locId, + const std::unordered_map voiceChData, uint16_t siteId, uint32_t sysId, uint8_t channelId, uint32_t channelNo, bool printOptions); /// Gets a flag indicating whether the NXDN control channel is running. diff --git a/nxdn/NXDNDefines.h b/nxdn/NXDNDefines.h index 134767d8..a26cc870 100644 --- a/nxdn/NXDNDefines.h +++ b/nxdn/NXDNDefines.h @@ -187,6 +187,10 @@ namespace nxdn const uint8_t DATA_RSP_CLASS_ACK = 0x00U; const uint8_t DATA_RSP_CLASS_ACK_S = 0x01U; const uint8_t DATA_RSP_CLASS_NACK = 0x03U; + + const uint8_t NXDN_LOC_CAT_GLOBAL = 0x00U; + const uint8_t NXDN_LOC_CAT_LOCAL = 0x01U; + const uint8_t NXDN_LOC_CAT_REGIONAL = 0x02U; const uint8_t NXDN_CAUSE_RSRC_NOT_AVAIL_NETWORK = 0x51U; const uint8_t NXDN_CAUSE_RSRC_NOT_AVAIL_TEMP = 0x52U; diff --git a/nxdn/SiteData.h b/nxdn/SiteData.h index d8749ea1..fbc604be 100644 --- a/nxdn/SiteData.h +++ b/nxdn/SiteData.h @@ -71,8 +71,8 @@ namespace nxdn m_requireReg(requireReq), m_netActive(false) { - if (m_locId > 0xFFFFFU) - m_locId = 0xFFFFFU; + if (m_locId > 0xFFFFFFU) + m_locId = 0xFFFFFFU; // channel id clamping if (channelId > 15U) @@ -110,8 +110,8 @@ namespace nxdn /// Service class. void setAdjSite(uint32_t locId, uint8_t rfssId, uint8_t siteId, uint8_t channelId, uint32_t channelNo, uint8_t serviceClass) { - if (m_locId > 0xFFFFFU) - m_locId = 0xFFFFFU; + if (m_locId > 0xFFFFFFU) + m_locId = 0xFFFFFFU; // channel id clamping if (channelId > 15U) diff --git a/nxdn/lc/RCCH.cpp b/nxdn/lc/RCCH.cpp index 8ce5691e..7e31b109 100644 --- a/nxdn/lc/RCCH.cpp +++ b/nxdn/lc/RCCH.cpp @@ -159,13 +159,15 @@ void RCCH::encode(uint8_t* data, const uint8_t* rcch, uint32_t length, uint32_t assert(data != nullptr); assert(rcch != nullptr); - data[0U] = m_messageType & 0x3FU; // Message Type - for (uint32_t i = 0U; i < length; i++, offset++) { bool b = READ_BIT(rcch, i); WRITE_BIT(data, offset, b); } + if (data[0U] == 0x00U) { + data[0U] = m_messageType & 0x3FU; // Message Type + } + if (m_verbose) { Utils::dump(2U, "Encoded RCCH Data", data, NXDN_RCCH_LC_LENGTH_BYTES); }