MOH Playing on Both Channels in ARI Bridge Scenario

I have two channels in a bridge managed via an ARI Stasis application. When I receive a **UserEvent** for hold, I place one channel on hold and play MOH (Music On Hold) for the other channel. However, MOH is being played for both channels instead of just the second leg, which is not the desired behavior.

Here’s the log snippet showing MOH being started and stopped for both channels:

Started music on hold, class 'default', on channel 'PJSIP/sipcore-00000277'  
Started music on hold, class 'default', on channel 'PJSIP/sipcore-00000278'  

Stopped music on hold on PJSIP/sipcore-00000277  
Stopped music on hold on PJSIP/sipcore-00000278  

nterestingly, when I perform the hold operation directly from the desk phone, MOH is correctly played only for the other channel.

Key Details:

  • Both channels are in a bridge.
  • Hold and MOH are triggered programmatically via the ARI Stasis app.
  • Desired behavior: MOH should only be heard on the second leg.

What could be causing MOH to play on both channels in this scenario, and how can I ensure it only plays for the second channel?

You need to show how in ARI you are actually doing this. Specifically, what “place one channel on hold” means and what “play MOH (Music On Hold) for the other channel” means.

I am controlling all from my stasis application.

  1. Channels are originated from stasis (using originate method)
  2. Added both channels in bridge.
  3. ARI is listening for all events
  4. I have triggered an custom event for hold
  5. After that i have put the channel from the event on hold using channels.hold methos
ari.channels.hold({ channelId: channelToHold });
  1. Then played moh for the other channel using
ari.channels.startMoh({channelId: playMohChannelId });

Those both mostly do the same thing. Calling hold will put the channel on hold, which will play music on hold. It generates hold events for hold/unhold. startMoh plays music on hold but does not generate the hold/unhold events.

There is no explicit ability, from a SIP signaling perspective, to send a SIP re-INVITE to put the remote side on hold unless you have moh_passthrough set on the PJSIP endpoint in which case Asterisk would never locally generate music on hold for that endpoint.

It sounds like you’re wanting a level of third party call control that isn’t really available to that degree.

Thanks for the tip.
I have one other issue also , that is I am getting the audio from the end which I put on hold. That end can only hear the hold music.

Use the mute functionality to mute that direction of their channel.

Ok thanks.

I got another issue while performing hold.

Started music on hold, class 'default', on channel 'PJSIP/sipcore-00000335'
       > Bridge BRvg0Ly6JLwbVytm6DKAhPS: switching from native_rtp technology to simple_bridge
Stopped music on hold on PJSIP/sipcore-00000335

This is the log from asterisk. The hold music starting and stopping. So not hearing any musics.

You haven’t provided any real information aside from showing that it happened. I don’t know what ARI things you’ve done in this new iteration, what the state of the channel is, nothing. The more information you provide - such as an Asterisk debug log and details of all the ARI interaction - the more likely it is I, or someone else, can provide some guidance.

I have a setup where a call is initiated from a mobile application to a desk phone. The call flow is as follows:

  1. The call originates from the mobile app and hits Twilio.
  2. Twilio forwards the call to Asterisk as an inbound call.
  3. From Asterisk, our ARI Stasis application originates the desk phone leg.
  4. Both channels are bridged.

Observed Behavior:

  • When I click the hold button on the desk phone, the mobile app correctly hears the MOH (Music On Hold).
  • However, when I initiate hold from the mobile app (handled via a UserEvent in the Stasis app), MOH is not played on the desk phone.

Logs from asterisk

Executing [jsclientdevelopment-metrowest@internal:1] Verbose("PJSIP/sipcore-00000344", "Call from softphone for outbound") in new stack
Call from softphone for outbound
    -- Executing [jsclientdevelopment-metrowest@internal:2] Ringing("PJSIP/sipcore-00000344", "") in new stack
    -- Executing [jsclientdevelopment-metrowest@internal:3] Set("PJSIP/sipcore-00000344", "callee=102") in new stack
    -- Executing [jsclientdevelopment-metrowest@internal:4] Set("PJSIP/sipcore-00000344") in new stack
    -- Executing [jsclientdevelopment-metrowest@internal:5] Stasis("PJSIP/sipcore-00000344", "stasis-app-dev,outgoing) in new stack
       > 0x7fa4c4141020 -- Strict RTP learning after remote address set to: 172.30.10.113:36840
    -- Channel PJSIP/sipcore-00000345 joined 'holding_bridge' stasis-bridge <f41fa6fd-b9b9-4333-9064-4e9a1e0f539b>
    -- Channel PJSIP/sipcore-00000344 joined 'simple_bridge' stasis-bridge <BRaJwf0Mw-W9tHTe9JWbvB->
    -- Channel PJSIP/sipcore-00000345 left 'holding_bridge' stasis-bridge <f41fa6fd-b9b9-4333-9064-4e9a1e0f539b>
    -- Channel PJSIP/sipcore-00000345 joined 'simple_bridge' stasis-bridge <BRaJwf0Mw-W9tHTe9JWbvB->
       > 0x7fa4c4141020 -- Strict RTP switching to RTP target address 172.30.10.113:36840 as source
sipmedia1*CLI> 
       > 0x7fa4c411b700 -- Strict RTP learning after remote address set to: 172.30.10.113:46774
    -- Channel PJSIP/sipcore-00000345 left 'simple_bridge' stasis-bridge <BRaJwf0Mw-W9tHTe9JWbvB->
    -- Channel PJSIP/sipcore-00000345 joined 'simple_bridge' stasis-bridge <BRaJwf0Mw-W9tHTe9JWbvB->
       > Bridge BRaJwf0Mw-W9tHTe9JWbvB-: switching from simple_bridge technology to native_rtp
       > Remotely bridged 'PJSIP/sipcore-00000345' and 'PJSIP/sipcore-00000344' - media will flow directly between them
    -- Channel PJSIP/sipcore-00000344 left 'native_rtp' stasis-bridge <BRaJwf0Mw-W9tHTe9JWbvB->
       > Bridge BRaJwf0Mw-W9tHTe9JWbvB-: switching from native_rtp technology to simple_bridge
    -- Channel PJSIP/sipcore-00000344 joined 'simple_bridge' stasis-bridge <BRaJwf0Mw-W9tHTe9JWbvB->
       > Bridge BRaJwf0Mw-W9tHTe9JWbvB-: switching from simple_bridge technology to native_rtp
       > Remotely bridged 'PJSIP/sipcore-00000344' and 'PJSIP/sipcore-00000345' - media will flow directly between them
       > 0x7fa4c411b700 -- Strict RTP learning after remote address set to: 172.30.10.113:46774
       > 0x7fa4c411b700 -- Strict RTP learning after remote address set to: 172.30.10.113:46774
       > 0x7fa4c411b700 -- Strict RTP learning after remote address set to: 172.30.10.113:46774
   **Log when hold from mobile**
    -- Started music on hold, class 'default', on channel 'PJSIP/sipcore-00000345'
       > Bridge BRaJwf0Mw-W9tHTe9JWbvB-: switching from native_rtp technology to simple_bridge
    -- Stopped music on hold on PJSIP/sipcore-00000345
       > 0x7fa4c411b700 -- Strict RTP switching to RTP target address 172.30.10.113:46774 as source
       > 0x7fa4c4141020 -- Strict RTP learning complete - Locking on source address 172.30.10.113:36840
       > 0x7fa4c411b700 -- Strict RTP learning complete - Locking on source address 172.30.10.113:46774
       > Bridge BRaJwf0Mw-W9tHTe9JWbvB-: switching from simple_bridge technology to native_rtp
       > Remotely bridged 'PJSIP/sipcore-00000344' and 'PJSIP/sipcore-00000345' - media will flow directly between them
    **Log when hold from Desk phone.**
    -- Started music on hold, class 'default', on channel 'PJSIP/sipcore-00000344'
    -- Stopped music on hold on PJSIP/sipcore-00000344
    -- Channel PJSIP/sipcore-00000344 left 'native_rtp' stasis-bridge <BRaJwf0Mw-W9tHTe9JWbvB->
       > Bridge BRaJwf0Mw-W9tHTe9JWbvB-: switching from native_rtp technology to simple_bridge
    -- Channel PJSIP/sipcore-00000345 left 'simple_bridge' stasis-bridge <BRaJwf0Mw-W9tHTe9JWbvB->

And if you remove the channel from the bridge and do hold?

I didn’t check. Do i need to check that?

It’s a basic step in troubleshooting and understanding. Simplify the scenario to see the result and what happens to narrow down the cause.

Ok

Now its working fine. I removed the holding channel from the bridge. What may be the issue?

Why its switching from native_rtp to simple_bridge on holding?

You haven’t disabled direct_media on the endpoints, causing media to flow directly when bridged. If you put a channel on hold the audio has to come from Asterisk, so it has to bring the media back to Asterisk to flow through it.