From 76177e619639ca48ffe8c98b4170dded8c1c080c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 20 Jun 2013 22:53:20 -0500 Subject: [PATCH 1/4] FS-5531 --resolve add another optional param to supply flags for either behaviour n for null and b for boolean --- .../applications/mod_commands/mod_commands.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 9e08234483..e6c7c990dd 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -1793,7 +1793,7 @@ SWITCH_STANDARD_API(regex_function) switch_regex_t *re = NULL; int ovector[30]; int argc; - char *mydata = NULL, *argv[3]; + char *mydata = NULL, *argv[4]; size_t len = 0; char *substituted = NULL; int proceed = 0; @@ -1834,6 +1834,12 @@ SWITCH_STANDARD_API(regex_function) proceed = switch_regex_perform(argv[0], argv[1], &re, ovector, sizeof(ovector) / sizeof(ovector[0])); if (argc > 2) { + char *flags = ""; + + if (argc > 3) { + flags = argv[3]; + } + if (proceed) { len = (strlen(argv[0]) + strlen(argv[2]) + 10) * proceed; substituted = malloc(len); @@ -1845,7 +1851,13 @@ SWITCH_STANDARD_API(regex_function) stream->write_function(stream, "%s", substituted); free(substituted); } else { - stream->write_function(stream, "%s", argv[0]); + if (strchr(flags, 'n')) { + stream->write_function(stream, "%s", ""); + } else if (strchr(flags, 'b')) { + stream->write_function(stream, "%s", "false"); + } else { + stream->write_function(stream, "%s", argv[0]); + } } } else { stream->write_function(stream, proceed ? "true" : "false"); @@ -6016,7 +6028,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) SWITCH_ADD_API(commands_api_interface, "originate", "Originate a call", originate_function, ORIGINATE_SYNTAX); SWITCH_ADD_API(commands_api_interface, "pause", "Pause media on a channel", pause_function, PAUSE_SYNTAX); SWITCH_ADD_API(commands_api_interface, "quote_shell_arg", "Quote/escape a string for use on shell command line", quote_shell_arg_function, ""); - SWITCH_ADD_API(commands_api_interface, "regex", "Evaluate a regex", regex_function, "|[|]"); + SWITCH_ADD_API(commands_api_interface, "regex", "Evaluate a regex", regex_function, "|[|][n|b]"); SWITCH_ADD_API(commands_api_interface, "reloadacl", "Reload XML", reload_acl_function, ""); SWITCH_ADD_API(commands_api_interface, "reload", "Reload module", reload_function, UNLOAD_SYNTAX); SWITCH_ADD_API(commands_api_interface, "reloadxml", "Reload XML", reload_xml_function, ""); From 5a0f43d95637e97c278c6a0e35c6bdbd3778870c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 21 Jun 2013 00:41:25 -0500 Subject: [PATCH 2/4] make sure sip-hold works on webrtc --- src/switch_core_media.c | 58 ++++++++++++++++++++++++++++++++++++++++- src/switch_rtp.c | 5 ++-- 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 531038c68d..ce70d4e0c4 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -1934,7 +1934,7 @@ static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_ sdp_attribute_t *attr; int i = 0, got_rtcp_mux = 0; - if (engine->ice_in.chosen[0] && engine->ice_in.chosen[1]) { + if (engine->ice_in.chosen[0] && engine->ice_in.chosen[1] && !switch_channel_test_flag(smh->session->channel, CF_REINVITE)) { return; } @@ -2175,6 +2175,62 @@ static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_ engine->rtcp_mux = -1; } + + + if (switch_channel_test_flag(smh->session->channel, CF_REINVITE)) { + if (switch_rtp_ready(engine->rtp_session) && engine->ice_in.cands[engine->ice_in.chosen[0]][0].ready) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_INFO, "RE-Activating %s ICE\n", type2str(type)); + + switch_rtp_activate_ice(engine->rtp_session, + engine->ice_in.ufrag, + engine->ice_out.ufrag, + engine->ice_out.pwd, + engine->ice_in.pwd, + IPR_RTP, +#ifdef GOOGLE_ICE + ICE_GOOGLE_JINGLE, + NULL +#else + switch_channel_direction(smh->session->channel) == + SWITCH_CALL_DIRECTION_OUTBOUND ? ICE_VANILLA : (ICE_VANILLA | ICE_CONTROLLED), + &engine->ice_in +#endif + ); + + + + } + + + + if (engine->ice_in.cands[engine->ice_in.chosen[1]][1].ready) { + if (!strcmp(engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_addr, engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr) + && engine->ice_in.cands[engine->ice_in.chosen[1]][1].con_port == engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_INFO, "Skipping %s RTCP ICE (Same as RTP)\n", type2str(type)); + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_INFO, "Activating %s RTCP ICE\n", type2str(type)); + + switch_rtp_activate_ice(engine->rtp_session, + engine->ice_in.ufrag, + engine->ice_out.ufrag, + engine->ice_out.pwd, + engine->ice_in.pwd, + IPR_RTCP, +#ifdef GOOGLE_ICE + ICE_GOOGLE_JINGLE, + NULL +#else + switch_channel_direction(smh->session->channel) == + SWITCH_CALL_DIRECTION_OUTBOUND ? ICE_VANILLA : (ICE_VANILLA | ICE_CONTROLLED), + &engine->ice_in +#endif + ); + } + + } + + } + } #ifdef _MSC_VER #pragma warning(pop) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 9096e7e88c..cb3d3b4695 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -876,7 +876,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d if (!zstr(username)) { if (!strcmp(username, ice->user_ice)) { ok = 1; - } else if(!strcmp(username, rtp_session->rtcp_ice.user_ice)) { + } else if(!zstr(rtp_session->rtcp_ice.user_ice) && !strcmp(username, rtp_session->rtcp_ice.user_ice)) { ice = &rtp_session->rtcp_ice; ok = 1; } @@ -891,7 +891,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d char *host = NULL; ice->missed_count++; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_CRIT, "missed %d\n", ice->missed_count); + //switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_CRIT, "missed %d\n", ice->missed_count); if (elapsed > 20000 && pri) { int i, j; @@ -971,6 +971,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d if (ice->missed_count > 5) { ice->rready = 0; + ok = 1; } if (ok) { From eb79128d8e9d7a370f027f2e392f91c0b7e51926 Mon Sep 17 00:00:00 2001 From: Giovanni Maruzzelli Date: Fri, 21 Jun 2013 10:57:59 +0200 Subject: [PATCH 3/4] skypopen: OSS driver has active timers only on active devices (eg: when it's actually used by a skypeclient) --- src/mod/endpoints/mod_skypopen/oss/main.c | 39 +++++++++++++++++-- src/mod/endpoints/mod_skypopen/oss/skypopen.h | 1 + 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/mod/endpoints/mod_skypopen/oss/main.c b/src/mod/endpoints/mod_skypopen/oss/main.c index 897978a2b7..bfa228d9b7 100644 --- a/src/mod/endpoints/mod_skypopen/oss/main.c +++ b/src/mod/endpoints/mod_skypopen/oss/main.c @@ -203,6 +203,9 @@ static int skypopen_c_open(struct inode *inode, struct file *filp) /* look for a skypopenc device in the list */ spin_lock(&skypopen_c_lock); dev = skypopen_c_lookfor_device(key); + if (dev){ + dev->opened++; + } spin_unlock(&skypopen_c_lock); if (!dev) @@ -215,10 +218,30 @@ static int skypopen_c_open(struct inode *inode, struct file *filp) static int skypopen_c_release(struct inode *inode, struct file *filp) { - /* - * Nothing to do, because the device is persistent. - * A `real' cloned device should be freed on last close - */ + dev_t key; + struct skypopen_dev *dev = filp->private_data; + int ret; + + key = current->tgid; + + spin_lock(&skypopen_c_lock); + dev->opened--; + spin_unlock(&skypopen_c_lock); + + if(!dev->opened){ +#ifdef WANT_HRTIMER + if(dev->timer_inq_started){ + ret = hrtimer_cancel( &dev->timer_inq ); + //printk( "Stopped skypopen OSS driver read HRtimer skype client:(%d) ret=%d\n", key, ret); + dev->timer_inq_started=0; + } + if(dev->timer_outq_started){ + ret = hrtimer_cancel( &dev->timer_outq ); + //printk( "Stopped skypopen OSS driver write HRtimer skype client:(%d) ret=%d\n", key, ret); + dev->timer_outq_started=0; + } +#endif// WANT_HRTIMER + } return 0; } @@ -231,6 +254,9 @@ static ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count, { DEFINE_WAIT(wait); struct skypopen_dev *dev = filp->private_data; + dev_t key; + + key = current->tgid; if(unload) return -1; @@ -244,6 +270,7 @@ static ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count, dev->timer_inq.function = &my_hrtimer_callback_inq; hrtimer_start( &dev->timer_inq, ktime_inq, HRTIMER_MODE_REL ); dev->timer_inq_started = 1; + //printk( "Started skypopen OSS driver read HRtimer skype client:(%d) \n", key); } #endif// WANT_HRTIMER @@ -259,6 +286,9 @@ static ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t { DEFINE_WAIT(wait); struct skypopen_dev *dev = filp->private_data; + dev_t key; + + key = current->tgid; if(unload) return -1; @@ -272,6 +302,7 @@ static ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t dev->timer_outq.function = &my_hrtimer_callback_outq; hrtimer_start( &dev->timer_outq, ktime_outq, HRTIMER_MODE_REL ); dev->timer_outq_started = 1; + //printk( "Started skypopen OSS driver write HRtimer skype client:(%d) \n", key); } #endif// WANT_HRTIMER diff --git a/src/mod/endpoints/mod_skypopen/oss/skypopen.h b/src/mod/endpoints/mod_skypopen/oss/skypopen.h index 29e32feeca..2b0527eeb9 100644 --- a/src/mod/endpoints/mod_skypopen/oss/skypopen.h +++ b/src/mod/endpoints/mod_skypopen/oss/skypopen.h @@ -66,6 +66,7 @@ struct skypopen_dev { #endif// WANT_HRTIMER int timer_inq_started; int timer_outq_started; + int opened; }; From 609b0b324d905c5b73ef61030d0198f341943111 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Fri, 21 Jun 2013 09:42:54 -0400 Subject: [PATCH 4/4] mod_rayo: fix crash when DTMF is received after input timeout --- .../event_handlers/mod_rayo/rayo_input_component.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/mod/event_handlers/mod_rayo/rayo_input_component.c b/src/mod/event_handlers/mod_rayo/rayo_input_component.c index 4bebb35e8c..acf2ce4a2f 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_input_component.c +++ b/src/mod/event_handlers/mod_rayo/rayo_input_component.c @@ -208,7 +208,14 @@ static switch_status_t input_component_on_dtmf(switch_core_session_t *session, c enum srgs_match_type match; switch_mutex_lock(handler->mutex); + component = handler->component; + /* additional paranoia check */ + if (!component) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Received DTMF without active input component\n"); + switch_mutex_unlock(handler->mutex); + return SWITCH_STATUS_SUCCESS; + } is_term_digit = digit_mask_test(component->term_digit_mask, dtmf->digit); @@ -280,6 +287,7 @@ static switch_bool_t input_component_bug_callback(switch_media_bug_t *bug, void switch(type) { case SWITCH_ABC_TYPE_INIT: { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Adding DTMF callback\n"); switch_core_event_hook_add_recv_dtmf(session, input_component_on_dtmf); break; } @@ -291,6 +299,7 @@ static switch_bool_t input_component_bug_callback(switch_media_bug_t *bug, void if (component->num_digits && component->inter_digit_timeout > 0 && elapsed_ms > component->inter_digit_timeout) { enum srgs_match_type match; handler->component = NULL; + switch_core_media_bug_set_flag(bug, SMBF_PRUNE); /* we got some input, check for match */ match = srgs_grammar_match(component->grammar, component->digits); @@ -306,6 +315,7 @@ static switch_bool_t input_component_bug_callback(switch_media_bug_t *bug, void } } else if (!component->num_digits && component->initial_timeout > 0 && elapsed_ms > component->initial_timeout) { handler->component = NULL; + switch_core_media_bug_set_flag(bug, SMBF_PRUNE); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "initial-timeout\n"); rayo_component_send_complete(RAYO_COMPONENT(component), INPUT_NOINPUT); } @@ -324,6 +334,7 @@ static switch_bool_t input_component_bug_callback(switch_media_bug_t *bug, void rayo_component_send_complete(RAYO_COMPONENT(component), COMPONENT_COMPLETE_HANGUP); } } + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Removing DTMF callback\n"); switch_core_event_hook_remove_recv_dtmf(session, input_component_on_dtmf); break; default: