Merge pull request #1307 in FS/freeswitch from ~HRISTO/freeswitch:feature/FS-10416-add-new-endpoints-to-be-called-while to master

* commit 'b11955db0bfdcccd5ad98fd689870153d31154f3':
  FS-10416: [mod_commands] add new outbound channels to an in-progress originate
This commit is contained in:
Mike Jerris 2017-07-06 20:41:20 +00:00
commit 2a788cdefd
4 changed files with 64 additions and 7 deletions

View File

@ -1548,6 +1548,7 @@ typedef enum {
CF_AWAITING_STREAM_CHANGE,
CF_PROCESSING_STREAM_CHANGE,
CF_STREAM_CHANGED,
CF_ADD_ENDPOINTS,
/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
/* IF YOU ADD NEW ONES CHECK IF THEY SHOULD PERSIST OR ZERO THEM IN switch_core_session.c switch_core_session_request_xml() */
CF_FLAG_MAX

View File

@ -4832,7 +4832,7 @@ SWITCH_STANDARD_API(pause_function)
return SWITCH_STATUS_SUCCESS;
}
#define ORIGINATE_SYNTAX "<call url> <exten>|&<application_name>(<app_args>) [<dialplan>] [<context>] [<cid_name>] [<cid_num>] [<timeout_sec>]"
#define ORIGINATE_SYNTAX "<call url> <exten>|&<application_name>(<app_args>) [<dialplan>] [<context>] [<cid_name>] [<cid_num>] [<timeout_sec>] [<originator_uuid>]"
SWITCH_STANDARD_API(originate_function)
{
switch_channel_t *caller_channel;
@ -4858,7 +4858,7 @@ SWITCH_STANDARD_API(originate_function)
switch_assert(mycmd);
argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
if (argc < 2 || argc > 7) {
if (argc < 2 || argc > 8) {
stream->write_function(stream, "-USAGE: %s\n", ORIGINATE_SYNTAX);
goto done;
}
@ -4888,6 +4888,30 @@ SWITCH_STANDARD_API(originate_function)
timeout = atoi(argv[6]);
}
/* It is OK to use the caller_session and caller_channel variables instead of adding new ones, since this isn't a real originate */
if (argv[7]) {
caller_session = switch_core_session_locate(argv[7]);
if (caller_session) {
caller_channel = switch_core_session_get_channel(caller_session);
if (caller_channel) {
if (switch_channel_test_flag(caller_channel, CF_ORIGINATOR) && switch_channel_test_flag(caller_channel, CF_ADD_ENDPOINTS) &&
!switch_channel_get_variable(caller_channel, "originate_add_endpoints")) {
switch_channel_set_variable(caller_channel, "originate_add_endpoints", aleg);
stream->write_function(stream, "+OK %s\n", switch_core_session_get_uuid(caller_session));
} else {
stream->write_function(stream, "-ERR originator is in the wrong state (originator: %d, add endpoints: %d, var: %s)\n",
switch_channel_test_flag(caller_channel, CF_ORIGINATOR),
switch_channel_test_flag(caller_channel, CF_ADD_ENDPOINTS),
switch_channel_get_variable(caller_channel, "originate_add_endpoints"));
}
}
switch_core_session_rwunlock(caller_session);
} else {
stream->write_function(stream, "-ERR originator session not found\n");
}
goto done;
}
if (switch_ivr_originate(NULL, &caller_session, &cause, aleg, timeout, NULL, cid_name, cid_num, NULL, NULL, SOF_NONE, NULL) != SWITCH_STATUS_SUCCESS
|| !caller_session) {
stream->write_function(stream, "-ERR %s\n", switch_channel_cause2str(cause));

View File

@ -2154,6 +2154,7 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_xml(switch_e
flags[CF_SIMPLIFY] = 0;
flags[CF_VIDEO_READY] = 0;
flags[CF_VIDEO_DECODED_READ] = 0;
flags[CF_ADD_ENDPOINTS] = 0;
if (!(session = switch_core_session_request_uuid(endpoint_interface, direction, SOF_NO_LIMITS, pool, uuid))) {
return NULL;

View File

@ -1929,6 +1929,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
originate_status_t originate_status[MAX_PEERS] = { {0} };
switch_originate_flag_t dftflags = SOF_NONE, myflags = dftflags;
char *pipe_names[MAX_PEERS] = { 0 };
const char *newep = NULL;
char *data = NULL;
switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_channel_t *caller_channel = NULL;
@ -1941,7 +1942,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
time_t start, global_start;
switch_time_t last_retry_start = 0;
switch_frame_t *read_frame = NULL;
int r = 0, i, and_argc = 0, or_argc = 0;
int r = 0, i, and_argc = 0, or_argc = 0, and_argc_offset = 0;
int32_t sleep_ms = 1000, try = 0, retries = 1, retry_timelimit_sec = 0;
int32_t min_retry_period_ms = sleep_ms;
switch_codec_t write_codec = { 0 };
@ -2613,6 +2614,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
last_retry_start = switch_micro_time_now();
}
add_endpoints:
p = pipe_names[r];
while (p && *p) {
@ -2646,20 +2648,20 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
p++;
}
and_argc = switch_separate_string(pipe_names[r], ',', peer_names, (sizeof(peer_names) / sizeof(peer_names[0])));
and_argc += switch_separate_string(pipe_names[r], ',', peer_names, (sizeof(peer_names) / sizeof(peer_names[0])));
if ((flags & SOF_NOBLOCK) && and_argc > 1) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Only calling the first element in the list in this mode.\n");
and_argc = 1;
}
for (i = 0; i < and_argc; i++) {
for (i = and_argc_offset; i < and_argc; i++) {
const char *current_variable;
switch_event_t *local_var_event = NULL, *originate_var_event = NULL;
end = NULL;
chan_type = peer_names[i];
chan_type = peer_names[i-and_argc_offset];
/* strip leading spaces */
@ -3055,7 +3057,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
for (;;) {
uint32_t valid_channels = 0;
for (i = 0; i < and_argc; i++) {
for (i = and_argc_offset; i < and_argc; i++) {
int state;
time_t elapsed;
@ -3135,6 +3137,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
if (caller_channel) {
soft_holding = switch_channel_get_variable(caller_channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE);
switch_channel_set_flag(caller_channel, CF_ADD_ENDPOINTS);
}
while ((!caller_channel || switch_channel_ready(caller_channel) || switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) &&
@ -3279,6 +3282,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
break;
case SWITCH_STATUS_BREAK:
status = SWITCH_STATUS_FALSE;
switch_channel_clear_flag(caller_channel, CF_ADD_ENDPOINTS);
switch_channel_set_variable(caller_channel, "originate_add_endpoints", NULL);
goto done;
break;
default:
@ -3382,6 +3387,17 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
do_continue:
if(caller_channel) {
newep = switch_channel_get_variable(caller_channel, "originate_add_endpoints");
if (newep) {
switch_channel_set_variable(caller_channel, "originate_add_endpoints", NULL);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Add new originate endpoint(s): %s\n", newep);
and_argc_offset = and_argc;
pipe_names[r] = strdup(newep);
goto add_endpoints;
}
}
if (!read_packet) {
switch_yield(20000);
}
@ -3390,6 +3406,21 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
notready:
if (caller_channel) {
switch_channel_clear_flag(caller_channel, CF_ADD_ENDPOINTS);
newep = switch_channel_get_variable(caller_channel, "originate_add_endpoints");
if (newep) {
switch_channel_set_variable(caller_channel, "originate_add_endpoints", NULL);
/* Only add new endpoints at this stage, if it's not originator cancel and if no outbound leg was aswered */
if(oglobals.idx != IDX_CANCEL && oglobals.hups == and_argc) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Add new originate endpoints: %s\n", newep);
and_argc_offset = and_argc;
pipe_names[r] = strdup(newep);
goto add_endpoints;
}
}
holding = switch_channel_get_variable(caller_channel, SWITCH_HOLDING_UUID_VARIABLE);
switch_channel_set_variable(caller_channel, SWITCH_HOLDING_UUID_VARIABLE, NULL);