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