diff --git a/conf/autoload_configs/acl.conf.xml b/conf/autoload_configs/acl.conf.xml
index a1708a55f3..0c117d07bf 100644
--- a/conf/autoload_configs/acl.conf.xml
+++ b/conf/autoload_configs/acl.conf.xml
@@ -21,7 +21,10 @@
digest authenticated.
-->
+
+
+
diff --git a/conf/sip_profiles/internal.xml b/conf/sip_profiles/internal.xml
index d09ca79dce..426264a1c5 100644
--- a/conf/sip_profiles/internal.xml
+++ b/conf/sip_profiles/internal.xml
@@ -114,6 +114,8 @@
+
+
diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c
index 8afe6e82f5..6cd2a226c8 100644
--- a/libs/freetdm/src/ftdm_io.c
+++ b/libs/freetdm/src/ftdm_io.c
@@ -2294,13 +2294,13 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch
ftdm_assert_return(ftdmchan, FTDM_FAIL, "Null channel\n");
- ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Indicating %s in state %s\n",
+ ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Indicating %s in state %s\n",
ftdm_channel_indication2str(indication), ftdm_channel_state2str(ftdmchan->state));
ftdm_channel_lock(ftdmchan);
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_IND_ACK_PENDING)) {
- ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Cannot indicate %s in channel with indication %s still pending in state %s\n",
+ ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_WARNING, "Cannot indicate %s in channel with indication %s still pending in state %s\n",
ftdm_channel_indication2str(indication),
ftdm_channel_indication2str(ftdmchan->indication),
ftdm_channel_state2str(ftdmchan->state));
@@ -2314,14 +2314,14 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch
}
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
- ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Cannot indicate %s in outgoing channel in state %s\n",
+ ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_WARNING, "Cannot indicate %s in outgoing channel in state %s\n",
ftdm_channel_indication2str(indication), ftdm_channel_state2str(ftdmchan->state));
status = FTDM_EINVAL;
goto done;
}
if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) {
- ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Ignoring indication %s because the call is in %s state\n",
+ ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Ignoring indication %s because the call is in %s state\n",
ftdm_channel_indication2str(indication), ftdm_channel_state2str(ftdmchan->state));
status = FTDM_ECANCELED;
goto done;
@@ -2358,7 +2358,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch
/* set state unlocks the channel so we need to re-confirm that the channel hasn't gone to hell */
if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) {
- ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring progress media because the call is terminating\n");
+ ftdm_log_chan_ex_msg(ftdmchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Ignoring progress media because the call is terminating\n");
goto done;
}
}
diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c
index 8be6d579e1..2f9c70a48d 100644
--- a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c
+++ b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c
@@ -406,25 +406,36 @@ static ftdm_state_map_t isdn_state_map = {
ZSD_OUTBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_DIALING, FTDM_END},
- {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}
+ {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
+ FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS,
+ FTDM_CHANNEL_STATE_UP, FTDM_END}
},
{
ZSD_OUTBOUND,
ZSM_UNACCEPTABLE,
- {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS, FTDM_END},
- {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_END}
+ {FTDM_CHANNEL_STATE_PROCEED, FTDM_END},
+ {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
+ FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
},
{
ZSD_OUTBOUND,
ZSM_UNACCEPTABLE,
- {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
- {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_DOWN, FTDM_END}
+ {FTDM_CHANNEL_STATE_RINGING, FTDM_END},
+ {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
+ FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
},
{
ZSD_OUTBOUND,
ZSM_UNACCEPTABLE,
- {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END},
- {FTDM_CHANNEL_STATE_DOWN, FTDM_END},
+ {FTDM_CHANNEL_STATE_PROGRESS, FTDM_END},
+ {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
+ FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_END}
+ },
+ {
+ ZSD_OUTBOUND,
+ ZSM_UNACCEPTABLE,
+ {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END},
+ {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_END}
},
{
ZSD_OUTBOUND,
@@ -432,6 +443,24 @@ static ftdm_state_map_t isdn_state_map = {
{FTDM_CHANNEL_STATE_UP, FTDM_END},
{FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}
},
+ {
+ ZSD_OUTBOUND,
+ ZSM_UNACCEPTABLE,
+ {FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
+ {FTDM_CHANNEL_STATE_HANGUP, FTDM_END}
+ },
+ {
+ ZSD_OUTBOUND,
+ ZSM_UNACCEPTABLE,
+ {FTDM_CHANNEL_STATE_HANGUP, FTDM_END},
+ {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END},
+ },
+ {
+ ZSD_OUTBOUND,
+ ZSM_UNACCEPTABLE,
+ {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END},
+ {FTDM_CHANNEL_STATE_DOWN, FTDM_END},
+ },
/****************************************/
{
@@ -462,26 +491,33 @@ static ftdm_state_map_t isdn_state_map = {
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_RING, FTDM_END},
- {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END}
+ {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_RINGING, FTDM_END}
},
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
- {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
- {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_DOWN, FTDM_END},
+ {FTDM_CHANNEL_STATE_PROCEED, FTDM_END},
+ {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS,
+ FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END}
},
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
- {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END},
- {FTDM_CHANNEL_STATE_DOWN, FTDM_END},
+ {FTDM_CHANNEL_STATE_RINGING, FTDM_END},
+ {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA,
+ FTDM_CHANNEL_STATE_UP, FTDM_END}
},
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
- {FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END},
- {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA,
- FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_UP, FTDM_END},
+ {FTDM_CHANNEL_STATE_PROGRESS, FTDM_END},
+ {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END}
+ },
+ {
+ ZSD_INBOUND,
+ ZSM_UNACCEPTABLE,
+ {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END},
+ {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_UP, FTDM_END}
},
{
ZSD_INBOUND,
@@ -489,6 +525,24 @@ static ftdm_state_map_t isdn_state_map = {
{FTDM_CHANNEL_STATE_UP, FTDM_END},
{FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
},
+ {
+ ZSD_INBOUND,
+ ZSM_UNACCEPTABLE,
+ {FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
+ {FTDM_CHANNEL_STATE_HANGUP, FTDM_END},
+ },
+ {
+ ZSD_INBOUND,
+ ZSM_UNACCEPTABLE,
+ {FTDM_CHANNEL_STATE_HANGUP, FTDM_END},
+ {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END},
+ },
+ {
+ ZSD_INBOUND,
+ ZSM_UNACCEPTABLE,
+ {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END},
+ {FTDM_CHANNEL_STATE_DOWN, FTDM_END},
+ },
}
};
@@ -533,8 +587,6 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan)
break;
case FTDM_CHANNEL_STATE_PROGRESS:
- /* RINGING is an alias for PROGRESS state in inbound calls ATM */
- case FTDM_CHANNEL_STATE_RINGING:
{
if (ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND)) {
sig.event_id = FTDM_SIGEVENT_PROGRESS;
@@ -542,7 +594,23 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan)
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP);
}
} else if (call) {
- pri_progress(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 1);
+ pri_progress(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 0);
+ } else {
+ ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART);
+ }
+ }
+ break;
+
+ case FTDM_CHANNEL_STATE_RINGING:
+ {
+ if (ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND)) {
+ sig.event_id = FTDM_SIGEVENT_RINGING;
+ if ((status = ftdm_span_send_signal(ftdm_channel_get_span(chan), &sig) != FTDM_SUCCESS)) {
+ ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP);
+ }
+ } else if (call) {
+// pri_progress(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 1);
+ pri_acknowledge(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 1);
} else {
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART);
}
@@ -561,7 +629,26 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan)
if (!ftdm_test_flag(chan, FTDM_CHANNEL_OPEN)) {
ftdm_channel_open_chan(chan);
}
- pri_proceeding(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 1);
+ pri_progress(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 1);
+ } else {
+ ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART);
+ }
+ }
+ break;
+
+ case FTDM_CHANNEL_STATE_PROCEED:
+ {
+ if (ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND)) {
+ /* PROCEED from other end, notify user */
+ sig.event_id = FTDM_SIGEVENT_PROCEED;
+ if ((status = ftdm_span_send_signal(ftdm_channel_get_span(chan), &sig) != FTDM_SUCCESS)) {
+ ftdm_log(FTDM_LOG_ERROR, "Failed to send PROCEED sigevent on Channel %d:%d\n",
+ ftdm_channel_get_span_id(chan),
+ ftdm_channel_get_id(chan));
+ ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP);
+ }
+ } else if (call) {
+ pri_proceeding(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 0);
} else {
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART);
}
@@ -572,11 +659,12 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan)
{
/*
* This needs more auditing for BRI PTMP:
- * does pri_acknowledge() steal the call from other devices?
+ * does pri_acknowledge() steal the call from other devices? (yes, it does)
*/
if (!ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND)) {
if (call) {
- pri_acknowledge(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 0);
+ pri_proceeding(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 0);
+// pri_acknowledge(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 0);
sig.event_id = FTDM_SIGEVENT_START;
if ((status = ftdm_span_send_signal(ftdm_channel_get_span(chan), &sig) != FTDM_SUCCESS)) {
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP);
@@ -690,15 +778,22 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan)
ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan);
pri_hangup(isdn_data->spri.pri, call, caller_data->hangup_cause);
- pri_destroycall(isdn_data->spri.pri, call);
+// pri_destroycall(isdn_data->spri.pri, call);
chan->call_data = NULL;
}
- ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_DOWN);
+ ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
}
break;
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
+ {
+ if (call) {
+ pri_destroycall(isdn_data->spri.pri, call);
+ chan->call_data = NULL;
+ }
+ ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_DOWN);
+ }
break;
case FTDM_CHANNEL_STATE_TERMINATING:
@@ -869,7 +964,7 @@ static int on_proceeding(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_
}
}
ftdm_log(FTDM_LOG_DEBUG, "-- Proceeding on channel %d:%d\n", ftdm_span_get_id(span), pevent->proceeding.channel);
- ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
+ ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROCEED);
} else {
ftdm_log(FTDM_LOG_DEBUG, "-- Proceeding on channel %d:%d but it's not in the span?\n",
ftdm_span_get_id(span), pevent->proceeding.channel);
@@ -909,9 +1004,12 @@ static int on_progress(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_ev
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_TERMINATING);
goto out;
}
+ ftdm_log(FTDM_LOG_DEBUG, "-- Progress on channel %d:%d with media\n", ftdm_span_get_id(span), pevent->proceeding.channel);
+ ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
+ } else {
+ ftdm_log(FTDM_LOG_DEBUG, "-- Progress on channel %d:%d\n", ftdm_span_get_id(span), pevent->proceeding.channel);
+ ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROGRESS);
}
- ftdm_log(FTDM_LOG_DEBUG, "-- Progress on channel %d:%d\n", ftdm_span_get_id(span), pevent->proceeding.channel);
- ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
} else {
ftdm_log(FTDM_LOG_DEBUG, "-- Progress on channel %d:%d but it's not in the span?\n",
ftdm_span_get_id(span), pevent->proceeding.channel);
@@ -936,10 +1034,10 @@ static int on_ringing(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_eve
ftdm_log(FTDM_LOG_DEBUG, "-- Ringing on channel %d:%d\n", ftdm_span_get_id(span), pevent->ringing.channel);
/* we may get on_ringing even when we're already in FTDM_CHANNEL_STATE_PROGRESS_MEDIA */
- if (ftdm_channel_get_state(chan) == FTDM_CHANNEL_STATE_PROGRESS_MEDIA) {
- /* dont try to move to STATE_PROGRESS to avoid annoying veto warning */
- return 0;
- }
+// if (ftdm_channel_get_state(chan) == FTDM_CHANNEL_STATE_PROGRESS_MEDIA) {
+// /* dont try to move to STATE_PROGRESS to avoid annoying veto warning */
+// return 0;
+// }
/* Open channel if inband information is available */
if ((pevent->ringing.progressmask & PRI_PROG_INBAND_AVAILABLE) && !ftdm_test_flag(chan, FTDM_CHANNEL_OPEN)) {
@@ -959,7 +1057,8 @@ static int on_ringing(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_eve
goto out;
}
}
- ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROGRESS);
+// ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROGRESS);
+ ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RINGING);
} else {
ftdm_log(FTDM_LOG_DEBUG, "-- Ringing on channel %d:%d but it's not in the span?\n",
ftdm_span_get_id(span), pevent->ringing.channel);
@@ -1913,6 +2012,9 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_libpri_configure_span)
span->get_channel_sig_status = isdn_get_channel_sig_status;
span->get_span_sig_status = isdn_get_span_sig_status;
+ /* move calls to PROCEED state when they hit dialplan (ROUTING state in FreeSWITCH) */
+ ftdm_set_flag(span, FTDM_SPAN_USE_PROCEED_STATE);
+
if ((isdn_data->opts & FTMOD_LIBPRI_OPT_SUGGEST_CHANNEL)) {
span->channel_request = isdn_channel_request;
ftdm_set_flag(span, FTDM_SPAN_SUGGEST_CHAN_ID);
diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h
index a5862e5d15..4fd8ec64ea 100644
--- a/libs/freetdm/src/include/private/ftdm_core.h
+++ b/libs/freetdm/src/include/private/ftdm_core.h
@@ -664,7 +664,11 @@ FT_DECLARE(void) ftdm_channel_clear_detected_tones(ftdm_channel_t *ftdmchan);
}
#define ftdm_log_chan_ex(fchan, file, func, line, level, format, ...) ftdm_log(file, func, line, level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__)
+
+#define ftdm_log_chan_ex_msg(fchan, file, func, line, level, msg) ftdm_log(file, func, line, level, "[s%dc%d][%d:%d] " msg, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id)
+
#define ftdm_log_chan(fchan, level, format, ...) ftdm_log(level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__)
+
#define ftdm_log_chan_msg(fchan, level, msg) ftdm_log(level, "[s%dc%d][%d:%d] " msg, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id)
#define ftdm_log_chan_throttle(fchan, level, format, ...) ftdm_log_throttle(level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__)
diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c
index 85b233d5f3..8f01290407 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.c
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.c
@@ -3695,11 +3695,39 @@ SWITCH_STANDARD_API(sofia_function)
int wdon = -1;
if (argc > 1) {
+ if (!strcasecmp(argv[1], "debug")) {
+
+ if (argc > 2) {
+ if (strstr(argv[2], "presence")) {
+ mod_sofia_globals.debug_presence = 1;
+ stream->write_function(stream, "+OK Debugging presence\n");
+ }
+
+ if (strstr(argv[2], "sla")) {
+ mod_sofia_globals.debug_sla = 1;
+ stream->write_function(stream, "+OK Debugging sla\n");
+ }
+
+ if (strstr(argv[2], "none")) {
+ stream->write_function(stream, "+OK Debugging nothing\n");
+ mod_sofia_globals.debug_presence = 0;
+ mod_sofia_globals.debug_sla = 0;
+ }
+ }
+
+ stream->write_function(stream, "+OK Debugging summary: presence: %s sla: %s\n",
+ mod_sofia_globals.debug_presence ? "on" : "off",
+ mod_sofia_globals.debug_sla ? "on" : "off");
+
+ goto done;
+ }
+
if (!strcasecmp(argv[1], "siptrace")) {
if (argc > 2) {
ston = switch_true(argv[2]);
}
}
+
if (!strcasecmp(argv[1], "watchdog")) {
if (argc > 2) {
wdon = switch_true(argv[2]);
@@ -3714,7 +3742,7 @@ SWITCH_STANDARD_API(sofia_function)
sofia_glue_global_watchdog(wdon);
stream->write_function(stream, "+OK Global watchdog %s", wdon ? "on" : "off");
} else {
- stream->write_function(stream, "-ERR Usage: siptrace |watchdog ");
+ stream->write_function(stream, "-ERR Usage: siptrace |watchdog |debug shutdown_type = "false";
profile->local_network = "localnet.auto";
sofia_set_flag(profile, TFLAG_ENABLE_SOA);
@@ -3090,6 +3102,16 @@ switch_status_t config_sofia(int reload, char *profile_name)
} else {
sofia_clear_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER);
}
+ } else if (!strcasecmp(var, "send-presence-on-register")) {
+ if (switch_true(val)) {
+ sofia_set_pflag(profile, PFLAG_PRESENCE_ON_REGISTER);
+ } else if (!strcasecmp(val, "first-only")) {
+ sofia_clear_pflag(profile, PFLAG_PRESENCE_ON_REGISTER);
+ sofia_set_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER);
+ } else {
+ sofia_clear_pflag(profile, PFLAG_PRESENCE_ON_REGISTER);
+ sofia_clear_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER);
+ }
} else if (!strcasecmp(var, "cid-in-1xx")) {
if (switch_true(val)) {
sofia_set_pflag(profile, PFLAG_CID_IN_1XX);
diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c
index a529844059..bf7c1aa7a1 100644
--- a/src/mod/endpoints/mod_sofia/sofia_glue.c
+++ b/src/mod/endpoints/mod_sofia/sofia_glue.c
@@ -2695,8 +2695,8 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force)
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE | tech_pvt->profile->codec_flags,
NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "Can't load codec?\n");
- switch_goto_status(SWITCH_STATUS_FALSE, end);
switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
+ switch_goto_status(SWITCH_STATUS_FALSE, end);
}
if (switch_core_codec_init_with_bitrate(&tech_pvt->write_codec,
diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c
index 288191807c..344e51774d 100644
--- a/src/mod/endpoints/mod_sofia/sofia_reg.c
+++ b/src/mod/endpoints/mod_sofia/sofia_reg.c
@@ -875,9 +875,19 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
long reg_count = 0;
int delete_subs;
const char *agent = "unknown";
-
+ const char *pres_on_reg = NULL;
+ int send_pres = 0;
+
delete_subs = sofia_test_pflag(profile, PFLAG_DEL_SUBS_ON_REG);
+ if (v_event && *v_event) pres_on_reg = switch_event_get_header(*v_event, "send-presence-on-register");
+
+ if (!(send_pres = switch_true(pres_on_reg))) {
+ if (pres_on_reg && !strcasecmp(pres_on_reg, "first-only")) {
+ send_pres = 2;
+ }
+ }
+
/* all callers must confirm that sip, sip->sip_request and sip->sip_contact are not NULL */
switch_assert(sip != NULL && sip->sip_contact != NULL && sip->sip_request != NULL);
@@ -1405,7 +1415,6 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
}
}
-
if (send && switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", rpid);
@@ -1493,27 +1502,31 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
}
}
- if (sofia_test_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER)) {
- if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
- switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "login", profile->name);
- switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, sub_host);
- switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "to", "%s@%s", to_user, sub_host);
- switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event_type", "presence");
- switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
- switch_event_fire(&s_event);
+ if (sofia_test_pflag(profile, PFLAG_PRESENCE_ON_REGISTER) ||
+ (reg_count == 1 && sofia_test_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER))
+ || send_pres == 1 || (reg_count == 1 && send_pres == 2)) {
+
+ if (sofia_test_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER)) {
+ if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) {
+ switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
+ switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "login", profile->name);
+ switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, sub_host);
+ switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "to", "%s@%s", to_user, sub_host);
+ switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event_type", "presence");
+ switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
+ switch_event_fire(&s_event);
+ }
+ } else {
+ if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
+ switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
+ switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "login", profile->name);
+ switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, sub_host);
+ switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", "unknown");
+ switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "status", "Registered");
+ switch_event_fire(&s_event);
+ }
}
- } else {
- if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
- switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "login", profile->name);
- switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, sub_host);
- switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", "unknown");
- switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "status", "Registered");
- switch_event_fire(&s_event);
- }
}
-
} else {
if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_UNREGISTER) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", profile->name);
diff --git a/src/switch_utils.c b/src/switch_utils.c
index 0c492525b1..850b07f51d 100644
--- a/src/switch_utils.c
+++ b/src/switch_utils.c
@@ -812,7 +812,7 @@ SWITCH_DECLARE(char *) switch_strip_whitespace(const char *str)
size_t len;
if (zstr(sp)) {
- return (char *) sp;
+ return strdup(SWITCH_BLANK_STRING);
}
while ((*sp == 13 ) || (*sp == 10 ) || (*sp == 9 ) || (*sp == 32) || (*sp == 11) ) {
@@ -820,7 +820,7 @@ SWITCH_DECLARE(char *) switch_strip_whitespace(const char *str)
}
if (zstr(sp)) {
- return (char *) sp;
+ return strdup(SWITCH_BLANK_STRING);
}
s = strdup(sp);
@@ -829,7 +829,7 @@ SWITCH_DECLARE(char *) switch_strip_whitespace(const char *str)
if ((len = strlen(s)) > 0) {
p = s + (len - 1);
- while (p > s && ((*p == 13 ) || (*p == 10 ) || (*p == 9 ) || (*p == 32) || (*p == 11))) {
+ while ((p >= s) && ((*p == 13 ) || (*p == 10 ) || (*p == 9 ) || (*p == 32) || (*p == 11))) {
*p-- = '\0';
}
}
@@ -844,7 +844,7 @@ SWITCH_DECLARE(char *) switch_strip_spaces(char *str, switch_bool_t dup)
size_t len;
if (zstr(sp)) {
- return sp;
+ return dup ? strdup(SWITCH_BLANK_STRING) : sp;
}
while (*sp == ' ') {
@@ -865,7 +865,7 @@ SWITCH_DECLARE(char *) switch_strip_spaces(char *str, switch_bool_t dup)
if ((len = strlen(s)) > 0) {
p = s + (len - 1);
- while (p && *p && p > s && *p == ' ') {
+ while (p && *p && (p >= s) && *p == ' ') {
*p-- = '\0';
}
}