freeswitch icon indicating copy to clipboard operation
freeswitch copied to clipboard

Music on hold not played after transferring a remotely held call

Open fmfig opened this issue 1 year ago • 1 comments

Describe the bug When a remotely held call is transferred to another user, the music on hold is not played.

To Reproduce Steps to reproduce the behavior:

  1. User A calls User B
  2. User B answers the call
  3. User A puts the call on hold, User B hears music on hold
  4. User B transfers the call to User C

Expected behavior User C should hear the music on hold.

Package version or git hash

  • Version 1.10.7

Trace logs Not available. However, I did some preliminary analysis of the code, which hopefully will help (please see Analysis sections below).

Analysis (part 1) When the INVITE is sent towards User C, the INVITE is sent with a=sendonly. I traced this back to switch_core_media.c:10374:

switch_core_session_t *orig_session = NULL;

switch_core_session_get_partner(session, &orig_session);

if (orig_session && !switch_channel_test_flag(session->channel, CF_ANSWERED)) {
	switch_core_media_set_smode(smh->session, SWITCH_MEDIA_TYPE_AUDIO,
								switch_core_session_remote_media_flow(orig_session, SWITCH_MEDIA_TYPE_AUDIO), sdp_type);
	switch_core_media_set_smode(smh->session, SWITCH_MEDIA_TYPE_VIDEO,
								switch_core_session_remote_media_flow(orig_session, SWITCH_MEDIA_TYPE_VIDEO), sdp_type);
}

This code seems to take the media flow (SWITCH_MEDIA_FLOW_SENDONY) from the orig_session.

☁️ Since “music on hold” is configured, I think that the INVITE shouldn’t rely on the orig_session, but instead send always sendrecv. This is at least what happens when a regular call is placed on hold: the callee does not receive a re-INVITE with the a=sendonly (he is not informed that the caller held the call).

Analysis (part 2) When the call is transferred, User A is receiving a re-INVITE request, which is replied with a a=sendonly:

o=- 3901021402 3901021404 IN IP4 172.16.0.1
s=pjmedia
b=AS:84
t=0 0
a=X-nat:0
m=audio 4000 RTP/AVP 9 121
c=IN IP4 172.16.0.1
b=TIAS:64000
a=rtcp:4001 IN IP4 172.16.0.1
a=rtpmap:9 G722/8000
a=rtpmap:121 telephone-event/8000
a=fmtp:121 0-16
a=ssrc:2019046580 cname:63ac66bf4b8db8b8
a=sendonly
a=oldmediaip:192.168.1.67
a=oldmediaip:192.168.1.67
a=oldmediaip:192.168.1.67
2023-08-14 17:03:33.339 [DEBUG] switch_ivr_bridge.c:915 BRIDGE THREAD DONE [sofia/sipinterface_1/[email protected]]
2023-08-14 17:03:33.339 [NOTICE] switch_ivr_bridge.c:930 Hangup sofia/sipinterface_1/[email protected] [CS_EXCHANGE_MEDIA] [NORMAL_CLEARING]
2023-08-14 17:03:33.339 [DEBUG] switch_channel.c:2161 (sofia/sipinterface_1/[email protected]) Callstate Change HELD -> UNHELD

I traced back the function call that makes the callstate changing from HELD → UNHELD to the instruction switch_channel_mark_hold(chan_a, SWITCH_FALSE); in switch_ivr_bridge.c:

	if (switch_channel_test_flag(chan_a, CF_LEG_HOLDING) || switch_channel_test_flag(chan_a, CF_HANGUP_HELD)) {
		if (switch_channel_ready(chan_b) &&
			switch_channel_get_state(chan_b) != CS_PARK && !data->other_leg_data->clean_exit && !switch_channel_test_flag(chan_b, CF_3P_NOMEDIA_REQUESTED)) {
			const char *ext = switch_channel_get_variable(chan_a, "hold_hangup_xfer_exten");

			switch_channel_stop_broadcast(chan_b);

			if (zstr(ext)) {
				switch_call_cause_t cause = switch_channel_get_cause(chan_b);
				if (cause == SWITCH_CAUSE_NONE) {
					cause = SWITCH_CAUSE_NORMAL_CLEARING;
				}
				switch_channel_hangup(chan_b, cause);
			} else {
				switch_channel_set_variable(chan_b, SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE, ext);
			}
		}

		if (switch_channel_test_flag(chan_a, CF_LEG_HOLDING)) {
			switch_channel_mark_hold(chan_a, SWITCH_FALSE);
		}
	}

This code was added in this commit, to solve FS-6272. I couldn’t find information regarding this issue, except for this:

f862c34 fixed bug in Freeswitch core dealing with calls not hanging up 
after hold
Jira: http://jira.freeswitch.org/browse/FS-6272

☁️ The strange thing here is that the channel being hanged up is the channel for User B, not User A, as shown in the log above. I also cannot understand why the channel needs to be unheld, as User A kept the call on hold.

fmfig avatar Sep 07 '23 13:09 fmfig

I'm facing same issue , any news on this ?

silviucpp avatar Dec 11 '23 11:12 silviucpp