1use sans_io_time::Instant;
14
15use crate::agent::{AgentError, AgentTransmit};
16use crate::candidate::{CandidatePair, TransportType};
17use crate::turn::TurnConfig;
18use crate::{Address, const_override, mut_override};
19
20#[derive(Debug)]
22pub struct Component {
23 ffi: *mut crate::ffi::RiceComponent,
24 stream_id: usize,
25}
26
27unsafe impl Send for Component {}
28unsafe impl Sync for Component {}
29
30impl Clone for Component {
31 fn clone(&self) -> Self {
32 Self {
33 ffi: unsafe { crate::ffi::rice_component_ref(self.ffi) },
34 stream_id: self.stream_id,
35 }
36 }
37}
38
39impl Drop for Component {
40 fn drop(&mut self) {
41 unsafe { crate::ffi::rice_component_unref(self.ffi) }
42 }
43}
44
45impl Component {
46 pub(crate) fn from_c_full(component: *mut crate::ffi::RiceComponent, stream_id: usize) -> Self {
47 Self {
48 ffi: component,
49 stream_id,
50 }
51 }
52
53 pub fn id(&self) -> usize {
55 unsafe { crate::ffi::rice_component_get_id(self.ffi) }
56 }
57
58 pub fn stream(&self) -> crate::stream::Stream {
60 unsafe {
61 crate::stream::Stream::from_c_full(crate::ffi::rice_component_get_stream(self.ffi))
62 }
63 }
64
65 pub fn state(&self) -> ComponentConnectionState {
67 unsafe { crate::ffi::rice_component_get_state(self.ffi).into() }
68 }
69
70 pub fn selected_pair(&self) -> Option<CandidatePair> {
73 unsafe {
74 let mut local = crate::ffi::RiceCandidate::zeroed();
75 let mut remote = crate::ffi::RiceCandidate::zeroed();
76 crate::ffi::rice_component_selected_pair(self.ffi, &mut local, &mut remote);
77 if local.address.is_null() || remote.address.is_null() {
78 None
79 } else {
80 Some(crate::candidate::CandidatePair::new(
81 crate::candidate::Candidate::from_c_full(local).to_owned(),
82 crate::candidate::Candidate::from_c_full(remote).to_owned(),
83 ))
84 }
85 }
86 }
87
88 pub fn gather_candidates<'a, 'b>(
105 &self,
106 sockets: impl IntoIterator<Item = (TransportType, &'a Address)>,
107 turn_servers: impl IntoIterator<Item = (&'b Address, TurnConfig)>,
108 ) -> Result<(), AgentError> {
109 unsafe {
110 let mut transports = vec![];
111 let mut socket_addr = vec![];
112 let mut socket_addresses = vec![];
113 for (ttype, addr) in sockets.into_iter() {
114 transports.push(ttype.into());
115 socket_addresses.push(const_override(addr.ffi));
116 socket_addr.push(addr);
117 }
118 let mut turn_sockets = vec![];
119 let mut turn_configs = vec![];
120 for (turn_addr, config) in turn_servers.into_iter() {
121 turn_sockets.push(const_override(turn_addr.ffi));
122 turn_configs.push(config.into_c_full());
123 }
124 AgentError::from_c(crate::ffi::rice_component_gather_candidates(
125 self.ffi,
126 transports.len(),
127 socket_addresses.as_ptr(),
128 transports.as_ptr(),
129 turn_sockets.len(),
130 turn_sockets.as_ptr(),
131 turn_configs.as_ptr(),
132 ))
133 }
134 }
135
136 pub fn set_selected_pair(&self, pair: CandidatePair) -> Result<(), AgentError> {
139 unsafe {
140 AgentError::from_c(crate::ffi::rice_component_set_selected_pair(
141 self.ffi,
142 pair.local.as_c(),
143 pair.remote.as_c(),
144 ))
145 }
146 }
147
148 pub fn send(&self, data: &[u8], now: Instant) -> Result<AgentTransmit, AgentError> {
151 unsafe {
152 let mut transmit = crate::ffi::RiceTransmit {
153 stream_id: self.stream_id,
154 transport: TransportType::Udp.into(),
155 from: core::ptr::null(),
156 to: core::ptr::null(),
157 data: crate::ffi::RiceDataImpl {
158 ptr: core::ptr::null_mut(),
159 size: 0,
160 },
161 };
162 AgentError::from_c(crate::ffi::rice_component_send(
163 self.ffi,
164 mut_override(data.as_ptr()),
165 data.len(),
166 now.as_nanos(),
167 &mut transmit,
168 ))?;
169 Ok(AgentTransmit::from_c_full(transmit))
170 }
171 }
172}
173
174#[repr(u32)]
176#[derive(Debug, Copy, Clone, PartialEq, Eq)]
177pub enum ComponentConnectionState {
178 New = crate::ffi::RICE_COMPONENT_CONNECTION_STATE_NEW,
180 Connecting = crate::ffi::RICE_COMPONENT_CONNECTION_STATE_CONNECTING,
182 Connected = crate::ffi::RICE_COMPONENT_CONNECTION_STATE_CONNECTED,
184 Failed = crate::ffi::RICE_COMPONENT_CONNECTION_STATE_FAILED,
186}
187
188impl ComponentConnectionState {
189 pub(crate) fn from_c(ffi: crate::ffi::RiceComponentConnectionState) -> Self {
190 match ffi {
191 crate::ffi::RICE_COMPONENT_CONNECTION_STATE_NEW => Self::New,
192 crate::ffi::RICE_COMPONENT_CONNECTION_STATE_CONNECTING => Self::Connecting,
193 crate::ffi::RICE_COMPONENT_CONNECTION_STATE_CONNECTED => Self::Connected,
194 crate::ffi::RICE_COMPONENT_CONNECTION_STATE_FAILED => Self::Failed,
195 _ => panic!("Unknown RiceComponentConnectionState value {ffi:x?}"),
196 }
197 }
198}
199
200impl From<crate::ffi::RiceComponentConnectionState> for ComponentConnectionState {
201 fn from(value: crate::ffi::RiceComponentConnectionState) -> Self {
202 match value {
203 crate::ffi::RICE_COMPONENT_CONNECTION_STATE_NEW => Self::New,
204 crate::ffi::RICE_COMPONENT_CONNECTION_STATE_CONNECTING => Self::Connecting,
205 crate::ffi::RICE_COMPONENT_CONNECTION_STATE_CONNECTED => Self::Connected,
206 crate::ffi::RICE_COMPONENT_CONNECTION_STATE_FAILED => Self::Failed,
207 val => panic!("Unknown component connection state value {val:x?}"),
208 }
209 }
210}