Skip to main content

gosuto_libwebrtc/
data_channel.rs

1// Copyright 2025 LiveKit, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::{fmt::Debug, str::Utf8Error};
16
17use serde::Deserialize;
18use thiserror::Error;
19
20use crate::{imp::data_channel as dc_imp, rtp_parameters::Priority};
21
22#[derive(Clone, Debug)]
23pub struct DataChannelInit {
24    pub ordered: bool,
25    pub max_retransmit_time: Option<i32>,
26    pub max_retransmits: Option<i32>,
27    pub protocol: String,
28    pub negotiated: bool,
29    pub id: i32,
30    pub priority: Option<Priority>,
31}
32
33impl Default for DataChannelInit {
34    fn default() -> Self {
35        Self {
36            ordered: true,
37            max_retransmit_time: None,
38            max_retransmits: None,
39            protocol: String::new(),
40            negotiated: false,
41            id: -1,
42            priority: None,
43        }
44    }
45}
46
47#[derive(Debug, Error)]
48pub enum DataChannelError {
49    #[error("failed to send data, dc not open? send buffer is full ?")]
50    Send,
51    #[error("only utf8 strings can be sent")]
52    Utf8(#[from] Utf8Error),
53}
54
55#[derive(Debug, Copy, Clone, PartialEq, Eq, Deserialize)]
56#[serde(rename_all = "lowercase")]
57pub enum DataChannelState {
58    Connecting,
59    Open,
60    Closing,
61    Closed,
62}
63
64#[derive(Debug)]
65pub struct DataBuffer<'a> {
66    pub data: &'a [u8],
67    pub binary: bool,
68}
69
70pub type OnStateChange = Box<dyn FnMut(DataChannelState) + Send + Sync>;
71pub type OnMessage = Box<dyn FnMut(DataBuffer) + Send + Sync>;
72pub type OnBufferedAmountChange = Box<dyn FnMut(u64) + Send + Sync>;
73
74#[derive(Clone)]
75pub struct DataChannel {
76    pub(crate) handle: dc_imp::DataChannel,
77}
78
79impl DataChannel {
80    pub fn send(&self, data: &[u8], binary: bool) -> Result<(), DataChannelError> {
81        self.handle.send(data, binary)
82    }
83
84    pub fn id(&self) -> i32 {
85        self.handle.id()
86    }
87
88    pub fn label(&self) -> String {
89        self.handle.label()
90    }
91
92    pub fn state(&self) -> DataChannelState {
93        self.handle.state()
94    }
95
96    pub fn close(&self) {
97        self.handle.close()
98    }
99
100    pub fn buffered_amount(&self) -> u64 {
101        self.handle.buffered_amount()
102    }
103
104    pub fn on_state_change(&self, callback: Option<OnStateChange>) {
105        self.handle.on_state_change(callback)
106    }
107
108    pub fn on_message(&self, callback: Option<OnMessage>) {
109        self.handle.on_message(callback)
110    }
111
112    pub fn on_buffered_amount_change(&self, callback: Option<OnBufferedAmountChange>) {
113        self.handle.on_buffered_amount_change(callback)
114    }
115}
116
117impl Debug for DataChannel {
118    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
119        f.debug_struct("DataChannel")
120            .field("id", &self.id())
121            .field("label", &self.label())
122            .field("state", &self.state())
123            .finish()
124    }
125}