Name the channel leg whose hold behavior changes
PJSIP_MOH_PASSTHROUGH() reads or changes the current PJSIP channel's hold mode. Record the channel name, unique ID, linked ID, endpoint, bridge peer and dialplan location before reading or writing it. A caller leg, callee leg, Local-channel half and transferred replacement are not interchangeable even when they share one linked ID.
The function changes a call-leg behavior, not a global endpoint template or every active channel. Set it before the relevant hold action on the channel that will process that action, and preserve the endpoint configuration owner separately.
Separate endpoint default from a per-call override
Asterisk documents the endpoint moh_passthrough option with a default of no. With passthrough enabled, hold and unhold are sent to the remote side using re-INVITEs with recvonly and sendrecv; with passthrough disabled, Asterisk generates music on hold. The dialplan function can override that endpoint option for the current call.
Confirm installed release support—the documented floors are 13.30.0, 16.7.0 and 17.1.0—and inspect the loaded endpoint plus the channel value. A current online page or source sample is not proof that an older vendor package implements the same function or that a prior write ran on this channel.
Choose who owns the held media path
Local generation keeps Asterisk responsible for selecting a music class and sending media to the held party. Passthrough asks the remote side to react to a new offer, so the remote endpoint, PBX or provider may become responsible for silence, tone, music or another policy. A valid local music file cannot repair remote behavior when passthrough owns the path.
Document what each party should hear and which system should send it. Preserve the selected music class, any start event, the signaling exchange, final RTP sources and a listening result separately. A hold icon, class name or successful SIP response proves less than audible media.
Read hold and resume as offer-answer transitions
RFC 6337 describes hold commonly using a new offer with a=sendonly and a compatible recvonly answer, while a=inactive can be used when the holding user agent intends to transmit no media. Resume commonly returns toward sendrecv, but each side retains its own desired state. Preserve the complete offer and answer rather than interpreting one direction attribute alone.
The RFC also warns that sendonly and inactive are not certain proof of a human hold action. Treat method, Call-ID, tags, CSeq, SDP origin version, media line, direction, final response and resulting packets as one bounded transaction.
Keep passthrough distinct from interception, early media and direct media
HOLD_INTERCEPT() can suppress a device-originated hold frame and raise an event for an application; that is separate from whether PJSIP later emits a hold re-INVITE. The suppress_moh_on_sendonly endpoint option separately stops Asterisk from generating music when received SDP contains sendonly or inactive, including in early-media responses. Neither control is an alias for passthrough.
Direct-media moves, session refreshes, connected-line changes and transfers can also create in-dialog requests. Attribute each re-INVITE or UPDATE to its demonstrated trigger, and reconstruct any 491 or other collision before changing glare or direct-media policy.
Accept hold, media and resume as separate results
Use an authorized non-emergency call in each required direction. Capture the effective channel mode, device action, hold offer and answer, music or remote-media owner, RTP source and destination, what each party hears, resume offer and answer, restored two-way audio, transfer behavior and hangup. Include a control that retains local music generation.
Correct one evidence-backed owner and preserve rollback. Do not enable passthrough fleet-wide to fix one music file, or replace local media when the remote system owns the held path. This guide is documentation-derived; no PBX, endpoint, channel, re-INVITE, music source, media stream or call was tested.
[hold-policy]
exten => s,1,NoOp(Current PJSIP hold passthrough: ${PJSIP_MOH_PASSTHROUGH()})
same => n,Set(PJSIP_MOH_PASSTHROUGH()=yes)
same => n,NoOp(Effective PJSIP hold passthrough: ${PJSIP_MOH_PASSTHROUGH()})
same => n,Return()Pair hold signaling with the runtime media restriction
The RTP context guide keeps CHANNEL(rtp,hold,...), SDP direction, bridge behavior, RTP and audible music as separate evidence.
Resolve the BridgeWait entertainment mode first
The BridgeWait diagnostic separates intended music, ring, silence, hold or no-entertainment behavior from PJSIP hold and media faults.
Sources & applicability
Primary references for the technical details above. Operational examples and planning checklists are VoIP.info editorial guidance.
- Asterisk PJSIP_MOH_PASSTHROUGH dialplan function ↗
- Asterisk PJSIP_ENDPOINT dialplan function ↗
- Asterisk res_pjsip module configuration ↗
- Asterisk pjsip.conf sample ↗
- RFC 6337: SIP usage of the offer-answer model ↗
- RFC 3264: An offer-answer model with SDP ↗
- Asterisk CHANNEL dialplan function ↗
- Asterisk bridge media paths ↗
- Asterisk PJSIP troubleshooting guide ↗
- RFC 3711: Secure RTP ↗
- Asterisk 23 BridgeWait application ↗
- Asterisk 22 BridgeWait application ↗
- Asterisk 23 BridgeAdd application ↗
- Asterisk 22 BridgeAdd application ↗
- Asterisk Bridge application overview ↗
- Asterisk ARI bridge overview ↗
Examples require adaptation to your topology. No live PBX or hardware testing is claimed.