1mod wire;
6
7use std::marker::PhantomData;
8use std::num::NonZero;
9use std::pin::Pin;
10use std::ptr::NonNull;
11use std::sync::{Mutex, MutexGuard};
12use std::task::{Context, Poll};
13
14use fidl_next::Chunk;
15use zx::{HandleBased, Status};
16
17use fdf_channel::arena::{Arena, ArenaBox};
18use fdf_channel::channel::Channel;
19use fdf_channel::futures::ReadMessageState;
20use fdf_channel::message::Message;
21use fdf_core::dispatcher::{CurrentDispatcher, OnDispatcher};
22use fdf_core::handle::{DriverHandle, MixedHandle, MixedHandleType};
23
24pub use self::wire::*;
25
26#[derive(Debug, PartialEq)]
29pub struct DriverChannel<D = CurrentDispatcher> {
30 dispatcher: D,
31 channel: Channel<[Chunk]>,
32}
33
34impl<D> DriverChannel<D> {
35 pub fn new_with_dispatcher(dispatcher: D, channel: Channel<[Chunk]>) -> Self {
38 Self { dispatcher, channel }
39 }
40
41 pub fn create_with_dispatchers(dispatcher1: D, dispatcher2: D) -> (Self, Self) {
44 let (channel1, channel2) = Channel::create();
45 (
46 Self { dispatcher: dispatcher1, channel: channel1 },
47 Self { dispatcher: dispatcher2, channel: channel2 },
48 )
49 }
50
51 pub fn create_with_dispatcher(dispatcher: D) -> (Self, Self)
54 where
55 D: Clone,
56 {
57 Self::create_with_dispatchers(dispatcher.clone(), dispatcher)
58 }
59
60 pub fn receive_from_token_with_dispatcher(
63 dispatcher: D,
64 token: zx::Channel,
65 ) -> Result<DriverChannel<D>, Status> {
66 let mut handle = 0;
67 Status::ok(unsafe { fdf_sys::fdf_token_receive(token.into_raw(), &mut handle) })?;
68 let handle = NonZero::new(handle).ok_or(Status::BAD_HANDLE)?;
69 let channel = unsafe { Channel::from_driver_handle(DriverHandle::new_unchecked(handle)) };
70 Ok(DriverChannel::new_with_dispatcher(dispatcher, channel))
71 }
72
73 pub fn into_channel(self) -> Channel<[Chunk]> {
75 self.channel
76 }
77
78 pub fn into_driver_handle(self) -> DriverHandle {
80 self.channel.into_driver_handle()
81 }
82}
83
84impl DriverChannel<CurrentDispatcher> {
85 pub fn new(channel: Channel<[Chunk]>) -> Self {
88 Self::new_with_dispatcher(CurrentDispatcher, channel)
89 }
90
91 pub fn create() -> (Self, Self) {
94 Self::create_with_dispatcher(CurrentDispatcher)
95 }
96
97 pub fn receive_from_token(token: zx::Channel) -> Result<DriverChannel, Status> {
100 Self::receive_from_token_with_dispatcher(CurrentDispatcher, token)
101 }
102}
103
104impl fidl_next::InstanceFromServiceTransport<zx::Channel> for DriverChannel<CurrentDispatcher> {
105 fn from_service_transport(handle: zx::Channel) -> Self {
106 DriverChannel::receive_from_token(handle).unwrap()
107 }
108}
109
110pub fn create_channel_with_dispatchers<P, D>(
113 client_dispatcher: D,
114 server_dispatcher: D,
115) -> (fidl_next::ClientEnd<P, DriverChannel<D>>, fidl_next::ServerEnd<P, DriverChannel<D>>) {
116 let (client_channel, server_channel) =
117 DriverChannel::create_with_dispatchers(client_dispatcher, server_dispatcher);
118 (
119 fidl_next::ClientEnd::from_untyped(client_channel),
120 fidl_next::ServerEnd::from_untyped(server_channel),
121 )
122}
123
124pub fn create_channel_with_dispatcher<P, D: Clone>(
127 dispatcher: D,
128) -> (fidl_next::ClientEnd<P, DriverChannel<D>>, fidl_next::ServerEnd<P, DriverChannel<D>>) {
129 create_channel_with_dispatchers(dispatcher.clone(), dispatcher)
130}
131
132pub fn create_channel<P>()
135-> (fidl_next::ClientEnd<P, DriverChannel>, fidl_next::ServerEnd<P, DriverChannel>) {
136 create_channel_with_dispatcher(CurrentDispatcher)
137}
138
139pub struct SendBuffer {
141 handles: Vec<Option<MixedHandle>>,
142 data: Vec<Chunk>,
143}
144
145impl SendBuffer {
146 fn new() -> Self {
147 Self { handles: Vec::new(), data: Vec::new() }
148 }
149}
150
151impl fidl_next::Encoder for SendBuffer {
152 #[inline]
153 fn bytes_written(&self) -> usize {
154 fidl_next::Encoder::bytes_written(&self.data)
155 }
156
157 #[inline]
158 fn write(&mut self, bytes: &[u8]) {
159 fidl_next::Encoder::write(&mut self.data, bytes)
160 }
161
162 #[inline]
163 fn rewrite(&mut self, pos: usize, bytes: &[u8]) {
164 fidl_next::Encoder::rewrite(&mut self.data, pos, bytes)
165 }
166
167 fn write_zeroes(&mut self, len: usize) {
168 fidl_next::Encoder::write_zeroes(&mut self.data, len);
169 }
170}
171
172impl fidl_next::encoder::InternalHandleEncoder for SendBuffer {
173 #[inline]
174 fn __internal_handle_count(&self) -> usize {
175 self.handles.len()
176 }
177}
178
179impl fidl_next::fuchsia::HandleEncoder for SendBuffer {
180 fn push_handle(&mut self, handle: zx::Handle) -> Result<(), fidl_next::EncodeError> {
181 if let Some(handle) = MixedHandle::from_zircon_handle(handle) {
182 if handle.is_driver() {
183 return Err(fidl_next::EncodeError::ExpectedZirconHandle);
184 }
185 self.handles.push(Some(handle));
186 } else {
187 self.handles.push(None);
188 }
189 Ok(())
190 }
191
192 unsafe fn push_raw_driver_handle(&mut self, handle: u32) -> Result<(), fidl_next::EncodeError> {
193 if let Some(handle) = NonZero::new(handle) {
194 let handle = unsafe { MixedHandle::from_raw(handle) };
197 if !handle.is_driver() {
198 return Err(fidl_next::EncodeError::ExpectedDriverHandle);
199 }
200 self.handles.push(Some(handle));
201 } else {
202 self.handles.push(None);
203 }
204 Ok(())
205 }
206
207 fn handles_pushed(&self) -> usize {
208 self.handles.len()
209 }
210}
211
212pub struct RecvBuffer {
213 buffer: Option<Message<[Chunk]>>,
214 data_offset: usize,
215 handle_offset: usize,
216}
217
218impl RecvBuffer {
219 fn next_handle(&self) -> Result<&MixedHandle, fidl_next::DecodeError> {
220 let Some(buffer) = &self.buffer else {
221 return Err(fidl_next::DecodeError::InsufficientHandles);
222 };
223
224 let Some(handles) = buffer.handles() else {
225 return Err(fidl_next::DecodeError::InsufficientHandles);
226 };
227 if handles.len() < self.handle_offset + 1 {
228 return Err(fidl_next::DecodeError::InsufficientHandles);
229 }
230 handles[self.handle_offset].as_ref().ok_or(fidl_next::DecodeError::RequiredHandleAbsent)
231 }
232}
233
234unsafe impl fidl_next::Decoder for RecvBuffer {
239 fn take_chunks_raw(&mut self, count: usize) -> Result<NonNull<Chunk>, fidl_next::DecodeError> {
242 let Some(buffer) = &mut self.buffer else {
243 return Err(fidl_next::DecodeError::InsufficientData);
244 };
245
246 let Some(data) = buffer.data_mut() else {
247 return Err(fidl_next::DecodeError::InsufficientData);
248 };
249 if data.len() < self.data_offset + count {
250 return Err(fidl_next::DecodeError::InsufficientData);
251 }
252 let pos = self.data_offset;
253 self.data_offset += count;
254 Ok(unsafe { NonNull::new_unchecked((data[pos..(pos + count)]).as_mut_ptr()) })
255 }
256
257 fn commit(&mut self) {
258 if let Some(handles) = self.buffer.as_mut().and_then(Message::handles_mut) {
259 for handle in handles.iter_mut().take(self.handle_offset) {
260 core::mem::forget(handle.take());
261 }
262 }
263 }
264
265 fn finish(&self) -> Result<(), fidl_next::DecodeError> {
266 if let Some(buffer) = &self.buffer {
267 let data_len = buffer.data().unwrap_or(&[]).len();
268 if self.data_offset != data_len {
269 return Err(fidl_next::DecodeError::ExtraBytes {
270 num_extra: data_len - self.data_offset,
271 });
272 }
273 let handle_len = buffer.handles().unwrap_or(&[]).len();
274 if self.handle_offset != handle_len {
275 return Err(fidl_next::DecodeError::ExtraHandles {
276 num_extra: handle_len - self.handle_offset,
277 });
278 }
279 }
280
281 Ok(())
282 }
283}
284
285impl fidl_next::decoder::InternalHandleDecoder for RecvBuffer {
286 fn __internal_take_handles(&mut self, count: usize) -> Result<(), fidl_next::DecodeError> {
287 let Some(handles) = self.buffer.as_mut().and_then(Message::handles_mut) else {
288 return Err(fidl_next::DecodeError::InsufficientHandles);
289 };
290 if handles.len() < self.handle_offset + count {
291 return Err(fidl_next::DecodeError::InsufficientHandles);
292 }
293 let pos = self.handle_offset;
294 self.handle_offset = pos + count;
295 Ok(())
296 }
297
298 fn __internal_handles_remaining(&self) -> usize {
299 self.buffer
300 .as_ref()
301 .map(|buffer| buffer.handles().unwrap_or(&[]).len() - self.handle_offset)
302 .unwrap_or(0)
303 }
304}
305
306impl fidl_next::fuchsia::HandleDecoder for RecvBuffer {
307 fn take_raw_handle(&mut self) -> Result<zx::sys::zx_handle_t, fidl_next::DecodeError> {
308 let result = {
309 let handle = self.next_handle()?.resolve_ref();
310 let MixedHandleType::Zircon(handle) = handle else {
311 return Err(fidl_next::DecodeError::ExpectedZirconHandle);
312 };
313 handle.raw_handle()
314 };
315 let pos = self.handle_offset;
316 self.handle_offset = pos + 1;
317 Ok(result)
318 }
319
320 fn take_raw_driver_handle(&mut self) -> Result<u32, fidl_next::DecodeError> {
321 let result = {
322 let handle = self.next_handle()?.resolve_ref();
323 let MixedHandleType::Driver(handle) = handle else {
324 return Err(fidl_next::DecodeError::ExpectedDriverHandle);
325 };
326 unsafe { handle.get_raw().get() }
327 };
328 let pos = self.handle_offset;
329 self.handle_offset = pos + 1;
330 Ok(result)
331 }
332
333 fn handles_remaining(&mut self) -> usize {
334 fidl_next::decoder::InternalHandleDecoder::__internal_handles_remaining(self)
335 }
336}
337
338pub struct DriverRecvState(ReadMessageState);
340
341pub struct Shared<D> {
343 channel: Mutex<DriverChannel<D>>,
344}
345
346impl<D> Shared<D> {
347 fn new(channel: Mutex<DriverChannel<D>>) -> Self {
348 Self { channel }
349 }
350
351 fn get_locked(&self) -> MutexGuard<'_, DriverChannel<D>> {
352 self.channel.lock().unwrap()
353 }
354}
355
356pub struct Exclusive {
358 _phantom: PhantomData<()>,
359}
360
361impl<D: OnDispatcher> fidl_next::Transport for DriverChannel<D> {
362 type Error = Status;
363
364 fn split(self) -> (Self::Shared, Self::Exclusive) {
365 (Shared::new(Mutex::new(self)), Exclusive { _phantom: PhantomData })
366 }
367
368 type Shared = Shared<D>;
369
370 type SendBuffer = SendBuffer;
371
372 type SendFutureState = SendBuffer;
373
374 fn acquire(_shared: &Self::Shared) -> Self::SendBuffer {
375 SendBuffer::new()
376 }
377
378 type Exclusive = Exclusive;
379
380 type RecvFutureState = DriverRecvState;
381
382 type RecvBuffer = RecvBuffer;
383
384 fn begin_send(_shared: &Self::Shared, buffer: Self::SendBuffer) -> Self::SendFutureState {
385 buffer
386 }
387
388 fn poll_send(
389 mut buffer: Pin<&mut Self::SendFutureState>,
390 _cx: &mut Context<'_>,
391 shared: &Self::Shared,
392 ) -> Poll<Result<(), Option<Self::Error>>> {
393 let arena = Arena::new();
394 let message = Message::new_with(arena, |arena| {
395 let data = arena.insert_slice(&buffer.data);
396 let handles = buffer.handles.split_off(0);
397 let handles = arena.insert_from_iter(handles);
398 (Some(data), Some(handles))
399 });
400 let result = match shared.get_locked().channel.write(message) {
401 Ok(()) => Ok(()),
402 Err(Status::PEER_CLOSED) => Err(None),
403 Err(e) => Err(Some(e)),
404 };
405 Poll::Ready(result)
406 }
407
408 fn begin_recv(
409 shared: &Self::Shared,
410 _exclusive: &mut Self::Exclusive,
411 ) -> Self::RecvFutureState {
412 let state =
415 unsafe { ReadMessageState::register_read_wait(&mut shared.get_locked().channel) };
416 DriverRecvState(state)
417 }
418
419 fn poll_recv(
420 mut future: Pin<&mut Self::RecvFutureState>,
421 cx: &mut Context<'_>,
422 shared: &Self::Shared,
423 _exclusive: &mut Self::Exclusive,
424 ) -> Poll<Result<Self::RecvBuffer, Option<Self::Error>>> {
425 use std::task::Poll::*;
426 match future.as_mut().0.poll_with_dispatcher(cx, shared.get_locked().dispatcher.clone()) {
427 Ready(Ok(maybe_buffer)) => {
428 let buffer = maybe_buffer.map(|buffer| {
429 buffer.map_data(|_, data| {
430 let bytes = data.len();
431 assert_eq!(
432 0,
433 bytes % size_of::<Chunk>(),
434 "Received driver channel buffer was not a multiple of {} bytes",
435 size_of::<Chunk>()
436 );
437 unsafe {
441 let ptr = ArenaBox::into_ptr(data).cast();
442 ArenaBox::new(NonNull::slice_from_raw_parts(
443 ptr,
444 bytes / size_of::<Chunk>(),
445 ))
446 }
447 })
448 });
449
450 Ready(Ok(RecvBuffer { buffer, data_offset: 0, handle_offset: 0 }))
451 }
452 Ready(Err(err)) => {
453 if err == Status::PEER_CLOSED {
454 Ready(Err(None))
455 } else {
456 Ready(Err(Some(err)))
457 }
458 }
459 Pending => Pending,
460 }
461 }
462}
463
464impl<D> fidl_next::RunsTransport<DriverChannel<D>> for fidl_next::fuchsia_async::FuchsiaAsync {}
465
466impl<D> fidl_next::HasExecutor for DriverChannel<D> {
467 type Executor = fidl_next::fuchsia_async::FuchsiaAsync;
468
469 fn executor(&self) -> Self::Executor {
470 fidl_next::fuchsia_async::FuchsiaAsync
471 }
472}
473
474#[cfg(test)]
475mod test {
476 use fidl_next::{ClientDispatcher, ClientEnd, Responder, ServerDispatcher, ServerEnd};
477 use fidl_next_fuchsia_examples_gizmo::device::{GetEvent, GetHardwareId};
478 use fidl_next_fuchsia_examples_gizmo::{
479 Device, DeviceClientHandler, DeviceGetEventResponse, DeviceGetHardwareIdResponse,
480 DeviceServerHandler,
481 };
482 use fuchsia_async::OnSignals;
483 use zx::{AsHandleRef, Event, Signals};
484
485 use super::*;
486 use fdf_core::dispatcher::{CurrentDispatcher, OnDispatcher};
487 use fdf_env::test::spawn_in_driver;
488
489 struct DeviceServer;
490 impl DeviceServerHandler<DriverChannel> for DeviceServer {
491 async fn get_hardware_id(&mut self, responder: Responder<GetHardwareId, DriverChannel>) {
492 responder
493 .respond(Result::<_, i32>::Ok(DeviceGetHardwareIdResponse { response: 4004 }))
494 .await
495 .unwrap();
496 }
497
498 async fn get_event(&mut self, responder: Responder<GetEvent, DriverChannel>) {
499 let event = Event::create();
500 event.signal_handle(Signals::empty(), Signals::USER_0).unwrap();
501 let response = DeviceGetEventResponse { event };
502 responder.respond(response).await.unwrap();
503 }
504 }
505
506 struct DeviceClient;
507 impl DeviceClientHandler<DriverChannel> for DeviceClient {}
508
509 #[test]
510 fn driver_fidl_server() {
511 spawn_in_driver("driver fidl server", async {
512 let (server_chan, client_chan) = Channel::<[Chunk]>::create();
513 let client_end: ClientEnd<Device, _> =
514 ClientEnd::<Device, _>::from_untyped(DriverChannel::new(client_chan));
515 let server_end: ServerEnd<Device, _> =
516 ServerEnd::from_untyped(DriverChannel::new(server_chan));
517 let client_dispatcher = ClientDispatcher::new(client_end);
518 let server_dispatcher = ServerDispatcher::new(server_end);
519 let client = client_dispatcher.client();
520
521 CurrentDispatcher
522 .spawn_task(async {
523 server_dispatcher.run(DeviceServer).await.unwrap();
524 println!("server task finished");
525 })
526 .unwrap();
527 CurrentDispatcher
528 .spawn_task(async {
529 client_dispatcher.run(DeviceClient).await.unwrap();
530 println!("client task finished");
531 })
532 .unwrap();
533
534 {
535 let res = client.get_hardware_id().await.unwrap();
536 let hardware_id = res.unwrap();
537 assert_eq!(hardware_id.response, 4004);
538 }
539
540 {
541 let res = client.get_event().await.unwrap().take();
542
543 let mut executor = fuchsia_async::LocalExecutor::default();
545 let signalled = executor
546 .run_singlethreaded(OnSignals::new(res.event, Signals::USER_0))
547 .unwrap();
548 assert_eq!(Signals::USER_0, signalled);
549 }
550 });
551 }
552}