1use 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 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>; }
209
210 extern "Rust" {
211 type PeerContext;
212 }
213}
214
215#[repr(transparent)]
216pub struct PeerContext(pub Box<dyn Any + Send>);
217
218impl_thread_safety!(ffi::PeerConnection, Send + Sync);
220
221impl Default for ffi::RtcOfferAnswerOptions {
222 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}