Skip to main content

webrtc_sys/
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::sync::Arc;
16
17use crate::impl_thread_safety;
18
19#[cxx::bridge(namespace = "livekit_ffi")]
20pub mod ffi {
21    #[derive(Debug)]
22    #[repr(i32)]
23    pub enum Priority {
24        VeryLow,
25        Low,
26        Medium,
27        High,
28    }
29
30    #[derive(Debug)]
31    pub struct DataChannelInit {
32        pub ordered: bool,
33        pub has_max_retransmit_time: bool,
34        pub max_retransmit_time: i32,
35        pub has_max_retransmits: bool,
36        pub max_retransmits: i32,
37        pub protocol: String,
38        pub negotiated: bool,
39        pub id: i32,
40        pub has_priority: bool,
41        pub priority: Priority,
42    }
43
44    #[derive(Debug)]
45    pub struct DataBuffer {
46        pub ptr: *const u8,
47        pub len: usize,
48        pub binary: bool,
49    }
50
51    #[derive(Debug)]
52    #[repr(i32)]
53    pub enum DataState {
54        Connecting,
55        Open,
56        Closing,
57        Closed,
58    }
59
60    unsafe extern "C++" {
61        include!("livekit/data_channel.h");
62
63        type DataChannel;
64
65        fn register_observer(self: &DataChannel, observer: Box<DataChannelObserverWrapper>);
66        fn unregister_observer(self: &DataChannel);
67
68        fn send(self: &DataChannel, data: &DataBuffer) -> bool;
69        fn id(self: &DataChannel) -> i32;
70        fn label(self: &DataChannel) -> String;
71        fn state(self: &DataChannel) -> DataState;
72        fn close(self: &DataChannel);
73        fn buffered_amount(self: &DataChannel) -> u64;
74
75        fn _shared_data_channel() -> SharedPtr<DataChannel>; // Ignore
76    }
77
78    extern "Rust" {
79        type DataChannelObserverWrapper;
80
81        fn on_state_change(self: &DataChannelObserverWrapper, state: DataState);
82        fn on_message(self: &DataChannelObserverWrapper, buffer: DataBuffer);
83        fn on_buffered_amount_change(self: &DataChannelObserverWrapper, sent_data_size: u64);
84    }
85}
86
87impl_thread_safety!(ffi::DataChannel, Send + Sync);
88
89pub trait DataChannelObserver: Send + Sync {
90    fn on_state_change(&self, state: ffi::DataState);
91    fn on_message(&self, data: &[u8], is_binary: bool);
92    fn on_buffered_amount_change(&self, sent_data_size: u64);
93}
94
95pub struct DataChannelObserverWrapper {
96    observer: Arc<dyn DataChannelObserver>,
97}
98
99impl DataChannelObserverWrapper {
100    pub fn new(observer: Arc<dyn DataChannelObserver>) -> Self {
101        Self { observer }
102    }
103
104    fn on_state_change(&self, state: ffi::DataState) {
105        self.observer.on_state_change(state);
106    }
107
108    fn on_message(&self, buffer: ffi::DataBuffer) {
109        unsafe {
110            let data = std::slice::from_raw_parts(buffer.ptr, buffer.len);
111            self.observer.on_message(data, buffer.binary);
112        }
113    }
114
115    fn on_buffered_amount_change(&self, sent_data_size: u64) {
116        self.observer.on_buffered_amount_change(sent_data_size);
117    }
118}