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