From 90b0718d5e3248413ac2a74b8bc7d81b3e925dfe Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Thu, 2 Dec 2010 12:21:38 -0500 Subject: [PATCH 1/7] freetdm: fix for TON/NPI not set to default if not available from core --- .../ftmod_sangoma_isdn_support.c | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c index 42bcd1e20a..636e788fc0 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c @@ -394,10 +394,19 @@ ftdm_status_t set_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb) cgPtyNmb->presInd0.val = caller_data->pres; cgPtyNmb->nmbPlanId.pres = PRSNT_NODEF; - cgPtyNmb->nmbPlanId.val = caller_data->cid_num.plan; + if (caller_data->cid_num.plan >= FTDM_NPI_INVALID) { + cgPtyNmb->nmbPlanId.val = FTDM_NPI_UNKNOWN; + } else { + cgPtyNmb->nmbPlanId.val = caller_data->cid_num.plan; + } cgPtyNmb->typeNmb1.pres = PRSNT_NODEF; - cgPtyNmb->typeNmb1.val = caller_data->cid_num.type; + + if (caller_data->cid_num.type >= FTDM_TON_INVALID) { + cgPtyNmb->typeNmb1.val = FTDM_TON_UNKNOWN; + } else { + cgPtyNmb->typeNmb1.val = caller_data->cid_num.type; + } cgPtyNmb->nmbDigits.pres = PRSNT_NODEF; cgPtyNmb->nmbDigits.len = len; @@ -418,14 +427,14 @@ ftdm_status_t set_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb) cdPtyNmb->eh.pres = PRSNT_NODEF; cdPtyNmb->nmbPlanId.pres = PRSNT_NODEF; - if (caller_data->dnis.plan == FTDM_NPI_INVALID) { + if (caller_data->dnis.plan >= FTDM_NPI_INVALID) { cdPtyNmb->nmbPlanId.val = FTDM_NPI_UNKNOWN; } else { cdPtyNmb->nmbPlanId.val = caller_data->dnis.plan; } cdPtyNmb->typeNmb0.pres = PRSNT_NODEF; - if (caller_data->dnis.type == FTDM_TON_INVALID) { + if (caller_data->dnis.type >= FTDM_TON_INVALID) { cdPtyNmb->typeNmb0.val = FTDM_TON_UNKNOWN; } else { cdPtyNmb->typeNmb0.val = caller_data->dnis.type; @@ -450,14 +459,14 @@ ftdm_status_t set_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb) redirNmb->eh.pres = PRSNT_NODEF; redirNmb->nmbPlanId.pres = PRSNT_NODEF; - if (caller_data->rdnis.plan == FTDM_NPI_INVALID) { + if (caller_data->rdnis.plan >= FTDM_NPI_INVALID) { redirNmb->nmbPlanId.val = FTDM_NPI_UNKNOWN; } else { redirNmb->nmbPlanId.val = caller_data->rdnis.plan; } redirNmb->typeNmb.pres = PRSNT_NODEF; - if (caller_data->rdnis.type == FTDM_TON_INVALID) { + if (caller_data->rdnis.type >= FTDM_TON_INVALID) { redirNmb->typeNmb.val = FTDM_TON_UNKNOWN; } else { redirNmb->typeNmb.val = caller_data->rdnis.type; From 60ab93e36c95d28530434810962ef8b102c8691c Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Thu, 2 Dec 2010 14:25:23 -0500 Subject: [PATCH 2/7] freetdm: Fix for TON/NPI from default_caller_data ignored --- libs/freetdm/src/ftdm_io.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 3dd1aa9ece..c0e45853d3 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -314,43 +314,43 @@ static ftdm_status_t ftdm_set_caller_data(ftdm_span_t *span, ftdm_caller_data_t return FTDM_FAIL; } - if (caller_data->dnis.plan == FTDM_NPI_INVALID) { + if (caller_data->dnis.plan >= FTDM_NPI_INVALID) { caller_data->dnis.plan = span->default_caller_data.dnis.plan; } - if (caller_data->dnis.type == FTDM_TON_INVALID) { + if (caller_data->dnis.type >= FTDM_TON_INVALID) { caller_data->dnis.type = span->default_caller_data.dnis.type; } - if (caller_data->cid_num.plan == FTDM_NPI_INVALID) { + if (caller_data->cid_num.plan >= FTDM_NPI_INVALID) { caller_data->cid_num.plan = span->default_caller_data.cid_num.plan; } - if (caller_data->cid_num.type == FTDM_TON_INVALID) { + if (caller_data->cid_num.type >= FTDM_TON_INVALID) { caller_data->cid_num.type = span->default_caller_data.cid_num.type; } - if (caller_data->ani.plan == FTDM_NPI_INVALID) { + if (caller_data->ani.plan >= FTDM_NPI_INVALID) { caller_data->ani.plan = span->default_caller_data.ani.plan; } - if (caller_data->ani.type == FTDM_TON_INVALID) { + if (caller_data->ani.type >= FTDM_TON_INVALID) { caller_data->ani.type = span->default_caller_data.ani.type; } - if (caller_data->rdnis.plan == FTDM_NPI_INVALID) { + if (caller_data->rdnis.plan >= FTDM_NPI_INVALID) { caller_data->rdnis.plan = span->default_caller_data.rdnis.plan; } - if (caller_data->rdnis.type == FTDM_NPI_INVALID) { + if (caller_data->rdnis.type >= FTDM_NPI_INVALID) { caller_data->rdnis.type = span->default_caller_data.rdnis.type; } - if (caller_data->bearer_capability == FTDM_INVALID_INT_PARM) { + if (caller_data->bearer_capability >= FTDM_INVALID_INT_PARM) { caller_data->bearer_capability = span->default_caller_data.bearer_capability; } - if (caller_data->bearer_layer1 == FTDM_INVALID_INT_PARM) { + if (caller_data->bearer_layer1 >= FTDM_INVALID_INT_PARM) { caller_data->bearer_layer1 = span->default_caller_data.bearer_layer1; } From 2673bb77a0f4e4c2336e038a41f622a7af0f0bd8 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Thu, 2 Dec 2010 14:26:11 -0500 Subject: [PATCH 3/7] freetdm: ISDN - Cause value only evaluated on switchtype=5ESS --- .../ftmod_sangoma_isdn_stack_hndl.c | 71 ++++++++++++------- 1 file changed, 45 insertions(+), 26 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c index d557ca3ba0..ab29b3e74b 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c @@ -33,6 +33,7 @@ */ #include "ftmod_sangoma_isdn.h" +ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn); /* Remote side transmit a SETUP */ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) @@ -352,33 +353,15 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) case MI_ALERTING: get_prog_ind_ie(ftdmchan, &cnStEvnt->progInd); - if (signal_data->ignore_cause_value != SNGISDN_OPT_TRUE && - cnStEvnt->causeDgn[0].eh.pres && cnStEvnt->causeDgn[0].causeVal.pres) { - - switch(cnStEvnt->causeDgn[0].causeVal.val) { - case 17: /* User Busy */ - case 18: /* No User responding */ - case 19: /* User alerting, no answer */ - case 21: /* Call rejected, the called party does not with to accept this call */ - case 27: /* Destination out of order */ - case 31: /* Normal, unspecified */ - case 34: /* Circuit/Channel congestion */ - case 41: /* Temporary failure */ - case 42: /* Switching equipment is experiencing a period of high traffic */ - case 47: /* Resource unavailable */ - case 58: /* Bearer Capability not available */ - case 63: /* Service or option not available */ - case 65: /* Bearer Cap not implemented, not supported */ - case 79: /* Service or option not implemented, unspecified */ - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Cause requires disconnect (cause:%d)\n", cnStEvnt->causeDgn[0].causeVal.val); - ftdmchan->caller_data.hangup_cause = cnStEvnt->causeDgn[0].causeVal.val; + if (sngisdn_cause_val_requires_disconnect(ftdmchan, &cnStEvnt->causeDgn[0]) == FTDM_SUCCESS) { + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Cause requires disconnect (cause:%d)\n", cnStEvnt->causeDgn[0].causeVal.val); + ftdmchan->caller_data.hangup_cause = cnStEvnt->causeDgn[0].causeVal.val; - sngisdn_set_flag(sngisdn_info, FLAG_SEND_DISC); - ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - goto sngisdn_process_cnst_ind_end; - } + sngisdn_set_flag(sngisdn_info, FLAG_SEND_DISC); + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); + goto sngisdn_process_cnst_ind_end; } - + switch(ftdmchan->state) { case FTDM_CHANNEL_STATE_DIALING: case FTDM_CHANNEL_STATE_PROCEED: @@ -1119,8 +1102,44 @@ void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event) (evntType == IN_LNK_DWN)?"LNK_DOWN": (evntType == IN_LNK_UP)?"LNK_UP": (evntType == IN_INDCHAN)?"b-channel": - (evntType == IN_LNK_DWN_DM_RLS)?"Nfas service procedures": + (evntType == IN_LNK_DWN_DM_RLS)?"NFAS service procedures": (evntType == IN_SWCHD_BU_DCHAN)?"NFAS switchover to backup":"Unknown"); ISDN_FUNC_TRACE_EXIT(__FUNCTION__); return; } + +ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn) +{ + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; + + if (signal_data->ignore_cause_value == SNGISDN_OPT_TRUE) { + return FTDM_FAIL; + } + + /* By default, we only evaluate cause value on 5ESS switches */ + if (signal_data->ignore_cause_value == SNGISDN_OPT_DEFAULT && + signal_data->switchtype != SNGISDN_SWITCH_5ESS) { + + return FTDM_FAIL; + } + + /* ignore_cause_value = SNGISDN_OPT_FALSE or switchtype == 5ESS */ + switch(causeDgn->causeVal.val) { + case 17: /* User Busy */ + case 18: /* No User responding */ + case 19: /* User alerting, no answer */ + case 21: /* Call rejected, the called party does not with to accept this call */ + case 27: /* Destination out of order */ + case 31: /* Normal, unspecified */ + case 34: /* Circuit/Channel congestion */ + case 41: /* Temporary failure */ + case 42: /* Switching equipment is experiencing a period of high traffic */ + case 47: /* Resource unavailable */ + case 58: /* Bearer Capability not available */ + case 63: /* Service or option not available */ + case 65: /* Bearer Cap not implemented, not supported */ + case 79: /* Service or option not implemented, unspecified */ + return FTDM_SUCCESS; + } + return FTDM_FAIL; +} From e0048ed24e7eee9cbfd07b7a9afc1d97941cd270 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Thu, 2 Dec 2010 16:43:27 -0500 Subject: [PATCH 4/7] freetdm: OPENZAP-120 - Allow FXO to bridge calls without digits --- libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c index 99d256655a..95002e3e70 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c +++ b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c @@ -341,8 +341,8 @@ static void send_caller_id(ftdm_channel_t *ftdmchan) static void analog_dial(ftdm_channel_t *ftdmchan, uint32_t *state_counter, uint32_t *dial_timeout) { if (ftdm_strlen_zero(ftdmchan->caller_data.dnis.digits)) { - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "No Digits to send!\n"); - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY); + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No digits to send, moving to UP!\n"); + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP); } else { if (ftdm_channel_command(ftdmchan, FTDM_COMMAND_SEND_DTMF, ftdmchan->caller_data.dnis.digits) != FTDM_SUCCESS) { ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Send Digits Failed [%s]\n", ftdmchan->last_error); From 59ea4a1b9cf788f20166708ea02c33568acf93bd Mon Sep 17 00:00:00 2001 From: Brian West Date: Thu, 2 Dec 2010 16:52:23 -0600 Subject: [PATCH 5/7] FS-2886: wrong IP in VIA and contact HEADER for MESSAGE method while fs run in private network --- src/mod/endpoints/mod_sofia/sofia_presence.c | 79 +++++++++++++++++++- 1 file changed, 76 insertions(+), 3 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 5c2517db61..143666ceb8 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -86,6 +86,10 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co char *to_uri = NULL; switch_console_callback_match_t *list = NULL; switch_console_callback_match_node_t *m; + char *remote_ip = NULL; + char *user_via = NULL; + char *contact_str = NULL; + char *dup_dest = NULL; if (!to) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing To: header.\n"); @@ -181,12 +185,80 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co /* sofia_glue is running sofia_overcome_sip_uri_weakness we do not, not sure if it matters */ + remote_ip = malloc(sizeof(80)); + dup_dest = strdup(dst->contact); + + if (switch_stristr("fs_path", dst->contact)) { + char *remote_host = NULL; + const char *s; + + if ((s = switch_stristr("fs_path=", dst->contact))) { + s += 8; + } + if (s) { + remote_host = strdup(s); + switch_url_decode(remote_host); + } + if (!zstr(remote_host)) { + switch_split_user_domain(remote_host, NULL, &remote_ip); + } + switch_safe_free(remote_host); + } + + if (zstr(remote_ip)) { + switch_split_user_domain(dup_dest, NULL, &remote_ip); + } + + if (!zstr(remote_ip) && sofia_glue_check_nat(profile, remote_ip)) { + char *ptr = NULL; + const char *transport_str = NULL; + if ((ptr = sofia_glue_find_parameter(dst->contact, "transport="))) { + sofia_transport_t transport = sofia_glue_str2transport(ptr); + transport_str = sofia_glue_transport2str(transport); + switch (transport) { + case SOFIA_TRANSPORT_TCP: + contact_str = profile->tcp_public_contact; + break; + case SOFIA_TRANSPORT_TCP_TLS: + contact_str = profile->tls_public_contact; + break; + default: + contact_str = profile->public_url; + break; + } + user_via = sofia_glue_create_external_via(NULL, profile, transport); + } else { + user_via = sofia_glue_create_external_via(NULL, profile, SOFIA_TRANSPORT_UDP); + contact_str = profile->public_url; + } + } else { + contact_str = profile->url; + } + + switch_safe_free(dup_dest); + free(remote_ip); + status = SWITCH_STATUS_SUCCESS; + /* if this cries, add contact here too, change the 1 to 0 and omit the safe_free */ - msg_nh = nua_handle(profile->nua, NULL, TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)), - SIPTAG_FROM_STR(from), TAG_IF(contact, NUTAG_URL(contact)), SIPTAG_TO_STR(dst->to), SIPTAG_CONTACT_STR(profile->url), TAG_END()); + + msg_nh = nua_handle(profile->nua, NULL, + TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)), + TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)), + SIPTAG_FROM_STR(from), + TAG_IF(contact, NUTAG_URL(contact)), + SIPTAG_TO_STR(dst->to), + SIPTAG_CONTACT_STR(contact_str), + TAG_END()); + nua_handle_bind(msg_nh, &mod_sofia_globals.destroy_private); - nua_message(msg_nh, SIPTAG_CONTENT_TYPE_STR(ct), SIPTAG_PAYLOAD_STR(body), TAG_END()); + + nua_message(msg_nh, + TAG_IF(user_via, SIPTAG_VIA_STR(user_via)), + SIPTAG_CONTENT_TYPE_STR(ct), + SIPTAG_PAYLOAD_STR(body), + TAG_END()); + sofia_glue_free_destination(dst); } @@ -197,6 +269,7 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co switch_safe_free(contact); switch_safe_free(ffrom); switch_safe_free(dup); + if (profile) { switch_thread_rwlock_unlock(profile->rwlock); } From 8cf1501203de1481089d3576333fe10278da23fe Mon Sep 17 00:00:00 2001 From: Brian West Date: Thu, 2 Dec 2010 16:55:02 -0600 Subject: [PATCH 6/7] FS-2881: SIP-header History-Info might exist multiple times, but only last header is exposed as a channel variable --- src/mod/endpoints/mod_sofia/sofia.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index e20d868548..2e13b544d0 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -7001,6 +7001,8 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ if (tech_pvt->caller_profile) { + int first_history_info = 1; + if (rpid) { if (rpid->rpid_privacy) { if (!strcasecmp(rpid->rpid_privacy, "yes")) { @@ -7045,7 +7047,25 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ } } } else if (!strncasecmp(un->un_name, "History-Info", 12)) { - switch_channel_set_variable(channel, "sip_history_info", un->un_value); + if (first_history_info) { + /* If the header exists first time, make sure to remove old info and re-set the variable */ + switch_channel_set_variable(channel, "sip_history_info", un->un_value); + first_history_info = 0; + } else { + /* Append the History-Info into one long string */ + const char *history_var = switch_channel_get_variable(channel, "sip_history_info"); + if (!zstr(history_var)) { + char *tmp_str; + if ((tmp_str = switch_mprintf("%s, %s", history_var, un->un_value))) { + switch_channel_set_variable(channel, "sip_history_info", tmp_str); + free(tmp_str); + } else { + switch_channel_set_variable(channel, "sip_history_info", un->un_value); + } + } else { + switch_channel_set_variable(channel, "sip_history_info", un->un_value); + } + } } else if (!strcasecmp(un->un_name, "X-FS-Support")) { tech_pvt->x_freeswitch_support_remote = switch_core_session_strdup(session, un->un_value); } else if (!strncasecmp(un->un_name, "X-", 2) || !strncasecmp(un->un_name, "P-", 2)) { From 6faa4c91c32028476f5df9af271fd4c7447f2f64 Mon Sep 17 00:00:00 2001 From: Brian West Date: Thu, 2 Dec 2010 17:11:04 -0600 Subject: [PATCH 7/7] using the wrong api to remove media bug from crienzo on IRC, thanks. --- src/mod/applications/mod_spandsp/mod_spandsp_dsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_dsp.c b/src/mod/applications/mod_spandsp/mod_spandsp_dsp.c index 005924194f..f576b7dd01 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp_dsp.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp_dsp.c @@ -495,7 +495,7 @@ switch_status_t callprogress_detector_stop(switch_core_session_t *session) switch_channel_t *channel = switch_core_session_get_channel(session); switch_media_bug_t *bug = switch_channel_get_private(channel, TONE_PRIVATE); if (bug) { - switch_core_media_bug_close(&bug); + switch_core_media_bug_remove(session, &bug); switch_channel_set_private(channel, TONE_PRIVATE, NULL); } return SWITCH_STATUS_SUCCESS;