361862768b4d0aa1bd157eec3e8b60983a5e6f3d
[platform/upstream/gstreamer.git] / tests / check / elements / webrtcbin.c
1 /* GStreamer
2  *
3  * Unit tests for webrtcbin
4  *
5  * Copyright (C) 2017 Matthew Waters <matthew@centricular.com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <gst/gst.h>
29 #include <gst/check/gstcheck.h>
30 #include <gst/check/gstharness.h>
31 #include <gst/webrtc/webrtc.h>
32 #include "../../../ext/webrtc/webrtcsdp.h"
33 #include "../../../ext/webrtc/webrtcsdp.c"
34 #include "../../../ext/webrtc/utils.h"
35 #include "../../../ext/webrtc/utils.c"
36
37 #define OPUS_RTP_CAPS(pt) "application/x-rtp,payload=" G_STRINGIFY(pt) ",encoding-name=OPUS,media=audio,clock-rate=48000,ssrc=(uint)3384078950"
38 #define VP8_RTP_CAPS(pt) "application/x-rtp,payload=" G_STRINGIFY(pt) ",encoding-name=VP8,media=video,clock-rate=90000,ssrc=(uint)3484078950"
39
40 #define TEST_IS_OFFER_ELEMENT(t, e) ((t)->offerror == 1 && (e) == (t)->webrtc1 ? TRUE : FALSE)
41 #define TEST_GET_OFFEROR(t) (TEST_IS_OFFER_ELEMENT(t, t->webrtc1) ? (t)->webrtc1 : t->webrtc2)
42 #define TEST_GET_ANSWERER(t) (TEST_IS_OFFER_ELEMENT(t, t->webrtc1) ? (t)->webrtc2 : t->webrtc1)
43
44 #define TEST_SDP_IS_LOCAL(t, e, d) ((TEST_IS_OFFER_ELEMENT (t, e) ^ ((d)->type == GST_WEBRTC_SDP_TYPE_OFFER)) == 0)
45
46 typedef enum
47 {
48   STATE_NEW,
49   STATE_NEGOTIATION_NEEDED,
50   STATE_OFFER_CREATED,
51   STATE_OFFER_SET,
52   STATE_ANSWER_CREATED,
53   STATE_ANSWER_SET,
54   STATE_EOS,
55   STATE_ERROR,
56   STATE_CUSTOM,
57 } TestState;
58
59 /* basic premise of this is that webrtc1 and webrtc2 are attempting to connect
60  * to each other in various configurations */
61 struct test_webrtc;
62 struct test_webrtc
63 {
64   GList *harnesses;
65   GThread *thread;
66   GMainLoop *loop;
67   GstBus *bus1;
68   GstBus *bus2;
69   GstElement *webrtc1;
70   GstElement *webrtc2;
71   GMutex lock;
72   GCond cond;
73   TestState state;
74   guint offerror;
75   gpointer user_data;
76   GDestroyNotify data_notify;
77 /* *INDENT-OFF* */
78   void      (*on_negotiation_needed)    (struct test_webrtc * t,
79                                          GstElement * element,
80                                          gpointer user_data);
81   gpointer negotiation_data;
82   GDestroyNotify negotiation_notify;
83   void      (*on_ice_candidate)         (struct test_webrtc * t,
84                                          GstElement * element,
85                                          guint mlineindex,
86                                          gchar * candidate,
87                                          GstElement * other,
88                                          gpointer user_data);
89   gpointer ice_candidate_data;
90   GDestroyNotify ice_candidate_notify;
91   void      (*on_offer_created)         (struct test_webrtc * t,
92                                          GstElement * element,
93                                          GstPromise * promise,
94                                          gpointer user_data);
95   GstWebRTCSessionDescription *offer_desc;
96   guint offer_set_count;
97   gpointer offer_data;
98   GDestroyNotify offer_notify;
99   void      (*on_offer_set)             (struct test_webrtc * t,
100                                          GstElement * element,
101                                          GstPromise * promise,
102                                          gpointer user_data);
103   gpointer offer_set_data;
104   GDestroyNotify offer_set_notify;
105   void      (*on_answer_created)        (struct test_webrtc * t,
106                                          GstElement * element,
107                                          GstPromise * promise,
108                                          gpointer user_data);
109   GstWebRTCSessionDescription *answer_desc;
110   guint answer_set_count;
111   gpointer answer_data;
112   GDestroyNotify answer_notify;
113   void      (*on_answer_set)            (struct test_webrtc * t,
114                                          GstElement * element,
115                                          GstPromise * promise,
116                                          gpointer user_data);
117   gpointer answer_set_data;
118   GDestroyNotify answer_set_notify;
119   void      (*on_data_channel)          (struct test_webrtc * t,
120                                          GstElement * element,
121                                          GObject *data_channel,
122                                          gpointer user_data);
123   gpointer data_channel_data;
124   GDestroyNotify data_channel_notify;
125   void      (*on_pad_added)             (struct test_webrtc * t,
126                                          GstElement * element,
127                                          GstPad * pad,
128                                          gpointer user_data);
129   gpointer pad_added_data;
130   GDestroyNotify pad_added_notify;
131   void      (*bus_message)              (struct test_webrtc * t,
132                                          GstBus * bus,
133                                          GstMessage * msg,
134                                          gpointer user_data);
135   gpointer bus_data;
136   GDestroyNotify bus_notify;
137 /* *INDENT-ON* */
138 };
139
140 static void
141 test_webrtc_signal_state_unlocked (struct test_webrtc *t, TestState state)
142 {
143   t->state = state;
144   g_cond_broadcast (&t->cond);
145 }
146
147 static void
148 test_webrtc_signal_state (struct test_webrtc *t, TestState state)
149 {
150   g_mutex_lock (&t->lock);
151   test_webrtc_signal_state_unlocked (t, state);
152   g_mutex_unlock (&t->lock);
153 }
154
155 static void
156 _on_answer_set (GstPromise * promise, gpointer user_data)
157 {
158   struct test_webrtc *t = user_data;
159   GstElement *answerer = TEST_GET_ANSWERER (t);
160
161   g_mutex_lock (&t->lock);
162   if (++t->answer_set_count >= 2 && t->on_answer_set) {
163     t->on_answer_set (t, answerer, promise, t->answer_set_data);
164   }
165   if (t->state == STATE_ANSWER_CREATED)
166     t->state = STATE_ANSWER_SET;
167   g_cond_broadcast (&t->cond);
168   gst_promise_unref (promise);
169   g_mutex_unlock (&t->lock);
170 }
171
172 static void
173 _on_answer_received (GstPromise * promise, gpointer user_data)
174 {
175   struct test_webrtc *t = user_data;
176   GstElement *offeror = TEST_GET_OFFEROR (t);
177   GstElement *answerer = TEST_GET_ANSWERER (t);
178   const GstStructure *reply;
179   GstWebRTCSessionDescription *answer = NULL;
180   GError *error = NULL;
181
182   reply = gst_promise_get_reply (promise);
183   if (gst_structure_get (reply, "answer",
184           GST_TYPE_WEBRTC_SESSION_DESCRIPTION, &answer, NULL)) {
185     gchar *desc = gst_sdp_message_as_text (answer->sdp);
186     GST_INFO ("Created Answer: %s", desc);
187     g_free (desc);
188   } else if (gst_structure_get (reply, "error", G_TYPE_ERROR, &error, NULL)) {
189     GST_INFO ("Creating answer resulted in error: %s", error->message);
190   } else {
191     g_assert_not_reached ();
192   }
193
194   g_mutex_lock (&t->lock);
195
196   g_assert (t->answer_desc == NULL);
197   t->answer_desc = answer;
198
199   if (t->on_answer_created) {
200     t->on_answer_created (t, answerer, promise, t->answer_data);
201   }
202   gst_promise_unref (promise);
203
204   if (error)
205     goto error;
206
207   if (t->answer_desc) {
208     promise = gst_promise_new_with_change_func (_on_answer_set, t, NULL);
209     g_signal_emit_by_name (answerer, "set-local-description", t->answer_desc,
210         promise);
211     promise = gst_promise_new_with_change_func (_on_answer_set, t, NULL);
212     g_signal_emit_by_name (offeror, "set-remote-description", t->answer_desc,
213         promise);
214   }
215
216   test_webrtc_signal_state_unlocked (t, STATE_ANSWER_CREATED);
217   g_mutex_unlock (&t->lock);
218   return;
219
220 error:
221   g_clear_error (&error);
222   if (t->state < STATE_ERROR)
223     test_webrtc_signal_state_unlocked (t, STATE_ERROR);
224   g_mutex_unlock (&t->lock);
225   return;
226 }
227
228 static void
229 _on_offer_set (GstPromise * promise, gpointer user_data)
230 {
231   struct test_webrtc *t = user_data;
232   GstElement *offeror = TEST_GET_OFFEROR (t);
233
234   g_mutex_lock (&t->lock);
235   if (++t->offer_set_count >= 2 && t->on_offer_set) {
236     t->on_offer_set (t, offeror, promise, t->offer_set_data);
237   }
238   if (t->state == STATE_OFFER_CREATED)
239     t->state = STATE_OFFER_SET;
240   g_cond_broadcast (&t->cond);
241   gst_promise_unref (promise);
242   g_mutex_unlock (&t->lock);
243 }
244
245 static void
246 _on_offer_received (GstPromise * promise, gpointer user_data)
247 {
248   struct test_webrtc *t = user_data;
249   GstElement *offeror = TEST_GET_OFFEROR (t);
250   GstElement *answerer = TEST_GET_ANSWERER (t);
251   const GstStructure *reply;
252   GstWebRTCSessionDescription *offer = NULL;
253   GError *error = NULL;
254
255   reply = gst_promise_get_reply (promise);
256   if (gst_structure_get (reply, "offer",
257           GST_TYPE_WEBRTC_SESSION_DESCRIPTION, &offer, NULL)) {
258     gchar *desc = gst_sdp_message_as_text (offer->sdp);
259     GST_INFO ("Created offer: %s", desc);
260     g_free (desc);
261   } else if (gst_structure_get (reply, "error", G_TYPE_ERROR, &error, NULL)) {
262     GST_INFO ("Creating offer resulted in error: %s", error->message);
263   } else {
264     g_assert_not_reached ();
265   }
266
267   g_mutex_lock (&t->lock);
268
269   g_assert (t->offer_desc == NULL);
270   t->offer_desc = offer;
271
272   if (t->on_offer_created) {
273     t->on_offer_created (t, offeror, promise, t->offer_data);
274   }
275   gst_promise_unref (promise);
276
277   if (error)
278     goto error;
279
280   if (t->offer_desc) {
281     promise = gst_promise_new_with_change_func (_on_offer_set, t, NULL);
282     g_signal_emit_by_name (offeror, "set-local-description", t->offer_desc,
283         promise);
284     promise = gst_promise_new_with_change_func (_on_offer_set, t, NULL);
285     g_signal_emit_by_name (answerer, "set-remote-description", t->offer_desc,
286         promise);
287
288     promise = gst_promise_new_with_change_func (_on_answer_received, t, NULL);
289     g_signal_emit_by_name (answerer, "create-answer", NULL, promise);
290   }
291
292   test_webrtc_signal_state_unlocked (t, STATE_OFFER_CREATED);
293   g_mutex_unlock (&t->lock);
294   return;
295
296 error:
297   g_clear_error (&error);
298   if (t->state < STATE_ERROR)
299     test_webrtc_signal_state_unlocked (t, STATE_ERROR);
300   g_mutex_unlock (&t->lock);
301   return;
302 }
303
304 static gboolean
305 _bus_watch (GstBus * bus, GstMessage * msg, struct test_webrtc *t)
306 {
307   g_mutex_lock (&t->lock);
308   switch (GST_MESSAGE_TYPE (msg)) {
309     case GST_MESSAGE_STATE_CHANGED:
310       if (GST_ELEMENT (msg->src) == t->webrtc1
311           || GST_ELEMENT (msg->src) == t->webrtc2) {
312         GstState old, new, pending;
313
314         gst_message_parse_state_changed (msg, &old, &new, &pending);
315
316         {
317           gchar *dump_name = g_strconcat ("%s-state_changed-",
318               GST_OBJECT_NAME (msg->src), gst_element_state_get_name (old), "_",
319               gst_element_state_get_name (new), NULL);
320           GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (msg->src),
321               GST_DEBUG_GRAPH_SHOW_ALL, dump_name);
322           g_free (dump_name);
323         }
324       }
325       break;
326     case GST_MESSAGE_ERROR:{
327       GError *err = NULL;
328       gchar *dbg_info = NULL;
329
330       {
331         gchar *dump_name;
332         dump_name =
333             g_strconcat ("%s-error", GST_OBJECT_NAME (t->webrtc1), NULL);
334         GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (t->webrtc1),
335             GST_DEBUG_GRAPH_SHOW_ALL, dump_name);
336         g_free (dump_name);
337         dump_name =
338             g_strconcat ("%s-error", GST_OBJECT_NAME (t->webrtc2), NULL);
339         GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (t->webrtc2),
340             GST_DEBUG_GRAPH_SHOW_ALL, dump_name);
341         g_free (dump_name);
342       }
343
344       gst_message_parse_error (msg, &err, &dbg_info);
345       GST_WARNING ("ERROR from element %s: %s",
346           GST_OBJECT_NAME (msg->src), err->message);
347       GST_WARNING ("Debugging info: %s", (dbg_info) ? dbg_info : "none");
348       g_error_free (err);
349       g_free (dbg_info);
350       test_webrtc_signal_state_unlocked (t, STATE_ERROR);
351       break;
352     }
353     case GST_MESSAGE_EOS:{
354       {
355         gchar *dump_name;
356         dump_name = g_strconcat ("%s-eos", GST_OBJECT_NAME (t->webrtc1), NULL);
357         GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (t->webrtc1),
358             GST_DEBUG_GRAPH_SHOW_ALL, dump_name);
359         g_free (dump_name);
360         dump_name = g_strconcat ("%s-eos", GST_OBJECT_NAME (t->webrtc2), NULL);
361         GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (t->webrtc2),
362             GST_DEBUG_GRAPH_SHOW_ALL, dump_name);
363         g_free (dump_name);
364       }
365       GST_INFO ("EOS received");
366       test_webrtc_signal_state_unlocked (t, STATE_EOS);
367       break;
368     }
369     default:
370       break;
371   }
372
373   if (t->bus_message)
374     t->bus_message (t, bus, msg, t->bus_data);
375   g_mutex_unlock (&t->lock);
376
377   return TRUE;
378 }
379
380 static void
381 _on_negotiation_needed (GstElement * webrtc, struct test_webrtc *t)
382 {
383   g_mutex_lock (&t->lock);
384   if (t->on_negotiation_needed)
385     t->on_negotiation_needed (t, webrtc, t->negotiation_data);
386   if (t->state == STATE_NEW)
387     t->state = STATE_NEGOTIATION_NEEDED;
388   g_cond_broadcast (&t->cond);
389   g_mutex_unlock (&t->lock);
390 }
391
392 static void
393 _on_ice_candidate (GstElement * webrtc, guint mlineindex, gchar * candidate,
394     struct test_webrtc *t)
395 {
396   GstElement *other;
397
398   g_mutex_lock (&t->lock);
399   other = webrtc == t->webrtc1 ? t->webrtc2 : t->webrtc1;
400
401   if (t->on_ice_candidate)
402     t->on_ice_candidate (t, webrtc, mlineindex, candidate, other,
403         t->ice_candidate_data);
404
405   g_signal_emit_by_name (other, "add-ice-candidate", mlineindex, candidate);
406   g_mutex_unlock (&t->lock);
407 }
408
409 static void
410 _on_pad_added (GstElement * webrtc, GstPad * new_pad, struct test_webrtc *t)
411 {
412   g_mutex_lock (&t->lock);
413   if (t->on_pad_added)
414     t->on_pad_added (t, webrtc, new_pad, t->pad_added_data);
415   g_mutex_unlock (&t->lock);
416 }
417
418 static void
419 _on_data_channel (GstElement * webrtc, GObject * data_channel,
420     struct test_webrtc *t)
421 {
422   g_mutex_lock (&t->lock);
423   if (t->on_data_channel)
424     t->on_data_channel (t, webrtc, data_channel, t->data_channel_data);
425   g_mutex_unlock (&t->lock);
426 }
427
428 static void
429 _pad_added_not_reached (struct test_webrtc *t, GstElement * element,
430     GstPad * pad, gpointer user_data)
431 {
432   g_assert_not_reached ();
433 }
434
435 static void
436 _ice_candidate_not_reached (struct test_webrtc *t, GstElement * element,
437     guint mlineindex, gchar * candidate, GstElement * other, gpointer user_data)
438 {
439   g_assert_not_reached ();
440 }
441
442 static void
443 _negotiation_not_reached (struct test_webrtc *t, GstElement * element,
444     gpointer user_data)
445 {
446   g_assert_not_reached ();
447 }
448
449 static void
450 _bus_no_errors (struct test_webrtc *t, GstBus * bus, GstMessage * msg,
451     gpointer user_data)
452 {
453   switch (GST_MESSAGE_TYPE (msg)) {
454     case GST_MESSAGE_ERROR:{
455       g_assert_not_reached ();
456       break;
457     }
458     default:
459       break;
460   }
461 }
462
463 static void
464 _offer_answer_not_reached (struct test_webrtc *t, GstElement * element,
465     GstPromise * promise, gpointer user_data)
466 {
467   g_assert_not_reached ();
468 }
469
470 static void
471 _on_data_channel_not_reached (struct test_webrtc *t, GstElement * element,
472     GObject * data_channel, gpointer user_data)
473 {
474   g_assert_not_reached ();
475 }
476
477 static void
478 _broadcast (struct test_webrtc *t)
479 {
480   g_mutex_lock (&t->lock);
481   g_cond_broadcast (&t->cond);
482   g_mutex_unlock (&t->lock);
483 }
484
485 static gboolean
486 _unlock_create_thread (GMutex * lock)
487 {
488   g_mutex_unlock (lock);
489   return G_SOURCE_REMOVE;
490 }
491
492 static gpointer
493 _bus_thread (struct test_webrtc *t)
494 {
495   g_mutex_lock (&t->lock);
496   t->loop = g_main_loop_new (NULL, FALSE);
497   g_idle_add ((GSourceFunc) _unlock_create_thread, &t->lock);
498   g_cond_broadcast (&t->cond);
499
500   g_main_loop_run (t->loop);
501
502   g_mutex_lock (&t->lock);
503   g_main_loop_unref (t->loop);
504   t->loop = NULL;
505   g_cond_broadcast (&t->cond);
506   g_mutex_unlock (&t->lock);
507
508   return NULL;
509 }
510
511 static void
512 element_added_disable_sync (GstBin * bin, GstBin * sub_bin,
513     GstElement * element, gpointer user_data)
514 {
515   GObjectClass *class = G_OBJECT_GET_CLASS (element);
516   if (g_object_class_find_property (class, "async"))
517     g_object_set (element, "async", FALSE, NULL);
518   if (g_object_class_find_property (class, "sync"))
519     g_object_set (element, "sync", FALSE, NULL);
520 }
521
522 static struct test_webrtc *
523 test_webrtc_new (void)
524 {
525   struct test_webrtc *ret = g_new0 (struct test_webrtc, 1);
526
527   ret->on_negotiation_needed = _negotiation_not_reached;
528   ret->on_ice_candidate = _ice_candidate_not_reached;
529   ret->on_pad_added = _pad_added_not_reached;
530   ret->on_offer_created = _offer_answer_not_reached;
531   ret->on_answer_created = _offer_answer_not_reached;
532   ret->on_data_channel = _on_data_channel_not_reached;
533   ret->bus_message = _bus_no_errors;
534
535   g_mutex_init (&ret->lock);
536   g_cond_init (&ret->cond);
537
538   ret->thread = g_thread_new ("test-webrtc", (GThreadFunc) _bus_thread, ret);
539
540   g_mutex_lock (&ret->lock);
541   while (!ret->loop)
542     g_cond_wait (&ret->cond, &ret->lock);
543   g_mutex_unlock (&ret->lock);
544
545   ret->bus1 = gst_bus_new ();
546   ret->bus2 = gst_bus_new ();
547   gst_bus_add_watch (ret->bus1, (GstBusFunc) _bus_watch, ret);
548   gst_bus_add_watch (ret->bus2, (GstBusFunc) _bus_watch, ret);
549   ret->webrtc1 = gst_element_factory_make ("webrtcbin", NULL);
550   ret->webrtc2 = gst_element_factory_make ("webrtcbin", NULL);
551   fail_unless (ret->webrtc1 != NULL && ret->webrtc2 != NULL);
552
553   gst_element_set_bus (ret->webrtc1, ret->bus1);
554   gst_element_set_bus (ret->webrtc2, ret->bus2);
555
556   g_signal_connect (ret->webrtc1, "deep-element-added",
557       G_CALLBACK (element_added_disable_sync), NULL);
558   g_signal_connect (ret->webrtc2, "deep-element-added",
559       G_CALLBACK (element_added_disable_sync), NULL);
560   g_signal_connect (ret->webrtc1, "on-negotiation-needed",
561       G_CALLBACK (_on_negotiation_needed), ret);
562   g_signal_connect (ret->webrtc2, "on-negotiation-needed",
563       G_CALLBACK (_on_negotiation_needed), ret);
564   g_signal_connect (ret->webrtc1, "on-ice-candidate",
565       G_CALLBACK (_on_ice_candidate), ret);
566   g_signal_connect (ret->webrtc2, "on-ice-candidate",
567       G_CALLBACK (_on_ice_candidate), ret);
568   g_signal_connect (ret->webrtc1, "on-data-channel",
569       G_CALLBACK (_on_data_channel), ret);
570   g_signal_connect (ret->webrtc2, "on-data-channel",
571       G_CALLBACK (_on_data_channel), ret);
572   g_signal_connect (ret->webrtc1, "pad-added", G_CALLBACK (_on_pad_added), ret);
573   g_signal_connect (ret->webrtc2, "pad-added", G_CALLBACK (_on_pad_added), ret);
574   g_signal_connect_swapped (ret->webrtc1, "notify::ice-gathering-state",
575       G_CALLBACK (_broadcast), ret);
576   g_signal_connect_swapped (ret->webrtc2, "notify::ice-gathering-state",
577       G_CALLBACK (_broadcast), ret);
578   g_signal_connect_swapped (ret->webrtc1, "notify::ice-connection-state",
579       G_CALLBACK (_broadcast), ret);
580   g_signal_connect_swapped (ret->webrtc2, "notify::ice-connection-state",
581       G_CALLBACK (_broadcast), ret);
582
583   return ret;
584 }
585
586 static void
587 test_webrtc_reset_negotiation (struct test_webrtc *t)
588 {
589   if (t->offer_desc)
590     gst_webrtc_session_description_free (t->offer_desc);
591   t->offer_desc = NULL;
592   t->offer_set_count = 0;
593   if (t->answer_desc)
594     gst_webrtc_session_description_free (t->answer_desc);
595   t->answer_desc = NULL;
596   t->answer_set_count = 0;
597
598   test_webrtc_signal_state (t, STATE_NEGOTIATION_NEEDED);
599 }
600
601 static void
602 test_webrtc_free (struct test_webrtc *t)
603 {
604   /* Otherwise while one webrtcbin is being destroyed, the other could
605    * generate a signal that calls into the destroyed webrtcbin */
606   g_signal_handlers_disconnect_by_data (t->webrtc1, t);
607   g_signal_handlers_disconnect_by_data (t->webrtc2, t);
608
609   g_main_loop_quit (t->loop);
610   g_mutex_lock (&t->lock);
611   while (t->loop)
612     g_cond_wait (&t->cond, &t->lock);
613   g_mutex_unlock (&t->lock);
614
615   g_thread_join (t->thread);
616
617   gst_bus_remove_watch (t->bus1);
618   gst_bus_remove_watch (t->bus2);
619
620   gst_bus_set_flushing (t->bus1, TRUE);
621   gst_bus_set_flushing (t->bus2, TRUE);
622
623   gst_object_unref (t->bus1);
624   gst_object_unref (t->bus2);
625
626   g_list_free_full (t->harnesses, (GDestroyNotify) gst_harness_teardown);
627
628   if (t->data_notify)
629     t->data_notify (t->user_data);
630   if (t->negotiation_notify)
631     t->negotiation_notify (t->negotiation_data);
632   if (t->ice_candidate_notify)
633     t->ice_candidate_notify (t->ice_candidate_data);
634   if (t->offer_notify)
635     t->offer_notify (t->offer_data);
636   if (t->offer_set_notify)
637     t->offer_set_notify (t->offer_set_data);
638   if (t->answer_notify)
639     t->answer_notify (t->answer_data);
640   if (t->answer_set_notify)
641     t->answer_set_notify (t->answer_set_data);
642   if (t->pad_added_notify)
643     t->pad_added_notify (t->pad_added_data);
644   if (t->data_channel_notify)
645     t->data_channel_notify (t->data_channel_data);
646
647   fail_unless_equals_int (GST_STATE_CHANGE_SUCCESS,
648       gst_element_set_state (t->webrtc1, GST_STATE_NULL));
649   fail_unless_equals_int (GST_STATE_CHANGE_SUCCESS,
650       gst_element_set_state (t->webrtc2, GST_STATE_NULL));
651
652   test_webrtc_reset_negotiation (t);
653
654   gst_object_unref (t->webrtc1);
655   gst_object_unref (t->webrtc2);
656
657   g_mutex_clear (&t->lock);
658   g_cond_clear (&t->cond);
659
660   g_free (t);
661 }
662
663 static void
664 test_webrtc_create_offer (struct test_webrtc *t, GstElement * webrtc)
665 {
666   GstPromise *promise;
667
668   t->offerror = webrtc == t->webrtc1 ? 1 : 2;
669   promise = gst_promise_new_with_change_func (_on_offer_received, t, NULL);
670   g_signal_emit_by_name (webrtc, "create-offer", NULL, promise);
671 }
672
673 static void
674 test_webrtc_wait_for_state_mask (struct test_webrtc *t, TestState state)
675 {
676   g_mutex_lock (&t->lock);
677   while (((1 << t->state) & state) == 0) {
678     GST_INFO ("test state 0x%x, current 0x%x", state, (1 << t->state));
679     g_cond_wait (&t->cond, &t->lock);
680   }
681   GST_INFO ("have test state 0x%x, current 0x%x", state, 1 << t->state);
682   g_mutex_unlock (&t->lock);
683 }
684
685 static void
686 test_webrtc_wait_for_answer_error_eos (struct test_webrtc *t)
687 {
688   TestState states = 0;
689   states |= (1 << STATE_ANSWER_SET);
690   states |= (1 << STATE_EOS);
691   states |= (1 << STATE_ERROR);
692   test_webrtc_wait_for_state_mask (t, states);
693 }
694
695 static void
696 test_webrtc_wait_for_ice_gathering_complete (struct test_webrtc *t)
697 {
698   GstWebRTCICEGatheringState ice_state1, ice_state2;
699   g_mutex_lock (&t->lock);
700   g_object_get (t->webrtc1, "ice-gathering-state", &ice_state1, NULL);
701   g_object_get (t->webrtc2, "ice-gathering-state", &ice_state2, NULL);
702   while (ice_state1 != GST_WEBRTC_ICE_GATHERING_STATE_COMPLETE &&
703       ice_state2 != GST_WEBRTC_ICE_GATHERING_STATE_COMPLETE) {
704     g_cond_wait (&t->cond, &t->lock);
705     g_object_get (t->webrtc1, "ice-gathering-state", &ice_state1, NULL);
706     g_object_get (t->webrtc2, "ice-gathering-state", &ice_state2, NULL);
707   }
708   g_mutex_unlock (&t->lock);
709 }
710
711 #if 0
712 static void
713 test_webrtc_wait_for_ice_connection (struct test_webrtc *t,
714     GstWebRTCICEConnectionState states)
715 {
716   GstWebRTCICEConnectionState ice_state1, ice_state2, current;
717   g_mutex_lock (&t->lock);
718   g_object_get (t->webrtc1, "ice-connection-state", &ice_state1, NULL);
719   g_object_get (t->webrtc2, "ice-connection-state", &ice_state2, NULL);
720   current = (1 << ice_state1) | (1 << ice_state2);
721   while ((current & states) == 0 || (current & ~states)) {
722     g_cond_wait (&t->cond, &t->lock);
723     g_object_get (t->webrtc1, "ice-connection-state", &ice_state1, NULL);
724     g_object_get (t->webrtc2, "ice-connection-state", &ice_state2, NULL);
725     current = (1 << ice_state1) | (1 << ice_state2);
726   }
727   g_mutex_unlock (&t->lock);
728 }
729 #endif
730 static void
731 _pad_added_fakesink (struct test_webrtc *t, GstElement * element,
732     GstPad * pad, gpointer user_data)
733 {
734   GstHarness *h;
735
736   if (GST_PAD_DIRECTION (pad) != GST_PAD_SRC)
737     return;
738
739   h = gst_harness_new_with_element (element, NULL, "src_%u");
740   gst_harness_add_sink_parse (h, "fakesink async=false sync=false");
741
742   t->harnesses = g_list_prepend (t->harnesses, h);
743 }
744
745 static void
746 on_negotiation_needed_hit (struct test_webrtc *t, GstElement * element,
747     gpointer user_data)
748 {
749   guint *flag = (guint *) user_data;
750
751   *flag = 1;
752 }
753
754 typedef void (*ValidateSDPFunc) (struct test_webrtc * t, GstElement * element,
755     GstWebRTCSessionDescription * desc, gpointer user_data);
756
757 struct validate_sdp;
758 struct validate_sdp
759 {
760   ValidateSDPFunc validate;
761   gpointer user_data;
762   struct validate_sdp *next;
763 };
764
765 #define VAL_SDP_INIT(name,func,data,next) \
766     struct validate_sdp name = { func, data, next }
767
768 static void
769 _check_validate_sdp (struct test_webrtc *t, GstElement * element,
770     GstPromise * promise, gpointer user_data)
771 {
772   struct validate_sdp *validate = user_data;
773   GstWebRTCSessionDescription *desc = NULL;
774
775   if (t->offerror == 1 && t->webrtc1 == element)
776     desc = t->offer_desc;
777   else
778     desc = t->answer_desc;
779
780   while (validate) {
781     validate->validate (t, element, desc, validate->user_data);
782     validate = validate->next;
783   }
784 }
785
786 static void
787 test_validate_sdp_full (struct test_webrtc *t, struct validate_sdp *offer,
788     struct validate_sdp *answer, TestState wait_mask,
789     gboolean perform_state_change)
790 {
791   if (offer) {
792     t->offer_data = offer;
793     t->on_offer_created = _check_validate_sdp;
794   } else {
795     t->offer_data = NULL;
796     t->on_offer_created = NULL;
797   }
798   if (answer) {
799     t->answer_data = answer;
800     t->on_answer_created = _check_validate_sdp;
801   } else {
802     t->answer_data = NULL;
803     t->on_answer_created = NULL;
804   }
805
806   if (perform_state_change) {
807     fail_if (gst_element_set_state (t->webrtc1,
808             GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
809     fail_if (gst_element_set_state (t->webrtc2,
810             GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
811   }
812
813   test_webrtc_create_offer (t, t->webrtc1);
814
815   if (wait_mask == 0) {
816     test_webrtc_wait_for_answer_error_eos (t);
817     fail_unless (t->state == STATE_ANSWER_SET);
818   } else {
819     test_webrtc_wait_for_state_mask (t, wait_mask);
820   }
821 }
822
823 static void
824 test_validate_sdp (struct test_webrtc *t, struct validate_sdp *offer,
825     struct validate_sdp *answer)
826 {
827   test_validate_sdp_full (t, offer, answer, 0, TRUE);
828 }
829
830 static void
831 _count_num_sdp_media (struct test_webrtc *t, GstElement * element,
832     GstWebRTCSessionDescription * desc, gpointer user_data)
833 {
834   guint expected = GPOINTER_TO_UINT (user_data);
835
836   fail_unless_equals_int (gst_sdp_message_medias_len (desc->sdp), expected);
837 }
838
839 GST_START_TEST (test_sdp_no_media)
840 {
841   struct test_webrtc *t = test_webrtc_new ();
842   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (0), NULL);
843
844   /* check that a no stream connection creates 0 media sections */
845
846   t->on_negotiation_needed = NULL;
847   test_validate_sdp (t, &count, &count);
848
849   test_webrtc_free (t);
850 }
851
852 GST_END_TEST;
853
854 static void
855 on_sdp_media_direction (struct test_webrtc *t, GstElement * element,
856     GstWebRTCSessionDescription * desc, gpointer user_data)
857 {
858   gchar **expected_directions = user_data;
859   int i;
860
861   for (i = 0; i < gst_sdp_message_medias_len (desc->sdp); i++) {
862     const GstSDPMedia *media = gst_sdp_message_get_media (desc->sdp, i);
863
864     if (g_strcmp0 (gst_sdp_media_get_media (media), "audio") == 0
865         || g_strcmp0 (gst_sdp_media_get_media (media), "video") == 0) {
866       gboolean have_direction = FALSE;
867       int j;
868
869       for (j = 0; j < gst_sdp_media_attributes_len (media); j++) {
870         const GstSDPAttribute *attr = gst_sdp_media_get_attribute (media, j);
871
872         if (g_strcmp0 (attr->key, "inactive") == 0) {
873           fail_unless (have_direction == FALSE,
874               "duplicate/multiple directions for media %u", j);
875           have_direction = TRUE;
876           fail_unless (g_strcmp0 (attr->key, expected_directions[i]) == 0);
877         } else if (g_strcmp0 (attr->key, "sendonly") == 0) {
878           fail_unless (have_direction == FALSE,
879               "duplicate/multiple directions for media %u", j);
880           have_direction = TRUE;
881           fail_unless (g_strcmp0 (attr->key, expected_directions[i]) == 0);
882         } else if (g_strcmp0 (attr->key, "recvonly") == 0) {
883           fail_unless (have_direction == FALSE,
884               "duplicate/multiple directions for media %u", j);
885           have_direction = TRUE;
886           fail_unless (g_strcmp0 (attr->key, expected_directions[i]) == 0);
887         } else if (g_strcmp0 (attr->key, "sendrecv") == 0) {
888           fail_unless (have_direction == FALSE,
889               "duplicate/multiple directions for media %u", j);
890           have_direction = TRUE;
891           fail_unless (g_strcmp0 (attr->key, expected_directions[i]) == 0);
892         }
893       }
894       fail_unless (have_direction, "no direction attribute in media %u", i);
895     }
896   }
897 }
898
899 static void
900 on_sdp_media_no_duplicate_payloads (struct test_webrtc *t, GstElement * element,
901     GstWebRTCSessionDescription * desc, gpointer user_data)
902 {
903   int i, j, k;
904
905   for (i = 0; i < gst_sdp_message_medias_len (desc->sdp); i++) {
906     const GstSDPMedia *media = gst_sdp_message_get_media (desc->sdp, i);
907
908     GArray *media_formats = g_array_new (FALSE, FALSE, sizeof (int));
909     for (j = 0; j < gst_sdp_media_formats_len (media); j++) {
910       int pt = atoi (gst_sdp_media_get_format (media, j));
911       for (k = 0; k < media_formats->len; k++) {
912         int val = g_array_index (media_formats, int, k);
913         if (pt == val)
914           fail ("found an unexpected duplicate payload type %u within media %u",
915               pt, i);
916       }
917       g_array_append_val (media_formats, pt);
918     }
919     g_array_free (media_formats, TRUE);
920   }
921 }
922
923 static void
924 on_sdp_media_count_formats (struct test_webrtc *t, GstElement * element,
925     GstWebRTCSessionDescription * desc, gpointer user_data)
926 {
927   guint *expected_n_media_formats = user_data;
928   int i;
929
930   for (i = 0; i < gst_sdp_message_medias_len (desc->sdp); i++) {
931     const GstSDPMedia *media = gst_sdp_message_get_media (desc->sdp, i);
932     fail_unless_equals_int (gst_sdp_media_formats_len (media),
933         expected_n_media_formats[i]);
934   }
935 }
936
937 static void
938 on_sdp_media_setup (struct test_webrtc *t, GstElement * element,
939     GstWebRTCSessionDescription * desc, gpointer user_data)
940 {
941   gchar **expected_setup = user_data;
942   int i;
943
944   for (i = 0; i < gst_sdp_message_medias_len (desc->sdp); i++) {
945     const GstSDPMedia *media = gst_sdp_message_get_media (desc->sdp, i);
946     gboolean have_setup = FALSE;
947     int j;
948
949     for (j = 0; j < gst_sdp_media_attributes_len (media); j++) {
950       const GstSDPAttribute *attr = gst_sdp_media_get_attribute (media, j);
951
952       if (g_strcmp0 (attr->key, "setup") == 0) {
953         fail_unless (have_setup == FALSE,
954             "duplicate/multiple setup for media %u", j);
955         have_setup = TRUE;
956         fail_unless (g_strcmp0 (attr->value, expected_setup[i]) == 0);
957       }
958     }
959     fail_unless (have_setup, "no setup attribute in media %u", i);
960   }
961 }
962
963 static void
964 add_fake_audio_src_harness (GstHarness * h, gint pt)
965 {
966   GstCaps *caps = gst_caps_from_string (OPUS_RTP_CAPS (pt));
967   GstStructure *s = gst_caps_get_structure (caps, 0);
968   gst_structure_set (s, "payload", G_TYPE_INT, pt, NULL);
969   gst_harness_set_src_caps (h, caps);
970   gst_harness_add_src_parse (h, "fakesrc is-live=true", TRUE);
971 }
972
973 static void
974 add_fake_video_src_harness (GstHarness * h, gint pt)
975 {
976   GstCaps *caps = gst_caps_from_string (VP8_RTP_CAPS (pt));
977   GstStructure *s = gst_caps_get_structure (caps, 0);
978   gst_structure_set (s, "payload", G_TYPE_INT, pt, NULL);
979   gst_harness_set_src_caps (h, caps);
980   gst_harness_add_src_parse (h, "fakesrc is-live=true", TRUE);
981 }
982
983 static struct test_webrtc *
984 create_audio_test (void)
985 {
986   struct test_webrtc *t = test_webrtc_new ();
987   GstHarness *h;
988
989   t->on_negotiation_needed = NULL;
990   t->on_ice_candidate = NULL;
991   t->on_pad_added = _pad_added_fakesink;
992
993   h = gst_harness_new_with_element (t->webrtc1, "sink_0", NULL);
994   add_fake_audio_src_harness (h, 96);
995   t->harnesses = g_list_prepend (t->harnesses, h);
996
997   return t;
998 }
999
1000 GST_START_TEST (test_audio)
1001 {
1002   struct test_webrtc *t = create_audio_test ();
1003   VAL_SDP_INIT (no_duplicate_payloads, on_sdp_media_no_duplicate_payloads,
1004       NULL, NULL);
1005   guint media_format_count[] = { 1 };
1006   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
1007       media_format_count, &no_duplicate_payloads);
1008   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (1),
1009       &media_formats);
1010   const gchar *expected_offer_setup[] = { "actpass", };
1011   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup, &count);
1012   const gchar *expected_answer_setup[] = { "active", };
1013   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
1014       &count);
1015   const gchar *expected_offer_direction[] = { "sendrecv", };
1016   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
1017       &offer_setup);
1018   const gchar *expected_answer_direction[] = { "recvonly", };
1019   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
1020       &answer_setup);
1021
1022   /* check that a single stream connection creates the associated number
1023    * of media sections */
1024
1025   test_validate_sdp (t, &offer, &answer);
1026   test_webrtc_free (t);
1027 }
1028
1029 GST_END_TEST;
1030
1031 static void
1032 _check_ice_port_restriction (struct test_webrtc *t, GstElement * element,
1033     guint mlineindex, gchar * candidate, GstElement * other, gpointer user_data)
1034 {
1035   GRegex *regex;
1036   GMatchInfo *match_info;
1037
1038   gchar *candidate_port;
1039   gchar *candidate_protocol;
1040   gchar *candidate_typ;
1041   guint port_as_int;
1042   guint peer_number;
1043
1044   regex =
1045       g_regex_new ("candidate:(\\d+) (1) (UDP|TCP) (\\d+) ([0-9.]+|[0-9a-f:]+)"
1046       " (\\d+) typ ([a-z]+)", 0, 0, NULL);
1047
1048   g_regex_match (regex, candidate, 0, &match_info);
1049   fail_unless (g_match_info_get_match_count (match_info) == 8, candidate);
1050
1051   candidate_protocol = g_match_info_fetch (match_info, 2);
1052   candidate_port = g_match_info_fetch (match_info, 6);
1053   candidate_typ = g_match_info_fetch (match_info, 7);
1054
1055   peer_number = t->webrtc1 == element ? 1 : 2;
1056
1057   port_as_int = atoi (candidate_port);
1058
1059   if (!g_strcmp0 (candidate_typ, "host") && port_as_int != 9) {
1060     guint expected_min = peer_number * 10000 + 1000;
1061     guint expected_max = expected_min + 999;
1062
1063     fail_unless (port_as_int >= expected_min);
1064     fail_unless (port_as_int <= expected_max);
1065   }
1066
1067   g_free (candidate_port);
1068   g_free (candidate_protocol);
1069   g_free (candidate_typ);
1070   g_match_info_free (match_info);
1071   g_regex_unref (regex);
1072 }
1073
1074 GST_START_TEST (test_ice_port_restriction)
1075 {
1076   struct test_webrtc *t = create_audio_test ();
1077   GObject *webrtcice;
1078
1079   VAL_SDP_INIT (offer, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
1080   VAL_SDP_INIT (answer, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
1081
1082   /*
1083    *  Ports are defined as follows "{peer}{protocol}000"
1084    *  - peer number: "1" for t->webrtc1, "2" for t->webrtc2
1085    */
1086   g_object_get (t->webrtc1, "ice-agent", &webrtcice, NULL);
1087   g_object_set (webrtcice, "min-rtp-port", 11000, "max-rtp-port", 11999, NULL);
1088   g_object_unref (webrtcice);
1089
1090   g_object_get (t->webrtc2, "ice-agent", &webrtcice, NULL);
1091   g_object_set (webrtcice, "min-rtp-port", 21000, "max-rtp-port", 21999, NULL);
1092   g_object_unref (webrtcice);
1093
1094   t->on_ice_candidate = _check_ice_port_restriction;
1095   test_validate_sdp (t, &offer, &answer);
1096
1097   test_webrtc_wait_for_ice_gathering_complete (t);
1098   test_webrtc_free (t);
1099 }
1100
1101 GST_END_TEST;
1102
1103 static struct test_webrtc *
1104 create_audio_video_test (void)
1105 {
1106   struct test_webrtc *t = create_audio_test ();
1107   GstHarness *h;
1108
1109   h = gst_harness_new_with_element (t->webrtc1, "sink_1", NULL);
1110   add_fake_video_src_harness (h, 97);
1111   t->harnesses = g_list_prepend (t->harnesses, h);
1112
1113   return t;
1114 }
1115
1116 GST_START_TEST (test_audio_video)
1117 {
1118   struct test_webrtc *t = create_audio_video_test ();
1119   VAL_SDP_INIT (no_duplicate_payloads, on_sdp_media_no_duplicate_payloads,
1120       NULL, NULL);
1121   guint media_format_count[] = { 1, 1 };
1122   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
1123       media_format_count, &no_duplicate_payloads);
1124   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
1125       &media_formats);
1126   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
1127   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup, &count);
1128   const gchar *expected_answer_setup[] = { "active", "active" };
1129   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
1130       &count);
1131   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv" };
1132   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
1133       &offer_setup);
1134   const gchar *expected_answer_direction[] = { "recvonly", "recvonly" };
1135   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
1136       &answer_setup);
1137
1138   /* check that a dual stream connection creates the associated number
1139    * of media sections */
1140
1141   test_validate_sdp (t, &offer, &answer);
1142   test_webrtc_free (t);
1143 }
1144
1145 GST_END_TEST;
1146
1147 GST_START_TEST (test_media_direction)
1148 {
1149   struct test_webrtc *t = create_audio_video_test ();
1150   VAL_SDP_INIT (no_duplicate_payloads, on_sdp_media_no_duplicate_payloads,
1151       NULL, NULL);
1152   guint media_format_count[] = { 1, 1 };
1153   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
1154       media_format_count, &no_duplicate_payloads);
1155   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
1156       &media_formats);
1157   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
1158   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup, &count);
1159   const gchar *expected_answer_setup[] = { "active", "active" };
1160   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
1161       &count);
1162
1163   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv" };
1164   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
1165       &offer_setup);
1166   const gchar *expected_answer_direction[] = { "sendrecv", "recvonly" };
1167   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
1168       &answer_setup);
1169   GstHarness *h;
1170
1171   /* check the default media directions for transceivers */
1172
1173   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
1174   add_fake_audio_src_harness (h, 96);
1175   t->harnesses = g_list_prepend (t->harnesses, h);
1176
1177   test_validate_sdp (t, &offer, &answer);
1178   test_webrtc_free (t);
1179 }
1180
1181 GST_END_TEST;
1182
1183 static void
1184 on_sdp_media_payload_types (struct test_webrtc *t, GstElement * element,
1185     GstWebRTCSessionDescription * desc, gpointer user_data)
1186 {
1187   const GstSDPMedia *vmedia;
1188   guint j;
1189
1190   vmedia = gst_sdp_message_get_media (desc->sdp, 1);
1191
1192   for (j = 0; j < gst_sdp_media_attributes_len (vmedia); j++) {
1193     const GstSDPAttribute *attr = gst_sdp_media_get_attribute (vmedia, j);
1194
1195     if (!g_strcmp0 (attr->key, "rtpmap")) {
1196       if (g_str_has_prefix (attr->value, "97")) {
1197         fail_unless_equals_string (attr->value, "97 VP8/90000");
1198       } else if (g_str_has_prefix (attr->value, "96")) {
1199         fail_unless_equals_string (attr->value, "96 red/90000");
1200       } else if (g_str_has_prefix (attr->value, "98")) {
1201         fail_unless_equals_string (attr->value, "98 ulpfec/90000");
1202       } else if (g_str_has_prefix (attr->value, "99")) {
1203         fail_unless_equals_string (attr->value, "99 rtx/90000");
1204       } else if (g_str_has_prefix (attr->value, "100")) {
1205         fail_unless_equals_string (attr->value, "100 rtx/90000");
1206       }
1207     }
1208   }
1209 }
1210
1211 /* In this test we verify that webrtcbin will pick available payload
1212  * types when it needs to, in that example for RTX and FEC */
1213 GST_START_TEST (test_payload_types)
1214 {
1215   struct test_webrtc *t = create_audio_video_test ();
1216   VAL_SDP_INIT (no_duplicate_payloads, on_sdp_media_no_duplicate_payloads,
1217       NULL, NULL);
1218   guint media_format_count[] = { 1, 5, };
1219   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
1220       media_format_count, &no_duplicate_payloads);
1221   VAL_SDP_INIT (payloads, on_sdp_media_payload_types, NULL, &media_formats);
1222   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2), &payloads);
1223   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
1224   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup, &count);
1225   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv" };
1226   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
1227       &offer_setup);
1228   GstWebRTCRTPTransceiver *trans;
1229   GArray *transceivers;
1230
1231   g_signal_emit_by_name (t->webrtc1, "get-transceivers", &transceivers);
1232   fail_unless_equals_int (transceivers->len, 2);
1233   trans = g_array_index (transceivers, GstWebRTCRTPTransceiver *, 1);
1234   g_object_set (trans, "fec-type", GST_WEBRTC_FEC_TYPE_ULP_RED, "do-nack", TRUE,
1235       NULL);
1236   g_array_unref (transceivers);
1237
1238   /* We don't really care about the answer here */
1239   test_validate_sdp (t, &offer, NULL);
1240   test_webrtc_free (t);
1241 }
1242
1243 GST_END_TEST;
1244
1245 GST_START_TEST (test_no_nice_elements_request_pad)
1246 {
1247   struct test_webrtc *t = test_webrtc_new ();
1248   GstPluginFeature *nicesrc, *nicesink;
1249   GstRegistry *registry;
1250   GstPad *pad;
1251
1252   /* check that the absence of libnice elements posts an error on the bus
1253    * when requesting a pad */
1254
1255   registry = gst_registry_get ();
1256   nicesrc = gst_registry_lookup_feature (registry, "nicesrc");
1257   nicesink = gst_registry_lookup_feature (registry, "nicesink");
1258
1259   if (nicesrc)
1260     gst_registry_remove_feature (registry, nicesrc);
1261   if (nicesink)
1262     gst_registry_remove_feature (registry, nicesink);
1263
1264   t->bus_message = NULL;
1265
1266   pad = gst_element_get_request_pad (t->webrtc1, "sink_0");
1267   fail_unless (pad == NULL);
1268
1269   test_webrtc_wait_for_answer_error_eos (t);
1270   fail_unless_equals_int (STATE_ERROR, t->state);
1271   test_webrtc_free (t);
1272
1273   if (nicesrc)
1274     gst_registry_add_feature (registry, nicesrc);
1275   if (nicesink)
1276     gst_registry_add_feature (registry, nicesink);
1277 }
1278
1279 GST_END_TEST;
1280
1281 GST_START_TEST (test_no_nice_elements_state_change)
1282 {
1283   struct test_webrtc *t = test_webrtc_new ();
1284   GstPluginFeature *nicesrc, *nicesink;
1285   GstRegistry *registry;
1286
1287   /* check that the absence of libnice elements posts an error on the bus */
1288
1289   registry = gst_registry_get ();
1290   nicesrc = gst_registry_lookup_feature (registry, "nicesrc");
1291   nicesink = gst_registry_lookup_feature (registry, "nicesink");
1292
1293   if (nicesrc)
1294     gst_registry_remove_feature (registry, nicesrc);
1295   if (nicesink)
1296     gst_registry_remove_feature (registry, nicesink);
1297
1298   t->bus_message = NULL;
1299   gst_element_set_state (t->webrtc1, GST_STATE_READY);
1300
1301   test_webrtc_wait_for_answer_error_eos (t);
1302   fail_unless_equals_int (STATE_ERROR, t->state);
1303   test_webrtc_free (t);
1304
1305   if (nicesrc)
1306     gst_registry_add_feature (registry, nicesrc);
1307   if (nicesink)
1308     gst_registry_add_feature (registry, nicesink);
1309 }
1310
1311 GST_END_TEST;
1312
1313 static void
1314 validate_rtc_stats (const GstStructure * s)
1315 {
1316   GstWebRTCStatsType type = 0;
1317   double ts = 0.;
1318   gchar *id = NULL;
1319
1320   fail_unless (gst_structure_get (s, "type", GST_TYPE_WEBRTC_STATS_TYPE, &type,
1321           NULL));
1322   fail_unless (gst_structure_get (s, "id", G_TYPE_STRING, &id, NULL));
1323   fail_unless (gst_structure_get (s, "timestamp", G_TYPE_DOUBLE, &ts, NULL));
1324   fail_unless (type != 0);
1325   fail_unless (ts != 0.);
1326   fail_unless (id != NULL);
1327
1328   g_free (id);
1329 }
1330
1331 static void
1332 validate_codec_stats (const GstStructure * s)
1333 {
1334   guint pt = 0, clock_rate = 0;
1335
1336   fail_unless (gst_structure_get (s, "payload-type", G_TYPE_UINT, &pt, NULL));
1337   fail_unless (gst_structure_get (s, "clock-rate", G_TYPE_UINT, &clock_rate,
1338           NULL));
1339   fail_unless (pt >= 0 && pt <= 127);
1340   fail_unless (clock_rate >= 0);
1341 }
1342
1343 static void
1344 validate_rtc_stream_stats (const GstStructure * s, const GstStructure * stats)
1345 {
1346   gchar *codec_id, *transport_id;
1347   GstStructure *codec, *transport;
1348
1349   fail_unless (gst_structure_get (s, "codec-id", G_TYPE_STRING, &codec_id,
1350           NULL));
1351   fail_unless (gst_structure_get (s, "transport-id", G_TYPE_STRING,
1352           &transport_id, NULL));
1353
1354   fail_unless (gst_structure_get (stats, codec_id, GST_TYPE_STRUCTURE, &codec,
1355           NULL));
1356   fail_unless (gst_structure_get (stats, transport_id, GST_TYPE_STRUCTURE,
1357           &transport, NULL));
1358
1359   fail_unless (codec != NULL);
1360   fail_unless (transport != NULL);
1361
1362   gst_structure_free (transport);
1363   gst_structure_free (codec);
1364
1365   g_free (codec_id);
1366   g_free (transport_id);
1367 }
1368
1369 static void
1370 validate_inbound_rtp_stats (const GstStructure * s, const GstStructure * stats)
1371 {
1372   guint ssrc, fir, pli, nack;
1373   gint packets_lost;
1374   guint64 packets_received, bytes_received;
1375   double jitter;
1376   gchar *remote_id;
1377   GstStructure *remote;
1378
1379   validate_rtc_stream_stats (s, stats);
1380
1381   fail_unless (gst_structure_get (s, "ssrc", G_TYPE_UINT, &ssrc, NULL));
1382   fail_unless (gst_structure_get (s, "fir-count", G_TYPE_UINT, &fir, NULL));
1383   fail_unless (gst_structure_get (s, "pli-count", G_TYPE_UINT, &pli, NULL));
1384   fail_unless (gst_structure_get (s, "nack-count", G_TYPE_UINT, &nack, NULL));
1385   fail_unless (gst_structure_get (s, "packets-received", G_TYPE_UINT64,
1386           &packets_received, NULL));
1387   fail_unless (gst_structure_get (s, "bytes-received", G_TYPE_UINT64,
1388           &bytes_received, NULL));
1389   fail_unless (gst_structure_get (s, "jitter", G_TYPE_DOUBLE, &jitter, NULL));
1390   fail_unless (gst_structure_get (s, "packets-lost", G_TYPE_INT, &packets_lost,
1391           NULL));
1392   fail_unless (gst_structure_get (s, "remote-id", G_TYPE_STRING, &remote_id,
1393           NULL));
1394   fail_unless (gst_structure_get (stats, remote_id, GST_TYPE_STRUCTURE, &remote,
1395           NULL));
1396   fail_unless (remote != NULL);
1397
1398   gst_structure_free (remote);
1399   g_free (remote_id);
1400 }
1401
1402 static void
1403 validate_remote_inbound_rtp_stats (const GstStructure * s,
1404     const GstStructure * stats)
1405 {
1406   guint ssrc;
1407   gint packets_lost;
1408   double jitter, rtt;
1409   gchar *local_id;
1410   GstStructure *local;
1411
1412   validate_rtc_stream_stats (s, stats);
1413
1414   fail_unless (gst_structure_get (s, "ssrc", G_TYPE_UINT, &ssrc, NULL));
1415   fail_unless (gst_structure_get (s, "jitter", G_TYPE_DOUBLE, &jitter, NULL));
1416   fail_unless (gst_structure_get (s, "packets-lost", G_TYPE_INT, &packets_lost,
1417           NULL));
1418   fail_unless (gst_structure_get (s, "round-trip-time", G_TYPE_DOUBLE, &rtt,
1419           NULL));
1420   fail_unless (gst_structure_get (s, "local-id", G_TYPE_STRING, &local_id,
1421           NULL));
1422   fail_unless (gst_structure_get (stats, local_id, GST_TYPE_STRUCTURE, &local,
1423           NULL));
1424   fail_unless (local != NULL);
1425
1426   gst_structure_free (local);
1427   g_free (local_id);
1428 }
1429
1430 static void
1431 validate_outbound_rtp_stats (const GstStructure * s, const GstStructure * stats)
1432 {
1433   guint ssrc, fir, pli, nack;
1434   guint64 packets_sent, bytes_sent;
1435   gchar *remote_id;
1436   GstStructure *remote;
1437
1438   validate_rtc_stream_stats (s, stats);
1439
1440   fail_unless (gst_structure_get (s, "ssrc", G_TYPE_UINT, &ssrc, NULL));
1441   fail_unless (gst_structure_get (s, "fir-count", G_TYPE_UINT, &fir, NULL));
1442   fail_unless (gst_structure_get (s, "pli-count", G_TYPE_UINT, &pli, NULL));
1443   fail_unless (gst_structure_get (s, "nack-count", G_TYPE_UINT, &nack, NULL));
1444   fail_unless (gst_structure_get (s, "packets-sent", G_TYPE_UINT64,
1445           &packets_sent, NULL));
1446   fail_unless (gst_structure_get (s, "bytes-sent", G_TYPE_UINT64, &bytes_sent,
1447           NULL));
1448   fail_unless (gst_structure_get (s, "remote-id", G_TYPE_STRING, &remote_id,
1449           NULL));
1450   fail_unless (gst_structure_get (stats, remote_id, GST_TYPE_STRUCTURE, &remote,
1451           NULL));
1452   fail_unless (remote != NULL);
1453
1454   gst_structure_free (remote);
1455   g_free (remote_id);
1456 }
1457
1458 static void
1459 validate_remote_outbound_rtp_stats (const GstStructure * s,
1460     const GstStructure * stats)
1461 {
1462   guint ssrc;
1463   gchar *local_id;
1464   GstStructure *local;
1465
1466   validate_rtc_stream_stats (s, stats);
1467
1468   fail_unless (gst_structure_get (s, "ssrc", G_TYPE_UINT, &ssrc, NULL));
1469   fail_unless (gst_structure_get (s, "local-id", G_TYPE_STRING, &local_id,
1470           NULL));
1471   fail_unless (gst_structure_get (stats, local_id, GST_TYPE_STRUCTURE, &local,
1472           NULL));
1473   fail_unless (local != NULL);
1474
1475   gst_structure_free (local);
1476   g_free (local_id);
1477 }
1478
1479 static gboolean
1480 validate_stats_foreach (GQuark field_id, const GValue * value,
1481     const GstStructure * stats)
1482 {
1483   const gchar *field = g_quark_to_string (field_id);
1484   GstWebRTCStatsType type;
1485   const GstStructure *s;
1486
1487   fail_unless (GST_VALUE_HOLDS_STRUCTURE (value));
1488
1489   s = gst_value_get_structure (value);
1490
1491   GST_INFO ("validating field %s %" GST_PTR_FORMAT, field, s);
1492
1493   validate_rtc_stats (s);
1494   gst_structure_get (s, "type", GST_TYPE_WEBRTC_STATS_TYPE, &type, NULL);
1495   if (type == GST_WEBRTC_STATS_CODEC) {
1496     validate_codec_stats (s);
1497   } else if (type == GST_WEBRTC_STATS_INBOUND_RTP) {
1498     validate_inbound_rtp_stats (s, stats);
1499   } else if (type == GST_WEBRTC_STATS_OUTBOUND_RTP) {
1500     validate_outbound_rtp_stats (s, stats);
1501   } else if (type == GST_WEBRTC_STATS_REMOTE_INBOUND_RTP) {
1502     validate_remote_inbound_rtp_stats (s, stats);
1503   } else if (type == GST_WEBRTC_STATS_REMOTE_OUTBOUND_RTP) {
1504     validate_remote_outbound_rtp_stats (s, stats);
1505   } else if (type == GST_WEBRTC_STATS_CSRC) {
1506   } else if (type == GST_WEBRTC_STATS_PEER_CONNECTION) {
1507   } else if (type == GST_WEBRTC_STATS_DATA_CHANNEL) {
1508   } else if (type == GST_WEBRTC_STATS_STREAM) {
1509   } else if (type == GST_WEBRTC_STATS_TRANSPORT) {
1510   } else if (type == GST_WEBRTC_STATS_CANDIDATE_PAIR) {
1511   } else if (type == GST_WEBRTC_STATS_LOCAL_CANDIDATE) {
1512   } else if (type == GST_WEBRTC_STATS_REMOTE_CANDIDATE) {
1513   } else if (type == GST_WEBRTC_STATS_CERTIFICATE) {
1514   } else {
1515     g_assert_not_reached ();
1516   }
1517
1518   return TRUE;
1519 }
1520
1521 static void
1522 validate_stats (const GstStructure * stats)
1523 {
1524   gst_structure_foreach (stats,
1525       (GstStructureForeachFunc) validate_stats_foreach, (gpointer) stats);
1526 }
1527
1528 static void
1529 _on_stats (GstPromise * promise, gpointer user_data)
1530 {
1531   struct test_webrtc *t = user_data;
1532   const GstStructure *reply = gst_promise_get_reply (promise);
1533   int i;
1534
1535   validate_stats (reply);
1536   i = GPOINTER_TO_INT (t->user_data);
1537   i++;
1538   t->user_data = GINT_TO_POINTER (i);
1539   if (i >= 2)
1540     test_webrtc_signal_state (t, STATE_CUSTOM);
1541
1542   gst_promise_unref (promise);
1543 }
1544
1545 GST_START_TEST (test_session_stats)
1546 {
1547   struct test_webrtc *t = test_webrtc_new ();
1548   GstPromise *p;
1549
1550   /* test that the stats generated without any streams are sane */
1551   t->on_negotiation_needed = NULL;
1552   test_validate_sdp (t, NULL, NULL);
1553
1554   p = gst_promise_new_with_change_func (_on_stats, t, NULL);
1555   g_signal_emit_by_name (t->webrtc1, "get-stats", NULL, p);
1556   p = gst_promise_new_with_change_func (_on_stats, t, NULL);
1557   g_signal_emit_by_name (t->webrtc2, "get-stats", NULL, p);
1558
1559   test_webrtc_wait_for_state_mask (t, 1 << STATE_CUSTOM);
1560
1561   test_webrtc_free (t);
1562 }
1563
1564 GST_END_TEST;
1565
1566 GST_START_TEST (test_add_transceiver)
1567 {
1568   struct test_webrtc *t = test_webrtc_new ();
1569   GstWebRTCRTPTransceiverDirection direction;
1570   GstWebRTCRTPTransceiver *trans;
1571
1572   direction = GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDRECV;
1573   g_signal_emit_by_name (t->webrtc1, "add-transceiver", direction, NULL,
1574       &trans);
1575   fail_unless (trans != NULL);
1576   fail_unless_equals_int (direction, trans->direction);
1577
1578   gst_object_unref (trans);
1579
1580   test_webrtc_free (t);
1581 }
1582
1583 GST_END_TEST;
1584
1585 GST_START_TEST (test_get_transceivers)
1586 {
1587   struct test_webrtc *t = create_audio_test ();
1588   GstWebRTCRTPTransceiver *trans;
1589   GArray *transceivers;
1590
1591   g_signal_emit_by_name (t->webrtc1, "get-transceivers", &transceivers);
1592   fail_unless (transceivers != NULL);
1593   fail_unless_equals_int (1, transceivers->len);
1594
1595   trans = g_array_index (transceivers, GstWebRTCRTPTransceiver *, 0);
1596   fail_unless (trans != NULL);
1597
1598   g_array_unref (transceivers);
1599
1600   test_webrtc_free (t);
1601 }
1602
1603 GST_END_TEST;
1604
1605 GST_START_TEST (test_add_recvonly_transceiver)
1606 {
1607   struct test_webrtc *t = test_webrtc_new ();
1608   GstWebRTCRTPTransceiverDirection direction;
1609   GstWebRTCRTPTransceiver *trans;
1610   VAL_SDP_INIT (no_duplicate_payloads, on_sdp_media_no_duplicate_payloads,
1611       NULL, NULL);
1612   guint media_format_count[] = { 1, 1, };
1613   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
1614       media_format_count, &no_duplicate_payloads);
1615   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (1),
1616       &media_formats);
1617   const gchar *expected_offer_setup[] = { "actpass", };
1618   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup, &count);
1619   const gchar *expected_answer_setup[] = { "active", };
1620   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
1621       &count);
1622   const gchar *expected_offer_direction[] = { "recvonly", };
1623   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
1624       &offer_setup);
1625   const gchar *expected_answer_direction[] = { "sendonly", };
1626   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
1627       &answer_setup);
1628   GstCaps *caps;
1629   GstHarness *h;
1630
1631   /* add a transceiver that will only receive an opus stream and check that
1632    * the created offer is marked as recvonly */
1633   t->on_negotiation_needed = NULL;
1634   t->on_ice_candidate = NULL;
1635   t->on_pad_added = _pad_added_fakesink;
1636
1637   /* setup recvonly transceiver */
1638   caps = gst_caps_from_string (OPUS_RTP_CAPS (96));
1639   direction = GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY;
1640   g_signal_emit_by_name (t->webrtc1, "add-transceiver", direction, caps,
1641       &trans);
1642   gst_caps_unref (caps);
1643   fail_unless (trans != NULL);
1644   gst_object_unref (trans);
1645
1646   /* setup sendonly peer */
1647   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
1648   add_fake_audio_src_harness (h, 96);
1649   t->harnesses = g_list_prepend (t->harnesses, h);
1650   test_validate_sdp (t, &offer, &answer);
1651
1652   test_webrtc_free (t);
1653 }
1654
1655 GST_END_TEST;
1656
1657 GST_START_TEST (test_recvonly_sendonly)
1658 {
1659   struct test_webrtc *t = test_webrtc_new ();
1660   GstWebRTCRTPTransceiverDirection direction;
1661   GstWebRTCRTPTransceiver *trans;
1662   VAL_SDP_INIT (no_duplicate_payloads, on_sdp_media_no_duplicate_payloads,
1663       NULL, NULL);
1664   guint media_format_count[] = { 1, 1, };
1665   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
1666       media_format_count, &no_duplicate_payloads);
1667   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
1668       &media_formats);
1669   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
1670   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup, &count);
1671   const gchar *expected_answer_setup[] = { "active", "active" };
1672   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
1673       &count);
1674   const gchar *expected_offer_direction[] = { "recvonly", "sendonly" };
1675   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
1676       &offer_setup);
1677   const gchar *expected_answer_direction[] = { "sendonly", "recvonly" };
1678   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
1679       &answer_setup);
1680   GstCaps *caps;
1681   GstHarness *h;
1682   GArray *transceivers;
1683
1684   /* add a transceiver that will only receive an opus stream and check that
1685    * the created offer is marked as recvonly */
1686   t->on_negotiation_needed = NULL;
1687   t->on_ice_candidate = NULL;
1688   t->on_pad_added = _pad_added_fakesink;
1689
1690   /* setup recvonly transceiver */
1691   caps = gst_caps_from_string (OPUS_RTP_CAPS (96));
1692   direction = GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY;
1693   g_signal_emit_by_name (t->webrtc1, "add-transceiver", direction, caps,
1694       &trans);
1695   gst_caps_unref (caps);
1696   fail_unless (trans != NULL);
1697   gst_object_unref (trans);
1698
1699   /* setup sendonly stream */
1700   h = gst_harness_new_with_element (t->webrtc1, "sink_1", NULL);
1701   add_fake_audio_src_harness (h, 96);
1702   t->harnesses = g_list_prepend (t->harnesses, h);
1703   g_signal_emit_by_name (t->webrtc1, "get-transceivers", &transceivers);
1704   fail_unless (transceivers != NULL);
1705   fail_unless_equals_int (transceivers->len, 2);
1706   trans = g_array_index (transceivers, GstWebRTCRTPTransceiver *, 1);
1707   trans->direction = GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDONLY;
1708
1709   g_array_unref (transceivers);
1710
1711   /* setup sendonly peer */
1712   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
1713   add_fake_audio_src_harness (h, 96);
1714   t->harnesses = g_list_prepend (t->harnesses, h);
1715
1716   test_validate_sdp (t, &offer, &answer);
1717
1718   test_webrtc_free (t);
1719 }
1720
1721 GST_END_TEST;
1722
1723 static void
1724 on_sdp_has_datachannel (struct test_webrtc *t, GstElement * element,
1725     GstWebRTCSessionDescription * desc, gpointer user_data)
1726 {
1727   gboolean have_data_channel = FALSE;
1728   int i;
1729
1730   for (i = 0; i < gst_sdp_message_medias_len (desc->sdp); i++) {
1731     if (_message_media_is_datachannel (desc->sdp, i)) {
1732       /* there should only be one data channel m= section */
1733       fail_unless_equals_int (FALSE, have_data_channel);
1734       have_data_channel = TRUE;
1735     }
1736   }
1737
1738   fail_unless_equals_int (TRUE, have_data_channel);
1739 }
1740
1741 static void
1742 on_channel_error_not_reached (GObject * channel, GError * error,
1743     gpointer user_data)
1744 {
1745   g_assert_not_reached ();
1746 }
1747
1748 GST_START_TEST (test_data_channel_create)
1749 {
1750   struct test_webrtc *t = test_webrtc_new ();
1751   GObject *channel = NULL;
1752   VAL_SDP_INIT (media_count, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
1753   VAL_SDP_INIT (offer, on_sdp_has_datachannel, NULL, &media_count);
1754   gchar *label;
1755
1756   t->on_negotiation_needed = NULL;
1757   t->on_ice_candidate = NULL;
1758
1759   fail_if (gst_element_set_state (t->webrtc1,
1760           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
1761   fail_if (gst_element_set_state (t->webrtc2,
1762           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
1763
1764   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
1765       &channel);
1766   g_assert_nonnull (channel);
1767   g_object_get (channel, "label", &label, NULL);
1768   g_assert_cmpstr (label, ==, "label");
1769   g_signal_connect (channel, "on-error",
1770       G_CALLBACK (on_channel_error_not_reached), NULL);
1771
1772   test_validate_sdp (t, &offer, &offer);
1773
1774   g_object_unref (channel);
1775   g_free (label);
1776   test_webrtc_free (t);
1777 }
1778
1779 GST_END_TEST;
1780
1781 static void
1782 have_data_channel (struct test_webrtc *t, GstElement * element,
1783     GObject * our, gpointer user_data)
1784 {
1785   GObject *other = user_data;
1786   gchar *our_label, *other_label;
1787
1788   g_signal_connect (our, "on-error", G_CALLBACK (on_channel_error_not_reached),
1789       NULL);
1790
1791   g_object_get (our, "label", &our_label, NULL);
1792   g_object_get (other, "label", &other_label, NULL);
1793
1794   g_assert_cmpstr (our_label, ==, other_label);
1795
1796   g_free (our_label);
1797   g_free (other_label);
1798
1799   test_webrtc_signal_state_unlocked (t, STATE_CUSTOM);
1800 }
1801
1802 GST_START_TEST (test_data_channel_remote_notify)
1803 {
1804   struct test_webrtc *t = test_webrtc_new ();
1805   GObject *channel = NULL;
1806   VAL_SDP_INIT (media_count, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
1807   VAL_SDP_INIT (offer, on_sdp_has_datachannel, NULL, &media_count);
1808
1809   t->on_negotiation_needed = NULL;
1810   t->on_ice_candidate = NULL;
1811   t->on_data_channel = have_data_channel;
1812
1813   fail_if (gst_element_set_state (t->webrtc1,
1814           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
1815   fail_if (gst_element_set_state (t->webrtc2,
1816           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
1817
1818   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
1819       &channel);
1820   g_assert_nonnull (channel);
1821   t->data_channel_data = channel;
1822   g_signal_connect (channel, "on-error",
1823       G_CALLBACK (on_channel_error_not_reached), NULL);
1824
1825   fail_if (gst_element_set_state (t->webrtc1,
1826           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
1827   fail_if (gst_element_set_state (t->webrtc2,
1828           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
1829
1830   test_validate_sdp_full (t, &offer, &offer, 1 << STATE_CUSTOM, FALSE);
1831
1832   g_object_unref (channel);
1833   test_webrtc_free (t);
1834 }
1835
1836 GST_END_TEST;
1837
1838 static const gchar *test_string = "GStreamer WebRTC is awesome!";
1839
1840 static void
1841 on_message_string (GObject * channel, const gchar * str, struct test_webrtc *t)
1842 {
1843   GstWebRTCDataChannelState state;
1844   gchar *expected;
1845
1846   g_object_get (channel, "ready-state", &state, NULL);
1847   fail_unless_equals_int (GST_WEBRTC_DATA_CHANNEL_STATE_OPEN, state);
1848
1849   expected = g_object_steal_data (channel, "expected");
1850   g_assert_cmpstr (expected, ==, str);
1851   g_free (expected);
1852
1853   test_webrtc_signal_state (t, STATE_CUSTOM);
1854 }
1855
1856 static void
1857 have_data_channel_transfer_string (struct test_webrtc *t, GstElement * element,
1858     GObject * our, gpointer user_data)
1859 {
1860   GObject *other = user_data;
1861   GstWebRTCDataChannelState state;
1862
1863   g_object_get (our, "ready-state", &state, NULL);
1864   fail_unless_equals_int (GST_WEBRTC_DATA_CHANNEL_STATE_OPEN, state);
1865
1866   g_object_set_data_full (our, "expected", g_strdup (test_string), g_free);
1867   g_signal_connect (our, "on-message-string", G_CALLBACK (on_message_string),
1868       t);
1869
1870   g_signal_connect (other, "on-error",
1871       G_CALLBACK (on_channel_error_not_reached), NULL);
1872   g_signal_emit_by_name (other, "send-string", test_string);
1873 }
1874
1875 GST_START_TEST (test_data_channel_transfer_string)
1876 {
1877   struct test_webrtc *t = test_webrtc_new ();
1878   GObject *channel = NULL;
1879   VAL_SDP_INIT (media_count, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
1880   VAL_SDP_INIT (offer, on_sdp_has_datachannel, NULL, &media_count);
1881
1882   t->on_negotiation_needed = NULL;
1883   t->on_ice_candidate = NULL;
1884   t->on_data_channel = have_data_channel_transfer_string;
1885
1886   fail_if (gst_element_set_state (t->webrtc1,
1887           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
1888   fail_if (gst_element_set_state (t->webrtc2,
1889           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
1890
1891   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
1892       &channel);
1893   g_assert_nonnull (channel);
1894   t->data_channel_data = channel;
1895   g_signal_connect (channel, "on-error",
1896       G_CALLBACK (on_channel_error_not_reached), NULL);
1897
1898   fail_if (gst_element_set_state (t->webrtc1,
1899           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
1900   fail_if (gst_element_set_state (t->webrtc2,
1901           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
1902
1903   test_validate_sdp_full (t, &offer, &offer, 1 << STATE_CUSTOM, FALSE);
1904
1905   g_object_unref (channel);
1906   test_webrtc_free (t);
1907 }
1908
1909 GST_END_TEST;
1910
1911 #define g_assert_cmpbytes(b1, b2)                       \
1912     G_STMT_START {                                      \
1913       gsize l1, l2;                                     \
1914       const guint8 *d1 = g_bytes_get_data (b1, &l1);    \
1915       const guint8 *d2 = g_bytes_get_data (b2, &l2);    \
1916       g_assert_cmpmem (d1, l1, d2, l2);                 \
1917     } G_STMT_END;
1918
1919 static void
1920 on_message_data (GObject * channel, GBytes * data, struct test_webrtc *t)
1921 {
1922   GstWebRTCDataChannelState state;
1923   GBytes *expected;
1924
1925   g_object_get (channel, "ready-state", &state, NULL);
1926   fail_unless_equals_int (GST_WEBRTC_DATA_CHANNEL_STATE_OPEN, state);
1927
1928   expected = g_object_steal_data (channel, "expected");
1929   g_assert_cmpbytes (data, expected);
1930   g_bytes_unref (expected);
1931
1932   test_webrtc_signal_state (t, STATE_CUSTOM);
1933 }
1934
1935 static void
1936 have_data_channel_transfer_data (struct test_webrtc *t, GstElement * element,
1937     GObject * our, gpointer user_data)
1938 {
1939   GObject *other = user_data;
1940   GBytes *data = g_bytes_new_static (test_string, strlen (test_string));
1941   GstWebRTCDataChannelState state;
1942
1943   g_object_get (our, "ready-state", &state, NULL);
1944   fail_unless_equals_int (GST_WEBRTC_DATA_CHANNEL_STATE_OPEN, state);
1945
1946   g_object_set_data_full (our, "expected", g_bytes_ref (data),
1947       (GDestroyNotify) g_bytes_unref);
1948   g_signal_connect (our, "on-message-data", G_CALLBACK (on_message_data), t);
1949
1950   g_signal_connect (other, "on-error",
1951       G_CALLBACK (on_channel_error_not_reached), NULL);
1952   g_signal_emit_by_name (other, "send-data", data);
1953   g_bytes_unref (data);
1954 }
1955
1956 GST_START_TEST (test_data_channel_transfer_data)
1957 {
1958   struct test_webrtc *t = test_webrtc_new ();
1959   GObject *channel = NULL;
1960   VAL_SDP_INIT (media_count, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
1961   VAL_SDP_INIT (offer, on_sdp_has_datachannel, NULL, &media_count);
1962
1963   t->on_negotiation_needed = NULL;
1964   t->on_ice_candidate = NULL;
1965   t->on_data_channel = have_data_channel_transfer_data;
1966
1967   fail_if (gst_element_set_state (t->webrtc1,
1968           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
1969   fail_if (gst_element_set_state (t->webrtc2,
1970           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
1971
1972   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
1973       &channel);
1974   g_assert_nonnull (channel);
1975   t->data_channel_data = channel;
1976   g_signal_connect (channel, "on-error",
1977       G_CALLBACK (on_channel_error_not_reached), NULL);
1978
1979   fail_if (gst_element_set_state (t->webrtc1,
1980           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
1981   fail_if (gst_element_set_state (t->webrtc2,
1982           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
1983
1984   test_validate_sdp_full (t, &offer, &offer, 1 << STATE_CUSTOM, FALSE);
1985
1986   g_object_unref (channel);
1987   test_webrtc_free (t);
1988 }
1989
1990 GST_END_TEST;
1991
1992 static void
1993 have_data_channel_create_data_channel (struct test_webrtc *t,
1994     GstElement * element, GObject * our, gpointer user_data)
1995 {
1996   GObject *another;
1997
1998   t->on_data_channel = have_data_channel_transfer_string;
1999
2000   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
2001       &another);
2002   g_assert_nonnull (another);
2003   t->data_channel_data = another;
2004   t->data_channel_notify = (GDestroyNotify) g_object_unref;
2005   g_signal_connect (another, "on-error",
2006       G_CALLBACK (on_channel_error_not_reached), NULL);
2007 }
2008
2009 GST_START_TEST (test_data_channel_create_after_negotiate)
2010 {
2011   struct test_webrtc *t = test_webrtc_new ();
2012   GObject *channel = NULL;
2013   VAL_SDP_INIT (media_count, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
2014   VAL_SDP_INIT (offer, on_sdp_has_datachannel, NULL, &media_count);
2015
2016   t->on_negotiation_needed = NULL;
2017   t->on_ice_candidate = NULL;
2018   t->on_data_channel = have_data_channel_create_data_channel;
2019
2020   fail_if (gst_element_set_state (t->webrtc1,
2021           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2022   fail_if (gst_element_set_state (t->webrtc2,
2023           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2024
2025   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "prev-label", NULL,
2026       &channel);
2027   g_assert_nonnull (channel);
2028   t->data_channel_data = channel;
2029   g_signal_connect (channel, "on-error",
2030       G_CALLBACK (on_channel_error_not_reached), NULL);
2031
2032   fail_if (gst_element_set_state (t->webrtc1,
2033           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2034   fail_if (gst_element_set_state (t->webrtc2,
2035           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2036
2037   test_validate_sdp_full (t, &offer, &offer, 1 << STATE_CUSTOM, FALSE);
2038
2039   g_object_unref (channel);
2040   test_webrtc_free (t);
2041 }
2042
2043 GST_END_TEST;
2044
2045 static void
2046 on_buffered_amount_low_emitted (GObject * channel, struct test_webrtc *t)
2047 {
2048   test_webrtc_signal_state (t, STATE_CUSTOM);
2049 }
2050
2051 static void
2052 have_data_channel_check_low_threshold_emitted (struct test_webrtc *t,
2053     GstElement * element, GObject * our, gpointer user_data)
2054 {
2055   g_signal_connect (our, "on-buffered-amount-low",
2056       G_CALLBACK (on_buffered_amount_low_emitted), t);
2057   g_object_set (our, "buffered-amount-low-threshold", 1, NULL);
2058
2059   g_signal_connect (our, "on-error", G_CALLBACK (on_channel_error_not_reached),
2060       NULL);
2061   g_signal_emit_by_name (our, "send-string", "A");
2062 }
2063
2064 GST_START_TEST (test_data_channel_low_threshold)
2065 {
2066   struct test_webrtc *t = test_webrtc_new ();
2067   GObject *channel = NULL;
2068   VAL_SDP_INIT (media_count, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
2069   VAL_SDP_INIT (offer, on_sdp_has_datachannel, NULL, &media_count);
2070
2071   t->on_negotiation_needed = NULL;
2072   t->on_ice_candidate = NULL;
2073   t->on_data_channel = have_data_channel_check_low_threshold_emitted;
2074
2075   fail_if (gst_element_set_state (t->webrtc1,
2076           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2077   fail_if (gst_element_set_state (t->webrtc2,
2078           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2079
2080   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
2081       &channel);
2082   g_assert_nonnull (channel);
2083   t->data_channel_data = channel;
2084   g_signal_connect (channel, "on-error",
2085       G_CALLBACK (on_channel_error_not_reached), NULL);
2086
2087   fail_if (gst_element_set_state (t->webrtc1,
2088           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2089   fail_if (gst_element_set_state (t->webrtc2,
2090           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2091
2092   test_validate_sdp_full (t, &offer, &offer, 1 << STATE_CUSTOM, FALSE);
2093
2094   g_object_unref (channel);
2095   test_webrtc_free (t);
2096 }
2097
2098 GST_END_TEST;
2099
2100 static void
2101 on_channel_error (GObject * channel, GError * error, struct test_webrtc *t)
2102 {
2103   g_assert_nonnull (error);
2104
2105   test_webrtc_signal_state (t, STATE_CUSTOM);
2106 }
2107
2108 static void
2109 have_data_channel_transfer_large_data (struct test_webrtc *t,
2110     GstElement * element, GObject * our, gpointer user_data)
2111 {
2112   GObject *other = user_data;
2113   const gsize size = 1024 * 1024;
2114   guint8 *random_data = g_new (guint8, size);
2115   GBytes *data;
2116   gsize i;
2117
2118   for (i = 0; i < size; i++)
2119     random_data[i] = (guint8) (i & 0xff);
2120
2121   data = g_bytes_new_with_free_func (random_data, size,
2122       (GDestroyNotify) g_free, random_data);
2123
2124   g_object_set_data_full (our, "expected", g_bytes_ref (data),
2125       (GDestroyNotify) g_bytes_unref);
2126   g_signal_connect (our, "on-message-data", G_CALLBACK (on_message_data), t);
2127
2128   g_signal_connect (other, "on-error", G_CALLBACK (on_channel_error), t);
2129   g_signal_emit_by_name (other, "send-data", data);
2130   g_bytes_unref (data);
2131 }
2132
2133 GST_START_TEST (test_data_channel_max_message_size)
2134 {
2135   struct test_webrtc *t = test_webrtc_new ();
2136   GObject *channel = NULL;
2137   VAL_SDP_INIT (media_count, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
2138   VAL_SDP_INIT (offer, on_sdp_has_datachannel, NULL, &media_count);
2139
2140   t->on_negotiation_needed = NULL;
2141   t->on_ice_candidate = NULL;
2142   t->on_data_channel = have_data_channel_transfer_large_data;
2143
2144   fail_if (gst_element_set_state (t->webrtc1,
2145           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2146   fail_if (gst_element_set_state (t->webrtc2,
2147           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2148
2149   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
2150       &channel);
2151   g_assert_nonnull (channel);
2152   t->data_channel_data = channel;
2153
2154   fail_if (gst_element_set_state (t->webrtc1,
2155           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2156   fail_if (gst_element_set_state (t->webrtc2,
2157           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2158
2159   test_validate_sdp_full (t, &offer, &offer, 1 << STATE_CUSTOM, FALSE);
2160
2161   g_object_unref (channel);
2162   test_webrtc_free (t);
2163 }
2164
2165 GST_END_TEST;
2166
2167 static void
2168 _on_ready_state_notify (GObject * channel, GParamSpec * pspec,
2169     struct test_webrtc *t)
2170 {
2171   gint *n_ready = t->data_channel_data;
2172   GstWebRTCDataChannelState ready_state;
2173
2174   g_object_get (channel, "ready-state", &ready_state, NULL);
2175
2176   if (ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_OPEN) {
2177     if (g_atomic_int_add (n_ready, 1) >= 1) {
2178       test_webrtc_signal_state (t, STATE_CUSTOM);
2179     }
2180   }
2181 }
2182
2183 GST_START_TEST (test_data_channel_pre_negotiated)
2184 {
2185   struct test_webrtc *t = test_webrtc_new ();
2186   GObject *channel1 = NULL, *channel2 = NULL;
2187   VAL_SDP_INIT (media_count, _count_num_sdp_media, GUINT_TO_POINTER (1), NULL);
2188   VAL_SDP_INIT (offer, on_sdp_has_datachannel, NULL, &media_count);
2189   GstStructure *s;
2190   gint n_ready = 0;
2191
2192   t->on_negotiation_needed = NULL;
2193   t->on_ice_candidate = NULL;
2194
2195   fail_if (gst_element_set_state (t->webrtc1,
2196           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2197   fail_if (gst_element_set_state (t->webrtc2,
2198           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2199
2200   s = gst_structure_new ("application/data-channel", "negotiated",
2201       G_TYPE_BOOLEAN, TRUE, "id", G_TYPE_INT, 1, NULL);
2202
2203   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", s,
2204       &channel1);
2205   g_assert_nonnull (channel1);
2206   g_signal_emit_by_name (t->webrtc2, "create-data-channel", "label", s,
2207       &channel2);
2208   g_assert_nonnull (channel2);
2209
2210   fail_if (gst_element_set_state (t->webrtc1,
2211           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2212   fail_if (gst_element_set_state (t->webrtc2,
2213           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2214
2215   test_validate_sdp_full (t, &offer, &offer, 0, FALSE);
2216
2217   t->data_channel_data = &n_ready;
2218
2219   g_signal_connect (channel1, "notify::ready-state",
2220       G_CALLBACK (_on_ready_state_notify), t);
2221   g_signal_connect (channel2, "notify::ready-state",
2222       G_CALLBACK (_on_ready_state_notify), t);
2223
2224   test_webrtc_wait_for_state_mask (t, 1 << STATE_CUSTOM);
2225   test_webrtc_signal_state (t, STATE_NEW);
2226
2227   have_data_channel_transfer_string (t, t->webrtc1, channel1, channel2);
2228
2229   test_webrtc_wait_for_state_mask (t, 1 << STATE_CUSTOM);
2230
2231   g_object_unref (channel1);
2232   g_object_unref (channel2);
2233   gst_structure_free (s);
2234   test_webrtc_free (t);
2235 }
2236
2237 GST_END_TEST;
2238
2239 static void
2240 _count_non_rejected_media (struct test_webrtc *t, GstElement * element,
2241     GstWebRTCSessionDescription * sd, gpointer user_data)
2242 {
2243   guint expected = GPOINTER_TO_UINT (user_data);
2244   guint non_rejected_media;
2245   guint i;
2246
2247   non_rejected_media = 0;
2248
2249   for (i = 0; i < gst_sdp_message_medias_len (sd->sdp); i++) {
2250     const GstSDPMedia *media = gst_sdp_message_get_media (sd->sdp, i);
2251
2252     if (gst_sdp_media_get_port (media) != 0)
2253       non_rejected_media += 1;
2254   }
2255
2256   fail_unless_equals_int (non_rejected_media, expected);
2257 }
2258
2259 static void
2260 _check_bundle_tag (struct test_webrtc *t, GstElement * element,
2261     GstWebRTCSessionDescription * sd, gpointer user_data)
2262 {
2263   gchar **bundled = NULL;
2264   GStrv expected = user_data;
2265   guint i;
2266
2267   fail_unless (_parse_bundle (sd->sdp, &bundled, NULL));
2268
2269   if (!bundled) {
2270     fail_unless_equals_int (g_strv_length (expected), 0);
2271   } else {
2272     fail_unless_equals_int (g_strv_length (bundled), g_strv_length (expected));
2273   }
2274
2275   for (i = 0; i < g_strv_length (expected); i++) {
2276     fail_unless (g_strv_contains ((const gchar **) bundled, expected[i]));
2277   }
2278
2279   g_strfreev (bundled);
2280 }
2281
2282 static void
2283 _check_bundle_only_media (struct test_webrtc *t, GstElement * element,
2284     GstWebRTCSessionDescription * sd, gpointer user_data)
2285 {
2286   gchar **expected_bundle_only = user_data;
2287   guint i;
2288
2289   for (i = 0; i < gst_sdp_message_medias_len (sd->sdp); i++) {
2290     const GstSDPMedia *media = gst_sdp_message_get_media (sd->sdp, i);
2291     const gchar *mid = gst_sdp_media_get_attribute_val (media, "mid");
2292
2293     if (g_strv_contains ((const gchar **) expected_bundle_only, mid))
2294       fail_unless (_media_has_attribute_key (media, "bundle-only"));
2295   }
2296 }
2297
2298 GST_START_TEST (test_bundle_audio_video_max_bundle_max_bundle)
2299 {
2300   struct test_webrtc *t = create_audio_video_test ();
2301   const gchar *bundle[] = { "audio0", "video1", NULL };
2302   const gchar *offer_bundle_only[] = { "video1", NULL };
2303   const gchar *answer_bundle_only[] = { NULL };
2304
2305   guint media_format_count[] = { 1, 1, };
2306   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2307       media_format_count, NULL);
2308   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
2309       &media_formats);
2310   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
2311   VAL_SDP_INIT (bundle_tag, _check_bundle_tag, bundle, &payloads);
2312   VAL_SDP_INIT (offer_non_reject, _count_non_rejected_media,
2313       GUINT_TO_POINTER (1), &bundle_tag);
2314   VAL_SDP_INIT (answer_non_reject, _count_non_rejected_media,
2315       GUINT_TO_POINTER (2), &bundle_tag);
2316   VAL_SDP_INIT (offer_bundle, _check_bundle_only_media, &offer_bundle_only,
2317       &offer_non_reject);
2318   VAL_SDP_INIT (answer_bundle, _check_bundle_only_media, &answer_bundle_only,
2319       &answer_non_reject);
2320   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
2321   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2322       &offer_bundle);
2323   const gchar *expected_answer_setup[] = { "active", "active" };
2324   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
2325       &answer_bundle);
2326   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv" };
2327   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
2328       &offer_setup);
2329   const gchar *expected_answer_direction[] = { "recvonly", "recvonly" };
2330   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
2331       &answer_setup);
2332
2333   /* We set a max-bundle policy on the offering webrtcbin,
2334    * this means that all the offered medias should be part
2335    * of the group:BUNDLE attribute, and they should be marked
2336    * as bundle-only
2337    */
2338   gst_util_set_object_arg (G_OBJECT (t->webrtc1), "bundle-policy",
2339       "max-bundle");
2340   /* We also set a max-bundle policy on the answering webrtcbin,
2341    * this means that all the offered medias should be part
2342    * of the group:BUNDLE attribute, but need not be marked
2343    * as bundle-only.
2344    */
2345   gst_util_set_object_arg (G_OBJECT (t->webrtc2), "bundle-policy",
2346       "max-bundle");
2347
2348   test_validate_sdp (t, &offer, &answer);
2349
2350   test_webrtc_free (t);
2351 }
2352
2353 GST_END_TEST;
2354
2355 GST_START_TEST (test_bundle_audio_video_max_compat_max_bundle)
2356 {
2357   struct test_webrtc *t = create_audio_video_test ();
2358   const gchar *bundle[] = { "audio0", "video1", NULL };
2359   const gchar *bundle_only[] = { NULL };
2360
2361   guint media_format_count[] = { 1, 1, };
2362   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2363       media_format_count, NULL);
2364   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
2365       &media_formats);
2366   VAL_SDP_INIT (bundle_tag, _check_bundle_tag, bundle, &count);
2367   VAL_SDP_INIT (count_non_reject, _count_non_rejected_media,
2368       GUINT_TO_POINTER (2), &bundle_tag);
2369   VAL_SDP_INIT (bundle_sdp, _check_bundle_only_media, &bundle_only,
2370       &count_non_reject);
2371   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
2372   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2373       &bundle_sdp);
2374   const gchar *expected_answer_setup[] = { "active", "active" };
2375   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
2376       &bundle_sdp);
2377   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv" };
2378   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
2379       &offer_setup);
2380   const gchar *expected_answer_direction[] = { "recvonly", "recvonly" };
2381   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
2382       &answer_setup);
2383
2384   /* We set a max-compat policy on the offering webrtcbin,
2385    * this means that all the offered medias should be part
2386    * of the group:BUNDLE attribute, and they should *not* be marked
2387    * as bundle-only
2388    */
2389   gst_util_set_object_arg (G_OBJECT (t->webrtc1), "bundle-policy",
2390       "max-compat");
2391   /* We set a max-bundle policy on the answering webrtcbin,
2392    * this means that all the offered medias should be part
2393    * of the group:BUNDLE attribute, but need not be marked
2394    * as bundle-only.
2395    */
2396   gst_util_set_object_arg (G_OBJECT (t->webrtc2), "bundle-policy",
2397       "max-bundle");
2398
2399   test_validate_sdp (t, &offer, &answer);
2400
2401   test_webrtc_free (t);
2402 }
2403
2404 GST_END_TEST;
2405
2406 GST_START_TEST (test_bundle_audio_video_max_bundle_none)
2407 {
2408   struct test_webrtc *t = create_audio_video_test ();
2409   const gchar *offer_mid[] = { "audio0", "video1", NULL };
2410   const gchar *offer_bundle_only[] = { "video1", NULL };
2411   const gchar *answer_mid[] = { NULL };
2412   const gchar *answer_bundle_only[] = { NULL };
2413
2414   guint media_format_count[] = { 1, 1, };
2415   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2416       media_format_count, NULL);
2417   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
2418       &media_formats);
2419   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
2420   VAL_SDP_INIT (count_non_reject, _count_non_rejected_media,
2421       GUINT_TO_POINTER (1), &payloads);
2422   VAL_SDP_INIT (offer_bundle_tag, _check_bundle_tag, offer_mid,
2423       &count_non_reject);
2424   VAL_SDP_INIT (answer_bundle_tag, _check_bundle_tag, answer_mid,
2425       &count_non_reject);
2426   VAL_SDP_INIT (offer_bundle, _check_bundle_only_media, &offer_bundle_only,
2427       &offer_bundle_tag);
2428   VAL_SDP_INIT (answer_bundle, _check_bundle_only_media, &answer_bundle_only,
2429       &answer_bundle_tag);
2430   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
2431   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2432       &offer_bundle);
2433   const gchar *expected_answer_setup[] = { "active", "active" };
2434   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
2435       &answer_bundle);
2436   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv" };
2437   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
2438       &offer_setup);
2439   const gchar *expected_answer_direction[] = { "recvonly", "recvonly" };
2440   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
2441       &answer_setup);
2442
2443   /* We set a max-bundle policy on the offering webrtcbin,
2444    * this means that all the offered medias should be part
2445    * of the group:BUNDLE attribute, and they should be marked
2446    * as bundle-only
2447    */
2448   gst_util_set_object_arg (G_OBJECT (t->webrtc1), "bundle-policy",
2449       "max-bundle");
2450   /* We set a none policy on the answering webrtcbin,
2451    * this means that the answer should contain no bundled
2452    * medias, and as the bundle-policy of the offering webrtcbin
2453    * is set to max-bundle, only one media should be active.
2454    */
2455   gst_util_set_object_arg (G_OBJECT (t->webrtc2), "bundle-policy", "none");
2456
2457   test_validate_sdp (t, &offer, &answer);
2458
2459   test_webrtc_free (t);
2460 }
2461
2462 GST_END_TEST;
2463
2464 GST_START_TEST (test_bundle_audio_video_data)
2465 {
2466   struct test_webrtc *t = create_audio_video_test ();
2467   const gchar *mids[] = { "audio0", "video1", "application2", NULL };
2468   const gchar *offer_bundle_only[] = { "video1", "application2", NULL };
2469   const gchar *answer_bundle_only[] = { NULL };
2470   GObject *channel = NULL;
2471
2472   guint media_format_count[] = { 1, 1, 1 };
2473   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2474       media_format_count, NULL);
2475   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (3),
2476       &media_formats);
2477   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
2478   VAL_SDP_INIT (bundle_tag, _check_bundle_tag, mids, &payloads);
2479   VAL_SDP_INIT (offer_non_reject, _count_non_rejected_media,
2480       GUINT_TO_POINTER (1), &bundle_tag);
2481   VAL_SDP_INIT (answer_non_reject, _count_non_rejected_media,
2482       GUINT_TO_POINTER (3), &bundle_tag);
2483   VAL_SDP_INIT (offer_bundle, _check_bundle_only_media, &offer_bundle_only,
2484       &offer_non_reject);
2485   VAL_SDP_INIT (answer_bundle, _check_bundle_only_media, &answer_bundle_only,
2486       &answer_non_reject);
2487   const gchar *expected_offer_setup[] = { "actpass", "actpass", "actpass" };
2488   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2489       &offer_bundle);
2490   const gchar *expected_answer_setup[] = { "active", "active", "active" };
2491   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
2492       &answer_bundle);
2493   const gchar *expected_offer_direction[] =
2494       { "sendrecv", "sendrecv", "sendrecv" };
2495   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
2496       &offer_setup);
2497   const gchar *expected_answer_direction[] =
2498       { "recvonly", "recvonly", "recvonly" };
2499   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
2500       &answer_setup);
2501
2502   /* We set a max-bundle policy on the offering webrtcbin,
2503    * this means that all the offered medias should be part
2504    * of the group:BUNDLE attribute, and they should be marked
2505    * as bundle-only
2506    */
2507   gst_util_set_object_arg (G_OBJECT (t->webrtc1), "bundle-policy",
2508       "max-bundle");
2509   /* We also set a max-bundle policy on the answering webrtcbin,
2510    * this means that all the offered medias should be part
2511    * of the group:BUNDLE attribute, but need not be marked
2512    * as bundle-only.
2513    */
2514   gst_util_set_object_arg (G_OBJECT (t->webrtc2), "bundle-policy",
2515       "max-bundle");
2516
2517   fail_if (gst_element_set_state (t->webrtc1,
2518           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2519   fail_if (gst_element_set_state (t->webrtc2,
2520           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
2521
2522   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
2523       &channel);
2524
2525   test_validate_sdp (t, &offer, &answer);
2526
2527   g_object_unref (channel);
2528   test_webrtc_free (t);
2529 }
2530
2531 GST_END_TEST;
2532
2533 GST_START_TEST (test_duplicate_nego)
2534 {
2535   struct test_webrtc *t = create_audio_video_test ();
2536   guint media_format_count[] = { 1, 1, };
2537   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2538       media_format_count, NULL);
2539   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
2540       &media_formats);
2541   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
2542   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
2543   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2544       &payloads);
2545   const gchar *expected_answer_setup[] = { "active", "active" };
2546   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
2547       &payloads);
2548   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv" };
2549   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
2550       &offer_setup);
2551   const gchar *expected_answer_direction[] = { "sendrecv", "recvonly" };
2552   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
2553       &answer_setup);
2554   GstHarness *h;
2555   guint negotiation_flag = 0;
2556
2557   /* check that negotiating twice succeeds */
2558
2559   t->on_negotiation_needed = on_negotiation_needed_hit;
2560   t->negotiation_data = &negotiation_flag;
2561
2562   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
2563   add_fake_audio_src_harness (h, 96);
2564   t->harnesses = g_list_prepend (t->harnesses, h);
2565
2566   test_validate_sdp (t, &offer, &answer);
2567   fail_unless_equals_int (negotiation_flag, 1);
2568
2569   test_webrtc_reset_negotiation (t);
2570   test_validate_sdp (t, &offer, &answer);
2571
2572   test_webrtc_free (t);
2573 }
2574
2575 GST_END_TEST;
2576
2577 GST_START_TEST (test_dual_audio)
2578 {
2579   struct test_webrtc *t = create_audio_test ();
2580   guint media_format_count[] = { 1, 1, };
2581   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2582       media_format_count, NULL);
2583   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
2584       &media_formats);
2585   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
2586   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
2587   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2588       &payloads);
2589   const gchar *expected_answer_setup[] = { "active", "active" };
2590   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
2591       &payloads);
2592   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv" };
2593   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
2594       &offer_setup);
2595   const gchar *expected_answer_direction[] = { "sendrecv", "recvonly" };
2596   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
2597       &answer_setup);
2598   GstHarness *h;
2599   GstWebRTCRTPTransceiver *trans;
2600   GArray *transceivers;
2601
2602   /* test that each mline gets a unique transceiver even with the same caps */
2603
2604   h = gst_harness_new_with_element (t->webrtc1, "sink_1", NULL);
2605   add_fake_audio_src_harness (h, 96);
2606   t->harnesses = g_list_prepend (t->harnesses, h);
2607
2608   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
2609   add_fake_audio_src_harness (h, 96);
2610   t->harnesses = g_list_prepend (t->harnesses, h);
2611
2612   t->on_negotiation_needed = NULL;
2613   test_validate_sdp (t, &offer, &answer);
2614
2615   g_signal_emit_by_name (t->webrtc1, "get-transceivers", &transceivers);
2616   fail_unless (transceivers != NULL);
2617   fail_unless_equals_int (2, transceivers->len);
2618
2619   trans = g_array_index (transceivers, GstWebRTCRTPTransceiver *, 0);
2620   fail_unless (trans != NULL);
2621   fail_unless_equals_int (trans->mline, 0);
2622
2623   trans = g_array_index (transceivers, GstWebRTCRTPTransceiver *, 1);
2624   fail_unless (trans != NULL);
2625   fail_unless_equals_int (trans->mline, 1);
2626
2627   g_array_unref (transceivers);
2628   test_webrtc_free (t);
2629 }
2630
2631 GST_END_TEST;
2632
2633 static void
2634 sdp_increasing_session_version (struct test_webrtc *t, GstElement * element,
2635     GstWebRTCSessionDescription * desc, gpointer user_data)
2636 {
2637   GstWebRTCSessionDescription *previous;
2638   const GstSDPOrigin *our_origin, *previous_origin;
2639   const gchar *prop;
2640   guint64 our_v, previous_v;
2641
2642   prop =
2643       TEST_SDP_IS_LOCAL (t, element,
2644       desc) ? "current-local-description" : "current-remote-description";
2645   g_object_get (element, prop, &previous, NULL);
2646
2647   our_origin = gst_sdp_message_get_origin (desc->sdp);
2648   previous_origin = gst_sdp_message_get_origin (previous->sdp);
2649
2650   our_v = g_ascii_strtoull (our_origin->sess_version, NULL, 10);
2651   previous_v = g_ascii_strtoull (previous_origin->sess_version, NULL, 10);
2652
2653   ck_assert_int_lt (previous_v, our_v);
2654
2655   gst_webrtc_session_description_free (previous);
2656 }
2657
2658 static void
2659 sdp_equal_session_id (struct test_webrtc *t, GstElement * element,
2660     GstWebRTCSessionDescription * desc, gpointer user_data)
2661 {
2662   GstWebRTCSessionDescription *previous;
2663   const GstSDPOrigin *our_origin, *previous_origin;
2664   const gchar *prop;
2665
2666   prop =
2667       TEST_SDP_IS_LOCAL (t, element,
2668       desc) ? "current-local-description" : "current-remote-description";
2669   g_object_get (element, prop, &previous, NULL);
2670
2671   our_origin = gst_sdp_message_get_origin (desc->sdp);
2672   previous_origin = gst_sdp_message_get_origin (previous->sdp);
2673
2674   fail_unless_equals_string (previous_origin->sess_id, our_origin->sess_id);
2675   gst_webrtc_session_description_free (previous);
2676 }
2677
2678 static void
2679 sdp_media_equal_attribute (struct test_webrtc *t, GstElement * element,
2680     GstWebRTCSessionDescription * desc, GstWebRTCSessionDescription * previous,
2681     const gchar * attr)
2682 {
2683   guint i, n;
2684
2685   n = MIN (gst_sdp_message_medias_len (previous->sdp),
2686       gst_sdp_message_medias_len (desc->sdp));
2687
2688   for (i = 0; i < n; i++) {
2689     const GstSDPMedia *our_media, *other_media;
2690     const gchar *our_mid, *other_mid;
2691
2692     our_media = gst_sdp_message_get_media (desc->sdp, i);
2693     other_media = gst_sdp_message_get_media (previous->sdp, i);
2694
2695     our_mid = gst_sdp_media_get_attribute_val (our_media, attr);
2696     other_mid = gst_sdp_media_get_attribute_val (other_media, attr);
2697
2698     fail_unless_equals_string (our_mid, other_mid);
2699   }
2700 }
2701
2702 static void
2703 sdp_media_equal_mid (struct test_webrtc *t, GstElement * element,
2704     GstWebRTCSessionDescription * desc, gpointer user_data)
2705 {
2706   GstWebRTCSessionDescription *previous;
2707   const gchar *prop;
2708
2709   prop =
2710       TEST_SDP_IS_LOCAL (t, element,
2711       desc) ? "current-local-description" : "current-remote-description";
2712   g_object_get (element, prop, &previous, NULL);
2713
2714   sdp_media_equal_attribute (t, element, desc, previous, "mid");
2715
2716   gst_webrtc_session_description_free (previous);
2717 }
2718
2719 static void
2720 sdp_media_equal_ice_params (struct test_webrtc *t, GstElement * element,
2721     GstWebRTCSessionDescription * desc, gpointer user_data)
2722 {
2723   GstWebRTCSessionDescription *previous;
2724   const gchar *prop;
2725
2726   prop =
2727       TEST_SDP_IS_LOCAL (t, element,
2728       desc) ? "current-local-description" : "current-remote-description";
2729   g_object_get (element, prop, &previous, NULL);
2730
2731   sdp_media_equal_attribute (t, element, desc, previous, "ice-ufrag");
2732   sdp_media_equal_attribute (t, element, desc, previous, "ice-pwd");
2733
2734   gst_webrtc_session_description_free (previous);
2735 }
2736
2737 static void
2738 sdp_media_equal_fingerprint (struct test_webrtc *t, GstElement * element,
2739     GstWebRTCSessionDescription * desc, gpointer user_data)
2740 {
2741   GstWebRTCSessionDescription *previous;
2742   const gchar *prop;
2743
2744   prop =
2745       TEST_SDP_IS_LOCAL (t, element,
2746       desc) ? "current-local-description" : "current-remote-description";
2747   g_object_get (element, prop, &previous, NULL);
2748
2749   sdp_media_equal_attribute (t, element, desc, previous, "fingerprint");
2750
2751   gst_webrtc_session_description_free (previous);
2752 }
2753
2754 GST_START_TEST (test_renego_add_stream)
2755 {
2756   struct test_webrtc *t = create_audio_video_test ();
2757   guint media_format_count[] = { 1, 1, 1 };
2758   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2759       media_format_count, NULL);
2760   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
2761       &media_formats);
2762   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
2763   const gchar *expected_offer_setup[] = { "actpass", "actpass", "actpass" };
2764   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2765       &payloads);
2766   const gchar *expected_answer_setup[] = { "active", "active", "active" };
2767   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
2768       &payloads);
2769   const gchar *expected_offer_direction[] =
2770       { "sendrecv", "sendrecv", "sendrecv" };
2771   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
2772       &offer_setup);
2773   const gchar *expected_answer_direction[] =
2774       { "sendrecv", "recvonly", "recvonly" };
2775   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
2776       &answer_setup);
2777   VAL_SDP_INIT (renego_mid, sdp_media_equal_mid, NULL, NULL);
2778   VAL_SDP_INIT (renego_ice_params, sdp_media_equal_ice_params, NULL,
2779       &renego_mid);
2780   VAL_SDP_INIT (renego_sess_id, sdp_equal_session_id, NULL, &renego_ice_params);
2781   VAL_SDP_INIT (renego_sess_ver, sdp_increasing_session_version, NULL,
2782       &renego_sess_id);
2783   VAL_SDP_INIT (renego_fingerprint, sdp_media_equal_fingerprint, NULL,
2784       &renego_sess_ver);
2785   GstHarness *h;
2786
2787   /* negotiate an AV stream and then renegotiate an extra stream */
2788   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
2789   add_fake_audio_src_harness (h, 96);
2790   t->harnesses = g_list_prepend (t->harnesses, h);
2791
2792   test_validate_sdp (t, &offer, &answer);
2793
2794   h = gst_harness_new_with_element (t->webrtc1, "sink_2", NULL);
2795   add_fake_audio_src_harness (h, 98);
2796   t->harnesses = g_list_prepend (t->harnesses, h);
2797
2798   media_formats.next = &renego_fingerprint;
2799   count.user_data = GUINT_TO_POINTER (3);
2800
2801   /* renegotiate! */
2802   test_webrtc_reset_negotiation (t);
2803   test_validate_sdp (t, &offer, &answer);
2804
2805   test_webrtc_free (t);
2806 }
2807
2808 GST_END_TEST;
2809
2810 GST_START_TEST (test_renego_stream_add_data_channel)
2811 {
2812   struct test_webrtc *t = create_audio_video_test ();
2813
2814   guint media_format_count[] = { 1, 1, 1 };
2815   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2816       media_format_count, NULL);
2817   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
2818       &media_formats);
2819   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
2820   const gchar *expected_offer_setup[] = { "actpass", "actpass", "actpass" };
2821   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2822       &payloads);
2823   const gchar *expected_answer_setup[] = { "active", "active", "active" };
2824   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
2825       &payloads);
2826   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv", NULL };
2827   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
2828       &offer_setup);
2829   const gchar *expected_answer_direction[] = { "sendrecv", "recvonly", NULL };
2830   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
2831       &answer_setup);
2832   VAL_SDP_INIT (renego_mid, sdp_media_equal_mid, NULL, NULL);
2833   VAL_SDP_INIT (renego_ice_params, sdp_media_equal_ice_params, NULL,
2834       &renego_mid);
2835   VAL_SDP_INIT (renego_sess_id, sdp_equal_session_id, NULL, &renego_ice_params);
2836   VAL_SDP_INIT (renego_sess_ver, sdp_increasing_session_version, NULL,
2837       &renego_sess_id);
2838   VAL_SDP_INIT (renego_fingerprint, sdp_media_equal_fingerprint, NULL,
2839       &renego_sess_ver);
2840   GObject *channel;
2841   GstHarness *h;
2842
2843   /* negotiate an AV stream and then renegotiate a data channel */
2844   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
2845   add_fake_audio_src_harness (h, 96);
2846   t->harnesses = g_list_prepend (t->harnesses, h);
2847
2848   test_validate_sdp (t, &offer, &answer);
2849
2850   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
2851       &channel);
2852
2853   media_formats.next = &renego_fingerprint;
2854   count.user_data = GUINT_TO_POINTER (3);
2855
2856   /* renegotiate! */
2857   test_webrtc_reset_negotiation (t);
2858   test_validate_sdp (t, &offer, &answer);
2859
2860   g_object_unref (channel);
2861   test_webrtc_free (t);
2862 }
2863
2864 GST_END_TEST;
2865
2866 GST_START_TEST (test_renego_data_channel_add_stream)
2867 {
2868   struct test_webrtc *t = test_webrtc_new ();
2869   guint media_format_count[] = { 1, 1, 1 };
2870   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2871       media_format_count, NULL);
2872   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (1),
2873       &media_formats);
2874   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
2875   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
2876   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2877       &payloads);
2878   const gchar *expected_answer_setup[] = { "active", "active" };
2879   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
2880       &payloads);
2881   const gchar *expected_offer_direction[] = { NULL, "sendrecv" };
2882   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
2883       &offer_setup);
2884   const gchar *expected_answer_direction[] = { NULL, "recvonly" };
2885   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
2886       &answer_setup);
2887   VAL_SDP_INIT (renego_mid, sdp_media_equal_mid, NULL, NULL);
2888   VAL_SDP_INIT (renego_ice_params, sdp_media_equal_ice_params, NULL,
2889       &renego_mid);
2890   VAL_SDP_INIT (renego_sess_id, sdp_equal_session_id, NULL, &renego_ice_params);
2891   VAL_SDP_INIT (renego_sess_ver, sdp_increasing_session_version, NULL,
2892       &renego_sess_id);
2893   VAL_SDP_INIT (renego_fingerprint, sdp_media_equal_fingerprint, NULL,
2894       &renego_sess_ver);
2895   GObject *channel;
2896   GstHarness *h;
2897
2898   /* negotiate an data channel and then renegotiate to add a av stream */
2899   t->on_negotiation_needed = NULL;
2900   t->on_ice_candidate = NULL;
2901   t->on_pad_added = _pad_added_fakesink;
2902
2903   fail_if (gst_element_set_state (t->webrtc1,
2904           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2905   fail_if (gst_element_set_state (t->webrtc2,
2906           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2907
2908   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
2909       &channel);
2910
2911   test_validate_sdp_full (t, &offer, &answer, 0, FALSE);
2912
2913   h = gst_harness_new_with_element (t->webrtc1, "sink_1", NULL);
2914   add_fake_audio_src_harness (h, 97);
2915   t->harnesses = g_list_prepend (t->harnesses, h);
2916
2917   media_formats.next = &renego_fingerprint;
2918   count.user_data = GUINT_TO_POINTER (2);
2919
2920   /* renegotiate! */
2921   test_webrtc_reset_negotiation (t);
2922   test_validate_sdp_full (t, &offer, &answer, 0, FALSE);
2923
2924   g_object_unref (channel);
2925   test_webrtc_free (t);
2926 }
2927
2928 GST_END_TEST;
2929
2930
2931 GST_START_TEST (test_renego_stream_data_channel_add_stream)
2932 {
2933   struct test_webrtc *t = test_webrtc_new ();
2934   guint media_format_count[] = { 1, 1, 1 };
2935   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
2936       media_format_count, NULL);
2937   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
2938       &media_formats);
2939   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
2940   const gchar *expected_offer_setup[] = { "actpass", "actpass", "actpass" };
2941   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
2942       &payloads);
2943   const gchar *expected_answer_setup[] = { "active", "active", "active" };
2944   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
2945       &payloads);
2946   const gchar *expected_offer_direction[] = { "sendrecv", NULL, "sendrecv" };
2947   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
2948       &offer_setup);
2949   const gchar *expected_answer_direction[] = { "recvonly", NULL, "recvonly" };
2950   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
2951       &answer_setup);
2952   VAL_SDP_INIT (renego_mid, sdp_media_equal_mid, NULL, NULL);
2953   VAL_SDP_INIT (renego_ice_params, sdp_media_equal_ice_params, NULL,
2954       &renego_mid);
2955   VAL_SDP_INIT (renego_sess_id, sdp_equal_session_id, NULL, &renego_ice_params);
2956   VAL_SDP_INIT (renego_sess_ver, sdp_increasing_session_version, NULL,
2957       &renego_sess_id);
2958   VAL_SDP_INIT (renego_fingerprint, sdp_media_equal_fingerprint, NULL,
2959       &renego_sess_ver);
2960   GObject *channel;
2961   GstHarness *h;
2962
2963   /* Negotiate a stream and a data channel, then renogotiate with a new stream */
2964   t->on_negotiation_needed = NULL;
2965   t->on_ice_candidate = NULL;
2966   t->on_pad_added = _pad_added_fakesink;
2967
2968   h = gst_harness_new_with_element (t->webrtc1, "sink_0", NULL);
2969   add_fake_audio_src_harness (h, 97);
2970   t->harnesses = g_list_prepend (t->harnesses, h);
2971
2972   fail_if (gst_element_set_state (t->webrtc1,
2973           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2974   fail_if (gst_element_set_state (t->webrtc2,
2975           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
2976
2977   g_signal_emit_by_name (t->webrtc1, "create-data-channel", "label", NULL,
2978       &channel);
2979
2980   test_validate_sdp_full (t, &offer, &answer, 0, FALSE);
2981
2982   h = gst_harness_new_with_element (t->webrtc1, "sink_2", NULL);
2983   add_fake_audio_src_harness (h, 97);
2984   t->harnesses = g_list_prepend (t->harnesses, h);
2985
2986   media_formats.next = &renego_fingerprint;
2987   count.user_data = GUINT_TO_POINTER (3);
2988
2989   /* renegotiate! */
2990   test_webrtc_reset_negotiation (t);
2991   test_validate_sdp_full (t, &offer, &answer, 0, FALSE);
2992
2993   g_object_unref (channel);
2994   test_webrtc_free (t);
2995 }
2996
2997 GST_END_TEST;
2998
2999 GST_START_TEST (test_bundle_renego_add_stream)
3000 {
3001   struct test_webrtc *t = create_audio_video_test ();
3002   const gchar *bundle[] = { "audio0", "video1", "audio2", NULL };
3003   const gchar *offer_bundle_only[] = { "video1", "audio2", NULL };
3004   const gchar *answer_bundle_only[] = { NULL };
3005   guint media_format_count[] = { 1, 1, 1 };
3006   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
3007       media_format_count, NULL);
3008   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
3009       &media_formats);
3010   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
3011   const gchar *expected_offer_setup[] = { "actpass", "actpass", "actpass" };
3012   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
3013       &payloads);
3014   const gchar *expected_answer_setup[] = { "active", "active", "active" };
3015   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
3016       &payloads);
3017   const gchar *expected_offer_direction[] =
3018       { "sendrecv", "sendrecv", "sendrecv" };
3019   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
3020       &offer_setup);
3021   const gchar *expected_answer_direction[] =
3022       { "sendrecv", "recvonly", "recvonly" };
3023   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
3024       &answer_setup);
3025
3026   VAL_SDP_INIT (renego_mid, sdp_media_equal_mid, NULL, &payloads);
3027   VAL_SDP_INIT (renego_ice_params, sdp_media_equal_ice_params, NULL,
3028       &renego_mid);
3029   VAL_SDP_INIT (renego_sess_id, sdp_equal_session_id, NULL, &renego_ice_params);
3030   VAL_SDP_INIT (renego_sess_ver, sdp_increasing_session_version, NULL,
3031       &renego_sess_id);
3032   VAL_SDP_INIT (renego_fingerprint, sdp_media_equal_fingerprint, NULL,
3033       &renego_sess_ver);
3034   VAL_SDP_INIT (bundle_tag, _check_bundle_tag, bundle, &renego_fingerprint);
3035   VAL_SDP_INIT (offer_non_reject, _count_non_rejected_media,
3036       GUINT_TO_POINTER (1), &bundle_tag);
3037   VAL_SDP_INIT (answer_non_reject, _count_non_rejected_media,
3038       GUINT_TO_POINTER (3), &bundle_tag);
3039   VAL_SDP_INIT (offer_bundle_only_sdp, _check_bundle_only_media,
3040       &offer_bundle_only, &offer_non_reject);
3041   VAL_SDP_INIT (answer_bundle_only_sdp, _check_bundle_only_media,
3042       &answer_bundle_only, &answer_non_reject);
3043   GstHarness *h;
3044
3045   /* We set a max-bundle policy on the offering webrtcbin,
3046    * this means that all the offered medias should be part
3047    * of the group:BUNDLE attribute, and they should be marked
3048    * as bundle-only
3049    */
3050   gst_util_set_object_arg (G_OBJECT (t->webrtc1), "bundle-policy",
3051       "max-bundle");
3052   /* We also set a max-bundle policy on the answering webrtcbin,
3053    * this means that all the offered medias should be part
3054    * of the group:BUNDLE attribute, but need not be marked
3055    * as bundle-only.
3056    */
3057   gst_util_set_object_arg (G_OBJECT (t->webrtc2), "bundle-policy",
3058       "max-bundle");
3059
3060   /* negotiate an AV stream and then renegotiate an extra stream */
3061   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
3062   add_fake_audio_src_harness (h, 96);
3063   t->harnesses = g_list_prepend (t->harnesses, h);
3064
3065   test_validate_sdp (t, &offer, &answer);
3066
3067   h = gst_harness_new_with_element (t->webrtc1, "sink_2", NULL);
3068   add_fake_audio_src_harness (h, 98);
3069   t->harnesses = g_list_prepend (t->harnesses, h);
3070
3071   offer_setup.next = &offer_bundle_only_sdp;
3072   answer_setup.next = &answer_bundle_only_sdp;
3073   count.user_data = GUINT_TO_POINTER (3);
3074
3075   /* renegotiate! */
3076   test_webrtc_reset_negotiation (t);
3077   test_validate_sdp (t, &offer, &answer);
3078
3079   test_webrtc_free (t);
3080 }
3081
3082 GST_END_TEST;
3083
3084 GST_START_TEST (test_bundle_max_compat_max_bundle_renego_add_stream)
3085 {
3086   struct test_webrtc *t = create_audio_video_test ();
3087   const gchar *bundle[] = { "audio0", "video1", "audio2", NULL };
3088   const gchar *bundle_only[] = { NULL };
3089   guint media_format_count[] = { 1, 1, 1 };
3090   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
3091       media_format_count, NULL);
3092   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
3093       &media_formats);
3094   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
3095   const gchar *expected_offer_setup[] = { "actpass", "actpass", "actpass" };
3096   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
3097       &payloads);
3098   const gchar *expected_answer_setup[] = { "active", "active", "active" };
3099   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
3100       &payloads);
3101   const gchar *expected_offer_direction[] =
3102       { "sendrecv", "sendrecv", "sendrecv" };
3103   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
3104       &offer_setup);
3105   const gchar *expected_answer_direction[] =
3106       { "sendrecv", "recvonly", "recvonly" };
3107   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
3108       &answer_setup);
3109
3110   VAL_SDP_INIT (renego_mid, sdp_media_equal_mid, NULL, NULL);
3111   VAL_SDP_INIT (renego_ice_params, sdp_media_equal_ice_params, NULL,
3112       &renego_mid);
3113   VAL_SDP_INIT (renego_sess_id, sdp_equal_session_id, NULL, &renego_ice_params);
3114   VAL_SDP_INIT (renego_sess_ver, sdp_increasing_session_version, NULL,
3115       &renego_sess_id);
3116   VAL_SDP_INIT (renego_fingerprint, sdp_media_equal_fingerprint, NULL,
3117       &renego_sess_ver);
3118   VAL_SDP_INIT (bundle_tag, _check_bundle_tag, bundle, &renego_fingerprint);
3119   VAL_SDP_INIT (count_non_reject, _count_non_rejected_media,
3120       GUINT_TO_POINTER (3), &bundle_tag);
3121   VAL_SDP_INIT (bundle_sdp, _check_bundle_only_media, &bundle_only,
3122       &count_non_reject);
3123   GstHarness *h;
3124
3125   /* We set a max-compat policy on the offering webrtcbin,
3126    * this means that all the offered medias should be part
3127    * of the group:BUNDLE attribute, and they should *not* be marked
3128    * as bundle-only
3129    */
3130   gst_util_set_object_arg (G_OBJECT (t->webrtc1), "bundle-policy",
3131       "max-compat");
3132   /* We set a max-bundle policy on the answering webrtcbin,
3133    * this means that all the offered medias should be part
3134    * of the group:BUNDLE attribute, but need not be marked
3135    * as bundle-only.
3136    */
3137   gst_util_set_object_arg (G_OBJECT (t->webrtc2), "bundle-policy",
3138       "max-bundle");
3139
3140   /* negotiate an AV stream and then renegotiate an extra stream */
3141   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
3142   add_fake_audio_src_harness (h, 96);
3143   t->harnesses = g_list_prepend (t->harnesses, h);
3144
3145   test_validate_sdp (t, &offer, &answer);
3146
3147   h = gst_harness_new_with_element (t->webrtc1, "sink_2", NULL);
3148   add_fake_audio_src_harness (h, 98);
3149   t->harnesses = g_list_prepend (t->harnesses, h);
3150
3151   media_formats.next = &bundle_sdp;
3152   count.user_data = GUINT_TO_POINTER (3);
3153
3154   /* renegotiate! */
3155   test_webrtc_reset_negotiation (t);
3156   test_validate_sdp (t, &offer, &answer);
3157
3158   test_webrtc_free (t);
3159 }
3160
3161 GST_END_TEST;
3162
3163 GST_START_TEST (test_renego_transceiver_set_direction)
3164 {
3165   struct test_webrtc *t = create_audio_test ();
3166   guint media_format_count[] = { 1, };
3167   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
3168       media_format_count, NULL);
3169   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (1),
3170       &media_formats);
3171   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
3172   const gchar *expected_offer_setup[] = { "actpass", };
3173   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
3174       &payloads);
3175   const gchar *expected_answer_setup[] = { "active", };
3176   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
3177       &payloads);
3178   const gchar *expected_offer_direction[] = { "sendrecv", };
3179   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
3180       &offer_setup);
3181   const gchar *expected_answer_direction[] = { "sendrecv", };
3182   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
3183       &answer_setup);
3184   GstWebRTCRTPTransceiver *transceiver;
3185   GstHarness *h;
3186   GstPad *pad;
3187
3188   /* negotiate an AV stream and then change the transceiver direction */
3189   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
3190   add_fake_audio_src_harness (h, 96);
3191   t->harnesses = g_list_prepend (t->harnesses, h);
3192
3193   test_validate_sdp (t, &offer, &answer);
3194
3195   /* renegotiate an inactive transceiver! */
3196   pad = gst_element_get_static_pad (t->webrtc1, "sink_0");
3197   g_object_get (pad, "transceiver", &transceiver, NULL);
3198   fail_unless (transceiver != NULL);
3199   g_object_set (transceiver, "direction",
3200       GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_INACTIVE, NULL);
3201   expected_offer_direction[0] = "inactive";
3202   expected_answer_direction[0] = "inactive";
3203
3204   /* TODO: also validate EOS events from the inactive change */
3205
3206   test_webrtc_reset_negotiation (t);
3207   test_validate_sdp (t, &offer, &answer);
3208
3209   gst_object_unref (pad);
3210   gst_object_unref (transceiver);
3211   test_webrtc_free (t);
3212 }
3213
3214 GST_END_TEST;
3215
3216 static void
3217 offer_remove_last_media (struct test_webrtc *t, GstElement * element,
3218     GstPromise * promise, gpointer user_data)
3219 {
3220   guint i, n;
3221   GstSDPMessage *new, *old;
3222   const GstSDPOrigin *origin;
3223   const GstSDPConnection *conn;
3224
3225   old = t->offer_desc->sdp;
3226   fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_new (&new));
3227
3228   origin = gst_sdp_message_get_origin (old);
3229   conn = gst_sdp_message_get_connection (old);
3230   fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_set_version (new,
3231           gst_sdp_message_get_version (old)));
3232   fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_set_origin (new,
3233           origin->username, origin->sess_id, origin->sess_version,
3234           origin->nettype, origin->addrtype, origin->addr));
3235   fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_set_session_name (new,
3236           gst_sdp_message_get_session_name (old)));
3237   fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_set_information (new,
3238           gst_sdp_message_get_information (old)));
3239   fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_set_uri (new,
3240           gst_sdp_message_get_uri (old)));
3241   fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_set_connection (new,
3242           conn->nettype, conn->addrtype, conn->address, conn->ttl,
3243           conn->addr_number));
3244
3245   n = gst_sdp_message_attributes_len (old);
3246   for (i = 0; i < n; i++) {
3247     const GstSDPAttribute *a = gst_sdp_message_get_attribute (old, i);
3248     fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_add_attribute (new,
3249             a->key, a->value));
3250   }
3251
3252   n = gst_sdp_message_medias_len (old);
3253   fail_unless (n > 0);
3254   for (i = 0; i < n - 1; i++) {
3255     const GstSDPMedia *m = gst_sdp_message_get_media (old, i);
3256     GstSDPMedia *new_m;
3257
3258     fail_unless_equals_int (GST_SDP_OK, gst_sdp_media_copy (m, &new_m));
3259     fail_unless_equals_int (GST_SDP_OK, gst_sdp_message_add_media (new, new_m));
3260     gst_sdp_media_init (new_m);
3261     gst_sdp_media_free (new_m);
3262   }
3263
3264   gst_webrtc_session_description_free (t->offer_desc);
3265   t->offer_desc = gst_webrtc_session_description_new (GST_WEBRTC_SDP_TYPE_OFFER,
3266       new);
3267 }
3268
3269 static void
3270 offer_set_produced_error (struct test_webrtc *t, GstElement * element,
3271     GstPromise * promise, gpointer user_data)
3272 {
3273   const GstStructure *reply;
3274   GError *error = NULL;
3275
3276   reply = gst_promise_get_reply (promise);
3277   fail_unless (gst_structure_get (reply, "error", G_TYPE_ERROR, &error, NULL));
3278   GST_INFO ("error produced: %s", error->message);
3279   g_clear_error (&error);
3280
3281   test_webrtc_signal_state_unlocked (t, STATE_CUSTOM);
3282 }
3283
3284 GST_START_TEST (test_renego_lose_media_fails)
3285 {
3286   struct test_webrtc *t = create_audio_video_test ();
3287   VAL_SDP_INIT (offer, _count_num_sdp_media, GUINT_TO_POINTER (2), NULL);
3288   VAL_SDP_INIT (answer, _count_num_sdp_media, GUINT_TO_POINTER (2), NULL);
3289
3290   /* check that removing an m=line will produce an error */
3291
3292   test_validate_sdp (t, &offer, &answer);
3293
3294   test_webrtc_reset_negotiation (t);
3295
3296   t->on_offer_created = offer_remove_last_media;
3297   t->on_offer_set = offer_set_produced_error;
3298   t->on_answer_created = NULL;
3299
3300   test_webrtc_create_offer (t, t->webrtc1);
3301   test_webrtc_wait_for_state_mask (t, 1 << STATE_CUSTOM);
3302
3303   test_webrtc_free (t);
3304 }
3305
3306 GST_END_TEST;
3307
3308 GST_START_TEST (test_bundle_codec_preferences_rtx_no_duplicate_payloads)
3309 {
3310   struct test_webrtc *t = test_webrtc_new ();
3311   GstWebRTCRTPTransceiverDirection direction;
3312   GstWebRTCRTPTransceiver *trans;
3313   guint offer_media_format_count[] = { 2, };
3314   guint answer_media_format_count[] = { 1, };
3315   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, NULL);
3316   VAL_SDP_INIT (offer_media_formats, on_sdp_media_count_formats,
3317       offer_media_format_count, &payloads);
3318   VAL_SDP_INIT (answer_media_formats, on_sdp_media_count_formats,
3319       answer_media_format_count, &payloads);
3320   const gchar *expected_offer_setup[] = { "actpass", };
3321   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
3322       &offer_media_formats);
3323   const gchar *expected_answer_setup[] = { "active", };
3324   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
3325       &answer_media_formats);
3326   const gchar *expected_offer_direction[] = { "recvonly", };
3327   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
3328       &offer_setup);
3329   const gchar *expected_answer_direction[] = { "sendonly", };
3330   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
3331       &answer_setup);
3332   GstCaps *caps;
3333   GstHarness *h;
3334
3335   /* add a transceiver that will only receive an opus stream and check that
3336    * the created offer is marked as recvonly */
3337   t->on_negotiation_needed = NULL;
3338   t->on_ice_candidate = NULL;
3339   t->on_pad_added = _pad_added_fakesink;
3340
3341   gst_util_set_object_arg (G_OBJECT (t->webrtc1), "bundle-policy",
3342       "max-bundle");
3343   gst_util_set_object_arg (G_OBJECT (t->webrtc2), "bundle-policy",
3344       "max-bundle");
3345
3346   /* setup recvonly transceiver */
3347   caps = gst_caps_from_string (VP8_RTP_CAPS (96));
3348   direction = GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY;
3349   g_signal_emit_by_name (t->webrtc1, "add-transceiver", direction, caps,
3350       &trans);
3351   g_object_set (GST_OBJECT (trans), "do-nack", TRUE, NULL);
3352   gst_caps_unref (caps);
3353   fail_unless (trans != NULL);
3354   gst_object_unref (trans);
3355
3356   /* setup sendonly peer */
3357   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
3358   add_fake_video_src_harness (h, 96);
3359   t->harnesses = g_list_prepend (t->harnesses, h);
3360   test_validate_sdp (t, &offer, &answer);
3361
3362   test_webrtc_free (t);
3363 }
3364
3365 GST_END_TEST;
3366
3367 GST_START_TEST (test_reject_request_pad)
3368 {
3369   struct test_webrtc *t = test_webrtc_new ();
3370   GstWebRTCRTPTransceiverDirection direction;
3371   GstWebRTCRTPTransceiver *trans, *trans2;
3372   guint offer_media_format_count[] = { 1, };
3373   guint answer_media_format_count[] = { 1, };
3374   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, NULL);
3375   VAL_SDP_INIT (offer_media_formats, on_sdp_media_count_formats,
3376       offer_media_format_count, &payloads);
3377   VAL_SDP_INIT (answer_media_formats, on_sdp_media_count_formats,
3378       answer_media_format_count, &payloads);
3379   const gchar *expected_offer_setup[] = { "actpass", };
3380   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
3381       &offer_media_formats);
3382   const gchar *expected_answer_setup[] = { "active", };
3383   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
3384       &answer_media_formats);
3385   const gchar *expected_offer_direction[] = { "recvonly", };
3386   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
3387       &offer_setup);
3388   const gchar *expected_answer_direction[] = { "sendonly", };
3389   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
3390       &answer_setup);
3391   GstCaps *caps;
3392   GstHarness *h;
3393   GstPad *pad;
3394   GstPadTemplate *templ;
3395
3396   t->on_negotiation_needed = NULL;
3397   t->on_ice_candidate = NULL;
3398   t->on_pad_added = _pad_added_fakesink;
3399
3400   gst_util_set_object_arg (G_OBJECT (t->webrtc1), "bundle-policy",
3401       "max-bundle");
3402   gst_util_set_object_arg (G_OBJECT (t->webrtc2), "bundle-policy",
3403       "max-bundle");
3404
3405   /* setup recvonly transceiver */
3406   caps = gst_caps_from_string (VP8_RTP_CAPS (96));
3407   direction = GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY;
3408   g_signal_emit_by_name (t->webrtc1, "add-transceiver", direction, caps,
3409       &trans);
3410   gst_caps_unref (caps);
3411   fail_unless (trans != NULL);
3412
3413   h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL);
3414   add_fake_video_src_harness (h, 96);
3415   t->harnesses = g_list_prepend (t->harnesses, h);
3416
3417   test_validate_sdp (t, &offer, &answer);
3418
3419   /* This should fail because the direction is wrong */
3420   pad = gst_element_get_request_pad (t->webrtc1, "sink_0");
3421   fail_unless (pad == NULL);
3422
3423   g_object_set (trans, "direction",
3424       GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDRECV, NULL);
3425
3426   templ = gst_element_get_pad_template (t->webrtc1, "sink_%u");
3427   fail_unless (templ != NULL);
3428
3429   /* This should fail because the caps are wrong */
3430   caps = gst_caps_from_string (OPUS_RTP_CAPS (96));
3431   pad = gst_element_request_pad (t->webrtc1, templ, "sink_0", caps);
3432   fail_unless (pad == NULL);
3433
3434   gst_caps_unref (trans->codec_preferences);
3435   trans->codec_preferences = NULL;
3436
3437   /* This should fail because the kind doesn't match */
3438   pad = gst_element_request_pad (t->webrtc1, templ, "sink_0", caps);
3439   fail_unless (pad == NULL);
3440   gst_caps_unref (caps);
3441
3442   /* This should succeed and give us sink_0 */
3443   pad = gst_element_get_request_pad (t->webrtc1, "sink_0");
3444   fail_unless (pad != NULL);
3445
3446   g_object_get (pad, "transceiver", &trans2, NULL);
3447
3448   fail_unless (trans == trans2);
3449
3450   gst_object_unref (pad);
3451   gst_object_unref (trans);
3452   gst_object_unref (trans2);
3453
3454   test_webrtc_free (t);
3455 }
3456
3457 GST_END_TEST;
3458
3459 static void
3460 _verify_media_types (struct test_webrtc *t, GstElement * element,
3461     GstWebRTCSessionDescription * desc, gpointer user_data)
3462 {
3463   gchar **media_types = user_data;
3464   int i;
3465
3466   for (i = 0; i < gst_sdp_message_medias_len (desc->sdp); i++) {
3467     const GstSDPMedia *media = gst_sdp_message_get_media (desc->sdp, i);
3468
3469     fail_unless_equals_string (gst_sdp_media_get_media (media), media_types[i]);
3470   }
3471 }
3472
3473 GST_START_TEST (test_reject_create_offer)
3474 {
3475   struct test_webrtc *t = test_webrtc_new ();
3476   GstHarness *h;
3477   GstPromise *promise;
3478   GstPromiseResult res;
3479   const GstStructure *s;
3480   GError *error = NULL;
3481
3482   const gchar *media_types[] = { "video", "audio" };
3483   VAL_SDP_INIT (media_type, _verify_media_types, &media_types, NULL);
3484   guint media_format_count[] = { 1, 1 };
3485   VAL_SDP_INIT (media_formats, on_sdp_media_count_formats,
3486       media_format_count, &media_type);
3487   VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (2),
3488       &media_formats);
3489   VAL_SDP_INIT (payloads, on_sdp_media_no_duplicate_payloads, NULL, &count);
3490   const gchar *expected_offer_setup[] = { "actpass", "actpass" };
3491   VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup,
3492       &payloads);
3493   const gchar *expected_answer_setup[] = { "active", "active" };
3494   VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup,
3495       &payloads);
3496   const gchar *expected_offer_direction[] = { "sendrecv", "sendrecv" };
3497   VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction,
3498       &offer_setup);
3499   const gchar *expected_answer_direction[] = { "recvonly", "recvonly" };
3500   VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction,
3501       &answer_setup);
3502
3503   t->on_negotiation_needed = NULL;
3504   t->on_ice_candidate = NULL;
3505   t->on_pad_added = _pad_added_fakesink;
3506
3507   /* setup sendonly peer */
3508   h = gst_harness_new_with_element (t->webrtc1, "sink_1", NULL);
3509   add_fake_audio_src_harness (h, 96);
3510   t->harnesses = g_list_prepend (t->harnesses, h);
3511
3512   /* Check that if there is no 0, we can't create an offer with a hole */
3513   promise = gst_promise_new ();
3514   g_signal_emit_by_name (t->webrtc1, "create-offer", NULL, promise);
3515   res = gst_promise_wait (promise);
3516   fail_unless_equals_int (res, GST_PROMISE_RESULT_REPLIED);
3517   s = gst_promise_get_reply (promise);
3518   fail_unless (s != NULL);
3519   fail_unless (gst_structure_has_name (s, "application/x-gstwebrtcbin-error"));
3520   gst_structure_get (s, "error", G_TYPE_ERROR, &error, NULL);
3521   fail_unless (g_error_matches (error, GST_WEBRTC_BIN_ERROR,
3522           GST_WEBRTC_BIN_ERROR_IMPOSSIBLE_MLINE_RESTRICTION));
3523   g_clear_error (&error);
3524   gst_promise_unref (promise);
3525
3526   h = gst_harness_new_with_element (t->webrtc1, "sink_%u", NULL);
3527   add_fake_video_src_harness (h, 97);
3528   t->harnesses = g_list_prepend (t->harnesses, h);
3529
3530   /* Adding a second sink, which will fill m-line 0, should fix it */
3531   test_validate_sdp (t, &offer, &answer);
3532
3533   test_webrtc_free (t);
3534 }
3535
3536 GST_END_TEST;
3537
3538 GST_START_TEST (test_reject_set_description)
3539 {
3540   struct test_webrtc *t = test_webrtc_new ();
3541   GstHarness *h;
3542   GstPromise *promise;
3543   GstPromiseResult res;
3544   const GstStructure *s;
3545   GError *error = NULL;
3546   GstWebRTCSessionDescription *desc = NULL;
3547   GstPadTemplate *templ;
3548   GstCaps *caps;
3549   GstPad *pad;
3550
3551   t->on_negotiation_needed = NULL;
3552   t->on_ice_candidate = NULL;
3553   t->on_pad_added = _pad_added_fakesink;
3554
3555   /* setup peer 1 */
3556   h = gst_harness_new_with_element (t->webrtc1, "sink_0", NULL);
3557   add_fake_audio_src_harness (h, 96);
3558   t->harnesses = g_list_prepend (t->harnesses, h);
3559
3560   /* Create a second side with specific video caps */
3561   templ = gst_element_get_pad_template (t->webrtc2, "sink_%u");
3562   fail_unless (templ != NULL);
3563   caps = gst_caps_from_string (VP8_RTP_CAPS (97));
3564   pad = gst_element_request_pad (t->webrtc2, templ, "sink_0", caps);
3565   fail_unless (pad != NULL);
3566   gst_caps_unref (caps);
3567   gst_object_unref (pad);
3568
3569   /* Create an offer */
3570   promise = gst_promise_new ();
3571   g_signal_emit_by_name (t->webrtc1, "create-offer", NULL, promise);
3572   res = gst_promise_wait (promise);
3573   fail_unless_equals_int (res, GST_PROMISE_RESULT_REPLIED);
3574   s = gst_promise_get_reply (promise);
3575   fail_unless (s != NULL);
3576   fail_unless (gst_structure_has_name (s, "application/x-gst-promise"));
3577   gst_structure_get (s, "offer", GST_TYPE_WEBRTC_SESSION_DESCRIPTION, &desc,
3578       NULL);
3579   fail_unless (desc != NULL);
3580   gst_promise_unref (promise);
3581
3582   fail_if (gst_element_set_state (t->webrtc2,
3583           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
3584
3585   /* Verify that setting an offer where there is a forced m-line with
3586      a different kind fails. */
3587   promise = gst_promise_new ();
3588   g_signal_emit_by_name (t->webrtc2, "set-remote-description", desc, promise);
3589   res = gst_promise_wait (promise);
3590   fail_unless_equals_int (res, GST_PROMISE_RESULT_REPLIED);
3591   s = gst_promise_get_reply (promise);
3592   fail_unless (gst_structure_has_name (s, "application/x-gstwebrtcbin-error"));
3593   gst_structure_get (s, "error", G_TYPE_ERROR, &error, NULL);
3594   fail_unless (g_error_matches (error, GST_WEBRTC_BIN_ERROR,
3595           GST_WEBRTC_BIN_ERROR_IMPOSSIBLE_MLINE_RESTRICTION));
3596   g_clear_error (&error);
3597   fail_unless (s != NULL);
3598   gst_promise_unref (promise);
3599   gst_webrtc_session_description_free (desc);
3600
3601   test_webrtc_free (t);
3602 }
3603
3604 GST_END_TEST;
3605
3606 static Suite *
3607 webrtcbin_suite (void)
3608 {
3609   Suite *s = suite_create ("webrtcbin");
3610   TCase *tc = tcase_create ("general");
3611   GstPluginFeature *nicesrc, *nicesink, *dtlssrtpdec, *dtlssrtpenc;
3612   GstPluginFeature *sctpenc, *sctpdec;
3613   GstRegistry *registry;
3614
3615   registry = gst_registry_get ();
3616   nicesrc = gst_registry_lookup_feature (registry, "nicesrc");
3617   nicesink = gst_registry_lookup_feature (registry, "nicesink");
3618   dtlssrtpenc = gst_registry_lookup_feature (registry, "dtlssrtpenc");
3619   dtlssrtpdec = gst_registry_lookup_feature (registry, "dtlssrtpdec");
3620   sctpenc = gst_registry_lookup_feature (registry, "sctpenc");
3621   sctpdec = gst_registry_lookup_feature (registry, "sctpdec");
3622
3623   tcase_add_test (tc, test_no_nice_elements_request_pad);
3624   tcase_add_test (tc, test_no_nice_elements_state_change);
3625   if (nicesrc && nicesink && dtlssrtpenc && dtlssrtpdec) {
3626     tcase_add_test (tc, test_sdp_no_media);
3627     tcase_add_test (tc, test_session_stats);
3628     tcase_add_test (tc, test_audio);
3629     tcase_add_test (tc, test_ice_port_restriction);
3630     tcase_add_test (tc, test_audio_video);
3631     tcase_add_test (tc, test_media_direction);
3632     tcase_add_test (tc, test_add_transceiver);
3633     tcase_add_test (tc, test_get_transceivers);
3634     tcase_add_test (tc, test_add_recvonly_transceiver);
3635     tcase_add_test (tc, test_recvonly_sendonly);
3636     tcase_add_test (tc, test_payload_types);
3637     tcase_add_test (tc, test_bundle_audio_video_max_bundle_max_bundle);
3638     tcase_add_test (tc, test_bundle_audio_video_max_bundle_none);
3639     tcase_add_test (tc, test_bundle_audio_video_max_compat_max_bundle);
3640     tcase_add_test (tc, test_dual_audio);
3641     tcase_add_test (tc, test_duplicate_nego);
3642     tcase_add_test (tc, test_renego_add_stream);
3643     tcase_add_test (tc, test_bundle_renego_add_stream);
3644     tcase_add_test (tc, test_bundle_max_compat_max_bundle_renego_add_stream);
3645     tcase_add_test (tc, test_renego_transceiver_set_direction);
3646     tcase_add_test (tc, test_renego_lose_media_fails);
3647     tcase_add_test (tc,
3648         test_bundle_codec_preferences_rtx_no_duplicate_payloads);
3649     tcase_add_test (tc, test_reject_request_pad);
3650     tcase_add_test (tc, test_reject_create_offer);
3651     tcase_add_test (tc, test_reject_set_description);
3652     if (sctpenc && sctpdec) {
3653       tcase_add_test (tc, test_data_channel_create);
3654       tcase_add_test (tc, test_data_channel_remote_notify);
3655       tcase_add_test (tc, test_data_channel_transfer_string);
3656       tcase_add_test (tc, test_data_channel_transfer_data);
3657       tcase_add_test (tc, test_data_channel_create_after_negotiate);
3658       tcase_add_test (tc, test_data_channel_low_threshold);
3659       tcase_add_test (tc, test_data_channel_max_message_size);
3660       tcase_add_test (tc, test_data_channel_pre_negotiated);
3661       tcase_add_test (tc, test_bundle_audio_video_data);
3662       tcase_add_test (tc, test_renego_stream_add_data_channel);
3663       tcase_add_test (tc, test_renego_data_channel_add_stream);
3664       tcase_add_test (tc, test_renego_stream_data_channel_add_stream);
3665     } else {
3666       GST_WARNING ("Some required elements were not found. "
3667           "All datachannel tests are disabled. sctpenc %p, sctpdec %p", sctpenc,
3668           sctpdec);
3669     }
3670   } else {
3671     GST_WARNING ("Some required elements were not found. "
3672         "All media tests are disabled. nicesrc %p, nicesink %p, "
3673         "dtlssrtpenc %p, dtlssrtpdec %p", nicesrc, nicesink, dtlssrtpenc,
3674         dtlssrtpdec);
3675   }
3676
3677   if (nicesrc)
3678     gst_object_unref (nicesrc);
3679   if (nicesink)
3680     gst_object_unref (nicesink);
3681   if (dtlssrtpdec)
3682     gst_object_unref (dtlssrtpdec);
3683   if (dtlssrtpenc)
3684     gst_object_unref (dtlssrtpenc);
3685   if (sctpenc)
3686     gst_object_unref (sctpenc);
3687   if (sctpdec)
3688     gst_object_unref (sctpdec);
3689
3690   suite_add_tcase (s, tc);
3691
3692   return s;
3693 }
3694
3695 GST_CHECK_MAIN (webrtcbin);