diff --git a/configs/config.example.yml b/configs/config.example.yml index c8e1961f..82293b49 100644 --- a/configs/config.example.yml +++ b/configs/config.example.yml @@ -155,9 +155,9 @@ protocols: # P25 Control Channel Configuration # control: - # Flag indicating whether or not CC is enabled. + # Flag indicating whether or not TSBK data support is enabled. enable: false - # Flag indicating whether or not the CC will optionally acknowledge incoming requests. + # Flag indicating whether or not TSBK requets will optionally acknowledge incoming requests. ackRequests: true # Flag indicating whether or not this CC is a dedicated CC. dedicated: false @@ -176,17 +176,11 @@ protocols: # Flag indicating immediate TSDUs will be sent twice. redundantImmediate: true # Flag indicating whether redundant grant responses should be transmitted. - # (This is useful for single-channel VOC (voice on control) configurations.) redundantGrantTransmit: false - # Flag indicating whether or not VOC (voice on control) support is enabled. - voiceOnControl: false # Flag indicating whether or not to ignore voice frames on a control channel - # This comes in handy if you're running non-dedicated with an FNE so the CC doesn't repeat voice traffic + # This comes in handy if you're running non-dedicated with an FNE so the CC doesn't repeat voice traffic. controlOnly: false - # Flag indicating whether or not the composite flag in the CC service options is set. - # (This is useful to disable for some radios when running in VOC mode.) - disableCompositeFlag: false # Flag indicating whether or not a voice HDU will transmitted at the start of a call from the network. disableNetworkHDU: false # Flag indicating whether or not network calls will generate a channel grant. @@ -261,10 +255,6 @@ protocols: # Flag indicating whether or not the source ID validation before granting disabled. disableGrantSourceIdCheck: false - # Flag indicating whether or not VOC (voice on control) support is enabled. - voiceOnControl: false - # Flag indicating whether or not the composite flag in the CC service options is set. - disableCompositeFlag: false # Flag indicating the host should verify group affiliation. verifyAff: false # Flag indicating the host should verify unit registration. diff --git a/src/RingBuffer.h b/src/RingBuffer.h index 4b0f3b7f..ebd01d96 100644 --- a/src/RingBuffer.h +++ b/src/RingBuffer.h @@ -76,7 +76,7 @@ public: bool addData(const T* buffer, uint32_t length) { if (length >= freeSpace()) { - LogError(LOG_HOST, "[%s] buffer overflow, clearing the buffer. (%u >= %u)", m_name, length, freeSpace()); + LogError(LOG_HOST, "**** Overflow in %s ring buffer, %u >= %u, clearing the buffer", m_name, length, freeSpace()); clear(); return false; } @@ -102,7 +102,7 @@ public: bool get(T* buffer, uint32_t length) { if (dataSize() < length) { - LogError(LOG_HOST, "**** Underflow in %s ring buffer, %u < %u", m_name, dataSize(), length); + LogError(LOG_HOST, "**** Underflow get in %s ring buffer, %u < %u", m_name, dataSize(), length); return false; } #if DEBUG_RINGBUFFER diff --git a/src/dmr/Slot.cpp b/src/dmr/Slot.cpp index d3756c73..7d251c76 100644 --- a/src/dmr/Slot.cpp +++ b/src/dmr/Slot.cpp @@ -678,8 +678,11 @@ void Slot::releaseGrantTG(uint32_t dstId) } if (m_affiliations->isGranted(dstId)) { + uint32_t chNo = m_affiliations->getGrantedCh(dstId); + ::lookups::VoiceChData voiceCh = m_affiliations->getRFChData(chNo); + if (m_verbose) { - LogMessage(LOG_DMR, "DMR Slot %u, REST request, TG grant released, dstId = %u", m_slotNo, dstId); + LogMessage(LOG_DMR, "DMR Slot %u, REST request, TG grant released, chNo = %u, dstId = %u, address = %s:%u", m_slotNo, chNo, dstId, voiceCh.address().c_str(), voiceCh.port()); } m_affiliations->releaseGrant(dstId, false); @@ -697,8 +700,11 @@ void Slot::touchGrantTG(uint32_t dstId) } if (m_affiliations->isGranted(dstId)) { + uint32_t chNo = m_affiliations->getGrantedCh(dstId); + ::lookups::VoiceChData voiceCh = m_affiliations->getRFChData(chNo); + if (m_verbose) { - LogMessage(LOG_DMR, "DMR Slot %u, REST request, touch TG grant, dstId = %u", m_slotNo, dstId); + LogMessage(LOG_DMR, "DMR Slot %u, REST request, touch TG grant, chNo = %u, dstId = %u, address = %s:%u", m_slotNo, chNo, dstId, voiceCh.address().c_str(), voiceCh.port()); } m_affiliations->touchGrant(dstId); diff --git a/src/network/RESTAPI.cpp b/src/network/RESTAPI.cpp index 0d69e4d5..a0d74d91 100644 --- a/src/network/RESTAPI.cpp +++ b/src/network/RESTAPI.cpp @@ -509,12 +509,7 @@ void RESTAPI::restAPI_GetStatus(const HTTPPayload& request, HTTPPayload& reply, response["nxdnCC"].set(m_host->m_nxdnCtrlChannel); yaml::Node p25Protocol = m_host->m_conf["protocols"]["p25"]; - bool p25VOC = p25Protocol["voiceOnControl"].as(false); yaml::Node nxdnProtocol = m_host->m_conf["protocols"]["nxdn"]; - bool nxdnVOC = nxdnProtocol["voiceOnControl"].as(false); - - response["p25VOC"].set(p25VOC); - response["nxdnVOC"].set(nxdnVOC); response["tx"].set(m_host->m_modem->m_tx); diff --git a/src/nxdn/Control.cpp b/src/nxdn/Control.cpp index e305e320..cbf1a86b 100644 --- a/src/nxdn/Control.cpp +++ b/src/nxdn/Control.cpp @@ -104,7 +104,6 @@ Control::Control(bool authoritative, uint32_t ran, uint32_t callHang, uint32_t q m_duplex(duplex), m_enableControl(false), m_dedicatedControl(false), - m_voiceOnControl(false), m_rfLastLICH(), m_rfLC(), m_netLC(), @@ -246,8 +245,6 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, const std::string cw m_dedicatedControl = false; } - m_voiceOnControl = nxdnProtocol["voiceOnControl"].as(false); - m_control->m_disableGrantSrcIdCheck = control["disableGrantSourceIdCheck"].as(false); yaml::Node rfssConfig = systemConf["config"]; @@ -280,18 +277,11 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, const std::string cw /* ** CC Service Class */ - bool disableCompositeFlag = nxdnProtocol["disableCompositeFlag"].as(false); uint8_t serviceClass = NXDN_SIF1_VOICE_CALL_SVC | NXDN_SIF1_DATA_CALL_SVC; if (m_enableControl) { serviceClass |= NXDN_SIF1_GRP_REG_SVC; } - if (m_voiceOnControl) { - if (!disableCompositeFlag) { - serviceClass |= NXDN_SIF1_COMPOSITE_CONTROL; - } - } - /* ** Site Data */ @@ -350,7 +340,6 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, const std::string cw LogInfo(" Frame Loss Threshold: %u", m_frameLossThreshold); if (m_enableControl) { - LogInfo(" Voice on Control: %s", m_voiceOnControl ? "yes" : "no"); if (m_control->m_disableGrantSrcIdCheck) { LogInfo(" Disable Grant Source ID Check: yes"); } @@ -505,24 +494,12 @@ bool Control::processFrame(uint8_t* data, uint32_t len) else if (rfct == NXDN_LICH_RFCT_RTCH || rfct == NXDN_LICH_RFCT_RDCH) { switch (fct) { case NXDN_LICH_USC_UDCH: - if (!m_dedicatedControl) { + if (!m_dedicatedControl) ret = m_data->process(option, data, len); - } - else { - if (m_voiceOnControl && m_affiliations.isChBusy(m_siteData.channelNo())) { - ret = m_data->process(option, data, len); - } - } break; default: - if (!m_dedicatedControl) { + if (!m_dedicatedControl) ret = m_voice->process(fct, option, data, len); - } - else { - if (m_voiceOnControl && m_affiliations.isChBusy(m_siteData.channelNo())) { - ret = m_voice->process(fct, option, data, len); - } - } break; } } @@ -769,8 +746,11 @@ void Control::releaseGrantTG(uint32_t dstId) } if (m_affiliations.isGranted(dstId)) { + uint32_t chNo = m_affiliations.getGrantedCh(dstId); + ::lookups::VoiceChData voiceCh = m_affiliations.getRFChData(chNo); + if (m_verbose) { - LogMessage(LOG_NXDN, "REST request, TG grant released, dstId = %u", dstId); + LogMessage(LOG_NXDN, "REST request, TG grant released, chNo = %u, dstId = %u, address = %s:%u", chNo, dstId, voiceCh.address().c_str(), voiceCh.port()); } m_affiliations.releaseGrant(dstId, false); @@ -788,8 +768,11 @@ void Control::touchGrantTG(uint32_t dstId) } if (m_affiliations.isGranted(dstId)) { + uint32_t chNo = m_affiliations.getGrantedCh(dstId); + ::lookups::VoiceChData voiceCh = m_affiliations.getRFChData(chNo); + if (m_verbose) { - LogMessage(LOG_NXDN, "REST request, touch TG grant, dstId = %u", dstId); + LogMessage(LOG_NXDN, "REST request, touch TG grant, chNo = %u, dstId = %u, address = %s:%u", chNo, dstId, voiceCh.address().c_str(), voiceCh.port()); } m_affiliations.touchGrant(dstId); @@ -1026,7 +1009,7 @@ void Control::processFrameLoss() m_voice->m_rfFrames, m_voice->m_rfBits, m_voice->m_rfUndecodableLC, m_voice->m_rfErrs, float(m_voice->m_rfErrs * 100U) / float(m_voice->m_rfBits)); m_affiliations.releaseGrant(m_rfLC.getDstId(), false); - if (!m_enableControl) { + if (m_notifyCC) { notifyCC_ReleaseGrant(m_rfLC.getDstId()); } diff --git a/src/nxdn/Control.h b/src/nxdn/Control.h index c2bbb027..0a0ff4c0 100644 --- a/src/nxdn/Control.h +++ b/src/nxdn/Control.h @@ -156,7 +156,6 @@ namespace nxdn bool m_duplex; bool m_enableControl; bool m_dedicatedControl; - bool m_voiceOnControl; channel::LICH m_rfLastLICH; lc::RTCH m_rfLC; diff --git a/src/nxdn/packet/ControlSignaling.cpp b/src/nxdn/packet/ControlSignaling.cpp index 191cd2d3..f986df19 100644 --- a/src/nxdn/packet/ControlSignaling.cpp +++ b/src/nxdn/packet/ControlSignaling.cpp @@ -281,7 +281,7 @@ bool ControlSignaling::processNetwork(uint8_t fct, uint8_t option, lc::RTCH& net switch (rcch->getMessageType()) { case RTCH_MESSAGE_TYPE_VCALL: { - if (m_nxdn->m_dedicatedControl && !m_nxdn->m_voiceOnControl) { + if (m_nxdn->m_dedicatedControl) { if (!m_nxdn->m_affiliations.isGranted(dstId)) { if (m_verbose) { LogMessage(LOG_NET, "NXDN, %s, emerg = %u, encrypt = %u, prio = %u, chNo = %u, srcId = %u, dstId = %u", diff --git a/src/p25/Control.cpp b/src/p25/Control.cpp index 7496b774..e76e9216 100644 --- a/src/p25/Control.cpp +++ b/src/p25/Control.cpp @@ -102,7 +102,6 @@ Control::Control(bool authoritative, uint32_t nac, uint32_t callHang, uint32_t q m_duplex(duplex), m_enableControl(false), m_dedicatedControl(false), - m_voiceOnControl(false), m_ackTSBKRequests(true), m_disableNetworkGrant(false), m_disableNetworkHDU(false), @@ -304,13 +303,6 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, const std::string cw m_dedicatedControl = false; } - m_voiceOnControl = p25Protocol["voiceOnControl"].as(false); - - // if control channel is off for voice on control off - if (!m_enableControl) { - m_voiceOnControl = false; - } - m_controlOnly = p25Protocol["controlOnly"].as(false); // if we're a dedicated control channel don't set the control only flag @@ -334,11 +326,6 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, const std::string cw yaml::Node controlCh = rfssConfig["controlCh"]; m_notifyCC = controlCh["notifyEnable"].as(false); - // voice on control forcibly disables CC notification - if (m_voiceOnControl) { - m_notifyCC = false; - } - /* ** Voice Silence and Frame Loss Thresholds */ @@ -381,18 +368,11 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, const std::string cw /* ** CC Service Class */ - bool disableCompositeFlag = p25Protocol["disableCompositeFlag"].as(false); uint8_t serviceClass = P25_SVC_CLS_VOICE | P25_SVC_CLS_DATA; if (m_enableControl) { serviceClass |= P25_SVC_CLS_REG; } - if (m_voiceOnControl) { - if (!disableCompositeFlag) { - serviceClass |= P25_SVC_CLS_COMPOSITE; - } - } - /* ** Site Data */ @@ -456,7 +436,6 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, const std::string cw LogInfo(" Frame Loss Threshold: %u", m_frameLossThreshold); if (m_enableControl) { - LogInfo(" Voice on Control: %s", m_voiceOnControl ? "yes" : "no"); LogInfo(" Ack Requests: %s", m_ackTSBKRequests ? "yes" : "no"); if (m_control->m_disableGrantSrcIdCheck) { LogInfo(" Disable Grant Source ID Check: yes"); @@ -654,11 +633,6 @@ bool Control::processFrame(uint8_t* data, uint32_t len) if (!m_dedicatedControl || m_control->m_convFallback) ret = m_voice->process(data, len); - else { - if (m_voiceOnControl && m_affiliations.isChBusy(m_siteData.channelNo())) { - ret = m_voice->process(data, len); - } - } break; case P25_DUID_TDU: @@ -994,9 +968,13 @@ void Control::releaseGrantTG(uint32_t dstId) } if (m_affiliations.isGranted(dstId)) { + uint32_t chNo = m_affiliations.getGrantedCh(dstId); + ::lookups::VoiceChData voiceCh = m_affiliations.getRFChData(chNo); + if (m_verbose) { - LogMessage(LOG_P25, "REST request, TG grant released, dstId = %u", dstId); + LogMessage(LOG_P25, "REST request, TG grant released, chId = %u, chNo = %u, dstId = %u, address = %s:%u", voiceCh.chId(), chNo, dstId, voiceCh.address().c_str(), voiceCh.port()); } + m_affiliations.releaseGrant(dstId, false); } } @@ -1012,8 +990,11 @@ void Control::touchGrantTG(uint32_t dstId) } if (m_affiliations.isGranted(dstId)) { + uint32_t chNo = m_affiliations.getGrantedCh(dstId); + ::lookups::VoiceChData voiceCh = m_affiliations.getRFChData(chNo); + if (m_verbose) { - LogMessage(LOG_P25, "REST request, call in progress, touch TG grant, dstId = %u", dstId); + LogMessage(LOG_P25, "REST request, call in progress, touch TG grant, chId = %u, chNo = %u, dstId = %u, address = %s:%u", voiceCh.chId(), chNo, dstId, voiceCh.address().c_str(), voiceCh.port()); } m_affiliations.touchGrant(dstId); @@ -1211,11 +1192,6 @@ void Control::processNetwork() if (!m_dedicatedControl) ret = m_data->processNetwork(data.get(), frameLength, blockLength); - else { - if (m_voiceOnControl) { - ret = m_data->processNetwork(data.get(), frameLength, blockLength); - } - } return; } diff --git a/src/p25/Control.h b/src/p25/Control.h index 7a932b58..9800f120 100644 --- a/src/p25/Control.h +++ b/src/p25/Control.h @@ -171,7 +171,6 @@ namespace p25 bool m_duplex; bool m_enableControl; bool m_dedicatedControl; - bool m_voiceOnControl; bool m_controlOnly; bool m_ackTSBKRequests; bool m_disableNetworkGrant; diff --git a/src/p25/packet/ControlSignaling.cpp b/src/p25/packet/ControlSignaling.cpp index 742424b5..390e2300 100644 --- a/src/p25/packet/ControlSignaling.cpp +++ b/src/p25/packet/ControlSignaling.cpp @@ -1002,7 +1002,7 @@ void ControlSignaling::writeAdjSSNetwork() if (m_p25->m_network != nullptr) { uint8_t cfva = P25_CFVA_VALID; - if (m_p25->m_enableControl && m_p25->m_voiceOnControl) { + if (m_p25->m_enableControl && !m_p25->m_dedicatedControl) { cfva |= P25_CFVA_CONV; } @@ -1750,7 +1750,7 @@ void ControlSignaling::writeRF_TDULC_ChanRelease(bool grp, uint32_t srcId, uint3 } uint32_t count = m_p25->m_hangCount / 2; - if (m_p25->m_voiceOnControl) { + if (!m_p25->m_dedicatedControl) { count = count / 2; } std::unique_ptr lc = nullptr; @@ -2356,10 +2356,8 @@ bool ControlSignaling::writeRF_TSDU_Grant(uint32_t srcId, uint32_t dstId, uint8_ // transmit group grant writeRF_TSDU_SBF_Imm(iosp.get(), net); if (m_redundantGrant) { - if (m_p25->m_dedicatedControl && m_p25->m_voiceOnControl) { - for (int i = 0; i < 3; i++) - writeRF_TSDU_SBF(iosp.get(), net); - } + for (int i = 0; i < 3; i++) + writeRF_TSDU_SBF(iosp.get(), net); } } else { @@ -2412,10 +2410,8 @@ bool ControlSignaling::writeRF_TSDU_Grant(uint32_t srcId, uint32_t dstId, uint8_ // transmit private grant writeRF_TSDU_SBF_Imm(iosp.get(), net); if (m_redundantGrant) { - if (m_p25->m_dedicatedControl && m_p25->m_voiceOnControl) { - for (int i = 0; i < 3; i++) - writeRF_TSDU_SBF(iosp.get(), net); - } + for (int i = 0; i < 3; i++) + writeRF_TSDU_SBF(iosp.get(), net); } } } diff --git a/src/p25/packet/Voice.cpp b/src/p25/packet/Voice.cpp index a0d71dd7..f8cdefd1 100644 --- a/src/p25/packet/Voice.cpp +++ b/src/p25/packet/Voice.cpp @@ -300,7 +300,7 @@ bool Voice::process(uint8_t* data, uint32_t len) } if (m_p25->m_enableControl) { - if (!m_p25->m_ccRunning && m_p25->m_voiceOnControl) { + if (!m_p25->m_ccRunning && !m_p25->m_dedicatedControl) { m_p25->m_control->writeRF_ControlData(255U, 0U, false); } } @@ -421,8 +421,8 @@ bool Voice::process(uint8_t* data, uint32_t len) } } - // single-channel trunking or voice on control support? - if (m_p25->m_enableControl && m_p25->m_voiceOnControl) { + // conventional registration or DVRS support? + if (m_p25->m_enableControl && !m_p25->m_dedicatedControl) { m_p25->m_control->writeRF_TSDU_Grant(srcId, dstId, serviceOptions, group, true, true); } @@ -578,8 +578,8 @@ bool Voice::process(uint8_t* data, uint32_t len) m_p25->notifyCC_TouchGrant(m_rfLC.getDstId()); } - // single-channel trunking or voice on control support? - if (m_p25->m_enableControl && m_p25->m_voiceOnControl) { + // conventional registration or DVRS support? + if (m_p25->m_enableControl && !m_p25->m_dedicatedControl) { // per TIA-102.AABD-B transmit RFSS_STS_BCAST every 3 superframes (e.g. every 3 LDU1s) m_vocLDU1Count++; if (m_vocLDU1Count > VOC_LDU1_COUNT) { @@ -764,6 +764,9 @@ bool Voice::process(uint8_t* data, uint32_t len) else if (duid == P25_DUID_TDU || duid == P25_DUID_TDULC) { if (!m_p25->m_enableControl) { m_p25->m_affiliations.releaseGrant(m_rfLC.getDstId(), false); + } + + if (m_p25->m_notifyCC) { m_p25->notifyCC_ReleaseGrant(m_rfLC.getDstId()); } @@ -957,7 +960,7 @@ bool Voice::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L m_p25->notifyCC_TouchGrant(control.getDstId()); } - if (m_p25->m_dedicatedControl && !m_p25->m_voiceOnControl) { + if (m_p25->m_dedicatedControl) { return true; } @@ -1026,14 +1029,12 @@ bool Voice::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L m_p25->notifyCC_TouchGrant(control.getDstId()); } - if (m_p25->m_dedicatedControl && !m_p25->m_voiceOnControl) { + if (m_p25->m_dedicatedControl) { return true; } if (m_p25->m_netState == RS_NET_IDLE) { - if (!m_p25->m_voiceOnControl) { - m_p25->m_modem->clearP25Frame(); - } + m_p25->m_modem->clearP25Frame(); m_p25->m_txQueue.clear(); resetRF(); @@ -1066,6 +1067,9 @@ bool Voice::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L if (!m_p25->m_enableControl) { m_p25->m_affiliations.releaseGrant(m_netLC.getDstId(), false); + } + + if (m_p25->m_notifyCC) { m_p25->notifyCC_ReleaseGrant(m_netLC.getDstId()); } @@ -1385,8 +1389,8 @@ void Voice::writeNet_LDU1() ::ActivityLog("P25", false, "network %svoice transmission from %u to %s%u", m_netLC.getEncrypted() ? "encrypted " : "", srcId, group ? "TG " : "", dstId); - // single-channel trunking or voice on control support? - if (m_p25->m_enableControl && m_p25->m_voiceOnControl && !m_p25->m_disableNetworkGrant) { + // conventional registration or DVRS support? + if (m_p25->m_enableControl && !m_p25->m_dedicatedControl && !m_p25->m_disableNetworkGrant) { uint8_t serviceOptions = (m_netLC.getEmergency() ? 0x80U : 0x00U) + // Emergency Flag (m_netLC.getEncrypted() ? 0x40U : 0x00U) + // Encrypted Flag (m_netLC.getPriority() & 0x07U); // Priority @@ -1512,8 +1516,8 @@ void Voice::writeNet_LDU1() sysId = lc::LC::getSiteData().sysId(); } - // single-channel trunking or voice on control support? - if (m_p25->m_enableControl && m_p25->m_voiceOnControl) { + // conventional registration or DVRS support? + if (m_p25->m_enableControl && !m_p25->m_dedicatedControl) { // per TIA-102.AABD-B transmit RFSS_STS_BCAST every 3 superframes (e.g. every 3 LDU1s) m_vocLDU1Count++; if (m_vocLDU1Count > VOC_LDU1_COUNT) {