[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