mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-20 08:41:07 +00:00
webrtcbin: Allow session level setup attribute in SDP
An SDP answer can declare its setup attribute at the session level or at the media level. Until this patch we were validating only the latter case and an assert was raised in the former case. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6930>
This commit is contained in:
parent
47087e1243
commit
299a000917
4 changed files with 125 additions and 10 deletions
|
@ -5747,7 +5747,15 @@ _update_transceiver_from_sdp_media (GstWebRTCBin * webrtc,
|
|||
GstWebRTCDTLSSetup local_setup, remote_setup;
|
||||
|
||||
local_setup = _get_dtls_setup_from_media (local_media);
|
||||
if (local_setup == GST_WEBRTC_DTLS_SETUP_NONE)
|
||||
local_setup =
|
||||
_get_dtls_setup_from_session (webrtc->current_local_description->sdp);
|
||||
|
||||
remote_setup = _get_dtls_setup_from_media (remote_media);
|
||||
if (remote_setup == GST_WEBRTC_DTLS_SETUP_NONE)
|
||||
remote_setup =
|
||||
_get_dtls_setup_from_session (webrtc->
|
||||
current_remote_description->sdp);
|
||||
new_setup = _get_final_setup (local_setup, remote_setup);
|
||||
if (new_setup == GST_WEBRTC_DTLS_SETUP_NONE) {
|
||||
g_set_error (error, GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_SDP_SYNTAX_ERROR,
|
||||
|
|
|
@ -236,9 +236,20 @@ _media_get_ice_pwd (const GstSDPMessage * msg, guint media_idx)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
_media_has_setup (const GstSDPMedia * media, guint media_idx, GError ** error)
|
||||
_validate_setup_attribute (const gchar * setup, GError ** error)
|
||||
{
|
||||
static const gchar *valid_setups[] = { "actpass", "active", "passive", NULL };
|
||||
if (!g_strv_contains (valid_setups, setup)) {
|
||||
g_set_error (error, GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_SDP_SYNTAX_ERROR,
|
||||
"SDP contains unknown \'setup\' attribute, \'%s\'", setup);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_media_has_setup (const GstSDPMedia * media, guint media_idx, GError ** error)
|
||||
{
|
||||
const gchar *setup = gst_sdp_media_get_attribute_val (media, "setup");
|
||||
if (IS_EMPTY_SDP_ATTRIBUTE (setup)) {
|
||||
g_set_error (error, GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_SDP_SYNTAX_ERROR,
|
||||
|
@ -246,13 +257,7 @@ _media_has_setup (const GstSDPMedia * media, guint media_idx, GError ** error)
|
|||
media_idx);
|
||||
return FALSE;
|
||||
}
|
||||
if (!g_strv_contains (valid_setups, setup)) {
|
||||
g_set_error (error, GST_WEBRTC_ERROR, GST_WEBRTC_ERROR_SDP_SYNTAX_ERROR,
|
||||
"media %u contains unknown \'setup\' attribute, \'%s\'", media_idx,
|
||||
setup);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
return _validate_setup_attribute (setup, error);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -273,9 +278,11 @@ gboolean
|
|||
validate_sdp (GstWebRTCSignalingState state, SDPSource source,
|
||||
GstWebRTCSessionDescription * sdp, GError ** error)
|
||||
{
|
||||
const gchar *group, *bundle_ice_ufrag = NULL, *bundle_ice_pwd = NULL;
|
||||
const gchar *group, *bundle_ice_ufrag = NULL, *bundle_ice_pwd = NULL, *setup =
|
||||
NULL;
|
||||
gchar **group_members = NULL;
|
||||
gboolean is_bundle = FALSE;
|
||||
gboolean has_session_setup = FALSE;
|
||||
int i;
|
||||
|
||||
if (!_check_valid_state_for_sdp_change (state, source, sdp->type, error))
|
||||
|
@ -290,6 +297,13 @@ validate_sdp (GstWebRTCSignalingState state, SDPSource source,
|
|||
if (is_bundle)
|
||||
group_members = g_strsplit (&group[6], " ", -1);
|
||||
|
||||
setup = gst_sdp_message_get_attribute_val (sdp->sdp, "setup");
|
||||
if (setup) {
|
||||
if (!_validate_setup_attribute (setup, error))
|
||||
return FALSE;
|
||||
has_session_setup = TRUE;
|
||||
}
|
||||
|
||||
for (i = 0; i < gst_sdp_message_medias_len (sdp->sdp); i++) {
|
||||
const GstSDPMedia *media = gst_sdp_message_get_media (sdp->sdp, i);
|
||||
const gchar *mid;
|
||||
|
@ -310,7 +324,7 @@ validate_sdp (GstWebRTCSignalingState state, SDPSource source,
|
|||
"media %u is missing or contains an empty \'ice-pwd\' attribute", i);
|
||||
goto fail;
|
||||
}
|
||||
if (!_media_has_setup (media, i, error))
|
||||
if (!has_session_setup && !_media_has_setup (media, i, error))
|
||||
goto fail;
|
||||
/* check parameters in bundle are the same */
|
||||
if (media_in_bundle) {
|
||||
|
@ -527,6 +541,26 @@ _get_dtls_setup_from_media (const GstSDPMedia * media)
|
|||
return SETUP (NONE);
|
||||
}
|
||||
|
||||
GstWebRTCDTLSSetup
|
||||
_get_dtls_setup_from_session (const GstSDPMessage * sdp)
|
||||
{
|
||||
const gchar *attr = gst_sdp_message_get_attribute_val (sdp, "setup");
|
||||
if (!attr) {
|
||||
GST_LOG ("no setup attribute in session");
|
||||
return SETUP (NONE);
|
||||
}
|
||||
if (g_strcmp0 (attr, "actpass") == 0) {
|
||||
return SETUP (ACTPASS);
|
||||
} else if (g_strcmp0 (attr, "active") == 0) {
|
||||
return SETUP (ACTIVE);
|
||||
} else if (g_strcmp0 (attr, "passive") == 0) {
|
||||
return SETUP (PASSIVE);
|
||||
}
|
||||
|
||||
GST_ERROR ("unknown setup value %s", attr);
|
||||
return SETUP (NONE);
|
||||
}
|
||||
|
||||
GstWebRTCDTLSSetup
|
||||
_intersect_dtls_setup (GstWebRTCDTLSSetup offer)
|
||||
{
|
||||
|
|
|
@ -58,6 +58,8 @@ GstWebRTCRTPTransceiverDirection _get_final_direction (Gs
|
|||
G_GNUC_INTERNAL
|
||||
GstWebRTCDTLSSetup _get_dtls_setup_from_media (const GstSDPMedia * media);
|
||||
G_GNUC_INTERNAL
|
||||
GstWebRTCDTLSSetup _get_dtls_setup_from_session (const GstSDPMessage * sdp);
|
||||
G_GNUC_INTERNAL
|
||||
GstWebRTCDTLSSetup _intersect_dtls_setup (GstWebRTCDTLSSetup offer);
|
||||
G_GNUC_INTERNAL
|
||||
void _media_replace_setup (GstSDPMedia * media,
|
||||
|
|
|
@ -5844,6 +5844,76 @@ GST_START_TEST (test_ice_end_of_candidates)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
static void
|
||||
_set_setup_session_attr_on_answer (struct test_webrtc *t, GstElement * element,
|
||||
GstPromise * promise, gpointer user_data)
|
||||
{
|
||||
GstSDPMessage *sdp;
|
||||
GstSDPMessage *modified_sdp = NULL;
|
||||
const GstSDPMedia *media;
|
||||
GstSDPMedia *modified_media;
|
||||
const gchar *attr;
|
||||
|
||||
if (TEST_IS_OFFER_ELEMENT (t, element))
|
||||
return;
|
||||
|
||||
sdp = t->answer_desc->sdp;
|
||||
media = gst_sdp_message_get_media (sdp, 0);
|
||||
attr = gst_sdp_media_get_attribute_val (media, "setup");
|
||||
|
||||
/* Remove the setup attribute from first media */
|
||||
gst_sdp_media_copy (media, &modified_media);
|
||||
for (unsigned index = 0;
|
||||
index < gst_sdp_media_attributes_len (modified_media); index++) {
|
||||
const GstSDPAttribute *current =
|
||||
gst_sdp_media_get_attribute (modified_media, index);
|
||||
if (!g_str_equal (current->key, "setup"))
|
||||
continue;
|
||||
gst_sdp_media_remove_attribute (modified_media, index);
|
||||
break;
|
||||
}
|
||||
|
||||
gst_sdp_message_copy (sdp, &modified_sdp);
|
||||
|
||||
/* Add session-level setup attribute to modified answer */
|
||||
gst_sdp_message_add_attribute (modified_sdp, "setup", attr);
|
||||
|
||||
/* Replace first media of answer with a media without session attribute */
|
||||
gst_sdp_message_remove_media (modified_sdp, 0);
|
||||
gst_sdp_message_add_media (modified_sdp, modified_media);
|
||||
gst_sdp_media_free (modified_media);
|
||||
|
||||
gst_sdp_message_free (sdp);
|
||||
t->answer_desc->sdp = modified_sdp;
|
||||
}
|
||||
|
||||
static void
|
||||
_offer_created_do_nothing (struct test_webrtc *t, GstElement * element,
|
||||
GstPromise * promise, gpointer user_data)
|
||||
{
|
||||
}
|
||||
|
||||
GST_START_TEST (test_sdp_session_setup_attribute)
|
||||
{
|
||||
struct test_webrtc *t = create_audio_test ();
|
||||
|
||||
t->on_offer_created = _offer_created_do_nothing;
|
||||
t->on_answer_created = _set_setup_session_attr_on_answer;
|
||||
|
||||
fail_if (gst_element_set_state (t->webrtc1, GST_STATE_READY) ==
|
||||
GST_STATE_CHANGE_FAILURE);
|
||||
fail_if (gst_element_set_state (t->webrtc2, GST_STATE_READY) ==
|
||||
GST_STATE_CHANGE_FAILURE);
|
||||
test_webrtc_create_offer (t);
|
||||
test_webrtc_wait_for_state_mask (t, 1 << STATE_ANSWER_SET);
|
||||
|
||||
test_webrtc_wait_for_ice_gathering_complete (t);
|
||||
|
||||
test_webrtc_free (t);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
static Suite *
|
||||
webrtcbin_suite (void)
|
||||
{
|
||||
|
@ -5910,6 +5980,7 @@ webrtcbin_suite (void)
|
|||
tcase_add_test (tc, test_add_turn_server);
|
||||
tcase_add_test (tc, test_msid);
|
||||
tcase_add_test (tc, test_ice_end_of_candidates);
|
||||
tcase_add_test (tc, test_sdp_session_setup_attribute);
|
||||
if (sctpenc && sctpdec) {
|
||||
tcase_add_test (tc, test_data_channel_create);
|
||||
tcase_add_test (tc, test_data_channel_create_two_channels);
|
||||
|
|
Loading…
Reference in a new issue