1use fdf_component::{
6 driver_register, Driver, DriverContext, Node, NodeBuilder, ZirconServiceOffer,
7};
8use fidl_fuchsia_hardware_i2c as i2c;
9use fuchsia_component::server::ServiceFs;
10use futures::{StreamExt, TryStreamExt};
11use log::info;
12use zx::Status;
13
14#[allow(unused)]
16struct ZirconParentDriver {
17 node: Node,
20}
21
22driver_register!(ZirconParentDriver);
25
26async fn i2c_server(mut service: i2c::DeviceRequestStream) {
27 use i2c::DeviceRequest::*;
28 while let Some(req) = service.try_next().await.unwrap() {
29 match req {
30 Transfer { responder, .. } => responder.send(Ok(&[vec![0x1u8, 0x2, 0x3]])),
31 GetName { responder } => responder.send(Ok("rust i2c server")),
32 }
33 .unwrap();
34 }
35}
36
37impl Driver for ZirconParentDriver {
38 const NAME: &str = "zircon_parent_rust_driver";
39
40 async fn start(mut context: DriverContext) -> Result<Self, Status> {
41 info!("Binding node client. Every driver needs to do this for the driver to be considered loaded.");
42 let node = context.take_node()?;
43
44 info!("Offering an i2c service in the outgoing directory");
45 let mut outgoing = ServiceFs::new();
46 let offer = ZirconServiceOffer::new()
47 .add_default_named(&mut outgoing, "default", |i| {
48 let i2c::ServiceRequest::Device(service) = i;
52 service
53 })
54 .build();
55
56 info!("Creating child node with a service offer");
57 let child_node = NodeBuilder::new("zircon_transport_rust_child").add_offer(offer).build();
58 node.add_child(child_node).await?;
59
60 context.serve_outgoing(&mut outgoing)?;
61
62 fuchsia_async::Task::spawn(async move {
63 outgoing.for_each_concurrent(None, i2c_server).await;
64 })
65 .detach();
66
67 Ok(Self { node })
68 }
69
70 async fn stop(&self) {
71 info!(
72 "ZirconParentDriver::stop() was invoked. Use this function to do any cleanup needed."
73 );
74 }
75}