diff --git a/configs/bridge-config.example.yml b/configs/bridge-config.example.yml index 7040e242..6e3ddf45 100644 --- a/configs/bridge-config.example.yml +++ b/configs/bridge-config.example.yml @@ -57,62 +57,6 @@ network: # Flag indicating whether or not verbose debug logging is enabled. debug: false - # - # UDP Audio Transport Configuration - # NOTE: Validate the UDP Audio Configuration section below when using UDP audio. Bridge does *not* - # by default, perform any timing for UDP audio, so proper configuration is required. - # - - # Enable PCM audio over UDP. - udpAudio: false - # Enable meta data such as dstId and srcId in the UDP data. - udpMetadata: false - # PCM over UDP send port. - udpSendPort: 34001 - # PCM over UDP send address destination. - udpSendAddress: "127.0.0.1" - # PCM over UDP receive port. - udpReceivePort: 32001 - # PCM over UDP receive address. - udpReceiveAddress: "127.0.0.1" - - # - # UDP Audio Configuration - # NOTE: When configuring UDP audio for back-to-back transcoding, it is highly recommended to - # enable 'udpRTPFrames' and 'udpUseULaw' to ensure proper timing and framing of audio packets. - # - - # Flag indicating UDP audio should be RTP framed. - udpRTPFrames: true - # Flag indicating UDP audio RTP timing should be ignored. - # (This allows the sending source to send audio as fast as it wants. This should not be used in combination - # with 'udpFrameTiming', and is intended for diagnostic purposes only.) - udpIgnoreRTPTiming: false - # Flag indicating UDP audio should be encoded using G.711 uLaw. - # NOTE: This flag is only applicable when sending audio via RTP. - udpUseULaw: false - - # Flag indicating UDP audio should follow the USRP format. - udpUsrp: false - - # Flag indicating UDP audio frame timing will be performed by the bridge. - # (This allows the sending source to send audio as fast as it wants. This should not be used in combination - # with 'udpRTPFrames'.) - udpFrameTiming: false - - # - # Traffic Encryption Key (TEK) Configuration - # - tek: - # Flag indicating whether or not traffic encryption is enabled. - enable: false - # Traffic Encryption Key Algorithm - # aes - AES-256 Encryption - # arc4 - ARC4/ADP Encryption - tekAlgo: "aes" - # Traffic Encryption Key ID (Hex) - tekKeyId: 1 - # Source "Radio ID" for transmitted audio frames. sourceId: 1234567 # Flag indicating the source "Radio ID" will be overridden from the detected @@ -138,6 +82,12 @@ system: # System ID. sysId: 001 + # Flag indicating whether a network grant demand packet will be sent before audio. + grantDemand: false + + # Audio transmit mode (1 - DMR, 2 - P25, 3 - Analog). + txMode: 1 + # PCM audio gain for received (from digital network) audio frames. # - This is used to apply gain to the decoded IMBE/AMBE audio, post-decoding. rxAudioGain: 1.0 @@ -158,8 +108,30 @@ system: # - (Not used when utilizing external USB vocoder!) vocoderEncoderAudioGain: 3.0 - # Audio transmit mode (1 - DMR, 2 - P25, 3 - Analog). - txMode: 1 + # Flag indicating whether or not trace logging is enabled. + trace: false + # Flag indicating whether or not debug logging is enabled. + debug: false + + # + # Traffic Encryption Key (TEK) Configuration + # + tek: + # Flag indicating whether or not traffic encryption is enabled. + enable: false + # Traffic Encryption Key Algorithm + # aes - AES-256 Encryption + # arc4 - ARC4/ADP Encryption + tekAlgo: "aes" + # Traffic Encryption Key ID (Hex) + tekKeyId: 1 + + # + # Local Audio Transport + # + + # Enable local audio over speakers. + localAudio: true # Relative sample level for VOX to activate. voxSampleLevel: 80.0 @@ -179,18 +151,53 @@ system: # Amount of time (ms) to transmit preamble tone. preambleLength: 200 - # Flag indicating whether a network grant demand packet will be sent before audio. - grantDemand: false + # + # UDP Audio Transport Configuration + # NOTE: Validate the UDP Audio Configuration section below when using UDP audio. Bridge does *not* + # by default, perform any timing for UDP audio, so proper configuration is required. + # - # Enable local audio over speakers. - localAudio: true + # Enable PCM audio over UDP. + udpAudio: false + # Enable meta data such as dstId and srcId in the UDP data. + udpMetadata: false + # PCM over UDP send port. + udpSendPort: 34001 + # PCM over UDP send address destination. + udpSendAddress: "127.0.0.1" + # PCM over UDP receive port. + udpReceivePort: 32001 + # PCM over UDP receive address. + udpReceiveAddress: "127.0.0.1" - # Flag indicating whether or not trace logging is enabled. - trace: false - # Flag indicating whether or not debug logging is enabled. - debug: false + # + # UDP Audio Configuration + # NOTE: When configuring UDP audio for back-to-back transcoding, it is highly recommended to + # enable 'udpRTPFrames' and 'udpUseULaw' to ensure proper timing and framing of audio packets. + # + # Flag indicating UDP audio should be RTP framed. + udpRTPFrames: true + # Flag indicating UDP audio RTP timing should be ignored. + # (This allows the sending source to send audio as fast as it wants. This should not be used in combination + # with 'udpFrameTiming', and is intended for diagnostic purposes only.) + udpIgnoreRTPTiming: false + # Flag indicating UDP audio should be encoded using G.711 uLaw. + # NOTE: This flag is only applicable when sending audio via RTP. + udpUseULaw: false + + # Flag indicating UDP audio should follow the USRP format. + udpUsrp: false + + # Flag indicating UDP audio frame timing will be performed by the bridge. + # (This allows the sending source to send audio as fast as it wants. This should not be used in combination + # with 'udpRTPFrames'.) + udpFrameTiming: false + + # # RTS PTT Configuration + # + # Flag indicating whether RTS PTT control is enabled. rtsPttEnable: false # Serial port device for RTS PTT control (e.g., /dev/ttyUSB0). @@ -198,7 +205,10 @@ system: # Hold-off time (ms) before clearing RTS PTT after last audio output. rtsPttHoldoffMs: 250 + # # CTS COR Configuration + # + # Flag indicating whether CTS-based COR detection is enabled. ctsCorEnable: false # Serial port device for CTS COR (e.g., /dev/ttyUSB0). Often same as RTS PTT. diff --git a/src/bridge/HostBridge.cpp b/src/bridge/HostBridge.cpp index efce15d2..e88ceb1a 100644 --- a/src/bridge/HostBridge.cpp +++ b/src/bridge/HostBridge.cpp @@ -938,6 +938,8 @@ bool HostBridge::readParams() yaml::Node systemConf = m_conf["system"]; m_identity = systemConf["identity"].as(); + m_trace = systemConf["trace"].as(false); + m_debug = systemConf["debug"].as(false); m_netId = (uint32_t)::strtoul(systemConf["netId"].as("BB800").c_str(), NULL, 16); m_netId = p25::P25Utils::netId(m_netId); @@ -1003,8 +1005,75 @@ bool HostBridge::readParams() m_localAudio = systemConf["localAudio"].as(true); - m_trace = systemConf["trace"].as(false); - m_debug = systemConf["debug"].as(false); + m_udpAudio = systemConf["udpAudio"].as(false); + m_udpMetadata = systemConf["udpMetadata"].as(false); + m_udpSendPort = (uint16_t)systemConf["udpSendPort"].as(34001); + m_udpSendAddress = systemConf["udpSendAddress"].as(); + m_udpReceivePort = (uint16_t)systemConf["udpReceivePort"].as(34001); + m_udpReceiveAddress = systemConf["udpReceiveAddress"].as(); + m_udpUsrp = systemConf["udpUsrp"].as(false); + m_udpFrameTiming = systemConf["udpFrameTiming"].as(false); + + if (m_udpUsrp) { + m_udpMetadata = false; // USRP disables metadata due to USRP always having metadata + m_udpRTPFrames = false; // USRP disables RTP + m_udpUseULaw = false; // USRP disables ULaw + } + + m_udpRTPFrames = systemConf["udpRTPFrames"].as(false); + m_udpIgnoreRTPTiming = systemConf["udpIgnoreRTPTiming"].as(false); + m_udpUseULaw = systemConf["udpUseULaw"].as(false); + if (m_udpRTPFrames) { + m_udpUsrp = false; // RTP disabled USRP + m_udpFrameTiming = false; + } + else { + if (m_udpUseULaw) { + ::LogWarning(LOG_HOST, "uLaw encoding can only be used with RTP frames, disabling."); + m_udpUseULaw = false; + } + } + + if (m_udpIgnoreRTPTiming) + ::LogWarning(LOG_HOST, "Ignoring RTP timing, audio frames will be processed as they arrive."); + + yaml::Node tekConf = systemConf["tek"]; + bool tekEnable = tekConf["enable"].as(false); + std::string tekAlgo = tekConf["tekAlgo"].as(); + std::transform(tekAlgo.begin(), tekAlgo.end(), tekAlgo.begin(), ::tolower); + m_tekKeyId = (uint32_t)::strtoul(tekConf["tekKeyId"].as("0").c_str(), NULL, 16); + if (tekEnable && m_tekKeyId > 0U) { + if (tekAlgo == TEK_AES) + m_tekAlgoId = P25DEF::ALGO_AES_256; + else if (tekAlgo == TEK_ARC4) + m_tekAlgoId = P25DEF::ALGO_ARC4; + else if (tekAlgo == TEK_DES) + m_tekAlgoId = P25DEF::ALGO_DES; + else { + ::LogError(LOG_HOST, "Invalid TEK algorithm specified, must be \"aes\" or \"adp\"."); + m_tekAlgoId = P25DEF::ALGO_UNENCRYPT; + m_tekKeyId = 0U; + } + } + + if (!tekEnable) + m_tekAlgoId = P25DEF::ALGO_UNENCRYPT; + if (m_tekAlgoId == P25DEF::ALGO_UNENCRYPT) + m_tekKeyId = 0U; + + // ensure encryption is currently disabled for DMR (its not supported) + if (m_txMode == TX_MODE_DMR && m_tekAlgoId != P25DEF::ALGO_UNENCRYPT && m_tekKeyId > 0U) { + ::LogError(LOG_HOST, "Encryption is not supported for DMR. Disabling."); + m_tekAlgoId = P25DEF::ALGO_UNENCRYPT; + m_tekKeyId = 0U; + } + + // ensure encryption is currently disabled for analog (its not supported) + if (m_txMode == TX_MODE_ANALOG && m_tekAlgoId != P25DEF::ALGO_UNENCRYPT && m_tekKeyId > 0U) { + ::LogError(LOG_HOST, "Encryption is not supported for Analog. Disabling."); + m_tekAlgoId = P25DEF::ALGO_UNENCRYPT; + m_tekKeyId = 0U; + } // RTS PTT Configuration m_rtsPttEnable = systemConf["rtsPttEnable"].as(false); @@ -1040,7 +1109,27 @@ bool HostBridge::readParams() LogInfo(" Preamble Tone Length: %ums", m_preambleLength); LogInfo(" Grant Demands: %s", m_grantDemand ? "yes" : "no"); LogInfo(" Local Audio: %s", m_localAudio ? "yes" : "no"); - LogInfo(" UDP Audio: %s", m_udpAudio ? "yes" : "no"); + LogInfo(" PCM over UDP Audio: %s", m_udpAudio ? "yes" : "no"); + if (m_udpAudio) { + LogInfo(" UDP Audio Metadata: %s", m_udpMetadata ? "yes" : "no"); + LogInfo(" UDP Audio Send Address: %s", m_udpSendAddress.c_str()); + LogInfo(" UDP Audio Send Port: %u", m_udpSendPort); + LogInfo(" UDP Audio Receive Address: %s", m_udpReceiveAddress.c_str()); + LogInfo(" UDP Audio Receive Port: %u", m_udpReceivePort); + LogInfo(" UDP Audio RTP Framed: %s", m_udpRTPFrames ? "yes" : "no"); + if (m_udpRTPFrames) { + LogInfo(" UDP Audio Use uLaw Encoding: %s", m_udpUseULaw ? "yes" : "no"); + LogInfo(" UDP Audio Ignore RTP Timing: %s", m_udpIgnoreRTPTiming ? "yes" : "no"); + } + LogInfo(" UDP Audio USRP: %s", m_udpUsrp ? "yes" : "no"); + LogInfo(" UDP Frame Timing: %s", m_udpFrameTiming ? "yes" : "no"); + } + + LogInfo(" Traffic Encrypted: %s", tekEnable ? "yes" : "no"); + if (tekEnable) { + LogInfo(" TEK Algorithm: %s", tekAlgo.c_str()); + LogInfo(" TEK Key ID: $%04X", m_tekKeyId); + } LogInfo(" RTS PTT Enable: %s", m_rtsPttEnable ? "yes" : "no"); if (m_rtsPttEnable) { LogInfo(" RTS PTT Port: %s", m_rtsPttPort.c_str()); @@ -1075,75 +1164,6 @@ bool HostBridge::createNetwork() bool packetDump = networkConf["packetDump"].as(false); bool debug = networkConf["debug"].as(false); - m_udpAudio = networkConf["udpAudio"].as(false); - m_udpMetadata = networkConf["udpMetadata"].as(false); - m_udpSendPort = (uint16_t)networkConf["udpSendPort"].as(34001); - m_udpSendAddress = networkConf["udpSendAddress"].as(); - m_udpReceivePort = (uint16_t)networkConf["udpReceivePort"].as(34001); - m_udpReceiveAddress = networkConf["udpReceiveAddress"].as(); - m_udpUsrp = networkConf["udpUsrp"].as(false); - m_udpFrameTiming = networkConf["udpFrameTiming"].as(false); - - if (m_udpUsrp) { - m_udpMetadata = false; // USRP disables metadata due to USRP always having metadata - m_udpRTPFrames = false; // USRP disables RTP - m_udpUseULaw = false; // USRP disables ULaw - } - - m_udpRTPFrames = networkConf["udpRTPFrames"].as(false); - m_udpIgnoreRTPTiming = networkConf["udpIgnoreRTPTiming"].as(false); - m_udpUseULaw = networkConf["udpUseULaw"].as(false); - if (m_udpRTPFrames) { - m_udpUsrp = false; // RTP disabled USRP - m_udpFrameTiming = false; - } else { - if (m_udpUseULaw) { - ::LogWarning(LOG_HOST, "uLaw encoding can only be used with RTP frames, disabling."); - m_udpUseULaw = false; - } - } - - if (m_udpIgnoreRTPTiming) - ::LogWarning(LOG_HOST, "Ignoring RTP timing, audio frames will be processed as they arrive."); - - yaml::Node tekConf = networkConf["tek"]; - bool tekEnable = tekConf["enable"].as(false); - std::string tekAlgo = tekConf["tekAlgo"].as(); - std::transform(tekAlgo.begin(), tekAlgo.end(), tekAlgo.begin(), ::tolower); - m_tekKeyId = (uint32_t)::strtoul(tekConf["tekKeyId"].as("0").c_str(), NULL, 16); - if (tekEnable && m_tekKeyId > 0U) { - if (tekAlgo == TEK_AES) - m_tekAlgoId = P25DEF::ALGO_AES_256; - else if (tekAlgo == TEK_ARC4) - m_tekAlgoId = P25DEF::ALGO_ARC4; - else if (tekAlgo == TEK_DES) - m_tekAlgoId = P25DEF::ALGO_DES; - else { - ::LogError(LOG_HOST, "Invalid TEK algorithm specified, must be \"aes\" or \"adp\"."); - m_tekAlgoId = P25DEF::ALGO_UNENCRYPT; - m_tekKeyId = 0U; - } - } - - if (!tekEnable) - m_tekAlgoId = P25DEF::ALGO_UNENCRYPT; - if (m_tekAlgoId == P25DEF::ALGO_UNENCRYPT) - m_tekKeyId = 0U; - - // ensure encryption is currently disabled for DMR (its not supported) - if (m_txMode == TX_MODE_DMR && m_tekAlgoId != P25DEF::ALGO_UNENCRYPT && m_tekKeyId > 0U) { - ::LogError(LOG_HOST, "Encryption is not supported for DMR. Disabling."); - m_tekAlgoId = P25DEF::ALGO_UNENCRYPT; - m_tekKeyId = 0U; - } - - // ensure encryption is currently disabled for analog (its not supported) - if (m_txMode == TX_MODE_ANALOG && m_tekAlgoId != P25DEF::ALGO_UNENCRYPT && m_tekKeyId > 0U) { - ::LogError(LOG_HOST, "Encryption is not supported for Analog. Disabling."); - m_tekAlgoId = P25DEF::ALGO_UNENCRYPT; - m_tekKeyId = 0U; - } - m_srcId = (uint32_t)networkConf["sourceId"].as(P25DEF::WUID_FNE); m_overrideSrcIdFromMDC = networkConf["overrideSourceIdFromMDC"].as(false); m_overrideSrcIdFromUDP = networkConf["overrideSourceIdFromUDP"].as(false); @@ -1236,29 +1256,6 @@ bool HostBridge::createNetwork() LogInfo(" Local: random"); LogInfo(" Encrypted: %s", encrypted ? "yes" : "no"); - - LogInfo(" PCM over UDP Audio: %s", m_udpAudio ? "yes" : "no"); - if (m_udpAudio) { - LogInfo(" UDP Audio Metadata: %s", m_udpMetadata ? "yes" : "no"); - LogInfo(" UDP Audio Send Address: %s", m_udpSendAddress.c_str()); - LogInfo(" UDP Audio Send Port: %u", m_udpSendPort); - LogInfo(" UDP Audio Receive Address: %s", m_udpReceiveAddress.c_str()); - LogInfo(" UDP Audio Receive Port: %u", m_udpReceivePort); - LogInfo(" UDP Audio RTP Framed: %s", m_udpRTPFrames ? "yes" : "no"); - if (m_udpRTPFrames) { - LogInfo(" UDP Audio Use uLaw Encoding: %s", m_udpUseULaw ? "yes" : "no"); - LogInfo(" UDP Audio Ignore RTP Timing: %s", m_udpIgnoreRTPTiming ? "yes" : "no"); - } - LogInfo(" UDP Audio USRP: %s", m_udpUsrp ? "yes" : "no"); - LogInfo(" UDP Frame Timing: %s", m_udpFrameTiming ? "yes" : "no"); - } - - LogInfo(" Traffic Encrypted: %s", tekEnable ? "yes" : "no"); - if (tekEnable) { - LogInfo(" TEK Algorithm: %s", tekAlgo.c_str()); - LogInfo(" TEK Key ID: $%04X", m_tekKeyId); - } - LogInfo(" Source ID: %u", m_srcId); LogInfo(" Destination ID: %u", m_dstId); LogInfo(" DMR Slot: %u", m_slot);