From 48554d1a851b9907e3b5321a747b860da26b9305 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 21 Dec 2012 21:30:14 -0600 Subject: [PATCH] compiles --- src/include/switch_core_media.h | 18 +- src/include/switch_types.h | 1 + src/mod/endpoints/mod_sofia/mod_sofia.h | 17 +- src/mod/endpoints/mod_sofia/sofia.c | 104 ++-- src/mod/endpoints/mod_sofia/sofia_glue.c | 320 ++++------- src/mod/endpoints/mod_sofia/sofia_media.c | 323 +---------- src/switch_core_media.c | 644 ++++++++++++++++++++-- 7 files changed, 793 insertions(+), 634 deletions(-) diff --git a/src/include/switch_core_media.h b/src/include/switch_core_media.h index 960ab2e955..45c4c5fe85 100644 --- a/src/include/switch_core_media.h +++ b/src/include/switch_core_media.h @@ -89,7 +89,7 @@ typedef struct switch_core_media_params_s { uint32_t rtp_hold_timeout_sec; uint32_t dtmf_delay; uint32_t codec_flags; - int reinvite; + switch_core_media_NDLB_t ndlb; switch_rtp_bug_flag_t auto_rtp_bugs; @@ -127,10 +127,16 @@ typedef struct switch_core_media_params_s { char *extsipip; char *local_network; + char *sipip; + char *sdp_username; switch_mutex_t *mutex; - + + switch_payload_t te;//x:tp + switch_payload_t recv_te;//x:tp + + char *adv_sdp_audio_ip; } switch_core_media_params_t; @@ -188,6 +194,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_write_frame(switch_core_sessio SWITCH_DECLARE(int) switch_core_media_check_nat(switch_media_handle_t *smh, const char *network_ip); SWITCH_DECLARE(switch_status_t) switch_core_media_choose_port(switch_core_session_t *session, switch_media_type_t type, int force); +SWITCH_DECLARE(void) switch_core_media_check_dtmf_type(switch_core_session_t *session); +SWITCH_DECLARE(void) switch_core_media_absorb_sdp(switch_core_session_t *session); +SWITCH_DECLARE(switch_status_t) switch_core_media_proxy_remote_addr(switch_core_session_t *session, const char *sdp_str); +SWITCH_DECLARE(void) switch_core_media_deactivate_rtp(switch_core_session_t *session); +SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_session_t *session); +SWITCH_DECLARE(switch_status_t) switch_core_media_ext_address_lookup(switch_core_session_t *session, char **ip, switch_port_t *port, const char *sourceip); +SWITCH_DECLARE(switch_status_t) switch_core_media_process_t38_passthru(switch_core_session_t *session, + switch_core_session_t *other_session, switch_t38_options_t *t38_options); SWITCH_END_EXTERN_C #endif diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 52885c9a81..f13600063a 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1292,6 +1292,7 @@ typedef enum { CF_PASS_RFC2833, CF_T38_PASSTHRU, CF_DROP_DTMF, + CF_REINVITE, /* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */ /* IF YOU ADD NEW ONES CHECK IF THEY SHOULD PERSIST OR ZERO THEM IN switch_core_session.c switch_core_session_request_xml() */ CF_FLAG_MAX diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 03d10a8705..b514824638 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -195,6 +195,7 @@ typedef enum { typedef enum { PFLAG_AUTH_CALLS, PFLAG_AUTH_MESSAGES, + PFLAG_PASS_RFC2833, PFLAG_BLIND_REG, PFLAG_AUTH_ALL, PFLAG_FULL_ID, @@ -286,7 +287,6 @@ typedef enum { TFLAG_EARLY_MEDIA, TFLAG_3PCC, TFLAG_READY, - TFLAG_REINVITE, TFLAG_REFER, TFLAG_NOHUP, TFLAG_NOSDP_REINVITE, @@ -523,8 +523,15 @@ struct sofia_profile { char *shutdown_type; char *extrtpip; char *rtpip[MAX_RTPIP]; + char *jb_msec; + switch_payload_t te;//x:tp + switch_payload_t recv_te;//x:tp uint32_t rtpip_index; uint32_t rtpip_next; + char *rtcp_audio_interval_msec; + char *rtcp_video_interval_msec; + + char *sdp_username; char *sipip; char *extsipip; char *url; @@ -573,7 +580,7 @@ struct sofia_profile { switch_core_media_flag_t media_flags[SCMF_MAX]; unsigned int mflags; unsigned int ndlb; - unsigned int mdlb; + unsigned int mndlb; uint32_t max_calls; uint32_t nonce_ttl; nua_t *nua; @@ -907,8 +914,6 @@ void launch_sofia_profile_thread(sofia_profile_t *profile); switch_status_t sofia_presence_chat_send(switch_event_t *message_event); -void sofia_media_tech_absorb_sdp(private_object_t *tech_pvt); - /* * \brief Sets the "ep_codec_string" channel variable, parsing r_sdp and taing codec_string in consideration * \param channel Current channel @@ -1152,6 +1157,10 @@ void sofia_glue_fire_events(sofia_profile_t *profile); void sofia_event_fire(sofia_profile_t *profile, switch_event_t **event); void sofia_queue_message(sofia_dispatch_event_t *de); void sofia_media_set_sdp_codec_string(switch_core_session_t *session, const char *r_sdp); +int sofia_glue_check_nat(sofia_profile_t *profile, const char *network_ip); + +switch_status_t sofia_glue_ext_address_lookup(sofia_profile_t *profile, char **ip, switch_port_t *port, + const char *sourceip, switch_memory_pool_t *pool); /* For Emacs: * Local Variables: diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index ebd14049c0..91061109c6 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -665,7 +665,7 @@ void sofia_handle_sip_i_bye(switch_core_session_t *session, int status, if (sip->sip_reason && sip->sip_reason->re_protocol && (!strcasecmp(sip->sip_reason->re_protocol, "Q.850") || !strcasecmp(sip->sip_reason->re_protocol, "FreeSWITCH") - || !strcasecmp(sip->sip_reason->re_protocol, profile->username)) && sip->sip_reason->re_cause) { + || !strcasecmp(sip->sip_reason->re_protocol, profile->sdp_username)) && sip->sip_reason->re_cause) { tech_pvt->q850_cause = atoi(sip->sip_reason->re_cause); cause = tech_pvt->q850_cause; } else { @@ -3590,7 +3590,6 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) profile->mflags = MFLAG_REFER | MFLAG_REGISTER; profile->server_rport_level = 1; profile->client_rport_level = 1; - sofia_set_pflag(profile, PFLAG_STUN_ENABLED); sofia_set_pflag(profile, PFLAG_DISABLE_100REL); profile->auto_restart = 1; sofia_set_media_flag(profile, SCMF_AUTOFIX_TIMING); @@ -3622,7 +3621,6 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) profile->nat_acl_count = 0; profile->reg_acl_count = 0; profile->proxy_acl_count = 0; - sofia_set_pflag(profile, PFLAG_STUN_ENABLED); sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID); profile->ib_calls = 0; profile->ob_calls = 0; @@ -3851,12 +3849,6 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) sofia_set_flag(profile, TFLAG_INB_NOMEDIA); } else if (!strcasecmp(var, "inbound-late-negotiation") && switch_true(val)) { sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION); - } else if (!strcasecmp(var, "rtp-autoflush-during-bridge")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE); - } else { - sofia_clear_pflag(profile, PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE); - } } else if (!strcasecmp(var, "rtp-notimer-during-bridge")) { if (switch_true(val)) { sofia_set_pflag(profile, PFLAG_RTP_NOTIMER_DURING_BRIDGE); @@ -3933,7 +3925,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) profile->max_registrations_perext = atoi(val); } else if (!strcasecmp(var, "rfc2833-pt")) { profile->te = (switch_payload_t) atoi(val); - } else if (!strcasecmp(var, "cng-pt") && !sofia_test_pflag(profile, PFLAG_SUPPRESS_CNG)) { + } else if (!strcasecmp(var, "cng-pt") && !sofia_test_media_flag(profile, SCMF_SUPPRESS_CNG)) { profile->cng_pt = (switch_payload_t) atoi(val); } else if (!strcasecmp(var, "sip-port")) { if (!strcasecmp(val, "auto")) { @@ -4018,7 +4010,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } else if (!strcasecmp(val, "auto-nat")) { ip = NULL; } else if (strcasecmp(val, "auto")) { - if (sofia_glue_ext_address_lookup(profile, NULL, &myip, &profile->extsipport, val, profile->pool) == SWITCH_STATUS_SUCCESS) { + if (sofia_glue_ext_address_lookup(profile, &myip, &profile->extsipport, val, profile->pool) == SWITCH_STATUS_SUCCESS) { ip = myip; sofia_clear_pflag(profile, PFLAG_AUTO_NAT); } else { @@ -4156,7 +4148,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } } else if (!strcasecmp(var, "supress-cng") || !strcasecmp(var, "suppress-cng")) { if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_SUPPRESS_CNG); + sofia_set_media_flag(profile, SCMF_SUPPRESS_CNG); profile->cng_pt = 0; } } else if (!strcasecmp(var, "NDLB-broken-auth-hash")) { @@ -4197,12 +4189,6 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) if (switch_true(val)) { sofia_set_pflag(profile, PFLAG_PASS_RFC2833); } - } else if (!strcasecmp(var, "rtp-autoflush")) { - if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_AUTOFLUSH); - } else { - sofia_clear_pflag(profile, PFLAG_AUTOFLUSH); - } } else if (!strcasecmp(var, "rtp-autofix-timing")) { if (switch_true(val)) { sofia_set_media_flag(profile, SCMF_AUTOFIX_TIMING); @@ -4241,7 +4227,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } } else if (!strcasecmp(var, "rtp-rewrite-timestamps")) { if (switch_true(val)) { - sofia_set_pflag(profile, PFLAG_REWRITE_TIMESTAMPS); + sofia_set_media_flag(profile, SCMF_REWRITE_TIMESTAMPS); } } else if (!strcasecmp(var, "auth-calls")) { if (switch_true(val)) { @@ -4522,7 +4508,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION); } - if ((!profile->cng_pt) && (!sofia_test_pflag(profile, PFLAG_SUPPRESS_CNG))) { + if ((!profile->cng_pt) && (!sofia_test_media_flag(profile, SCMF_SUPPRESS_CNG))) { profile->cng_pt = SWITCH_RTP_CNG_PAYLOAD; } @@ -4554,8 +4540,8 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) profile->nonce_ttl = 60; } - if (!profile->username) { - profile->username = switch_core_strdup(profile->pool, "FreeSWITCH"); + if (!profile->sdp_username) { + profile->sdp_username = switch_core_strdup(profile->pool, "FreeSWITCH"); } if (!profile->rtpip[0]) { @@ -4843,7 +4829,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status if (status >= 400 && sip->sip_reason && sip->sip_reason->re_protocol && (!strcasecmp(sip->sip_reason->re_protocol, "Q.850") || !strcasecmp(sip->sip_reason->re_protocol, "FreeSWITCH") - || !strcasecmp(sip->sip_reason->re_protocol, profile->username)) && sip->sip_reason->re_cause) { + || !strcasecmp(sip->sip_reason->re_protocol, profile->sdp_username)) && sip->sip_reason->re_cause) { tech_pvt->q850_cause = atoi(sip->sip_reason->re_cause); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote Reason: %d\n", tech_pvt->q850_cause); } @@ -4861,9 +4847,9 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status caller_profile->network_addr = switch_core_strdup(caller_profile->pool, network_ip); } - tech_pvt->last_sdp_str = NULL; + tech_pvt->mparams->last_sdp_str = NULL; if (!sofia_use_soa(tech_pvt) && sip->sip_payload && sip->sip_payload->pl_data) { - tech_pvt->last_sdp_str = switch_core_session_strdup(session, sip->sip_payload->pl_data); + tech_pvt->mparams->last_sdp_str = switch_core_session_strdup(session, sip->sip_payload->pl_data); } @@ -5200,9 +5186,9 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status if (sip->sip_payload && sip->sip_payload->pl_data && sip->sip_content_type && sip->sip_content_type->c_subtype && switch_stristr("sdp", sip->sip_content_type->c_subtype)) { - tech_pvt->remote_sdp_str = switch_core_session_strdup(tech_pvt->session, sip->sip_payload->pl_data); - r_sdp = tech_pvt->remote_sdp_str; - sofia_glue_tech_proxy_remote_addr(tech_pvt, NULL); + tech_pvt->mparams->remote_sdp_str = switch_core_session_strdup(tech_pvt->session, sip->sip_payload->pl_data); + r_sdp = tech_pvt->mparams->remote_sdp_str; + switch_core_media_proxy_remote_addr(session, NULL); } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Passing %d %s to other leg\n", status, phrase); @@ -5249,7 +5235,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status if (status == 200 && sofia_test_flag(tech_pvt, TFLAG_T38_PASSTHRU) && has_t38) { if (switch_rtp_ready(tech_pvt->rtp_session) && switch_rtp_ready(other_tech_pvt->rtp_session)) { - sofia_clear_flag(tech_pvt, TFLAG_NOTIMER_DURING_BRIDGE); + switch_channel_clear_flag(tech_pvt->channel, CF_NOTIMER_DURING_BRIDGE); switch_rtp_udptl_mode(tech_pvt->rtp_session); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating T38 Passthru\n"); } @@ -5543,8 +5529,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } } - if (status > 100 && status < 300 && tech_pvt && !sofia_use_soa(tech_pvt) && !r_sdp && tech_pvt->last_sdp_str) { - r_sdp = tech_pvt->last_sdp_str; + if (status > 100 && status < 300 && tech_pvt && !sofia_use_soa(tech_pvt) && !r_sdp && tech_pvt->mparams->last_sdp_str) { + r_sdp = tech_pvt->mparams->last_sdp_str; } if ((channel && (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA))) || @@ -5591,7 +5577,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_channel_get_name(channel), nua_callstate_name(ss_state), status); goto done; } else if (switch_channel_test_flag(channel, CF_EARLY_MEDIA) && (status == 180 || status == 183) && r_sdp) { - sofia_set_flag_locked(tech_pvt, TFLAG_REINVITE); + switch_channel_set_flag(tech_pvt->channel, CF_REINVITE); } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Channel %s entering state [%s][%d]\n", @@ -5599,12 +5585,12 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (r_sdp) { - if (!(profile->mndlb & SM_NDLB_ALLOW_NONDUP_SDP) || (!zstr(tech_pvt->remote_sdp_str) && !strcmp(tech_pvt->remote_sdp_str, r_sdp))) { + if (!(profile->mndlb & SM_NDLB_ALLOW_NONDUP_SDP) || (!zstr(tech_pvt->mparams->remote_sdp_str) && !strcmp(tech_pvt->mparams->remote_sdp_str, r_sdp))) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Duplicate SDP\n%s\n", r_sdp); is_dup_sdp = 1; } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote SDP:\n%s\n", r_sdp); - tech_pvt->remote_sdp_str = switch_core_session_strdup(session, r_sdp); + tech_pvt->mparams->remote_sdp_str = switch_core_session_strdup(session, r_sdp); switch_channel_set_variable(channel, SWITCH_R_SDP_VARIABLE, r_sdp); if ((sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) || switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) { @@ -5699,7 +5685,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, sofia_set_flag_locked(tech_pvt, TFLAG_EARLY_MEDIA); switch_channel_mark_pre_answered(channel); sofia_set_flag(tech_pvt, TFLAG_SDP); - if (switch_channel_test_flag(channel, CF_PROXY_MEDIA) || sofia_test_flag(tech_pvt, TFLAG_REINVITE)) { + if (switch_channel_test_flag(channel, CF_PROXY_MEDIA) || switch_channel_test_flag(channel, CF_REINVITE)) { if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) { goto done; } @@ -5909,7 +5895,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (sofia_use_soa(tech_pvt)) { nua_respond(tech_pvt->nh, SIP_200_OK, SIPTAG_CONTACT_STR(tech_pvt->profile->url), - SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str), + SOATAG_USER_SDP_STR(tech_pvt->mparams->local_sdp_str), SOATAG_REUSE_REJECTED(1), SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"), TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), TAG_END()); @@ -5917,7 +5903,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, nua_respond(tech_pvt->nh, SIP_200_OK, NUTAG_MEDIA_ENABLE(0), SIPTAG_CONTACT_STR(tech_pvt->profile->url), - SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->local_sdp_str), TAG_END()); + SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams->local_sdp_str), TAG_END()); } } } else if (sofia_test_pflag(profile, PFLAG_3PCC_PROXY)) { @@ -6025,7 +6011,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (sofia_use_soa(tech_pvt)) { nua_respond(tech_pvt->nh, SIP_200_OK, SIPTAG_CONTACT_STR(tech_pvt->reply_contact), - SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str), + SOATAG_USER_SDP_STR(tech_pvt->mparams->local_sdp_str), SOATAG_REUSE_REJECTED(1), SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"), TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), TAG_END()); @@ -6033,7 +6019,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, nua_respond(tech_pvt->nh, SIP_200_OK, NUTAG_MEDIA_ENABLE(0), SIPTAG_CONTACT_STR(tech_pvt->reply_contact), - SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->local_sdp_str), TAG_END()); + SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams->local_sdp_str), TAG_END()); } switch_channel_set_flag(channel, CF_PROXY_MODE); @@ -6046,7 +6032,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { - if (sofia_glue_tech_proxy_remote_addr(tech_pvt, r_sdp) == SWITCH_STATUS_SUCCESS && !is_t38) { + if (switch_core_media_proxy_remote_addr(session, r_sdp) == SWITCH_STATUS_SUCCESS && !is_t38) { nua_respond(tech_pvt->nh, SIP_200_OK, TAG_END()); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio params changed, NOT proxying re-invite.\n"); switch_core_session_rwunlock(other_session); @@ -6110,7 +6096,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, goto done; } - sofia_set_flag_locked(tech_pvt, TFLAG_REINVITE); + switch_channel_set_flag(tech_pvt->channel, CF_REINVITE); if (tech_pvt->num_codecs) { match = sofia_media_negotiate_sdp(session, r_sdp); @@ -6135,7 +6121,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Processing updated SDP\n"); } else { - sofia_clear_flag_locked(tech_pvt, TFLAG_REINVITE); + switch_channel_set_flag(tech_pvt->channel, CF_REINVITE); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Reinvite Codec Error!\n"); is_ok = 0; } @@ -6150,7 +6136,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (sofia_use_soa(tech_pvt)) { nua_respond(tech_pvt->nh, SIP_200_OK, SIPTAG_CONTACT_STR(tech_pvt->reply_contact), - SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str), + SOATAG_USER_SDP_STR(tech_pvt->mparams->local_sdp_str), SOATAG_REUSE_REJECTED(1), SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"), TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), TAG_END()); @@ -6158,7 +6144,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, nua_respond(tech_pvt->nh, SIP_200_OK, NUTAG_MEDIA_ENABLE(0), SIPTAG_CONTACT_STR(tech_pvt->reply_contact), - SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->local_sdp_str), TAG_END()); + SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams->local_sdp_str), TAG_END()); } if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_REINVITE) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(session)); @@ -6174,7 +6160,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, /* sdp changed since 18X w sdp, we're supposed to ignore it but we, of course, were pressured into supporting it */ uint8_t match = 0; - sofia_set_flag_locked(tech_pvt, TFLAG_REINVITE); + switch_channel_set_flag(tech_pvt->channel, CF_REINVITE); if (tech_pvt->num_codecs) { match = sofia_media_negotiate_sdp(session, r_sdp); @@ -6186,7 +6172,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, sofia_media_set_local_sdp(tech_pvt, NULL, 0, NULL, 0); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Processing updated SDP\n"); - sofia_set_flag_locked(tech_pvt, TFLAG_REINVITE); + switch_channel_set_flag(tech_pvt->channel, CF_REINVITE); if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "RTP Error!\n"); @@ -6194,7 +6180,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, goto done; } } else { - sofia_clear_flag_locked(tech_pvt, TFLAG_REINVITE); + switch_channel_clear_flag(tech_pvt->channel, CF_REINVITE); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Error! %s\n", r_sdp); goto done; @@ -6241,13 +6227,13 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } if (match) { - sofia_set_flag_locked(tech_pvt, TFLAG_REINVITE); + switch_channel_set_flag(tech_pvt->channel, CF_REINVITE); if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "RTP Error!\n"); switch_channel_set_variable(tech_pvt->channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RTP ERROR"); is_ok = 0; } - sofia_clear_flag_locked(tech_pvt, TFLAG_REINVITE); + switch_channel_clear_flag(tech_pvt->channel, CF_REINVITE); } else { switch_channel_set_variable(tech_pvt->channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR"); is_ok = 0; @@ -6266,7 +6252,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } if (tech_pvt && nh == tech_pvt->nh2) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Cheater Reinvite!\n"); - sofia_set_flag_locked(tech_pvt, TFLAG_REINVITE); + switch_channel_set_flag(tech_pvt->channel, CF_REINVITE); tech_pvt->nh = tech_pvt->nh2; tech_pvt->nh2 = NULL; if (sofia_glue_tech_choose_port(tech_pvt, 0) == SWITCH_STATUS_SUCCESS) { @@ -7805,8 +7791,8 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia - tech_pvt->remote_ip = switch_core_session_strdup(session, network_ip); - tech_pvt->remote_port = network_port; + tech_pvt->mparams->remote_ip = switch_core_session_strdup(session, network_ip); + tech_pvt->mparams->remote_port = network_port; channel = tech_pvt->channel = switch_core_session_get_channel(session); @@ -7827,7 +7813,7 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia if (sip->sip_contact && sip->sip_contact->m_url) { char tmp[35] = ""; - const char *ipv6 = strchr(tech_pvt->remote_ip, ':'); + const char *ipv6 = strchr(tech_pvt->mparams->remote_ip, ':'); transport = sofia_glue_url2transport(sip->sip_contact->m_url); @@ -7835,10 +7821,10 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia switch_core_session_sprintf(session, "sip:%s@%s%s%s:%d;transport=%s", sip->sip_contact->m_url->url_user, - ipv6 ? "[" : "", tech_pvt->remote_ip, ipv6 ? "]" : "", tech_pvt->remote_port, sofia_glue_transport2str(transport)); + ipv6 ? "[" : "", tech_pvt->mparams->remote_ip, ipv6 ? "]" : "", tech_pvt->mparams->remote_port, sofia_glue_transport2str(transport)); - switch_channel_set_variable(channel, "sip_received_ip", tech_pvt->remote_ip); - snprintf(tmp, sizeof(tmp), "%d", tech_pvt->remote_port); + switch_channel_set_variable(channel, "sip_received_ip", tech_pvt->mparams->remote_ip); + snprintf(tmp, sizeof(tmp), "%d", tech_pvt->mparams->remote_port); switch_channel_set_variable(channel, "sip_received_port", tmp); } @@ -8039,7 +8025,7 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia "sip:%s@%s%s%s:%d;transport=%s", user, ipv6 ? "[" : "", host, ipv6 ? "]" : "", port, sofia_glue_transport2str(transport)); - if (sofia_glue_check_nat(profile, tech_pvt->remote_ip)) { + if (sofia_glue_check_nat(profile, tech_pvt->mparams->remote_ip)) { url = (sofia_glue_transport_has_tls(transport)) ? profile->tls_public_url : profile->public_url; check_nat = 1; } else { @@ -8079,7 +8065,7 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia } else { const char *url = NULL; - if (sofia_glue_check_nat(profile, tech_pvt->remote_ip)) { + if (sofia_glue_check_nat(profile, tech_pvt->mparams->remote_ip)) { url = (sofia_glue_transport_has_tls(transport)) ? profile->tls_public_url : profile->public_url; } else { url = (sofia_glue_transport_has_tls(transport)) ? profile->tls_url : profile->url; @@ -8101,7 +8087,7 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia } } - if (sofia_glue_check_nat(profile, tech_pvt->remote_ip)) { + if (sofia_glue_check_nat(profile, tech_pvt->mparams->remote_ip)) { tech_pvt->user_via = sofia_glue_create_external_via(session, profile, tech_pvt->transport); nua_set_hparams(tech_pvt->nh, SIPTAG_VIA_STR(tech_pvt->user_via), TAG_END()); } diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 767400f4d4..7e2df4067a 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -39,146 +39,16 @@ switch_cache_db_handle_t *_sofia_glue_get_db_handle(sofia_profile_t *profile, const char *file, const char *func, int line); #define sofia_glue_get_db_handle(_p) _sofia_glue_get_db_handle(_p, __FILE__, __SWITCH_FUNC__, __LINE__) -void sofia_glue_set_udptl_image_sdp(private_object_t *tech_pvt, switch_t38_options_t *t38_options, int insist) + +int sofia_glue_check_nat(sofia_profile_t *profile, const char *network_ip) { - char buf[2048] = ""; - char max_buf[128] = ""; - char max_data[128] = ""; - const char *ip; - uint32_t port; - const char *family = "IP4"; - const char *username; - const char *bit_removal_on = "a=T38FaxFillBitRemoval\n"; - const char *bit_removal_off = ""; - - const char *mmr_on = "a=T38FaxTranscodingMMR\n"; - const char *mmr_off = ""; - - const char *jbig_on = "a=T38FaxTranscodingJBIG\n"; - const char *jbig_off = ""; - const char *var; - int broken_boolean; - - switch_assert(tech_pvt); - switch_assert(t38_options); - - ip = t38_options->local_ip; - port = t38_options->local_port; - username = tech_pvt->profile->username; - - //sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA); - - var = switch_channel_get_variable(tech_pvt->channel, "t38_broken_boolean"); - - broken_boolean = switch_true(var); - - if (!ip) { - if (!(ip = tech_pvt->adv_sdp_audio_ip)) { - ip = tech_pvt->proxy_sdp_audio_ip; - } - } - - if (!ip) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s NO IP!\n", switch_channel_get_name(tech_pvt->channel)); - return; - } - - if (!port) { - if (!(port = tech_pvt->adv_sdp_audio_port)) { - port = tech_pvt->proxy_sdp_audio_port; - } - } - - if (!port) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s NO PORT!\n", switch_channel_get_name(tech_pvt->channel)); - return; - } - - if (!tech_pvt->owner_id) { - tech_pvt->owner_id = (uint32_t) switch_epoch_time_now(NULL) - port; - } - - if (!tech_pvt->session_id) { - tech_pvt->session_id = tech_pvt->owner_id; - } - - tech_pvt->session_id++; - - family = strchr(ip, ':') ? "IP6" : "IP4"; - - - switch_snprintf(buf, sizeof(buf), - "v=0\n" - "o=%s %010u %010u IN %s %s\n" - "s=%s\n" - "c=IN %s %s\n" - "t=0 0\n", username, tech_pvt->owner_id, tech_pvt->session_id, family, ip, username, family, ip); - - if (t38_options->T38FaxMaxBuffer) { - switch_snprintf(max_buf, sizeof(max_buf), "a=T38FaxMaxBuffer:%d\n", t38_options->T38FaxMaxBuffer); - }; - - if (t38_options->T38FaxMaxDatagram) { - switch_snprintf(max_data, sizeof(max_data), "a=T38FaxMaxDatagram:%d\n", t38_options->T38FaxMaxDatagram); - }; - - - - - if (broken_boolean) { - bit_removal_on = "a=T38FaxFillBitRemoval:1\n"; - bit_removal_off = "a=T38FaxFillBitRemoval:0\n"; - - mmr_on = "a=T38FaxTranscodingMMR:1\n"; - mmr_off = "a=T38FaxTranscodingMMR:0\n"; - - jbig_on = "a=T38FaxTranscodingJBIG:1\n"; - jbig_off = "a=T38FaxTranscodingJBIG:0\n"; - - } - - - switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - "m=image %d udptl t38\n" - "a=T38FaxVersion:%d\n" - "a=T38MaxBitRate:%d\n" - "%s" - "%s" - "%s" - "a=T38FaxRateManagement:%s\n" - "%s" - "%s" - "a=T38FaxUdpEC:%s\n", - //"a=T38VendorInfo:%s\n", - port, - t38_options->T38FaxVersion, - t38_options->T38MaxBitRate, - t38_options->T38FaxFillBitRemoval ? bit_removal_on : bit_removal_off, - t38_options->T38FaxTranscodingMMR ? mmr_on : mmr_off, - t38_options->T38FaxTranscodingJBIG ? jbig_on : jbig_off, - t38_options->T38FaxRateManagement, - max_buf, - max_data, - t38_options->T38FaxUdpEC - //t38_options->T38VendorInfo ? t38_options->T38VendorInfo : "0 0 0" - ); - - - - if (insist) { - switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "m=audio 0 RTP/AVP 19\n"); - } - - sofia_media_tech_set_local_sdp(tech_pvt, buf, SWITCH_TRUE); - - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "%s image media sdp:\n%s\n", - switch_channel_get_name(tech_pvt->channel), tech_pvt->local_sdp_str); - + switch_assert(network_ip); + return (profile->extsipip && + !switch_check_network_list_ip(network_ip, "loopback.auto") && + !switch_check_network_list_ip(network_ip, profile->local_network)); } - private_object_t *sofia_glue_new_pvt(switch_core_session_t *session) { private_object_t *tech_pvt = (private_object_t *) switch_core_session_alloc(session, sizeof(private_object_t)); @@ -222,7 +92,7 @@ void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t * tech_pvt->profile = profile; - tech_pvt->rtpip = switch_core_session_strdup(session, profile->rtpip[profile->rtpip_next++]); + tech_pvt->mparams->rtpip = switch_core_session_strdup(session, profile->rtpip[profile->rtpip_next++]); if (profile->rtpip_next >= profile->rtpip_index) { profile->rtpip_next = 0; } @@ -234,12 +104,12 @@ void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t * if (tech_pvt->bte) { tech_pvt->recv_te = tech_pvt->te = tech_pvt->bte; } else if (!tech_pvt->te) { - tech_pvt->recv_te = tech_pvt->te = profile->te; + tech_pvt->mparams->recv_te = tech_pvt->mparams->te = profile->te; } tech_pvt->dtmf_type = tech_pvt->profile->dtmf_type; - if (!sofia_test_pflag(tech_pvt->profile, PFLAG_SUPPRESS_CNG)) { + if (!sofia_test_media_flag(tech_pvt->profile, SCMF_SUPPRESS_CNG)) { if (tech_pvt->bcng_pt) { tech_pvt->cng_pt = tech_pvt->bcng_pt; } else if (!tech_pvt->cng_pt) { @@ -254,7 +124,13 @@ void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t * switch_channel_set_flag(tech_pvt->channel, CF_TRACKABLE); } - sofia_glue_check_dtmf_type(tech_pvt); + + if (profile->flags[PFLAG_PASS_RFC2833]) { + switch_channel_set_flag(tech_pvt->channel, CF_PASS_RFC2833); + } + + + switch_core_media_check_dtmf_type(session); switch_channel_set_cap(tech_pvt->channel, CC_MEDIA_ACK); switch_channel_set_cap(tech_pvt->channel, CC_BYPASS_MEDIA); switch_channel_set_cap(tech_pvt->channel, CC_PROXY_MEDIA); @@ -273,9 +149,12 @@ void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t * tech_pvt->mparams->extsipip = profile->extsipip; tech_pvt->mparams->local_network = profile->local_network; tech_pvt->mparams->mutex = tech_pvt->sofia_mutex; + tech_pvt->mparams->sipip = profile->sipip; + tech_pvt->mparams->jb_msec = profile->jb_msec; + tech_pvt->mparams->rtcp_audio_interval_msec = profile->rtcp_audio_interval_msec; + tech_pvt->mparams->rtcp_video_interval_msec = profile->rtcp_video_interval_msec; - - switch_media_handle_create(&tech_pvt->media_handle, session, &tech_pvt->mparams); + switch_media_handle_create(&tech_pvt->media_handle, session, tech_pvt->mparams); switch_media_handle_set_media_flags(tech_pvt->media_handle, tech_pvt->profile->media_flags); @@ -289,6 +168,71 @@ void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t * } + + + +switch_status_t sofia_glue_ext_address_lookup(sofia_profile_t *profile, char **ip, switch_port_t *port, + const char *sourceip, switch_memory_pool_t *pool) +{ + char *error = ""; + switch_status_t status = SWITCH_STATUS_FALSE; + int x; + switch_port_t stun_port = SWITCH_STUN_DEFAULT_PORT; + char *stun_ip = NULL; + + if (!sourceip) { + return status; + } + + if (!strncasecmp(sourceip, "host:", 5)) { + status = (*ip = switch_stun_host_lookup(sourceip + 5, pool)) ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; + } else if (!strncasecmp(sourceip, "stun:", 5)) { + char *p; + + stun_ip = strdup(sourceip + 5); + + if ((p = strchr(stun_ip, ':'))) { + int iport; + *p++ = '\0'; + iport = atoi(p); + if (iport > 0 && iport < 0xFFFF) { + stun_port = (switch_port_t) iport; + } + } + + if (zstr(stun_ip)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "STUN Failed! NO STUN SERVER\n"); + goto out; + } + + + for (x = 0; x < 5; x++) { + if ((status = switch_stun_lookup(ip, port, stun_ip, stun_port, &error, pool)) != SWITCH_STATUS_SUCCESS) { + switch_yield(100000); + } else { + break; + } + } + + if (!*ip) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "STUN Failed! No IP returned\n"); + goto out; + } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "STUN Success [%s]:[%d]\n", *ip, *port); + status = SWITCH_STATUS_SUCCESS; + } else { + *ip = (char *) sourceip; + status = SWITCH_STATUS_SUCCESS; + } + + out: + + switch_safe_free(stun_ip); + + return status; +} + + const char *sofia_glue_get_unknown_header(sip_t const *sip, const char *name) { sip_unknown_t *un; @@ -769,7 +713,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) return status; } - if (!switch_channel_get_private(tech_pvt->channel, "t38_options") || zstr(tech_pvt->local_sdp_str)) { + if (!switch_channel_get_private(tech_pvt->channel, "t38_options") || zstr(tech_pvt->mparams->local_sdp_str)) { sofia_media_set_local_sdp(tech_pvt, NULL, 0, NULL, 0); } @@ -816,7 +760,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) sipip = tech_pvt->profile->sipip; - if (!zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) { + if (!zstr(tech_pvt->mparams->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->mparams->remote_ip)) { sipip = tech_pvt->profile->extsipip; } @@ -856,7 +800,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) } if (sofia_test_pflag(tech_pvt->profile, PFLAG_AUTO_NAT)) { - if (!zstr(tech_pvt->remote_ip) && !zstr(tech_pvt->profile->extsipip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) { + if (!zstr(tech_pvt->mparams->remote_ip) && !zstr(tech_pvt->profile->extsipip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->mparams->remote_ip)) { rpid_domain = tech_pvt->profile->extsipip; } else { rpid_domain = tech_pvt->profile->sipip; @@ -890,7 +834,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) } } - if (!zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) { + if (!zstr(tech_pvt->mparams->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->mparams->remote_ip)) { tech_pvt->user_via = sofia_glue_create_external_via(session, tech_pvt->profile, tech_pvt->transport); } @@ -905,7 +849,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) char *ip_addr = tech_pvt->profile->sipip; char *ipv6; - if ( !zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip ) ) { + if ( !zstr(tech_pvt->mparams->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->mparams->remote_ip ) ) { ip_addr = tech_pvt->profile->extsipip; } @@ -922,7 +866,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) if (sofia_glue_transport_has_tls(tech_pvt->transport)) { tech_pvt->invite_contact = tech_pvt->profile->tls_url; } else { - if (!zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) { + if (!zstr(tech_pvt->mparams->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->mparams->remote_ip)) { tech_pvt->invite_contact = tech_pvt->profile->public_url; } else { tech_pvt->invite_contact = tech_pvt->profile->url; @@ -1190,7 +1134,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { if (switch_rtp_ready(tech_pvt->rtp_session)) { - sofia_glue_tech_proxy_remote_addr(tech_pvt, NULL); + switch_core_media_proxy_remote_addr(session, NULL); } sofia_media_tech_patch_sdp(tech_pvt); } @@ -1231,7 +1175,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) tech_pvt->nh->nh_has_invite = 1; } - if ((mp = sofia_media_get_multipart(session, SOFIA_MULTIPART_PREFIX, tech_pvt->local_sdp_str, &mp_type))) { + if ((mp = sofia_media_get_multipart(session, SOFIA_MULTIPART_PREFIX, tech_pvt->mparams->local_sdp_str, &mp_type))) { sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA); } @@ -1241,16 +1185,16 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) tech_pvt->session_refresher = nua_no_refresher; } - if (tech_pvt->local_sdp_str) { + if (tech_pvt->mparams->local_sdp_str) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, - "Local SDP:\n%s\n", tech_pvt->local_sdp_str); + "Local SDP:\n%s\n", tech_pvt->mparams->local_sdp_str); } if (sofia_use_soa(tech_pvt)) { nua_invite(tech_pvt->nh, NUTAG_AUTOANSWER(0), - //TAG_IF(zstr(tech_pvt->local_sdp_str), NUTAG_AUTOACK(0)), - //TAG_IF(!zstr(tech_pvt->local_sdp_str), NUTAG_AUTOACK(1)), + //TAG_IF(zstr(tech_pvt->mparams->local_sdp_str), NUTAG_AUTOACK(0)), + //TAG_IF(!zstr(tech_pvt->mparams->local_sdp_str), NUTAG_AUTOACK(1)), // The code above is breaking things...... grrr WE need this because we handle our own acks and there are 3pcc cases in there too NUTAG_AUTOACK(0), NUTAG_SESSION_TIMER(tech_pvt->session_timeout), @@ -1274,16 +1218,16 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) TAG_IF(!zstr(route), SIPTAG_ROUTE_STR(route)), TAG_IF(tech_pvt->profile->minimum_session_expires, NUTAG_MIN_SE(tech_pvt->profile->minimum_session_expires)), TAG_IF(cseq, SIPTAG_CSEQ(cseq)), - TAG_IF(zstr(tech_pvt->local_sdp_str), SIPTAG_PAYLOAD_STR("")), - TAG_IF(!zstr(tech_pvt->local_sdp_str), SOATAG_ADDRESS(tech_pvt->adv_sdp_audio_ip)), - TAG_IF(!zstr(tech_pvt->local_sdp_str), SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str)), - TAG_IF(!zstr(tech_pvt->local_sdp_str), SOATAG_REUSE_REJECTED(1)), - TAG_IF(!zstr(tech_pvt->local_sdp_str), SOATAG_ORDERED_USER(1)), - TAG_IF(!zstr(tech_pvt->local_sdp_str), SOATAG_RTP_SORT(SOA_RTP_SORT_REMOTE)), - TAG_IF(!zstr(tech_pvt->local_sdp_str), SOATAG_RTP_SELECT(SOA_RTP_SELECT_ALL)), + TAG_IF(zstr(tech_pvt->mparams->local_sdp_str), SIPTAG_PAYLOAD_STR("")), + TAG_IF(!zstr(tech_pvt->mparams->local_sdp_str), SOATAG_ADDRESS(tech_pvt->mparams->adv_sdp_audio_ip)), + TAG_IF(!zstr(tech_pvt->mparams->local_sdp_str), SOATAG_USER_SDP_STR(tech_pvt->mparams->local_sdp_str)), + TAG_IF(!zstr(tech_pvt->mparams->local_sdp_str), SOATAG_REUSE_REJECTED(1)), + TAG_IF(!zstr(tech_pvt->mparams->local_sdp_str), SOATAG_ORDERED_USER(1)), + TAG_IF(!zstr(tech_pvt->mparams->local_sdp_str), SOATAG_RTP_SORT(SOA_RTP_SORT_REMOTE)), + TAG_IF(!zstr(tech_pvt->mparams->local_sdp_str), SOATAG_RTP_SELECT(SOA_RTP_SELECT_ALL)), TAG_IF(rep, SIPTAG_REPLACES_STR(rep)), TAG_IF(!require_timer, NUTAG_TIMER_AUTOREQUIRE(0)), - TAG_IF(!zstr(tech_pvt->local_sdp_str), SOATAG_HOLD(holdstr)), TAG_END()); + TAG_IF(!zstr(tech_pvt->mparams->local_sdp_str), SOATAG_HOLD(holdstr)), TAG_END()); } else { nua_invite(tech_pvt->nh, NUTAG_AUTOANSWER(0), @@ -1312,7 +1256,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) TAG_IF(cseq, SIPTAG_CSEQ(cseq)), NUTAG_MEDIA_ENABLE(0), SIPTAG_CONTENT_TYPE_STR(mp_type ? mp_type : "application/sdp"), - SIPTAG_PAYLOAD_STR(mp ? mp : tech_pvt->local_sdp_str), TAG_IF(rep, SIPTAG_REPLACES_STR(rep)), SOATAG_HOLD(holdstr), TAG_END()); + SIPTAG_PAYLOAD_STR(mp ? mp : tech_pvt->mparams->local_sdp_str), TAG_IF(rep, SIPTAG_REPLACES_STR(rep)), SOATAG_HOLD(holdstr), TAG_END()); } sofia_glue_free_destination(dst); @@ -1334,7 +1278,7 @@ void sofia_glue_do_xfer_invite(switch_core_session_t *session) switch_mutex_lock(tech_pvt->sofia_mutex); caller_profile = switch_channel_get_caller_profile(channel); - if (!zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) { + if (!zstr(tech_pvt->mparams->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->mparams->remote_ip)) { sipip = tech_pvt->profile->extsipip; contact_url = tech_pvt->profile->public_url; } else { @@ -1356,8 +1300,8 @@ void sofia_glue_do_xfer_invite(switch_core_session_t *session) nua_invite(tech_pvt->nh2, SIPTAG_CONTACT_STR(contact_url), TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), - SOATAG_ADDRESS(tech_pvt->adv_sdp_audio_ip), - SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str), + SOATAG_ADDRESS(tech_pvt->mparams->adv_sdp_audio_ip), + SOATAG_USER_SDP_STR(tech_pvt->mparams->local_sdp_str), SOATAG_REUSE_REJECTED(1), SOATAG_ORDERED_USER(1), SOATAG_RTP_SORT(SOA_RTP_SORT_REMOTE), SOATAG_RTP_SELECT(SOA_RTP_SELECT_ALL), TAG_IF(rep, SIPTAG_REPLACES_STR(rep)), TAG_END()); @@ -1417,42 +1361,6 @@ void sofia_glue_set_rtp_stats(private_object_t *tech_pvt) } } -void sofia_glue_deactivate_rtp(private_object_t *tech_pvt) -{ - int loops = 0; - if (switch_rtp_ready(tech_pvt->rtp_session)) { - while (loops < 10 && (sofia_test_flag(tech_pvt, TFLAG_READING) || sofia_test_flag(tech_pvt, TFLAG_WRITING))) { - switch_yield(10000); - loops++; - } - } - - if (tech_pvt->video_rtp_session) { - switch_rtp_destroy(&tech_pvt->video_rtp_session); - } else if (tech_pvt->local_sdp_video_port) { - switch_rtp_release_port(tech_pvt->rtpip, tech_pvt->local_sdp_video_port); - } - - - if (tech_pvt->local_sdp_video_port > 0 && !zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) { - switch_nat_del_mapping((switch_port_t) tech_pvt->local_sdp_video_port, SWITCH_NAT_UDP); - switch_nat_del_mapping((switch_port_t) tech_pvt->local_sdp_video_port + 1, SWITCH_NAT_UDP); - } - - - if (tech_pvt->rtp_session) { - switch_rtp_destroy(&tech_pvt->rtp_session); - } else if (tech_pvt->local_sdp_audio_port) { - switch_rtp_release_port(tech_pvt->rtpip, tech_pvt->local_sdp_audio_port); - } - - if (tech_pvt->local_sdp_audio_port > 0 && !zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) { - switch_nat_del_mapping((switch_port_t) tech_pvt->local_sdp_audio_port, SWITCH_NAT_UDP); - switch_nat_del_mapping((switch_port_t) tech_pvt->local_sdp_audio_port + 1, SWITCH_NAT_UDP); - } - -} - /* map sip responses to QSIG cause codes ala RFC4497 section 8.4.4 */ switch_call_cause_t sofia_glue_sip_cause_to_freeswitch(int status) { @@ -1903,7 +1811,7 @@ int sofia_recover_callback(switch_core_session_t *session) switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); switch_mutex_init(&tech_pvt->sofia_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); - tech_pvt->remote_ip = (char *) switch_channel_get_variable(channel, "sip_network_ip"); + tech_pvt->mparams->remote_ip = (char *) switch_channel_get_variable(channel, "sip_network_ip"); tech_pvt->remote_port = atoi(switch_str_nil(switch_channel_get_variable(channel, "sip_network_port"))); tech_pvt->caller_profile = switch_channel_get_caller_profile(channel); @@ -1963,7 +1871,7 @@ int sofia_recover_callback(switch_core_session_t *session) switch_core_session_get_recovery_crypto_key(session, SWITCH_MEDIA_TYPE_VIDEO, "srtp_remote_video_crypto_key"); if ((tmp = switch_channel_get_variable(channel, "sip_local_sdp_str"))) { - tech_pvt->local_sdp_str = switch_core_session_strdup(session, tmp); + tech_pvt->mparams->local_sdp_str = switch_core_session_strdup(session, tmp); } if ((tmp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE))) { @@ -2018,7 +1926,7 @@ int sofia_recover_callback(switch_core_session_t *session) switch_core_media_set_codec(tech_pvt->session, 1, tech_pvt->profile->codec_flags); - tech_pvt->adv_sdp_audio_ip = tech_pvt->extrtpip = (char *) ip; + tech_pvt->mparams->adv_sdp_audio_ip = tech_pvt->extrtpip = (char *) ip; tech_pvt->adv_sdp_audio_port = tech_pvt->local_sdp_audio_port = (switch_port_t)atoi(port); if (!zstr(ip)) { @@ -2027,7 +1935,7 @@ int sofia_recover_callback(switch_core_session_t *session) } if (!zstr(a_ip)) { - tech_pvt->adv_sdp_audio_ip = switch_core_session_strdup(session, a_ip); + tech_pvt->mparams->adv_sdp_audio_ip = switch_core_session_strdup(session, a_ip); } if (r_ip && r_port) { diff --git a/src/mod/endpoints/mod_sofia/sofia_media.c b/src/mod/endpoints/mod_sofia/sofia_media.c index 6b66806b80..d5e0784388 100644 --- a/src/mod/endpoints/mod_sofia/sofia_media.c +++ b/src/mod/endpoints/mod_sofia/sofia_media.c @@ -34,45 +34,6 @@ -void sofia_media_tech_absorb_sdp(private_object_t *tech_pvt) -{ - const char *sdp_str; - - if ((sdp_str = switch_channel_get_variable(tech_pvt->channel, SWITCH_B_SDP_VARIABLE))) { - sdp_parser_t *parser; - sdp_session_t *sdp; - sdp_media_t *m; - sdp_connection_t *connection; - - if ((parser = sdp_parse(NULL, sdp_str, (int) strlen(sdp_str), 0))) { - if ((sdp = sdp_session(parser))) { - for (m = sdp->sdp_media; m; m = m->m_next) { - if (m->m_type != sdp_media_audio || !m->m_port) { - continue; - } - - connection = sdp->sdp_connection; - if (m->m_connections) { - connection = m->m_connections; - } - - if (connection) { - tech_pvt->proxy_sdp_audio_ip = switch_core_session_strdup(tech_pvt->session, connection->c_address); - } - tech_pvt->proxy_sdp_audio_port = (switch_port_t) m->m_port; - if (tech_pvt->proxy_sdp_audio_ip && tech_pvt->proxy_sdp_audio_port) { - break; - } - } - } - sdp_parser_free(parser); - } - sofia_media_tech_set_local_sdp(tech_pvt, sdp_str, SWITCH_TRUE); - } -} - - - void sofia_media_proxy_codec(switch_core_session_t *session, const char *r_sdp) { sdp_media_t *m; @@ -141,7 +102,7 @@ uint8_t sofia_media_negotiate_sdp(switch_core_session_t *session, const char *r_ uint8_t t, p = 0; private_object_t *tech_pvt = switch_core_session_get_private(session); - if ((t = switch_core_media_negotiate_sdp(session, r_sdp, &p, sofia_test_flag(tech_pvt, TFLAG_REINVITE), + if ((t = switch_core_media_negotiate_sdp(session, r_sdp, &p, switch_channel_test_flag(tech_pvt->channel, CF_REINVITE), tech_pvt->profile->codec_flags, tech_pvt->profile->te))) { sofia_set_flag_locked(tech_pvt, TFLAG_SDP); } @@ -155,16 +116,18 @@ uint8_t sofia_media_negotiate_sdp(switch_core_session_t *session, const char *r_ switch_status_t sofia_media_activate_rtp(private_object_t *tech_pvt) { - int ok; + switch_status_t status; switch_mutex_lock(tech_pvt->sofia_mutex); + status = switch_core_media_activate_rtp(tech_pvt->session); switch_mutex_unlock(tech_pvt->sofia_mutex); - if (ok) { + if (status == SWITCH_STATUS_SUCCESS) { sofia_set_flag(tech_pvt, TFLAG_RTP); sofia_set_flag(tech_pvt, TFLAG_IO); } + return status; } @@ -511,279 +474,15 @@ void sofia_media_tech_prepare_codecs(private_object_t *tech_pvt) } -void sofia_media_tech_patch_sdp(private_object_t *tech_pvt) +void sofia_media_deactivate_rtp(private_object_t *tech_pvt) { - switch_size_t len; - char *p, *q, *pe, *qe; - int has_video = 0, has_audio = 0, has_ip = 0; - char port_buf[25] = ""; - char vport_buf[25] = ""; - char *new_sdp; - int bad = 0; - - if (zstr(tech_pvt->local_sdp_str)) { - return; + int loops = 0; + while (loops < 10 && (sofia_test_flag(tech_pvt, TFLAG_READING) || sofia_test_flag(tech_pvt, TFLAG_WRITING))) { + switch_yield(10000); + loops++; } - len = strlen(tech_pvt->local_sdp_str) * 2; - - if (switch_channel_test_flag(tech_pvt->channel, CF_ANSWERED) && - (switch_stristr("sendonly", tech_pvt->local_sdp_str) || switch_stristr("0.0.0.0", tech_pvt->local_sdp_str))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Skip patch on hold SDP\n"); - return; - } - - if (zstr(tech_pvt->adv_sdp_audio_ip) || !tech_pvt->adv_sdp_audio_port) { - if (sofia_glue_tech_choose_port(tech_pvt, 1) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "%s I/O Error\n", - switch_channel_get_name(tech_pvt->channel)); - return; - } - tech_pvt->iananame = switch_core_session_strdup(tech_pvt->session, "PROXY"); - tech_pvt->rm_rate = 8000; - tech_pvt->codec_ms = 20; - } - - new_sdp = switch_core_session_alloc(tech_pvt->session, len); - switch_snprintf(port_buf, sizeof(port_buf), "%u", tech_pvt->adv_sdp_audio_port); - - - p = tech_pvt->local_sdp_str; - q = new_sdp; - pe = p + strlen(p); - qe = q + len - 1; - - - while (p && *p) { - if (p >= pe) { - bad = 1; - goto end; - } - - if (q >= qe) { - bad = 2; - goto end; - } - - if (tech_pvt->adv_sdp_audio_ip && !strncmp("c=IN IP", p, 7)) { - strncpy(q, p, 7); - p += 7; - q += 7; - strncpy(q, strchr(tech_pvt->adv_sdp_audio_ip, ':') ? "6 " : "4 ", 2); - p +=2; - q +=2; - strncpy(q, tech_pvt->adv_sdp_audio_ip, strlen(tech_pvt->adv_sdp_audio_ip)); - q += strlen(tech_pvt->adv_sdp_audio_ip); - - while (p && *p && ((*p >= '0' && *p <= '9') || *p == '.' || *p == ':' || (*p >= 'A' && *p <= 'F') || (*p >= 'a' && *p <= 'f'))) { - if (p >= pe) { - bad = 3; - goto end; - } - p++; - } - - has_ip++; - - } else if (!strncmp("o=", p, 2)) { - char *oe = strchr(p, '\n'); - switch_size_t len; - - if (oe) { - const char *family = "IP4"; - char o_line[1024] = ""; - - if (oe >= pe) { - bad = 5; - goto end; - } - - len = (oe - p); - p += len; - - - family = strchr(tech_pvt->profile->sipip, ':') ? "IP6" : "IP4"; - - if (!tech_pvt->owner_id) { - tech_pvt->owner_id = (uint32_t) switch_epoch_time_now(NULL) * 31821U + 13849U; - } - - if (!tech_pvt->session_id) { - tech_pvt->session_id = tech_pvt->owner_id; - } - - tech_pvt->session_id++; - - - snprintf(o_line, sizeof(o_line), "o=%s %010u %010u IN %s %s\n", - tech_pvt->profile->username, tech_pvt->owner_id, tech_pvt->session_id, family, tech_pvt->profile->sipip); - - strncpy(q, o_line, strlen(o_line)); - q += strlen(o_line) - 1; - - } - - } else if (!strncmp("s=", p, 2)) { - char *se = strchr(p, '\n'); - switch_size_t len; - - if (se) { - char s_line[1024] = ""; - - if (se >= pe) { - bad = 5; - goto end; - } - - len = (se - p); - p += len; - - snprintf(s_line, sizeof(s_line), "s=%s\n", tech_pvt->profile->username); - - strncpy(q, s_line, strlen(s_line)); - q += strlen(s_line) - 1; - - } - - } else if ((!strncmp("m=audio ", p, 8) && *(p + 8) != '0') || (!strncmp("m=image ", p, 8) && *(p + 8) != '0')) { - strncpy(q, p, 8); - p += 8; - - if (p >= pe) { - bad = 4; - goto end; - } - - - q += 8; - - if (q >= qe) { - bad = 5; - goto end; - } - - - strncpy(q, port_buf, strlen(port_buf)); - q += strlen(port_buf); - - if (q >= qe) { - bad = 6; - goto end; - } - - while (p && *p && (*p >= '0' && *p <= '9')) { - if (p >= pe) { - bad = 7; - goto end; - } - p++; - } - - has_audio++; - - } else if (!strncmp("m=video ", p, 8) && *(p + 8) != '0') { - if (!has_video) { - sofia_glue_tech_choose_video_port(tech_pvt, 1); - tech_pvt->video_rm_encoding = "PROXY-VID"; - tech_pvt->video_rm_rate = 90000; - tech_pvt->video_codec_ms = 0; - switch_snprintf(vport_buf, sizeof(vport_buf), "%u", tech_pvt->adv_sdp_video_port); - if (switch_channel_media_ready(tech_pvt->channel) && !switch_rtp_ready(tech_pvt->video_rtp_session)) { - switch_channel_set_flag(tech_pvt->channel, CF_VIDEO_POSSIBLE); - sofia_set_flag(tech_pvt, TFLAG_REINVITE); - sofia_media_activate_rtp(tech_pvt); - } - } - - strncpy(q, p, 8); - p += 8; - - if (p >= pe) { - bad = 8; - goto end; - } - - q += 8; - - if (q >= qe) { - bad = 9; - goto end; - } - - strncpy(q, vport_buf, strlen(vport_buf)); - q += strlen(vport_buf); - - if (q >= qe) { - bad = 10; - goto end; - } - - while (p && *p && (*p >= '0' && *p <= '9')) { - - if (p >= pe) { - bad = 11; - goto end; - } - - p++; - } - - has_video++; - } - - while (p && *p && *p != '\n') { - - if (p >= pe) { - bad = 12; - goto end; - } - - if (q >= qe) { - bad = 13; - goto end; - } - - *q++ = *p++; - } - - if (p >= pe) { - bad = 14; - goto end; - } - - if (q >= qe) { - bad = 15; - goto end; - } - - *q++ = *p++; - - } - - end: - - if (bad) { - return; - } - - - if (switch_channel_down(tech_pvt->channel) || sofia_test_flag(tech_pvt, TFLAG_BYE)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "%s too late.\n", switch_channel_get_name(tech_pvt->channel)); - return; - } - - - if (!has_ip && !has_audio) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "%s SDP has no audio in it.\n%s\n", - switch_channel_get_name(tech_pvt->channel), tech_pvt->local_sdp_str); - return; - } - - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "%s Patched SDP\n---\n%s\n+++\n%s\n", - switch_channel_get_name(tech_pvt->channel), tech_pvt->local_sdp_str, new_sdp); - - sofia_media_tech_set_local_sdp(tech_pvt, new_sdp, SWITCH_FALSE); + switch_core_media_deactivate_rtp(tech_pvt->session); } diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 3429f014ee..95184e38ca 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -139,8 +139,6 @@ struct switch_media_handle_s { int payload_space;//x:tp char *origin;//x:tp int hold_laps;//x:tp - switch_payload_t te;//x:tp - switch_payload_t recv_te;//x:tp switch_payload_t cng_pt;//x:tp switch_core_media_dtmf_t dtmf_type;//x:tp const switch_codec_implementation_t *negotiated_codecs[SWITCH_MAX_CODECS];//x:tp @@ -1883,7 +1881,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s } if ((pass == 2 && switch_media_handle_test_media_flag(smh, SCMF_T38_PASSTHRU)) - || !reinvite || + || !switch_channel_test_flag(session->channel, CF_REINVITE) || switch_channel_test_flag(session->channel, CF_PROXY_MODE) || switch_channel_test_flag(session->channel, CF_PROXY_MEDIA) || @@ -2001,7 +1999,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s x = 0; if (a_engine->codec_params.rm_encoding && !(switch_media_handle_test_media_flag(smh, SCMF_LIBERAL_DTMF) || - switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF))) { // && !reinvite) { + switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF))) { // && !switch_channel_test_flag(session->channel, CF_REINVITE)) { char *remote_host = a_engine->codec_params.remote_sdp_ip; switch_port_t remote_port = a_engine->codec_params.remote_sdp_port; int same = 0; @@ -2216,7 +2214,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s if (!switch_true(mirror) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND && - (!reinvite || switch_media_handle_test_media_flag(smh, SCMF_RENEG_ON_REINVITE))) { + (!switch_channel_test_flag(session->channel, CF_REINVITE) || switch_media_handle_test_media_flag(smh, SCMF_RENEG_ON_REINVITE))) { switch_core_media_get_offered_pt(session, mimp, &a_engine->codec_params.recv_pt); } @@ -2242,14 +2240,14 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s if (best_te) { if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { - te = smh->te = (switch_payload_t) best_te; + te = smh->mparams->te = (switch_payload_t) best_te; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set 2833 dtmf send payload to %u\n", best_te); if (a_engine->rtp_session) { switch_rtp_set_telephony_event(a_engine->rtp_session, (switch_payload_t) best_te); switch_channel_set_variable_printf(session->channel, "sip_2833_send_payload", "%d", best_te); } } else { - te = smh->recv_te = smh->te = (switch_payload_t) best_te; + te = smh->mparams->recv_te = smh->mparams->te = (switch_payload_t) best_te; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set 2833 dtmf send/recv payload to %u\n", te); if (a_engine->rtp_session) { switch_rtp_set_telephony_event(a_engine->rtp_session, te); @@ -2264,11 +2262,11 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No 2833 in SDP. Disable 2833 dtmf and switch to INFO\n"); switch_channel_set_variable(session->channel, "dtmf_type", "info"); smh->dtmf_type = DTMF_INFO; - te = smh->recv_te = smh->te = 0; + te = smh->mparams->recv_te = smh->mparams->te = 0; } else { switch_channel_set_variable(session->channel, "dtmf_type", "none"); smh->dtmf_type = DTMF_NONE; - te = smh->recv_te = smh->te = 0; + te = smh->mparams->recv_te = smh->mparams->te = 0; } } @@ -2699,7 +2697,7 @@ SWITCH_DECLARE(int) switch_core_media_check_nat(switch_media_handle_t *smh, cons } //? -SWITCH_DECLARE(switch_status_t) sofia_glue_ext_address_lookup(switch_core_session_t *session, char **ip, switch_port_t *port, const char *sourceip) +SWITCH_DECLARE(switch_status_t) switch_core_media_ext_address_lookup(switch_core_session_t *session, char **ip, switch_port_t *port, const char *sourceip) { char *error = ""; @@ -2816,6 +2814,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_choose_port(switch_core_sessio return SWITCH_STATUS_FALSE; } + engine->codec_params.local_sdp_ip = smh->mparams->rtpip; + + sdp_port = engine->codec_params.local_sdp_port; /* Check if NAT is detected */ @@ -2832,7 +2833,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_choose_port(switch_core_sessio } if (use_ip) { - if (sofia_glue_ext_address_lookup(session, &lookup_rtpip, &sdp_port, use_ip) != SWITCH_STATUS_SUCCESS) { + if (switch_core_media_ext_address_lookup(session, &lookup_rtpip, &sdp_port, use_ip) != SWITCH_STATUS_SUCCESS) { /* Address lookup was required and fail (external ip was "host:..." or "stun:...") */ return SWITCH_STATUS_FALSE; } else { @@ -2849,16 +2850,72 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_choose_port(switch_core_sessio } engine->codec_params.adv_sdp_port = sdp_port; - switch_channel_set_variable(session->channel, SWITCH_LOCAL_VIDEO_IP_VARIABLE, engine->codec_params.adv_sdp_ip); - switch_channel_set_variable_printf(session->channel, SWITCH_LOCAL_VIDEO_PORT_VARIABLE, "%d", sdp_port); + engine->codec_params.adv_sdp_ip = smh->mparams->adv_sdp_audio_ip = smh->mparams->extrtpip = switch_core_session_strdup(session, use_ip); + + + if (type == SWITCH_MEDIA_TYPE_AUDIO) { + switch_channel_set_variable(session->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE, engine->codec_params.local_sdp_ip); + switch_channel_set_variable_printf(session->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE, "%d", sdp_port); + switch_channel_set_variable(session->channel, SWITCH_ADVERTISED_MEDIA_IP_VARIABLE, engine->codec_params.adv_sdp_ip); + } else { + switch_channel_set_variable(session->channel, SWITCH_LOCAL_VIDEO_IP_VARIABLE, engine->codec_params.adv_sdp_ip); + switch_channel_set_variable_printf(session->channel, SWITCH_LOCAL_VIDEO_PORT_VARIABLE, "%d", sdp_port); + } return SWITCH_STATUS_SUCCESS; } +//? +SWITCH_DECLARE(void) switch_core_media_deactivate_rtp(switch_core_session_t *session) +{ + switch_rtp_engine_t *a_engine, *v_engine; + switch_media_handle_t *smh; + + if (!(smh = session->media_handle)) { + return; + } + + a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO]; + v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO]; + + + if (switch_rtp_ready(a_engine->rtp_session)) { + + } + + if (v_engine->rtp_session) { + switch_rtp_destroy(&v_engine->rtp_session); + } else if (v_engine->codec_params.local_sdp_port) { + switch_rtp_release_port(smh->mparams->rtpip, v_engine->codec_params.local_sdp_port); + } + + + if (v_engine->codec_params.local_sdp_port > 0 && !zstr(smh->mparams->remote_ip) && + switch_core_media_check_nat(smh, smh->mparams->remote_ip)) { + switch_nat_del_mapping((switch_port_t) v_engine->codec_params.local_sdp_port, SWITCH_NAT_UDP); + switch_nat_del_mapping((switch_port_t) v_engine->codec_params.local_sdp_port + 1, SWITCH_NAT_UDP); + } + + + if (a_engine->rtp_session) { + switch_rtp_destroy(&a_engine->rtp_session); + } else if (a_engine->codec_params.local_sdp_port) { + switch_rtp_release_port(smh->mparams->rtpip, a_engine->codec_params.local_sdp_port); + } + + if (a_engine->codec_params.local_sdp_port > 0 && !zstr(smh->mparams->remote_ip) && + switch_core_media_check_nat(smh, smh->mparams->remote_ip)) { + switch_nat_del_mapping((switch_port_t) a_engine->codec_params.local_sdp_port, SWITCH_NAT_UDP); + switch_nat_del_mapping((switch_port_t) a_engine->codec_params.local_sdp_port + 1, SWITCH_NAT_UDP); + } + +} + + //? -SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_session_t *session, switch_core_media_params_t *params) +SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_session_t *session) { const char *err = NULL; @@ -2897,7 +2954,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi goto end; } - if (!params->reinvite) { + if (!switch_channel_test_flag(session->channel, CF_REINVITE)) { if (switch_rtp_ready(a_engine->rtp_session)) { if (switch_channel_test_flag(session->channel, CF_VIDEO_POSSIBLE) && !switch_rtp_ready(v_engine->rtp_session)) { goto video; @@ -2908,7 +2965,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi } } - if ((status = switch_core_media_set_codec(session, 0, params->codec_flags)) != SWITCH_STATUS_SUCCESS) { + if ((status = switch_core_media_set_codec(session, 0, smh->mparams->codec_flags)) != SWITCH_STATUS_SUCCESS) { goto end; } @@ -2952,7 +3009,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi flags[SWITCH_RTP_FLAG_BYTESWAP] = 0; } - if (a_engine->rtp_session && params->reinvite) { + if (a_engine->rtp_session && switch_channel_test_flag(session->channel, CF_REINVITE)) { //const char *ip = switch_channel_get_variable(session->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE); //const char *port = switch_channel_get_variable(session->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE); char *remote_host = switch_rtp_get_remote_host(a_engine->rtp_session); @@ -3016,7 +3073,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi switch_channel_set_variable(session->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE, tmp); switch_channel_set_variable(session->channel, SWITCH_ADVERTISED_MEDIA_IP_VARIABLE, a_engine->codec_params.adv_sdp_ip); - if (a_engine->rtp_session && params->reinvite) { + if (a_engine->rtp_session && switch_channel_test_flag(session->channel, CF_REINVITE)) { const char *rport = NULL; switch_port_t remote_rtcp_port = 0; @@ -3232,40 +3289,40 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi if ((val = switch_channel_get_variable(session->channel, "params->rtp_timeout_sec"))) { int v = atoi(val); if (v >= 0) { - params->rtp_timeout_sec = v; + smh->mparams->rtp_timeout_sec = v; } } if ((val = switch_channel_get_variable(session->channel, "params->rtp_hold_timeout_sec"))) { int v = atoi(val); if (v >= 0) { - params->rtp_hold_timeout_sec = v; + smh->mparams->rtp_hold_timeout_sec = v; } } - if (params->rtp_timeout_sec) { - a_engine->max_missed_packets = (a_engine->read_impl.samples_per_second * params->rtp_timeout_sec) / a_engine->read_impl.samples_per_packet; + if (smh->mparams->rtp_timeout_sec) { + a_engine->max_missed_packets = (a_engine->read_impl.samples_per_second * smh->mparams->rtp_timeout_sec) / a_engine->read_impl.samples_per_packet; switch_rtp_set_max_missed_packets(a_engine->rtp_session, a_engine->max_missed_packets); - if (!params->rtp_hold_timeout_sec) { - params->rtp_hold_timeout_sec = params->rtp_timeout_sec * 10; + if (!smh->mparams->rtp_hold_timeout_sec) { + smh->mparams->rtp_hold_timeout_sec = smh->mparams->rtp_timeout_sec * 10; } } - if (params->rtp_hold_timeout_sec) { - a_engine->max_missed_hold_packets = (a_engine->read_impl.samples_per_second * params->rtp_hold_timeout_sec) / a_engine->read_impl.samples_per_packet; + if (smh->mparams->rtp_hold_timeout_sec) { + a_engine->max_missed_hold_packets = (a_engine->read_impl.samples_per_second * smh->mparams->rtp_hold_timeout_sec) / a_engine->read_impl.samples_per_packet; } - if (smh->te) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set 2833 dtmf send payload to %u\n", smh->te); - switch_rtp_set_telephony_event(a_engine->rtp_session, smh->te); - switch_channel_set_variable_printf(session->channel, "sip_2833_send_payload", "%d", smh->te); + if (smh->mparams->te) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set 2833 dtmf send payload to %u\n", smh->mparams->te); + switch_rtp_set_telephony_event(a_engine->rtp_session, smh->mparams->te); + switch_channel_set_variable_printf(session->channel, "sip_2833_send_payload", "%d", smh->mparams->te); } - if (smh->recv_te) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set 2833 dtmf receive payload to %u\n", smh->recv_te); - switch_rtp_set_telephony_recv_event(a_engine->rtp_session, smh->recv_te); - switch_channel_set_variable_printf(session->channel, "sip_2833_recv_payload", "%d", smh->recv_te); + if (smh->mparams->recv_te) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set 2833 dtmf receive payload to %u\n", smh->mparams->recv_te); + switch_rtp_set_telephony_recv_event(a_engine->rtp_session, smh->mparams->recv_te); + switch_channel_set_variable_printf(session->channel, "sip_2833_recv_payload", "%d", smh->mparams->recv_te); } if (a_engine->codec_params.recv_pt != a_engine->codec_params.agreed_pt) { @@ -3284,14 +3341,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi if (((val = switch_channel_get_variable(session->channel, "rtp_digit_delay")))) { int delayi = atoi(val); if (delayi < 0) delayi = 0; - params->dtmf_delay = (uint32_t) delayi; + smh->mparams->dtmf_delay = (uint32_t) delayi; } - if (params->dtmf_delay) { - switch_rtp_set_interdigit_delay(a_engine->rtp_session, params->dtmf_delay); + if (smh->mparams->dtmf_delay) { + switch_rtp_set_interdigit_delay(a_engine->rtp_session, smh->mparams->dtmf_delay); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, - "%s Set rtp dtmf delay to %u\n", switch_channel_get_name(session->channel), params->dtmf_delay); + "%s Set rtp dtmf delay to %u\n", switch_channel_get_name(session->channel), smh->mparams->dtmf_delay); } @@ -3322,7 +3379,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi if (switch_channel_test_flag(session->channel, CF_VIDEO_POSSIBLE) && v_engine->codec_params.rm_encoding && v_engine->codec_params.remote_sdp_port) { /******************************************************************************************/ - if (v_engine->rtp_session && params->reinvite) { + if (v_engine->rtp_session && switch_channel_test_flag(session->channel, CF_REINVITE)) { //const char *ip = switch_channel_get_variable(session->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE); //const char *port = switch_channel_get_variable(session->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE); char *remote_host = switch_rtp_get_remote_host(v_engine->rtp_session); @@ -3357,11 +3414,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi switch_channel_set_variable(session->channel, SWITCH_LOCAL_VIDEO_PORT_VARIABLE, tmp); - if (v_engine->rtp_session && params->reinvite) { + if (v_engine->rtp_session && switch_channel_test_flag(session->channel, CF_REINVITE)) { const char *rport = NULL; switch_port_t remote_rtcp_port = 0; - params->reinvite = 0; + switch_channel_clear_flag(session->channel, CF_REINVITE); if ((rport = switch_channel_get_variable(session->channel, "sip_remote_video_rtcp_port"))) { remote_rtcp_port = (switch_port_t)atoi(rport); @@ -3540,7 +3597,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi end: - params->reinvite = 0; + switch_channel_clear_flag(session->channel, CF_REINVITE); switch_core_recovery_track(session); @@ -3609,8 +3666,8 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen, switch_snprintf(buf + strlen(buf), buflen - strlen(buf), " %d", smh->ianacodes[i]); } - if (smh->dtmf_type == DTMF_2833 && smh->te > 95) { - switch_snprintf(buf + strlen(buf), buflen - strlen(buf), " %d", smh->te); + if (smh->dtmf_type == DTMF_2833 && smh->mparams->te > 95) { + switch_snprintf(buf + strlen(buf), buflen - strlen(buf), " %d", smh->mparams->te); } if (!switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) && cng_type && use_cng) { @@ -3679,8 +3736,8 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen, if ((smh->dtmf_type == DTMF_2833 || switch_media_handle_test_media_flag(smh, SCMF_LIBERAL_DTMF) || - switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF)) && smh->te > 95) { - switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtpmap:%d telephone-event/8000\na=fmtp:%d 0-16\n", smh->te, smh->te); + switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF)) && smh->mparams->te > 95) { + switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtpmap:%d telephone-event/8000\na=fmtp:%d 0-16\n", smh->mparams->te, smh->mparams->te); } if (secure) { @@ -3878,7 +3935,7 @@ void sofia_media_set_local_sdp(switch_core_session_t *session, const char *ip, s smh->ianacodes[i] = imp->ianacode; if (smh->ianacodes[i] > 64) { - if (smh->dtmf_type == DTMF_2833 && smh->te > 95 && smh->te == smh->payload_space) { + if (smh->dtmf_type == DTMF_2833 && smh->mparams->te > 95 && smh->mparams->te == smh->payload_space) { smh->payload_space++; } if (!switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) && @@ -3978,8 +4035,8 @@ void sofia_media_set_local_sdp(switch_core_session_t *session, const char *ip, s switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", a_engine->codec_params.pt); if ((smh->dtmf_type == DTMF_2833 || switch_media_handle_test_media_flag(smh, SCMF_LIBERAL_DTMF) || - switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF)) && smh->te > 95) { - switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", smh->te); + switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF)) && smh->mparams->te > 95) { + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", smh->mparams->te); } if (!switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) && smh->cng_pt && use_cng) { @@ -4001,8 +4058,8 @@ void sofia_media_set_local_sdp(switch_core_session_t *session, const char *ip, s if ((smh->dtmf_type == DTMF_2833 || switch_media_handle_test_media_flag(smh, SCMF_LIBERAL_DTMF) || switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF)) - && smh->te > 95) { - switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d telephone-event/8000\na=fmtp:%d 0-16\n", smh->te, smh->te); + && smh->mparams->te > 95) { + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d telephone-event/8000\na=fmtp:%d 0-16\n", smh->mparams->te, smh->mparams->te); } if (!switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) && smh->cng_pt && use_cng) { switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d CN/8000\n", smh->cng_pt); @@ -4262,6 +4319,491 @@ void sofia_media_set_local_sdp(switch_core_session_t *session, const char *ip, s switch_safe_free(buf); } +//? +SWITCH_DECLARE(void) switch_core_media_absorb_sdp(switch_core_session_t *session) +{ + const char *sdp_str; + switch_rtp_engine_t *a_engine; + switch_media_handle_t *smh; + + if (!(smh = session->media_handle)) { + return; + } + + a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO]; + + if ((sdp_str = switch_channel_get_variable(session->channel, SWITCH_B_SDP_VARIABLE))) { + sdp_parser_t *parser; + sdp_session_t *sdp; + sdp_media_t *m; + sdp_connection_t *connection; + + if ((parser = sdp_parse(NULL, sdp_str, (int) strlen(sdp_str), 0))) { + if ((sdp = sdp_session(parser))) { + for (m = sdp->sdp_media; m; m = m->m_next) { + if (m->m_type != sdp_media_audio || !m->m_port) { + continue; + } + + connection = sdp->sdp_connection; + if (m->m_connections) { + connection = m->m_connections; + } + + if (connection) { + a_engine->codec_params.proxy_sdp_ip = switch_core_session_strdup(session, connection->c_address); + } + a_engine->codec_params.proxy_sdp_port = (switch_port_t) m->m_port; + if (a_engine->codec_params.proxy_sdp_ip && a_engine->codec_params.proxy_sdp_port) { + break; + } + } + } + sdp_parser_free(parser); + } + switch_core_media_set_local_sdp(session, sdp_str, SWITCH_TRUE); + } +} + + +//? +SWITCH_DECLARE(void) switch_core_media_set_image_sdp(switch_core_session_t *session, switch_t38_options_t *t38_options, int insist) +{ + char buf[2048] = ""; + char max_buf[128] = ""; + char max_data[128] = ""; + const char *ip; + uint32_t port; + const char *family = "IP4"; + const char *username; + const char *bit_removal_on = "a=T38FaxFillBitRemoval\n"; + const char *bit_removal_off = ""; + + const char *mmr_on = "a=T38FaxTranscodingMMR\n"; + const char *mmr_off = ""; + + const char *jbig_on = "a=T38FaxTranscodingJBIG\n"; + const char *jbig_off = ""; + const char *var; + int broken_boolean; + switch_media_handle_t *smh; + switch_rtp_engine_t *a_engine; + + if (!(smh = session->media_handle)) { + return; + } + + a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO]; + + + switch_assert(t38_options); + + ip = t38_options->local_ip; + port = t38_options->local_port; + username = smh->mparams->sdp_username; + + //sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA); + + var = switch_channel_get_variable(session->channel, "t38_broken_boolean"); + + broken_boolean = switch_true(var); + + + if (!ip) { + if (!(ip = a_engine->codec_params.adv_sdp_ip)) { + ip = a_engine->codec_params.proxy_sdp_ip; + } + } + + if (!ip) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s NO IP!\n", switch_channel_get_name(session->channel)); + return; + } + + if (!port) { + if (!(port = a_engine->codec_params.adv_sdp_port)) { + port = a_engine->codec_params.proxy_sdp_port; + } + } + + if (!port) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s NO PORT!\n", switch_channel_get_name(session->channel)); + return; + } + + if (!smh->owner_id) { + smh->owner_id = (uint32_t) switch_epoch_time_now(NULL) - port; + } + + if (!smh->session_id) { + smh->session_id = smh->owner_id; + } + + smh->session_id++; + + family = strchr(ip, ':') ? "IP6" : "IP4"; + + + switch_snprintf(buf, sizeof(buf), + "v=0\n" + "o=%s %010u %010u IN %s %s\n" + "s=%s\n" "c=IN %s %s\n" "t=0 0\n", username, smh->owner_id, smh->session_id, family, ip, username, family, ip); + + if (t38_options->T38FaxMaxBuffer) { + switch_snprintf(max_buf, sizeof(max_buf), "a=T38FaxMaxBuffer:%d\n", t38_options->T38FaxMaxBuffer); + }; + + if (t38_options->T38FaxMaxDatagram) { + switch_snprintf(max_data, sizeof(max_data), "a=T38FaxMaxDatagram:%d\n", t38_options->T38FaxMaxDatagram); + }; + + + + + if (broken_boolean) { + bit_removal_on = "a=T38FaxFillBitRemoval:1\n"; + bit_removal_off = "a=T38FaxFillBitRemoval:0\n"; + + mmr_on = "a=T38FaxTranscodingMMR:1\n"; + mmr_off = "a=T38FaxTranscodingMMR:0\n"; + + jbig_on = "a=T38FaxTranscodingJBIG:1\n"; + jbig_off = "a=T38FaxTranscodingJBIG:0\n"; + + } + + + switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), + "m=image %d udptl t38\n" + "a=T38FaxVersion:%d\n" + "a=T38MaxBitRate:%d\n" + "%s" + "%s" + "%s" + "a=T38FaxRateManagement:%s\n" + "%s" + "%s" + "a=T38FaxUdpEC:%s\n", + //"a=T38VendorInfo:%s\n", + port, + t38_options->T38FaxVersion, + t38_options->T38MaxBitRate, + t38_options->T38FaxFillBitRemoval ? bit_removal_on : bit_removal_off, + t38_options->T38FaxTranscodingMMR ? mmr_on : mmr_off, + t38_options->T38FaxTranscodingJBIG ? jbig_on : jbig_off, + t38_options->T38FaxRateManagement, + max_buf, + max_data, + t38_options->T38FaxUdpEC + //t38_options->T38VendorInfo ? t38_options->T38VendorInfo : "0 0 0" + ); + + + + if (insist) { + switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "m=audio 0 RTP/AVP 19\n"); + } + + switch_core_media_set_local_sdp(session, buf, SWITCH_TRUE); + + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s image media sdp:\n%s\n", + switch_channel_get_name(session->channel), smh->mparams->local_sdp_str); + + +} + + + +//? +SWITCH_DECLARE(void) switch_core_media_patch_sdp(switch_core_session_t *session) +{ + switch_size_t len; + char *p, *q, *pe, *qe; + int has_video = 0, has_audio = 0, has_ip = 0; + char port_buf[25] = ""; + char vport_buf[25] = ""; + char *new_sdp; + int bad = 0; + switch_media_handle_t *smh; + switch_rtp_engine_t *a_engine, *v_engine; + + if (!(smh = session->media_handle)) { + return; + } + + a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO]; + v_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO]; + + if (zstr(smh->mparams->local_sdp_str)) { + return; + } + + len = strlen(smh->mparams->local_sdp_str) * 2; + + if (switch_channel_test_flag(session->channel, CF_ANSWERED) && + (switch_stristr("sendonly", smh->mparams->local_sdp_str) || switch_stristr("0.0.0.0", smh->mparams->local_sdp_str))) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Skip patch on hold SDP\n"); + return; + } + + if (zstr(a_engine->codec_params.local_sdp_ip) || !a_engine->codec_params.local_sdp_port) { + if (switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_AUDIO, 1) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s I/O Error\n", + switch_channel_get_name(session->channel)); + return; + } + a_engine->codec_params.iananame = switch_core_session_strdup(session, "PROXY"); + a_engine->codec_params.rm_rate = 8000; + a_engine->codec_params.codec_ms = 20; + } + + new_sdp = switch_core_session_alloc(session, len); + switch_snprintf(port_buf, sizeof(port_buf), "%u", a_engine->codec_params.local_sdp_port); + + + p = smh->mparams->local_sdp_str; + q = new_sdp; + pe = p + strlen(p); + qe = q + len - 1; + + + while (p && *p) { + if (p >= pe) { + bad = 1; + goto end; + } + + if (q >= qe) { + bad = 2; + goto end; + } + + if (a_engine->codec_params.local_sdp_ip && !strncmp("c=IN IP", p, 7)) { + strncpy(q, p, 7); + p += 7; + q += 7; + strncpy(q, strchr(a_engine->codec_params.local_sdp_ip, ':') ? "6 " : "4 ", 2); + p +=2; + q +=2; + strncpy(q, a_engine->codec_params.local_sdp_ip, strlen(a_engine->codec_params.local_sdp_ip)); + q += strlen(a_engine->codec_params.local_sdp_ip); + + while (p && *p && ((*p >= '0' && *p <= '9') || *p == '.' || *p == ':' || (*p >= 'A' && *p <= 'F') || (*p >= 'a' && *p <= 'f'))) { + if (p >= pe) { + bad = 3; + goto end; + } + p++; + } + + has_ip++; + + } else if (!strncmp("o=", p, 2)) { + char *oe = strchr(p, '\n'); + switch_size_t len; + + if (oe) { + const char *family = "IP4"; + char o_line[1024] = ""; + + if (oe >= pe) { + bad = 5; + goto end; + } + + len = (oe - p); + p += len; + + + family = strchr(smh->mparams->sipip, ':') ? "IP6" : "IP4"; + + if (!smh->owner_id) { + smh->owner_id = (uint32_t) switch_epoch_time_now(NULL) * 31821U + 13849U; + } + + if (!smh->session_id) { + smh->session_id = smh->owner_id; + } + + smh->session_id++; + + + snprintf(o_line, sizeof(o_line), "o=%s %010u %010u IN %s %s\n", + smh->mparams->sdp_username, smh->owner_id, smh->session_id, family, smh->mparams->sipip); + + strncpy(q, o_line, strlen(o_line)); + q += strlen(o_line) - 1; + + } + + } else if (!strncmp("s=", p, 2)) { + char *se = strchr(p, '\n'); + switch_size_t len; + + if (se) { + char s_line[1024] = ""; + + if (se >= pe) { + bad = 5; + goto end; + } + + len = (se - p); + p += len; + + snprintf(s_line, sizeof(s_line), "s=%s\n", smh->mparams->sdp_username); + + strncpy(q, s_line, strlen(s_line)); + q += strlen(s_line) - 1; + + } + + } else if ((!strncmp("m=audio ", p, 8) && *(p + 8) != '0') || (!strncmp("m=image ", p, 8) && *(p + 8) != '0')) { + strncpy(q, p, 8); + p += 8; + + if (p >= pe) { + bad = 4; + goto end; + } + + + q += 8; + + if (q >= qe) { + bad = 5; + goto end; + } + + + strncpy(q, port_buf, strlen(port_buf)); + q += strlen(port_buf); + + if (q >= qe) { + bad = 6; + goto end; + } + + while (p && *p && (*p >= '0' && *p <= '9')) { + if (p >= pe) { + bad = 7; + goto end; + } + p++; + } + + has_audio++; + + } else if (!strncmp("m=video ", p, 8) && *(p + 8) != '0') { + if (!has_video) { + switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_VIDEO, 1); + v_engine->codec_params.rm_encoding = "PROXY-VID"; + v_engine->codec_params.rm_rate = 90000; + v_engine->codec_params.codec_ms = 0; + switch_snprintf(vport_buf, sizeof(vport_buf), "%u", v_engine->codec_params.adv_sdp_port); + if (switch_channel_media_ready(session->channel) && !switch_rtp_ready(v_engine->rtp_session)) { + switch_channel_set_flag(session->channel, CF_VIDEO_POSSIBLE); + switch_channel_set_flag(session->channel, CF_REINVITE); + switch_core_media_activate_rtp(session); + } + } + + strncpy(q, p, 8); + p += 8; + + if (p >= pe) { + bad = 8; + goto end; + } + + q += 8; + + if (q >= qe) { + bad = 9; + goto end; + } + + strncpy(q, vport_buf, strlen(vport_buf)); + q += strlen(vport_buf); + + if (q >= qe) { + bad = 10; + goto end; + } + + while (p && *p && (*p >= '0' && *p <= '9')) { + + if (p >= pe) { + bad = 11; + goto end; + } + + p++; + } + + has_video++; + } + + while (p && *p && *p != '\n') { + + if (p >= pe) { + bad = 12; + goto end; + } + + if (q >= qe) { + bad = 13; + goto end; + } + + *q++ = *p++; + } + + if (p >= pe) { + bad = 14; + goto end; + } + + if (q >= qe) { + bad = 15; + goto end; + } + + *q++ = *p++; + + } + + end: + + if (bad) { + return; + } + + + if (switch_channel_down(session->channel)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s too late.\n", switch_channel_get_name(session->channel)); + return; + } + + + if (!has_ip && !has_audio) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s SDP has no audio in it.\n%s\n", + switch_channel_get_name(session->channel), smh->mparams->local_sdp_str); + return; + } + + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Patched SDP\n---\n%s\n+++\n%s\n", + switch_channel_get_name(session->channel), smh->mparams->local_sdp_str, new_sdp); + + switch_core_media_set_local_sdp(session, new_sdp, SWITCH_FALSE); + +} + + + + /* For Emacs: * Local Variables: