@ -173,7 +173,6 @@ HostBridge::HostBridge(const std::string& confFile) :
m_udpUseULaw ( false ) ,
m_udpUseULaw ( false ) ,
m_udpUsrp ( false ) ,
m_udpUsrp ( false ) ,
m_udpFrameTiming ( false ) ,
m_udpFrameTiming ( false ) ,
m_udpFrameTimeout ( 40U ) ,
m_udpFrameCnt ( 0U ) ,
m_udpFrameCnt ( 0U ) ,
m_tekAlgoId ( P25DEF : : ALGO_UNENCRYPT ) ,
m_tekAlgoId ( P25DEF : : ALGO_UNENCRYPT ) ,
m_tekKeyId ( 0U ) ,
m_tekKeyId ( 0U ) ,
@ -1042,7 +1041,6 @@ bool HostBridge::createNetwork()
m_udpReceiveAddress = networkConf [ " udpReceiveAddress " ] . as < std : : string > ( ) ;
m_udpReceiveAddress = networkConf [ " udpReceiveAddress " ] . as < std : : string > ( ) ;
m_udpUsrp = networkConf [ " udpUsrp " ] . as < bool > ( false ) ;
m_udpUsrp = networkConf [ " udpUsrp " ] . as < bool > ( false ) ;
m_udpFrameTiming = networkConf [ " udpFrameTiming " ] . as < bool > ( false ) ;
m_udpFrameTiming = networkConf [ " udpFrameTiming " ] . as < bool > ( false ) ;
m_udpFrameTimeout = ( uint16_t ) networkConf [ " udpFrameTimeout " ] . as < uint32_t > ( 40U ) ;
if ( m_udpUsrp ) {
if ( m_udpUsrp ) {
m_udpMetadata = false ; // USRP disables metadata due to USRP always having metadata
m_udpMetadata = false ; // USRP disables metadata due to USRP always having metadata
@ -1211,9 +1209,6 @@ bool HostBridge::createNetwork()
}
}
LogInfo ( " UDP Audio USRP: %s " , m_udpUsrp ? " yes " : " no " ) ;
LogInfo ( " UDP Audio USRP: %s " , m_udpUsrp ? " yes " : " no " ) ;
LogInfo ( " UDP Frame Timing: %s " , m_udpFrameTiming ? " yes " : " no " ) ;
LogInfo ( " UDP Frame Timing: %s " , m_udpFrameTiming ? " yes " : " no " ) ;
if ( m_udpFrameTiming ) {
LogInfo ( " UDP Frame Timeout: %u ms " , m_udpFrameTimeout ) ;
}
}
}
LogInfo ( " Traffic Encrypted: %s " , tekEnable ? " yes " : " no " ) ;
LogInfo ( " Traffic Encrypted: %s " , tekEnable ? " yes " : " no " ) ;
@ -1664,6 +1659,8 @@ void HostBridge::callEnd(uint32_t srcId, uint32_t dstId)
break ;
break ;
case TX_MODE_P25 :
case TX_MODE_P25 :
{
{
// insert 2 silence LDUs at call end for clean transition
padSilenceAudio ( srcId , dstId ) ;
padSilenceAudio ( srcId , dstId ) ;
padSilenceAudio ( srcId , dstId ) ;
p25 : : lc : : LC lc = p25 : : lc : : LC ( ) ;
p25 : : lc : : LC lc = p25 : : lc : : LC ( ) ;
@ -2129,7 +2126,6 @@ void* HostBridge::threadUDPAudioProcess(void* arg)
stopWatch . start ( ) ;
stopWatch . start ( ) ;
ulong64_t lastFrameTime = 0U ;
ulong64_t lastFrameTime = 0U ;
Timer frameTimeout = Timer ( 1000U , 0U , bridge - > m_udpFrameTimeout ) ;
while ( ! g_killed ) {
while ( ! g_killed ) {
if ( ! HostBridge : : s_running ) {
if ( ! HostBridge : : s_running ) {
@ -2141,202 +2137,251 @@ void* HostBridge::threadUDPAudioProcess(void* arg)
uint32_t ms = stopWatch . elapsed ( ) ;
uint32_t ms = stopWatch . elapsed ( ) ;
stopWatch . start ( ) ;
stopWatch . start ( ) ;
// don't consider frame timeouts for RTP or USRP UDP streams (these will be properly timed anyway, we hope)
if ( ! bridge - > m_udpRTPFrames & & ! bridge - > m_udpUsrp ) {
frameTimeout . clock ( ms ) ;
if ( frameTimeout . isRunning ( ) & & bridge - > m_udpPackets . size ( ) > 0 )
frameTimeout . start ( ) ; // clock the frame timeout timer
if ( frameTimeout . isRunning ( ) & & frameTimeout . hasExpired ( ) ) {
frameTimeout . stop ( ) ;
bridge - > padSilenceAudio ( bridge - > m_udpSrcId , bridge - > m_udpDstId ) ;
}
} else {
if ( frameTimeout . isRunning ( ) )
frameTimeout . stop ( ) ;
}
if ( bridge - > m_udpPackets . empty ( ) )
if ( bridge - > m_udpPackets . empty ( ) )
Thread : : sleep ( 1U ) ;
Thread : : sleep ( 1U ) ;
else {
else {
NetPacketRequest * req = bridge - > m_udpPackets [ 0 ] ;
NetPacketRequest * req = bridge - > m_udpPackets . front ( ) ;
if ( req ! = nullptr ) {
if ( req = = nullptr ) {
uint64_t now = std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( std : : chrono : : system_clock : : now ( ) . time_since_epoch ( ) ) . count ( ) ;
bridge - > m_udpPackets . pop_front ( ) ;
continue ;
// are we timing UDP audio frame release?
}
if ( bridge - > m_udpFrameTiming ) {
if ( lastFrameTime = = 0U )
lastFrameTime = now ;
else {
// IMBEs must go out at 20ms intervals
if ( lastFrameTime + 20U > now )
continue ;
lastFrameTime = now ;
bool shouldProcess = true ;
}
uint16_t pktSeq = 0U ;
}
uint16_t pktSeq = 0U ;
// are we using RTP frames?
if ( bridge - > m_udpRTPFrames ) {
if ( bridge - > m_udpRTPFrames ) {
pktSeq = req - > rtpHeader . getSequence ( ) ;
pktSeq = req - > rtpHeader . getSequence ( ) ;
// are we timing based on RTP timestamps?
if ( ! bridge - > m_udpIgnoreRTPTiming ) {
if ( lastFrameTime = = 0U )
lastFrameTime = req - > rtpHeader . getTimestamp ( ) ;
else {
if ( lastFrameTime + ( RTP_GENERIC_CLOCK_RATE / AUDIO_SAMPLES_LENGTH ) > = req - > rtpHeader . getTimestamp ( ) ) {
// already time to send next frame
}
else {
if ( bridge - > m_debug )
LogDebugEx ( LOG_HOST , " HostBridge::threadUDPAudioProcess() " , " RTP frame timing, delaying packet, now = %llu, lastUdpFrameTime = %llu, pktSeq = %u " ,
now , lastFrameTime , pktSeq ) ;
continue ;
}
}
lastFrameTime = now ;
// are we timing based on RTP timestamps?
if ( ! bridge - > m_udpIgnoreRTPTiming ) {
// RTP timing takes precedence - use RTP timestamps exclusively
uint32_t rtpTimestamp = req - > rtpHeader . getTimestamp ( ) ;
if ( lastFrameTime = = 0U ) {
lastFrameTime = rtpTimestamp ;
}
else {
// RTP timestamps increment by samples per frame
uint32_t expectedTimestamp = ( uint32_t ) lastFrameTime + ( RTP_GENERIC_CLOCK_RATE / AUDIO_SAMPLES_LENGTH ) ;
if ( rtpTimestamp < expectedTimestamp ) {
// Frame is too early, already processed a more recent frame
if ( bridge - > m_debug )
LogDebugEx ( LOG_HOST , " HostBridge::threadUDPAudioProcess() " , " RTP frame too early, rtpTs = %u, expected >= %u, pktSeq = %u " ,
rtpTimestamp , expectedTimestamp , pktSeq ) ;
shouldProcess = false ;
} else {
// frame is ready to process - update RTP timestamp marker
lastFrameTime = rtpTimestamp ;
}
}
}
} else if ( bridge - > m_udpFrameTiming ) {
// raw PCM with frame timing - pace at 10ms intervals using system time
if ( lastFrameTime ! = 0U ) {
// get current time right before the timing check for accuracy
uint64_t now = std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( std : : chrono : : system_clock : : now ( ) . time_since_epoch ( ) ) . count ( ) ;
// check if enough time has passed since last frame (10ms for P25 LDUs)
if ( now < lastFrameTime + 10U ) {
// Too early, don't process yet - keep frame in queue
shouldProcess = false ;
}
}
}
}
// lastFrameTime is updated AFTER we pop and commit to processing
}
// if timing checks say we shouldn't process yet, skip this iteration
if ( ! shouldProcess ) {
Thread : : sleep ( 1U ) ;
continue ;
}
uint64_t now = std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( std : : chrono : : system_clock : : now ( ) . time_since_epoch ( ) ) . count ( ) ;
if ( bridge - > m_debug )
if ( bridge - > m_debug )
LogDebugEx ( LOG_HOST , " HostBridge::threadUDPAudioProcess() " , " now = %llu, lastUdpFrameTime = %llu, audioDetect = %u, callInProgress = %u, p25N = %u, dmrN = %u, analogN = %u, frameCnt = %u, pktSeq = %u " ,
LogDebugEx ( LOG_HOST , " HostBridge::threadUDPAudioProcess() " , " now = %llu, lastUdpFrameTime = %llu, audioDetect = %u, callInProgress = %u, p25N = %u, dmrN = %u, analogN = %u, frameCnt = %u, pktSeq = %u " ,
now , lastFrameTime , bridge - > m_audioDetect , bridge - > m_callInProgress , bridge - > m_p25N , bridge - > m_dmrN , bridge - > m_analogN , bridge - > m_udpFrameCnt , pktSeq ) ;
now , lastFrameTime , bridge - > m_audioDetect , bridge - > m_callInProgress , bridge - > m_p25N , bridge - > m_dmrN , bridge - > m_analogN , bridge - > m_udpFrameCnt , pktSeq ) ;
// validate frame before popping
if ( req - > pcm = = nullptr | | req - > pcmLength = = 0U ) {
LogWarning ( LOG_HOST , " UDP audio frame has null or zero-length PCM data, discarding (pcm=%p, len=%u) " ,
req - > pcm , req - > pcmLength ) ;
bridge - > m_udpPackets . pop_front ( ) ;
bridge - > m_udpPackets . pop_front ( ) ;
bridge - > m_udpDropTime . start ( ) ;
if ( req - > pcm ! = nullptr )
frameTimeout . start ( ) ;
delete [ ] req - > pcm ;
delete req ;
// handle source ID management
continue ;
bool forceCallStart = false ;
}
uint32_t txStreamId = bridge - > m_txStreamId ;
// determine source ID to use for this UDP audio frame
if ( bridge - > m_udpMetadata ) {
// use source ID from UDP metadata if available and override is enabled
if ( bridge - > m_overrideSrcIdFromUDP ) {
if ( req - > srcId ! = 0U & & bridge - > m_udpSrcId ! = 0U ) {
// if the UDP source ID now doesn't match the current call ID, reset call states
if ( bridge - > m_resetCallForSourceIdChange & & ( req - > srcId ! = bridge - > m_udpSrcId ) ) {
LogInfoEx ( LOG_HOST , " %s, call switch over, old srcId = %u, new srcId = %u " , UDP_CALL , bridge - > m_udpSrcId , req - > srcId ) ;
bridge - > callEnd ( bridge - > m_udpSrcId , bridge - > m_dstId ) ;
if ( bridge - > m_udpDropTime . isRunning ( ) )
bridge - > m_udpDropTime . start ( ) ;
forceCallStart = true ;
}
bridge - > m_udpSrcId = req - > srcId ;
uint32_t framePcmLength = req - > pcmLength ;
uint32_t frameSrcId = req - > srcId ;
uint32_t frameDstId = req - > dstId ;
uint32_t copyLength = ( framePcmLength < = AUDIO_SAMPLES_LENGTH_BYTES ) ? framePcmLength : AUDIO_SAMPLES_LENGTH_BYTES ;
uint8_t * framePcmData = new uint8_t [ copyLength ] ;
: : memcpy ( framePcmData , req - > pcm , copyLength ) ;
// now pop the frame from the queue and free it
bridge - > m_udpPackets . pop_front ( ) ;
delete [ ] req - > pcm ;
delete req ;
req = nullptr ; // prevent use-after-free
// update frame timing marker after committing to process this frame
// (only for raw PCM timing mode - RTP timing updates within the RTP block above)
if ( ! bridge - > m_udpRTPFrames & & bridge - > m_udpFrameTiming ) {
lastFrameTime = now ;
}
bridge - > m_udpDropTime . start ( ) ;
// handle source ID management
bool forceCallStart = false ;
uint32_t txStreamId = bridge - > m_txStreamId ;
// determine source ID to use for this UDP audio frame
if ( bridge - > m_udpMetadata ) {
// use source ID from UDP metadata if available and override is enabled
if ( bridge - > m_overrideSrcIdFromUDP ) {
if ( frameSrcId ! = 0U & & bridge - > m_udpSrcId ! = 0U ) {
// if the UDP source ID now doesn't match the current call ID, reset call states
if ( bridge - > m_resetCallForSourceIdChange & & ( frameSrcId ! = bridge - > m_udpSrcId ) ) {
LogInfoEx ( LOG_HOST , " %s, call switch over, old srcId = %u, new srcId = %u " , UDP_CALL , bridge - > m_udpSrcId , frameSrcId ) ;
bridge - > callEnd ( bridge - > m_udpSrcId , bridge - > m_dstId ) ;
if ( bridge - > m_udpDropTime . isRunning ( ) )
bridge - > m_udpDropTime . start ( ) ;
forceCallStart = true ;
}
}
else {
if ( bridge - > m_udpSrcId = = 0U ) {
bridge - > m_udpSrcId = req - > srcId ;
}
if ( bridge - > m_udpSrcId = = 0U ) {
bridge - > m_udpSrcId = frameSrcId ;
bridge - > m_udpSrcId = bridge - > m_srcId ;
}
}
}
}
else {
else {
bridge - > m_udpSrcId = bridge - > m_srcId ;
if ( bridge - > m_udpSrcId = = 0U ) {
bridge - > m_udpSrcId = frameSrcId ;
}
if ( bridge - > m_udpSrcId = = 0U ) {
bridge - > m_udpSrcId = bridge - > m_srcId ;
}
}
}
}
}
else {
else {
bridge - > m_udpSrcId = bridge - > m_srcId ;
bridge - > m_udpSrcId = bridge - > m_srcId ;
}
}
}
else {
bridge - > m_udpSrcId = bridge - > m_srcId ;
}
bridge - > m_udpDstId = bridge - > m_dstId ;
bridge - > m_udpDstId = bridge - > m_dstId ;
// force start a call if one isn't already in progress
if ( ( ! bridge - > m_audioDetect & & ! bridge - > m_callInProgress ) | | forceCallStart ) {
bridge - > m_audioDetect = true ;
if ( bridge - > m_txStreamId = = 0U ) {
bridge - > m_txStreamId = 1U ;
if ( forceCallStart )
bridge - > m_txStreamId = txStreamId ;
LogInfoEx ( LOG_HOST , " %s, call start, srcId = %u, dstId = %u " , UDP_CALL , bridge - > m_udpSrcId , bridge - > m_udpDstId ) ;
if ( bridge - > m_grantDemand ) {
switch ( bridge - > m_txMode ) {
case TX_MODE_P25 :
{
p25 : : lc : : LC lc = p25 : : lc : : LC ( ) ;
lc . setLCO ( P25DEF : : LCO : : GROUP ) ;
lc . setDstId ( bridge - > m_udpDstId ) ;
lc . setSrcId ( bridge - > m_udpSrcId ) ;
p25 : : data : : LowSpeedData lsd = p25 : : data : : LowSpeedData ( ) ;
// force start a call if one isn't already in progress
if ( ( ! bridge - > m_audioDetect & & ! bridge - > m_callInProgress ) | | forceCallStart ) {
bridge - > m_audioDetect = true ;
if ( bridge - > m_txStreamId = = 0U ) {
bridge - > m_txStreamId = 1U ;
if ( forceCallStart )
bridge - > m_txStreamId = txStreamId ;
uint8_t controlByte = network : : NET_CTRL_GRANT_DEMAND ;
LogInfoEx ( LOG_HOST , " %s, call start, srcId = %u, dstId = %u " , UDP_CALL , bridge - > m_udpSrcId , bridge - > m_udpDstId ) ;
if ( bridge - > m_tekAlgoId ! = P25DEF : : ALGO_UNENCRYPT )
if ( bridge - > m_grantDemand ) {
controlByte | = network : : NET_CTRL_GRANT_ENCRYPT ;
switch ( bridge - > m_txMode ) {
controlByte | = network : : NET_CTRL_SWITCH_OVER ;
case TX_MODE_P25 :
bridge - > m_network - > writeP25TDU ( lc , lsd , controlByte ) ;
{
}
p25 : : lc : : LC lc = p25 : : lc : : LC ( ) ;
break ;
lc . setLCO ( P25DEF : : LCO : : GROUP ) ;
}
lc . setDstId ( bridge - > m_udpDstId ) ;
lc . setSrcId ( bridge - > m_udpSrcId ) ;
p25 : : data : : LowSpeedData lsd = p25 : : data : : LowSpeedData ( ) ;
uint8_t controlByte = network : : NET_CTRL_GRANT_DEMAND ;
if ( bridge - > m_tekAlgoId ! = P25DEF : : ALGO_UNENCRYPT )
controlByte | = network : : NET_CTRL_GRANT_ENCRYPT ;
controlByte | = network : : NET_CTRL_SWITCH_OVER ;
bridge - > m_network - > writeP25TDU ( lc , lsd , controlByte ) ;
// insert 2 silence LDUs at call start for clean transition
bridge - > padSilenceAudio ( bridge - > m_udpSrcId , bridge - > m_udpDstId ) ;
bridge - > padSilenceAudio ( bridge - > m_udpSrcId , bridge - > m_udpDstId ) ;
}
break ;
}
}
}
}
bridge - > m_udpDropTime . stop ( ) ;
if ( ! bridge - > m_udpDropTime . isRunning ( ) )
bridge - > m_udpDropTime . start ( ) ;
}
}
// process the received audio frame
bridge - > m_udpDropTime . stop ( ) ;
std : : lock_guard < std : : mutex > lock ( s_audioMutex ) ;
if ( ! bridge - > m_udpDropTime . isRunning ( ) )
uint8_t pcm [ AUDIO_SAMPLES_LENGTH_BYTES ] ;
bridge - > m_udpDropTime . start ( ) ;
: : memset ( pcm , 0x00U , AUDIO_SAMPLES_LENGTH_BYTES ) ;
}
: : memcpy ( pcm , req - > pcm , AUDIO_SAMPLES_LENGTH_BYTES ) ;
if ( bridge - > m_udpUseULaw ) {
if ( bridge - > m_trace )
Utils : : dump ( 1U , " HostBridge()::threadUDPAudioProcess(), uLaw Audio " , pcm , AUDIO_SAMPLES_LENGTH * 2U ) ;
int smpIdx = 0 ;
short samples [ AUDIO_SAMPLES_LENGTH ] ;
for ( uint32_t pcmIdx = 0 ; pcmIdx < AUDIO_SAMPLES_LENGTH ; pcmIdx + + ) {
samples [ smpIdx ] = AnalogAudio : : decodeMuLaw ( pcm [ pcmIdx ] ) ;
smpIdx + + ;
}
int pcmIdx = 0 ;
// process the received audio frame
for ( uint32_t smpIdx = 0 ; smpIdx < AUDIO_SAMPLES_LENGTH ; smpIdx + + ) {
std : : lock_guard < std : : mutex > lock ( s_audioMutex ) ;
pcm [ pcmIdx + 0 ] = ( uint8_t ) ( samples [ smpIdx ] & 0xFF ) ;
uint8_t pcm [ AUDIO_SAMPLES_LENGTH_BYTES ] ;
pcm [ pcmIdx + 1 ] = ( uint8_t ) ( ( samples [ smpIdx ] > > 8 ) & 0xFF ) ;
: : memset ( pcm , 0x00U , AUDIO_SAMPLES_LENGTH_BYTES ) ;
pcmIdx + = 2 ;
}
// copy the frame data we saved earlier
: : memcpy ( pcm , framePcmData , copyLength ) ;
// free the temporary copy
delete [ ] framePcmData ;
if ( bridge - > m_udpUseULaw ) {
if ( bridge - > m_trace )
Utils : : dump ( 1U , " HostBridge()::threadUDPAudioProcess(), uLaw Audio " , pcm , AUDIO_SAMPLES_LENGTH * 2U ) ;
int smpIdx = 0 ;
short samples [ AUDIO_SAMPLES_LENGTH ] ;
for ( uint32_t pcmIdx = 0 ; pcmIdx < AUDIO_SAMPLES_LENGTH ; pcmIdx + + ) {
samples [ smpIdx ] = AnalogAudio : : decodeMuLaw ( pcm [ pcmIdx ] ) ;
smpIdx + + ;
}
}
bridge - > m_trafficFromUDP = true ;
int pcmIdx = 0 ;
for ( uint32_t smpIdx = 0 ; smpIdx < AUDIO_SAMPLES_LENGTH ; smpIdx + + ) {
pcm [ pcmIdx + 0 ] = ( uint8_t ) ( samples [ smpIdx ] & 0xFF ) ;
pcm [ pcmIdx + 1 ] = ( uint8_t ) ( ( samples [ smpIdx ] > > 8 ) & 0xFF ) ;
pcmIdx + = 2 ;
}
}
// if audio detection is active and no call is in progress, encode and transmit the audio
bridge - > m_trafficFromUDP = true ;
if ( bridge - > m_audioDetect & & ! bridge - > m_callInProgress ) {
bridge - > m_udpDropTime . start ( ) ;
switch ( bridge - > m_txMode ) {
// check if PCM buffer is all zeros (silence detection for diagnostics)
case TX_MODE_DMR :
bool isSilence = true ;
bridge - > encodeDMRAudioFrame ( pcm , bridge - > m_udpSrcId ) ;
for ( uint32_t i = 0 ; i < copyLength & & isSilence ; i + + ) {
break ;
if ( pcm [ i ] ! = 0x00U ) {
case TX_MODE_P25 :
isSilence = false ;
bridge - > encodeP25AudioFrame ( pcm , bridge - > m_udpSrcId ) ;
break ;
case TX_MODE_ANALOG :
bridge - > encodeAnalogAudioFrame ( pcm , bridge - > m_udpSrcId ) ;
break ;
}
}
}
}
if ( isSilence & & bridge - > m_debug ) {
LogWarning ( LOG_HOST , " UDP audio frame contains all zeros (silence), pcmLength=%u " , copyLength ) ;
}
bridge - > m_udpFrameCnt + + ;
// encode and transmit UDP audio if audio detection is active
// Note: We encode even if a network call is in progress, since UDP audio takes priority
if ( bridge - > m_audioDetect ) {
bridge - > m_udpDropTime . start ( ) ;
delete [ ] req - > pcm ;
switch ( bridge - > m_txMode ) {
delete req ;
case TX_MODE_DMR :
} else {
bridge - > encodeDMRAudioFrame ( pcm , bridge - > m_udpSrcId ) ;
bridge - > m_udpPackets . pop_front ( ) ;
break ;
case TX_MODE_P25 :
bridge - > encodeP25AudioFrame ( pcm , bridge - > m_udpSrcId ) ;
break ;
case TX_MODE_ANALOG :
bridge - > encodeAnalogAudioFrame ( pcm , bridge - > m_udpSrcId ) ;
break ;
}
}
}
bridge - > m_udpFrameCnt + + ;
if ( ! bridge - > m_callInProgress )
if ( ! bridge - > m_callInProgress )
Thread : : sleep ( 1U ) ;
Thread : : sleep ( 1U ) ;
}
}
@ -2546,12 +2591,12 @@ void HostBridge::padSilenceAudio(uint32_t srcId, uint32_t dstId)
using namespace p25 : : defines ;
using namespace p25 : : defines ;
using namespace p25 : : data ;
using namespace p25 : : data ;
uint8_t n = m_p25N ;
// fill the LDU buffers appropriately
// fill the LDU buffers appropriately
if ( m_p25N > 0U ) {
if ( m_p25N > 0U ) {
// LDU1
// LDU1
if ( m_p25N > = 0U & & m_p25N < 9U ) {
if ( m_p25N > = 0U & & m_p25N < 9U ) {
LogWarning ( LOG_HOST , " incomplete audio frame, padding %u audio sequences with silence " , 8U - m_p25N ) ;
for ( uint8_t n = m_p25N ; n < 9U ; n + + ) {
for ( uint8_t n = m_p25N ; n < 9U ; n + + ) {
switch ( n ) {
switch ( n ) {
case 0 :
case 0 :
@ -2589,8 +2634,6 @@ void HostBridge::padSilenceAudio(uint32_t srcId, uint32_t dstId)
// LDU2
// LDU2
if ( m_p25N > = 9U & & m_p25N < 17U ) {
if ( m_p25N > = 9U & & m_p25N < 17U ) {
LogWarning ( LOG_HOST , " incomplete audio frame, padding %u audio sequences with silence " , 17U - m_p25N ) ;
for ( uint8_t n = m_p25N ; n < 18U ; n + + ) {
for ( uint8_t n = m_p25N ; n < 18U ; n + + ) {
switch ( n ) {
switch ( n ) {
case 9 :
case 9 :
@ -2666,7 +2709,7 @@ void HostBridge::padSilenceAudio(uint32_t srcId, uint32_t dstId)
// send P25 LDU1
// send P25 LDU1
if ( m_p25N = = 8U ) {
if ( m_p25N = = 8U ) {
LogInfoEx ( LOG_HOST , P25_LDU1_STR " audio (silence padded ), srcId = %u, dstId = %u" , srcId , dstId ) ;
LogInfoEx ( LOG_HOST , P25_LDU1_STR " audio (silence padded %u ), srcId = %u, dstId = %u" , 8U - n , srcId , dstId ) ;
m_network - > writeP25LDU1 ( lc , lsd , m_netLDU1 , FrameType : : DATA_UNIT ) ;
m_network - > writeP25LDU1 ( lc , lsd , m_netLDU1 , FrameType : : DATA_UNIT ) ;
m_p25N = 9U ;
m_p25N = 9U ;
break ;
break ;
@ -2674,7 +2717,7 @@ void HostBridge::padSilenceAudio(uint32_t srcId, uint32_t dstId)
// send P25 LDU2
// send P25 LDU2
if ( m_p25N = = 17U ) {
if ( m_p25N = = 17U ) {
LogInfoEx ( LOG_HOST , P25_LDU2_STR " audio (silence padded ), algo = $%02X, kid = $%04X" , ALGO_UNENCRYPT , 0U ) ;
LogInfoEx ( LOG_HOST , P25_LDU2_STR " audio (silence padded %u ), algo = $%02X, kid = $%04X" , 17U - n , ALGO_UNENCRYPT , 0U ) ;
m_network - > writeP25LDU2 ( lc , lsd , m_netLDU2 ) ;
m_network - > writeP25LDU2 ( lc , lsd , m_netLDU2 ) ;
m_p25N = 0U ;
m_p25N = 0U ;
break ;
break ;