]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
first crack at multipart content in invites
authorAnthony Minessale <anthm@freeswitch.org>
Tue, 1 Jun 2010 22:13:22 +0000 (17:13 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Tue, 1 Jun 2010 22:13:32 +0000 (17:13 -0500)
src/mod/endpoints/mod_sofia/mod_sofia.h
src/mod/endpoints/mod_sofia/sofia.c
src/mod/endpoints/mod_sofia/sofia_glue.c

index be50dba83f0b1e0eb06d0f5d8e25b3f5526f5059..1de46e97d6dd40882e945cb39ba8043a6c71cc97 100644 (file)
@@ -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);
index 29fbbd8fdff580e42aeea2ce63b9882be5f4635f..9f5e673a8c1a7ee8a10aaaf9ecd103efa15dbcca 100644 (file)
@@ -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);
index eaae144078ec9042d01ce55b527b871864045eb1..c261b2bd425305e91ac19d854a395e722eb6f97d 100644 (file)
@@ -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;