freeswitch icon indicating copy to clipboard operation
freeswitch copied to clipboard

bypass_media is not working when using enterprise originate

Open silviucpp opened this issue 2 years ago • 0 comments

I'm uncertain whether it's a bug, but in FS 1.10.10, the bypass_media feature doesn't seem to function properly when using enterprise originate.

Upon examining the code, it appears to be intentional. In particular, switch_ivr_enterprise_originate invokes switch_ivr_originate with session = NULL. This decision makes sense because within this function, multiple calls to switch_ivr_originate are triggered from different threads (one for each destination) using the same session.

Within switch_ivr_originate, if session is NULL, the section of code responsible for setting the appropriate channel flags for media bypass is not executed. This section of code is :

if (session) {
	const char *to_var, *bypass_media = NULL, *proxy_media = NULL;
	switch_channel_set_flag(caller_channel, CF_ORIGINATOR);
	oglobals.session = session;

	switch_channel_execute_on(caller_channel, SWITCH_CHANNEL_EXECUTE_ON_PRE_ORIGINATE_VARIABLE);
	switch_channel_api_on(caller_channel, SWITCH_CHANNEL_API_ON_PRE_ORIGINATE_VARIABLE);

	switch_core_session_get_read_impl(session, &read_impl);

	if ((to_var = switch_channel_get_variable(caller_channel, SWITCH_CALL_TIMEOUT_VARIABLE))) {
		timelimit_sec = atoi(to_var);
	}

	proxy_media = switch_channel_get_variable(caller_channel, SWITCH_PROXY_MEDIA_VARIABLE);
	bypass_media = switch_channel_get_variable(caller_channel, SWITCH_BYPASS_MEDIA_VARIABLE);

	if (!zstr(proxy_media)) {
		if (switch_true(proxy_media)) {
			switch_channel_set_flag(caller_channel, CF_PROXY_MEDIA);
		} else if (switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA)) {
			switch_channel_clear_flag(caller_channel, CF_PROXY_MEDIA);
		}
	}

	if (bypass_media && switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA) && !switch_channel_test_flag(caller_channel, CF_ANSWERED)) {
		switch_core_session_message_t msg = { 0 };

		msg.message_id = SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS;
		msg.from = __FILE__;
		switch_core_session_receive_message(session, &msg);
	}


	if (!zstr(bypass_media) && !switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA)) {
		if (switch_true(bypass_media)) {
			switch_channel_set_flag(caller_channel, CF_PROXY_MODE);
		} else if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)) {
			if (!switch_channel_test_flag(caller_channel, CF_ANSWERED) && switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA)) {
				switch_channel_set_variable(caller_channel, SWITCH_B_SDP_VARIABLE, NULL);
				switch_channel_answer(caller_channel);
				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
								  "Must answer channel %s due to SIP PARADOX\n", switch_channel_get_name(caller_channel));
			}
			switch_channel_set_variable(caller_channel, SWITCH_B_SDP_VARIABLE, NULL);
			switch_ivr_media(switch_core_session_get_uuid(session), SMF_NONE);
		}
	}

	if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE) && switch_channel_test_flag(caller_channel, CF_ANSWERED)) {
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
						  "Channel is already up, delaying proxy mode 'till both legs are answered.\n");
		switch_channel_set_variable(caller_channel, "bypass_media_after_bridge", "true");
		switch_channel_set_variable(caller_channel, SWITCH_BYPASS_MEDIA_VARIABLE, NULL);
		switch_channel_clear_flag(caller_channel, CF_PROXY_MODE);
	}
}

So question : is this a bug or an unsupported feature that's not documented ?

silviucpp avatar Dec 07 '23 13:12 silviucpp