From 92ddf4729320d826b2aea993009127f530b42f5d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 22 Dec 2012 11:51:03 -0600 Subject: [PATCH] expose some rtp func via media handle --- src/include/switch_core_media.h | 17 +- src/include/switch_types.h | 2 + src/mod/endpoints/mod_sofia/mod_sofia.h | 133 +++++- src/mod/endpoints/mod_sofia/sofia.c | 6 +- src/mod/endpoints/mod_sofia/sofia_glue.c | 5 + src/switch_core_media.c | 514 ++++++++++++++++++++++- src/switch_core_session.c | 11 +- 7 files changed, 670 insertions(+), 18 deletions(-) diff --git a/src/include/switch_core_media.h b/src/include/switch_core_media.h index f72a85ea23..c9f7bee415 100644 --- a/src/include/switch_core_media.h +++ b/src/include/switch_core_media.h @@ -68,6 +68,7 @@ typedef enum { SCMF_PASS_RFC2833, SCMF_AUTOFLUSH, SCMF_REWRITE_TIMESTAMPS, + SCMF_RTP_AUTOFLUSH_DURING_BRIDGE, SCMF_MAX } switch_core_media_flag_t; @@ -139,6 +140,8 @@ typedef struct switch_core_media_params_s { char *adv_sdp_audio_ip; int num_codecs;//x:tp + int hold_laps;//x:tp + // HACK REMOVE ME switch_rtp_t *rtp_session; @@ -214,10 +217,21 @@ SWITCH_DECLARE(void)switch_core_media_set_local_sdp(switch_core_session_t *sessi SWITCH_DECLARE(void) switch_core_media_patch_sdp(switch_core_session_t *session); SWITCH_DECLARE(void) switch_core_media_set_image_sdp(switch_core_session_t *session, switch_t38_options_t *t38_options, int insist); SWITCH_DECLARE(void) switch_core_media_prepare_codecs(switch_core_session_t *session, switch_bool_t force); +SWITCH_DECLARE(void) switch_core_media_start_udptl(switch_core_session_t *session, switch_t38_options_t *t38_options); +SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg); - +SWITCH_DECLARE(void) switch_core_media_break(switch_media_handle_t *smh, switch_media_type_t type); +SWITCH_DECLARE(void) switch_core_media_kill_socket(switch_media_handle_t *smh, switch_media_type_t type); +SWITCH_DECLARE(switch_status_t) switch_core_media_queue_rfc2833(switch_media_handle_t *smh, switch_media_type_t type, const switch_dtmf_t *dtmf); +SWITCH_DECLARE(switch_status_t) switch_core_media_queue_rfc2833_in(switch_media_handle_t *smh, switch_media_type_t type, const switch_dtmf_t *dtmf); +SWITCH_DECLARE(uint8_t) switch_core_media_ready(switch_media_handle_t *smh, switch_media_type_t type); +SWITCH_DECLARE(void) switch_core_media_set_recv_pt(switch_media_handle_t *smh, switch_media_type_t type, switch_payload_t pt); +SWITCH_DECLARE(void) switch_core_media_set_telephony_event(switch_media_handle_t *smh, switch_media_type_t type, switch_payload_t te); +SWITCH_DECLARE(void) switch_core_media_set_telephony_recv_event(switch_media_handle_t *smh, switch_media_type_t type, switch_payload_t te); +SWITCH_DECLARE(switch_rtp_stats_t *) switch_core_media_stats(switch_media_handle_t *smh, switch_media_type_t type, switch_memory_pool_t *pool); +SWITCH_DECLARE(switch_status_t) switch_core_media_udptl_mode(switch_media_handle_t *smh, switch_media_type_t type); SWITCH_END_EXTERN_C #endif @@ -231,3 +245,4 @@ SWITCH_END_EXTERN_C * For VIM: * vim:set softtabstop=4 shiftwidth=4 tabstop=4: */ + diff --git a/src/include/switch_types.h b/src/include/switch_types.h index f13600063a..68d9984bfa 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1293,6 +1293,8 @@ typedef enum { CF_T38_PASSTHRU, CF_DROP_DTMF, CF_REINVITE, + CF_AUTOFLUSH_DURING_BRIDGE, + CF_RTP_NOTIMER_DURING_BRIDGE, /* 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 deefaa6dcb..992eaafff6 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -228,7 +228,6 @@ typedef enum { PFLAG_ALL_REG_OPTIONS_PING, PFLAG_MESSAGE_QUERY_ON_REGISTER, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER, - PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE, PFLAG_MANUAL_REDIRECT, PFLAG_AUTO_NAT, PFLAG_SIPCOMPACT, @@ -302,13 +301,11 @@ typedef enum { TFLAG_ZRTP_PASSTHRU, TFLAG_HOLD_LOCK, TFLAG_3PCC_HAS_ACK, - TFLAG_PASS_RFC2833, TFLAG_UPDATING_DISPLAY, TFLAG_ENABLE_SOA, TFLAG_T38_PASSTHRU, TFLAG_RECOVERED, TFLAG_AUTOFLUSH_DURING_BRIDGE, - TFLAG_JB_PAUSED, TFLAG_3PCC_INVITE, TFLAG_NOREPLY, TFLAG_GOT_ACK, @@ -524,8 +521,8 @@ struct sofia_profile { char *extrtpip; char *rtpip[MAX_RTPIP]; char *jb_msec; - switch_payload_t te;//x:tp - switch_payload_t recv_te;//x:tp + switch_payload_t te; + switch_payload_t recv_te; uint32_t rtpip_index; uint32_t rtpip_next; char *rtcp_audio_interval_msec; @@ -670,6 +667,131 @@ struct sofia_profile { switch_core_media_vflag_t vflags; }; +#if 0 +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_media_handle_t *media_handle; + switch_core_media_params_t mparams; + + //switch_frame_t read_frame; + char *codec_order[SWITCH_MAX_CODECS]; + //int codec_order_last; + const switch_codec_implementation_t *codecs[SWITCH_MAX_CODECS]; + + const switch_codec_implementation_t *negotiated_codecs[SWITCH_MAX_CODECS]; + //int num_negotiated_codecs; + //switch_codec_t read_codec; + //switch_codec_t write_codec; + //uint32_t codec_ms; + // uint32_t bitrate; + switch_caller_profile_t *caller_profile; + //uint32_t timestamp_send; + switch_rtp_t *rtp_session; + +// uint32_t video_ssrc; + sofia_profile_t *profile; + char *reply_contact; + char *from_uri; + char *to_uri; + char *from_address; + char *to_address; + char *callid; + char *contact_url; + char *from_str; + char *rpid; + char *asserted_id; + char *preferred_id; + char *privacy; + char *gateway_from_str; + char *rm_encoding; + char *iananame; + char *rm_fmtp; + char *fmtp_out; + char *dest; + char *dest_to; + char *key; + char *xferto; + char *kick; + char *origin; + char *hash_key; + char *chat_from; + char *chat_to; + char *e_dest; + char *call_id; + char *invite_contact; + char *local_url; + char *gateway_name; + char *record_route; + char *route_uri; + char *x_freeswitch_support_remote; + char *x_freeswitch_support_local; + char *last_sent_callee_id_name; + char *last_sent_callee_id_number; + + //unsigned long rm_rate; + //switch_payload_t pt; + switch_mutex_t *flag_mutex; + switch_mutex_t *sofia_mutex; + ////switch_payload_t te; + ////switch_payload_t recv_te; + //switch_payload_t bte; + //switch_payload_t cng_pt; + //switch_payload_t bcng_pt; + sofia_transport_t transport; + nua_handle_t *nh; + nua_handle_t *nh2; + sip_contact_t *contact; + //uint32_t max_missed_packets; + //uint32_t max_missed_hold_packets; + /** VIDEO **/ +// switch_frame_t video_read_frame; +// switch_codec_t video_read_codec; +// switch_codec_t video_write_codec; + switch_rtp_t *video_rtp_session; +// switch_port_t adv_sdp_video_port; +// switch_port_t local_sdp_video_port; +// char *video_rm_encoding; +// switch_payload_t video_pt; +// unsigned long video_rm_rate; +// uint32_t video_codec_ms; +// char *video_rm_fmtp; +// switch_payload_t video_agreed_pt; +// char *video_fmtp_out; +// uint32_t video_count; + //switch_core_media_dtmf_t dtmf_type; + int q850_cause; + int got_bye; + //int hold_laps; + switch_thread_id_t locker; + //switch_size_t last_ts; + //uint32_t check_frames; + //uint32_t mismatch_count; + //uint32_t last_codec_ms; + //uint8_t codec_reinvites; + nua_event_t want_event; + switch_rtp_bug_flag_t rtp_bugs; +// switch_rtp_bug_flag_t video_rtp_bugs; + //switch_codec_implementation_t read_impl; + //switch_codec_implementation_t write_impl; + char *user_via; + char *redirected; + sofia_cid_type_t cid_type; + switch_payload_t payload_space; + switch_payload_t ianacodes[SWITCH_MAX_CODECS]; + uint32_t session_timeout; + enum nua_session_refresher session_refresher; + char *respond_phrase; + int respond_code; + char *respond_dest; +}; + +#else struct private_object { sofia_private_t *sofia_private; uint8_t flags[TFLAG_MAX]; @@ -792,6 +914,7 @@ struct private_object { int respond_code; char *respond_dest; }; +#endif struct callback_t { char *val; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 784eed3e5f..f44acd2fce 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -3593,7 +3593,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) sofia_set_pflag(profile, PFLAG_DISABLE_100REL); profile->auto_restart = 1; sofia_set_media_flag(profile, SCMF_AUTOFIX_TIMING); - sofia_set_pflag(profile, PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE); + sofia_set_media_flag(profile, SCMF_RTP_AUTOFLUSH_DURING_BRIDGE); profile->contact_user = SOFIA_DEFAULT_CONTACT_USER; sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID); sofia_set_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE); @@ -5958,7 +5958,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (r_sdp) { const char *var; uint8_t match = 0, is_ok = 1, is_t38 = 0; - tech_pvt->hold_laps = 0; + tech_pvt->mparams.hold_laps = 0; if ((var = switch_channel_get_variable(channel, "sip_ignore_reinvites")) && switch_true(var)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Ignoring Re-invite\n"); @@ -5977,7 +5977,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (switch_channel_test_flag(channel, CF_PROXY_MODE) && !is_t38 && (profile->media_options & MEDIA_OPT_MEDIA_ON_HOLD)) { if (switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp)) { - tech_pvt->hold_laps = 1; + tech_pvt->mparams.hold_laps = 1; switch_channel_set_variable(channel, SWITCH_R_SDP_VARIABLE, r_sdp); switch_channel_clear_flag(channel, CF_PROXY_MODE); switch_core_media_set_local_sdp(tech_pvt->session, NULL, SWITCH_FALSE); diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 659c0c8755..2f0121b630 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -129,6 +129,11 @@ void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t * switch_channel_set_flag(tech_pvt->channel, CF_PASS_RFC2833); } + if (sofia_test_pflag(tech_pvt->profile, PFLAG_RTP_NOTIMER_DURING_BRIDGE)) { + switch_channel_set_flag(tech_pvt->channel, CF_RTP_NOTIMER_DURING_BRIDGE); + } + + switch_core_media_check_dtmf_type(session); switch_channel_set_cap(tech_pvt->channel, CC_MEDIA_ACK); diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 25026cd7e1..a06925afc4 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -44,8 +44,9 @@ #define MAX_MISMATCH_FRAMES 5//x:mod_sofia.h typedef enum { - SMH_INIT = (1 << 0), - SMH_READY = (1 << 1) + SMF_INIT = (1 << 0), + SMF_READY = (1 << 1), + SMF_JB_PAUSED = (1 << 2) } smh_flag_t; @@ -138,7 +139,7 @@ struct switch_media_handle_s { int payload_space;//x:tp char *origin;//x:tp - int hold_laps;//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 @@ -832,7 +833,7 @@ SWITCH_DECLARE(switch_status_t) switch_media_handle_create(switch_media_handle_t if ((session->media_handle = switch_core_session_alloc(session, (sizeof(*smh))))) { session->media_handle->session = session; *smhp = session->media_handle; - switch_set_flag(session->media_handle, SMH_INIT); + switch_set_flag(session->media_handle, SMF_INIT); session->media_handle->media_flags[SCMF_RUNNING] = 1; session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].read_frame.buflen = SWITCH_RTP_MAX_BUF_LEN; session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].read_frame.buflen = SWITCH_RTP_MAX_BUF_LEN; @@ -880,7 +881,7 @@ SWITCH_DECLARE(int32_t) switch_media_handle_test_media_flag(switch_media_handle_ SWITCH_DECLARE(switch_status_t) switch_core_session_media_handle_ready(switch_core_session_t *session) { - if (session->media_handle && switch_test_flag(session->media_handle, SMH_INIT)) { + if (session->media_handle && switch_test_flag(session->media_handle, SMF_INIT)) { return SWITCH_STATUS_SUCCESS; } @@ -1790,8 +1791,8 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s sendonly = 0; } else { - if (!smh->hold_laps) { - smh->hold_laps++; + if (!smh->mparams->hold_laps) { + smh->mparams->hold_laps++; if (switch_core_media_toggle_hold(session, sendonly)) { reneg = switch_media_handle_test_media_flag(smh, SCMF_RENEG_ON_HOLD); @@ -4808,6 +4809,504 @@ SWITCH_DECLARE(void) switch_core_media_patch_sdp(switch_core_session_t *session) } +//? +SWITCH_DECLARE(void) switch_core_media_start_udptl(switch_core_session_t *session, switch_t38_options_t *t38_options) +{ + switch_media_handle_t *smh; + switch_rtp_engine_t *a_engine;; + + if (!(smh = session->media_handle)) { + return; + } + + if (switch_channel_down(session->channel)) { + return; + } + + a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO]; + + + if (switch_rtp_ready(a_engine->rtp_session)) { + char *remote_host = switch_rtp_get_remote_host(a_engine->rtp_session); + switch_port_t remote_port = switch_rtp_get_remote_port(a_engine->rtp_session); + const char *err, *val; + + switch_channel_clear_flag(session->channel, CF_NOTIMER_DURING_BRIDGE); + switch_rtp_udptl_mode(a_engine->rtp_session); + + if (!t38_options || !t38_options->remote_ip) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No remote address\n"); + return; + } + + if (remote_host && remote_port && remote_port == t38_options->remote_port && !strcmp(remote_host, t38_options->remote_ip)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote address:port [%s:%d] has not changed.\n", + t38_options->remote_ip, t38_options->remote_port); + return; + } + + if (switch_rtp_set_remote_address(a_engine->rtp_session, t38_options->remote_ip, + t38_options->remote_port, 0, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "IMAGE UDPTL REPORTS ERROR: [%s]\n", err); + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "IMAGE UDPTL CHANGING DEST TO: [%s:%d]\n", + t38_options->remote_ip, t38_options->remote_port); + if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && + !((val = switch_channel_get_variable(session->channel, "disable_udptl_auto_adjust")) && switch_true(val))) { + /* Reactivate the NAT buster flag. */ + switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ); + } + } + } +} + + + + + +//? +SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg) +{ + switch_media_handle_t *smh; + switch_rtp_engine_t *a_engine, *v_engine; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (!(smh = session->media_handle)) { + return SWITCH_STATUS_FALSE; + } + + if (switch_channel_down(session->channel)) { + return SWITCH_STATUS_FALSE; + } + + a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO]; + v_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO]; + + switch (msg->message_id) { + + case SWITCH_MESSAGE_INDICATE_PROXY_MEDIA: + { + if (switch_rtp_ready(a_engine->rtp_session)) { + if (msg->numeric_arg) { + switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA); + } else { + switch_rtp_clear_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA); + } + } + } + break; + + case SWITCH_MESSAGE_INDICATE_JITTER_BUFFER: + { + if (switch_rtp_ready(a_engine->rtp_session)) { + int len = 0, maxlen = 0, qlen = 0, maxqlen = 50, max_drift = 0; + + if (msg->string_arg) { + char *p, *q; + const char *s; + + if (!strcasecmp(msg->string_arg, "pause")) { + switch_rtp_pause_jitter_buffer(a_engine->rtp_session, SWITCH_TRUE); + goto end; + } else if (!strcasecmp(msg->string_arg, "resume")) { + switch_rtp_pause_jitter_buffer(a_engine->rtp_session, SWITCH_FALSE); + goto end; + } else if (!strncasecmp(msg->string_arg, "debug:", 6)) { + s = msg->string_arg + 6; + if (s && !strcmp(s, "off")) { + s = NULL; + } + status = switch_rtp_debug_jitter_buffer(a_engine->rtp_session, s); + goto end; + } + + + if ((len = atoi(msg->string_arg))) { + qlen = len / (a_engine->read_impl.microseconds_per_packet / 1000); + if (qlen < 1) { + qlen = 3; + } + } + + if (qlen) { + if ((p = strchr(msg->string_arg, ':'))) { + p++; + maxlen = atol(p); + if ((q = strchr(p, ':'))) { + q++; + max_drift = abs(atol(q)); + } + } + } + + + if (maxlen) { + maxqlen = maxlen / (a_engine->read_impl.microseconds_per_packet / 1000); + } + } + + if (qlen) { + if (maxqlen < qlen) { + maxqlen = qlen * 5; + } + if (switch_rtp_activate_jitter_buffer(a_engine->rtp_session, qlen, maxqlen, + a_engine->read_impl.samples_per_packet, + a_engine->read_impl.samples_per_second, max_drift) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), + SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames) (%d max frames) (%d max drift)\n", + len, qlen, maxqlen, max_drift); + switch_channel_set_flag(session->channel, CF_JITTERBUFFER); + if (!switch_false(switch_channel_get_variable(session->channel, "sip_jitter_buffer_plc"))) { + switch_channel_set_flag(session->channel, CF_JITTERBUFFER_PLC); + } + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), + SWITCH_LOG_WARNING, "Error Setting Jitterbuffer to %dms (%d frames)\n", len, qlen); + } + + } else { + switch_rtp_deactivate_jitter_buffer(a_engine->rtp_session); + } + } + } + break; + case SWITCH_MESSAGE_INDICATE_DEBUG_AUDIO: + { + if (switch_rtp_ready(a_engine->rtp_session) && !zstr(msg->string_array_arg[0]) && !zstr(msg->string_array_arg[1])) { + int32_t flags = 0; + if (!strcasecmp(msg->string_array_arg[0], "read")) { + flags |= SWITCH_RTP_FLAG_DEBUG_RTP_READ; + } else if (!strcasecmp(msg->string_array_arg[0], "write")) { + flags |= SWITCH_RTP_FLAG_DEBUG_RTP_WRITE; + } else if (!strcasecmp(msg->string_array_arg[0], "both")) { + flags |= SWITCH_RTP_FLAG_DEBUG_RTP_READ | SWITCH_RTP_FLAG_DEBUG_RTP_WRITE; + } + + if (flags) { + if (switch_true(msg->string_array_arg[1])) { + switch_rtp_set_flag(a_engine->rtp_session, flags); + } else { + switch_rtp_clear_flag(a_engine->rtp_session, flags); + } + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid Options\n"); + } + } + } + goto end; + case SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY: + if (a_engine->rtp_session && switch_rtp_test_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Pass 2833 mode may not work on a transcoded call.\n"); + } + goto end; + + case SWITCH_MESSAGE_INDICATE_BRIDGE: + { + + if (switch_rtp_ready(a_engine->rtp_session)) { + const char *val; + int ok = 0; + + if (!(val = switch_channel_get_variable(session->channel, "sip_jitter_buffer_during_bridge")) || switch_false(val)) { + if (switch_channel_test_flag(session->channel, CF_JITTERBUFFER) && switch_channel_test_cap_partner(session->channel, CC_FS_RTP)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, + "%s PAUSE Jitterbuffer\n", switch_channel_get_name(session->channel)); + switch_rtp_pause_jitter_buffer(a_engine->rtp_session, SWITCH_TRUE); + switch_set_flag(smh, SMF_JB_PAUSED); + } + } + + if (switch_channel_test_flag(session->channel, CF_PASS_RFC2833) && switch_channel_test_flag_partner(session->channel, CF_FS_RTP)) { + switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, + "%s activate passthru 2833 mode.\n", switch_channel_get_name(session->channel)); + } + + + if ((val = switch_channel_get_variable(session->channel, "rtp_notimer_during_bridge"))) { + ok = switch_true(val); + } else { + ok = switch_channel_test_flag(session->channel, CF_RTP_NOTIMER_DURING_BRIDGE); + } + + if (ok && !switch_rtp_test_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_USE_TIMER)) { + ok = 0; + } + + if (ok) { + switch_rtp_clear_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_USE_TIMER); + switch_rtp_clear_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_NOBLOCK); + switch_channel_set_flag(session->channel, CF_NOTIMER_DURING_BRIDGE); + } + + if (ok && switch_channel_test_flag(session->channel, CF_NOTIMER_DURING_BRIDGE)) { + /* these are not compat */ + ok = 0; + } else { + if ((val = switch_channel_get_variable(session->channel, "rtp_autoflush_during_bridge"))) { + ok = switch_true(val); + } else { + ok = smh->media_flags[SCMF_RTP_AUTOFLUSH_DURING_BRIDGE]; + } + } + + if (ok) { + rtp_flush_read_buffer(a_engine->rtp_session, SWITCH_RTP_FLUSH_STICK); + switch_channel_set_flag(session->channel, CF_AUTOFLUSH_DURING_BRIDGE); + } else { + rtp_flush_read_buffer(a_engine->rtp_session, SWITCH_RTP_FLUSH_ONCE); + } + + } + } + goto end; + case SWITCH_MESSAGE_INDICATE_UNBRIDGE: + if (switch_rtp_ready(a_engine->rtp_session)) { + + if (switch_test_flag(smh, SMF_JB_PAUSED)) { + switch_clear_flag(smh, SMF_JB_PAUSED); + if (switch_channel_test_flag(session->channel, CF_JITTERBUFFER)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, + "%s RESUME Jitterbuffer\n", switch_channel_get_name(session->channel)); + switch_rtp_pause_jitter_buffer(a_engine->rtp_session, SWITCH_FALSE); + } + } + + + if (switch_rtp_test_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s deactivate passthru 2833 mode.\n", + switch_channel_get_name(session->channel)); + switch_rtp_clear_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833); + } + + if (switch_channel_test_flag(session->channel, CF_NOTIMER_DURING_BRIDGE)) { + if (!switch_rtp_test_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_UDPTL) && + !switch_rtp_test_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA)) { + switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_USE_TIMER); + switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_NOBLOCK); + } + switch_channel_clear_flag(session->channel, CF_NOTIMER_DURING_BRIDGE); + } + + if (switch_channel_test_flag(session->channel, CF_AUTOFLUSH_DURING_BRIDGE)) { + rtp_flush_read_buffer(a_engine->rtp_session, SWITCH_RTP_FLUSH_UNSTICK); + switch_channel_clear_flag(session->channel, CF_AUTOFLUSH_DURING_BRIDGE); + } else { + rtp_flush_read_buffer(a_engine->rtp_session, SWITCH_RTP_FLUSH_ONCE); + } + + } + goto end; + case SWITCH_MESSAGE_INDICATE_AUDIO_SYNC: + if (switch_rtp_ready(a_engine->rtp_session)) { + rtp_flush_read_buffer(a_engine->rtp_session, SWITCH_RTP_FLUSH_ONCE); + } + goto end; + + default: + break; + } + + + if (smh->mparams->mutex) switch_mutex_lock(smh->mparams->mutex); + + + if (switch_channel_down(session->channel)) { + status = SWITCH_STATUS_FALSE; + goto end_lock; + } + + switch (msg->message_id) { + case SWITCH_MESSAGE_INDICATE_MEDIA_RENEG: + { + switch_core_session_t *nsession; + + if (msg->string_arg) { + switch_channel_set_variable(session->channel, "absolute_codec_string", NULL); + if (*msg->string_arg == '=') { + switch_channel_set_variable(session->channel, "codec_string", msg->string_arg); + } else { + switch_channel_set_variable_printf(session->channel, "codec_string", "=%s%s%s,%s", + v_engine->codec_params.rm_encoding ? v_engine->codec_params.rm_encoding : "", + v_engine->codec_params.rm_encoding ? "," : "", + a_engine->codec_params.rm_encoding, msg->string_arg); + } + + + + a_engine->codec_params.rm_encoding = NULL; + v_engine->codec_params.rm_encoding = NULL; + switch_channel_clear_flag(session->channel, CF_VIDEO_POSSIBLE); + switch_core_media_prepare_codecs(session, SWITCH_TRUE); + switch_core_media_check_video_codecs(session); + switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 1); + } + + if (msg->numeric_arg && switch_core_session_get_partner(session, &nsession) == SWITCH_STATUS_SUCCESS) { + msg->numeric_arg = 0; + switch_core_session_receive_message(nsession, msg); + switch_core_session_rwunlock(nsession); + } + + } + break; + case SWITCH_MESSAGE_INDICATE_NOMEDIA: + { + const char *uuid; + switch_core_session_t *other_session; + switch_channel_t *other_channel; + const char *ip = NULL, *port = NULL; + + switch_channel_set_flag(session->channel, CF_PROXY_MODE); + if (a_engine->codec_params.rm_encoding) { + a_engine->codec_params.rm_encoding = NULL; + } + switch_core_media_set_local_sdp(session, NULL, SWITCH_FALSE); + + if ((uuid = switch_channel_get_partner_uuid(session->channel)) + && (other_session = switch_core_session_locate(uuid))) { + other_channel = switch_core_session_get_channel(other_session); + ip = switch_channel_get_variable(other_channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE); + port = switch_channel_get_variable(other_channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE); + switch_core_session_rwunlock(other_session); + if (ip && port) { + switch_core_media_gen_local_sdp(session, ip, (switch_port_t)atoi(port), NULL, 1); + } + } + + + if (!smh->mparams->local_sdp_str) { + switch_core_media_absorb_sdp(session); + } + + } + break; + case SWITCH_MESSAGE_INDICATE_AUDIO_DATA: + { + if (switch_rtp_ready(a_engine->rtp_session)) { + if (msg->numeric_arg) { + if (switch_channel_test_flag(session->channel, CF_JITTERBUFFER)) { + switch_rtp_pause_jitter_buffer(a_engine->rtp_session, SWITCH_TRUE); + switch_set_flag(smh, SMF_JB_PAUSED); + } + + rtp_flush_read_buffer(a_engine->rtp_session, SWITCH_RTP_FLUSH_UNSTICK); + + } else { + if (switch_test_flag(smh, SMF_JB_PAUSED)) { + switch_clear_flag(smh, SMF_JB_PAUSED); + if (switch_channel_test_flag(session->channel, CF_JITTERBUFFER)) { + switch_rtp_pause_jitter_buffer(a_engine->rtp_session, SWITCH_FALSE); + } + } + } + } + } + break; + + case SWITCH_MESSAGE_INDICATE_UDPTL_MODE: + { + switch_t38_options_t *t38_options = switch_channel_get_private(session->channel, "t38_options"); + + if (t38_options) { + switch_core_media_start_udptl(session, t38_options); + } + + } + + + default: + break; + } + + + end_lock: + + if (smh->mparams->mutex) switch_mutex_unlock(smh->mparams->mutex); + + end: + + if (switch_channel_down(session->channel)) { + status = SWITCH_STATUS_FALSE; + } + + return status; + +} + +SWITCH_DECLARE(void) switch_core_media_break(switch_media_handle_t *smh, switch_media_type_t type) +{ + if (switch_rtp_ready(smh->engines[type].rtp_session)) { + switch_rtp_break(smh->engines[type].rtp_session); + } +} + +SWITCH_DECLARE(void) switch_core_media_kill_socket(switch_media_handle_t *smh, switch_media_type_t type) +{ + if (switch_rtp_ready(smh->engines[type].rtp_session)) { + switch_rtp_kill_socket(smh->engines[type].rtp_session); + } +} + +SWITCH_DECLARE(switch_status_t) switch_core_media_queue_rfc2833(switch_media_handle_t *smh, switch_media_type_t type, const switch_dtmf_t *dtmf) +{ + if (switch_rtp_ready(smh->engines[type].rtp_session)) { + return switch_rtp_queue_rfc2833(smh->engines[type].rtp_session, dtmf); + } + return SWITCH_STATUS_FALSE; +} + +SWITCH_DECLARE(switch_status_t) switch_core_media_queue_rfc2833_in(switch_media_handle_t *smh, switch_media_type_t type, const switch_dtmf_t *dtmf) +{ + if (switch_rtp_ready(smh->engines[type].rtp_session)) { + return switch_rtp_queue_rfc2833_in(smh->engines[type].rtp_session, dtmf); + } + return SWITCH_STATUS_FALSE; +} + +SWITCH_DECLARE(uint8_t) switch_core_media_ready(switch_media_handle_t *smh, switch_media_type_t type) +{ + return switch_rtp_ready(smh->engines[type].rtp_session); +} + +SWITCH_DECLARE(void) switch_core_media_set_recv_pt(switch_media_handle_t *smh, switch_media_type_t type, switch_payload_t pt) +{ + if (switch_rtp_ready(smh->engines[type].rtp_session)) { + switch_rtp_set_recv_pt(smh->engines[type].rtp_session, pt); + } +} + +SWITCH_DECLARE(void) switch_core_media_set_telephony_event(switch_media_handle_t *smh, switch_media_type_t type, switch_payload_t te) +{ + if (switch_rtp_ready(smh->engines[type].rtp_session)) { + switch_rtp_set_telephony_event(smh->engines[type].rtp_session, te); + } +} + +SWITCH_DECLARE(void) switch_core_media_set_telephony_recv_event(switch_media_handle_t *smh, switch_media_type_t type, switch_payload_t te) +{ + if (switch_rtp_ready(smh->engines[type].rtp_session)) { + switch_rtp_set_telephony_recv_event(smh->engines[type].rtp_session, te); + } +} + +SWITCH_DECLARE(switch_rtp_stats_t *) switch_core_media_get_stats(switch_media_handle_t *smh, switch_media_type_t type, switch_memory_pool_t *pool) +{ + if (switch_rtp_ready(smh->engines[type].rtp_session)) { + return switch_rtp_get_stats(smh->engines[type].rtp_session, pool); + } + + return NULL; +} + +SWITCH_DECLARE(switch_status_t) switch_core_media_udptl_mode(switch_media_handle_t *smh, switch_media_type_t type) +{ + if (switch_rtp_ready(smh->engines[type].rtp_session)) { + return switch_rtp_udptl_mode(smh->engines[type].rtp_session); + } + return SWITCH_STATUS_FALSE; +} + @@ -4822,3 +5321,4 @@ SWITCH_DECLARE(void) switch_core_media_patch_sdp(switch_core_session_t *session) * For VIM: * vim:set softtabstop=4 shiftwidth=4 tabstop=4: */ + diff --git a/src/switch_core_session.c b/src/switch_core_session.c index dd617fe8d3..7a16ed4574 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -792,8 +792,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_perform_receive_message(swit switch_core_session_get_uuid(session), SWITCH_LOG_DEBUG, "%s skip receive message [%s] (channel is hungup already)\n", switch_channel_get_name(session->channel), message_names[message->message_id]); - } else if (session->endpoint_interface->io_routines->receive_message) { - status = session->endpoint_interface->io_routines->receive_message(session, message); + } else { + if (session->media_handle) { + status = switch_core_media_receive_message(session, message); + } + if (status == SWITCH_STATUS_SUCCESS) { + if (session->endpoint_interface->io_routines->receive_message) { + status = session->endpoint_interface->io_routines->receive_message(session, message); + } + } } if (status == SWITCH_STATUS_SUCCESS) {