webrtc: Fix documentaton moving symbols in the right pages
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-bad / gst-libs / gst / webrtc / ice.c
1 /* GStreamer
2  * Copyright (C) 2017 Matthew Waters <matthew@centricular.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 /**
20  * SECTION:gstwebrtcice
21  * @title: GstWebRTCICE
22  * @short_description: Base class WebRTC ICE handling
23  * @symbols:
24  * - GstWebRTCICE
25  */
26
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include "ice.h"
32 #include "icestream.h"
33
34 #include "webrtc-priv.h"
35
36 #define GST_CAT_DEFAULT gst_webrtc_ice_debug
37 GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
38
39 enum
40 {
41   SIGNAL_0,
42   ADD_LOCAL_IP_ADDRESS_SIGNAL,
43   LAST_SIGNAL,
44 };
45
46 enum
47 {
48   PROP_0,
49   PROP_MIN_RTP_PORT,
50   PROP_MAX_RTP_PORT,
51 };
52
53 static guint gst_webrtc_ice_signals[LAST_SIGNAL] = { 0 };
54
55 #define gst_webrtc_ice_parent_class parent_class
56 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstWebRTCICE, gst_webrtc_ice,
57     GST_TYPE_OBJECT, GST_DEBUG_CATEGORY_INIT (gst_webrtc_ice_debug,
58         "webrtcice", 0, "webrtcice"););
59
60 /**
61  * gst_webrtc_ice_add_stream:
62  * @ice: The #GstWebRTCICE
63  * @session_id: The session id
64  *
65  * Returns: (transfer full) (nullable): The #GstWebRTCICEStream, or %NULL
66  * Since: 1.22
67  */
68 GstWebRTCICEStream *
69 gst_webrtc_ice_add_stream (GstWebRTCICE * ice, guint session_id)
70 {
71   g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), NULL);
72   g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->add_stream);
73
74   return GST_WEBRTC_ICE_GET_CLASS (ice)->add_stream (ice, session_id);
75 }
76
77 /**
78  * gst_webrtc_ice_find_transport:
79  * @ice: The #GstWebRTCICE
80  * @stream: The #GstWebRTCICEStream
81  * @component: The #GstWebRTCICEComponent
82  *
83  * Returns: (transfer full) (nullable): The #GstWebRTCICETransport, or %NULL
84  * Since: 1.22
85  */
86 GstWebRTCICETransport *
87 gst_webrtc_ice_find_transport (GstWebRTCICE * ice,
88     GstWebRTCICEStream * stream, GstWebRTCICEComponent component)
89 {
90   g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), NULL);
91   g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->find_transport);
92
93   return GST_WEBRTC_ICE_GET_CLASS (ice)->find_transport (ice, stream,
94       component);
95 }
96
97 /**
98  * gst_webrtc_ice_add_candidate:
99  * @ice: The #GstWebRTCICE
100  * @stream: The #GstWebRTCICEStream
101  * @candidate: The ICE candidate
102  * Since: 1.22
103  */
104 void
105 gst_webrtc_ice_add_candidate (GstWebRTCICE * ice,
106     GstWebRTCICEStream * stream, const gchar * candidate)
107 {
108   g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
109   g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->add_candidate);
110
111   GST_WEBRTC_ICE_GET_CLASS (ice)->add_candidate (ice, stream, candidate);
112 }
113
114 /**
115  * gst_webrtc_ice_set_remote_credentials:
116  * @ice: The #GstWebRTCICE
117  * @stream: The #GstWebRTCICEStream
118  * @ufrag: ICE username
119  * @pwd: ICE password
120  * Returns: FALSE on error, TRUE otherwise
121  * Since: 1.22
122  */
123 gboolean
124 gst_webrtc_ice_set_remote_credentials (GstWebRTCICE * ice,
125     GstWebRTCICEStream * stream, gchar * ufrag, gchar * pwd)
126 {
127   g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), FALSE);
128   g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_remote_credentials);
129
130   return GST_WEBRTC_ICE_GET_CLASS (ice)->set_remote_credentials (ice, stream,
131       ufrag, pwd);
132 }
133
134 /**
135  * gst_webrtc_ice_add_turn_server:
136  * @ice: The #GstWebRTCICE
137  * @uri: URI of the TURN server
138  * Returns: FALSE on error, TRUE otherwise
139  * Since: 1.22
140  */
141 gboolean
142 gst_webrtc_ice_add_turn_server (GstWebRTCICE * ice, const gchar * uri)
143 {
144   g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), FALSE);
145   g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->add_turn_server);
146
147   return GST_WEBRTC_ICE_GET_CLASS (ice)->add_turn_server (ice, uri);
148 }
149
150 /**
151  * gst_webrtc_ice_set_local_credentials:
152  * @ice: The #GstWebRTCICE
153  * @stream: The #GstWebRTCICEStream
154  * @ufrag: ICE username
155  * @pwd: ICE password
156  * Returns: FALSE on error, TRUE otherwise
157  * Since: 1.22
158  */
159 gboolean
160 gst_webrtc_ice_set_local_credentials (GstWebRTCICE * ice,
161     GstWebRTCICEStream * stream, gchar * ufrag, gchar * pwd)
162 {
163   g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), FALSE);
164   g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_local_credentials);
165
166   return GST_WEBRTC_ICE_GET_CLASS (ice)->set_local_credentials (ice, stream,
167       ufrag, pwd);
168 }
169
170 /**
171  * gst_webrtc_ice_gather_candidates:
172  * @ice: The #GstWebRTCICE
173  * @stream: The #GstWebRTCICEStream
174  * Returns: FALSE on error, TRUE otherwise
175  * Since: 1.22
176  */
177 gboolean
178 gst_webrtc_ice_gather_candidates (GstWebRTCICE * ice,
179     GstWebRTCICEStream * stream)
180 {
181   g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), FALSE);
182   g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->gather_candidates);
183
184   return GST_WEBRTC_ICE_GET_CLASS (ice)->gather_candidates (ice, stream);
185 }
186
187 /**
188  * gst_webrtc_ice_set_is_controller:
189  * @ice: The #GstWebRTCICE
190  * @controller: TRUE to set as controller
191  * Since: 1.22
192  */
193 void
194 gst_webrtc_ice_set_is_controller (GstWebRTCICE * ice, gboolean controller)
195 {
196   g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
197   g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_is_controller);
198
199   GST_WEBRTC_ICE_GET_CLASS (ice)->set_is_controller (ice, controller);
200 }
201
202 /**
203  * gst_webrtc_ice_get_is_controller:
204  * @ice: The #GstWebRTCICE
205  * Returns: TRUE if set as controller, FALSE otherwise
206  * Since: 1.22
207  */
208 gboolean
209 gst_webrtc_ice_get_is_controller (GstWebRTCICE * ice)
210 {
211   g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), FALSE);
212   g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->get_is_controller);
213
214   return GST_WEBRTC_ICE_GET_CLASS (ice)->get_is_controller (ice);
215 }
216
217 /**
218  * gst_webrtc_ice_set_force_relay:
219  * @ice: The #GstWebRTCICE
220  * @force_relay: TRUE to enable force relay
221  * Since: 1.22
222  */
223 void
224 gst_webrtc_ice_set_force_relay (GstWebRTCICE * ice, gboolean force_relay)
225 {
226   g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
227   g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_force_relay);
228
229   GST_WEBRTC_ICE_GET_CLASS (ice)->set_force_relay (ice, force_relay);
230 }
231
232 /**
233  * gst_webrtc_ice_set_tos:
234  * @ice: The #GstWebRTCICE
235  * @stream: The #GstWebRTCICEStream
236  * @tos: ToS to be set
237  * Since: 1.22
238  */
239 void
240 gst_webrtc_ice_set_tos (GstWebRTCICE * ice, GstWebRTCICEStream * stream,
241     guint tos)
242 {
243   g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
244   g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_tos);
245
246   GST_WEBRTC_ICE_GET_CLASS (ice)->set_tos (ice, stream, tos);
247 }
248
249
250 /**
251  * gst_webrtc_ice_get_local_candidates:
252  * @ice: The #GstWebRTCICE
253  * @stream: The #GstWebRTCICEStream
254  * Returns: (transfer full)(array zero-terminated=1): List of local candidates
255  * Since: 1.22
256  */
257 GstWebRTCICECandidateStats *
258 gst_webrtc_ice_get_local_candidates (GstWebRTCICE * ice,
259     GstWebRTCICEStream * stream)
260 {
261   g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), NULL);
262   g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->get_local_candidates);
263
264   return GST_WEBRTC_ICE_GET_CLASS (ice)->get_local_candidates (ice, stream);
265 }
266
267
268 /**
269  * gst_webrtc_ice_get_remote_candidates:
270  * @ice: The #GstWebRTCICE
271  * @stream: The #GstWebRTCICEStream
272  * Returns: (transfer full) (array zero-terminated=1): List of remote candidates
273  * Since: 1.22
274  */
275 GstWebRTCICECandidateStats *
276 gst_webrtc_ice_get_remote_candidates (GstWebRTCICE * ice,
277     GstWebRTCICEStream * stream)
278 {
279   g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), NULL);
280   g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->get_remote_candidates);
281
282   return GST_WEBRTC_ICE_GET_CLASS (ice)->get_remote_candidates (ice, stream);
283 }
284
285 /**
286  * gst_webrtc_ice_get_selected_pair:
287  * @ice: The #GstWebRTCICE
288  * @stream: The #GstWebRTCICEStream
289  * @local_stats: (out) (transfer full): A pointer to #GstWebRTCICECandidateStats for local candidate
290  * @remote_stats: (out) (transfer full): pointer to #GstWebRTCICECandidateStats for remote candidate
291  *
292  * Returns: FALSE on failure, otherwise @local_stats @remote_stats will be set
293  * Since: 1.22
294  */
295 gboolean
296 gst_webrtc_ice_get_selected_pair (GstWebRTCICE * ice,
297     GstWebRTCICEStream * stream, GstWebRTCICECandidateStats ** local_stats,
298     GstWebRTCICECandidateStats ** remote_stats)
299 {
300   g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), FALSE);
301   g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->get_selected_pair);
302
303   return GST_WEBRTC_ICE_GET_CLASS (ice)->get_selected_pair (ice, stream,
304       local_stats, remote_stats);
305 }
306
307 /**
308  * gst_webrtc_ice_candidate_stats_free:
309  * @stats: The #GstWebRTCICECandidateStats to be free'd
310  *
311  * Helper function to free #GstWebRTCICECandidateStats
312  * Since: 1.22
313  */
314 void
315 gst_webrtc_ice_candidate_stats_free (GstWebRTCICECandidateStats * stats)
316 {
317   if (stats) {
318     g_free (stats->ipaddr);
319     g_free (stats->url);
320   }
321
322   g_free (stats);
323 }
324
325 /**
326  * gst_webrtc_ice_candidate_stats_copy:
327  * @stats: The #GstWebRTCICE
328  *
329  * Returns: (transfer full): A copy of @stats
330  * Since: 1.22
331  */
332 GstWebRTCICECandidateStats *
333 gst_webrtc_ice_candidate_stats_copy (GstWebRTCICECandidateStats * stats)
334 {
335   GstWebRTCICECandidateStats *copy =
336       g_malloc (sizeof (GstWebRTCICECandidateStats));
337
338   *copy = *stats;
339
340   copy->ipaddr = g_strdup (stats->ipaddr);
341   copy->url = g_strdup (stats->url);
342
343   return copy;
344 }
345
346 G_DEFINE_BOXED_TYPE (GstWebRTCICECandidateStats, gst_webrtc_ice_candidate_stats,
347     (GBoxedCopyFunc) gst_webrtc_ice_candidate_stats_copy,
348     (GBoxedFreeFunc) gst_webrtc_ice_candidate_stats_free);
349
350 /**
351  * gst_webrtc_ice_set_on_ice_candidate:
352  * @ice: The #GstWebRTCICE
353  * @func: The #GstWebRTCICEOnCandidateFunc callback function
354  * @user_data: User data passed to the callback function
355  * @notify: a #GDestroyNotify when the candidate is no longer needed
356  * Since: 1.22
357  */
358 void
359 gst_webrtc_ice_set_on_ice_candidate (GstWebRTCICE * ice,
360     GstWebRTCICEOnCandidateFunc func, gpointer user_data, GDestroyNotify notify)
361 {
362   g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
363   g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_on_ice_candidate);
364
365   GST_WEBRTC_ICE_GET_CLASS (ice)->set_on_ice_candidate (ice, func, user_data,
366       notify);
367 }
368
369 /**
370  * gst_webrtc_ice_set_stun_server:
371  * @ice: The #GstWebRTCICE
372  * @uri: URI of the STUN server
373  * Since: 1.22
374  */
375 void
376 gst_webrtc_ice_set_stun_server (GstWebRTCICE * ice, const gchar * uri_s)
377 {
378   g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
379   g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_stun_server);
380
381   GST_WEBRTC_ICE_GET_CLASS (ice)->set_stun_server (ice, uri_s);
382 }
383
384 /**
385  * gst_webrtc_ice_get_stun_server:
386  * @ice: The #GstWebRTCICE
387  * Returns: URI of the STUN sever
388  * Since: 1.22
389  */
390 gchar *
391 gst_webrtc_ice_get_stun_server (GstWebRTCICE * ice)
392 {
393   g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), NULL);
394   g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->get_stun_server);
395
396   return GST_WEBRTC_ICE_GET_CLASS (ice)->get_stun_server (ice);
397 }
398
399 /**
400  * gst_webrtc_ice_set_turn_server:
401  * @ice: The #GstWebRTCICE
402  * @uri: URI of the TURN sever
403  * Since: 1.22
404  */
405 void
406 gst_webrtc_ice_set_turn_server (GstWebRTCICE * ice, const gchar * uri_s)
407 {
408   g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
409   g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_turn_server);
410
411   GST_WEBRTC_ICE_GET_CLASS (ice)->set_turn_server (ice, uri_s);
412 }
413
414 /**
415  * gst_webrtc_ice_get_turn_server:
416  * @ice: The #GstWebRTCICE
417  * Returns: URI of the TURN sever
418  * Since: 1.22
419  */
420 gchar *
421 gst_webrtc_ice_get_turn_server (GstWebRTCICE * ice)
422 {
423   g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), NULL);
424   g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->get_turn_server);
425
426   return GST_WEBRTC_ICE_GET_CLASS (ice)->get_turn_server (ice);
427 }
428
429
430 static void
431 gst_webrtc_ice_set_property (GObject * object, guint prop_id,
432     const GValue * value, GParamSpec * pspec)
433 {
434   GstWebRTCICE *ice = GST_WEBRTC_ICE (object);
435
436   switch (prop_id) {
437     case PROP_MIN_RTP_PORT:
438       ice->min_rtp_port = g_value_get_uint (value);
439       if (ice->min_rtp_port > ice->max_rtp_port)
440         g_warning ("Set min-rtp-port to %u which is larger than"
441             " max-rtp-port %u", ice->min_rtp_port, ice->max_rtp_port);
442       break;
443     case PROP_MAX_RTP_PORT:
444       ice->max_rtp_port = g_value_get_uint (value);
445       if (ice->min_rtp_port > ice->max_rtp_port)
446         g_warning ("Set max-rtp-port to %u which is smaller than"
447             " min-rtp-port %u", ice->max_rtp_port, ice->min_rtp_port);
448       break;
449     default:
450       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
451       break;
452   }
453 }
454
455 static void
456 gst_webrtc_ice_get_property (GObject * object, guint prop_id,
457     GValue * value, GParamSpec * pspec)
458 {
459   GstWebRTCICE *ice = GST_WEBRTC_ICE (object);
460
461   switch (prop_id) {
462     case PROP_MIN_RTP_PORT:
463       g_value_set_uint (value, ice->min_rtp_port);
464       break;
465     case PROP_MAX_RTP_PORT:
466       g_value_set_uint (value, ice->max_rtp_port);
467       break;
468     default:
469       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
470       break;
471   }
472 }
473
474 static void
475 gst_webrtc_ice_class_init (GstWebRTCICEClass * klass)
476 {
477   GObjectClass *gobject_class = (GObjectClass *) klass;
478
479   klass->add_stream = NULL;
480   klass->find_transport = NULL;
481   klass->gather_candidates = NULL;
482   klass->add_candidate = NULL;
483   klass->set_local_credentials = NULL;
484   klass->set_remote_credentials = NULL;
485   klass->add_turn_server = NULL;
486   klass->set_is_controller = NULL;
487   klass->get_is_controller = NULL;
488   klass->set_force_relay = NULL;
489   klass->set_stun_server = NULL;
490   klass->get_stun_server = NULL;
491   klass->set_turn_server = NULL;
492   klass->get_turn_server = NULL;
493   klass->set_tos = NULL;
494   klass->set_on_ice_candidate = NULL;
495   klass->get_local_candidates = NULL;
496   klass->get_remote_candidates = NULL;
497   klass->get_selected_pair = NULL;
498
499   gobject_class->get_property = gst_webrtc_ice_get_property;
500   gobject_class->set_property = gst_webrtc_ice_set_property;
501
502   /**
503    * GstWebRTCICE:min-rtp-port:
504    *
505    * Minimum port for local rtp port range.
506    * min-rtp-port must be <= max-rtp-port
507    *
508    * Since: 1.20
509    */
510   g_object_class_install_property (gobject_class,
511       PROP_MIN_RTP_PORT,
512       g_param_spec_uint ("min-rtp-port", "ICE RTP candidate min port",
513           "Minimum port for local rtp port range. "
514           "min-rtp-port must be <= max-rtp-port",
515           0, 65535, 0,
516           G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
517
518   /**
519    * GstWebRTCICE:max-rtp-port:
520    *
521    * Maximum port for local rtp port range.
522    * min-rtp-port must be <= max-rtp-port
523    *
524    * Since: 1.20
525    */
526   g_object_class_install_property (gobject_class,
527       PROP_MAX_RTP_PORT,
528       g_param_spec_uint ("max-rtp-port", "ICE RTP candidate max port",
529           "Maximum port for local rtp port range. "
530           "max-rtp-port must be >= min-rtp-port",
531           0, 65535, 65535,
532           G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
533
534   /**
535    * GstWebRTCICE::add-local-ip-address:
536    * @object: the #GstWebRTCICE
537    * @address: The local IP address
538    *
539    * Add a local IP address to use for ICE candidate gathering.  If none
540    * are supplied, they will be discovered automatically. Calling this signal
541    * stops automatic ICE gathering.
542    *
543    * Returns: whether the address could be added.
544    */
545   gst_webrtc_ice_signals[ADD_LOCAL_IP_ADDRESS_SIGNAL] =
546       g_signal_new_class_handler ("add-local-ip-address",
547       G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
548       NULL, NULL, NULL,
549       g_cclosure_marshal_generic, G_TYPE_BOOLEAN, 1, G_TYPE_STRING);
550 }
551
552 static void
553 gst_webrtc_ice_init (GstWebRTCICE * ice)
554 {
555 }