_fake_driver_rustc/
lib.rs

1// Copyright 2025 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use fdf_component::{
6    driver_register, Driver, DriverContext, Node, NodeBuilder, ZirconServiceOffer,
7};
8use fidl::endpoints::ClientEnd;
9use fidl_fuchsia_driver_framework::NodeControllerMarker;
10use fidl_fuchsia_hardware_interconnect as icc;
11use fuchsia_component::server::ServiceFs;
12use futures::{StreamExt, TryStreamExt};
13use log::{info, warn};
14use zx::Status;
15
16driver_register!(FakeInterconnectDriver);
17
18#[allow(unused)]
19struct FakeInterconnectDriver {
20    node: Node,
21    child_controller: ClientEnd<NodeControllerMarker>,
22    scope: fuchsia_async::Scope,
23}
24
25impl Driver for FakeInterconnectDriver {
26    const NAME: &str = "fake_interconnect";
27
28    async fn start(mut context: DriverContext) -> Result<Self, Status> {
29        let node = context.take_node()?;
30
31        let mut outgoing = ServiceFs::new();
32
33        let offer = ZirconServiceOffer::new()
34            .add_default_named(&mut outgoing, Self::NAME, move |req| {
35                let icc::ServiceRequest::Device(service) = req;
36                service
37            })
38            .build();
39
40        let node_args = NodeBuilder::new(Self::NAME).add_offer(offer).build();
41        let child_controller = node.add_child(node_args).await?;
42        context.serve_outgoing(&mut outgoing)?;
43
44        let scope = fuchsia_async::Scope::new_with_name("outgoing_directory");
45        scope.spawn_local(async move {
46            outgoing
47                .for_each_concurrent(None, move |request| async move {
48                    let mut connection = Connection;
49                    connection.run_device_server(request).await;
50                })
51                .await;
52        });
53
54        Ok(Self { node, child_controller, scope })
55    }
56
57    async fn stop(&self) {}
58}
59
60struct Connection;
61
62impl Connection {
63    fn set_nodes_bandwidth(&self, _nodes: Vec<icc::NodeBandwidth>) -> Result<(), Status> {
64        info!("set_nodes_bandwidth called");
65        Ok(())
66    }
67
68    fn get_node_graph(&self) -> (Vec<icc::Node>, Vec<icc::Edge>) {
69        info!("get_node_graph called");
70        let nodes = vec![
71            icc::Node {
72                id: Some(0),
73                name: Some("zero".to_string()),
74                interconnect_name: None,
75                ..Default::default()
76            },
77            icc::Node {
78                id: Some(1),
79                name: Some("one".to_string()),
80                interconnect_name: None,
81                ..Default::default()
82            },
83            icc::Node {
84                id: Some(2),
85                name: Some("two".to_string()),
86                interconnect_name: None,
87                ..Default::default()
88            },
89            icc::Node {
90                id: Some(3),
91                name: Some("three".to_string()),
92                interconnect_name: None,
93                ..Default::default()
94            },
95        ];
96        let edges = vec![
97            icc::Edge {
98                src_node_id: Some(0),
99                dst_node_id: Some(1),
100                weight: Some(1),
101                ..Default::default()
102            },
103            icc::Edge {
104                src_node_id: Some(1),
105                dst_node_id: Some(2),
106                weight: Some(1),
107                ..Default::default()
108            },
109            icc::Edge {
110                src_node_id: Some(1),
111                dst_node_id: Some(3),
112                weight: Some(1),
113                ..Default::default()
114            },
115            icc::Edge {
116                src_node_id: Some(2),
117                dst_node_id: Some(1),
118                weight: Some(1),
119                ..Default::default()
120            },
121        ];
122        (nodes, edges)
123    }
124
125    fn get_path_endpoints(&self) -> Vec<icc::PathEndpoints> {
126        info!("get_path_endpoints called");
127        vec![
128            icc::PathEndpoints {
129                name: Some("path_a".to_string()),
130                id: Some(0),
131                src_node_id: Some(0),
132                dst_node_id: Some(2),
133                ..Default::default()
134            },
135            icc::PathEndpoints {
136                name: Some("path_b".to_string()),
137                id: Some(1),
138                src_node_id: Some(0),
139                dst_node_id: Some(3),
140                ..Default::default()
141            },
142            icc::PathEndpoints {
143                name: Some("path_c".to_string()),
144                id: Some(2),
145                src_node_id: Some(2),
146                dst_node_id: Some(3),
147                ..Default::default()
148            },
149        ]
150    }
151
152    async fn run_device_server(&mut self, mut service: icc::DeviceRequestStream) {
153        use icc::DeviceRequest::*;
154        while let Some(req) = service.try_next().await.unwrap() {
155            match req {
156                SetNodesBandwidth { nodes, responder, .. } => {
157                    responder.send(self.set_nodes_bandwidth(nodes).map_err(Status::into_raw))
158                }
159                GetNodeGraph { responder, .. } => {
160                    let (nodes, edges) = self.get_node_graph();
161                    responder.send(&nodes, &edges)
162                }
163                GetPathEndpoints { responder, .. } => responder.send(&self.get_path_endpoints()),
164                // Ignore unknown requests.
165                _ => {
166                    warn!("Received unknown path request");
167                    Ok(())
168                }
169            }
170            .unwrap();
171        }
172    }
173}