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'; } }