add switch_ivr_enterprise_originate optional new dimension to originate strings every element in :_: separated list in originate strings will fire in a dedicated thread and can contain their own {} and , and | lists
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@15455 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
7d0980232e
commit
06a68fce64
|
@ -409,6 +409,19 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
|
||||||
switch_originate_flag_t flags
|
switch_originate_flag_t flags
|
||||||
);
|
);
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_ivr_enterprise_originate(switch_core_session_t *session,
|
||||||
|
switch_core_session_t **bleg,
|
||||||
|
switch_call_cause_t *cause,
|
||||||
|
const char *bridgeto,
|
||||||
|
uint32_t timelimit_sec,
|
||||||
|
const switch_state_handler_table_t *table,
|
||||||
|
const char *cid_name_override,
|
||||||
|
const char *cid_num_override,
|
||||||
|
switch_caller_profile_t *caller_profile_override,
|
||||||
|
switch_event_t *ovars,
|
||||||
|
switch_originate_flag_t flags
|
||||||
|
);
|
||||||
|
|
||||||
SWITCH_DECLARE(void) switch_ivr_bridge_display(switch_core_session_t *session, switch_core_session_t *peer_session);
|
SWITCH_DECLARE(void) switch_ivr_bridge_display(switch_core_session_t *session, switch_core_session_t *peer_session);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -517,6 +517,7 @@ SWITCH_DECLARE(switch_time_t) switch_str_time(const char *in);
|
||||||
\return the number of elements added to the array
|
\return the number of elements added to the array
|
||||||
*/
|
*/
|
||||||
SWITCH_DECLARE(unsigned int) switch_separate_string(char *buf, char delim, char **array, unsigned int arraylen);
|
SWITCH_DECLARE(unsigned int) switch_separate_string(char *buf, char delim, char **array, unsigned int arraylen);
|
||||||
|
SWITCH_DECLARE(unsigned int) switch_separate_string_string(char *buf, char *delim, char **array, unsigned int arraylen);
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_bool_t) switch_is_number(const char *str);
|
SWITCH_DECLARE(switch_bool_t) switch_is_number(const char *str);
|
||||||
SWITCH_DECLARE(char *) switch_strip_spaces(const char *str);
|
SWITCH_DECLARE(char *) switch_strip_spaces(const char *str);
|
||||||
|
|
|
@ -1134,6 +1134,180 @@ static switch_status_t setup_ringback(originate_global_t *oglobals,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define OSEP ":_:"
|
||||||
|
#define MAX_PEERS 128
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
switch_core_session_t *session;
|
||||||
|
switch_core_session_t *bleg;
|
||||||
|
switch_call_cause_t cause;
|
||||||
|
const char *bridgeto;
|
||||||
|
uint32_t timelimit_sec;
|
||||||
|
const switch_state_handler_table_t *table;
|
||||||
|
const char *cid_name_override;
|
||||||
|
const char *cid_num_override;
|
||||||
|
switch_caller_profile_t *caller_profile_override;
|
||||||
|
switch_event_t *ovars;
|
||||||
|
switch_originate_flag_t flags;
|
||||||
|
switch_status_t status;
|
||||||
|
int done;
|
||||||
|
switch_thread_t *thread;
|
||||||
|
} enterprise_originate_handle_t;
|
||||||
|
|
||||||
|
|
||||||
|
static void *SWITCH_THREAD_FUNC enterprise_originate_thread(switch_thread_t *thread, void *obj)
|
||||||
|
{
|
||||||
|
enterprise_originate_handle_t *handle = (enterprise_originate_handle_t *) obj;
|
||||||
|
|
||||||
|
handle->done = 0;
|
||||||
|
handle->status = switch_ivr_originate(NULL, &handle->bleg, &handle->cause,
|
||||||
|
handle->bridgeto, handle->timelimit_sec,
|
||||||
|
handle->table,
|
||||||
|
handle->cid_name_override,
|
||||||
|
handle->cid_num_override,
|
||||||
|
handle->caller_profile_override,
|
||||||
|
handle->ovars,
|
||||||
|
handle->flags
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
handle->done = 1;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SWITCH_DECLARE(switch_status_t) switch_ivr_enterprise_originate(switch_core_session_t *session,
|
||||||
|
switch_core_session_t **bleg,
|
||||||
|
switch_call_cause_t *cause,
|
||||||
|
const char *bridgeto,
|
||||||
|
uint32_t timelimit_sec,
|
||||||
|
const switch_state_handler_table_t *table,
|
||||||
|
const char *cid_name_override,
|
||||||
|
const char *cid_num_override,
|
||||||
|
switch_caller_profile_t *caller_profile_override,
|
||||||
|
switch_event_t *ovars,
|
||||||
|
switch_originate_flag_t flags
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int x_argc;
|
||||||
|
char *x_argv[MAX_PEERS] = { 0 };
|
||||||
|
enterprise_originate_handle_t *hp = NULL, handles[MAX_PEERS] = { { 0 } };
|
||||||
|
int i;
|
||||||
|
switch_caller_profile_t *cp = NULL;
|
||||||
|
switch_channel_t *channel = NULL;
|
||||||
|
char *data;
|
||||||
|
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||||
|
switch_threadattr_t *thd_attr = NULL;
|
||||||
|
int running = 0;
|
||||||
|
switch_status_t tstatus = SWITCH_STATUS_FALSE;
|
||||||
|
switch_memory_pool_t *pool;
|
||||||
|
switch_event_header_t *hi = NULL;
|
||||||
|
|
||||||
|
switch_core_new_memory_pool(&pool);
|
||||||
|
|
||||||
|
if (zstr(bridgeto)) {
|
||||||
|
*cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
||||||
|
switch_goto_status(SWITCH_STATUS_FALSE, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
data = switch_core_strdup(pool, bridgeto);
|
||||||
|
|
||||||
|
if (!(x_argc = switch_separate_string_string(data, OSEP, x_argv, MAX_PEERS))) {
|
||||||
|
*cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
||||||
|
switch_goto_status(SWITCH_STATUS_FALSE, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session) {
|
||||||
|
channel = switch_core_session_get_channel(session);
|
||||||
|
cp = switch_channel_get_caller_profile(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_threadattr_create(&thd_attr, pool);
|
||||||
|
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
|
||||||
|
|
||||||
|
for(i = 0; i < x_argc; i++) {
|
||||||
|
handles[i].session = session;
|
||||||
|
handles[i].bleg = NULL;
|
||||||
|
handles[i].cause = 0;
|
||||||
|
handles[i].bridgeto = x_argv[i];
|
||||||
|
handles[i].timelimit_sec = timelimit_sec;
|
||||||
|
handles[i].table = table;
|
||||||
|
handles[i].cid_name_override = cid_name_override;
|
||||||
|
handles[i].cid_num_override = cid_num_override;
|
||||||
|
handles[i].caller_profile_override = cp;
|
||||||
|
|
||||||
|
if (channel) {
|
||||||
|
switch_channel_get_variables(channel, &handles[i].ovars);
|
||||||
|
} else {
|
||||||
|
switch_event_create_plain(&handles[i].ovars, SWITCH_EVENT_CHANNEL_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ovars) {
|
||||||
|
for (hi = ovars->headers; hi; hi = hi->next) {
|
||||||
|
switch_event_add_header_string(handles[i].ovars, SWITCH_STACK_BOTTOM, hi->name, hi->value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handles[i].flags = flags;
|
||||||
|
switch_thread_create(&handles[i].thread, thd_attr, enterprise_originate_thread, &handles[i], pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
running = 0;
|
||||||
|
|
||||||
|
for(i = 0; i < x_argc; i++) {
|
||||||
|
if (handles[i].done == 0) {
|
||||||
|
running++;
|
||||||
|
} else if (handles[i].done == 1) {
|
||||||
|
if (handles[i].status == SWITCH_STATUS_SUCCESS) {
|
||||||
|
hp = &handles[i];
|
||||||
|
goto done;
|
||||||
|
} else {
|
||||||
|
handles[i].done = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch_cond_next();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!running) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
|
||||||
|
for(i = 0; i < x_argc; i++) {
|
||||||
|
if (hp && hp == &handles[i]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (handles[i].bleg) {
|
||||||
|
switch_channel_hangup(switch_core_session_get_channel(handles[i].bleg), SWITCH_CAUSE_LOSE_RACE);
|
||||||
|
switch_core_session_rwunlock(handles[i].bleg);
|
||||||
|
}
|
||||||
|
|
||||||
|
handles[i].cause = SWITCH_CAUSE_LOSE_RACE;
|
||||||
|
switch_thread_join(&tstatus, handles[i].thread);
|
||||||
|
switch_event_destroy(&handles[i].ovars);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (hp) {
|
||||||
|
*cause = hp->cause;
|
||||||
|
status = hp->status;
|
||||||
|
*bleg = hp->bleg;
|
||||||
|
switch_thread_join(&tstatus, hp->thread);
|
||||||
|
switch_event_destroy(&hp->ovars);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end:
|
||||||
|
|
||||||
|
switch_core_destroy_memory_pool(&pool);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#define peer_eligible(_peer) (_peer && !(switch_channel_test_flag(_peer, CF_TRANSFER) || \
|
#define peer_eligible(_peer) (_peer && !(switch_channel_test_flag(_peer, CF_TRANSFER) || \
|
||||||
switch_channel_test_flag(_peer, CF_REDIRECT) || \
|
switch_channel_test_flag(_peer, CF_REDIRECT) || \
|
||||||
|
@ -1141,7 +1315,7 @@ static switch_status_t setup_ringback(originate_global_t *oglobals,
|
||||||
switch_channel_get_state(_peer) == CS_RESET || \
|
switch_channel_get_state(_peer) == CS_RESET || \
|
||||||
!switch_channel_test_flag(_peer, CF_ORIGINATING)))
|
!switch_channel_test_flag(_peer, CF_ORIGINATING)))
|
||||||
|
|
||||||
#define MAX_PEERS 128
|
|
||||||
SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *session,
|
SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *session,
|
||||||
switch_core_session_t **bleg,
|
switch_core_session_t **bleg,
|
||||||
switch_call_cause_t *cause,
|
switch_call_cause_t *cause,
|
||||||
|
@ -1195,6 +1369,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
|
||||||
const char *holding = NULL;
|
const char *holding = NULL;
|
||||||
const char *export_vars = NULL;
|
const char *export_vars = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
if (strstr(bridgeto, OSEP)) {
|
||||||
|
return switch_ivr_enterprise_originate(session, bleg, cause, bridgeto, timelimit_sec, table, cid_name_override, cid_num_override,
|
||||||
|
caller_profile_override, ovars, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
oglobals.ringback_ok = 1;
|
oglobals.ringback_ok = 1;
|
||||||
|
|
||||||
if (session) {
|
if (session) {
|
||||||
|
@ -1240,8 +1421,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
|
||||||
oglobals.idx = IDX_NADA;
|
oglobals.idx = IDX_NADA;
|
||||||
oglobals.early_ok = 1;
|
oglobals.early_ok = 1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
*bleg = NULL;
|
*bleg = NULL;
|
||||||
|
|
||||||
switch_zmalloc(write_frame.data, SWITCH_RECOMMENDED_BUFFER_SIZE);
|
switch_zmalloc(write_frame.data, SWITCH_RECOMMENDED_BUFFER_SIZE);
|
||||||
|
@ -2088,7 +2267,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
|
||||||
oglobals.ringback_ok = 0;
|
oglobals.ringback_ok = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((!caller_channel || switch_channel_ready(caller_channel) || switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) &&
|
*cause = 0;
|
||||||
|
while (*cause == 0 && ((!caller_channel || switch_channel_ready(caller_channel) || switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE))) &&
|
||||||
check_channel_status(&oglobals, originate_status, and_argc)) {
|
check_channel_status(&oglobals, originate_status, and_argc)) {
|
||||||
time_t elapsed = switch_epoch_time_now(NULL) - start;
|
time_t elapsed = switch_epoch_time_now(NULL) - start;
|
||||||
|
|
||||||
|
@ -2252,6 +2432,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*cause) {
|
||||||
|
force_reason = *cause;
|
||||||
|
}
|
||||||
|
|
||||||
notready:
|
notready:
|
||||||
|
|
||||||
if (caller_channel) {
|
if (caller_channel) {
|
||||||
|
|
|
@ -1589,6 +1589,25 @@ static char *cleanup_separated_string(char *str, char delim)
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SWITCH_DECLARE(unsigned int) switch_separate_string_string(char *buf, char *delim, char **array, unsigned int arraylen)
|
||||||
|
{
|
||||||
|
unsigned int count = 0;
|
||||||
|
char *d;
|
||||||
|
size_t dlen = strlen(delim);
|
||||||
|
|
||||||
|
array[count++] = buf;
|
||||||
|
|
||||||
|
while (count < arraylen && array[count-1]) {
|
||||||
|
if ((d = strstr(array[count-1], delim))) {
|
||||||
|
*d = '\0';
|
||||||
|
d += dlen;
|
||||||
|
array[count++] = d;
|
||||||
|
} else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
/* Separate a string using a delimiter that is not a space */
|
/* Separate a string using a delimiter that is not a space */
|
||||||
static unsigned int separate_string_char_delim(char *buf, char delim, char **array, unsigned int arraylen)
|
static unsigned int separate_string_char_delim(char *buf, char delim, char **array, unsigned int arraylen)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue