From c17eefb2a4dfefc2030823bafaf49243fd8dacf5 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 1 Jun 2010 17:13:22 -0500 Subject: [PATCH] first crack at multipart content in invites --- src/mod/endpoints/mod_sofia/mod_sofia.h | 2 + src/mod/endpoints/mod_sofia/sofia.c | 15 +++++-- src/mod/endpoints/mod_sofia/sofia_glue.c | 56 ++++++++++++++++++++++-- 3 files changed, 66 insertions(+), 7 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index be50dba83f..1de46e97d6 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -88,6 +88,7 @@ typedef struct private_object private_object_t; #define SOFIA_REPLACES_HEADER "_sofia_replaces_" #define SOFIA_USER_AGENT "FreeSWITCH-mod_sofia/" SWITCH_VERSION_MAJOR "." SWITCH_VERSION_MINOR "." SWITCH_VERSION_MICRO "-" SWITCH_VERSION_REVISION #define SOFIA_CHAT_PROTO "sip" +#define SOFIA_MULTIPART_PREFIX "sip_mp_" #define SOFIA_SIP_HEADER_PREFIX "sip_h_" #define SOFIA_SIP_RESPONSE_HEADER_PREFIX "sip_rh_" #define SOFIA_SIP_BYE_HEADER_PREFIX "sip_bye_h_" @@ -989,3 +990,4 @@ const char *sofia_gateway_status_name(sofia_gateway_status_t status); void sofia_reg_fire_custom_gateway_state_event(sofia_gateway_t *gateway, int status, const char *phrase); void sofia_glue_copy_t38_options(switch_t38_options_t *t38_options, switch_core_session_t *session); switch_t38_options_t *sofia_glue_extract_t38_options(switch_core_session_t *session, const char *r_sdp); +char *sofia_glue_get_multipart(switch_core_session_t *session, const char *prefix, const char *sdp, char **mp_type); diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 29fbbd8fdf..9f5e673a8c 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -5805,10 +5805,6 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ char sip_acl_authed_by[512] = ""; char sip_acl_token[512] = ""; - if (sip->sip_multipart) { - printf("W0000000t\n"); - } - profile->ib_calls++; if (sess_count >= sess_max || !sofia_test_pflag(profile, PFLAG_RUNNING)) { @@ -6353,6 +6349,17 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ } } + + if (sip->sip_multipart) { + msg_multipart_t *mp; + + for (mp = sip->sip_multipart; mp; mp = mp->mp_next) { + if (mp->mp_payload && mp->mp_payload->pl_data && mp->mp_content_type && mp->mp_content_type->c_type) { + switch_channel_set_variable_name_printf(channel, mp->mp_payload->pl_data, SOFIA_MULTIPART_PREFIX "%s", mp->mp_content_type->c_type); + } + } + } + if (sip->sip_max_forwards) { char max_forwards[32]; switch_snprintf(max_forwards, sizeof(max_forwards), "%lu", sip->sip_max_forwards->mf_count); diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index eaae144078..c261b2bd42 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -1506,6 +1506,48 @@ void sofia_glue_tech_set_local_sdp(private_object_t *tech_pvt, const char *sdp_s switch_mutex_unlock(tech_pvt->sofia_mutex); } +char *sofia_glue_get_multipart(switch_core_session_t *session, const char *prefix, const char *sdp, char **mp_type) +{ + char *extra_headers = NULL; + switch_stream_handle_t stream = { 0 }; + switch_event_header_t *hi = NULL; + int x = 0; + switch_channel_t *channel = switch_core_session_get_channel(session); + const char *boundary = switch_core_session_get_uuid(session); + + SWITCH_STANDARD_STREAM(stream); + if ((hi = switch_channel_variable_first(channel))) { + for (; hi; hi = hi->next) { + const char *name = (char *) hi->name; + char *value = (char *) hi->value; + + if (!strncasecmp(name, prefix, strlen(prefix))) { + const char *hname = name + strlen(prefix); + stream.write_function(&stream, "--%s\nContent-Type: %s\nContent-Length: %d\n\n%s\n", boundary, hname, strlen(value) + 1, value); + x++; + } + } + switch_channel_variable_last(channel); + } + + if (x) { + *mp_type = switch_core_session_sprintf(session, "multipart/mixed; boundary=%s", boundary); + if (sdp) { + stream.write_function(&stream, "--%s\nContent-Type: application/sdp\nContent-Length: %d\n\n%s\n", boundary, strlen(sdp) + 1, sdp); + } + stream.write_function(&stream, "--%s--\n", boundary); + } + + if (!zstr((char *) stream.data)) { + extra_headers = stream.data; + } else { + switch_safe_free(stream.data); + } + + return extra_headers; +} + + char *sofia_glue_get_extra_headers(switch_channel_t *channel, const char *prefix) { char *extra_headers = NULL; @@ -1583,7 +1625,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) const char *invite_full_to = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_to"); const char *handle_full_from = switch_channel_get_variable(tech_pvt->channel, "sip_handle_full_from"); const char *handle_full_to = switch_channel_get_variable(tech_pvt->channel, "sip_handle_full_to"); - + char *mp = NULL, *mp_type = NULL; rep = switch_channel_get_variable(channel, SOFIA_REPLACES_HEADER); @@ -2018,6 +2060,10 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) tech_pvt->nh->nh_has_invite = 1; } + if ((mp = sofia_glue_get_multipart(session, SOFIA_MULTIPART_PREFIX, tech_pvt->local_sdp_str, &mp_type))) { + sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA); + } + if (sofia_use_soa(tech_pvt)) { nua_invite(tech_pvt->nh, NUTAG_AUTOANSWER(0), @@ -2069,12 +2115,16 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) TAG_IF(tech_pvt->profile->minimum_session_expires, NUTAG_MIN_SE(tech_pvt->profile->minimum_session_expires)), TAG_IF(cseq, SIPTAG_CSEQ(cseq)), NUTAG_MEDIA_ENABLE(0), - SIPTAG_CONTENT_TYPE_STR("application/sdp"), - SIPTAG_PAYLOAD_STR(tech_pvt->local_sdp_str), TAG_IF(rep, SIPTAG_REPLACES_STR(rep)), SOATAG_HOLD(holdstr), TAG_END()); + 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()); } sofia_glue_free_destination(dst); switch_safe_free(extra_headers); + switch_safe_free(mp); tech_pvt->redirected = NULL; return SWITCH_STATUS_SUCCESS;