Skip to main content

webrtc_sys/
peer_connection.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::any::Any;
16
17use crate::impl_thread_safety;
18
19#[cxx::bridge(namespace = "livekit_ffi")]
20pub mod ffi {
21    #[repr(i32)]
22    pub enum PeerConnectionState {
23        New,
24        Connecting,
25        Connected,
26        Disconnected,
27        Failed,
28        Closed,
29    }
30
31    #[repr(i32)]
32    pub enum SignalingState {
33        Stable,
34        HaveLocalOffer,
35        HaveLocalPrAnswer,
36        HaveRemoteOffer,
37        HaveRemotePrAnswer,
38        Closed,
39    }
40
41    #[repr(i32)]
42    pub enum IceConnectionState {
43        IceConnectionNew,
44        IceConnectionChecking,
45        IceConnectionConnected,
46        IceConnectionCompleted,
47        IceConnectionFailed,
48        IceConnectionDisconnected,
49        IceConnectionClosed,
50        IceConnectionMax,
51    }
52
53    #[repr(i32)]
54    pub enum IceGatheringState {
55        IceGatheringNew,
56        IceGatheringGathering,
57        IceGatheringComplete,
58    }
59
60    #[repr(i32)]
61    pub enum ContinualGatheringPolicy {
62        GatherOnce,
63        GatherContinually,
64    }
65
66    #[repr(i32)]
67    pub enum IceTransportsType {
68        None,
69        Relay,
70        NoHost,
71        All,
72    }
73
74    pub struct RtcOfferAnswerOptions {
75        offer_to_receive_video: i32,
76        offer_to_receive_audio: i32,
77        voice_activity_detection: bool,
78        ice_restart: bool,
79        use_rtp_mux: bool,
80        raw_packetization_for_video: bool,
81        num_simulcast_layers: i32,
82        use_obsolete_sctp_sdp: bool,
83    }
84
85    pub struct IceServer {
86        pub urls: Vec<String>,
87        pub username: String,
88        pub password: String,
89    }
90
91    pub struct RtcConfiguration {
92        pub ice_servers: Vec<IceServer>,
93        pub continual_gathering_policy: ContinualGatheringPolicy,
94        pub ice_transport_type: IceTransportsType,
95        // WARP/SNAP: enable SCTP-INIT-in-SDP. Must be carried consistently across
96        // create + set_configuration (it is an immutable RTCConfiguration field).
97        pub enable_sctp_snap: bool,
98    }
99
100    extern "C++" {
101        include!("livekit/rtc_error.h");
102        include!("livekit/helper.h");
103        include!("livekit/candidate.h");
104        include!("livekit/media_stream.h");
105        include!("livekit/rtp_transceiver.h");
106        include!("livekit/rtp_sender.h");
107        include!("livekit/rtp_receiver.h");
108        include!("livekit/data_channel.h");
109        include!("livekit/jsep.h");
110        include!("livekit/webrtc.h");
111
112        type RtpSenderPtr = crate::helper::ffi::RtpSenderPtr;
113        type RtpReceiverPtr = crate::helper::ffi::RtpReceiverPtr;
114        type RtpTransceiverPtr = crate::helper::ffi::RtpTransceiverPtr;
115        type RtcError = crate::rtc_error::ffi::RtcError;
116        type Candidate = crate::candidate::ffi::Candidate;
117        type IceCandidate = crate::jsep::ffi::IceCandidate;
118        type DataChannel = crate::data_channel::ffi::DataChannel;
119        type DataChannelInit = crate::data_channel::ffi::DataChannelInit;
120        type RtpSender = crate::rtp_sender::ffi::RtpSender;
121        type RtpReceiver = crate::rtp_receiver::ffi::RtpReceiver;
122        type RtpTransceiver = crate::rtp_transceiver::ffi::RtpTransceiver;
123        type RtpTransceiverInit = crate::rtp_transceiver::ffi::RtpTransceiverInit;
124        type MediaStream = crate::media_stream::ffi::MediaStream;
125        type MediaStreamTrack = crate::media_stream::ffi::MediaStreamTrack;
126        type SessionDescription = crate::jsep::ffi::SessionDescription;
127        type MediaType = crate::webrtc::ffi::MediaType;
128    }
129
130    unsafe extern "C++" {
131        include!("livekit/peer_connection.h");
132
133        type PeerConnection;
134
135        fn set_configuration(self: &PeerConnection, config: RtcConfiguration) -> Result<()>;
136
137        fn create_offer(
138            self: &PeerConnection,
139            options: RtcOfferAnswerOptions,
140            ctx: Box<PeerContext>,
141            on_success: fn(ctx: Box<PeerContext>, sdp: UniquePtr<SessionDescription>),
142            on_error: fn(ctx: Box<PeerContext>, error: RtcError),
143        );
144        fn create_answer(
145            self: &PeerConnection,
146            options: RtcOfferAnswerOptions,
147            ctx: Box<PeerContext>,
148            on_success: fn(ctx: Box<PeerContext>, sdp: UniquePtr<SessionDescription>),
149            on_error: fn(ctx: Box<PeerContext>, error: RtcError),
150        );
151        fn set_local_description(
152            self: &PeerConnection,
153            desc: UniquePtr<SessionDescription>,
154            ctx: Box<PeerContext>,
155            on_complete: fn(ctx: Box<PeerContext>, error: RtcError),
156        );
157        fn set_remote_description(
158            self: &PeerConnection,
159            desc: UniquePtr<SessionDescription>,
160            ctx: Box<PeerContext>,
161            on_complete: fn(ctx: Box<PeerContext>, error: RtcError),
162        );
163        fn add_track(
164            self: &PeerConnection,
165            track: SharedPtr<MediaStreamTrack>,
166            stream_ids: &Vec<String>,
167        ) -> Result<SharedPtr<RtpSender>>;
168        fn remove_track(self: &PeerConnection, sender: SharedPtr<RtpSender>) -> Result<()>;
169        fn get_stats(
170            self: &PeerConnection,
171            ctx: Box<PeerContext>,
172            on_stats: fn(ctx: Box<PeerContext>, json: String),
173        );
174        fn add_transceiver(
175            self: &PeerConnection,
176            track: SharedPtr<MediaStreamTrack>,
177            init: RtpTransceiverInit,
178        ) -> Result<SharedPtr<RtpTransceiver>>;
179        fn add_transceiver_for_media(
180            self: &PeerConnection,
181            media_type: MediaType,
182            init: RtpTransceiverInit,
183        ) -> Result<SharedPtr<RtpTransceiver>>;
184        fn get_senders(self: &PeerConnection) -> Vec<RtpSenderPtr>;
185        fn get_receivers(self: &PeerConnection) -> Vec<RtpReceiverPtr>;
186        fn get_transceivers(self: &PeerConnection) -> Vec<RtpTransceiverPtr>;
187        fn create_data_channel(
188            self: &PeerConnection,
189            label: String,
190            init: DataChannelInit,
191        ) -> Result<SharedPtr<DataChannel>>;
192        fn add_ice_candidate(
193            self: &PeerConnection,
194            candidate: SharedPtr<IceCandidate>,
195            ctx: Box<PeerContext>,
196            on_complete: fn(ctx: Box<PeerContext>, error: RtcError),
197        );
198        fn restart_ice(self: &PeerConnection);
199        fn current_local_description(self: &PeerConnection) -> UniquePtr<SessionDescription>;
200        fn current_remote_description(self: &PeerConnection) -> UniquePtr<SessionDescription>;
201        fn connection_state(self: &PeerConnection) -> PeerConnectionState;
202        fn signaling_state(self: &PeerConnection) -> SignalingState;
203        fn ice_gathering_state(self: &PeerConnection) -> IceGatheringState;
204        fn ice_connection_state(self: &PeerConnection) -> IceConnectionState;
205        fn close(self: &PeerConnection);
206
207        fn _shared_peer_connection() -> SharedPtr<PeerConnection>; // Ignore
208    }
209
210    extern "Rust" {
211        type PeerContext;
212    }
213}
214
215#[repr(transparent)]
216pub struct PeerContext(pub Box<dyn Any + Send>);
217
218// https://webrtc.github.io/webrtc-org/native-code/native-apis/
219impl_thread_safety!(ffi::PeerConnection, Send + Sync);
220
221impl Default for ffi::RtcOfferAnswerOptions {
222    // static const int kUndefined = -1;
223    // static const int kMaxOfferToReceiveMedia = 1;
224    // static const int kOfferToReceiveMediaTrue = 1;
225
226    fn default() -> Self {
227        Self {
228            offer_to_receive_video: -1,
229            offer_to_receive_audio: -1,
230            voice_activity_detection: true,
231            ice_restart: false,
232            use_rtp_mux: true,
233            raw_packetization_for_video: false,
234            num_simulcast_layers: 1,
235            use_obsolete_sctp_sdp: false,
236        }
237    }
238}