bt_test_harness/
core_realm.rs1use crate::emulator::EMULATOR_ROOT_DRIVER_URL;
6use anyhow::{format_err, Error};
7use fidl_fuchsia_bluetooth_snoop::SnoopMarker;
8use fidl_fuchsia_device::NameProviderMarker;
9use fidl_fuchsia_logger::LogSinkMarker;
10use fidl_fuchsia_stash::SecureStoreMarker;
11use fuchsia_component_test::{
12 Capability, ChildOptions, RealmBuilder, RealmInstance, Ref, Route, ScopedInstance,
13};
14use fuchsia_driver_test::{DriverTestRealmBuilder, DriverTestRealmInstance};
15use futures::FutureExt;
16use realmbuilder_mock_helpers::stateless_mock_responder;
17use {
18 fidl_fuchsia_bluetooth_bredr as fbredr, fidl_fuchsia_bluetooth_gatt as fbgatt,
19 fidl_fuchsia_bluetooth_le as fble, fidl_fuchsia_bluetooth_sys as fbsys,
20 fidl_fuchsia_driver_test as fdt, fidl_fuchsia_io as fio,
21};
22
23pub const SHARED_STATE_INDEX: &str = "BT-CORE-REALM";
24pub const DEFAULT_TEST_DEVICE_NAME: &str = "fuchsia-bt-integration-test";
25
26mod constants {
30 pub mod bt_init {
31 pub const URL: &str = "#meta/test-bt-init.cm";
32 pub const MONIKER: &str = "bt-init";
33 }
34 pub mod secure_stash {
35 pub const URL: &str = "#meta/test-stash-secure.cm";
36 pub const MONIKER: &str = "secure-stash";
37 }
38 pub mod mock_name_provider {
39 pub const MONIKER: &str = "mock-name-provider";
40 }
41 pub mod mock_snoop {
42 pub const MONIKER: &str = "mock-snoop";
43 }
44}
45
46pub struct CoreRealm {
53 realm: RealmInstance,
54}
55
56impl CoreRealm {
57 pub async fn create(test_component: String) -> Result<Self, Error> {
58 let resolved_test_component = {
61 let client = fuchsia_component::client::connect_to_protocol_at_path::<
62 fidl_fuchsia_component_resolution::ResolverMarker,
63 >("/svc/fuchsia.component.resolution.Resolver-hermetic")
64 .unwrap();
65 client
66 .resolve(test_component.as_str())
67 .await
68 .unwrap()
69 .expect("Failed to resolve test component")
70 };
71
72 let builder = RealmBuilder::new().await?;
73 let _ = builder.driver_test_realm_setup().await?;
74
75 let bt_init = builder
77 .add_child(
78 constants::bt_init::MONIKER,
79 constants::bt_init::URL,
80 ChildOptions::new().eager(),
81 )
82 .await?;
83 let secure_stash = builder
84 .add_child(
85 constants::secure_stash::MONIKER,
86 constants::secure_stash::URL,
87 ChildOptions::new(),
88 )
89 .await?;
90 let mock_name_provider = builder
91 .add_local_child(
92 constants::mock_name_provider::MONIKER,
93 |handles| {
94 stateless_mock_responder::<NameProviderMarker, _>(handles, |req| {
95 let responder = req
96 .into_get_device_name()
97 .ok_or(format_err!("got unexpected NameProviderRequest"))?;
98 Ok(responder.send(Ok(DEFAULT_TEST_DEVICE_NAME))?)
99 })
100 .boxed()
101 },
102 ChildOptions::new(),
103 )
104 .await?;
105 let mock_snoop = builder
106 .add_local_child(
107 constants::mock_snoop::MONIKER,
108 |handles| {
109 stateless_mock_responder::<SnoopMarker, _>(handles, |req| {
110 let _ =
112 req.into_start().ok_or(format_err!("got unexpected SnoopRequest"))?;
113 Ok(())
114 })
115 .boxed()
116 },
117 ChildOptions::new(),
118 )
119 .await?;
120
121 builder
123 .add_route(
124 Route::new()
125 .capability(Capability::protocol::<LogSinkMarker>())
126 .capability(Capability::dictionary("diagnostics"))
127 .from(Ref::parent())
128 .to(&bt_init)
129 .to(&secure_stash),
130 )
131 .await?;
132 builder
133 .add_route(
134 Route::new()
135 .capability(Capability::storage("tmp"))
136 .from(Ref::parent())
137 .to(&secure_stash),
138 )
139 .await?;
140 builder
141 .add_route(
142 Route::new()
143 .capability(Capability::protocol::<SecureStoreMarker>())
144 .from(&secure_stash)
145 .to(&bt_init),
146 )
147 .await?;
148 builder
149 .add_route(
150 Route::new()
151 .capability(Capability::protocol::<NameProviderMarker>())
152 .from(&mock_name_provider)
153 .to(&bt_init),
154 )
155 .await?;
156 builder
157 .add_route(
158 Route::new()
159 .capability(Capability::protocol::<SnoopMarker>())
160 .from(&mock_snoop)
161 .to(&bt_init),
162 )
163 .await?;
164 builder
165 .add_route(
166 Route::new()
167 .capability(Capability::protocol::<fbgatt::Server_Marker>())
168 .capability(Capability::protocol::<fble::CentralMarker>())
169 .capability(Capability::protocol::<fble::PeripheralMarker>())
170 .capability(Capability::protocol::<fbsys::AccessMarker>())
171 .capability(Capability::protocol::<fbsys::HostWatcherMarker>())
172 .capability(Capability::protocol::<fbredr::ProfileMarker>())
173 .capability(Capability::protocol::<fbsys::BootstrapMarker>())
174 .from(&bt_init)
175 .to(Ref::parent()),
176 )
177 .await?;
178
179 crate::host_realm::add_host_routes(&builder, &bt_init).await?;
180 let instance = builder.build().await?;
181
182 let args = fdt::RealmArgs {
184 root_driver: Some(EMULATOR_ROOT_DRIVER_URL.to_string()),
185 software_devices: Some(vec![fidl_fuchsia_driver_test::SoftwareDevice {
186 device_name: "bt-hci-emulator".to_string(),
187 device_id: bind_fuchsia_platform::BIND_PLATFORM_DEV_DID_BT_HCI_EMULATOR,
188 }]),
189 test_component: Some(resolved_test_component),
190 ..Default::default()
191 };
192 instance.driver_test_realm_start(args).await?;
193
194 Ok(Self { realm: instance })
195 }
196
197 pub fn instance(&self) -> &ScopedInstance {
198 &self.realm.root
199 }
200
201 pub fn dev(&self) -> Result<fio::DirectoryProxy, Error> {
202 self.realm.driver_test_realm_connect_to_dev()
203 }
204}