use fdf_component::{
driver_register, Driver, DriverContext, Node, NodeBuilder, ZirconServiceOffer,
};
use fidl_fuchsia_hardware_i2c as i2c;
use fuchsia_component::server::ServiceFs;
use futures::{StreamExt, TryStreamExt};
use tracing::info;
use zx::Status;
#[allow(unused)]
struct ZirconParentDriver {
node: Node,
}
driver_register!(ZirconParentDriver);
async fn i2c_server(mut service: i2c::DeviceRequestStream) {
use i2c::DeviceRequest::*;
while let Some(req) = service.try_next().await.unwrap() {
match req {
Transfer { responder, .. } => responder.send(Ok(&[vec![0x1u8, 0x2, 0x3]])),
GetName { responder } => responder.send(Ok("rust i2c server")),
}
.unwrap();
}
}
impl Driver for ZirconParentDriver {
const NAME: &str = "zircon_parent_rust_driver";
async fn start(mut context: DriverContext) -> Result<Self, Status> {
info!("Binding node client. Every driver needs to do this for the driver to be considered loaded.");
let node = context.take_node()?;
info!("Offering an i2c service in the outgoing directory");
let mut outgoing = ServiceFs::new();
let offer = ZirconServiceOffer::new()
.add_default_named(&mut outgoing, "default", |i| {
let i2c::ServiceRequest::Device(service) = i;
service
})
.build();
info!("Creating child node with a service offer");
let child_node = NodeBuilder::new("zircon_transport_rust_child").add_offer(offer).build();
node.add_child(child_node).await?;
context.serve_outgoing(&mut outgoing)?;
fuchsia_async::Task::spawn(async move {
outgoing.for_each_concurrent(None, i2c_server).await;
})
.detach();
Ok(Self { node })
}
async fn stop(&self) {
info!(
"ZirconParentDriver::stop() was invoked. Use this function to do any cleanup needed."
);
}
}