diff --git a/src/include/switch_core_media.h b/src/include/switch_core_media.h index fff45129d4..d794918cb3 100644 --- a/src/include/switch_core_media.h +++ b/src/include/switch_core_media.h @@ -216,6 +216,7 @@ SWITCH_DECLARE(void) switch_core_media_pass_zrtp_hash(switch_core_session_t *ses SWITCH_DECLARE(const char *) switch_core_media_get_zrtp_hash(switch_core_session_t *session, switch_media_type_t type, switch_bool_t local); SWITCH_DECLARE(void) switch_core_media_pass_zrtp_hash2(switch_core_session_t *aleg_session, switch_core_session_t *bleg_session); SWITCH_DECLARE(int) switch_core_media_toggle_hold(switch_core_session_t *session, int sendonly); +SWITCH_DECLARE(void) switch_core_media_reset_t38(switch_core_session_t *session); SWITCH_DECLARE(void) switch_core_media_copy_t38_options(switch_t38_options_t *t38_options, switch_core_session_t *session); SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *session, const char *r_sdp, uint8_t *proceed, switch_sdp_type_t sdp_type); SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_codec(switch_core_session_t *session, int force); diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 3d924cbfc6..b2f91735a5 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1562,7 +1562,8 @@ typedef enum { CF_APP_T38 = (1 << 1), CF_APP_T38_REQ = (1 << 2), CF_APP_T38_FAIL = (1 << 3), - CF_APP_T38_NEGOTIATED = (1 << 4) + CF_APP_T38_NEGOTIATED = (1 << 4), + CF_APP_T38_POSSIBLE = (1 << 5) } switch_channel_app_flag_t; diff --git a/src/mod/applications/mod_spandsp/mod_spandsp.c b/src/mod/applications/mod_spandsp/mod_spandsp.c index fdbb44c5a6..4e4319bfb8 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp.c @@ -221,6 +221,8 @@ SWITCH_STANDARD_APP(t38_gateway_function) } } + switch_channel_set_app_flag_key("T38", channel, CF_APP_T38_POSSIBLE); + if (zstr(direction) || strcasecmp(direction, "self")) { direction = "peer"; } diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c index 3d175a18e5..81dabb3f44 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c @@ -1354,7 +1354,12 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat counter_increment(); - + if (app_mode == FUNCTION_GW || + switch_channel_var_true(channel, "fax_enable_t38") || + switch_channel_var_true(channel, "fax_enable_t38_insist")) { + switch_channel_set_app_flag_key("T38", channel, CF_APP_T38_POSSIBLE); + } + pvt = pvt_init(session, app_mode); switch_channel_set_private(channel, "_fax_pvt", pvt); @@ -1599,6 +1604,8 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat /* Destroy the SpanDSP structures */ spanfax_destroy(pvt); + switch_channel_clear_app_flag_key("T38", channel, CF_APP_T38_POSSIBLE); + /* restore the original codecs over the channel */ switch_core_session_set_read_codec(session, NULL); @@ -2071,6 +2078,9 @@ switch_bool_t t38_gateway_start(switch_core_session_t *session, const char *app, switch_channel_set_app_flag_key("T38", peer ? channel : other_channel, CF_APP_TAGGED); switch_channel_clear_app_flag_key("T38", peer ? other_channel : channel, CF_APP_TAGGED); + switch_channel_set_app_flag_key("T38", channel, CF_APP_T38_POSSIBLE); + switch_channel_set_app_flag_key("T38", other_channel, CF_APP_T38_POSSIBLE); + switch_channel_set_flag(channel, CF_REDIRECT); switch_channel_set_state(channel, CS_RESET); @@ -2268,6 +2278,7 @@ switch_status_t spandsp_fax_detect_session(switch_core_session_t *session, switch_codec_implementation_t read_impl = { 0 }; switch_core_session_get_read_impl(session, &read_impl); + if (timeout) { to = switch_epoch_time_now(NULL) + timeout; } @@ -2281,6 +2292,8 @@ switch_status_t spandsp_fax_detect_session(switch_core_session_t *session, return SWITCH_STATUS_MEMERR; } + switch_channel_set_app_flag_key("T38", channel, CF_APP_T38_POSSIBLE); + if (app) { cont->app = switch_core_session_strdup(session, app); } diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 369277e2d9..de780ef41a 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -6770,7 +6770,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status const char *r_sdp = NULL; switch_core_session_message_t *msg; private_object_t *other_tech_pvt = switch_core_session_get_private(other_session); - switch_channel_t *other_channel = switch_core_session_get_channel(other_session); + //switch_channel_t *other_channel = switch_core_session_get_channel(other_session); 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)) { @@ -6799,13 +6799,8 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status switch_core_session_rwunlock(other_session); goto end; } else if (status > 299) { - switch_channel_set_private(channel, "t38_options", NULL); - switch_channel_set_private(other_channel, "t38_options", NULL); - switch_channel_clear_flag(channel, CF_T38_PASSTHRU); - switch_channel_clear_flag(other_channel, CF_T38_PASSTHRU); - switch_channel_clear_app_flag_key("T38", channel, CF_APP_T38); - switch_channel_clear_app_flag_key("T38", channel, CF_APP_T38_REQ); - switch_channel_set_app_flag_key("T38", channel, CF_APP_T38_FAIL); + switch_core_media_reset_t38(session); + switch_core_media_reset_t38(other_session); } else if (status == 200 && switch_channel_test_flag(channel, CF_T38_PASSTHRU) && has_t38 && sip->sip_payload && sip->sip_payload->pl_data) { switch_t38_options_t *t38_options = switch_core_media_extract_t38_options(session, sip->sip_payload->pl_data); @@ -8127,8 +8122,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, goto done; } - switch_channel_set_flag(tech_pvt->channel, CF_REINVITE); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Reinvite Codec Error!\n"); + switch_channel_clear_flag(tech_pvt->channel, CF_REINVITE); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Reinvite resulted in codec negotiation failure.\n"); is_ok = 0; } } diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 6100766b41..827a305cc9 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -3465,6 +3465,8 @@ static int broadsoft_sla_gather_state_callback(void *pArg, int argc, char **argv callee_name = "unknown"; } + //callee_number = "666"; + if (data) { tmp = switch_core_sprintf(sh->pool, "%s,;%s;appearance-state=%s;appearance-uri=\"\\\"%s\\\" \"", diff --git a/src/switch_core.c b/src/switch_core.c index 606ccb59be..d38f3d1a92 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -2795,6 +2795,7 @@ SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, void * switch_set_flag((&runtime), SCF_RESTART); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Restarting\n"); } else { + assert(0); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Shutting down\n"); #ifdef _MSC_VER fclose(stdin); diff --git a/src/switch_core_media.c b/src/switch_core_media.c index da406d3ab7..8caa3a88d9 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -2450,7 +2450,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session engine = &smh->engines[type]; if (type == SWITCH_MEDIA_TYPE_AUDIO && ! switch_channel_test_flag(session->channel, CF_AUDIO)) { - //switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Reading audio from a non-audio session.\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "%s Reading audio from a non-audio session.\n", switch_channel_get_name(session->channel)); switch_yield(50000); return SWITCH_STATUS_INUSE; } @@ -4078,6 +4078,17 @@ static void clear_pmaps(switch_rtp_engine_t *engine) } } +static void restore_pmaps(switch_rtp_engine_t *engine) +{ + payload_map_t *pmap; + int top = 0; + + for (pmap = engine->payload_map; pmap && pmap->allocated; pmap = pmap->next) { + pmap->negotiated = 1; + if (!top++) pmap->current = 1; + } +} + //? SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *session, const char *r_sdp, uint8_t *proceed, switch_sdp_type_t sdp_type) { @@ -4387,22 +4398,30 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_channel_set_flag(session->channel, CF_IMAGE_SDP); if (m->m_port) { - switch_t38_options_t *t38_options = switch_core_media_process_udptl(session, sdp, m); - if (switch_channel_test_app_flag_key("T38", session->channel, CF_APP_T38_NEGOTIATED)) { fmatch = 1; goto done; } - if (switch_true(switch_channel_get_variable(channel, "refuse_t38"))) { + if (switch_channel_var_true(channel, "refuse_t38")) { switch_channel_clear_app_flag_key("T38", session->channel, CF_APP_T38); - match = 0; - goto done; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s T38 REFUSE on %s\n", + switch_channel_get_name(channel), + sdp_type == SDP_TYPE_RESPONSE ? "response" : "request"); + + restore_pmaps(a_engine); + fmatch = 0; + + goto t38_done; } else { + switch_t38_options_t *t38_options = switch_core_media_process_udptl(session, sdp, m); const char *var = switch_channel_get_variable(channel, "t38_passthru"); int pass = switch_channel_test_flag(smh->session->channel, CF_T38_PASSTHRU); - - + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s T38 ACCEPT on %s\n", + switch_channel_get_name(channel), + sdp_type == SDP_TYPE_RESPONSE ? "response" : "request"); + if (switch_channel_test_app_flag_key("T38", session->channel, CF_APP_T38)) { if (proceed) *proceed = 0; } @@ -4440,10 +4459,13 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s pass = 0; match = 0; + fmatch = 0; goto done; } - + switch_channel_set_app_flag_key("T38", channel, CF_APP_T38_POSSIBLE); + switch_channel_set_app_flag_key("T38", other_channel, CF_APP_T38_POSSIBLE); + if (switch_true(switch_channel_get_variable(session->channel, "t38_broken_boolean")) && switch_true(switch_channel_get_variable(session->channel, "t38_pass_broken_boolean"))) { switch_channel_set_variable(other_channel, "t38_broken_boolean", "true"); @@ -4494,7 +4516,19 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s /* do nothing here, mod_fax will trigger a response (if it's listening =/) */ - fmatch = 1; + if (switch_channel_test_app_flag_key("T38", channel, CF_APP_T38_POSSIBLE)) { + fmatch = 1; + } else { + + fmatch = 0; + } + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s T38 %s POSSIBLE on %s\n", + switch_channel_get_name(channel), + fmatch ? "IS" : "IS NOT", + sdp_type == SDP_TYPE_RESPONSE ? "response" : "request"); + + goto done; } } else if (m->m_type == sdp_media_audio && m->m_port && got_audio && got_savp) { @@ -5615,6 +5649,8 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_channel_clear_flag(channel, CF_IMAGE_SDP); } + t38_done: + if (parser) { sdp_parser_free(parser); } @@ -5625,6 +5661,30 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s return match || vmatch || tmatch || fmatch; } +//? +SWITCH_DECLARE(void) switch_core_media_reset_t38(switch_core_session_t *session) +{ + switch_rtp_engine_t *a_engine; + switch_media_handle_t *smh; + switch_channel_t *channel = switch_core_session_get_channel(session); + + switch_assert(session); + + if (!(smh = session->media_handle)) { + return; + } + + a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO]; + + restore_pmaps(a_engine); + + switch_channel_set_private(channel, "t38_options", NULL); + switch_channel_clear_flag(channel, CF_T38_PASSTHRU); + switch_channel_clear_app_flag_key("T38", channel, CF_APP_T38); + switch_channel_clear_app_flag_key("T38", channel, CF_APP_T38_REQ); + switch_channel_set_app_flag_key("T38", channel, CF_APP_T38_FAIL); +} + //? SWITCH_DECLARE(int) switch_core_media_toggle_hold(switch_core_session_t *session, int sendonly)