From 52bf0423e2231e7e16126baa13b8fef14132ac57 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 1 Feb 2011 11:23:32 -0600 Subject: [PATCH 1/8] try to fix SOA problem with early and answer audio with dissimilar sdp --- src/mod/endpoints/mod_sofia/mod_sofia.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 6c91ce1274..8bceb3bba5 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -707,11 +707,20 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) cid = generate_pai_str(tech_pvt); - if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) && tech_pvt->early_sdp && strcmp(tech_pvt->early_sdp, tech_pvt->local_sdp_str)) { - /* The SIP RFC for SOA forbids sending a 183 with one sdp then a 200 with another but it won't do us much good unless - we do so in this case we will abandon the SOA rules and go rogue. - */ - sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA); + if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) && tech_pvt->early_sdp) { + char *a, *b; + + /* start at the s= line to avoid some devices who update the o= between messages */ + a = strstr(tech_pvt->early_sdp, "s="); + b = strstr(tech_pvt->local_sdp_str, "s="); + + if (!a || !b || strcmp(a, b)) { + + /* The SIP RFC for SOA forbids sending a 183 with one sdp then a 200 with another but it won't do us much good unless + we do so in this case we will abandon the SOA rules and go rogue. + */ + sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA); + } } if (sofia_use_soa(tech_pvt)) { From 45b3adda57a9281d0dd4389884d2a42eebc7dbba Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 1 Feb 2011 11:43:02 -0600 Subject: [PATCH 2/8] revert 02d1af647bac6b937de02608d53ea1831f51b968 --- src/mod/endpoints/mod_loopback/mod_loopback.c | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index aa57668718..f875f6b804 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -77,11 +77,11 @@ struct private_object { switch_frame_t cng_frame; unsigned char cng_databuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; + switch_timer_t timer; switch_caller_profile_t *caller_profile; int32_t bowout_frame_count; char *other_uuid; switch_queue_t *frame_queue; - switch_codec_implementation_t read_impl; }; typedef struct private_object private_t; @@ -111,6 +111,7 @@ static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *ses int interval = 20; switch_status_t status = SWITCH_STATUS_SUCCESS; switch_channel_t *channel = switch_core_session_get_channel(session); + const switch_codec_implementation_t *read_impl; if (codec) { iananame = codec->implementation->iananame; @@ -165,7 +166,15 @@ static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *ses switch_core_session_set_read_codec(session, &tech_pvt->read_codec); switch_core_session_set_write_codec(session, &tech_pvt->write_codec); - tech_pvt->read_impl = *tech_pvt->read_codec.implementation; + if (tech_pvt->flag_mutex) { + switch_core_timer_destroy(&tech_pvt->timer); + } + + read_impl = tech_pvt->read_codec.implementation; + + switch_core_timer_init(&tech_pvt->timer, "soft", + read_impl->microseconds_per_packet / 1000, read_impl->samples_per_packet * 4, switch_core_session_get_pool(session)); + if (!tech_pvt->flag_mutex) { switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); @@ -367,6 +376,7 @@ static switch_status_t channel_on_destroy(switch_core_session_t *session) tech_pvt = switch_core_session_get_private(session); if (tech_pvt) { + switch_core_timer_destroy(&tech_pvt->timer); if (switch_core_codec_ready(&tech_pvt->read_codec)) { switch_core_codec_destroy(&tech_pvt->read_codec); @@ -558,10 +568,12 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch goto end; } + switch_core_timer_next(&tech_pvt->timer); + mutex = tech_pvt->mutex; + switch_mutex_lock(mutex); - - if (switch_queue_pop_timeout(tech_pvt->frame_queue, &pop, tech_pvt->read_impl.microseconds_per_packet) == SWITCH_STATUS_SUCCESS && pop) { + if (switch_queue_trypop(tech_pvt->frame_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) { if (tech_pvt->write_frame) { switch_frame_free(&tech_pvt->write_frame); } @@ -573,8 +585,6 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch switch_set_flag(tech_pvt, TFLAG_CNG); } - switch_mutex_lock(mutex); - if (switch_test_flag(tech_pvt, TFLAG_CNG)) { unsigned char data[SWITCH_RECOMMENDED_BUFFER_SIZE]; uint32_t flag = 0; @@ -765,6 +775,8 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s switch_frame_free(&frame); } + switch_core_timer_sync(&tech_pvt->timer); + } break; default: From 2404dd295aa0b6ef2e9da1598a4b3d479ee6317f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 1 Feb 2011 11:46:15 -0600 Subject: [PATCH 3/8] try another approach to previous mod_loopback fix ... FS-3011 --- src/mod/endpoints/mod_loopback/mod_loopback.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index f875f6b804..727de27138 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -608,9 +608,9 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch if (encode_status != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); } - + } else { + switch_set_flag((&tech_pvt->cng_frame), SFF_CNG); } - //switch_set_flag((&tech_pvt->cng_frame), SFF_CNG); switch_clear_flag_locked(tech_pvt, TFLAG_CNG); } @@ -642,7 +642,10 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc tech_pvt = switch_core_session_get_private(session); switch_assert(tech_pvt != NULL); - if (switch_test_flag(frame, SFF_CNG) || switch_test_flag(tech_pvt, TFLAG_CNG) || (switch_test_flag(tech_pvt, TFLAG_BOWOUT) && switch_test_flag(tech_pvt, TFLAG_BOWOUT_USED))) { + if (switch_test_flag(frame, SFF_CNG) || + switch_test_flag(tech_pvt, TFLAG_CNG) || (switch_test_flag(tech_pvt, TFLAG_BOWOUT) && switch_test_flag(tech_pvt, TFLAG_BOWOUT_USED))) { + switch_core_timer_sync(&tech_pvt->timer); + switch_core_timer_sync(&tech_pvt->other_tech_pvt->timer); return SWITCH_STATUS_SUCCESS; } From d72cde9b76a856cf002366300bea02c26db44ffb Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 1 Feb 2011 13:39:36 -0600 Subject: [PATCH 4/8] only execute execute_on_[answer|media|ring] async when its expressed in app::arg form vs 'app arg form' --- src/switch_channel.c | 47 +++++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/src/switch_channel.c b/src/switch_channel.c index de472a91d5..70b1879274 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -2595,14 +2595,15 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_ring_ready_value(swi if (var) { char *arg = NULL; app = switch_core_session_strdup(channel->session, var); - if ((arg = strchr(app, ' '))) { - *arg++ = '\0'; - } - if (switch_core_session_in_thread(channel->session)) { - switch_core_session_execute_application(channel->session, app, arg); - } else { + if (strstr(app, "::")) { switch_core_session_execute_application_async(channel->session, app, arg); + } else { + if ((arg = strchr(app, ' '))) { + *arg++ = '\0'; + } + + switch_core_session_execute_application(channel->session, app, arg); } } @@ -2653,14 +2654,16 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_pre_answered(switch_ (var = switch_channel_get_variable(channel, SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE))) && !zstr(var)) { char *arg = NULL; app = switch_core_session_strdup(channel->session, var); - if ((arg = strchr(app, ' '))) { - *arg++ = '\0'; - } - if (switch_core_session_in_thread(channel->session)) { - switch_core_session_execute_application(channel->session, app, arg); - } else { + + if (strstr(app, "::")) { switch_core_session_execute_application_async(channel->session, app, arg); + } else { + if ((arg = strchr(app, ' '))) { + *arg++ = '\0'; + } + + switch_core_session_execute_application(channel->session, app, arg); } } @@ -2825,27 +2828,17 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_answered(switch_chan (!switch_channel_test_flag(channel, CF_EARLY_MEDIA) && (var = switch_channel_get_variable(channel, SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE)))) && !zstr(var)) { char *arg = NULL; - char *colon = NULL; app = switch_core_session_strdup(channel->session, var); - arg = strchr(app, ' '); - colon = strchr(app, ':'); - if (colon && (!arg || arg > colon) && *(colon + 1) == ':') { - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "%s execute on answer: %s (BROADCAST)\n", channel->name, app); - switch_ivr_broadcast(switch_core_session_get_uuid(channel->session), app, SMF_NONE); + if (strstr(app, "::")) { + switch_core_session_execute_application_async(channel->session, app, arg); } else { - if (arg) { + if ((arg = strchr(app, ' '))) { *arg++ = '\0'; } - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "%s execute on answer: %s(%s)\n", channel->name, app, - switch_str_nil(arg)); - - if (switch_core_session_in_thread(channel->session)) { - switch_core_session_execute_application(channel->session, app, arg); - } else { - switch_core_session_execute_application_async(channel->session, app, arg); - } + + switch_core_session_execute_application(channel->session, app, arg); } } From 6a524a1d567f9e73d10d14067212bda5f67b7ffb Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Tue, 1 Feb 2011 14:54:53 -0500 Subject: [PATCH 5/8] chlog: freetdm: Fix for only checking first progress indicator for early-media flag --- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 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 0b52011d42..578677a39f 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 @@ -385,8 +385,12 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) case FTDM_CHANNEL_STATE_DIALING: case FTDM_CHANNEL_STATE_PROCEED: case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_RINGING: - if (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) { + case FTDM_CHANNEL_STATE_RINGING: + if ((cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) || + (cnStEvnt->progInd1.eh.pres && cnStEvnt->progInd1.progDesc.val == IN_PD_IBAVAIL) || + (cnStEvnt->progInd2.eh.pres && cnStEvnt->progInd2.progDesc.val == IN_PD_IBAVAIL) || + (cnStEvnt->progInd3.eh.pres && cnStEvnt->progInd3.progDesc.val == IN_PD_IBAVAIL)) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media available\n"); sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY); } else { From fb66abfab4a74055c38cdc67da83e6e0175a4a0b Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 1 Feb 2011 16:22:36 -0600 Subject: [PATCH 6/8] more loopback improvements --- src/mod/endpoints/mod_loopback/mod_loopback.c | 29 ++++--------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index 727de27138..be9b4994d6 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -82,6 +82,7 @@ struct private_object { int32_t bowout_frame_count; char *other_uuid; switch_queue_t *frame_queue; + int64_t packet_count; }; typedef struct private_object private_t; @@ -577,40 +578,22 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch if (tech_pvt->write_frame) { switch_frame_free(&tech_pvt->write_frame); } - + tech_pvt->write_frame = (switch_frame_t *) pop; tech_pvt->write_frame->codec = &tech_pvt->read_codec; *frame = tech_pvt->write_frame; + tech_pvt->packet_count++; + switch_clear_flag_locked(tech_pvt, TFLAG_CNG); + switch_clear_flag(tech_pvt->write_frame, SFF_CNG); } else { switch_set_flag(tech_pvt, TFLAG_CNG); } if (switch_test_flag(tech_pvt, TFLAG_CNG)) { - unsigned char data[SWITCH_RECOMMENDED_BUFFER_SIZE]; - uint32_t flag = 0; - switch_status_t encode_status; - uint32_t rate = tech_pvt->read_codec.implementation->actual_samples_per_second; - *frame = &tech_pvt->cng_frame; tech_pvt->cng_frame.codec = &tech_pvt->read_codec; tech_pvt->cng_frame.datalen = tech_pvt->read_codec.implementation->decoded_bytes_per_packet; - - memset(tech_pvt->cng_frame.data, 0, tech_pvt->cng_frame.datalen); - memset(&data, 0, tech_pvt->read_codec.implementation->decoded_bytes_per_packet); - - if (strcasecmp(tech_pvt->read_codec.implementation->iananame, "L16")) { - encode_status = switch_core_codec_encode(&tech_pvt->read_codec, - NULL, - data, - tech_pvt->read_codec.implementation->decoded_bytes_per_packet, - tech_pvt->read_codec.implementation->actual_samples_per_second, - tech_pvt->cng_frame.data, &tech_pvt->cng_frame.datalen, &rate, &flag); - if (encode_status != SWITCH_STATUS_SUCCESS) { - switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); - } - } else { - switch_set_flag((&tech_pvt->cng_frame), SFF_CNG); - } + switch_set_flag((&tech_pvt->cng_frame), SFF_CNG); switch_clear_flag_locked(tech_pvt, TFLAG_CNG); } From 43dd776c3616f3735bd8b73d965f81e9d16dab79 Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 1 Feb 2011 16:35:53 -0600 Subject: [PATCH 7/8] sigh --- libs/openzap/mod_openzap/mod_openzap.c | 30 ++++++++++++++------------ 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/libs/openzap/mod_openzap/mod_openzap.c b/libs/openzap/mod_openzap/mod_openzap.c index 3e5227ea90..d52149c657 100644 --- a/libs/openzap/mod_openzap/mod_openzap.c +++ b/libs/openzap/mod_openzap/mod_openzap.c @@ -135,7 +135,9 @@ void dump_chan_xml(zap_span_t *span, uint32_t chan_id, switch_stream_handle_t *s static void zap_set_npi(const char *npi_string, uint8_t *target) { - if (!strcasecmp(npi_string, "isdn") || !strcasecmp(npi_string, "e164")) { + if (switch_is_number(npi_string)) { + *target = (uint8_t)atoi(npi_string); + } else if (!strcasecmp(npi_string, "isdn") || !strcasecmp(npi_string, "e164")) { *target = ZAP_NPI_ISDN; } else if (!strcasecmp(npi_string, "data")) { *target = ZAP_NPI_DATA; @@ -157,7 +159,9 @@ static void zap_set_npi(const char *npi_string, uint8_t *target) static void zap_set_ton(const char *ton_string, uint8_t *target) { - if (!strcasecmp(ton_string, "national")) { + if (switch_is_number(ton_string)) { + *target = (uint8_t)atoi(ton_string); + } else if (!strcasecmp(ton_string, "national")) { *target = ZAP_TON_NATIONAL; } else if (!strcasecmp(ton_string, "international")) { *target = ZAP_TON_INTERNATIONAL; @@ -1231,15 +1235,8 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi } if ((var = switch_event_get_header(var_event, "openzap_outbound_ton")) || (var = switch_core_get_variable("openzap_outbound_ton"))) { - if (!strcasecmp(var, "national")) { - caller_data.ani.type = ZAP_TON_NATIONAL; - } else if (!strcasecmp(var, "international")) { - caller_data.ani.type = ZAP_TON_INTERNATIONAL; - } else if (!strcasecmp(var, "local")) { - caller_data.ani.type = ZAP_TON_SUBSCRIBER_NUMBER; - } else if (!strcasecmp(var, "unknown")) { - caller_data.ani.type = ZAP_TON_UNKNOWN; - } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting TON to: %s\n", var); + zap_set_ton(var, &caller_data.ani.type); } else { caller_data.ani.type = outbound_profile->destination_number_ton; } @@ -1248,9 +1245,14 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi zap_set_string((char *)caller_data.raw_data, var); caller_data.raw_data_len = strlen(var); } - - caller_data.ani.plan = outbound_profile->destination_number_numplan; - + + if ((var = switch_event_get_header(var_event, "openzap_outbound_npi")) || (var = switch_core_get_variable("openzap_outbound_npi"))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting NPI to: %s\n", var); + zap_set_npi(var, &caller_data.ani.plan); + } else { + caller_data.ani.plan = outbound_profile->destination_number_numplan; + } + /* blindly copy data from outbound_profile. They will be overwritten * by calling zap_caller_data if needed after */ caller_data.cid_num.type = outbound_profile->caller_ton; From 10d696ebacedde5416e99f03911c928eea8889d1 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 2 Feb 2011 00:01:38 -0500 Subject: [PATCH 8/8] Added conference UUID to xml_list --- src/mod/applications/mod_conference/mod_conference.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 12b3193363..961a140342 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -3778,6 +3778,7 @@ static void conference_xlist(conference_obj_t *conference, switch_xml_t x_confer switch_xml_set_attr_d(x_conference, "member-count", ival); switch_snprintf(i, sizeof(i), "%u", conference->rate); switch_xml_set_attr_d(x_conference, "rate", ival); + switch_xml_set_attr_d(x_conference, "uuid", conference->uuid_str); if (switch_test_flag(conference, CFLAG_LOCKED)) { switch_xml_set_attr_d(x_conference, "locked", "true");