From de0f311f2d8ba443b13efbffd10bdb527b4defb9 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 4 Sep 2012 15:07:09 -0500 Subject: [PATCH 01/13] FS-4591 --resolve --- src/mod/languages/mod_managed/managed/ManagedSession.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mod/languages/mod_managed/managed/ManagedSession.cs b/src/mod/languages/mod_managed/managed/ManagedSession.cs index 07832ae102..0bf28468af 100644 --- a/src/mod/languages/mod_managed/managed/ManagedSession.cs +++ b/src/mod/languages/mod_managed/managed/ManagedSession.cs @@ -145,6 +145,8 @@ namespace FreeSWITCH.Native switch_state_handler_t_delegate del = ptr => { using (var sess = new ManagedSession(new SWIGTYPE_p_switch_core_session(ptr, false))) { handler(sess); + sess.setAutoHangup(false); + sess.destroy(); return switch_status_t.SWITCH_STATUS_SUCCESS; } }; From 1a47eb933b363d9a02f739eafd68196ab46371b4 Mon Sep 17 00:00:00 2001 From: Stefan Knoblich Date: Wed, 5 Sep 2012 00:13:18 +0200 Subject: [PATCH 02/13] ftmod_libpri: Reset timer parameters in lpwrap_run_expired() before invoking the callback. Allowing us to restart the timer from the callback with lpwrap_start_timer(). Signed-off-by: Stefan Knoblich --- libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c b/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c index 7cbcc7cd41..fb478901b3 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c +++ b/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c @@ -275,15 +275,17 @@ static int lpwrap_run_expired(struct lpwrap_pri *spri, ftdm_time_t now_ms) /* fire callbacks */ while ((cur = expired_list)) { + timeout_handler handler = cur->callback; expired_list = cur->next; - if (cur->callback) - cur->callback(spri, cur); - /* stop timer */ + + /* Stop timer */ cur->next = NULL; cur->timeout = 0; cur->callback = NULL; - } + if (handler) + handler(spri, cur); + } return 0; } From 4ffcb7c9efd257c91b0cb765fc5bbc8aed05faa0 Mon Sep 17 00:00:00 2001 From: Stefan Knoblich Date: Wed, 5 Sep 2012 00:22:52 +0200 Subject: [PATCH 03/13] ftmod_libpri: Improve RESTART handling, add PTP NT idle channel restart and T316. Do not try to send RESTART on BRI PTMP spans, libpri will just print an error and do nothing, causing the channels to be stuck in RESTART forever. Add T316 (RESTART ACK timeout), which is not implemented by libpri. The default timeout is 30 seconds (Q.931 recommends 2 minutes, but that is a little long and libpri layer 2 is being stupid) and the restart attempt limit to 3 (instead of 2). Periodically send RESTART on idle b-channels in PTP NT mode. Default interval is 15 minutes, feature can be disabled by setting "idle_restart_interval" to 0 in the span configuration. Allow timeout / interval values to have an additional time unit suffix for convenience reasons, the default (no unit specified) is milliseconds, valid units include: w (week), d (day), h (hour), m (minute), s (second) Only full integers are accepted, no fractional numbers, valid examples: 2w = two weeks 37m = 37 minutes 1h = 1 hour Combinations of multiple numbers and units (e.g. "1w5d") are not supported. New span configuration parameters: idle_restart_interval (milliseconds / time unit suffix / 0 = disabled) t316 / restart_timeout (milliseconds / time unit suffix) t316_limit / restart_attempts (number of max. attempts) Signed-off-by: Stefan Knoblich --- .../src/ftmod/ftmod_libpri/ftmod_libpri.c | 212 +++++++++++++++++- .../src/ftmod/ftmod_libpri/ftmod_libpri.h | 25 +++ 2 files changed, 227 insertions(+), 10 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c index 033d24b620..9412d75c9b 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c +++ b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c @@ -39,6 +39,8 @@ static ftdm_status_t ftdm_libpri_start(ftdm_span_t *span); static ftdm_io_interface_t ftdm_libpri_interface; static int on_timeout_t302(struct lpwrap_pri *spri, struct lpwrap_timer *timer); +static int on_timeout_t316(struct lpwrap_pri *spri, struct lpwrap_timer *timer); +static int on_timeout_t3xx(struct lpwrap_pri *spri, struct lpwrap_timer *timer); static void _ftdm_channel_set_state_force(ftdm_channel_t *chan, const ftdm_channel_state_t state) @@ -739,7 +741,7 @@ static ftdm_state_map_t isdn_state_map = { ZSD_OUTBOUND, ZSM_UNACCEPTABLE, {FTDM_CHANNEL_STATE_RESTART, FTDM_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_END} + {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_SUSPENDED, FTDM_END} }, { ZSD_OUTBOUND, @@ -806,6 +808,12 @@ static ftdm_state_map_t isdn_state_map = { {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END}, {FTDM_CHANNEL_STATE_DOWN, FTDM_END}, }, + { + ZSD_OUTBOUND, + ZSM_UNACCEPTABLE, + {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_END}, + {FTDM_CHANNEL_STATE_DOWN, FTDM_END}, + }, /****************************************/ { @@ -818,7 +826,7 @@ static ftdm_state_map_t isdn_state_map = { ZSD_INBOUND, ZSM_UNACCEPTABLE, {FTDM_CHANNEL_STATE_RESTART, FTDM_END}, - {FTDM_CHANNEL_STATE_DOWN, FTDM_END} + {FTDM_CHANNEL_STATE_DOWN, FTDM_CHANNEL_STATE_SUSPENDED, FTDM_END} }, { ZSD_INBOUND, @@ -894,6 +902,12 @@ static ftdm_state_map_t isdn_state_map = { {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END}, {FTDM_CHANNEL_STATE_DOWN, FTDM_END}, }, + { + ZSD_INBOUND, + ZSM_UNACCEPTABLE, + {FTDM_CHANNEL_STATE_SUSPENDED, FTDM_END}, + {FTDM_CHANNEL_STATE_DOWN, FTDM_END}, + }, } }; @@ -935,6 +949,10 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan) /* Stop T302 */ lpwrap_stop_timer(&isdn_data->spri, &chan_priv->t302); + /* Stop T316 and reset counter */ + lpwrap_stop_timer(&isdn_data->spri, &chan_priv->t316); + chan_priv->t316_timeout_cnt = 0; + if (ftdm_channel_close(&chtmp) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_WARNING, "-- Failed to close channel %d:%d\n", ftdm_channel_get_span_id(chan), @@ -1073,11 +1091,17 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan) sig.event_id = FTDM_SIGEVENT_RESTART; status = ftdm_span_send_signal(span, &sig); - if (!(chan_priv->flags & FTDM_LIBPRI_B_REMOTE_RESTART)) { + if (ftdm_span_get_trunk_type(span) == FTDM_TRUNK_BRI_PTMP) { + /* Just put the channel into DOWN state, libpri won't send RESTART on BRI PTMP */ + ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_DOWN); + + } else if (!(chan_priv->flags & FTDM_LIBPRI_B_REMOTE_RESTART)) { /* Locally triggered restart, send RESTART to remote, wait for ACK */ pri_reset(isdn_data->spri.pri, ftdm_channel_get_id(chan)); + /* Start T316 */ + lpwrap_start_timer(&isdn_data->spri, &chan_priv->t316, isdn_data->t316_timeout_ms, &on_timeout_t316); } else { - /* Remote restart complete, clear flag */ + /* Remote restart complete, clear flag (RESTART ACK already sent by libpri) */ chan_priv->flags &= ~FTDM_LIBPRI_B_REMOTE_RESTART; ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_DOWN); } @@ -1865,11 +1889,67 @@ static int on_timeout_t302(struct lpwrap_pri *spri, struct lpwrap_timer *timer) ftdm_libpri_b_chan_t *chan_priv = ftdm_container_of(timer, ftdm_libpri_b_chan_t, t302); ftdm_channel_t *chan = chan_priv->channel; - ftdm_log(FTDM_LOG_NOTICE, "-- T302 timed out, going to state RING\n"); + ftdm_log_chan_msg(chan, FTDM_LOG_INFO, "-- T302 timed out, going to state RING\n"); ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RING); return 0; } +/** + * Timeout handler for T316 (RESTART ACK timer) + */ +static int on_timeout_t316(struct lpwrap_pri *spri, struct lpwrap_timer *timer) +{ + ftdm_libpri_b_chan_t *chan_priv = ftdm_container_of(timer, ftdm_libpri_b_chan_t, t316); + ftdm_libpri_data_t *isdn_data = ftdm_container_of(spri, ftdm_libpri_data_t, spri); + ftdm_channel_t *chan = chan_priv->channel; + + if (++chan_priv->t316_timeout_cnt > isdn_data->t316_max_attempts) { + ftdm_log_chan(chan, FTDM_LOG_ERROR, "-- T316 timed out, channel reached restart attempt limit '%d' and is suspended\n", + isdn_data->t316_max_attempts); + + ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_SUSPENDED); + } else { + ftdm_log_chan_msg(chan, FTDM_LOG_WARNING, "-- T316 timed out, resending RESTART request\n"); + pri_reset(spri->pri, ftdm_channel_get_id(chan)); + + /* Restart T316 */ + lpwrap_start_timer(spri, timer, isdn_data->t316_timeout_ms, &on_timeout_t316); + } + return 0; +} + + +/** + * Timeout handler for T3xx (NT-mode idle restart) + */ +static int on_timeout_t3xx(struct lpwrap_pri *spri, struct lpwrap_timer *timer) +{ + ftdm_span_t *span = spri->span; + ftdm_libpri_data_t *isdn_data = span->signal_data; + ftdm_iterator_t *iter = NULL; + + ftdm_log_chan_msg(isdn_data->dchan, FTDM_LOG_INFO, "-- T3xx timed out, restarting idle b-channels\n"); + ftdm_mutex_lock(span->mutex); + + /* Iterate b-channels */ + for (iter = ftdm_span_get_chan_iterator(span, NULL); iter; iter = ftdm_iterator_next(iter)) { + ftdm_channel_t *cur = ftdm_iterator_current(iter); + /* Skip non-b-channels */ + if (ftdm_channel_get_type(cur) != FTDM_CHAN_TYPE_B) + continue; + /* Restart idle b-channels */ + if (ftdm_channel_get_state(cur) == FTDM_CHANNEL_STATE_DOWN) { + ftdm_set_state_locked(cur, FTDM_CHANNEL_STATE_RESTART); + } + } + ftdm_iterator_free(iter); + ftdm_mutex_unlock(span->mutex); + + /* Start timer again */ + lpwrap_start_timer(spri, timer, isdn_data->idle_restart_timeout_ms, &on_timeout_t3xx); + return 0; +} + /** * \brief Processes freetdm event @@ -2237,6 +2317,7 @@ static int on_dchan_up(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_ev if (!ftdm_test_flag(spri, LPWRAP_PRI_READY)) { ftdm_signaling_status_t status = FTDM_SIG_STATE_UP; ftdm_span_t *span = spri->span; + ftdm_libpri_data_t *isdn_data = span->signal_data; ftdm_sigmsg_t sig; int i; @@ -2257,6 +2338,15 @@ static int on_dchan_up(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_ev sig.ev_data.sigstatus.status = status; ftdm_span_send_signal(span, &sig); } + + /* NT-mode idle b-channel restart timer */ + if (ftdm_span_get_trunk_type(span) != FTDM_TRUNK_BRI_PTMP && + isdn_data->mode == PRI_NETWORK && isdn_data->idle_restart_timeout_ms > 0) + { + ftdm_log_chan(isdn_data->dchan, FTDM_LOG_INFO, "Starting NT-mode idle b-channel restart timer (%d ms)\n", + isdn_data->idle_restart_timeout_ms); + lpwrap_start_timer(&isdn_data->spri, &isdn_data->t3xx, isdn_data->idle_restart_timeout_ms, &on_timeout_t3xx); + } } return 0; } @@ -2273,6 +2363,7 @@ static int on_dchan_down(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_ if (ftdm_test_flag(spri, LPWRAP_PRI_READY)) { ftdm_signaling_status_t status = FTDM_SIG_STATE_DOWN; ftdm_span_t *span = spri->span; + ftdm_libpri_data_t *isdn_data = span->signal_data; ftdm_sigmsg_t sig; int i; @@ -2293,9 +2384,19 @@ static int on_dchan_down(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_ sig.ev_data.sigstatus.status = status; ftdm_span_send_signal(span, &sig); - } - } + if (ftdm_channel_get_type(chan) == FTDM_CHAN_TYPE_B) { + ftdm_libpri_b_chan_t *chan_priv = chan->call_data; + /* Stop T316 and reset counter */ + lpwrap_stop_timer(spri, &chan_priv->t316); + chan_priv->t316_timeout_cnt = 0; + } + } + + /* NT-mode idle b-channel restart timer */ + ftdm_log_chan_msg(isdn_data->dchan, FTDM_LOG_INFO, "Stopping NT-mode idle b-channel restart timer\n"); + lpwrap_stop_timer(&isdn_data->spri, &isdn_data->t3xx); + } return 0; } @@ -2646,6 +2747,53 @@ static uint32_t parse_opts(const char *in) return flags; } +/** + * Parse timeout value with (convenience) modifier suffix + * \param[in] in Input string, e.g. '1d' = 1 day, '7w' = 7 weeks, '3s' = 3 seconds + * \todo Could be simplified by using strtol() instead of atoi() + */ +static int parse_timeout(const char *in) +{ + const char *p_end = NULL, *p_start = in; + int msec = 0; + + if (ftdm_strlen_zero(in)) + return 0; + + p_end = in + strlen(in); + + /* skip whitespace at start */ + while (p_start != p_end && *p_start == ' ') + p_start++; + + /* skip whitespace at end */ + while (p_end != p_start && (*p_end == ' ' || *p_end == '\0')) + p_end--; + + msec = atoi(p_start); + + switch (p_end[0]) { + case 's': /* seconds */ + msec *= 1000; + break; + case 'm': /* minutes */ + if (p_end[1] != 's') msec *= 60 * 1000; + break; + case 'h': /* hours */ + msec *= 3600 * 1000; + break; + case 'd': /* days */ + msec *= 86400 * 1000; + break; + case 'w': /* weeks */ + msec *= 604800 * 1000; + break; + default: /* miliseconds */ + break; + } + return msec; +} + /** * \brief Initialises a libpri span from configuration variables * \param span Span to configure @@ -2699,6 +2847,15 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_libpri_configure_span) /* set some default values */ isdn_data->ton = PRI_UNKNOWN; isdn_data->overlap_timeout_ms = OVERLAP_TIMEOUT_MS_DEFAULT; + isdn_data->idle_restart_timeout_ms = IDLE_RESTART_TIMEOUT_MS_DEFAULT; + + /* + * T316 restart ack timeout and retry limit + * (ITU-T Q.931 05/98 Paragraph 5.5.1 and Table 9-1) + */ + isdn_data->t316_timeout_ms = T316_TIMEOUT_MS_DEFAULT; + isdn_data->t316_max_attempts = T316_ATTEMPT_LIMIT_DEFAULT; + /* Use span's trunk_mode as a reference for the default libpri mode */ if (ftdm_span_get_trunk_mode(span) == FTDM_TRUNK_MODE_NET) { @@ -2777,16 +2934,51 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_libpri_configure_span) } } else if (!strcasecmp(var, "digit_timeout") || !strcasecmp(var, "t302")) { - int tmp = atoi(val); + int tmp = parse_timeout(val); if (!tmp) { isdn_data->overlap_timeout_ms = 0; /* disabled */ } else if ((isdn_data->overlap_timeout_ms = ftdm_clamp(tmp, OVERLAP_TIMEOUT_MS_MIN, OVERLAP_TIMEOUT_MS_MAX)) != tmp) { - ftdm_log(FTDM_LOG_WARNING, "'%s' value '%d' outside of range [%d:%d], using '%d' ms instead\n", - var, tmp, OVERLAP_TIMEOUT_MS_MIN, OVERLAP_TIMEOUT_MS_MAX, + ftdm_log(FTDM_LOG_WARNING, "'%s' value %d ms ('%s') outside of range [%d:%d] ms, using %d ms instead\n", + var, tmp, val, OVERLAP_TIMEOUT_MS_MIN, OVERLAP_TIMEOUT_MS_MAX, isdn_data->overlap_timeout_ms); } } + else if (!strcasecmp(var, "idle_restart_interval")) { + int tmp = parse_timeout(val); + if (!tmp) { + isdn_data->idle_restart_timeout_ms = 0; /* disabled */ + } + else if ((isdn_data->idle_restart_timeout_ms = ftdm_clamp(tmp, IDLE_RESTART_TIMEOUT_MS_MIN, IDLE_RESTART_TIMEOUT_MS_MAX)) != tmp) { + ftdm_log(FTDM_LOG_WARNING, "'%s' value %d ms ('%s') outside of range [%d:%d] ms, using %d ms instead\n", + var, tmp, val, IDLE_RESTART_TIMEOUT_MS_MIN, IDLE_RESTART_TIMEOUT_MS_MAX, + isdn_data->idle_restart_timeout_ms); + } + } + else if (!strcasecmp(var, "restart_timeout") || !strcasecmp(var, "t316")) { + int tmp = parse_timeout(val); + if (tmp <= 0) { + ftdm_log(FTDM_LOG_ERROR, "'%s' value '%s' is invalid\n", var, val); + goto error; + } + else if ((isdn_data->t316_timeout_ms = ftdm_clamp(tmp, T316_TIMEOUT_MS_MIN, T316_TIMEOUT_MS_MAX)) != tmp) { + ftdm_log(FTDM_LOG_WARNING, "'%s' value %d ms ('%s') outside of range [%d:%d] ms, using %d ms instead\n", + var, tmp, val, T316_TIMEOUT_MS_MIN, T316_TIMEOUT_MS_MAX, + isdn_data->t316_timeout_ms); + } + } + else if (!strcasecmp(var, "restart_attempts") || !strcasecmp(var, "t316_limit")) { + int tmp = atoi(val); + if (tmp <= 0) { + ftdm_log(FTDM_LOG_ERROR, "'%s' value '%s' is invalid\n", var, val); + goto error; + } + else if ((isdn_data->t316_max_attempts = ftdm_clamp(tmp, T316_ATTEMPT_LIMIT_MIN, T316_ATTEMPT_LIMIT_MAX)) != tmp) { + ftdm_log(FTDM_LOG_WARNING, "'%s' value %d ('%s') outside of range [%d:%d], using %d instead\n", + var, tmp, val, T316_ATTEMPT_LIMIT_MIN, T316_ATTEMPT_LIMIT_MAX, + isdn_data->t316_max_attempts); + } + } else if (!strcasecmp(var, "debug")) { if (parse_debug(val, &isdn_data->debug_mask) == -1) { ftdm_log(FTDM_LOG_ERROR, "Invalid debug flag, ignoring parameter\n"); diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.h b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.h index fcaa1bc457..f439694886 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.h +++ b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.h @@ -35,10 +35,27 @@ #include "freetdm.h" #include "lpwrap_pri.h" +/* T302 Overlap receiving inter-digit timeout */ #define OVERLAP_TIMEOUT_MS_DEFAULT 5000 /* 5 sec */ #define OVERLAP_TIMEOUT_MS_MIN 3000 /* 3 sec */ #define OVERLAP_TIMEOUT_MS_MAX 30000 /* 30 sec */ +/* NT-mode idle b-channel restart timer */ +#define IDLE_RESTART_TIMEOUT_MS_DEFAULT 900000 /* 15 min */ +#define IDLE_RESTART_TIMEOUT_MS_MIN 10000 /* 10 sec */ +#define IDLE_RESTART_TIMEOUT_MS_MAX 86400000 /* 1 day */ + +/* T316 RESTART ACK wait timer */ +#define T316_TIMEOUT_MS_DEFAULT 30000 /* 30 sec */ +#define T316_TIMEOUT_MS_MIN 10000 /* 10 sec */ +#define T316_TIMEOUT_MS_MAX 300000 /* 5 min */ + +/* T316 restart attempts until channel is suspended */ +#define T316_ATTEMPT_LIMIT_DEFAULT 3 +#define T316_ATTEMPT_LIMIT_MIN 1 +#define T316_ATTEMPT_LIMIT_MAX 10 + + typedef enum { SERVICE_CHANGE_STATUS_INSERVICE = 0, SERVICE_CHANGE_STATUS_MAINTENANCE, @@ -76,6 +93,9 @@ struct ftdm_libpri_data { int dialect; int overlap; /*!< Overlap dial flags */ int overlap_timeout_ms; /*!< Overlap dial timeout */ + int idle_restart_timeout_ms; /*!< NT-mode idle b-channel restart */ + int t316_timeout_ms; /*!< T316 RESTART ACK timeout */ + int t316_max_attempts; /*!< T316 timeout limit */ unsigned int layer1; unsigned int ton; unsigned int service_message_support; @@ -85,6 +105,9 @@ struct ftdm_libpri_data { /* MSN filter */ ftdm_hash_t *msn_hash; ftdm_mutex_t *msn_mutex; + + /* NT-mode idle restart timer */ + struct lpwrap_timer t3xx; }; typedef struct ftdm_libpri_data ftdm_libpri_data_t; @@ -103,9 +126,11 @@ enum { */ struct ftdm_libpri_b_chan { struct lpwrap_timer t302; /*!< T302 overlap receive timer */ + struct lpwrap_timer t316; /*!< T316 restart ack timer */ ftdm_channel_t *channel; /*!< back-pointer to b-channel */ q931_call *call; /*!< libpri opaque call handle */ uint32_t flags; /*!< channel flags */ + uint32_t t316_timeout_cnt; /*!< T316 timeout counter */ }; typedef struct ftdm_libpri_b_chan ftdm_libpri_b_chan_t; From a9d72bc35d0e021f8db1ea480b1ddb0744d73bac Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 4 Sep 2012 19:08:06 -0500 Subject: [PATCH 04/13] fix small broadcast bug --- src/switch_ivr.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 0f98a9b856..95f0e901d8 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -560,7 +560,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_event(switch_core_session_t *se if (!switch_channel_test_flag(channel, CF_BROADCAST)) { switch_channel_set_flag(channel, CF_BROADCAST); - inner--; + if (inner) { + inner--; + } } if (hold_bleg && switch_true(hold_bleg)) { @@ -611,7 +613,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_event(switch_core_session_t *se if (switch_core_session_execute_application(session, app_name, app_arg) != SWITCH_STATUS_SUCCESS) { if (!inner || switch_channel_test_flag(channel, CF_STOP_BROADCAST)) switch_channel_clear_flag(channel, CF_BROADCAST); - goto done; + break; } aftr = switch_micro_time_now(); From 528d10319feea08447c6ca94c6690fc4de19480b Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Tue, 4 Sep 2012 23:32:59 -0500 Subject: [PATCH 05/13] fix naming issue in last mod_managed change - trivial --- src/mod/languages/mod_managed/managed/ManagedSession.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/languages/mod_managed/managed/ManagedSession.cs b/src/mod/languages/mod_managed/managed/ManagedSession.cs index 0bf28468af..9629215c70 100644 --- a/src/mod/languages/mod_managed/managed/ManagedSession.cs +++ b/src/mod/languages/mod_managed/managed/ManagedSession.cs @@ -145,7 +145,7 @@ namespace FreeSWITCH.Native switch_state_handler_t_delegate del = ptr => { using (var sess = new ManagedSession(new SWIGTYPE_p_switch_core_session(ptr, false))) { handler(sess); - sess.setAutoHangup(false); + sess.SetAutoHangup(false); sess.destroy(); return switch_status_t.SWITCH_STATUS_SUCCESS; } From 8ec031e7c915f6bf131c88957dc32397fab6d65d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 5 Sep 2012 11:12:06 -0500 Subject: [PATCH 06/13] let callers delete themselves on reload --- src/mod/applications/mod_fifo/mod_fifo.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 15c6d124f9..2ef5c7fca9 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -2247,7 +2247,7 @@ static void fifo_caller_del(const char *uuid) if (uuid) { sql = switch_mprintf("delete from fifo_callers where uuid='%q'", uuid); } else { - sql = switch_mprintf("delete from fifo_callers", uuid); + sql = switch_mprintf("delete from fifo_callers"); } fifo_execute_sql(sql, globals.sql_mutex); @@ -4251,7 +4251,6 @@ static switch_status_t load_config(int reload, int del_all) } } switch_mutex_unlock(globals.mutex); - fifo_caller_del(NULL); } From 709e4fb28a2bc72accd4905c8c0aa7254e982558 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 5 Sep 2012 11:20:17 -0500 Subject: [PATCH 07/13] add make version target --- Makefile.am | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile.am b/Makefile.am index 413fe49bfc..c33c521bfa 100644 --- a/Makefile.am +++ b/Makefile.am @@ -585,6 +585,9 @@ libs/openzap/Makefile: cd libs/openzap && autoconf cd libs/openzap && ./configure +version: + git log -1 | head -3 + reinstall: modwipe uninstall install update-clean: clean libs/openzap/Makefile python-reconf From f79668d57a233c0ac354ffb2d0d4f8abe01cd15d Mon Sep 17 00:00:00 2001 From: Michael S Collins Date: Wed, 5 Sep 2012 09:28:43 -0700 Subject: [PATCH 08/13] Update phrase_en.xml for sounds ver 1.0.21 --- docs/phrase/phrase_en.xml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/phrase/phrase_en.xml b/docs/phrase/phrase_en.xml index 17c4ce5f03..fa9f4f7cc8 100644 --- a/docs/phrase/phrase_en.xml +++ b/docs/phrase/phrase_en.xml @@ -382,6 +382,7 @@ + @@ -566,7 +567,6 @@ - @@ -583,18 +583,13 @@ - - - - - - - + + @@ -622,6 +617,12 @@ + + + + + + From 3dc829afa1e803a0ce67b155fd8318baf8eff541 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 5 Sep 2012 11:29:39 -0500 Subject: [PATCH 09/13] remove .la files on modwipe --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index c33c521bfa..8c61da454a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -695,7 +695,7 @@ modclean: $(switch_builddir)/modules.conf @cd src/mod && $(MAKE) $(AM_MAKEFLAGS) clean modwipe: - rm -f $(modulesdir)/*.${DYNAMIC_LIB_EXTEN} + rm -f $(modulesdir)/*.${DYNAMIC_LIB_EXTEN} $(modulesdir)/*.la dox: cd docs && doxygen $(PWD)/docs/Doxygen.conf From 8650116d2067c3c7691eaa579a60aeabfff20f17 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 5 Sep 2012 11:36:07 -0500 Subject: [PATCH 10/13] move verbos zrtp debug messages to log level DEBUG1 fsctl debug_level 1 to see them --- src/mod/endpoints/mod_sofia/sofia_glue.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index c642657fb7..c381ead0d4 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -3915,9 +3915,9 @@ void sofia_glue_pass_zrtp_hash2(switch_core_session_t *aleg_session, switch_core bleg_channel = switch_core_session_get_channel(bleg_session); bleg_tech_pvt = switch_core_session_get_private(bleg_session); - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(aleg_channel), SWITCH_LOG_DEBUG, "Deciding whether to pass zrtp-hash between a-leg and b-leg\n"); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(aleg_channel), SWITCH_LOG_DEBUG1, "Deciding whether to pass zrtp-hash between a-leg and b-leg\n"); if (!(switch_channel_test_flag(aleg_tech_pvt->channel, CF_ZRTP_PASSTHRU_REQ))) { - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(aleg_channel), SWITCH_LOG_DEBUG, "CF_ZRTP_PASSTHRU_REQ not set on a-leg, so not propagating zrtp-hash\n"); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(aleg_channel), SWITCH_LOG_DEBUG1, "CF_ZRTP_PASSTHRU_REQ not set on a-leg, so not propagating zrtp-hash\n"); return; } if (aleg_tech_pvt->remote_sdp_audio_zrtp_hash) { @@ -3947,15 +3947,15 @@ void sofia_glue_pass_zrtp_hash(switch_core_session_t *session) switch_channel_t *channel = switch_core_session_get_channel(session); private_object_t *tech_pvt = switch_core_session_get_private(session); switch_core_session_t *other_session; - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Deciding whether to pass zrtp-hash between legs\n"); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "Deciding whether to pass zrtp-hash between legs\n"); if (!(switch_channel_test_flag(tech_pvt->channel, CF_ZRTP_PASSTHRU_REQ))) { - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "CF_ZRTP_PASSTHRU_REQ not set, so not propagating zrtp-hash\n"); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "CF_ZRTP_PASSTHRU_REQ not set, so not propagating zrtp-hash\n"); return; } else if (!(switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS)) { - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "No partner channel found, so not propagating zrtp-hash\n"); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "No partner channel found, so not propagating zrtp-hash\n"); return; } else { - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Found peer channel; propagating zrtp-hash if set\n"); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "Found peer channel; propagating zrtp-hash if set\n"); sofia_glue_pass_zrtp_hash2(session, other_session); switch_core_session_rwunlock(other_session); } @@ -3969,7 +3969,7 @@ static void find_zrtp_hash(switch_core_session_t *session, sdp_session_t *sdp) sdp_attribute_t *attr; int got_audio = 0, got_video = 0; - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Looking for zrtp-hash\n"); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG1, "Looking for zrtp-hash\n"); for (m = sdp->sdp_media; m; m = m->m_next) { if (got_audio && got_video) break; if (m->m_port && ((m->m_type == sdp_media_audio && !got_audio) From 352b1903da645de16572ef2591d6820eeeedf4bd Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 5 Sep 2012 12:47:47 -0500 Subject: [PATCH 11/13] FS-4593 please test this and post logs if necessary --- src/switch_ivr_bridge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index f2aec42fdd..590ebcea34 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -588,7 +588,7 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "BRIDGE THREAD DONE [%s]\n", switch_channel_get_name(chan_a)); switch_channel_clear_flag(chan_a, CF_BRIDGED); - if (switch_channel_test_flag(chan_a, CF_LEG_HOLDING) && switch_channel_ready(chan_b)) { + if (switch_channel_test_flag(chan_a, CF_LEG_HOLDING) && switch_channel_ready(chan_b) && switch_channel_get_state(chan_b) != CS_PARK) { const char *ext = switch_channel_get_variable(chan_a, "hold_hangup_xfer_exten"); switch_channel_stop_broadcast(chan_b); From d45db898339e1b2212f5befff1af714abcec034f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 5 Sep 2012 13:11:32 -0500 Subject: [PATCH 12/13] second try at sip_wait_for_aleg_ack --- src/mod/endpoints/mod_sofia/mod_sofia.h | 1 + src/mod/endpoints/mod_sofia/sofia.c | 80 ++++++++++++++++++------- 2 files changed, 58 insertions(+), 23 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 7d6659cdfc..f0c57cb988 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -341,6 +341,7 @@ typedef enum { TFLAG_REINVITED, TFLAG_SLA_BARGE, TFLAG_SLA_BARGING, + TFLAG_PASS_ACK, /* No new flags below this line */ TFLAG_MAX } TFLAGS; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index d132d15918..2523f7ae5d 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -954,6 +954,36 @@ void sofia_update_callee_id(switch_core_session_t *session, sofia_profile_t *pro switch_safe_free(dup); } +static void tech_send_ack(nua_handle_t *nh, private_object_t *tech_pvt) +{ + const char *invite_full_from = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_from"); + const char *invite_full_to = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_to"); + + + if (sofia_test_pflag(tech_pvt->profile, PFLAG_TRACK_CALLS)) { + const char *invite_full_via = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_via"); + const char *invite_route_uri = switch_channel_get_variable(tech_pvt->channel, "sip_invite_route_uri"); + + nua_ack(nh, + TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)), + TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)), + TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), + TAG_IF((zstr(tech_pvt->user_via) && !zstr(invite_full_via)), SIPTAG_VIA_STR(invite_full_via)), + TAG_IF(!zstr(invite_route_uri), SIPTAG_ROUTE_STR(invite_route_uri)), + TAG_END()); + + + } else { + nua_ack(nh, + TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)), + TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)), + TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), + TAG_END()); + } + +} + + //sofia_dispatch_event_t *de static void our_sofia_event_callback(nua_event_t event, int status, @@ -1124,6 +1154,24 @@ static void our_sofia_event_callback(nua_event_t event, extract_header_vars(profile, sip, session, nh); switch_core_recovery_track(session); sofia_set_flag(tech_pvt, TFLAG_GOT_ACK); + + if (sofia_test_flag(tech_pvt, TFLAG_PASS_ACK)) { + switch_core_session_t *other_session; + + sofia_clear_flag(tech_pvt, TFLAG_PASS_ACK); + + + if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { + if (switch_core_session_compare(session, other_session)) { + private_object_t *other_tech_pvt = switch_core_session_get_private(other_session); + tech_send_ack(other_tech_pvt->nh, other_tech_pvt); + } + switch_core_session_rwunlock(other_session); + } + + } + + } } case nua_r_ack: @@ -6311,16 +6359,18 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, break; case nua_callstate_completing: { - const char *invite_full_from = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_from"); - const char *invite_full_to = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_to"); const char *wait_for_ack = switch_channel_get_variable(channel, "sip_wait_for_aleg_ack"); + int send_ack = 1; if (switch_true(wait_for_ack)) { switch_core_session_t *other_session; if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { - switch_channel_t *other_channel = switch_core_session_get_channel(other_session); - switch_channel_wait_for_flag(other_channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL); + if (switch_core_session_compare(session, other_session)) { + private_object_t *other_tech_pvt = switch_core_session_get_private(other_session); + sofia_set_flag(other_tech_pvt, TFLAG_PASS_ACK); + send_ack = 0; + } switch_core_session_rwunlock(other_session); } } @@ -6341,26 +6391,10 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } - if (sofia_test_pflag(profile, PFLAG_TRACK_CALLS)) { - const char *invite_full_via = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_via"); - const char *invite_route_uri = switch_channel_get_variable(tech_pvt->channel, "sip_invite_route_uri"); - - nua_ack(nh, - TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)), - TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)), - TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), - TAG_IF((zstr(tech_pvt->user_via) && !zstr(invite_full_via)), SIPTAG_VIA_STR(invite_full_via)), - - TAG_IF(!zstr(invite_route_uri), SIPTAG_ROUTE_STR(invite_route_uri)), - TAG_END()); - - } else { - nua_ack(nh, - TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)), - TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)), - TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), - TAG_END()); + if (send_ack) { + tech_send_ack(nh, tech_pvt); } + } goto done; case nua_callstate_received: From 77de3905ee58c7964d1ee93f2612d070c063f5ca Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 5 Sep 2012 13:48:52 -0500 Subject: [PATCH 13/13] one more try --- src/mod/endpoints/mod_sofia/sofia.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 2523f7ae5d..d1e4a09e73 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -6393,6 +6393,9 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (send_ack) { tech_send_ack(nh, tech_pvt); + } else { + ss_state = nua_callstate_ready; + goto state_process; } }