webrtc: Fix documentaton moving symbols in the right pages
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-bad / gst-libs / gst / webrtc / datachannel.c
1 /* GStreamer
2  * Copyright (C) 2017 Matthew Waters <matthew@centricular.com>
3  * Copyright (C) 2020 Sebastian Dröge <sebastian@centricular.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 /**
22  * SECTION:gstwebrtc-datachannel
23  * @short_description: RTCDataChannel object
24  * @title: GstWebRTCDataChannel
25  * @symbols:
26  * - GstWebRTCDataChannel
27  *
28  * <https://www.w3.org/TR/webrtc/#rtcdatachannel>
29  *
30  * Since: 1.18
31  */
32
33 #ifdef HAVE_CONFIG_H
34 # include "config.h"
35 #endif
36
37 #include "datachannel.h"
38 #include "webrtc-priv.h"
39
40 #define GST_CAT_DEFAULT gst_webrtc_data_channel_debug
41 GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
42
43 #define gst_webrtc_data_channel_parent_class parent_class
44 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstWebRTCDataChannel, gst_webrtc_data_channel,
45     G_TYPE_OBJECT, GST_DEBUG_CATEGORY_INIT (gst_webrtc_data_channel_debug,
46         "webrtcdatachannel", 0, "webrtcdatachannel"););
47
48 enum
49 {
50   SIGNAL_0,
51   SIGNAL_ON_OPEN,
52   SIGNAL_ON_CLOSE,
53   SIGNAL_ON_ERROR,
54   SIGNAL_ON_MESSAGE_DATA,
55   SIGNAL_ON_MESSAGE_STRING,
56   SIGNAL_ON_BUFFERED_AMOUNT_LOW,
57   SIGNAL_SEND_DATA,
58   SIGNAL_SEND_STRING,
59   SIGNAL_CLOSE,
60   LAST_SIGNAL,
61 };
62
63 enum
64 {
65   PROP_0,
66   PROP_LABEL,
67   PROP_ORDERED,
68   PROP_MAX_PACKET_LIFETIME,
69   PROP_MAX_RETRANSMITS,
70   PROP_PROTOCOL,
71   PROP_NEGOTIATED,
72   PROP_ID,
73   PROP_PRIORITY,
74   PROP_READY_STATE,
75   PROP_BUFFERED_AMOUNT,
76   PROP_BUFFERED_AMOUNT_LOW_THRESHOLD,
77 };
78
79 static guint gst_webrtc_data_channel_signals[LAST_SIGNAL] = { 0 };
80
81 static void
82 gst_webrtc_data_channel_set_property (GObject * object, guint prop_id,
83     const GValue * value, GParamSpec * pspec)
84 {
85   GstWebRTCDataChannel *channel = GST_WEBRTC_DATA_CHANNEL (object);
86
87   GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
88   switch (prop_id) {
89     case PROP_LABEL:
90       g_free (channel->label);
91       channel->label = g_value_dup_string (value);
92       break;
93     case PROP_ORDERED:
94       channel->ordered = g_value_get_boolean (value);
95       break;
96     case PROP_MAX_PACKET_LIFETIME:
97       channel->max_packet_lifetime = g_value_get_int (value);
98       break;
99     case PROP_MAX_RETRANSMITS:
100       channel->max_retransmits = g_value_get_int (value);
101       break;
102     case PROP_PROTOCOL:
103       g_free (channel->protocol);
104       channel->protocol = g_value_dup_string (value);
105       break;
106     case PROP_NEGOTIATED:
107       channel->negotiated = g_value_get_boolean (value);
108       break;
109     case PROP_ID:
110       channel->id = g_value_get_int (value);
111       break;
112     case PROP_PRIORITY:
113       channel->priority = g_value_get_enum (value);
114       break;
115     case PROP_BUFFERED_AMOUNT_LOW_THRESHOLD:
116       channel->buffered_amount_low_threshold = g_value_get_uint64 (value);
117       break;
118     default:
119       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
120       break;
121   }
122   GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
123 }
124
125 static void
126 gst_webrtc_data_channel_get_property (GObject * object, guint prop_id,
127     GValue * value, GParamSpec * pspec)
128 {
129   GstWebRTCDataChannel *channel = GST_WEBRTC_DATA_CHANNEL (object);
130
131   GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
132   switch (prop_id) {
133     case PROP_LABEL:
134       g_value_set_string (value, channel->label);
135       break;
136     case PROP_ORDERED:
137       g_value_set_boolean (value, channel->ordered);
138       break;
139     case PROP_MAX_PACKET_LIFETIME:
140       g_value_set_int (value, channel->max_packet_lifetime);
141       break;
142     case PROP_MAX_RETRANSMITS:
143       g_value_set_int (value, channel->max_retransmits);
144       break;
145     case PROP_PROTOCOL:
146       g_value_set_string (value, channel->protocol);
147       break;
148     case PROP_NEGOTIATED:
149       g_value_set_boolean (value, channel->negotiated);
150       break;
151     case PROP_ID:
152       g_value_set_int (value, channel->id);
153       break;
154     case PROP_PRIORITY:
155       g_value_set_enum (value, channel->priority);
156       break;
157     case PROP_READY_STATE:
158       g_value_set_enum (value, channel->ready_state);
159       break;
160     case PROP_BUFFERED_AMOUNT:
161       g_value_set_uint64 (value, channel->buffered_amount);
162       break;
163     case PROP_BUFFERED_AMOUNT_LOW_THRESHOLD:
164       g_value_set_uint64 (value, channel->buffered_amount_low_threshold);
165       break;
166     default:
167       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
168       break;
169   }
170   GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
171 }
172
173 static void
174 gst_webrtc_data_channel_finalize (GObject * object)
175 {
176   GstWebRTCDataChannel *channel = GST_WEBRTC_DATA_CHANNEL (object);
177
178   g_free (channel->label);
179   channel->label = NULL;
180
181   g_free (channel->protocol);
182   channel->protocol = NULL;
183
184   g_mutex_clear (&channel->lock);
185
186   G_OBJECT_CLASS (parent_class)->finalize (object);
187 }
188
189 static void
190 gst_webrtc_data_channel_class_init (GstWebRTCDataChannelClass * klass)
191 {
192   GObjectClass *gobject_class = (GObjectClass *) klass;
193
194   gobject_class->get_property = gst_webrtc_data_channel_get_property;
195   gobject_class->set_property = gst_webrtc_data_channel_set_property;
196   gobject_class->finalize = gst_webrtc_data_channel_finalize;
197
198   g_object_class_install_property (gobject_class,
199       PROP_LABEL,
200       g_param_spec_string ("label",
201           "Label", "Data channel label",
202           NULL,
203           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
204
205   g_object_class_install_property (gobject_class,
206       PROP_ORDERED,
207       g_param_spec_boolean ("ordered",
208           "Ordered", "Using ordered transmission mode",
209           FALSE,
210           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
211
212   g_object_class_install_property (gobject_class,
213       PROP_MAX_PACKET_LIFETIME,
214       g_param_spec_int ("max-packet-lifetime",
215           "Maximum Packet Lifetime",
216           "Maximum number of milliseconds that transmissions and "
217           "retransmissions may occur in unreliable mode (-1 = unset)",
218           -1, G_MAXUINT16, -1,
219           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
220
221   g_object_class_install_property (gobject_class,
222       PROP_MAX_RETRANSMITS,
223       g_param_spec_int ("max-retransmits",
224           "Maximum Retransmits",
225           "Maximum number of retransmissions attempted in unreliable mode",
226           -1, G_MAXUINT16, 0,
227           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
228
229   g_object_class_install_property (gobject_class,
230       PROP_PROTOCOL,
231       g_param_spec_string ("protocol",
232           "Protocol", "Data channel protocol",
233           "",
234           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
235
236   g_object_class_install_property (gobject_class,
237       PROP_NEGOTIATED,
238       g_param_spec_boolean ("negotiated",
239           "Negotiated",
240           "Whether this data channel was negotiated by the application", FALSE,
241           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
242
243   g_object_class_install_property (gobject_class,
244       PROP_ID,
245       g_param_spec_int ("id",
246           "ID",
247           "ID negotiated by this data channel (-1 = unset)",
248           -1, G_MAXUINT16, -1,
249           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
250
251   g_object_class_install_property (gobject_class,
252       PROP_PRIORITY,
253       g_param_spec_enum ("priority",
254           "Priority",
255           "The priority of data sent using this data channel",
256           GST_TYPE_WEBRTC_PRIORITY_TYPE,
257           GST_WEBRTC_PRIORITY_TYPE_LOW,
258           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
259
260   g_object_class_install_property (gobject_class,
261       PROP_READY_STATE,
262       g_param_spec_enum ("ready-state",
263           "Ready State",
264           "The Ready state of this data channel",
265           GST_TYPE_WEBRTC_DATA_CHANNEL_STATE,
266           GST_WEBRTC_DATA_CHANNEL_STATE_CONNECTING,
267           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
268
269   g_object_class_install_property (gobject_class,
270       PROP_BUFFERED_AMOUNT,
271       g_param_spec_uint64 ("buffered-amount",
272           "Buffered Amount",
273           "The amount of data in bytes currently buffered",
274           0, G_MAXUINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
275
276   g_object_class_install_property (gobject_class,
277       PROP_BUFFERED_AMOUNT_LOW_THRESHOLD,
278       g_param_spec_uint64 ("buffered-amount-low-threshold",
279           "Buffered Amount Low Threshold",
280           "The threshold at which the buffered amount is considered low and "
281           "the buffered-amount-low signal is emitted",
282           0, G_MAXUINT64, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
283
284   /**
285    * GstWebRTCDataChannel::on-open:
286    * @object: the #GstWebRTCDataChannel
287    */
288   gst_webrtc_data_channel_signals[SIGNAL_ON_OPEN] =
289       g_signal_new ("on-open", G_TYPE_FROM_CLASS (klass),
290       G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
291
292   /**
293    * GstWebRTCDataChannel::on-close:
294    * @object: the #GstWebRTCDataChannel
295    */
296   gst_webrtc_data_channel_signals[SIGNAL_ON_CLOSE] =
297       g_signal_new ("on-close", G_TYPE_FROM_CLASS (klass),
298       G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
299
300   /**
301    * GstWebRTCDataChannel::on-error:
302    * @object: the #GstWebRTCDataChannel
303    * @error: the #GError thrown
304    */
305   gst_webrtc_data_channel_signals[SIGNAL_ON_ERROR] =
306       g_signal_new ("on-error", G_TYPE_FROM_CLASS (klass),
307       G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_ERROR);
308
309   /**
310    * GstWebRTCDataChannel::on-message-data:
311    * @object: the #GstWebRTCDataChannel
312    * @data: (nullable): a #GBytes of the data received
313    */
314   gst_webrtc_data_channel_signals[SIGNAL_ON_MESSAGE_DATA] =
315       g_signal_new ("on-message-data", G_TYPE_FROM_CLASS (klass),
316       G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_BYTES);
317
318   /**
319    * GstWebRTCDataChannel::on-message-string:
320    * @object: the #GstWebRTCDataChannel
321    * @data: (nullable): the data received as a string
322    */
323   gst_webrtc_data_channel_signals[SIGNAL_ON_MESSAGE_STRING] =
324       g_signal_new ("on-message-string", G_TYPE_FROM_CLASS (klass),
325       G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_STRING);
326
327   /**
328    * GstWebRTCDataChannel::on-buffered-amount-low:
329    * @object: the #GstWebRTCDataChannel
330    */
331   gst_webrtc_data_channel_signals[SIGNAL_ON_BUFFERED_AMOUNT_LOW] =
332       g_signal_new ("on-buffered-amount-low", G_TYPE_FROM_CLASS (klass),
333       G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
334
335   /**
336    * GstWebRTCDataChannel::send-data:
337    * @object: the #GstWebRTCDataChannel
338    * @data: (nullable): a #GBytes with the data
339    */
340   gst_webrtc_data_channel_signals[SIGNAL_SEND_DATA] =
341       g_signal_new_class_handler ("send-data", G_TYPE_FROM_CLASS (klass),
342       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
343       G_CALLBACK (gst_webrtc_data_channel_send_data), NULL, NULL, NULL,
344       G_TYPE_NONE, 1, G_TYPE_BYTES);
345
346   /**
347    * GstWebRTCDataChannel::send-string:
348    * @object: the #GstWebRTCDataChannel
349    * @data: (nullable): the data to send as a string
350    */
351   gst_webrtc_data_channel_signals[SIGNAL_SEND_STRING] =
352       g_signal_new_class_handler ("send-string", G_TYPE_FROM_CLASS (klass),
353       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
354       G_CALLBACK (gst_webrtc_data_channel_send_string), NULL, NULL, NULL,
355       G_TYPE_NONE, 1, G_TYPE_STRING);
356
357   /**
358    * GstWebRTCDataChannel::close:
359    * @object: the #GstWebRTCDataChannel
360    *
361    * Close the data channel
362    */
363   gst_webrtc_data_channel_signals[SIGNAL_CLOSE] =
364       g_signal_new_class_handler ("close", G_TYPE_FROM_CLASS (klass),
365       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
366       G_CALLBACK (gst_webrtc_data_channel_close), NULL, NULL, NULL,
367       G_TYPE_NONE, 0);
368 }
369
370 static void
371 gst_webrtc_data_channel_init (GstWebRTCDataChannel * channel)
372 {
373   g_mutex_init (&channel->lock);
374 }
375
376 /**
377  * gst_webrtc_data_channel_on_open:
378  * @channel: a #GstWebRTCDataChannel
379  *
380  * Signal that the data channel was opened. Should only be used by subclasses.
381  */
382 void
383 gst_webrtc_data_channel_on_open (GstWebRTCDataChannel * channel)
384 {
385   g_return_if_fail (GST_IS_WEBRTC_DATA_CHANNEL (channel));
386
387   GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
388   if (channel->ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_CLOSING ||
389       channel->ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_CLOSED) {
390     GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
391     return;
392   }
393
394   if (channel->ready_state != GST_WEBRTC_DATA_CHANNEL_STATE_OPEN) {
395     channel->ready_state = GST_WEBRTC_DATA_CHANNEL_STATE_OPEN;
396     GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
397     g_object_notify (G_OBJECT (channel), "ready-state");
398
399     GST_INFO_OBJECT (channel, "We are open and ready for data!");
400   } else {
401     GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
402   }
403
404   GST_INFO_OBJECT (channel, "Opened");
405
406   g_signal_emit (channel, gst_webrtc_data_channel_signals[SIGNAL_ON_OPEN], 0,
407       NULL);
408 }
409
410 /**
411  * gst_webrtc_data_channel_on_close:
412  * @channel: a #GstWebRTCDataChannel
413  *
414  * Signal that the data channel was closed. Should only be used by subclasses.
415  */
416 void
417 gst_webrtc_data_channel_on_close (GstWebRTCDataChannel * channel)
418 {
419   g_return_if_fail (GST_IS_WEBRTC_DATA_CHANNEL (channel));
420
421   GST_INFO_OBJECT (channel, "Closed");
422
423   GST_WEBRTC_DATA_CHANNEL_LOCK (channel);
424   if (channel->ready_state == GST_WEBRTC_DATA_CHANNEL_STATE_CLOSED) {
425     GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
426     return;
427   }
428
429   channel->ready_state = GST_WEBRTC_DATA_CHANNEL_STATE_CLOSED;
430   GST_WEBRTC_DATA_CHANNEL_UNLOCK (channel);
431
432   g_object_notify (G_OBJECT (channel), "ready-state");
433   GST_INFO_OBJECT (channel, "We are closed for data");
434
435   g_signal_emit (channel, gst_webrtc_data_channel_signals[SIGNAL_ON_CLOSE], 0,
436       NULL);
437 }
438
439 /**
440  * gst_webrtc_data_channel_on_error:
441  * @channel: a #GstWebRTCDataChannel
442  * @error: (transfer full): a #GError
443  *
444  * Signal that the data channel had an error. Should only be used by subclasses.
445  */
446 void
447 gst_webrtc_data_channel_on_error (GstWebRTCDataChannel * channel,
448     GError * error)
449 {
450   g_return_if_fail (GST_IS_WEBRTC_DATA_CHANNEL (channel));
451   g_return_if_fail (error != NULL);
452
453   GST_WARNING_OBJECT (channel, "Error: %s", GST_STR_NULL (error->message));
454
455   g_signal_emit (channel, gst_webrtc_data_channel_signals[SIGNAL_ON_ERROR], 0,
456       error);
457 }
458
459 /**
460  * gst_webrtc_data_channel_on_message_data:
461  * @channel: a #GstWebRTCDataChannel
462  * @data: (nullable): a #GBytes or %NULL
463  *
464  * Signal that the data channel received a data message. Should only be used by subclasses.
465  */
466 void
467 gst_webrtc_data_channel_on_message_data (GstWebRTCDataChannel * channel,
468     GBytes * data)
469 {
470   g_return_if_fail (GST_IS_WEBRTC_DATA_CHANNEL (channel));
471
472   GST_LOG_OBJECT (channel, "Have data %p", data);
473   g_signal_emit (channel,
474       gst_webrtc_data_channel_signals[SIGNAL_ON_MESSAGE_DATA], 0, data);
475 }
476
477 /**
478  * gst_webrtc_data_channel_on_message_string:
479  * @channel: a #GstWebRTCDataChannel
480  * @str: (nullable): a string or %NULL
481  *
482  * Signal that the data channel received a string message. Should only be used by subclasses.
483  */
484 void
485 gst_webrtc_data_channel_on_message_string (GstWebRTCDataChannel * channel,
486     const gchar * str)
487 {
488   g_return_if_fail (GST_IS_WEBRTC_DATA_CHANNEL (channel));
489
490   GST_LOG_OBJECT (channel, "Have string %p", str);
491   g_signal_emit (channel,
492       gst_webrtc_data_channel_signals[SIGNAL_ON_MESSAGE_STRING], 0, str);
493 }
494
495 /**
496  * gst_webrtc_data_channel_on_buffered_amount_low:
497  * @channel: a #GstWebRTCDataChannel
498  *
499  * Signal that the data channel reached a low buffered amount. Should only be used by subclasses.
500  */
501 void
502 gst_webrtc_data_channel_on_buffered_amount_low (GstWebRTCDataChannel * channel)
503 {
504   g_return_if_fail (GST_IS_WEBRTC_DATA_CHANNEL (channel));
505
506   GST_LOG_OBJECT (channel, "Low threshold reached");
507   g_signal_emit (channel,
508       gst_webrtc_data_channel_signals[SIGNAL_ON_BUFFERED_AMOUNT_LOW], 0);
509 }
510
511 /**
512  * gst_webrtc_data_channel_send_data:
513  * @channel: a #GstWebRTCDataChannel
514  * @data: (nullable): a #GBytes or %NULL
515  *
516  * Send @data as a data message over @channel.
517  */
518 void
519 gst_webrtc_data_channel_send_data (GstWebRTCDataChannel * channel,
520     GBytes * data)
521 {
522   GstWebRTCDataChannelClass *klass;
523
524   g_return_if_fail (GST_IS_WEBRTC_DATA_CHANNEL (channel));
525
526   klass = GST_WEBRTC_DATA_CHANNEL_GET_CLASS (channel);
527   klass->send_data (channel, data);
528 }
529
530 /**
531  * gst_webrtc_data_channel_send_string:
532  * @channel: a #GstWebRTCDataChannel
533  * @str: (nullable): a string or %NULL
534  *
535  * Send @str as a string message over @channel.
536  */
537 void
538 gst_webrtc_data_channel_send_string (GstWebRTCDataChannel * channel,
539     const gchar * str)
540 {
541   GstWebRTCDataChannelClass *klass;
542
543   g_return_if_fail (GST_IS_WEBRTC_DATA_CHANNEL (channel));
544
545   klass = GST_WEBRTC_DATA_CHANNEL_GET_CLASS (channel);
546   klass->send_string (channel, str);
547 }
548
549 /**
550  * gst_webrtc_data_channel_close:
551  * @channel: a #GstWebRTCDataChannel
552  *
553  * Close the @channel.
554  */
555 void
556 gst_webrtc_data_channel_close (GstWebRTCDataChannel * channel)
557 {
558   GstWebRTCDataChannelClass *klass;
559
560   g_return_if_fail (GST_IS_WEBRTC_DATA_CHANNEL (channel));
561
562   klass = GST_WEBRTC_DATA_CHANNEL_GET_CLASS (channel);
563   klass->close (channel);
564 }