Exemple #1
0
static switch_status_t loopback_bowout_on_execute_state_handler(switch_core_session_t *session)
{
	switch_channel_t *channel = switch_core_session_get_channel(session);
	switch_channel_state_t state = switch_channel_get_state(channel);
	private_t *tech_pvt = NULL;


	if (state == CS_EXECUTE) {
		const char *uuid;
		switch_core_session_t *other_session = NULL;
		switch_channel_t *b_channel = NULL;

		tech_pvt = switch_core_session_get_private(session);

		if (switch_core_session_read_lock(tech_pvt->other_session) == SWITCH_STATUS_SUCCESS) {
			b_channel = switch_core_session_get_channel(tech_pvt->other_session);

			/* Wait for b_channel to be fully bridged */
			switch_channel_wait_for_flag(b_channel, CF_BRIDGED, SWITCH_TRUE, 5000, NULL);

			uuid = switch_channel_get_partner_uuid(b_channel);

			if (uuid && (other_session = switch_core_session_locate(uuid))) {
				switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
				switch_caller_profile_t *cp, *clone;

				switch_channel_wait_for_state(other_channel, NULL, CS_EXCHANGE_MEDIA);

				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->other_session), SWITCH_LOG_INFO, "Replacing loopback channel: %s with real channel: %s\n",
								  switch_channel_get_name(b_channel), switch_channel_get_name(other_channel));

				if ((cp = switch_channel_get_caller_profile(channel))) {
					clone = switch_caller_profile_clone(other_session, cp);
					clone->originator_caller_profile = NULL;
					clone->originatee_caller_profile = NULL;
					switch_channel_set_caller_profile(other_channel, clone);
				}

				switch_channel_caller_extension_masquerade(channel, other_channel, 0);
				switch_channel_set_state(other_channel, CS_RESET);
				switch_channel_wait_for_state(other_channel, NULL, CS_RESET);
				switch_channel_set_variable(channel, "process_cdr", "false");
				switch_channel_set_variable(b_channel, "process_cdr", "false");
				switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
				switch_channel_set_state(other_channel, CS_EXECUTE);
				switch_core_session_rwunlock(other_session);
			}

			switch_core_session_rwunlock(tech_pvt->other_session);
		}
		
		switch_core_event_hook_remove_state_change(session, loopback_bowout_on_execute_state_handler);
	}

	return SWITCH_STATUS_SUCCESS;
}
Exemple #2
0
static switch_status_t channel_on_execute(switch_core_session_t *session)
{
	switch_channel_t *channel = NULL;
	loopback_private_t *tech_pvt = NULL;
	switch_caller_extension_t *exten = NULL;
	const char *bowout = NULL;
	int bow = 0;

	channel = switch_core_session_get_channel(session);
	assert(channel != NULL);

	tech_pvt = switch_core_session_get_private(session);
	assert(tech_pvt != NULL);

	switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL EXECUTE\n", switch_channel_get_name(channel));

	if ((bowout = switch_channel_get_variable(tech_pvt->channel, "loopback_bowout_on_execute")) && switch_true(bowout)) {
		/* loopback_bowout_on_execute variable is set */
		bow = 1;
	} else if ((exten = switch_channel_get_caller_extension(channel))) {
		/* check for bowout flag */
		switch_caller_application_t *app_p;

		for (app_p = exten->applications; app_p; app_p = app_p->next) {
			int32_t flags;

			switch_core_session_get_app_flags(app_p->application_name, &flags);

			if ((flags & SAF_NO_LOOPBACK)) {
				bow = 1;
				break;
			}
		}
	}

	if (bow) {
		switch_core_session_t *other_session = NULL;
		switch_caller_profile_t *cp, *clone;
		const char *other_uuid = NULL;
		switch_event_t *event = NULL;

		switch_set_flag(tech_pvt, TFLAG_BOWOUT);

		if ((find_non_loopback_bridge(tech_pvt->other_session, &other_session, &other_uuid) == SWITCH_STATUS_SUCCESS)) {
			switch_channel_t *other_channel = switch_core_session_get_channel(other_session);

			switch_channel_wait_for_state_timeout(other_channel, CS_EXCHANGE_MEDIA, 5000);

			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_INFO, "BOWOUT Replacing loopback channel with real channel: %s\n",
							  switch_channel_get_name(other_channel));

			if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, "loopback::bowout") == SWITCH_STATUS_SUCCESS) {
				switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Resigning-UUID", switch_channel_get_uuid(channel));
				switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Acquired-UUID", switch_channel_get_uuid(other_channel));
				switch_event_fire(&event);
			}

			if ((cp = switch_channel_get_caller_profile(channel))) {
				clone = switch_caller_profile_clone(other_session, cp);
				clone->originator_caller_profile = NULL;
				clone->originatee_caller_profile = NULL;
				switch_channel_set_caller_profile(other_channel, clone);
			}

			switch_channel_caller_extension_masquerade(channel, other_channel, 0);
			switch_channel_set_state(other_channel, CS_RESET);
			switch_channel_wait_for_state(other_channel, NULL, CS_RESET);
			switch_channel_set_state(other_channel, CS_EXECUTE);
			switch_core_session_rwunlock(other_session);
			switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_UNSPECIFIED);
		}
	}

	return SWITCH_STATUS_SUCCESS;
}