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;
27use fdf_core::handle::{DriverHandle, MixedHandle, MixedHandleType};
28use libasync_dispatcher::OnDispatcher;
29
30pub type FidlExecutor<D = CurrentDispatcher> = libasync_fidl::FidlExecutor<D>;
33
34#[derive(Debug, PartialEq)]
37pub struct DriverChannel<D = CurrentDispatcher> {
38 dispatcher: D,
39 channel: Channel<[Chunk]>,
40}
41
42impl<D> DriverChannel<D> {
43 pub fn new_with_dispatcher(dispatcher: D, channel: Channel<[Chunk]>) -> Self {
46 Self { dispatcher, channel }
47 }
48
49 pub fn create_with_dispatchers(dispatcher1: D, dispatcher2: D) -> (Self, Self) {
52 let (channel1, channel2) = Channel::create();
53 (
54 Self { dispatcher: dispatcher1, channel: channel1 },
55 Self { dispatcher: dispatcher2, channel: channel2 },
56 )
57 }
58
59 pub fn create_with_dispatcher(dispatcher: D) -> (Self, Self)
62 where
63 D: Clone,
64 {
65 Self::create_with_dispatchers(dispatcher.clone(), dispatcher)
66 }
67
68 pub fn receive_from_token_with_dispatcher(
71 dispatcher: D,
72 token: zx::Channel,
73 ) -> Result<DriverChannel<D>, Status> {
74 let mut handle = 0;
75 Status::ok(unsafe { fdf_sys::fdf_token_receive(token.into_raw(), &mut handle) })?;
76 let handle = NonZero::new(handle).ok_or(Status::BAD_HANDLE)?;
77 let channel = unsafe { Channel::from_driver_handle(DriverHandle::new_unchecked(handle)) };
78 Ok(DriverChannel::new_with_dispatcher(dispatcher, channel))
79 }
80
81 pub fn into_channel(self) -> Channel<[Chunk]> {
83 self.channel
84 }
85
86 pub fn into_driver_handle(self) -> DriverHandle {
88 self.channel.into_driver_handle()
89 }
90}
91
92impl DriverChannel<CurrentDispatcher> {
93 pub fn new(channel: Channel<[Chunk]>) -> Self {
96 Self::new_with_dispatcher(CurrentDispatcher, channel)
97 }
98
99 pub fn create() -> (Self, Self) {
102 Self::create_with_dispatcher(CurrentDispatcher)
103 }
104
105 pub fn receive_from_token(token: zx::Channel) -> Result<DriverChannel, Status> {
108 Self::receive_from_token_with_dispatcher(CurrentDispatcher, token)
109 }
110}
111
112impl fidl_next::InstanceFromServiceTransport<zx::Channel> for DriverChannel<CurrentDispatcher> {
113 fn from_service_transport(handle: zx::Channel) -> Self {
114 DriverChannel::receive_from_token(handle).unwrap()
115 }
116}
117
118pub fn create_channel_with_dispatchers<P, D>(
121 client_dispatcher: D,
122 server_dispatcher: D,
123) -> (fidl_next::ClientEnd<P, DriverChannel<D>>, fidl_next::ServerEnd<P, DriverChannel<D>>) {
124 let (client_channel, server_channel) =
125 DriverChannel::create_with_dispatchers(client_dispatcher, server_dispatcher);
126 (
127 fidl_next::ClientEnd::from_untyped(client_channel),
128 fidl_next::ServerEnd::from_untyped(server_channel),
129 )
130}
131
132pub fn create_channel_with_dispatcher<P, D: Clone>(
135 dispatcher: D,
136) -> (fidl_next::ClientEnd<P, DriverChannel<D>>, fidl_next::ServerEnd<P, DriverChannel<D>>) {
137 create_channel_with_dispatchers(dispatcher.clone(), dispatcher)
138}
139
140pub fn create_channel<P>()
143-> (fidl_next::ClientEnd<P, DriverChannel>, fidl_next::ServerEnd<P, DriverChannel>) {
144 create_channel_with_dispatcher(CurrentDispatcher)
145}
146
147#[derive(Default)]
149pub struct SendBuffer {
150 handles: Vec<Option<MixedHandle>>,
151 data: Vec<Chunk>,
152}
153
154impl SendBuffer {
155 fn new() -> Self {
156 Self { handles: Vec::new(), data: Vec::new() }
157 }
158}
159
160impl fidl_next::Encoder for SendBuffer {
161 #[inline]
162 fn bytes_written(&self) -> usize {
163 fidl_next::Encoder::bytes_written(&self.data)
164 }
165
166 #[inline]
167 fn write(&mut self, bytes: &[u8]) {
168 fidl_next::Encoder::write(&mut self.data, bytes)
169 }
170
171 #[inline]
172 fn rewrite(&mut self, pos: usize, bytes: &[u8]) {
173 fidl_next::Encoder::rewrite(&mut self.data, pos, bytes)
174 }
175
176 fn write_zeroes(&mut self, len: usize) {
177 fidl_next::Encoder::write_zeroes(&mut self.data, len);
178 }
179}
180
181impl fidl_next::encoder::InternalHandleEncoder for SendBuffer {
182 #[inline]
183 fn __internal_handle_count(&self) -> usize {
184 self.handles.len()
185 }
186}
187
188impl fidl_next::fuchsia::HandleEncoder for SendBuffer {
189 fn push_handle(&mut self, handle: zx::NullableHandle) -> Result<(), fidl_next::EncodeError> {
190 if let Some(handle) = MixedHandle::from_zircon_handle(handle) {
191 if handle.is_driver() {
192 return Err(fidl_next::EncodeError::ExpectedZirconHandle);
193 }
194 self.handles.push(Some(handle));
195 } else {
196 self.handles.push(None);
197 }
198 Ok(())
199 }
200
201 unsafe fn push_raw_driver_handle(&mut self, handle: u32) -> Result<(), fidl_next::EncodeError> {
202 if let Some(handle) = NonZero::new(handle) {
203 let handle = unsafe { MixedHandle::from_raw(handle) };
206 if !handle.is_driver() {
207 return Err(fidl_next::EncodeError::ExpectedDriverHandle);
208 }
209 self.handles.push(Some(handle));
210 } else {
211 self.handles.push(None);
212 }
213 Ok(())
214 }
215
216 fn handles_pushed(&self) -> usize {
217 self.handles.len()
218 }
219}
220
221#[doc(hidden)] pub struct RecvBuffer {
223 message: Option<Message<[Chunk]>>,
224}
225
226unsafe impl<'de> AsDecoder<'de> for RecvBuffer {
227 type Decoder = RecvBufferDecoder<'de>;
228
229 fn as_decoder(&'de mut self) -> Self::Decoder {
230 RecvBufferDecoder { buffer: self, data_offset: 0, handle_offset: 0 }
231 }
232}
233
234#[doc(hidden)] pub struct RecvBufferDecoder<'de> {
236 buffer: &'de mut RecvBuffer,
237 data_offset: usize,
238 handle_offset: usize,
239}
240
241impl RecvBufferDecoder<'_> {
242 fn next_handle(&self) -> Result<&MixedHandle, fidl_next::DecodeError> {
243 let Some(message) = &self.buffer.message else {
244 return Err(fidl_next::DecodeError::InsufficientHandles);
245 };
246
247 let Some(handles) = message.handles() else {
248 return Err(fidl_next::DecodeError::InsufficientHandles);
249 };
250 if handles.len() < self.handle_offset + 1 {
251 return Err(fidl_next::DecodeError::InsufficientHandles);
252 }
253 handles[self.handle_offset].as_ref().ok_or(fidl_next::DecodeError::RequiredHandleAbsent)
254 }
255}
256
257impl<'de> fidl_next::Decoder<'de> for RecvBufferDecoder<'de> {
258 fn take_chunks(&mut self, count: usize) -> Result<&'de mut [Chunk], fidl_next::DecodeError> {
259 let Some(message) = &mut self.buffer.message else {
260 return Err(fidl_next::DecodeError::InsufficientData);
261 };
262
263 let Some(data) = message.data_mut() else {
264 return Err(fidl_next::DecodeError::InsufficientData);
265 };
266 if data.len() < self.data_offset + count {
267 return Err(fidl_next::DecodeError::InsufficientData);
268 }
269 let pos = self.data_offset;
270 self.data_offset += count;
271
272 let ptr = data.as_mut_ptr();
273 Ok(unsafe { slice::from_raw_parts_mut(ptr.add(pos), count) })
274 }
275
276 fn commit(&mut self) {
277 if let Some(handles) = self.buffer.message.as_mut().and_then(Message::handles_mut) {
278 for handle in handles.iter_mut().take(self.handle_offset) {
279 core::mem::forget(handle.take());
280 }
281 }
282 }
283
284 fn finish(&self) -> Result<(), fidl_next::DecodeError> {
285 if let Some(message) = &self.buffer.message {
286 let data_len = message.data().unwrap_or(&[]).len();
287 if self.data_offset != data_len {
288 return Err(fidl_next::DecodeError::ExtraBytes {
289 num_extra: data_len - self.data_offset,
290 });
291 }
292 let handle_len = message.handles().unwrap_or(&[]).len();
293 if self.handle_offset != handle_len {
294 return Err(fidl_next::DecodeError::ExtraHandles {
295 num_extra: handle_len - self.handle_offset,
296 });
297 }
298 }
299
300 Ok(())
301 }
302}
303
304impl fidl_next::decoder::InternalHandleDecoder for RecvBufferDecoder<'_> {
305 fn __internal_take_handles(&mut self, count: usize) -> Result<(), fidl_next::DecodeError> {
306 let Some(handles) = self.buffer.message.as_mut().and_then(Message::handles_mut) else {
307 return Err(fidl_next::DecodeError::InsufficientHandles);
308 };
309 if handles.len() < self.handle_offset + count {
310 return Err(fidl_next::DecodeError::InsufficientHandles);
311 }
312 let pos = self.handle_offset;
313 self.handle_offset = pos + count;
314 Ok(())
315 }
316
317 fn __internal_handles_remaining(&self) -> usize {
318 self.buffer
319 .message
320 .as_ref()
321 .map(|buffer| buffer.handles().unwrap_or(&[]).len() - self.handle_offset)
322 .unwrap_or(0)
323 }
324}
325
326impl fidl_next::fuchsia::HandleDecoder for RecvBufferDecoder<'_> {
327 fn take_raw_handle(&mut self) -> Result<zx::sys::zx_handle_t, fidl_next::DecodeError> {
328 let result = {
329 let handle = self.next_handle()?.resolve_ref();
330 let MixedHandleType::Zircon(handle) = handle else {
331 return Err(fidl_next::DecodeError::ExpectedZirconHandle);
332 };
333 handle.raw_handle()
334 };
335 let pos = self.handle_offset;
336 self.handle_offset = pos + 1;
337 Ok(result)
338 }
339
340 fn take_raw_driver_handle(&mut self) -> Result<u32, fidl_next::DecodeError> {
341 let result = {
342 let handle = self.next_handle()?.resolve_ref();
343 let MixedHandleType::Driver(handle) = handle else {
344 return Err(fidl_next::DecodeError::ExpectedDriverHandle);
345 };
346 unsafe { handle.get_raw().get() }
347 };
348 let pos = self.handle_offset;
349 self.handle_offset = pos + 1;
350 Ok(result)
351 }
352
353 fn handles_remaining(&mut self) -> usize {
354 fidl_next::decoder::InternalHandleDecoder::__internal_handles_remaining(self)
355 }
356}
357
358pub struct DriverRecvState(ReadMessageState);
360
361pub struct Shared<D> {
363 channel: Mutex<DriverChannel<D>>,
364}
365
366impl<D> Shared<D> {
367 fn new(channel: Mutex<DriverChannel<D>>) -> Self {
368 Self { channel }
369 }
370
371 fn get_locked(&self) -> MutexGuard<'_, DriverChannel<D>> {
372 self.channel.lock()
373 }
374}
375
376pub struct Exclusive {
378 _phantom: PhantomData<()>,
379}
380
381impl<D: OnDispatcher> fidl_next::Transport for DriverChannel<D> {
382 type Error = Status;
383
384 fn split(self) -> (Self::Shared, Self::Exclusive) {
385 (Shared::new(Mutex::new(self)), Exclusive { _phantom: PhantomData })
386 }
387
388 type Shared = Shared<D>;
389
390 type SendBuffer = SendBuffer;
391
392 type SendFutureState = SendBuffer;
393
394 fn acquire(_shared: &Self::Shared) -> Self::SendBuffer {
395 SendBuffer::new()
396 }
397
398 type Exclusive = Exclusive;
399
400 type RecvFutureState = DriverRecvState;
401
402 type RecvBuffer = RecvBuffer;
403
404 fn begin_send(_shared: &Self::Shared, buffer: Self::SendBuffer) -> Self::SendFutureState {
405 buffer
406 }
407
408 fn poll_send(
409 mut buffer: Pin<&mut Self::SendFutureState>,
410 _cx: &mut Context<'_>,
411 shared: &Self::Shared,
412 ) -> Poll<Result<(), Option<Self::Error>>> {
413 Poll::Ready(Self::send_immediately(&mut *buffer, shared))
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 { message: buffer }))
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: OnDispatcher> fidl_next::protocol::NonBlockingTransport for DriverChannel<D> {
473 fn send_immediately(
474 future_state: &mut Self::SendFutureState,
475 shared: &Self::Shared,
476 ) -> Result<(), Option<Self::Error>> {
477 let arena = Arena::new();
478 let message = Message::new_with(arena, |arena| {
479 let data = arena.insert_slice(&future_state.data);
480 let handles = future_state.handles.split_off(0);
481 let handles = arena.insert_from_iter(handles);
482 (Some(data), Some(handles))
483 });
484 match shared.get_locked().channel.write(message) {
485 Ok(()) => Ok(()),
486 Err(Status::PEER_CLOSED) => Err(None),
487 Err(e) => Err(Some(e)),
488 }
489 }
490}
491
492impl<D> fidl_next::RunsTransport<DriverChannel<D>> for fidl_next::fuchsia_async::FuchsiaAsync {}
493impl<D: OnDispatcher> fidl_next::RunsTransport<DriverChannel<D>> for FidlExecutor<D> {}
494
495impl<D: OnDispatcher + 'static> HasExecutor for DriverChannel<D> {
496 type Executor = FidlExecutor<D>;
497
498 fn executor(&self) -> Self::Executor {
499 FidlExecutor::from(self.dispatcher.clone())
500 }
501}