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