1use crate::agent::{AgentError, AgentTransmit};
12use crate::candidate::{CandidatePair, TransportType};
13use crate::{const_override, mut_override, Address};
14
15#[derive(Debug)]
17pub struct Component {
18 ffi: *mut crate::ffi::RiceComponent,
19 stream_id: usize,
20}
21
22unsafe impl Send for Component {}
23unsafe impl Sync for Component {}
24
25impl Clone for Component {
26 fn clone(&self) -> Self {
27 Self {
28 ffi: unsafe { crate::ffi::rice_component_ref(self.ffi) },
29 stream_id: self.stream_id,
30 }
31 }
32}
33
34impl Drop for Component {
35 fn drop(&mut self) {
36 unsafe { crate::ffi::rice_component_unref(self.ffi) }
37 }
38}
39
40impl Component {
41 pub(crate) fn from_c_full(component: *mut crate::ffi::RiceComponent, stream_id: usize) -> Self {
42 Self {
43 ffi: component,
44 stream_id,
45 }
46 }
47
48 pub fn id(&self) -> usize {
50 unsafe { crate::ffi::rice_component_get_id(self.ffi) }
51 }
52
53 pub fn state(&self) -> ComponentConnectionState {
55 unsafe { crate::ffi::rice_component_get_state(self.ffi).into() }
56 }
57
58 pub fn selected_pair(&self) -> Option<CandidatePair> {
61 unsafe {
62 let mut local = crate::ffi::RiceCandidate::zeroed();
63 let mut remote = crate::ffi::RiceCandidate::zeroed();
64 crate::ffi::rice_component_selected_pair(self.ffi, &mut local, &mut remote);
65 if local.address.is_null() || remote.address.is_null() {
66 None
67 } else {
68 Some(crate::candidate::CandidatePair::new(
69 crate::candidate::Candidate::from_c_full(local).to_owned(),
70 crate::candidate::Candidate::from_c_full(remote).to_owned(),
71 ))
72 }
73 }
74 }
75
76 pub fn gather_candidates(
80 &self,
81 sockets: impl IntoIterator<Item = (TransportType, Address)>,
82 ) -> Result<(), AgentError> {
83 let mut transports = vec![];
84 let mut socket_addr = vec![];
85 let mut socket_addresses = vec![];
86 for (ttype, addr) in sockets.into_iter() {
87 transports.push(ttype.into());
88 socket_addresses.push(const_override(addr.ffi));
89 socket_addr.push(addr);
90 }
91 unsafe {
92 AgentError::from_c(crate::ffi::rice_component_gather_candidates(
93 self.ffi,
94 transports.len(),
95 socket_addresses.as_ptr(),
96 transports.as_ptr(),
97 ))
98 }
99 }
100
101 pub fn set_selected_pair(&self, pair: CandidatePair) -> Result<(), AgentError> {
104 unsafe {
105 AgentError::from_c(crate::ffi::rice_component_set_selected_pair(
106 self.ffi,
107 pair.local.as_c(),
108 pair.remote.as_c(),
109 ))
110 }
111 }
112
113 pub fn send(&self, data: &[u8], now_micros: u64) -> Result<AgentTransmit, AgentError> {
116 unsafe {
117 let mut transmit = crate::ffi::RiceTransmit {
118 stream_id: self.stream_id,
119 transport: TransportType::Udp.into(),
120 from: core::ptr::null(),
121 to: core::ptr::null(),
122 data: crate::ffi::RiceDataImpl {
123 ptr: core::ptr::null_mut(),
124 size: 0,
125 },
126 };
127 AgentError::from_c(crate::ffi::rice_component_send(
128 self.ffi,
129 mut_override(data.as_ptr()),
130 data.len(),
131 now_micros,
132 &mut transmit,
133 ))?;
134 Ok(AgentTransmit::from_c_full(transmit))
135 }
136 }
137}
138
139#[repr(u32)]
141#[derive(Debug, Copy, Clone, PartialEq, Eq)]
142pub enum ComponentConnectionState {
143 New = crate::ffi::RICE_COMPONENT_CONNECTION_STATE_NEW,
145 Connecting = crate::ffi::RICE_COMPONENT_CONNECTION_STATE_CONNECTING,
147 Connected = crate::ffi::RICE_COMPONENT_CONNECTION_STATE_CONNECTED,
149 Failed = crate::ffi::RICE_COMPONENT_CONNECTION_STATE_FAILED,
151}
152
153impl ComponentConnectionState {
154 pub(crate) fn from_c(ffi: crate::ffi::RiceComponentConnectionState) -> Self {
155 match ffi {
156 crate::ffi::RICE_COMPONENT_CONNECTION_STATE_NEW => Self::New,
157 crate::ffi::RICE_COMPONENT_CONNECTION_STATE_CONNECTING => Self::Connecting,
158 crate::ffi::RICE_COMPONENT_CONNECTION_STATE_CONNECTED => Self::Connected,
159 crate::ffi::RICE_COMPONENT_CONNECTION_STATE_FAILED => Self::Failed,
160 _ => panic!("Unknown RiceComponentConnectionState value {ffi:x?}"),
161 }
162 }
163}
164
165impl From<crate::ffi::RiceComponentConnectionState> for ComponentConnectionState {
166 fn from(value: crate::ffi::RiceComponentConnectionState) -> Self {
167 match value {
168 crate::ffi::RICE_COMPONENT_CONNECTION_STATE_NEW => Self::New,
169 crate::ffi::RICE_COMPONENT_CONNECTION_STATE_CONNECTING => Self::Connecting,
170 crate::ffi::RICE_COMPONENT_CONNECTION_STATE_CONNECTED => Self::Connected,
171 crate::ffi::RICE_COMPONENT_CONNECTION_STATE_FAILED => Self::Failed,
172 val => panic!("Unknown component connection state value {val:x?}"),
173 }
174 }
175}