2 * Copyright (C) 2017 Matthew Waters <matthew@centricular.com>
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.
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.
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.
20 * SECTION:gstwebrtcice
21 * @title: GstWebRTCICE
22 * @short_description: Base class WebRTC ICE handling
32 #include "icestream.h"
34 #include "webrtc-priv.h"
36 #define GST_CAT_DEFAULT gst_webrtc_ice_debug
37 GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
42 ADD_LOCAL_IP_ADDRESS_SIGNAL,
53 static guint gst_webrtc_ice_signals[LAST_SIGNAL] = { 0 };
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"););
61 * gst_webrtc_ice_add_stream:
62 * @ice: The #GstWebRTCICE
63 * @session_id: The session id
65 * Returns: (transfer full) (nullable): The #GstWebRTCICEStream, or %NULL
69 gst_webrtc_ice_add_stream (GstWebRTCICE * ice, guint session_id)
71 g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), NULL);
72 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->add_stream);
74 return GST_WEBRTC_ICE_GET_CLASS (ice)->add_stream (ice, session_id);
78 * gst_webrtc_ice_find_transport:
79 * @ice: The #GstWebRTCICE
80 * @stream: The #GstWebRTCICEStream
81 * @component: The #GstWebRTCICEComponent
83 * Returns: (transfer full) (nullable): The #GstWebRTCICETransport, or %NULL
86 GstWebRTCICETransport *
87 gst_webrtc_ice_find_transport (GstWebRTCICE * ice,
88 GstWebRTCICEStream * stream, GstWebRTCICEComponent component)
90 g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), NULL);
91 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->find_transport);
93 return GST_WEBRTC_ICE_GET_CLASS (ice)->find_transport (ice, stream,
98 * gst_webrtc_ice_add_candidate:
99 * @ice: The #GstWebRTCICE
100 * @stream: The #GstWebRTCICEStream
101 * @candidate: The ICE candidate
105 gst_webrtc_ice_add_candidate (GstWebRTCICE * ice,
106 GstWebRTCICEStream * stream, const gchar * candidate)
108 g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
109 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->add_candidate);
111 GST_WEBRTC_ICE_GET_CLASS (ice)->add_candidate (ice, stream, candidate);
115 * gst_webrtc_ice_set_remote_credentials:
116 * @ice: The #GstWebRTCICE
117 * @stream: The #GstWebRTCICEStream
118 * @ufrag: ICE username
120 * Returns: FALSE on error, TRUE otherwise
124 gst_webrtc_ice_set_remote_credentials (GstWebRTCICE * ice,
125 GstWebRTCICEStream * stream, gchar * ufrag, gchar * pwd)
127 g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), FALSE);
128 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_remote_credentials);
130 return GST_WEBRTC_ICE_GET_CLASS (ice)->set_remote_credentials (ice, stream,
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
142 gst_webrtc_ice_add_turn_server (GstWebRTCICE * ice, const gchar * uri)
144 g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), FALSE);
145 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->add_turn_server);
147 return GST_WEBRTC_ICE_GET_CLASS (ice)->add_turn_server (ice, uri);
151 * gst_webrtc_ice_set_local_credentials:
152 * @ice: The #GstWebRTCICE
153 * @stream: The #GstWebRTCICEStream
154 * @ufrag: ICE username
156 * Returns: FALSE on error, TRUE otherwise
160 gst_webrtc_ice_set_local_credentials (GstWebRTCICE * ice,
161 GstWebRTCICEStream * stream, gchar * ufrag, gchar * pwd)
163 g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), FALSE);
164 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_local_credentials);
166 return GST_WEBRTC_ICE_GET_CLASS (ice)->set_local_credentials (ice, stream,
171 * gst_webrtc_ice_gather_candidates:
172 * @ice: The #GstWebRTCICE
173 * @stream: The #GstWebRTCICEStream
174 * Returns: FALSE on error, TRUE otherwise
178 gst_webrtc_ice_gather_candidates (GstWebRTCICE * ice,
179 GstWebRTCICEStream * stream)
181 g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), FALSE);
182 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->gather_candidates);
184 return GST_WEBRTC_ICE_GET_CLASS (ice)->gather_candidates (ice, stream);
188 * gst_webrtc_ice_set_is_controller:
189 * @ice: The #GstWebRTCICE
190 * @controller: TRUE to set as controller
194 gst_webrtc_ice_set_is_controller (GstWebRTCICE * ice, gboolean controller)
196 g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
197 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_is_controller);
199 GST_WEBRTC_ICE_GET_CLASS (ice)->set_is_controller (ice, controller);
203 * gst_webrtc_ice_get_is_controller:
204 * @ice: The #GstWebRTCICE
205 * Returns: TRUE if set as controller, FALSE otherwise
209 gst_webrtc_ice_get_is_controller (GstWebRTCICE * ice)
211 g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), FALSE);
212 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->get_is_controller);
214 return GST_WEBRTC_ICE_GET_CLASS (ice)->get_is_controller (ice);
218 * gst_webrtc_ice_set_force_relay:
219 * @ice: The #GstWebRTCICE
220 * @force_relay: TRUE to enable force relay
224 gst_webrtc_ice_set_force_relay (GstWebRTCICE * ice, gboolean force_relay)
226 g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
227 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_force_relay);
229 GST_WEBRTC_ICE_GET_CLASS (ice)->set_force_relay (ice, force_relay);
233 * gst_webrtc_ice_set_tos:
234 * @ice: The #GstWebRTCICE
235 * @stream: The #GstWebRTCICEStream
236 * @tos: ToS to be set
240 gst_webrtc_ice_set_tos (GstWebRTCICE * ice, GstWebRTCICEStream * stream,
243 g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
244 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_tos);
246 GST_WEBRTC_ICE_GET_CLASS (ice)->set_tos (ice, stream, tos);
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
257 GstWebRTCICECandidateStats *
258 gst_webrtc_ice_get_local_candidates (GstWebRTCICE * ice,
259 GstWebRTCICEStream * stream)
261 g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), NULL);
262 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->get_local_candidates);
264 return GST_WEBRTC_ICE_GET_CLASS (ice)->get_local_candidates (ice, stream);
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
275 GstWebRTCICECandidateStats *
276 gst_webrtc_ice_get_remote_candidates (GstWebRTCICE * ice,
277 GstWebRTCICEStream * stream)
279 g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), NULL);
280 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->get_remote_candidates);
282 return GST_WEBRTC_ICE_GET_CLASS (ice)->get_remote_candidates (ice, stream);
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
292 * Returns: FALSE on failure, otherwise @local_stats @remote_stats will be set
296 gst_webrtc_ice_get_selected_pair (GstWebRTCICE * ice,
297 GstWebRTCICEStream * stream, GstWebRTCICECandidateStats ** local_stats,
298 GstWebRTCICECandidateStats ** remote_stats)
300 g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), FALSE);
301 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->get_selected_pair);
303 return GST_WEBRTC_ICE_GET_CLASS (ice)->get_selected_pair (ice, stream,
304 local_stats, remote_stats);
308 * gst_webrtc_ice_candidate_stats_free:
309 * @stats: The #GstWebRTCICECandidateStats to be free'd
311 * Helper function to free #GstWebRTCICECandidateStats
315 gst_webrtc_ice_candidate_stats_free (GstWebRTCICECandidateStats * stats)
318 g_free (stats->ipaddr);
326 * gst_webrtc_ice_candidate_stats_copy:
327 * @stats: The #GstWebRTCICE
329 * Returns: (transfer full): A copy of @stats
332 GstWebRTCICECandidateStats *
333 gst_webrtc_ice_candidate_stats_copy (GstWebRTCICECandidateStats * stats)
335 GstWebRTCICECandidateStats *copy =
336 g_malloc (sizeof (GstWebRTCICECandidateStats));
340 copy->ipaddr = g_strdup (stats->ipaddr);
341 copy->url = g_strdup (stats->url);
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);
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
359 gst_webrtc_ice_set_on_ice_candidate (GstWebRTCICE * ice,
360 GstWebRTCICEOnCandidateFunc func, gpointer user_data, GDestroyNotify notify)
362 g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
363 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_on_ice_candidate);
365 GST_WEBRTC_ICE_GET_CLASS (ice)->set_on_ice_candidate (ice, func, user_data,
370 * gst_webrtc_ice_set_stun_server:
371 * @ice: The #GstWebRTCICE
372 * @uri: URI of the STUN server
376 gst_webrtc_ice_set_stun_server (GstWebRTCICE * ice, const gchar * uri_s)
378 g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
379 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_stun_server);
381 GST_WEBRTC_ICE_GET_CLASS (ice)->set_stun_server (ice, uri_s);
385 * gst_webrtc_ice_get_stun_server:
386 * @ice: The #GstWebRTCICE
387 * Returns: URI of the STUN sever
391 gst_webrtc_ice_get_stun_server (GstWebRTCICE * ice)
393 g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), NULL);
394 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->get_stun_server);
396 return GST_WEBRTC_ICE_GET_CLASS (ice)->get_stun_server (ice);
400 * gst_webrtc_ice_set_turn_server:
401 * @ice: The #GstWebRTCICE
402 * @uri: URI of the TURN sever
406 gst_webrtc_ice_set_turn_server (GstWebRTCICE * ice, const gchar * uri_s)
408 g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
409 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_turn_server);
411 GST_WEBRTC_ICE_GET_CLASS (ice)->set_turn_server (ice, uri_s);
415 * gst_webrtc_ice_get_turn_server:
416 * @ice: The #GstWebRTCICE
417 * Returns: URI of the TURN sever
421 gst_webrtc_ice_get_turn_server (GstWebRTCICE * ice)
423 g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), NULL);
424 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->get_turn_server);
426 return GST_WEBRTC_ICE_GET_CLASS (ice)->get_turn_server (ice);
431 gst_webrtc_ice_set_property (GObject * object, guint prop_id,
432 const GValue * value, GParamSpec * pspec)
434 GstWebRTCICE *ice = GST_WEBRTC_ICE (object);
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);
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);
450 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
456 gst_webrtc_ice_get_property (GObject * object, guint prop_id,
457 GValue * value, GParamSpec * pspec)
459 GstWebRTCICE *ice = GST_WEBRTC_ICE (object);
462 case PROP_MIN_RTP_PORT:
463 g_value_set_uint (value, ice->min_rtp_port);
465 case PROP_MAX_RTP_PORT:
466 g_value_set_uint (value, ice->max_rtp_port);
469 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
475 gst_webrtc_ice_class_init (GstWebRTCICEClass * klass)
477 GObjectClass *gobject_class = (GObjectClass *) klass;
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;
499 gobject_class->get_property = gst_webrtc_ice_get_property;
500 gobject_class->set_property = gst_webrtc_ice_set_property;
503 * GstWebRTCICE:min-rtp-port:
505 * Minimum port for local rtp port range.
506 * min-rtp-port must be <= max-rtp-port
510 g_object_class_install_property (gobject_class,
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",
516 G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
519 * GstWebRTCICE:max-rtp-port:
521 * Maximum port for local rtp port range.
522 * min-rtp-port must be <= max-rtp-port
526 g_object_class_install_property (gobject_class,
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",
532 G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
535 * GstWebRTCICE::add-local-ip-address:
536 * @object: the #GstWebRTCICE
537 * @address: The local IP address
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.
543 * Returns: whether the address could be added.
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,
549 g_cclosure_marshal_generic, G_TYPE_BOOLEAN, 1, G_TYPE_STRING);
553 gst_webrtc_ice_init (GstWebRTCICE * ice)