]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
MODENDP-206
authorMathieu Rene <mrene@avgs.ca>
Wed, 8 Apr 2009 06:05:56 +0000 (06:05 +0000)
committerMathieu Rene <mrene@avgs.ca>
Wed, 8 Apr 2009 06:05:56 +0000 (06:05 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@12946 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/mod/endpoints/mod_sofia/mod_sofia.h
src/mod/endpoints/mod_sofia/sofia.c
src/mod/endpoints/mod_sofia/sofia_glue.c

index 1452c223b057cc91c8303bae8ed8d07c8b50724f..3f93e60f3eeb82b045628565892591b9a776505c 100644 (file)
@@ -671,6 +671,8 @@ void launch_sofia_profile_thread(sofia_profile_t *profile);
 switch_status_t sofia_presence_chat_send(const char *proto, const char *from, const char *to, const char *subject,
                                                  const char *body, const char *type, const char *hint);
 void sofia_glue_tech_absorb_sdp(private_object_t *tech_pvt);
+
+void sofia_glue_set_r_sdp_codec_string(switch_channel_t *channel,const char *codec_string, sdp_session_t *sdp);
 switch_status_t sofia_glue_tech_media(private_object_t *tech_pvt, const char *r_sdp);
 char *sofia_reg_find_reg_url(sofia_profile_t *profile, const char *user, const char *host, char *val, switch_size_t len);
 void event_handler(switch_event_t *event);
index ae4eca7d2257f08e25266811bfaa2b321239c07c..40e55f102a46f8ec9b04c923e9bb0372d84b4369 100644 (file)
@@ -2886,9 +2886,19 @@ 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);
                
                if (r_sdp) {
+                       sdp_parser_t *parser;
+                       sdp_session_t *sdp;
+
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Remote SDP:\n%s\n", r_sdp);
                        tech_pvt->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) && (parser = sdp_parse(NULL, r_sdp, (int) strlen(r_sdp), 0))) {
+                               if ((sdp = sdp_session(parser))) {
+                                       sofia_glue_set_r_sdp_codec_string(channel, (tech_pvt->profile?tech_pvt->profile->codec_string:NULL), sdp);
+                               }
+                               sdp_parser_free(parser);
+                       }
                        sofia_glue_pass_sdp(tech_pvt, (char *) r_sdp);
                }
        }
index 1b77e00212fe31e504cc0781887797ab8a9c9d64..300bccd97d20ff3b145853c0ee0a35853c9004f2 100644 (file)
@@ -2380,6 +2380,142 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
 
 }
 
+void sofia_glue_set_r_sdp_codec_string(switch_channel_t *channel,const char *codec_string, sdp_session_t *sdp)
+{
+       char buf[1024] = {0};
+       sdp_media_t *m;
+       sdp_attribute_t *attr;
+       int ptime = 0, dptime = 0;
+       sdp_connection_t *connection;
+       sdp_rtpmap_t *map;
+       short int match = 0;
+       int i;
+       int already_did[128] = { 0 };
+       int num_codecs = 0;
+       char *codec_order[SWITCH_MAX_CODECS];
+       const switch_codec_implementation_t *codecs[SWITCH_MAX_CODECS] = { 0 };
+
+       if (codec_string) {
+               char *tmp_codec_string;
+               if ((tmp_codec_string = strdup(codec_string))) {
+                       num_codecs = switch_separate_string(tmp_codec_string, ',', codec_order, SWITCH_MAX_CODECS);
+                       num_codecs = switch_loadable_module_get_codecs_sorted(codecs, SWITCH_MAX_CODECS, codec_order, num_codecs);
+                       switch_safe_free(tmp_codec_string);
+               }
+       } else {
+               num_codecs = switch_loadable_module_get_codecs(codecs, SWITCH_MAX_CODECS);
+       }
+
+       if (!channel || !num_codecs) {
+               return;
+       }
+
+       for (attr = sdp->sdp_attributes; attr; attr = attr->a_next) {
+               if (switch_strlen_zero(attr->a_name)) {
+                       continue;
+               }
+
+               if (!strcasecmp(attr->a_name, "ptime")) {
+                       dptime = atoi(attr->a_value);
+                       break;
+               }
+       }
+
+       for (m = sdp->sdp_media; m; m = m->m_next) {
+               ptime = dptime;
+               if ( m->m_type == sdp_media_image && m->m_port) {
+                       switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",t38");
+               } else if (m->m_type == sdp_media_audio && m->m_port) {
+                       for (attr = m->m_attributes; attr; attr = attr->a_next) {
+                               if (switch_strlen_zero(attr->a_name)) {
+                                       continue;
+                               }
+                               if (!strcasecmp(attr->a_name, "ptime") && attr->a_value) {
+                                       ptime = atoi(attr->a_value);
+                                       break;
+                               }
+                       }
+                       connection = sdp->sdp_connection;
+                       if (m->m_connections) {
+                               connection = m->m_connections;
+                       }
+
+                       if (!connection) {
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find a c= line in the sdp at media or session level!\n");
+                               break;
+                       }
+
+                       for (i = 0; i < num_codecs; i++) {
+                               const switch_codec_implementation_t *imp = codecs[i];
+                               if (imp->codec_type != SWITCH_CODEC_TYPE_AUDIO || imp->ianacode > 127 || already_did[imp->ianacode]) {
+                                       continue;
+                               }
+                               for (map = m->m_rtpmaps; map; map = map->rm_next) {
+                                       if ( map->rm_pt > 127 ||  already_did[map->rm_pt]) {
+                                               continue;
+                                       }
+
+                                       if (map->rm_pt < 96) {
+                                               match = (map->rm_pt == imp->ianacode) ? 1 : 0;
+                                       } else {
+                                               if(map->rm_encoding) {
+                                                       match = strcasecmp(map->rm_encoding, imp->iananame) ? 0 : 1;
+                                               } else {
+                                                       match = 0;
+                                               }
+                                       }
+
+                                       if (match) {
+                                               switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",%s@%uh@%di", imp->iananame, (int) map->rm_rate, ptime);
+                                               already_did[imp->ianacode] = 1;
+                                               break;
+                                       }
+                               }
+                       }
+               } else if (m->m_type == sdp_media_video && m->m_port) {
+                       connection = sdp->sdp_connection;
+                       if (m->m_connections) {
+                               connection = m->m_connections;
+                       }
+
+                       if (!connection) {
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find a c= line in the sdp at media or session level!\n");
+                               break;
+                       }
+                       for (i = 0; i < num_codecs; i++) {
+                               const switch_codec_implementation_t *imp = codecs[i];
+                               if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO || imp->ianacode > 127 || already_did[imp->ianacode]) {
+                                       continue;
+                               }
+                               for (map = m->m_rtpmaps; map; map = map->rm_next) {
+                                       if ( map->rm_pt > 127 || already_did[map->rm_pt]) {
+                                               continue;
+                                       }
+
+                                       if (map->rm_pt < 96) {
+                                               match = (map->rm_pt == imp->ianacode) ? 1 : 0;
+                                       } else {
+                                               if(map->rm_encoding) {
+                                                       match = strcasecmp(map->rm_encoding, imp->iananame) ? 0 : 1;
+                                               } else {
+                                                       match = 0;
+                                               }
+                                       }
+
+                                       if (match) {
+                                               switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",%s@%uh@%di", imp->iananame, (int) map->rm_rate, ptime);
+                                               already_did[imp->ianacode] = 1;
+                                               break;
+                                       }
+                               }
+                       }
+               }
+       }
+       if (buf[0] == ',') {
+               switch_channel_set_variable(channel, "ep_codec_string", buf + 1);
+       }
+}
+
 switch_status_t sofia_glue_tech_media(private_object_t *tech_pvt, const char *r_sdp)
 {
        sdp_parser_t *parser = NULL;