summaryrefslogtreecommitdiff
path: root/res/res_pjsip_session.c
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2017-10-25 22:31:33 +0000
committerJoshua Colp <jcolp@digium.com>2017-10-30 22:09:59 +0000
commit046c250199d4be728463e8450894d4864e7287fd (patch)
treef927eb58a7b9e0b31cff38817c21dc3f334f7851 /res/res_pjsip_session.c
parent760fab5e0b6899651e10e0e1d86d6adb5b3e33b3 (diff)
core / pjsip: Add support for grouping streams together.
In WebRTC streams (or media tracks in their world) can be grouped together using the mslabel. This informs the browser that each should be synchronized with each other. This change extends the stream API so this information can be stored with streams. The PJSIP support has been extended to use the mslabel to determine grouped streams and store this association on the streams. Finally when creating the SDP the group information is used to cause each media stream to use the same mslabel. ASTERISK-27379 Change-Id: Id6299aa031efe46254edbdc7973c534d54d641ad
Diffstat (limited to 'res/res_pjsip_session.c')
-rw-r--r--res/res_pjsip_session.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index 37ff53105..4724d46ce 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -399,6 +399,7 @@ static void session_media_dtor(void *obj)
}
ast_free(session_media->mid);
+ ast_free(session_media->remote_mslabel);
}
struct ast_sip_session_media *ast_sip_session_media_state_add(struct ast_sip_session *session,
@@ -553,6 +554,70 @@ static int set_mid_and_bundle_group(struct ast_sip_session *session,
return 0;
}
+static void set_remote_mslabel_and_stream_group(struct ast_sip_session *session,
+ struct ast_sip_session_media *session_media,
+ const pjmedia_sdp_session *sdp,
+ const struct pjmedia_sdp_media *stream,
+ struct ast_stream *asterisk_stream)
+{
+ int index;
+
+ ast_free(session_media->remote_mslabel);
+ session_media->remote_mslabel = NULL;
+
+ for (index = 0; index < stream->attr_count; ++index) {
+ pjmedia_sdp_attr *attr = stream->attr[index];
+ char attr_value[pj_strlen(&attr->value) + 1];
+ char *ssrc_attribute_name, *ssrc_attribute_value = NULL;
+ char *msid, *tmp = attr_value;
+ static const pj_str_t STR_msid = { "msid", 4 };
+ static const pj_str_t STR_ssrc = { "ssrc", 4 };
+
+ if (!pj_strcmp(&attr->name, &STR_msid)) {
+ ast_copy_pj_str(attr_value, &attr->value, sizeof(attr_value));
+ msid = strsep(&tmp, " ");
+ session_media->remote_mslabel = ast_strdup(msid);
+ break;
+ } else if (!pj_strcmp(&attr->name, &STR_ssrc)) {
+ ast_copy_pj_str(attr_value, &attr->value, sizeof(attr_value));
+
+ if ((ssrc_attribute_name = strchr(attr_value, ' '))) {
+ /* This has an actual attribute */
+ *ssrc_attribute_name++ = '\0';
+ ssrc_attribute_value = strchr(ssrc_attribute_name, ':');
+ if (ssrc_attribute_value) {
+ /* Values are actually optional according to the spec */
+ *ssrc_attribute_value++ = '\0';
+ }
+
+ if (!strcasecmp(ssrc_attribute_name, "mslabel") && !ast_strlen_zero(ssrc_attribute_value)) {
+ session_media->remote_mslabel = ast_strdup(ssrc_attribute_value);
+ break;
+ }
+ }
+ }
+ }
+
+ if (ast_strlen_zero(session_media->remote_mslabel)) {
+ return;
+ }
+
+ /* Iterate through the existing streams looking for a match and if so then group this with it */
+ for (index = 0; index < AST_VECTOR_SIZE(&session->pending_media_state->sessions); ++index) {
+ struct ast_sip_session_media *group_session_media;
+
+ group_session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, index);
+
+ if (ast_strlen_zero(group_session_media->remote_mslabel) ||
+ strcmp(group_session_media->remote_mslabel, session_media->remote_mslabel)) {
+ continue;
+ }
+
+ ast_stream_set_group(asterisk_stream, index);
+ break;
+ }
+}
+
static void remove_stream_from_bundle(struct ast_sip_session_media *session_media,
struct ast_stream *stream)
{
@@ -630,6 +695,7 @@ static int handle_incoming_sdp(struct ast_sip_session *session, const pjmedia_sd
}
set_mid_and_bundle_group(session, session_media, sdp, remote_stream);
+ set_remote_mslabel_and_stream_group(session, session_media, sdp, remote_stream, stream);
if (session_media->handler) {
handler = session_media->handler;
@@ -730,6 +796,7 @@ static int handle_negotiated_sdp_session_media(struct ast_sip_session_media *ses
ast_copy_pj_str(media, &local->media[index]->desc.media, sizeof(media));
set_mid_and_bundle_group(session, session_media, remote, remote->media[index]);
+ set_remote_mslabel_and_stream_group(session, session_media, remote, remote->media[index], asterisk_stream);
handler = session_media->handler;
if (handler) {