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::{AsDecoder, Chunk, HasExecutor};
19use zx::Status;
20
21use fdf_channel::arena::{Arena, ArenaBox};
22use fdf_channel::channel::Channel;
23use fdf_channel::futures::ReadMessageState;
24use fdf_channel::message::Message;
25use fdf_core::dispatcher::{CurrentDispatcher, OnDispatcher};
26use fdf_core::handle::{DriverHandle, MixedHandle, MixedHandleType};
27
28pub type FidlExecutor<D = CurrentDispatcher> = libasync_fidl::FidlExecutor<D>;
31
32#[derive(Debug, PartialEq)]
35pub struct DriverChannel<D = CurrentDispatcher> {
36 dispatcher: D,
37 channel: Channel<[Chunk]>,
38}
39
40impl<D> DriverChannel<D> {
41 pub fn new_with_dispatcher(dispatcher: D, channel: Channel<[Chunk]>) -> Self {
44 Self { dispatcher, channel }
45 }
46
47 pub fn create_with_dispatchers(dispatcher1: D, dispatcher2: D) -> (Self, Self) {
50 let (channel1, channel2) = Channel::create();
51 (
52 Self { dispatcher: dispatcher1, channel: channel1 },
53 Self { dispatcher: dispatcher2, channel: channel2 },
54 )
55 }
56
57 pub fn create_with_dispatcher(dispatcher: D) -> (Self, Self)
60 where
61 D: Clone,
62 {
63 Self::create_with_dispatchers(dispatcher.clone(), dispatcher)
64 }
65
66 pub fn receive_from_token_with_dispatcher(
69 dispatcher: D,
70 token: zx::Channel,
71 ) -> Result<DriverChannel<D>, Status> {
72 let mut handle = 0;
73 Status::ok(unsafe { fdf_sys::fdf_token_receive(token.into_raw(), &mut handle) })?;
74 let handle = NonZero::new(handle).ok_or(Status::BAD_HANDLE)?;
75 let channel = unsafe { Channel::from_driver_handle(DriverHandle::new_unchecked(handle)) };
76 Ok(DriverChannel::new_with_dispatcher(dispatcher, channel))
77 }
78
79 pub fn into_channel(self) -> Channel<[Chunk]> {
81 self.channel
82 }
83
84 pub fn into_driver_handle(self) -> DriverHandle {
86 self.channel.into_driver_handle()
87 }
88}
89
90impl DriverChannel<CurrentDispatcher> {
91 pub fn new(channel: Channel<[Chunk]>) -> Self {
94 Self::new_with_dispatcher(CurrentDispatcher, channel)
95 }
96
97 pub fn create() -> (Self, Self) {
100 Self::create_with_dispatcher(CurrentDispatcher)
101 }
102
103 pub fn receive_from_token(token: zx::Channel) -> Result<DriverChannel, Status> {
106 Self::receive_from_token_with_dispatcher(CurrentDispatcher, token)
107 }
108}
109
110impl fidl_next::InstanceFromServiceTransport<zx::Channel> for DriverChannel<CurrentDispatcher> {
111 fn from_service_transport(handle: zx::Channel) -> Self {
112 DriverChannel::receive_from_token(handle).unwrap()
113 }
114}
115
116pub fn create_channel_with_dispatchers<P, D>(
119 client_dispatcher: D,
120 server_dispatcher: D,
121) -> (fidl_next::ClientEnd<P, DriverChannel<D>>, fidl_next::ServerEnd<P, DriverChannel<D>>) {
122 let (client_channel, server_channel) =
123 DriverChannel::create_with_dispatchers(client_dispatcher, server_dispatcher);
124 (
125 fidl_next::ClientEnd::from_untyped(client_channel),
126 fidl_next::ServerEnd::from_untyped(server_channel),
127 )
128}
129
130pub fn create_channel_with_dispatcher<P, D: Clone>(
133 dispatcher: D,
134) -> (fidl_next::ClientEnd<P, DriverChannel<D>>, fidl_next::ServerEnd<P, DriverChannel<D>>) {
135 create_channel_with_dispatchers(dispatcher.clone(), dispatcher)
136}
137
138pub fn create_channel<P>()
141-> (fidl_next::ClientEnd<P, DriverChannel>, fidl_next::ServerEnd<P, DriverChannel>) {
142 create_channel_with_dispatcher(CurrentDispatcher)
143}
144
145#[derive(Default)]
147pub 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 message: Option<Message<[Chunk]>>,
222}
223
224unsafe impl<'de> AsDecoder<'de> for RecvBuffer {
225 type Decoder = RecvBufferDecoder<'de>;
226
227 fn as_decoder(&'de mut self) -> Self::Decoder {
228 RecvBufferDecoder { buffer: self, data_offset: 0, handle_offset: 0 }
229 }
230}
231
232#[doc(hidden)] pub struct RecvBufferDecoder<'de> {
234 buffer: &'de mut RecvBuffer,
235 data_offset: usize,
236 handle_offset: usize,
237}
238
239impl RecvBufferDecoder<'_> {
240 fn next_handle(&self) -> Result<&MixedHandle, fidl_next::DecodeError> {
241 let Some(message) = &self.buffer.message else {
242 return Err(fidl_next::DecodeError::InsufficientHandles);
243 };
244
245 let Some(handles) = message.handles() else {
246 return Err(fidl_next::DecodeError::InsufficientHandles);
247 };
248 if handles.len() < self.handle_offset + 1 {
249 return Err(fidl_next::DecodeError::InsufficientHandles);
250 }
251 handles[self.handle_offset].as_ref().ok_or(fidl_next::DecodeError::RequiredHandleAbsent)
252 }
253}
254
255impl<'de> fidl_next::Decoder<'de> for RecvBufferDecoder<'de> {
256 fn take_chunks(&mut self, count: usize) -> Result<&'de mut [Chunk], fidl_next::DecodeError> {
257 let Some(message) = &mut self.buffer.message else {
258 return Err(fidl_next::DecodeError::InsufficientData);
259 };
260
261 let Some(data) = message.data_mut() else {
262 return Err(fidl_next::DecodeError::InsufficientData);
263 };
264 if data.len() < self.data_offset + count {
265 return Err(fidl_next::DecodeError::InsufficientData);
266 }
267 let pos = self.data_offset;
268 self.data_offset += count;
269
270 let ptr = data.as_mut_ptr();
271 Ok(unsafe { slice::from_raw_parts_mut(ptr.add(pos), count) })
272 }
273
274 fn commit(&mut self) {
275 if let Some(handles) = self.buffer.message.as_mut().and_then(Message::handles_mut) {
276 for handle in handles.iter_mut().take(self.handle_offset) {
277 core::mem::forget(handle.take());
278 }
279 }
280 }
281
282 fn finish(&self) -> Result<(), fidl_next::DecodeError> {
283 if let Some(message) = &self.buffer.message {
284 let data_len = message.data().unwrap_or(&[]).len();
285 if self.data_offset != data_len {
286 return Err(fidl_next::DecodeError::ExtraBytes {
287 num_extra: data_len - self.data_offset,
288 });
289 }
290 let handle_len = message.handles().unwrap_or(&[]).len();
291 if self.handle_offset != handle_len {
292 return Err(fidl_next::DecodeError::ExtraHandles {
293 num_extra: handle_len - self.handle_offset,
294 });
295 }
296 }
297
298 Ok(())
299 }
300}
301
302impl fidl_next::decoder::InternalHandleDecoder for RecvBufferDecoder<'_> {
303 fn __internal_take_handles(&mut self, count: usize) -> Result<(), fidl_next::DecodeError> {
304 let Some(handles) = self.buffer.message.as_mut().and_then(Message::handles_mut) else {
305 return Err(fidl_next::DecodeError::InsufficientHandles);
306 };
307 if handles.len() < self.handle_offset + count {
308 return Err(fidl_next::DecodeError::InsufficientHandles);
309 }
310 let pos = self.handle_offset;
311 self.handle_offset = pos + count;
312 Ok(())
313 }
314
315 fn __internal_handles_remaining(&self) -> usize {
316 self.buffer
317 .message
318 .as_ref()
319 .map(|buffer| buffer.handles().unwrap_or(&[]).len() - self.handle_offset)
320 .unwrap_or(0)
321 }
322}
323
324impl fidl_next::fuchsia::HandleDecoder for RecvBufferDecoder<'_> {
325 fn take_raw_handle(&mut self) -> Result<zx::sys::zx_handle_t, fidl_next::DecodeError> {
326 let result = {
327 let handle = self.next_handle()?.resolve_ref();
328 let MixedHandleType::Zircon(handle) = handle else {
329 return Err(fidl_next::DecodeError::ExpectedZirconHandle);
330 };
331 handle.raw_handle()
332 };
333 let pos = self.handle_offset;
334 self.handle_offset = pos + 1;
335 Ok(result)
336 }
337
338 fn take_raw_driver_handle(&mut self) -> Result<u32, fidl_next::DecodeError> {
339 let result = {
340 let handle = self.next_handle()?.resolve_ref();
341 let MixedHandleType::Driver(handle) = handle else {
342 return Err(fidl_next::DecodeError::ExpectedDriverHandle);
343 };
344 unsafe { handle.get_raw().get() }
345 };
346 let pos = self.handle_offset;
347 self.handle_offset = pos + 1;
348 Ok(result)
349 }
350
351 fn handles_remaining(&mut self) -> usize {
352 fidl_next::decoder::InternalHandleDecoder::__internal_handles_remaining(self)
353 }
354}
355
356pub struct DriverRecvState(ReadMessageState);
358
359pub struct Shared<D> {
361 channel: Mutex<DriverChannel<D>>,
362}
363
364impl<D> Shared<D> {
365 fn new(channel: Mutex<DriverChannel<D>>) -> Self {
366 Self { channel }
367 }
368
369 fn get_locked(&self) -> MutexGuard<'_, DriverChannel<D>> {
370 self.channel.lock()
371 }
372}
373
374pub struct Exclusive {
376 _phantom: PhantomData<()>,
377}
378
379impl<D: OnDispatcher> fidl_next::Transport for DriverChannel<D> {
380 type Error = Status;
381
382 fn split(self) -> (Self::Shared, Self::Exclusive) {
383 (Shared::new(Mutex::new(self)), Exclusive { _phantom: PhantomData })
384 }
385
386 type Shared = Shared<D>;
387
388 type SendBuffer = SendBuffer;
389
390 type SendFutureState = SendBuffer;
391
392 fn acquire(_shared: &Self::Shared) -> Self::SendBuffer {
393 SendBuffer::new()
394 }
395
396 type Exclusive = Exclusive;
397
398 type RecvFutureState = DriverRecvState;
399
400 type RecvBuffer = RecvBuffer;
401
402 fn begin_send(_shared: &Self::Shared, buffer: Self::SendBuffer) -> Self::SendFutureState {
403 buffer
404 }
405
406 fn poll_send(
407 mut buffer: Pin<&mut Self::SendFutureState>,
408 _cx: &mut Context<'_>,
409 shared: &Self::Shared,
410 ) -> Poll<Result<(), Option<Self::Error>>> {
411 let arena = Arena::new();
412 let message = Message::new_with(arena, |arena| {
413 let data = arena.insert_slice(&buffer.data);
414 let handles = buffer.handles.split_off(0);
415 let handles = arena.insert_from_iter(handles);
416 (Some(data), Some(handles))
417 });
418 let result = match shared.get_locked().channel.write(message) {
419 Ok(()) => Ok(()),
420 Err(Status::PEER_CLOSED) => Err(None),
421 Err(e) => Err(Some(e)),
422 };
423 Poll::Ready(result)
424 }
425
426 fn begin_recv(
427 shared: &Self::Shared,
428 _exclusive: &mut Self::Exclusive,
429 ) -> Self::RecvFutureState {
430 let state =
433 unsafe { ReadMessageState::register_read_wait(&mut shared.get_locked().channel) };
434 DriverRecvState(state)
435 }
436
437 fn poll_recv(
438 mut future: Pin<&mut Self::RecvFutureState>,
439 cx: &mut Context<'_>,
440 shared: &Self::Shared,
441 _exclusive: &mut Self::Exclusive,
442 ) -> Poll<Result<Self::RecvBuffer, Option<Self::Error>>> {
443 use std::task::Poll::*;
444 match future.as_mut().0.poll_with_dispatcher(cx, shared.get_locked().dispatcher.clone()) {
445 Ready(Ok(maybe_buffer)) => {
446 let buffer = maybe_buffer.map(|buffer| {
447 buffer.map_data(|_, data| {
448 let bytes = data.len();
449 assert_eq!(
450 0,
451 bytes % size_of::<Chunk>(),
452 "Received driver channel buffer was not a multiple of {} bytes",
453 size_of::<Chunk>()
454 );
455 unsafe {
459 let ptr = ArenaBox::into_ptr(data).cast();
460 ArenaBox::new(NonNull::slice_from_raw_parts(
461 ptr,
462 bytes / size_of::<Chunk>(),
463 ))
464 }
465 })
466 });
467
468 Ready(Ok(RecvBuffer { message: buffer }))
469 }
470 Ready(Err(err)) => {
471 if err == Status::PEER_CLOSED {
472 Ready(Err(None))
473 } else {
474 Ready(Err(Some(err)))
475 }
476 }
477 Pending => Pending,
478 }
479 }
480}
481
482impl<D> fidl_next::RunsTransport<DriverChannel<D>> for fidl_next::fuchsia_async::FuchsiaAsync {}
483impl<D: OnDispatcher> fidl_next::RunsTransport<DriverChannel<D>> for FidlExecutor<D> {}
484
485impl<D: OnDispatcher + 'static> HasExecutor for DriverChannel<D> {
486 type Executor = FidlExecutor<D>;
487
488 fn executor(&self) -> Self::Executor {
489 FidlExecutor::from(self.dispatcher.clone())
490 }
491}