1#![deny(unsafe_op_in_unsafe_fn, missing_docs)]
7
8mod wire;
9
10use fuchsia_sync::{Mutex, MutexGuard};
11use std::marker::PhantomData;
12use std::num::NonZero;
13use std::pin::Pin;
14use std::ptr::NonNull;
15use std::task::{Context, Poll};
16
17use fidl_next::{Chunk, HasExecutor};
18use zx::{HandleBased, Status};
19
20use fdf_channel::arena::{Arena, ArenaBox};
21use fdf_channel::channel::Channel;
22use fdf_channel::futures::ReadMessageState;
23use fdf_channel::message::Message;
24use fdf_core::dispatcher::{CurrentDispatcher, OnDispatcher};
25use fdf_core::handle::{DriverHandle, MixedHandle, MixedHandleType};
26
27pub use self::wire::*;
28
29pub type FidlExecutor<D = CurrentDispatcher> = libasync_fidl::FidlExecutor<D>;
32
33#[derive(Debug, PartialEq)]
36pub struct DriverChannel<D = CurrentDispatcher> {
37 dispatcher: D,
38 channel: Channel<[Chunk]>,
39}
40
41impl<D> DriverChannel<D> {
42 pub fn new_with_dispatcher(dispatcher: D, channel: Channel<[Chunk]>) -> Self {
45 Self { dispatcher, channel }
46 }
47
48 pub fn create_with_dispatchers(dispatcher1: D, dispatcher2: D) -> (Self, Self) {
51 let (channel1, channel2) = Channel::create();
52 (
53 Self { dispatcher: dispatcher1, channel: channel1 },
54 Self { dispatcher: dispatcher2, channel: channel2 },
55 )
56 }
57
58 pub fn create_with_dispatcher(dispatcher: D) -> (Self, Self)
61 where
62 D: Clone,
63 {
64 Self::create_with_dispatchers(dispatcher.clone(), dispatcher)
65 }
66
67 pub fn receive_from_token_with_dispatcher(
70 dispatcher: D,
71 token: zx::Channel,
72 ) -> Result<DriverChannel<D>, Status> {
73 let mut handle = 0;
74 Status::ok(unsafe { fdf_sys::fdf_token_receive(token.into_raw(), &mut handle) })?;
75 let handle = NonZero::new(handle).ok_or(Status::BAD_HANDLE)?;
76 let channel = unsafe { Channel::from_driver_handle(DriverHandle::new_unchecked(handle)) };
77 Ok(DriverChannel::new_with_dispatcher(dispatcher, channel))
78 }
79
80 pub fn into_channel(self) -> Channel<[Chunk]> {
82 self.channel
83 }
84
85 pub fn into_driver_handle(self) -> DriverHandle {
87 self.channel.into_driver_handle()
88 }
89}
90
91impl DriverChannel<CurrentDispatcher> {
92 pub fn new(channel: Channel<[Chunk]>) -> Self {
95 Self::new_with_dispatcher(CurrentDispatcher, channel)
96 }
97
98 pub fn create() -> (Self, Self) {
101 Self::create_with_dispatcher(CurrentDispatcher)
102 }
103
104 pub fn receive_from_token(token: zx::Channel) -> Result<DriverChannel, Status> {
107 Self::receive_from_token_with_dispatcher(CurrentDispatcher, token)
108 }
109}
110
111impl fidl_next::InstanceFromServiceTransport<zx::Channel> for DriverChannel<CurrentDispatcher> {
112 fn from_service_transport(handle: zx::Channel) -> Self {
113 DriverChannel::receive_from_token(handle).unwrap()
114 }
115}
116
117pub fn create_channel_with_dispatchers<P, D>(
120 client_dispatcher: D,
121 server_dispatcher: D,
122) -> (fidl_next::ClientEnd<P, DriverChannel<D>>, fidl_next::ServerEnd<P, DriverChannel<D>>) {
123 let (client_channel, server_channel) =
124 DriverChannel::create_with_dispatchers(client_dispatcher, server_dispatcher);
125 (
126 fidl_next::ClientEnd::from_untyped(client_channel),
127 fidl_next::ServerEnd::from_untyped(server_channel),
128 )
129}
130
131pub fn create_channel_with_dispatcher<P, D: Clone>(
134 dispatcher: D,
135) -> (fidl_next::ClientEnd<P, DriverChannel<D>>, fidl_next::ServerEnd<P, DriverChannel<D>>) {
136 create_channel_with_dispatchers(dispatcher.clone(), dispatcher)
137}
138
139pub fn create_channel<P>()
142-> (fidl_next::ClientEnd<P, DriverChannel>, fidl_next::ServerEnd<P, DriverChannel>) {
143 create_channel_with_dispatcher(CurrentDispatcher)
144}
145
146pub struct SendBuffer {
148 handles: Vec<Option<MixedHandle>>,
149 data: Vec<Chunk>,
150}
151
152impl SendBuffer {
153 fn new() -> Self {
154 Self { handles: Vec::new(), data: Vec::new() }
155 }
156}
157
158impl fidl_next::Encoder for SendBuffer {
159 #[inline]
160 fn bytes_written(&self) -> usize {
161 fidl_next::Encoder::bytes_written(&self.data)
162 }
163
164 #[inline]
165 fn write(&mut self, bytes: &[u8]) {
166 fidl_next::Encoder::write(&mut self.data, bytes)
167 }
168
169 #[inline]
170 fn rewrite(&mut self, pos: usize, bytes: &[u8]) {
171 fidl_next::Encoder::rewrite(&mut self.data, pos, bytes)
172 }
173
174 fn write_zeroes(&mut self, len: usize) {
175 fidl_next::Encoder::write_zeroes(&mut self.data, len);
176 }
177}
178
179impl fidl_next::encoder::InternalHandleEncoder for SendBuffer {
180 #[inline]
181 fn __internal_handle_count(&self) -> usize {
182 self.handles.len()
183 }
184}
185
186impl fidl_next::fuchsia::HandleEncoder for SendBuffer {
187 fn push_handle(&mut self, handle: zx::NullableHandle) -> Result<(), fidl_next::EncodeError> {
188 if let Some(handle) = MixedHandle::from_zircon_handle(handle) {
189 if handle.is_driver() {
190 return Err(fidl_next::EncodeError::ExpectedZirconHandle);
191 }
192 self.handles.push(Some(handle));
193 } else {
194 self.handles.push(None);
195 }
196 Ok(())
197 }
198
199 unsafe fn push_raw_driver_handle(&mut self, handle: u32) -> Result<(), fidl_next::EncodeError> {
200 if let Some(handle) = NonZero::new(handle) {
201 let handle = unsafe { MixedHandle::from_raw(handle) };
204 if !handle.is_driver() {
205 return Err(fidl_next::EncodeError::ExpectedDriverHandle);
206 }
207 self.handles.push(Some(handle));
208 } else {
209 self.handles.push(None);
210 }
211 Ok(())
212 }
213
214 fn handles_pushed(&self) -> usize {
215 self.handles.len()
216 }
217}
218
219#[doc(hidden)] pub struct RecvBuffer {
221 buffer: Option<Message<[Chunk]>>,
222 data_offset: usize,
223 handle_offset: usize,
224}
225
226impl RecvBuffer {
227 fn next_handle(&self) -> Result<&MixedHandle, fidl_next::DecodeError> {
228 let Some(buffer) = &self.buffer else {
229 return Err(fidl_next::DecodeError::InsufficientHandles);
230 };
231
232 let Some(handles) = buffer.handles() else {
233 return Err(fidl_next::DecodeError::InsufficientHandles);
234 };
235 if handles.len() < self.handle_offset + 1 {
236 return Err(fidl_next::DecodeError::InsufficientHandles);
237 }
238 handles[self.handle_offset].as_ref().ok_or(fidl_next::DecodeError::RequiredHandleAbsent)
239 }
240}
241
242unsafe impl fidl_next::Decoder for RecvBuffer {
247 fn take_chunks_raw(&mut self, count: usize) -> Result<NonNull<Chunk>, fidl_next::DecodeError> {
250 let Some(buffer) = &mut self.buffer else {
251 return Err(fidl_next::DecodeError::InsufficientData);
252 };
253
254 let Some(data) = buffer.data_mut() else {
255 return Err(fidl_next::DecodeError::InsufficientData);
256 };
257 if data.len() < self.data_offset + count {
258 return Err(fidl_next::DecodeError::InsufficientData);
259 }
260 let pos = self.data_offset;
261 self.data_offset += count;
262 Ok(unsafe { NonNull::new_unchecked((data[pos..(pos + count)]).as_mut_ptr()) })
263 }
264
265 fn commit(&mut self) {
266 if let Some(handles) = self.buffer.as_mut().and_then(Message::handles_mut) {
267 for handle in handles.iter_mut().take(self.handle_offset) {
268 core::mem::forget(handle.take());
269 }
270 }
271 }
272
273 fn finish(&self) -> Result<(), fidl_next::DecodeError> {
274 if let Some(buffer) = &self.buffer {
275 let data_len = buffer.data().unwrap_or(&[]).len();
276 if self.data_offset != data_len {
277 return Err(fidl_next::DecodeError::ExtraBytes {
278 num_extra: data_len - self.data_offset,
279 });
280 }
281 let handle_len = buffer.handles().unwrap_or(&[]).len();
282 if self.handle_offset != handle_len {
283 return Err(fidl_next::DecodeError::ExtraHandles {
284 num_extra: handle_len - self.handle_offset,
285 });
286 }
287 }
288
289 Ok(())
290 }
291}
292
293impl fidl_next::decoder::InternalHandleDecoder for RecvBuffer {
294 fn __internal_take_handles(&mut self, count: usize) -> Result<(), fidl_next::DecodeError> {
295 let Some(handles) = self.buffer.as_mut().and_then(Message::handles_mut) else {
296 return Err(fidl_next::DecodeError::InsufficientHandles);
297 };
298 if handles.len() < self.handle_offset + count {
299 return Err(fidl_next::DecodeError::InsufficientHandles);
300 }
301 let pos = self.handle_offset;
302 self.handle_offset = pos + count;
303 Ok(())
304 }
305
306 fn __internal_handles_remaining(&self) -> usize {
307 self.buffer
308 .as_ref()
309 .map(|buffer| buffer.handles().unwrap_or(&[]).len() - self.handle_offset)
310 .unwrap_or(0)
311 }
312}
313
314impl fidl_next::fuchsia::HandleDecoder for RecvBuffer {
315 fn take_raw_handle(&mut self) -> Result<zx::sys::zx_handle_t, fidl_next::DecodeError> {
316 let result = {
317 let handle = self.next_handle()?.resolve_ref();
318 let MixedHandleType::Zircon(handle) = handle else {
319 return Err(fidl_next::DecodeError::ExpectedZirconHandle);
320 };
321 handle.raw_handle()
322 };
323 let pos = self.handle_offset;
324 self.handle_offset = pos + 1;
325 Ok(result)
326 }
327
328 fn take_raw_driver_handle(&mut self) -> Result<u32, fidl_next::DecodeError> {
329 let result = {
330 let handle = self.next_handle()?.resolve_ref();
331 let MixedHandleType::Driver(handle) = handle else {
332 return Err(fidl_next::DecodeError::ExpectedDriverHandle);
333 };
334 unsafe { handle.get_raw().get() }
335 };
336 let pos = self.handle_offset;
337 self.handle_offset = pos + 1;
338 Ok(result)
339 }
340
341 fn handles_remaining(&mut self) -> usize {
342 fidl_next::decoder::InternalHandleDecoder::__internal_handles_remaining(self)
343 }
344}
345
346pub struct DriverRecvState(ReadMessageState);
348
349pub struct Shared<D> {
351 channel: Mutex<DriverChannel<D>>,
352}
353
354impl<D> Shared<D> {
355 fn new(channel: Mutex<DriverChannel<D>>) -> Self {
356 Self { channel }
357 }
358
359 fn get_locked(&self) -> MutexGuard<'_, DriverChannel<D>> {
360 self.channel.lock()
361 }
362}
363
364pub struct Exclusive {
366 _phantom: PhantomData<()>,
367}
368
369impl<D: OnDispatcher> fidl_next::Transport for DriverChannel<D> {
370 type Error = Status;
371
372 fn split(self) -> (Self::Shared, Self::Exclusive) {
373 (Shared::new(Mutex::new(self)), Exclusive { _phantom: PhantomData })
374 }
375
376 type Shared = Shared<D>;
377
378 type SendBuffer = SendBuffer;
379
380 type SendFutureState = SendBuffer;
381
382 fn acquire(_shared: &Self::Shared) -> Self::SendBuffer {
383 SendBuffer::new()
384 }
385
386 type Exclusive = Exclusive;
387
388 type RecvFutureState = DriverRecvState;
389
390 type RecvBuffer = RecvBuffer;
391
392 fn begin_send(_shared: &Self::Shared, buffer: Self::SendBuffer) -> Self::SendFutureState {
393 buffer
394 }
395
396 fn poll_send(
397 mut buffer: Pin<&mut Self::SendFutureState>,
398 _cx: &mut Context<'_>,
399 shared: &Self::Shared,
400 ) -> Poll<Result<(), Option<Self::Error>>> {
401 let arena = Arena::new();
402 let message = Message::new_with(arena, |arena| {
403 let data = arena.insert_slice(&buffer.data);
404 let handles = buffer.handles.split_off(0);
405 let handles = arena.insert_from_iter(handles);
406 (Some(data), Some(handles))
407 });
408 let result = match shared.get_locked().channel.write(message) {
409 Ok(()) => Ok(()),
410 Err(Status::PEER_CLOSED) => Err(None),
411 Err(e) => Err(Some(e)),
412 };
413 Poll::Ready(result)
414 }
415
416 fn begin_recv(
417 shared: &Self::Shared,
418 _exclusive: &mut Self::Exclusive,
419 ) -> Self::RecvFutureState {
420 let state =
423 unsafe { ReadMessageState::register_read_wait(&mut shared.get_locked().channel) };
424 DriverRecvState(state)
425 }
426
427 fn poll_recv(
428 mut future: Pin<&mut Self::RecvFutureState>,
429 cx: &mut Context<'_>,
430 shared: &Self::Shared,
431 _exclusive: &mut Self::Exclusive,
432 ) -> Poll<Result<Self::RecvBuffer, Option<Self::Error>>> {
433 use std::task::Poll::*;
434 match future.as_mut().0.poll_with_dispatcher(cx, shared.get_locked().dispatcher.clone()) {
435 Ready(Ok(maybe_buffer)) => {
436 let buffer = maybe_buffer.map(|buffer| {
437 buffer.map_data(|_, data| {
438 let bytes = data.len();
439 assert_eq!(
440 0,
441 bytes % size_of::<Chunk>(),
442 "Received driver channel buffer was not a multiple of {} bytes",
443 size_of::<Chunk>()
444 );
445 unsafe {
449 let ptr = ArenaBox::into_ptr(data).cast();
450 ArenaBox::new(NonNull::slice_from_raw_parts(
451 ptr,
452 bytes / size_of::<Chunk>(),
453 ))
454 }
455 })
456 });
457
458 Ready(Ok(RecvBuffer { buffer, data_offset: 0, handle_offset: 0 }))
459 }
460 Ready(Err(err)) => {
461 if err == Status::PEER_CLOSED {
462 Ready(Err(None))
463 } else {
464 Ready(Err(Some(err)))
465 }
466 }
467 Pending => Pending,
468 }
469 }
470}
471
472impl<D> fidl_next::RunsTransport<DriverChannel<D>> for fidl_next::fuchsia_async::FuchsiaAsync {}
473impl<D: OnDispatcher> fidl_next::RunsTransport<DriverChannel<D>> for FidlExecutor<D> {}
474
475impl<D: OnDispatcher + 'static> HasExecutor for DriverChannel<D> {
476 type Executor = FidlExecutor<D>;
477
478 fn executor(&self) -> Self::Executor {
479 FidlExecutor::from(self.dispatcher.clone())
480 }
481}