summaryrefslogtreecommitdiff
path: root/res
diff options
context:
space:
mode:
authorJenkins2 <jenkins2@gerrit.asterisk.org>2017-07-17 15:16:30 -0500
committerGerrit Code Review <gerrit2@gerrit.digium.api>2017-07-17 15:16:30 -0500
commit647f539e1569ad27c46352e58be9447e21c23923 (patch)
treea4d42c9bce7c5087b2bbc709af9815322cf599a9 /res
parent29af7d5558d325e262fc033fd1399e79bcefb0e0 (diff)
parent7da6ddda30ab9291ec810fa88d4219145616bae8 (diff)
Merge "res_pjsip: Add "webrtc" configuration option"
Diffstat (limited to 'res')
-rw-r--r--res/res_pjsip.c24
-rw-r--r--res/res_pjsip.exports.in1
-rw-r--r--res/res_pjsip/pjsip_configuration.c27
-rw-r--r--res/res_pjsip_sdp_rtp.c63
-rw-r--r--res/res_pjsip_session.c9
5 files changed, 118 insertions, 6 deletions
diff --git a/res/res_pjsip.c b/res/res_pjsip.c
index ee5c5fe5e..02112113c 100644
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -1010,6 +1010,18 @@
underlying transport. Note that enabling bundle will also enable the rtcp_mux option.
</para></description>
</configOption>
+ <configOption name="webrtc" default="no">
+ <synopsis>Defaults and enables some options that are relevant to WebRTC</synopsis>
+ <description><para>
+ When set to "yes" this also enables the following values that are needed in
+ order for basic WebRTC support to work: rtcp_mux, use_avpf, ice_support, and
+ use_received_transport. The following configuration settings also get defaulted
+ as follows:</para>
+ <para>media_encryption=dtls</para>
+ <para>dtls_verify=fingerprint</para>
+ <para>dtls_setup=actpass</para>
+ </description>
+ </configOption>
</configObject>
<configObject name="auth">
<synopsis>Authentication type</synopsis>
@@ -4244,6 +4256,18 @@ void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
dest[chars_to_copy] = '\0';
}
+int ast_copy_pj_str2(char **dest, const pj_str_t *src)
+{
+ int res = ast_asprintf(dest, "%.*s", (int)pj_strlen(src), pj_strbuf(src));
+
+ if (res < 0) {
+ *dest = NULL;
+ }
+
+ return res;
+}
+
+
int ast_sip_is_content_type(pjsip_media_type *content_type, char *type, char *subtype)
{
pjsip_media_type compare;
diff --git a/res/res_pjsip.exports.in b/res/res_pjsip.exports.in
index 8b62abbfe..4adecd419 100644
--- a/res/res_pjsip.exports.in
+++ b/res/res_pjsip.exports.in
@@ -2,6 +2,7 @@
global:
LINKER_SYMBOL_PREFIXast_sip_*;
LINKER_SYMBOL_PREFIXast_copy_pj_str;
+ LINKER_SYMBOL_PREFIXast_copy_pj_str2;
LINKER_SYMBOL_PREFIXast_pjsip_rdata_get_endpoint;
local:
*;
diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c
index c60173721..9f9de36fa 100644
--- a/res/res_pjsip/pjsip_configuration.c
+++ b/res/res_pjsip/pjsip_configuration.c
@@ -1363,8 +1363,30 @@ static int sip_endpoint_apply_handler(const struct ast_sorcery *sorcery, void *o
return -1;
}
- if (endpoint->media.bundle) {
- endpoint->media.rtcp_mux = 1;
+ endpoint->media.rtcp_mux |= endpoint->media.bundle;
+
+ /*
+ * If webrtc has been enabled then enable those attributes, and default
+ * some, that are needed in order for webrtc to work.
+ */
+ endpoint->media.bundle |= endpoint->media.webrtc;
+ endpoint->media.rtcp_mux |= endpoint->media.webrtc;
+ endpoint->media.rtp.use_avpf |= endpoint->media.webrtc;
+ endpoint->media.rtp.ice_support |= endpoint->media.webrtc;
+ endpoint->media.rtp.use_received_transport |= endpoint->media.webrtc;
+
+ if (endpoint->media.webrtc) {
+ endpoint->media.rtp.encryption = AST_SIP_MEDIA_ENCRYPT_DTLS;
+ endpoint->media.rtp.dtls_cfg.enabled = 1;
+ endpoint->media.rtp.dtls_cfg.default_setup = AST_RTP_DTLS_SETUP_ACTPASS;
+ endpoint->media.rtp.dtls_cfg.verify = AST_RTP_DTLS_VERIFY_FINGERPRINT;
+
+ if (ast_strlen_zero(endpoint->media.rtp.dtls_cfg.certfile) ||
+ (ast_strlen_zero(endpoint->media.rtp.dtls_cfg.cafile))) {
+ ast_log(LOG_ERROR, "WebRTC can't be enabled on endpoint '%s' - a DTLS cert "
+ "or ca file has not been specified", ast_sorcery_object_get_id(endpoint));
+ return -1;
+ }
}
return 0;
@@ -1990,6 +2012,7 @@ int ast_res_pjsip_initialize_configuration(void)
ast_sorcery_object_field_register(sip_sorcery, "endpoint", "max_audio_streams", "1", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, media.max_audio_streams));
ast_sorcery_object_field_register(sip_sorcery, "endpoint", "max_video_streams", "1", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, media.max_video_streams));
ast_sorcery_object_field_register(sip_sorcery, "endpoint", "bundle", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.bundle));
+ ast_sorcery_object_field_register(sip_sorcery, "endpoint", "webrtc", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.webrtc));
if (ast_sip_initialize_sorcery_transport()) {
ast_log(LOG_ERROR, "Failed to register SIP transport support with sorcery\n");
diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c
index 4ec811528..a2e7f8f92 100644
--- a/res/res_pjsip_sdp_rtp.c
+++ b/res/res_pjsip_sdp_rtp.c
@@ -1025,6 +1025,65 @@ static void process_ssrc_attributes(struct ast_sip_session *session, struct ast_
}
}
+static void process_msid_attribute(struct ast_sip_session *session,
+ struct ast_sip_session_media *session_media, pjmedia_sdp_media *media)
+{
+ pjmedia_sdp_attr *attr;
+
+ if (!session->endpoint->media.webrtc) {
+ return;
+ }
+
+ attr = pjmedia_sdp_media_find_attr2(media, "msid", NULL);
+ if (attr) {
+ ast_free(session_media->msid);
+ ast_copy_pj_str2(&session_media->msid, &attr->value);
+ }
+}
+
+static void add_msid_to_stream(struct ast_sip_session *session,
+ struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media)
+{
+ pj_str_t stmp;
+ pjmedia_sdp_attr *attr;
+
+ if (!session->endpoint->media.webrtc) {
+ return;
+ }
+
+ if (ast_strlen_zero(session_media->msid)) {
+ char uuid1[AST_UUID_STR_LEN], uuid2[AST_UUID_STR_LEN];
+
+ if (ast_asprintf(&session_media->msid, "{%s} {%s}",
+ ast_uuid_generate_str(uuid1, sizeof(uuid1)),
+ ast_uuid_generate_str(uuid2, sizeof(uuid2))) < 0) {
+ session_media->msid = NULL;
+ return;
+ }
+ }
+
+ attr = pjmedia_sdp_attr_create(pool, "msid", pj_cstr(&stmp, session_media->msid));
+ pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
+}
+
+static void add_rtcp_fb_to_stream(struct ast_sip_session *session,
+ struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media)
+{
+ pj_str_t stmp;
+ pjmedia_sdp_attr *attr;
+
+ if (!session->endpoint->media.webrtc || session_media->type != AST_MEDIA_TYPE_VIDEO) {
+ return;
+ }
+
+ /*
+ * For now just automatically add it the stream even though it hasn't
+ * necessarily been negotiated.
+ */
+ attr = pjmedia_sdp_attr_create(pool, "rtcp-fb", pj_cstr(&stmp, "* ccm fir"));
+ pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
+}
+
/*! \brief Function which negotiates an incoming media stream */
static int negotiate_incoming_sdp_stream(struct ast_sip_session *session,
struct ast_sip_session_media *session_media, const pjmedia_sdp_session *sdp,
@@ -1068,7 +1127,7 @@ static int negotiate_incoming_sdp_stream(struct ast_sip_session *session,
}
process_ssrc_attributes(session, session_media, stream);
-
+ process_msid_attribute(session, session_media, stream);
session_media_transport = ast_sip_session_media_get_transport(session, session_media);
if (session_media_transport == session_media || !session_media->bundled) {
@@ -1527,6 +1586,8 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as
}
add_ssrc_to_stream(session, session_media, pool, media);
+ add_msid_to_stream(session, session_media, pool, media);
+ add_rtcp_fb_to_stream(session, session_media, pool, media);
/* Add the media stream to the SDP */
sdp->media[sdp->media_count++] = media;
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index 315db6df5..fe3680f3b 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -395,6 +395,7 @@ static void session_media_dtor(void *obj)
}
ast_free(session_media->mid);
+ ast_free(session_media->msid);
}
struct ast_sip_session_media *ast_sip_session_media_state_add(struct ast_sip_session *session,
@@ -3573,15 +3574,17 @@ static int add_bundle_groups(struct ast_sip_session *session, pj_pool_t *pool, p
int index, mid_id;
struct sip_session_media_bundle_group *bundle_group;
+ if (session->endpoint->media.webrtc) {
+ attr = pjmedia_sdp_attr_create(pool, "msid-semantic", pj_cstr(&stmp, "WMS *"));
+ pjmedia_sdp_attr_add(&answer->attr_count, answer->attr, attr);
+ }
+
if (!session->endpoint->media.bundle) {
return 0;
}
memset(bundle_groups, 0, sizeof(bundle_groups));
- attr = pjmedia_sdp_attr_create(pool, "msid-semantic", pj_cstr(&stmp, "WMS *"));
- pjmedia_sdp_attr_add(&answer->attr_count, answer->attr, attr);
-
/* Build the bundle group layout so we can then add it to the SDP */
for (index = 0; index < AST_VECTOR_SIZE(&session->pending_media_state->sessions); ++index) {
struct ast_sip_session_media *session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, index);