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")]
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    }
96
97    extern "C++" {
98        include!("livekit/rtc_error.h");
99        include!("livekit/helper.h");
100        include!("livekit/candidate.h");
101        include!("livekit/media_stream.h");
102        include!("livekit/rtp_transceiver.h");
103        include!("livekit/rtp_sender.h");
104        include!("livekit/rtp_receiver.h");
105        include!("livekit/data_channel.h");
106        include!("livekit/jsep.h");
107        include!("livekit/webrtc.h");
108
109        type RtpSenderPtr = crate::helper::ffi::RtpSenderPtr;
110        type RtpReceiverPtr = crate::helper::ffi::RtpReceiverPtr;
111        type RtpTransceiverPtr = crate::helper::ffi::RtpTransceiverPtr;
112        type RtcError = crate::rtc_error::ffi::RtcError;
113        type Candidate = crate::candidate::ffi::Candidate;
114        type IceCandidate = crate::jsep::ffi::IceCandidate;
115        type DataChannel = crate::data_channel::ffi::DataChannel;
116        type DataChannelInit = crate::data_channel::ffi::DataChannelInit;
117        type RtpSender = crate::rtp_sender::ffi::RtpSender;
118        type RtpReceiver = crate::rtp_receiver::ffi::RtpReceiver;
119        type RtpTransceiver = crate::rtp_transceiver::ffi::RtpTransceiver;
120        type RtpTransceiverInit = crate::rtp_transceiver::ffi::RtpTransceiverInit;
121        type MediaStream = crate::media_stream::ffi::MediaStream;
122        type MediaStreamTrack = crate::media_stream::ffi::MediaStreamTrack;
123        type SessionDescription = crate::jsep::ffi::SessionDescription;
124        type MediaType = crate::webrtc::ffi::MediaType;
125    }
126
127    unsafe extern "C++" {
128        include!("livekit/peer_connection.h");
129
130        type PeerConnection;
131
132        fn set_configuration(self: &PeerConnection, config: RtcConfiguration) -> Result<()>;
133
134        fn create_offer(
135            self: &PeerConnection,
136            options: RtcOfferAnswerOptions,
137            ctx: Box<PeerContext>,
138            on_success: fn(ctx: Box<PeerContext>, sdp: UniquePtr<SessionDescription>),
139            on_error: fn(ctx: Box<PeerContext>, error: RtcError),
140        );
141        fn create_answer(
142            self: &PeerConnection,
143            options: RtcOfferAnswerOptions,
144            ctx: Box<PeerContext>,
145            on_success: fn(ctx: Box<PeerContext>, sdp: UniquePtr<SessionDescription>),
146            on_error: fn(ctx: Box<PeerContext>, error: RtcError),
147        );
148        fn set_local_description(
149            self: &PeerConnection,
150            desc: UniquePtr<SessionDescription>,
151            ctx: Box<PeerContext>,
152            on_complete: fn(ctx: Box<PeerContext>, error: RtcError),
153        );
154        fn set_remote_description(
155            self: &PeerConnection,
156            desc: UniquePtr<SessionDescription>,
157            ctx: Box<PeerContext>,
158            on_complete: fn(ctx: Box<PeerContext>, error: RtcError),
159        );
160        fn add_track(
161            self: &PeerConnection,
162            track: SharedPtr<MediaStreamTrack>,
163            stream_ids: &Vec<String>,
164        ) -> Result<SharedPtr<RtpSender>>;
165        fn remove_track(self: &PeerConnection, sender: SharedPtr<RtpSender>) -> Result<()>;
166        fn get_stats(
167            self: &PeerConnection,
168            ctx: Box<PeerContext>,
169            on_stats: fn(ctx: Box<PeerContext>, json: String),
170        );
171        fn add_transceiver(
172            self: &PeerConnection,
173            track: SharedPtr<MediaStreamTrack>,
174            init: RtpTransceiverInit,
175        ) -> Result<SharedPtr<RtpTransceiver>>;
176        fn add_transceiver_for_media(
177            self: &PeerConnection,
178            media_type: MediaType,
179            init: RtpTransceiverInit,
180        ) -> Result<SharedPtr<RtpTransceiver>>;
181        fn get_senders(self: &PeerConnection) -> Vec<RtpSenderPtr>;
182        fn get_receivers(self: &PeerConnection) -> Vec<RtpReceiverPtr>;
183        fn get_transceivers(self: &PeerConnection) -> Vec<RtpTransceiverPtr>;
184        fn create_data_channel(
185            self: &PeerConnection,
186            label: String,
187            init: DataChannelInit,
188        ) -> Result<SharedPtr<DataChannel>>;
189        fn add_ice_candidate(
190            self: &PeerConnection,
191            candidate: SharedPtr<IceCandidate>,
192            ctx: Box<PeerContext>,
193            on_complete: fn(ctx: Box<PeerContext>, error: RtcError),
194        );
195        fn restart_ice(self: &PeerConnection);
196        fn current_local_description(self: &PeerConnection) -> UniquePtr<SessionDescription>;
197        fn current_remote_description(self: &PeerConnection) -> UniquePtr<SessionDescription>;
198        fn connection_state(self: &PeerConnection) -> PeerConnectionState;
199        fn signaling_state(self: &PeerConnection) -> SignalingState;
200        fn ice_gathering_state(self: &PeerConnection) -> IceGatheringState;
201        fn ice_connection_state(self: &PeerConnection) -> IceConnectionState;
202        fn close(self: &PeerConnection);
203
204        fn _shared_peer_connection() -> SharedPtr<PeerConnection>; // Ignore
205    }
206
207    extern "Rust" {
208        type PeerContext;
209    }
210}
211
212#[repr(transparent)]
213pub struct PeerContext(pub Box<dyn Any + Send>);
214
215// https://webrtc.github.io/webrtc-org/native-code/native-apis/
216impl_thread_safety!(ffi::PeerConnection, Send + Sync);
217
218impl Default for ffi::RtcOfferAnswerOptions {
219    // static const int kUndefined = -1;
220    // static const int kMaxOfferToReceiveMedia = 1;
221    // static const int kOfferToReceiveMediaTrue = 1;
222
223    fn default() -> Self {
224        Self {
225            offer_to_receive_video: -1,
226            offer_to_receive_audio: -1,
227            voice_activity_detection: true,
228            ice_restart: false,
229            use_rtp_mux: true,
230            raw_packetization_for_video: false,
231            num_simulcast_layers: 1,
232            use_obsolete_sctp_sdp: false,
233        }
234    }
235}