monitor_media function

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@11295 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2009-01-19 23:15:59 +00:00
parent fcc6043bc1
commit 697bb6ec6e
1 changed files with 165 additions and 14 deletions

View File

@ -97,6 +97,8 @@ typedef struct {
uint8_t sent_ring;
uint8_t progress;
uint8_t return_ring_ready;
uint8_t monitor_early_media_ring;
uint8_t monitor_early_media_fail;
} originate_global_t;
@ -239,6 +241,25 @@ static int check_per_channel_timeouts(originate_status_t *originate_status,
return x;
}
static switch_bool_t monitor_callback(switch_core_session_t *session, const char *app, const char *data)
{
if (app) {
switch_channel_t *channel = switch_core_session_get_channel(session);
if (!strcmp(app, "fail")) {
switch_channel_hangup(channel, data ? switch_channel_str2cause(data) : SWITCH_CAUSE_USER_BUSY);
} else if (!strcmp(app, "ring")) {
originate_global_t *oglobals = (originate_global_t *) switch_channel_get_private(channel, "_oglobals_");
if (oglobals) {
switch_channel_set_private(channel, "_oglobals_", NULL);
oglobals->early_ok = 1;
}
}
}
return SWITCH_FALSE;
}
static uint8_t check_channel_status(originate_global_t *oglobals, originate_status_t *originate_status, uint32_t len)
{
@ -276,8 +297,118 @@ static uint8_t check_channel_status(originate_global_t *oglobals, originate_stat
if (oglobals->early_ok) {
pindex = i;
}
if (oglobals->monitor_early_media_fail) {
const char *var = switch_channel_get_variable(originate_status[i].peer_channel, "monitor_early_media_fail");
if (!switch_strlen_zero(var)) {
char *fail_array[128] = {0};
int fail_count = 0;
char *fail_data = strdup(var);
int fx;
switch_assert(fail_data);
fail_count = switch_separate_string(fail_data, '!', fail_array, (sizeof(fail_array) / sizeof(fail_array[0])));
for(fx = 0; fx < fail_count; fx++) {
char *cause = fail_array[fx];
int hits = 2;
char *p, *q;
if (!(p = strchr(cause, ':'))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error\n");
continue;
}
*p++ = '\0';
if (!p) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error\n");
continue;
}
if (!(hits = atoi(p))) {
hits = 2;
}
if (!(p = strchr(p, ':'))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error\n");
continue;
}
*p++ = '\0';
if (!p) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error\n");
continue;
}
for(q = p; q && *q; q++) {
if (*q == '+') {
*q = ',';
}
}
switch_ivr_tone_detect_session(originate_status[i].peer_session,
"monitor_early_media_fail",
p, "r", 0, hits, "fail", cause, monitor_callback);
}
switch_safe_free(fail_data);
}
}
if (oglobals->monitor_early_media_ring) {
const char *var = switch_channel_get_variable(originate_status[i].peer_channel, "monitor_early_media_ring");
if (!switch_strlen_zero(var)) {
char *ring_array[128] = {0};
int ring_count = 0;
char *ring_data = strdup(var);
int fx;
switch_assert(ring_data);
ring_count = switch_separate_string(ring_data, '!', ring_array, (sizeof(ring_array) / sizeof(ring_array[0])));
for(fx = 0; fx < ring_count; fx++) {
int hits = 2;
char *p = ring_array[fx], *q;
if (!(hits = atoi(p))) {
hits = 2;
}
if (!(p = strchr(p, ':'))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error\n");
continue;
}
*p++ = '\0';
if (!p) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error\n");
continue;
}
for(q = p; q && *q; q++) {
if (*q == '+') {
*q = ',';
}
}
switch_channel_set_private(originate_status[i].peer_channel, "_oglobals_", oglobals);
switch_ivr_tone_detect_session(originate_status[i].peer_session,
"monitor_early_media_ring",
p, "r", 0, hits, "ring", NULL, monitor_callback);
}
switch_safe_free(ring_data);
}
}
}
if (!oglobals->progress) {
oglobals->progress = 1;
}
@ -619,7 +750,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_wait_for_answer(switch_core_session_t
}
}
done:
done:
if (ringback.fh) {
switch_core_file_close(ringback.fh);
@ -796,7 +927,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
/* Some channel are created from an originating channel and some aren't so not all outgoing calls have a way to get params
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 (ovars) {
var_event = ovars;
@ -824,6 +955,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
ok = 1;
} else if (!strcasecmp((char *) hi->name, "ignore_early_media")) {
ok = 1;
} else if (!strcasecmp((char *) hi->name, "monitor_early_media_ring")) {
ok = 1;
} else if (!strcasecmp((char *) hi->name, "monitor_early_media_fail")) {
ok = 1;
} else if (!strcasecmp((char *) hi->name, "return_ring_ready")) {
ok = 1;
} else if (!strcasecmp((char *) hi->name, "ring_ready")) {
@ -849,16 +984,16 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
switch_channel_variable_last(caller_channel);
}
/*
if ((hi = switch_channel_variable_first(caller_channel))) {
for (; hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, &vvar, NULL, &vval);
if (vvar && vval) {
switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, (void *) vvar, (char *) vval);
}
}
switch_channel_variable_last(caller_channel);
}
*/
if ((hi = switch_channel_variable_first(caller_channel))) {
for (; hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, &vvar, NULL, &vval);
if (vvar && vval) {
switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, (void *) vvar, (char *) vval);
}
}
switch_channel_variable_last(caller_channel);
}
*/
}
if (vars) { /* Parse parameters specified from the dialstring */
@ -936,6 +1071,16 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
oglobals.early_ok = 0;
}
if ((var_val = switch_event_get_header(var_event, "monitor_early_media_ring"))) {
oglobals.early_ok = 0;
oglobals.monitor_early_media_ring = 1;
}
if ((var_val = switch_event_get_header(var_event, "monitor_early_media_fail"))) {
oglobals.early_ok = 0;
oglobals.monitor_early_media_fail = 1;
}
if ((var_val = switch_event_get_header(var_event, "return_ring_ready")) && switch_true(var_val)) {
oglobals.return_ring_ready = 1;
}
@ -1359,7 +1504,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
}
endfor1:
endfor1:
if (caller_channel) {
if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE) || switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA)) {
@ -1698,6 +1843,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
(oglobals.return_ring_ready && switch_channel_test_flag(peer_channel, CF_RING_READY))
) {
*bleg = peer_session;
if (oglobals.monitor_early_media_ring || oglobals.monitor_early_media_fail) {
switch_ivr_stop_tone_detect_session(peer_session);
switch_channel_set_private(peer_channel, "_oglobals_", NULL);
}
status = SWITCH_STATUS_SUCCESS;
} else {
status = SWITCH_STATUS_FALSE;