1#![deny(unsafe_op_in_unsafe_fn, missing_docs)]
7
8pub mod 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::slice;
16use std::task::{Context, Poll};
17
18use fidl_next::protocol::NonBlockingTransport;
19use fidl_next::{AsDecoder, Chunk, HasExecutor};
20use zx::Status;
21
22use fdf_channel::arena::{Arena, ArenaBox};
23use fdf_channel::channel::Channel;
24use fdf_channel::futures::ReadMessageState;
25use fdf_channel::message::Message;
26use fdf_core::dispatcher::{CurrentDispatcher, OnDispatcher};
27use fdf_core::handle::{DriverHandle, MixedHandle, MixedHandleType};
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
146#[derive(Default)]
148pub struct SendBuffer {
149 handles: Vec<Option<MixedHandle>>,
150 data: Vec<Chunk>,
151}
152
153impl SendBuffer {
154 fn new() -> Self {
155 Self { handles: Vec::new(), data: Vec::new() }
156 }
157}
158
159impl fidl_next::Encoder for SendBuffer {
160 #[inline]
161 fn bytes_written(&self) -> usize {
162 fidl_next::Encoder::bytes_written(&self.data)
163 }
164
165 #[inline]
166 fn write(&mut self, bytes: &[u8]) {
167 fidl_next::Encoder::write(&mut self.data, bytes)
168 }
169
170 #[inline]
171 fn rewrite(&mut self, pos: usize, bytes: &[u8]) {
172 fidl_next::Encoder::rewrite(&mut self.data, pos, bytes)
173 }
174
175 fn write_zeroes(&mut self, len: usize) {
176 fidl_next::Encoder::write_zeroes(&mut self.data, len);
177 }
178}
179
180impl fidl_next::encoder::InternalHandleEncoder for SendBuffer {
181 #[inline]
182 fn __internal_handle_count(&self) -> usize {
183 self.handles.len()
184 }
185}
186
187impl fidl_next::fuchsia::HandleEncoder for SendBuffer {
188 fn push_handle(&mut self, handle: zx::NullableHandle) -> Result<(), fidl_next::EncodeError> {
189 if let Some(handle) = MixedHandle::from_zircon_handle(handle) {
190 if handle.is_driver() {
191 return Err(fidl_next::EncodeError::ExpectedZirconHandle);
192 }
193 self.handles.push(Some(handle));
194 } else {
195 self.handles.push(None);
196 }
197 Ok(())
198 }
199
200 unsafe fn push_raw_driver_handle(&mut self, handle: u32) -> Result<(), fidl_next::EncodeError> {
201 if let Some(handle) = NonZero::new(handle) {
202 let handle = unsafe { MixedHandle::from_raw(handle) };
205 if !handle.is_driver() {
206 return Err(fidl_next::EncodeError::ExpectedDriverHandle);
207 }
208 self.handles.push(Some(handle));
209 } else {
210 self.handles.push(None);
211 }
212 Ok(())
213 }
214
215 fn handles_pushed(&self) -> usize {
216 self.handles.len()
217 }
218}
219
220#[doc(hidden)] pub struct RecvBuffer {
222 message: Option<Message<[Chunk]>>,
223}
224
225unsafe impl<'de> AsDecoder<'de> for RecvBuffer {
226 type Decoder = RecvBufferDecoder<'de>;
227
228 fn as_decoder(&'de mut self) -> Self::Decoder {
229 RecvBufferDecoder { buffer: self, data_offset: 0, handle_offset: 0 }
230 }
231}
232
233#[doc(hidden)] pub struct RecvBufferDecoder<'de> {
235 buffer: &'de mut RecvBuffer,
236 data_offset: usize,
237 handle_offset: usize,
238}
239
240impl RecvBufferDecoder<'_> {
241 fn next_handle(&self) -> Result<&MixedHandle, fidl_next::DecodeError> {
242 let Some(message) = &self.buffer.message else {
243 return Err(fidl_next::DecodeError::InsufficientHandles);
244 };
245
246 let Some(handles) = message.handles() else {
247 return Err(fidl_next::DecodeError::InsufficientHandles);
248 };
249 if handles.len() < self.handle_offset + 1 {
250 return Err(fidl_next::DecodeError::InsufficientHandles);
251 }
252 handles[self.handle_offset].as_ref().ok_or(fidl_next::DecodeError::RequiredHandleAbsent)
253 }
254}
255
256impl<'de> fidl_next::Decoder<'de> for RecvBufferDecoder<'de> {
257 fn take_chunks(&mut self, count: usize) -> Result<&'de mut [Chunk], fidl_next::DecodeError> {
258 let Some(message) = &mut self.buffer.message else {
259 return Err(fidl_next::DecodeError::InsufficientData);
260 };
261
262 let Some(data) = message.data_mut() else {
263 return Err(fidl_next::DecodeError::InsufficientData);
264 };
265 if data.len() < self.data_offset + count {
266 return Err(fidl_next::DecodeError::InsufficientData);
267 }
268 let pos = self.data_offset;
269 self.data_offset += count;
270
271 let ptr = data.as_mut_ptr();
272 Ok(unsafe { slice::from_raw_parts_mut(ptr.add(pos), count) })
273 }
274
275 fn commit(&mut self) {
276 if let Some(handles) = self.buffer.message.as_mut().and_then(Message::handles_mut) {
277 for handle in handles.iter_mut().take(self.handle_offset) {
278 core::mem::forget(handle.take());
279 }
280 }
281 }
282
283 fn finish(&self) -> Result<(), fidl_next::DecodeError> {
284 if let Some(message) = &self.buffer.message {
285 let data_len = message.data().unwrap_or(&[]).len();
286 if self.data_offset != data_len {
287 return Err(fidl_next::DecodeError::ExtraBytes {
288 num_extra: data_len - self.data_offset,
289 });
290 }
291 let handle_len = message.handles().unwrap_or(&[]).len();
292 if self.handle_offset != handle_len {
293 return Err(fidl_next::DecodeError::ExtraHandles {
294 num_extra: handle_len - self.handle_offset,
295 });
296 }
297 }
298
299 Ok(())
300 }
301}
302
303impl fidl_next::decoder::InternalHandleDecoder for RecvBufferDecoder<'_> {
304 fn __internal_take_handles(&mut self, count: usize) -> Result<(), fidl_next::DecodeError> {
305 let Some(handles) = self.buffer.message.as_mut().and_then(Message::handles_mut) else {
306 return Err(fidl_next::DecodeError::InsufficientHandles);
307 };
308 if handles.len() < self.handle_offset + count {
309 return Err(fidl_next::DecodeError::InsufficientHandles);
310 }
311 let pos = self.handle_offset;
312 self.handle_offset = pos + count;
313 Ok(())
314 }
315
316 fn __internal_handles_remaining(&self) -> usize {
317 self.buffer
318 .message
319 .as_ref()
320 .map(|buffer| buffer.handles().unwrap_or(&[]).len() - self.handle_offset)
321 .unwrap_or(0)
322 }
323}
324
325impl fidl_next::fuchsia::HandleDecoder for RecvBufferDecoder<'_> {
326 fn take_raw_handle(&mut self) -> Result<zx::sys::zx_handle_t, fidl_next::DecodeError> {
327 let result = {
328 let handle = self.next_handle()?.resolve_ref();
329 let MixedHandleType::Zircon(handle) = handle else {
330 return Err(fidl_next::DecodeError::ExpectedZirconHandle);
331 };
332 handle.raw_handle()
333 };
334 let pos = self.handle_offset;
335 self.handle_offset = pos + 1;
336 Ok(result)
337 }
338
339 fn take_raw_driver_handle(&mut self) -> Result<u32, fidl_next::DecodeError> {
340 let result = {
341 let handle = self.next_handle()?.resolve_ref();
342 let MixedHandleType::Driver(handle) = handle else {
343 return Err(fidl_next::DecodeError::ExpectedDriverHandle);
344 };
345 unsafe { handle.get_raw().get() }
346 };
347 let pos = self.handle_offset;
348 self.handle_offset = pos + 1;
349 Ok(result)
350 }
351
352 fn handles_remaining(&mut self) -> usize {
353 fidl_next::decoder::InternalHandleDecoder::__internal_handles_remaining(self)
354 }
355}
356
357pub struct DriverRecvState(ReadMessageState);
359
360pub struct Shared<D> {
362 channel: Mutex<DriverChannel<D>>,
363}
364
365impl<D> Shared<D> {
366 fn new(channel: Mutex<DriverChannel<D>>) -> Self {
367 Self { channel }
368 }
369
370 fn get_locked(&self) -> MutexGuard<'_, DriverChannel<D>> {
371 self.channel.lock()
372 }
373}
374
375pub struct Exclusive {
377 _phantom: PhantomData<()>,
378}
379
380impl<D: OnDispatcher> fidl_next::Transport for DriverChannel<D> {
381 type Error = Status;
382
383 fn split(self) -> (Self::Shared, Self::Exclusive) {
384 (Shared::new(Mutex::new(self)), Exclusive { _phantom: PhantomData })
385 }
386
387 type Shared = Shared<D>;
388
389 type SendBuffer = SendBuffer;
390
391 type SendFutureState = SendBuffer;
392
393 fn acquire(_shared: &Self::Shared) -> Self::SendBuffer {
394 SendBuffer::new()
395 }
396
397 type Exclusive = Exclusive;
398
399 type RecvFutureState = DriverRecvState;
400
401 type RecvBuffer = RecvBuffer;
402
403 fn begin_send(_shared: &Self::Shared, buffer: Self::SendBuffer) -> Self::SendFutureState {
404 buffer
405 }
406
407 fn poll_send(
408 mut buffer: Pin<&mut Self::SendFutureState>,
409 _cx: &mut Context<'_>,
410 shared: &Self::Shared,
411 ) -> Poll<Result<(), Option<Self::Error>>> {
412 Poll::Ready(Self::send_immediately(&mut *buffer, shared))
413 }
414
415 fn begin_recv(
416 shared: &Self::Shared,
417 _exclusive: &mut Self::Exclusive,
418 ) -> Self::RecvFutureState {
419 let state =
422 unsafe { ReadMessageState::register_read_wait(&mut shared.get_locked().channel) };
423 DriverRecvState(state)
424 }
425
426 fn poll_recv(
427 mut future: Pin<&mut Self::RecvFutureState>,
428 cx: &mut Context<'_>,
429 shared: &Self::Shared,
430 _exclusive: &mut Self::Exclusive,
431 ) -> Poll<Result<Self::RecvBuffer, Option<Self::Error>>> {
432 use std::task::Poll::*;
433 match future.as_mut().0.poll_with_dispatcher(cx, shared.get_locked().dispatcher.clone()) {
434 Ready(Ok(maybe_buffer)) => {
435 let buffer = maybe_buffer.map(|buffer| {
436 buffer.map_data(|_, data| {
437 let bytes = data.len();
438 assert_eq!(
439 0,
440 bytes % size_of::<Chunk>(),
441 "Received driver channel buffer was not a multiple of {} bytes",
442 size_of::<Chunk>()
443 );
444 unsafe {
448 let ptr = ArenaBox::into_ptr(data).cast();
449 ArenaBox::new(NonNull::slice_from_raw_parts(
450 ptr,
451 bytes / size_of::<Chunk>(),
452 ))
453 }
454 })
455 });
456
457 Ready(Ok(RecvBuffer { message: buffer }))
458 }
459 Ready(Err(err)) => {
460 if err == Status::PEER_CLOSED {
461 Ready(Err(None))
462 } else {
463 Ready(Err(Some(err)))
464 }
465 }
466 Pending => Pending,
467 }
468 }
469}
470
471impl<D: OnDispatcher> fidl_next::protocol::NonBlockingTransport for DriverChannel<D> {
472 fn send_immediately(
473 future_state: &mut Self::SendFutureState,
474 shared: &Self::Shared,
475 ) -> Result<(), Option<Self::Error>> {
476 let arena = Arena::new();
477 let message = Message::new_with(arena, |arena| {
478 let data = arena.insert_slice(&future_state.data);
479 let handles = future_state.handles.split_off(0);
480 let handles = arena.insert_from_iter(handles);
481 (Some(data), Some(handles))
482 });
483 match shared.get_locked().channel.write(message) {
484 Ok(()) => Ok(()),
485 Err(Status::PEER_CLOSED) => Err(None),
486 Err(e) => Err(Some(e)),
487 }
488 }
489}
490
491impl<D> fidl_next::RunsTransport<DriverChannel<D>> for fidl_next::fuchsia_async::FuchsiaAsync {}
492impl<D: OnDispatcher> fidl_next::RunsTransport<DriverChannel<D>> for FidlExecutor<D> {}
493
494impl<D: OnDispatcher + 'static> HasExecutor for DriverChannel<D> {
495 type Executor = FidlExecutor<D>;
496
497 fn executor(&self) -> Self::Executor {
498 FidlExecutor::from(self.dispatcher.clone())
499 }
500}