mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-27 20:59:50 +00:00
add parameter parsing to dial string (leading name=val pairs sep by , inside {} such as {foo=bar} )
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@3905 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
73609f0478
commit
01541265ec
116
src/switch_ivr.c
116
src/switch_ivr.c
@ -2221,7 +2221,7 @@ static uint8_t check_channel_status(switch_channel_t **peer_channels,
|
|||||||
int32_t *idx,
|
int32_t *idx,
|
||||||
char *file,
|
char *file,
|
||||||
char *key,
|
char *key,
|
||||||
char *ringback_data)
|
uint8_t early_ok)
|
||||||
{
|
{
|
||||||
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
@ -2235,7 +2235,7 @@ static uint8_t check_channel_status(switch_channel_t **peer_channels,
|
|||||||
if (switch_channel_get_state(peer_channels[i]) >= CS_HANGUP) {
|
if (switch_channel_get_state(peer_channels[i]) >= CS_HANGUP) {
|
||||||
hups++;
|
hups++;
|
||||||
} else if ((switch_channel_test_flag(peer_channels[i], CF_ANSWERED) ||
|
} else if ((switch_channel_test_flag(peer_channels[i], CF_ANSWERED) ||
|
||||||
(!ringback_data && len == 1 && switch_channel_test_flag(peer_channels[i], CF_EARLY_MEDIA))) &&
|
(early_ok && len == 1 && switch_channel_test_flag(peer_channels[i], CF_EARLY_MEDIA))) &&
|
||||||
!switch_channel_test_flag(peer_channels[i], CF_TAGGED)) {
|
!switch_channel_test_flag(peer_channels[i], CF_TAGGED)) {
|
||||||
|
|
||||||
if (key) {
|
if (key) {
|
||||||
@ -2325,14 +2325,15 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
|
|||||||
int32_t idx = IDX_NADA;
|
int32_t idx = IDX_NADA;
|
||||||
switch_codec_t write_codec = {0};
|
switch_codec_t write_codec = {0};
|
||||||
switch_frame_t write_frame = {0};
|
switch_frame_t write_frame = {0};
|
||||||
uint8_t err = 0, fdata[1024], pass = 0;
|
uint8_t fdata[1024], pass = 0;
|
||||||
char *file = NULL, *key = NULL, *odata, *var;
|
char *file = NULL, *key = NULL, *odata, *var;
|
||||||
switch_call_cause_t reason = SWITCH_CAUSE_UNALLOCATED;
|
switch_call_cause_t reason = SWITCH_CAUSE_UNALLOCATED;
|
||||||
uint8_t to = 0;
|
uint8_t to = 0;
|
||||||
char *ringback_data = NULL;
|
char *var_val, *vars = NULL, *ringback_data = NULL;
|
||||||
switch_codec_t *read_codec = NULL;
|
switch_codec_t *read_codec = NULL;
|
||||||
uint8_t sent_ring = 0;
|
uint8_t sent_ring = 0, early_ok = 1;
|
||||||
switch_core_session_message_t *message = NULL;
|
switch_core_session_message_t *message = NULL;
|
||||||
|
switch_event_t *var_event = NULL;
|
||||||
|
|
||||||
write_frame.data = fdata;
|
write_frame.data = fdata;
|
||||||
|
|
||||||
@ -2340,47 +2341,86 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
|
|||||||
odata = strdup(bridgeto);
|
odata = strdup(bridgeto);
|
||||||
data = odata;
|
data = odata;
|
||||||
|
|
||||||
if (!strncasecmp(data, "confirm=", 8)) {
|
if (*data == '{') {
|
||||||
data += 8;
|
vars = data + 1;
|
||||||
file = data;
|
if (!(data = strchr(data, '}'))) {
|
||||||
if ((data = strchr(file, ';'))) {
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error!\n");
|
||||||
*data++ = '\0';
|
status = SWITCH_STATUS_GENERR;
|
||||||
if ((key = strchr(file, ':'))) {
|
goto done;
|
||||||
*key++ = '\0';
|
}
|
||||||
} else {
|
*data++ = '\0';
|
||||||
err++;
|
}
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err) {
|
|
||||||
status = SWITCH_STATUS_GENERR;
|
/* Some channel are created from an originating channel and some aren't so not all outgoing calls have a way to get params
|
||||||
goto done;
|
so we will normalize dialstring params and channel variables (when there is an originator) into an event that we
|
||||||
}
|
will use as a pseudo hash to consult for params as needed.
|
||||||
|
*/
|
||||||
|
if (switch_event_create(&var_event, SWITCH_EVENT_MESSAGE) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
|
||||||
|
status = SWITCH_STATUS_MEMERR;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
if (session) {
|
if (session) {
|
||||||
caller_channel = switch_core_session_get_channel(session);
|
switch_hash_index_t *hi;
|
||||||
|
void *vval;
|
||||||
|
const void *vvar;
|
||||||
|
|
||||||
|
caller_channel = switch_core_session_get_channel(session);
|
||||||
assert(caller_channel != NULL);
|
assert(caller_channel != NULL);
|
||||||
|
|
||||||
|
/* Copy all the channel variables into the event */
|
||||||
|
for (hi = switch_channel_variable_first(caller_channel, switch_core_session_get_pool(session)); hi; hi = switch_hash_next(hi)) {
|
||||||
|
switch_hash_this(hi, &vvar, NULL, &vval);
|
||||||
|
if (vvar && vval) {
|
||||||
|
switch_event_add_header(var_event, SWITCH_STACK_BOTTOM, vvar, vval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vars) { /* Parse parameters specified from the dialstring */
|
||||||
|
char *var_array[1024] = {0};
|
||||||
|
int var_count = 0;
|
||||||
|
if ((var_count = switch_separate_string(vars, ',', var_array, (sizeof(var_array) / sizeof(var_array[0]))))) {
|
||||||
|
int x = 0;
|
||||||
|
for (x = 0; x < var_count; x++) {
|
||||||
|
char *inner_var_array[2];
|
||||||
|
int inner_var_count;
|
||||||
|
if ((inner_var_count =
|
||||||
|
switch_separate_string(var_array[x], '=', inner_var_array, (sizeof(inner_var_array) / sizeof(inner_var_array[0])))) == 2) {
|
||||||
|
|
||||||
|
switch_event_add_header(var_event, SWITCH_STACK_BOTTOM, inner_var_array[0], inner_var_array[1]);
|
||||||
|
if (caller_channel) {
|
||||||
|
switch_channel_set_variable(caller_channel, inner_var_array[0], inner_var_array[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (caller_channel) { /* ringback is only useful when there is an originator */
|
||||||
ringback_data = switch_channel_get_variable(caller_channel, "ringback");
|
ringback_data = switch_channel_get_variable(caller_channel, "ringback");
|
||||||
switch_channel_set_variable(caller_channel, "originate_disposition", "failure");
|
switch_channel_set_variable(caller_channel, "originate_disposition", "failure");
|
||||||
|
|
||||||
if ((var = switch_channel_get_variable(caller_channel, "group_confirm_key"))) {
|
|
||||||
key = switch_core_session_strdup(session, var);
|
|
||||||
if ((var = switch_channel_get_variable(caller_channel, "group_confirm_file"))) {
|
|
||||||
file = switch_core_session_strdup(session, var);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((var = switch_event_get_header(var_event, "group_confirm_key"))) {
|
||||||
|
key = switch_core_session_strdup(session, var);
|
||||||
|
if ((var = switch_event_get_header(var_event, "group_confirm_file"))) {
|
||||||
|
file = switch_core_session_strdup(session, var);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (file && !strcmp(file, "undef")) {
|
if (file && !strcmp(file, "undef")) {
|
||||||
file = NULL;
|
file = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((var_val = switch_event_get_header(var_event, "noanswer_early_media")) && switch_true(var_val)) {
|
||||||
|
early_ok = 0;
|
||||||
|
}
|
||||||
|
|
||||||
or_argc = switch_separate_string(data, '|', pipe_names, (sizeof(pipe_names) / sizeof(pipe_names[0])));
|
or_argc = switch_separate_string(data, '|', pipe_names, (sizeof(pipe_names) / sizeof(pipe_names[0])));
|
||||||
|
|
||||||
if (caller_channel && or_argc > 1 && !ringback_data) {
|
if (caller_channel && or_argc > 1 && !ringback_data) {
|
||||||
@ -2653,8 +2693,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((!caller_channel || switch_channel_ready(caller_channel)) &&
|
if (ringback_data) {
|
||||||
check_channel_status(peer_channels, peer_sessions, and_argc, &idx, file, key, ringback_data)) {
|
early_ok = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((!caller_channel || switch_channel_ready(caller_channel)) &&
|
||||||
|
check_channel_status(peer_channels, peer_sessions, and_argc, &idx, file, key, early_ok)) {
|
||||||
|
|
||||||
if ((to = (uint8_t)((time(NULL) - start) >= (time_t)timelimit_sec))) {
|
if ((to = (uint8_t)((time(NULL) - start) >= (time_t)timelimit_sec))) {
|
||||||
idx = IDX_CANCEL;
|
idx = IDX_CANCEL;
|
||||||
@ -2804,6 +2848,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
|
|||||||
done:
|
done:
|
||||||
*cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
*cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
||||||
|
|
||||||
|
if (var_event) {
|
||||||
|
switch_event_destroy(&var_event);
|
||||||
|
}
|
||||||
|
|
||||||
if (status == SWITCH_STATUS_SUCCESS) {
|
if (status == SWITCH_STATUS_SUCCESS) {
|
||||||
if (caller_channel) {
|
if (caller_channel) {
|
||||||
switch_channel_set_variable(caller_channel, "originate_disposition", "call accepted");
|
switch_channel_set_variable(caller_channel, "originate_disposition", "call accepted");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user