From c565501f555a507fa2c56eccedccdbba7a366d6d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 15 Feb 2011 16:09:48 -0600 Subject: [PATCH 1/3] tell rtp stack about what remote payload type to expect when the receiving end follows the stupid SHOULD as WONT and sends a different dynamic payload number than the one in the offer --- src/include/switch_rtp.h | 2 + src/mod/endpoints/mod_sofia/mod_sofia.h | 2 + src/mod/endpoints/mod_sofia/sofia_glue.c | 71 ++++++++++++++++++++++-- src/switch_rtp.c | 12 ++-- 4 files changed, 78 insertions(+), 9 deletions(-) diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h index 27dacc7c18..2870bba3af 100644 --- a/src/include/switch_rtp.h +++ b/src/include/switch_rtp.h @@ -437,6 +437,8 @@ SWITCH_DECLARE(void) switch_rtp_set_private(switch_rtp_t *rtp_session, void *pri */ SWITCH_DECLARE(void) switch_rtp_set_telephony_event(switch_rtp_t *rtp_session, switch_payload_t te); SWITCH_DECLARE(void) switch_rtp_set_telephony_recv_event(switch_rtp_t *rtp_session, switch_payload_t te); +SWITCH_DECLARE(void) switch_rtp_set_recv_pt(switch_rtp_t *rtp_session, switch_payload_t pt); + /*! \brief Set the payload type for comfort noise \param rtp_session the RTP session to modify diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 12148c0f1b..da92746319 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -587,6 +587,8 @@ struct private_object { sofia_private_t *sofia_private; uint8_t flags[TFLAG_MAX]; switch_payload_t agreed_pt; + switch_payload_t audio_recv_pt; + switch_payload_t video_recv_pt; switch_core_session_t *session; switch_channel_t *channel; switch_frame_t read_frame; diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index a0b7fca2ff..b2185a2f15 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -3234,6 +3234,11 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f switch_rtp_set_telephony_recv_event(tech_pvt->rtp_session, tech_pvt->recv_te); } + if (tech_pvt->audio_recv_pt != tech_pvt->agreed_pt) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_CRIT, "Set audio receive payload to %u\n", tech_pvt->audio_recv_pt); + switch_rtp_set_recv_pt(tech_pvt->rtp_session, tech_pvt->audio_recv_pt); + } + if (sofia_test_pflag(tech_pvt->profile, PFLAG_SUPPRESS_CNG) || ((val = switch_channel_get_variable(tech_pvt->channel, "supress_cng")) && switch_true(val)) || ((val = switch_channel_get_variable(tech_pvt->channel, "suppress_cng")) && switch_true(val))) { @@ -3307,7 +3312,7 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f if ((rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_video_rtcp_port"))) { remote_rtcp_port = (switch_port_t)atoi(rport); } - + if (switch_rtp_set_remote_address (tech_pvt->video_rtp_session, tech_pvt->remote_sdp_video_ip, tech_pvt->remote_sdp_video_port, remote_rtcp_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { @@ -3412,6 +3417,13 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f switch_rtp_set_ssrc(tech_pvt->video_rtp_session, ssrc_ul); } + + if (tech_pvt->video_recv_pt != tech_pvt->video_agreed_pt) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, + "Set video receive payload to %u\n", tech_pvt->video_recv_pt); + switch_rtp_set_recv_pt(tech_pvt->rtp_session, tech_pvt->video_recv_pt); + } + switch_channel_set_variable_printf(tech_pvt->channel, "sip_use_video_pt", "%d", tech_pvt->video_agreed_pt); tech_pvt->video_ssrc = switch_rtp_get_ssrc(tech_pvt->rtp_session); switch_channel_set_variable_printf(tech_pvt->channel, "rtp_use_video_ssrc", "%u", tech_pvt->ssrc); @@ -4038,6 +4050,24 @@ switch_t38_options_t *sofia_glue_extract_t38_options(switch_core_session_t *sess } +switch_status_t sofia_glue_get_offered_pt(private_object_t *tech_pvt, const switch_codec_implementation_t *mimp, switch_payload_t *pt) +{ + int i = 0; + + for (i = 0; i < tech_pvt->num_codecs; i++) { + const switch_codec_implementation_t *imp = tech_pvt->codecs[i]; + + if (!strcasecmp(imp->iananame, mimp->iananame)) { + *pt = tech_pvt->ianacodes[i]; + + return SWITCH_STATUS_SUCCESS; + } + } + + return SWITCH_STATUS_FALSE; +} + + uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_sdp) { uint8_t match = 0; @@ -4554,9 +4584,17 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->remote_sdp_audio_port); switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, tech_pvt->remote_sdp_audio_ip); switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp); - + tech_pvt->audio_recv_pt = map->rm_pt; + + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { + sofia_glue_get_offered_pt(tech_pvt, mimp, &tech_pvt->audio_recv_pt); + } + + switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->audio_recv_pt); + switch_channel_set_variable(tech_pvt->channel, "sip_audio_recv_pt", tmp); + } - + if (match) { if (sofia_glue_tech_set_codec(tech_pvt, 1) == SWITCH_STATUS_SUCCESS) { got_audio = 1; @@ -4583,7 +4621,7 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s } } - + if (!match && greedy && mine < tech_pvt->num_codecs) { mine++; skip = 0; @@ -4665,6 +4703,16 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->video_agreed_pt); switch_channel_set_variable(tech_pvt->channel, "sip_video_pt", tmp); sofia_glue_check_video_codecs(tech_pvt); + + tech_pvt->video_recv_pt = map->rm_pt; + + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { + sofia_glue_get_offered_pt(tech_pvt, mimp, &tech_pvt->video_recv_pt); + } + + switch_snprintf(tmp, sizeof(tmp), "%d", tech_pvt->video_recv_pt); + switch_channel_set_variable(tech_pvt->channel, "sip_video_recv_pt", tmp); + break; } else { vmatch = 0; @@ -5164,7 +5212,7 @@ static int recover_callback(void *pArg, int argc, char **argv, char **columnName if ((tmp = switch_channel_get_variable(channel, "sip_use_pt"))) { tech_pvt->pt = tech_pvt->agreed_pt = (switch_payload_t)atoi(tmp); } - + sofia_glue_tech_set_codec(tech_pvt, 1); tech_pvt->adv_sdp_audio_ip = tech_pvt->extrtpip = (char *) ip; @@ -5219,6 +5267,19 @@ static int recover_callback(void *pArg, int argc, char **argv, char **columnName switch_xml_free(xml); return 0; } + + if (switch_rtp_ready(tech_pvt->rtp_session)) { + if ((tmp = switch_channel_get_variable(channel, "sip_audio_recv_pt"))) { + switch_rtp_set_recv_pt(tech_pvt->rtp_session, atoi(tmp)); + } + } + + if (switch_rtp_ready(tech_pvt->video_rtp_session)) { + if ((tmp = switch_channel_get_variable(channel, "sip_video_recv_pt"))) { + switch_rtp_set_recv_pt(tech_pvt->rtp_session, atoi(tmp)); + } + } + } if (switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE)) { diff --git a/src/switch_rtp.c b/src/switch_rtp.c index faa79e35a2..ffc41a73c6 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -1578,7 +1578,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session rtp_session->recv_msg.header.cc = 0; rtp_session->payload = payload; - + rtp_session->rpayload = payload; rtp_session->rtcp_send_msg.header.version = 2; rtp_session->rtcp_send_msg.header.p = 0; @@ -1773,6 +1773,12 @@ SWITCH_DECLARE(void) switch_rtp_set_telephony_recv_event(switch_rtp_t *rtp_sessi } } +SWITCH_DECLARE(void) switch_rtp_set_recv_pt(switch_rtp_t *rtp_session, switch_payload_t pt) +{ + rtp_session->rpayload = pt; +} + + SWITCH_DECLARE(void) switch_rtp_set_cng_pt(switch_rtp_t *rtp_session, switch_payload_t pt) { rtp_session->cng_pt = pt; @@ -2813,7 +2819,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ rtp_session->recv_msg.header.pt != 13 && rtp_session->recv_msg.header.pt != rtp_session->recv_te && (!rtp_session->cng_pt || rtp_session->recv_msg.header.pt != rtp_session->cng_pt) && - rtp_session->recv_msg.header.pt != rtp_session->payload) { + rtp_session->recv_msg.header.pt != rtp_session->rpayload) { /* drop frames of incorrect payload number and return CNG frame instead */ return_cng_frame(); } @@ -3131,8 +3137,6 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ rtp_session->recv_msg.header.pt = 97; } - rtp_session->rpayload = (switch_payload_t) rtp_session->recv_msg.header.pt; - break; do_continue: From b7fd81de33a28c95cb935cc57429081b6c5a5f41 Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 15 Feb 2011 16:30:57 -0600 Subject: [PATCH 2/3] rip off the fs_ args on message like we do in SEND_MESSAGE --- src/mod/endpoints/mod_sofia/sofia_presence.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 2313cb7a1a..3755894cb8 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -80,6 +80,7 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co char *ffrom = NULL; nua_handle_t *msg_nh; char *contact = NULL; + char *p; char *dup = NULL; switch_status_t status = SWITCH_STATUS_FALSE; const char *ct = "text/html"; @@ -239,8 +240,12 @@ switch_status_t sofia_presence_chat_send(const char *proto, const char *from, co status = SWITCH_STATUS_SUCCESS; - /* if this cries, add contact here too, change the 1 to 0 and omit the safe_free */ + if ((p = strstr(contact, ";fs_"))) { + *p = '\0'; + } + /* 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)), From 4f93ea25ece53df029e6dc6c913ad7c190df22d5 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 15 Feb 2011 17:43:13 -0600 Subject: [PATCH 3/3] allow uuid bridge on unaswered channels as long as there is media available on at least one --- src/switch_ivr_bridge.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 6f84de3893..f130625a75 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -1398,8 +1398,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu return SWITCH_STATUS_FALSE; } - if (!switch_channel_test_flag(originator_channel, CF_ANSWERED)) { - if (switch_channel_test_flag(originatee_channel, CF_ANSWERED)) { + //if (!switch_channel_test_flag(originator_channel, CF_ANSWERED)) { + if (!switch_channel_media_ready(originator_channel)) { + if (switch_channel_media_ready(originatee_channel)) { + //if (switch_channel_test_flag(originatee_channel, CF_ANSWERED)) { swap_session = originator_session; originator_session = originatee_session; originatee_session = swap_session;