[svn-commits] file: branch file/pimp_sip_nat r381827 - in /team/file/pimp_sip_nat: include/...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Feb 20 10:40:20 CST 2013


Author: file
Date: Wed Feb 20 10:40:17 2013
New Revision: 381827

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=381827
Log:
Add support for ICE to res_sip_sdp_audio.

Modified:
    team/file/pimp_sip_nat/include/asterisk/res_sip.h
    team/file/pimp_sip_nat/res/res_sip/sip_configuration.c
    team/file/pimp_sip_nat/res/res_sip_sdp_audio.c

Modified: team/file/pimp_sip_nat/include/asterisk/res_sip.h
URL: http://svnview.digium.com/svn/asterisk/team/file/pimp_sip_nat/include/asterisk/res_sip.h?view=diff&rev=381827&r1=381826&r2=381827
==============================================================================
--- team/file/pimp_sip_nat/include/asterisk/res_sip.h (original)
+++ team/file/pimp_sip_nat/include/asterisk/res_sip.h Wed Feb 20 10:40:17 2013
@@ -241,6 +241,8 @@
 	unsigned int rtp_ipv6;
 	/*! Whether symmetric RTP is enabled or not */
 	unsigned int rtp_symmetric;
+	/*! Whether ICE support is enabled or not */
+	unsigned int ice_support;
 	/*! Whether to use the "ptime" attribute received from the endpoint or not */
 	unsigned int use_ptime;
 	/*! Enabled SIP extensions */

Modified: team/file/pimp_sip_nat/res/res_sip/sip_configuration.c
URL: http://svnview.digium.com/svn/asterisk/team/file/pimp_sip_nat/res/res_sip/sip_configuration.c?view=diff&rev=381827&r1=381826&r2=381827
==============================================================================
--- team/file/pimp_sip_nat/res/res_sip/sip_configuration.c (original)
+++ team/file/pimp_sip_nat/res/res_sip/sip_configuration.c Wed Feb 20 10:40:17 2013
@@ -278,6 +278,7 @@
 	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "dtmfmode", "rfc4733", dtmf_handler, NULL, 0, 0);
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "rtp_ipv6", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, rtp_ipv6));
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "rtp_symmetric", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, rtp_symmetric));
+	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "ice_support", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, ice_support));
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "use_ptime", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, use_ptime));
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "transport", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, transport));
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "mohsuggest", "default", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, mohsuggest));

Modified: team/file/pimp_sip_nat/res/res_sip_sdp_audio.c
URL: http://svnview.digium.com/svn/asterisk/team/file/pimp_sip_nat/res/res_sip_sdp_audio.c?view=diff&rev=381827&r1=381826&r2=381827
==============================================================================
--- team/file/pimp_sip_nat/res/res_sip_sdp_audio.c (original)
+++ team/file/pimp_sip_nat/res/res_sip_sdp_audio.c Wed Feb 20 10:40:17 2013
@@ -81,6 +81,7 @@
 	pj_sockaddr addr;
 	char hostip[PJ_INET6_ADDRSTRLEN+2];
 	struct ast_sockaddr tmp;
+	struct ast_rtp_engine_ice *ice;
 
 	if (pj_gethostip(ipv6 ? pj_AF_INET6() : pj_AF_INET(), &addr) != PJ_SUCCESS) {
 		return -1;
@@ -101,6 +102,10 @@
 
 	ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(session->media[AST_SIP_MEDIA_AUDIO].rtp),
 					 session->media[AST_SIP_MEDIA_AUDIO].rtp, &session->endpoint->prefs);
+
+	if (!session->endpoint->ice_support && (ice = ast_rtp_instance_get_ice(session->media[AST_SIP_MEDIA_AUDIO].rtp))) {
+		ice->stop(session->media[AST_SIP_MEDIA_AUDIO].rtp);
+	}
 
 	return 0;
 }
@@ -145,10 +150,12 @@
 	pj_pool_t *pool = session->inv_session->pool_active;
 	pjmedia_sdp_media *media;
 	struct ast_sockaddr addr;
-	char tmp[32];
+	char tmp[512];
 	pj_str_t stmp;
 	pjmedia_sdp_attr *attr;
 	int index = 0, min_packet_size = 0, noncodec = (session->endpoint->dtmf == AST_SIP_DTMF_RFC_4733) ? AST_RTP_DTMF : 0;
+	struct ast_rtp_engine_ice *ice;
+	struct ao2_container *candidates;
 
 	if (!ast_format_cap_has_type(session->endpoint->codecs, AST_FORMAT_TYPE_AUDIO)) {
 		/* If no audio formats are configured don't add a stream */
@@ -158,7 +165,7 @@
 	}
 
 	if (!(media = pj_pool_zalloc(pool, sizeof(struct pjmedia_sdp_media))) ||
-	    !(media->conn = pj_pool_zalloc(pool, sizeof(struct pjmedia_sdp_conn)))) {
+		!(media->conn = pj_pool_zalloc(pool, sizeof(struct pjmedia_sdp_conn)))) {
 		return -1;
 	}
 
@@ -173,6 +180,56 @@
 	pj_strdup2(pool, &media->conn->addr, ast_sockaddr_stringify_addr_remote(&addr));
 	media->desc.port = (pj_uint16_t) ast_sockaddr_port(&addr);
 	media->desc.port_count = 1;
+
+	/* Add ICE attributes and candidates */
+	if ((ice = ast_rtp_instance_get_ice(session->media[AST_SIP_MEDIA_AUDIO].rtp)) &&
+		(candidates = ice->get_local_candidates(session->media[AST_SIP_MEDIA_AUDIO].rtp))) {
+		const char *username, *password;
+		struct ao2_iterator it_candidates;
+		struct ast_rtp_engine_ice_candidate *candidate;
+
+		if ((username = ice->get_ufrag(session->media[AST_SIP_MEDIA_AUDIO].rtp))) {
+			attr = pjmedia_sdp_attr_create(pool, "ice-ufrag", pj_cstr(&stmp, username));
+			media->attr[media->attr_count++] = attr;
+		}
+
+		if ((password = ice->get_password(session->media[AST_SIP_MEDIA_AUDIO].rtp))) {
+			attr = pjmedia_sdp_attr_create(pool, "ice-pwd", pj_cstr(&stmp, password));
+			media->attr[media->attr_count++] = attr;
+		}
+
+		it_candidates = ao2_iterator_init(candidates, 0);
+		for (; (candidate = ao2_iterator_next(&it_candidates)); ao2_ref(candidate, -1)) {
+			struct ast_str *attr_candidate = ast_str_create(128);
+
+			ast_str_set(&attr_candidate, -1, "%s %d %s %d %s ", candidate->foundation, candidate->id, candidate->transport,
+						candidate->priority, ast_sockaddr_stringify_host(&candidate->address));
+			ast_str_append(&attr_candidate, -1, "%s typ ", ast_sockaddr_stringify_port(&candidate->address));
+
+			switch (candidate->type) {
+				case AST_RTP_ICE_CANDIDATE_TYPE_HOST:
+					ast_str_append(&attr_candidate, -1, "host");
+					break;
+				case AST_RTP_ICE_CANDIDATE_TYPE_SRFLX:
+					ast_str_append(&attr_candidate, -1, "srflx");
+					break;
+				case AST_RTP_ICE_CANDIDATE_TYPE_RELAYED:
+					ast_str_append(&attr_candidate, -1, "relay");
+					break;
+			}
+
+			if (!ast_sockaddr_isnull(&candidate->relay_address)) {
+				ast_str_append(&attr_candidate, -1, " raddr %s rport ", ast_sockaddr_stringify_host(&candidate->relay_address));
+				ast_str_append(&attr_candidate, -1, " %s", ast_sockaddr_stringify_port(&candidate->relay_address));
+			}
+
+			attr = pjmedia_sdp_attr_create(pool, "candidate", pj_cstr(&stmp, ast_str_buffer(attr_candidate)));
+			media->attr[media->attr_count++] = attr;
+
+			ast_free(attr_candidate);
+		}
+		ao2_iterator_destroy(&it_candidates);
+	}
 
 	/* Add formats */
 	for (index = 0; (index < AST_CODEC_PREF_SIZE); index++) {
@@ -266,6 +323,7 @@
 	RAII_VAR(struct ast_format_cap *, jointcap, NULL, ast_format_cap_destroy);
 	RAII_VAR(struct ast_format_cap *, peercap, NULL, ast_format_cap_destroy);
 	struct ast_format fmt;
+	struct ast_rtp_engine_ice *ice;
 
 	/* Create an RTP instance if need be */
 	if (!session->media[AST_SIP_MEDIA_AUDIO].rtp && audio_create_rtp(session, session->endpoint->rtp_ipv6)) {
@@ -282,7 +340,7 @@
 
 	/* To properly apply formats to the channel we need to keep track of capabilities */
 	if (!(cap = ast_format_cap_alloc_nolock()) ||
-	    !(peercap = ast_format_cap_alloc_nolock())) {
+		!(peercap = ast_format_cap_alloc_nolock())) {
 		ast_log(LOG_ERROR, "Failed to allocate audio capabilities\n");
 		return -1;
 	}
@@ -308,7 +366,7 @@
 
 				ast_copy_pj_str(name, &rtpmap->enc_name, sizeof(name));
 				ast_rtp_codecs_payloads_set_rtpmap_type_rate(&codecs, NULL, pj_strtoul(&local_stream->desc.fmt[format]),
-									     "audio", name, 0, rtpmap->clock_rate);
+										 "audio", name, 0, rtpmap->clock_rate);
 			}
 		}
 	}
@@ -354,7 +412,7 @@
 	}
 
 	ast_rtp_codecs_payloads_copy(&codecs, ast_rtp_instance_get_codecs(session->media[AST_SIP_MEDIA_AUDIO].rtp),
-				     session->media[AST_SIP_MEDIA_AUDIO].rtp);
+					 session->media[AST_SIP_MEDIA_AUDIO].rtp);
 
 	/* Now that we have joint formats for audio remove the existing ones from the channel and add the new ones */
 	ast_format_cap_copy(cap, ast_channel_nativeformats(session->channel));
@@ -371,6 +429,75 @@
 
 	ast_channel_set_fd(session->channel, 0, ast_rtp_instance_fd(session->media[AST_SIP_MEDIA_AUDIO].rtp, 0));
 	ast_channel_set_fd(session->channel, 1, ast_rtp_instance_fd(session->media[AST_SIP_MEDIA_AUDIO].rtp, 1));
+
+	/* If ICE support is enabled find all the needed attributes */
+	if (session->endpoint->ice_support && (ice = ast_rtp_instance_get_ice(session->media[AST_SIP_MEDIA_AUDIO].rtp))) {
+		char attr_value[256];
+		unsigned int attr_i;
+
+		if ((attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-ufrag", NULL))) {
+			ast_copy_pj_str(attr_value, (pj_str_t*)&attr->value, sizeof(attr_value));
+			ice->set_authentication(session->media[AST_SIP_MEDIA_AUDIO].rtp, attr_value, NULL);
+		}
+
+		if ((attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-pwd", NULL))) {
+			ast_copy_pj_str(attr_value, (pj_str_t*)&attr->value, sizeof(attr_value));
+			ice->set_authentication(session->media[AST_SIP_MEDIA_AUDIO].rtp, NULL, attr_value);
+		}
+
+		if (pjmedia_sdp_media_find_attr2(remote_stream, "ice-lite", NULL)) {
+			ice->ice_lite(session->media[AST_SIP_MEDIA_AUDIO].rtp);
+		}
+
+		/* Find all of the candidates */
+		for (attr_i = 0; attr_i < remote_stream->attr_count; ++attr_i) {
+			char foundation[32], transport[4], address[46], cand_type[6], relay_address[46] = "";
+			int port, relay_port = 0;
+			struct ast_rtp_engine_ice_candidate candidate = { 0, };
+
+			attr = remote_stream->attr[attr_i];
+
+			/* If this is not a candidate line skip it */
+			if (pj_strcmp2(&attr->name, "candidate")) {
+				continue;
+			}
+
+			ast_copy_pj_str(attr_value, (pj_str_t*)&attr->value, sizeof(attr_value));
+
+			if (sscanf(attr_value, "%31s %30u %3s %30u %23s %30u typ %5s %*s %23s %*s %30u", foundation, &candidate.id, transport,
+				&candidate.priority, address, &port, cand_type, relay_address, &relay_port) < 7) {
+				/* Candidate did not parse properly */
+				continue;
+			}
+
+			candidate.foundation = foundation;
+			candidate.transport = transport;
+
+			ast_sockaddr_parse(&candidate.address, address, PARSE_PORT_FORBID);
+			ast_sockaddr_set_port(&candidate.address, port);
+
+			if (!strcasecmp(cand_type, "host")) {
+				candidate.type = AST_RTP_ICE_CANDIDATE_TYPE_HOST;
+			} else if (!strcasecmp(cand_type, "srflx")) {
+				candidate.type = AST_RTP_ICE_CANDIDATE_TYPE_SRFLX;
+			} else if (!strcasecmp(cand_type, "relay")) {
+				candidate.type = AST_RTP_ICE_CANDIDATE_TYPE_RELAYED;
+			} else {
+				continue;
+			}
+
+			if (!ast_strlen_zero(relay_address)) {
+				ast_sockaddr_parse(&candidate.relay_address, relay_address, PARSE_PORT_FORBID);
+			}
+
+			if (relay_port) {
+				ast_sockaddr_set_port(&candidate.relay_address, relay_port);
+			}
+
+			ice->add_remote_candidate(session->media[AST_SIP_MEDIA_AUDIO].rtp, &candidate);
+		}
+
+	}
 
 	if (session->media[AST_SIP_MEDIA_AUDIO].held && (!ast_sockaddr_isnull(addrs) ||
 							  !pjmedia_sdp_media_find_attr2(remote_stream, "sendonly", NULL))) {
@@ -381,7 +508,7 @@
 	} else if (ast_sockaddr_isnull(addrs) || ast_sockaddr_is_any(addrs) || pjmedia_sdp_media_find_attr2(remote_stream, "sendonly", NULL)) {
 		/* The remote side has put us on hold */
 		ast_queue_control_data(session->channel, AST_CONTROL_HOLD, S_OR(session->endpoint->mohsuggest, NULL),
-				       !ast_strlen_zero(session->endpoint->mohsuggest) ? strlen(session->endpoint->mohsuggest) + 1 : 0);
+					   !ast_strlen_zero(session->endpoint->mohsuggest) ? strlen(session->endpoint->mohsuggest) + 1 : 0);
 		ast_rtp_instance_stop(session->media[AST_SIP_MEDIA_AUDIO].rtp);
 		ast_queue_frame(session->channel, &ast_null_frame);
 		session->media[AST_SIP_MEDIA_AUDIO].held = 1;
@@ -461,4 +588,4 @@
 		.load = load_module,
 		.unload = unload_module,
 		.load_pri = AST_MODPRI_CHANNEL_DRIVER,
-	       );
+		   );




More information about the svn-commits mailing list