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.
25 #include "icestream.h"
27 #include "webrtc-priv.h"
29 #define GST_CAT_DEFAULT gst_webrtc_ice_debug
30 GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
35 ADD_LOCAL_IP_ADDRESS_SIGNAL,
46 static guint gst_webrtc_ice_signals[LAST_SIGNAL] = { 0 };
48 #define gst_webrtc_ice_parent_class parent_class
49 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstWebRTCICE, gst_webrtc_ice,
50 GST_TYPE_OBJECT, GST_DEBUG_CATEGORY_INIT (gst_webrtc_ice_debug,
51 "webrtcice", 0, "webrtcice"););
54 * gst_webrtc_ice_add_stream:
55 * @ice: The #GstWebRTCICE
56 * @session_id: The session id
58 * Returns: (transfer full) (nullable): The #GstWebRTCICEStream, or %NULL
62 gst_webrtc_ice_add_stream (GstWebRTCICE * ice, guint session_id)
64 g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), NULL);
65 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->add_stream);
67 return GST_WEBRTC_ICE_GET_CLASS (ice)->add_stream (ice, session_id);
71 * gst_webrtc_ice_find_transport:
72 * @ice: The #GstWebRTCICE
73 * @stream: The #GstWebRTCICEStream
74 * @component: The #GstWebRTCICEComponent
76 * Returns: (transfer full) (nullable): The #GstWebRTCICETransport, or %NULL
79 GstWebRTCICETransport *
80 gst_webrtc_ice_find_transport (GstWebRTCICE * ice,
81 GstWebRTCICEStream * stream, GstWebRTCICEComponent component)
83 g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), NULL);
84 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->find_transport);
86 return GST_WEBRTC_ICE_GET_CLASS (ice)->find_transport (ice, stream,
91 * gst_webrtc_ice_add_candidate:
92 * @ice: The #GstWebRTCICE
93 * @stream: The #GstWebRTCICEStream
94 * @candidate: The ICE candidate
98 gst_webrtc_ice_add_candidate (GstWebRTCICE * ice,
99 GstWebRTCICEStream * stream, const gchar * candidate)
101 g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
102 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->add_candidate);
104 GST_WEBRTC_ICE_GET_CLASS (ice)->add_candidate (ice, stream, candidate);
108 * gst_webrtc_ice_set_remote_credentials:
109 * @ice: The #GstWebRTCICE
110 * @stream: The #GstWebRTCICEStream
111 * @ufrag: ICE username
113 * Returns: FALSE on error, TRUE otherwise
117 gst_webrtc_ice_set_remote_credentials (GstWebRTCICE * ice,
118 GstWebRTCICEStream * stream, gchar * ufrag, gchar * pwd)
120 g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), FALSE);
121 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_remote_credentials);
123 return GST_WEBRTC_ICE_GET_CLASS (ice)->set_remote_credentials (ice, stream,
128 * gst_webrtc_ice_add_turn_server:
129 * @ice: The #GstWebRTCICE
130 * @uri: URI of the TURN server
131 * Returns: FALSE on error, TRUE otherwise
135 gst_webrtc_ice_add_turn_server (GstWebRTCICE * ice, const gchar * uri)
137 g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), FALSE);
138 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->add_turn_server);
140 return GST_WEBRTC_ICE_GET_CLASS (ice)->add_turn_server (ice, uri);
144 * gst_webrtc_ice_set_local_credentials:
145 * @ice: The #GstWebRTCICE
146 * @stream: The #GstWebRTCICEStream
147 * @ufrag: ICE username
149 * Returns: FALSE on error, TRUE otherwise
153 gst_webrtc_ice_set_local_credentials (GstWebRTCICE * ice,
154 GstWebRTCICEStream * stream, gchar * ufrag, gchar * pwd)
156 g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), FALSE);
157 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_local_credentials);
159 return GST_WEBRTC_ICE_GET_CLASS (ice)->set_local_credentials (ice, stream,
164 * gst_webrtc_ice_gather_candidates:
165 * @ice: The #GstWebRTCICE
166 * @stream: The #GstWebRTCICEStream
167 * Returns: FALSE on error, TRUE otherwise
171 gst_webrtc_ice_gather_candidates (GstWebRTCICE * ice,
172 GstWebRTCICEStream * stream)
174 g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), FALSE);
175 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->gather_candidates);
177 return GST_WEBRTC_ICE_GET_CLASS (ice)->gather_candidates (ice, stream);
181 * gst_webrtc_ice_set_is_controller:
182 * @ice: The #GstWebRTCICE
183 * @controller: TRUE to set as controller
187 gst_webrtc_ice_set_is_controller (GstWebRTCICE * ice, gboolean controller)
189 g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
190 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_is_controller);
192 GST_WEBRTC_ICE_GET_CLASS (ice)->set_is_controller (ice, controller);
196 * gst_webrtc_ice_get_is_controller:
197 * @ice: The #GstWebRTCICE
198 * Returns: TRUE if set as controller, FALSE otherwise
202 gst_webrtc_ice_get_is_controller (GstWebRTCICE * ice)
204 g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), FALSE);
205 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->get_is_controller);
207 return GST_WEBRTC_ICE_GET_CLASS (ice)->get_is_controller (ice);
211 * gst_webrtc_ice_set_force_relay:
212 * @ice: The #GstWebRTCICE
213 * @force_relay: TRUE to enable force relay
217 gst_webrtc_ice_set_force_relay (GstWebRTCICE * ice, gboolean force_relay)
219 g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
220 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_force_relay);
222 GST_WEBRTC_ICE_GET_CLASS (ice)->set_force_relay (ice, force_relay);
226 * gst_webrtc_ice_set_tos:
227 * @ice: The #GstWebRTCICE
228 * @stream: The #GstWebRTCICEStream
229 * @tos: ToS to be set
233 gst_webrtc_ice_set_tos (GstWebRTCICE * ice, GstWebRTCICEStream * stream,
236 g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
237 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_tos);
239 GST_WEBRTC_ICE_GET_CLASS (ice)->set_tos (ice, stream, tos);
244 * gst_webrtc_ice_get_local_candidates:
245 * @ice: The #GstWebRTCICE
246 * @stream: The #GstWebRTCICEStream
247 * Returns: (transfer full)(array zero-terminated=1): List of local candidates
250 GstWebRTCICECandidateStats *
251 gst_webrtc_ice_get_local_candidates (GstWebRTCICE * ice,
252 GstWebRTCICEStream * stream)
254 g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), NULL);
255 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->get_local_candidates);
257 return GST_WEBRTC_ICE_GET_CLASS (ice)->get_local_candidates (ice, stream);
262 * gst_webrtc_ice_get_remote_candidates:
263 * @ice: The #GstWebRTCICE
264 * @stream: The #GstWebRTCICEStream
265 * Returns: (transfer full) (array zero-terminated=1): List of remote candidates
268 GstWebRTCICECandidateStats *
269 gst_webrtc_ice_get_remote_candidates (GstWebRTCICE * ice,
270 GstWebRTCICEStream * stream)
272 g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), NULL);
273 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->get_remote_candidates);
275 return GST_WEBRTC_ICE_GET_CLASS (ice)->get_remote_candidates (ice, stream);
279 * gst_webrtc_ice_get_selected_pair:
280 * @ice: The #GstWebRTCICE
281 * @stream: The #GstWebRTCICEStream
282 * @local_stats: (out) (transfer full): A pointer to #GstWebRTCICECandidateStats for local candidate
283 * @remote_stats: (out) (transfer full): pointer to #GstWebRTCICECandidateStats for remote candidate
285 * Returns: FALSE on failure, otherwise @local_stats @remote_stats will be set
289 gst_webrtc_ice_get_selected_pair (GstWebRTCICE * ice,
290 GstWebRTCICEStream * stream, GstWebRTCICECandidateStats ** local_stats,
291 GstWebRTCICECandidateStats ** remote_stats)
293 g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), FALSE);
294 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->get_selected_pair);
296 return GST_WEBRTC_ICE_GET_CLASS (ice)->get_selected_pair (ice, stream,
297 local_stats, remote_stats);
301 * gst_webrtc_ice_candidate_stats_free:
302 * @stats: The #GstWebRTCICECandidateStats to be free'd
304 * Helper function to free #GstWebRTCICECandidateStats
308 gst_webrtc_ice_candidate_stats_free (GstWebRTCICECandidateStats * stats)
311 g_free (stats->ipaddr);
319 * gst_webrtc_ice_candidate_stats_copy:
320 * @stats: The #GstWebRTCICE
322 * Returns: (transfer full): A copy of @stats
325 GstWebRTCICECandidateStats *
326 gst_webrtc_ice_candidate_stats_copy (GstWebRTCICECandidateStats * stats)
328 GstWebRTCICECandidateStats *copy =
329 g_malloc (sizeof (GstWebRTCICECandidateStats));
333 copy->ipaddr = g_strdup (stats->ipaddr);
334 copy->url = g_strdup (stats->url);
339 G_DEFINE_BOXED_TYPE (GstWebRTCICECandidateStats, gst_webrtc_ice_candidate_stats,
340 (GBoxedCopyFunc) gst_webrtc_ice_candidate_stats_copy,
341 (GBoxedFreeFunc) gst_webrtc_ice_candidate_stats_free);
344 * gst_webrtc_ice_set_on_ice_candidate:
345 * @ice: The #GstWebRTCICE
346 * @func: The #GstWebRTCICEOnCandidateFunc callback function
347 * @user_data: User data passed to the callback function
348 * @notify: a #GDestroyNotify when the candidate is no longer needed
352 gst_webrtc_ice_set_on_ice_candidate (GstWebRTCICE * ice,
353 GstWebRTCICEOnCandidateFunc func, gpointer user_data, GDestroyNotify notify)
355 g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
356 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_on_ice_candidate);
358 GST_WEBRTC_ICE_GET_CLASS (ice)->set_on_ice_candidate (ice, func, user_data,
363 * gst_webrtc_ice_set_stun_server:
364 * @ice: The #GstWebRTCICE
365 * @uri: URI of the STUN server
369 gst_webrtc_ice_set_stun_server (GstWebRTCICE * ice, const gchar * uri_s)
371 g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
372 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_stun_server);
374 GST_WEBRTC_ICE_GET_CLASS (ice)->set_stun_server (ice, uri_s);
378 * gst_webrtc_ice_get_stun_server:
379 * @ice: The #GstWebRTCICE
380 * Returns: URI of the STUN sever
384 gst_webrtc_ice_get_stun_server (GstWebRTCICE * ice)
386 g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), NULL);
387 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->get_stun_server);
389 return GST_WEBRTC_ICE_GET_CLASS (ice)->get_stun_server (ice);
393 * gst_webrtc_ice_set_turn_server:
394 * @ice: The #GstWebRTCICE
395 * @uri: URI of the TURN sever
399 gst_webrtc_ice_set_turn_server (GstWebRTCICE * ice, const gchar * uri_s)
401 g_return_if_fail (GST_IS_WEBRTC_ICE (ice));
402 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->set_turn_server);
404 GST_WEBRTC_ICE_GET_CLASS (ice)->set_turn_server (ice, uri_s);
408 * gst_webrtc_ice_get_turn_server:
409 * @ice: The #GstWebRTCICE
410 * Returns: URI of the TURN sever
414 gst_webrtc_ice_get_turn_server (GstWebRTCICE * ice)
416 g_return_val_if_fail (GST_IS_WEBRTC_ICE (ice), NULL);
417 g_assert (GST_WEBRTC_ICE_GET_CLASS (ice)->get_turn_server);
419 return GST_WEBRTC_ICE_GET_CLASS (ice)->get_turn_server (ice);
424 gst_webrtc_ice_set_property (GObject * object, guint prop_id,
425 const GValue * value, GParamSpec * pspec)
427 GstWebRTCICE *ice = GST_WEBRTC_ICE (object);
430 case PROP_MIN_RTP_PORT:
431 ice->min_rtp_port = g_value_get_uint (value);
432 if (ice->min_rtp_port > ice->max_rtp_port)
433 g_warning ("Set min-rtp-port to %u which is larger than"
434 " max-rtp-port %u", ice->min_rtp_port, ice->max_rtp_port);
436 case PROP_MAX_RTP_PORT:
437 ice->max_rtp_port = g_value_get_uint (value);
438 if (ice->min_rtp_port > ice->max_rtp_port)
439 g_warning ("Set max-rtp-port to %u which is smaller than"
440 " min-rtp-port %u", ice->max_rtp_port, ice->min_rtp_port);
443 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
449 gst_webrtc_ice_get_property (GObject * object, guint prop_id,
450 GValue * value, GParamSpec * pspec)
452 GstWebRTCICE *ice = GST_WEBRTC_ICE (object);
455 case PROP_MIN_RTP_PORT:
456 g_value_set_uint (value, ice->min_rtp_port);
458 case PROP_MAX_RTP_PORT:
459 g_value_set_uint (value, ice->max_rtp_port);
462 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
468 gst_webrtc_ice_class_init (GstWebRTCICEClass * klass)
470 GObjectClass *gobject_class = (GObjectClass *) klass;
472 klass->add_stream = NULL;
473 klass->find_transport = NULL;
474 klass->gather_candidates = NULL;
475 klass->add_candidate = NULL;
476 klass->set_local_credentials = NULL;
477 klass->set_remote_credentials = NULL;
478 klass->add_turn_server = NULL;
479 klass->set_is_controller = NULL;
480 klass->get_is_controller = NULL;
481 klass->set_force_relay = NULL;
482 klass->set_stun_server = NULL;
483 klass->get_stun_server = NULL;
484 klass->set_turn_server = NULL;
485 klass->get_turn_server = NULL;
486 klass->set_tos = NULL;
487 klass->set_on_ice_candidate = NULL;
488 klass->get_local_candidates = NULL;
489 klass->get_remote_candidates = NULL;
490 klass->get_selected_pair = NULL;
492 gobject_class->get_property = gst_webrtc_ice_get_property;
493 gobject_class->set_property = gst_webrtc_ice_set_property;
496 * GstWebRTCICE:min-rtp-port:
498 * Minimum port for local rtp port range.
499 * min-rtp-port must be <= max-rtp-port
503 g_object_class_install_property (gobject_class,
505 g_param_spec_uint ("min-rtp-port", "ICE RTP candidate min port",
506 "Minimum port for local rtp port range. "
507 "min-rtp-port must be <= max-rtp-port",
509 G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
512 * GstWebRTCICE:max-rtp-port:
514 * Maximum port for local rtp port range.
515 * min-rtp-port must be <= max-rtp-port
519 g_object_class_install_property (gobject_class,
521 g_param_spec_uint ("max-rtp-port", "ICE RTP candidate max port",
522 "Maximum port for local rtp port range. "
523 "max-rtp-port must be >= min-rtp-port",
525 G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
528 * GstWebRTCICE::add-local-ip-address:
529 * @object: the #GstWebRTCICE
530 * @address: The local IP address
532 * Add a local IP address to use for ICE candidate gathering. If none
533 * are supplied, they will be discovered automatically. Calling this signal
534 * stops automatic ICE gathering.
536 * Returns: whether the address could be added.
538 gst_webrtc_ice_signals[ADD_LOCAL_IP_ADDRESS_SIGNAL] =
539 g_signal_new_class_handler ("add-local-ip-address",
540 G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
542 g_cclosure_marshal_generic, G_TYPE_BOOLEAN, 1, G_TYPE_STRING);
546 gst_webrtc_ice_init (GstWebRTCICE * ice)