diff --git a/src/include/switch_caller.h b/src/include/switch_caller.h index f0dc1c76fe..1fd5ecbd29 100644 --- a/src/include/switch_caller.h +++ b/src/include/switch_caller.h @@ -127,6 +127,7 @@ typedef struct profile_node_s { switch_memory_pool_t *pool; struct switch_caller_profile *next; switch_call_direction_t direction; + switch_call_direction_t logical_direction; profile_node_t *soft; char *uuid_str; char *clone_of; diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index 234b692114..9e7c91f935 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -633,6 +633,7 @@ SWITCH_DECLARE(int) switch_channel_test_app_flag_key(const char *app, switch_cha SWITCH_DECLARE(void) switch_channel_set_bridge_time(switch_channel_t *channel); SWITCH_DECLARE(void) switch_channel_set_hangup_time(switch_channel_t *channel); SWITCH_DECLARE(switch_call_direction_t) switch_channel_direction(switch_channel_t *channel); +SWITCH_DECLARE(switch_call_direction_t) switch_channel_logical_direction(switch_channel_t *channel); SWITCH_DECLARE(void) switch_channel_set_direction(switch_channel_t *channel, switch_call_direction_t direction); SWITCH_DECLARE(switch_core_session_t *) switch_channel_get_session(switch_channel_t *channel); diff --git a/src/switch_channel.c b/src/switch_channel.c index aa73b4d2fc..21b9dedc6f 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -139,6 +139,7 @@ typedef enum { struct switch_channel { char *name; switch_call_direction_t direction; + switch_call_direction_t logical_direction; switch_queue_t *dtmf_queue; switch_queue_t *dtmf_log_queue; switch_mutex_t*dtmf_mutex; @@ -393,7 +394,7 @@ SWITCH_DECLARE(switch_channel_timetable_t *) switch_channel_get_timetable(switch SWITCH_DECLARE(void) switch_channel_set_direction(switch_channel_t *channel, switch_call_direction_t direction) { if (!switch_core_session_in_thread(channel->session)) { - channel->direction = direction; + channel->direction = channel->logical_direction = direction; } } @@ -402,6 +403,11 @@ SWITCH_DECLARE(switch_call_direction_t) switch_channel_direction(switch_channel_ return channel->direction; } +SWITCH_DECLARE(switch_call_direction_t) switch_channel_logical_direction(switch_channel_t *channel) +{ + return channel->logical_direction; +} + SWITCH_DECLARE(switch_status_t) switch_channel_alloc(switch_channel_t **channel, switch_call_direction_t direction, switch_memory_pool_t *pool) { switch_assert(pool != NULL); @@ -423,7 +429,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_alloc(switch_channel_t **channel, switch_mutex_init(&(*channel)->profile_mutex, SWITCH_MUTEX_NESTED, pool); (*channel)->hangup_cause = SWITCH_CAUSE_NONE; (*channel)->name = ""; - (*channel)->direction = direction; + (*channel)->direction = (*channel)->logical_direction = direction; switch_channel_set_variable(*channel, "direction", switch_channel_direction(*channel) == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound"); return SWITCH_STATUS_SUCCESS; @@ -1762,6 +1768,20 @@ SWITCH_DECLARE(void) switch_channel_set_flag_value(switch_channel_t *channel, sw switch_channel_set_callstate(channel, CCS_RING_WAIT); } + if (flag == CF_DIALPLAN) { + if (channel->direction == SWITCH_CALL_DIRECTION_INBOUND) { + channel->logical_direction = SWITCH_CALL_DIRECTION_OUTBOUND; + if (channel->device_node) { + channel->device_node->direction = SWITCH_CALL_DIRECTION_INBOUND; + } + } else { + channel->logical_direction = SWITCH_CALL_DIRECTION_INBOUND; + if (channel->device_node) { + channel->device_node->direction = SWITCH_CALL_DIRECTION_OUTBOUND; + } + } + } + if (HELD) { switch_hold_record_t *hr; const char *brto = switch_channel_get_partner_uuid(channel); @@ -1930,6 +1950,15 @@ SWITCH_DECLARE(void) switch_channel_clear_flag(switch_channel_t *channel, switch channel->flags[flag] = 0; switch_mutex_unlock(channel->flag_mutex); + if (flag == CF_DIALPLAN) { + if (channel->direction == SWITCH_CALL_DIRECTION_OUTBOUND) { + channel->logical_direction = SWITCH_CALL_DIRECTION_OUTBOUND; + if (channel->device_node) { + channel->device_node->direction = SWITCH_CALL_DIRECTION_INBOUND; + } + } + } + if (ACTIVE) { switch_channel_set_callstate(channel, CCS_UNHOLD); switch_mutex_lock(channel->profile_mutex); @@ -2615,6 +2644,7 @@ SWITCH_DECLARE(void) switch_channel_set_caller_profile(switch_channel_t *channel switch_assert(caller_profile != NULL); caller_profile->direction = channel->direction; + caller_profile->logical_direction = channel->logical_direction; uuid = switch_core_session_get_uuid(channel->session); if (!caller_profile->uuid || strcasecmp(caller_profile->uuid, uuid)) { @@ -2697,6 +2727,7 @@ SWITCH_DECLARE(void) switch_channel_set_hunt_caller_profile(switch_channel_t *ch channel->caller_profile->hunt_caller_profile = NULL; if (channel->caller_profile && caller_profile) { caller_profile->direction = channel->direction; + caller_profile->logical_direction = channel->logical_direction; channel->caller_profile->hunt_caller_profile = caller_profile; } switch_mutex_unlock(channel->profile_mutex); @@ -5038,7 +5069,7 @@ static void add_uuid(switch_device_record_t *drec, switch_channel_t *channel) node->uuid = switch_core_strdup(drec->pool, switch_core_session_get_uuid(channel->session)); node->parent = drec; node->callstate = channel->callstate; - node->direction = channel->direction == SWITCH_CALL_DIRECTION_INBOUND ? SWITCH_CALL_DIRECTION_OUTBOUND : SWITCH_CALL_DIRECTION_INBOUND; + node->direction = channel->logical_direction == SWITCH_CALL_DIRECTION_INBOUND ? SWITCH_CALL_DIRECTION_OUTBOUND : SWITCH_CALL_DIRECTION_INBOUND; channel->device_node = node; diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 356e03f43d..089301da0e 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -1695,6 +1695,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu } } + if (switch_channel_direction(originatee_channel) == SWITCH_CALL_DIRECTION_OUTBOUND && switch_channel_test_flag(originatee_channel, CF_DIALPLAN)) { + switch_channel_clear_flag(originatee_channel, CF_DIALPLAN); + } + cleanup_proxy_mode_a(originator_session); cleanup_proxy_mode_a(originatee_session);